Interacting with the Oracle contract directly is a common use case, one of the possible methods to interact with this contract is illustrated below.
Viem
, a Typescript library similar to ethers.js
that simplifies the process of interacting with the Oracle contract.
import { createWalletClient, createPublicClient, http } from 'viem';
import { rootPorcini } from 'viem/chains';
const account = privateKeyToAccount("0x123abc");
const syloTokenAddress = "0xCCcCCcCC00000C64000000000000000000000000";
const oracleAddress = "0xf459E82138096876C25cd5fbc54c487476640619";
const publicClient = createPublicClient({
chain: rootPorcini,
transport: http("https://porcini.rootnet.app"),
});
const walletClient = createWalletClient({
account,
chain: rootPorcini,
transport: http("https://porcini.rootnet.app"),
});
export default { walletClient, publicClient, syloTokenAddress, oracleAddress };
async function depositTokens() {
// First approve the Oracle to spend your SYLO tokens
const approvalHash = await walletClient.writeContract({
address: syloTokenAddress,
abi: ERC20_ABI,
functionName: "approve",
account,
args: [oracleAddress, parseUnits("100", 18)], // 100 SYLO tokens
});
// Wait for approval transaction to be mined
await publicClient.waitForTransactionReceipt({ hash: approvalHash });
// Deposit SYLO to the Oracle contract
const depositHash = await walletClient.writeContract({
address: oracleAddress,
abi: ORACLE_ABI,
functionName: "deposit",
account,
args: [parseUnits("100", 18), account.address],
});
// Wait for deposit transaction to be mined
return await publicClient.waitForTransactionReceipt({ hash: depositHash });
}
async function requestTokenPrice(tokenId: string) {
const hash = await walletClient.writeContract({
address: oracleAddress,
abi: ORACLE_ABI,
functionName: "createRequest",
account,
args: [tokenId],
});
// Wait for createRequest transaction to be mined
await publicClient.waitForTransactionReceipt({ hash });
const requestId = (await publicClient.readContract({
address: oracleAddress,
abi: ORACLE_ABI,
functionName: "requestId",
})) as string;
return requestId;
}
Asset Id | Token |
---|---|
1 | ROOT |
2 | XRP |
3172 | SYLO |
17508 | ASTO |
1124 | ETH |
2148 | USDC |
8292 | WBTC |
async function getResponseData(requestId: string) {
</strong> // Check if request is processed
const isProcessed = await publicClient.readContract({
address: oracleAddress,
abi: ORACLE_ABI,
functionName: "isProcessed",
args: [requestId],
});
if (!isProcessed) {
console.log("Request not yet processed, try again later");
return null;
}
// Get response data
const response = (await publicClient.readContract({
address: oracleAddress,
abi: ORACLE_ABI,
functionName: "getResponse",
args: [requestId],
})) as { value: bigint; timestamp: string };
console.log(`Token price: ${formatUnits(response.value, 18)}`);
console.log(`Timestamp: ${new Date(Number(response.timestamp) * 1000)}`);
return response;
}
async function priceRequestWorkflow(tokenId: string) {
// Step 1
await depositTokens();
// Step 2
const requestId = await requestTokenPrice(tokenId);
console.log(`Request created with ID: ${requestId}`);
// Step 3
if (requestId) {
// Wait for daemon to emit responded event and get response data
console.log("waiting for responded event ...");
publicClient.watchEvent({
address: oracleAddress,
event: parseAbiItem("event Responded(uint256 indexed requestId)"),
onLogs: async (logs) => {
const requestId = logs[0].args.requestId;
if (requestId) {
await getResponseData(requestId.toString());
}
},
});
}
}
priceRequestWorkflow("1"); // Asset Id for ROOT
requestId
can be done in a few different ways. In this particular example, the Responded
event indicates that the Daemon has processed the request and that the token data is ready to be read.
[
{
"inputs": [
{
"internalType": "address",
"name": "_responder",
"type": "address"
},
{
"internalType": "uint32[]",
"name": "_tokens",
"type": "uint32[]"
},
{
"internalType": "contract IERC20",
"name": "_syloToken",
"type": "address"
},
{
"internalType": "address",
"name": "_initialManager",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "AccessControlBadConfirmation",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "bytes32",
"name": "neededRole",
"type": "bytes32"
}
],
"name": "AccessControlUnauthorizedAccount",
"type": "error"
},
{
"inputs": [],
"name": "AlreadyFulfilled",
"type": "error"
},
{
"inputs": [],
"name": "InsufficientBalance",
"type": "error"
},
{
"inputs": [],
"name": "InvalidValue",
"type": "error"
},
{
"inputs": [],
"name": "NotAllowedToken",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
}
],
"name": "AdminWithdrawal",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "Deposited",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "requestId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "string",
"name": "token",
"type": "string"
}
],
"name": "Requested",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "requestId",
"type": "uint256"
}
],
"name": "Responded",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "previousAdminRole",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "newAdminRole",
"type": "bytes32"
}
],
"name": "RoleAdminChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleGranted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleRevoked",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "string",
"name": "token",
"type": "string"
},
{
"indexed": false,
"internalType": "bool",
"name": "state",
"type": "bool"
}
],
"name": "TokenUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [],
"name": "UpdatedAmountPerRequest",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
}
],
"name": "WithdrawalForUser",
"type": "event"
},
{
"inputs": [],
"name": "DEFAULT_ADMIN_ROLE",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MANAGER_ROLE",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "RESPONDER_ROLE",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint32",
"name": "_token",
"type": "uint32"
}
],
"name": "createRequest",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint32[]",
"name": "_tokens",
"type": "uint32[]"
}
],
"name": "createRequests",
"outputs": [
{
"internalType": "uint256[]",
"name": "",
"type": "uint256[]"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_value",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_requestId",
"type": "uint256"
}
],
"name": "createResponse",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"internalType": "address",
"name": "_sender",
"type": "address"
}
],
"name": "deposit",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"internalType": "address",
"name": "_recipient",
"type": "address"
}
],
"name": "depositForUser",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "deposits",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint32[]",
"name": "_tokens",
"type": "uint32[]"
}
],
"name": "getLatestData",
"outputs": [
{
"components": [
{
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "requestId",
"type": "uint256"
}
],
"internalType": "struct Oracle.Response[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bool",
"name": "_breakOnProcessed",
"type": "bool"
}
],
"name": "getPendingRequests",
"outputs": [
{
"internalType": "uint256[]",
"name": "",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_address",
"type": "address"
}
],
"name": "getRemainingRequests",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_requestId",
"type": "uint256"
}
],
"name": "getResponse",
"outputs": [
{
"components": [
{
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "requestId",
"type": "uint256"
}
],
"internalType": "struct Oracle.Response",
"name": "",
"type": "tuple"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
}
],
"name": "getRoleAdmin",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "grantRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "hasRole",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_requestId",
"type": "uint256"
}
],
"name": "isProcessed",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pricePerRequest",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"internalType": "address",
"name": "callerConfirmation",
"type": "address"
}
],
"name": "renounceRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "requestId",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "requests",
"outputs": [
{
"internalType": "uint32",
"name": "tokenId",
"type": "uint32"
},
{
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
},
{
"internalType": "bool",
"name": "processed",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "responses",
"outputs": [
{
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "requestId",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "revokeRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "interfaceId",
"type": "bytes4"
}
],
"name": "supportsInterface",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "syloToken",
"outputs": [
{
"internalType": "contract IERC20",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "tokenData",
"outputs": [
{
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "requestId",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint32",
"name": "",
"type": "uint32"
}
],
"name": "tokenNames",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint32",
"name": "",
"type": "uint32"
}
],
"name": "tokens",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
}
],
"name": "updateAmountPerRequest",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint32",
"name": "_token",
"type": "uint32"
},
{
"internalType": "string",
"name": "_name",
"type": "string"
},
{
"internalType": "bool",
"name": "_state",
"type": "bool"
}
],
"name": "updateToken",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"internalType": "address",
"name": "_from",
"type": "address"
},
{
"internalType": "address",
"name": "_recipient",
"type": "address"
}
],
"name": "withdrawForUser",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"internalType": "address",
"name": "_recipient",
"type": "address"
}
],
"name": "withdrawFunds",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "withdrawable",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
}
]
Was this page helpful?