Now I am trying to call external API on Chainlink Function Contract. I created an API, tested it with Postman. It works well.
This is the response of the API.
{ "price": 11192.32 }
And now I am trying to call the API in the chainlink contract.
This is the contract code.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import {Chainlink, ChainlinkClient} from "@chainlink/contracts/src/v0.8/ChainlinkClient.sol";
import {ConfirmedOwner} from "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";
import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol";
contract RolexPriceConsumer is ChainlinkClient, ConfirmedOwner {
using Chainlink for Chainlink.Request;
uint256 public price;
address private oracle;
bytes32 private jobId;
uint256 private fee;
event RequestPrice(bytes32 indexed requestId, uint256 price);
constructor() ConfirmedOwner(msg.sender) {
_setChainlinkToken(0x779877A7B0D9E8603169DdbD7836e478b4624789);
_setChainlinkOracle(0x6090149792dAAeE9D1D568c9f9a6F6B46AA29eFD);
jobId = "ca98366cc7314957b8c012c72f05aeeb";
fee = 0.1 * 10 ** 18;
}
function requestRolexPrice(
string memory _url
) public returns (bytes32 requestId) {
Chainlink.Request memory req = _buildChainlinkRequest(
jobId,
address(this),
this.fulfill.selector
);
req._add("get", _url);
req._add("multiply", "100000000");
req._add("path", "price");
requestId = _sendChainlinkRequest(req, fee);
}
function fulfill(
bytes32 _requestId,
uint256 _price
) public recordChainlinkFulfillment(_requestId) {
emit RequestPrice(_requestId, _price);
price = _price;
}
function getLatestPrice() public view returns (uint256) {
return price;
}
function withdrawLink() public onlyOwner {
LinkTokenInterface link = LinkTokenInterface(_chainlinkTokenAddress());
require(
link.transfer(msg.sender, link.balanceOf(address(this))),
"Unable to transfer"
);
}
}
I deployed this contract on Sepolia Testnet, verified it. When I deploy this contract, the API is called. But the getlatestPrice returned 0 in Sepolia Scan.
I think fulfill function isn't called correctly. But I am not sure exactly. I'd be appreciate if you help me.
I ran this code
function requestRolexPrice(
string memory _url
) public returns (bytes32) {
Chainlink.Request memory req = _buildChainlinkRequest(
jobId,
address(this),
this.fulfill.selector
);
req.add("get", _url); // Use `add` instead of `_add`
req.add("path", "price"); // Correct method call
req.add("multiply", "100000000");
// Send the request and store the requestId
bytes32 requestId = _sendChainlinkRequest(req, fee);
// Return the requestId
return requestId;
}
The correct field to multiply the result (to remove decimals) is times
, and it expects a numeric value. Therefore, you should use either req._addUint
or req._addInt
.
So, replace this line:
req.add("multiply", "100000000");
with:
req._addUint("times", 100000000);
NOTE: As of now, the recommended way to fetch data from any API into a smart contract is by using Chainlink Functions, rather than utilizing Job Specs and Operator/Oracle contracts that interact with a Chainlink Node.