Let’s create a JOB, so you can test and see if your oracle is interacting with the external world.
We have the following Jobs that need to be set up.
Direct Request Job
Steps to Setup Direct Request Job
ORACLE CONTRACT:
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;
import "@goplugin/contracts2_3/src/v0.7/Operator.sol";
While deploying this contract, need to give the “PLI” as “0xff7412ea7c8445c46a8254dfb557ac1e48094391” for Mainnet and for “Owner”, the wallet address from which you are going to deploy.
Once the contract is deployed, note down the Oracle contract address. Node Fulfillment:
In the deployed Oracle click on the ‘setAuthorizedSenders’ button and pass on the node address in array format e.g([‘<Node_address>’], replace ‘xdc’ to ‘0x’ in the node address) and click on the ‘transact’.
JOB SUBMISSION:
- In the Jobs Section, click on the “New Job” button.
2. Now, submit the below Job Spec and press the “Create job” button
Job Spec:
type = "directrequest"
schemaVersion = 1
name = "Sample Request"
forwardingAllowed = false
maxTaskDuration = "0s"
contractAddress = "<Oracle Contract Address>"
minContractPaymentLinkJuels = "0"
observationSource = """
decode_log [type="ethabidecodelog" abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)" data="$(jobRun.logData)" topics="$(jobRun.logTopics)"]
decode_cbor [type="cborparse" data="$(decode_log.data)"]
fetch [type=http method=GET url="https://pro-api.coinmarketcap.com/v2/cryptocurrency/quotes/latest?symbol=XDC&convert=USDT" allowUnrestrictedNetworkAccess="true"];
parse [type="jsonparse" path="USDT" data="$(fetch)"]
multiply [type="multiply" input="$(parse)" times="$(decode_cbor.times)"]
encode_data [type="ethabiencode" abi="(bytes32 requestId, uint256 value)" data="{ \\"requestId\\": $(decode_log.requestId), \\"value\\": $(multiply) }"]
encode_tx [type="ethabiencode" abi="fulfillOracleRequest2(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes calldata data)"
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}" ]
submit_tx [type="ethtx" to="Oracle Contract Address" data="$(encode_tx)"] //paste the Oracle Address which you deployed in ‘to’ field
decode_log -> decode_cbor -> fetch -> parse -> multiply -> encode_data -> encode_tx -> submit_tx
"""
3. Once the Job has been submitted successfully, copy the External Job ID and remove the hyphen(‘-’) from the job ID
CONSUMER CONTRACT
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "@goplugin/contracts2_3/src/v0.8/PluginClient.sol";
import "@goplugin/contracts2_3/src/v0.8/ConfirmedOwner.sol";
/**
* THIS IS AN EXAMPLE CONTRACT WHICH USES HARDCODED VALUES FOR CLARITY.
* THIS EXAMPLE USES UN-AUDITED CODE.
* DO NOT USE THIS CODE IN PRODUCTION.
*/
contract APIConsumer is PluginClient, ConfirmedOwner {
using Plugin for Plugin.Request;
uint256 public volume;
bytes32 private jobId;
uint256 private fee;
event RequestVolume(bytes32 indexed requestId, uint256 volume);
/**
* @notice Initialize the pli token and target oracle
*
* Details:
* A. Pli Token for Mainnt: 0xff7412ea7c8445c46a8254dfb557ac1e48094391
* B. Oracle: [Copy paste the Oracle Contract Address, which you deployed as first step in this page] (Plugin DevRel)
* C. jobId: <job ID>
* */
constructor() ConfirmedOwner(msg.sender) {
setPluginToken(0xff7412ea7c8445c46a8254dfb557ac1e48094391);//Pli address as mentioned in ‘A’
setPluginOracle(<Copy paste the Oracle Contract Address>);//Oracle address
jobId = "<job ID>";//Job ID as stored in ‘C’ JOB SUBMISSION
fee = (0.001 * 1000000000000000000) / 10;
}
/**
* Create a Plugin request to retrieve API response, find the target
* data, then multiply by 1000000000000000000 (to remove decimal places from data).
*/
function requestVolumeData() public returns (bytes32 requestId) {
Plugin.Request memory req = buildPluginRequest(
jobId,
address(this),
this.fulfill.selector
);
// Set the URL to perform the GET request on
// req.add(
// "get",
// "<sample_api_link>/data/pricemultifull?fsyms=ETH&tsyms=USD"
// );
req.add(
"get",
"<sample_api_link>/data/price?fsym=XDC&tsyms=USDT"
);
// Multiply the result by 1000000000000000000 to remove decimals
int256 timesAmount = 10 ** 18;
req.addInt("times", timesAmount);
// Sends the request
return sendPluginRequest(req, fee);
}
/**
* Receive the response in the form of uint256
*/
function fulfill(
bytes32 _requestId,
uint256 _volume
) public recordPluginFulfillment(_requestId) {
emit RequestVolume(_requestId, _volume);
volume = _volume;
}
/**
* Allow withdraw of Link tokens from the contract
*/
function withdrawPli() public onlyOwner {
PliTokenInterface pli = PliTokenInterface(PluginTokenAddress());
require(
pli.transfer(msg.sender, pli.balanceOf(address(this))),
"Unable to transfer"
);
}
}
Once the contract is deployed, fund the contract with 0.1 PLI and click on ‘requestVolumeData’ & wait for few minutes and then click on ‘volume’ to get the XDC-USDT value.