Skip to content

Instantly share code, notes, and snippets.

@hbarcelos
Last active May 30, 2020 04:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hbarcelos/05854cb1ab91bf9024d03456241492cc to your computer and use it in GitHub Desktop.
Save hbarcelos/05854cb1ab91bf9024d03456241492cc to your computer and use it in GitHub Desktop.
Getting the USD/ETH price from MakerDAO feed [off-chain only]
const Web3 = require("web3");
const abi = require("./MedianEthUsd.json");
const providerUrl = `https://mainnet.infura.io/v3/${process.env.INFURA_API_KEY}`;
const provider = new Web3.providers.HttpProvider(providerUrl);
const web3 = new Web3(provider);
const contract = new web3.eth.Contract(
abi,
"0x64de91f5a373cd4c28de3600cb34c7c6ce410c85"
);
async function getPriceFromLatestBlocks({ fromBlock }) {
const events = await contract.getPastEvents("LogMedianPrice", {
fromBlock,
});
if (events.length === 0) {
throw Object.create(new Error(`No updates in the last ${blocks} blocks`), {
code: {
value: "ENOTFOUND",
},
});
}
const lastEvent = events[events.length - 1];
const price = Number(Web3.utils.fromWei(lastEvent.returnValues.val));
if (Number.isNaN(price)) {
throw new Error(`Invalid value for price ${lastEvent.returnValues.val}`);
}
return price;
}
/**
* In case the feed stops being updated for a while,
* we can still try to go further in the history to
* get a price, even though it would be outdated.
*/
async function getPrice() {
const maxAttempts = 5;
let attempts = 0;
const currentBlockNumber = await web3.eth.getBlockNumber();
let searchBlocks = 1000;
while (attempts < maxAttempts) {
try {
return await getPriceFromLatestBlocks({
fromBlock: currentBlockNumber - searchBlocks,
});
} catch (err) {
if (err.code !== "ENOTFOUND") {
throw err;
}
attempts += 1;
searchBlocks *= 10;
}
}
}
(async () => {
console.log(await getPrice());
})();
[
{
"constant": false,
"inputs": [
{
"internalType": "address",
"name": "usr",
"type": "address"
}
],
"name": "deny",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "address[]",
"name": "a",
"type": "address[]"
}
],
"name": "diss",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "address",
"name": "a",
"type": "address"
}
],
"name": "diss",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "address[]",
"name": "a",
"type": "address[]"
}
],
"name": "drop",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "address[]",
"name": "a",
"type": "address[]"
}
],
"name": "kiss",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "address",
"name": "a",
"type": "address"
}
],
"name": "kiss",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "address[]",
"name": "a",
"type": "address[]"
}
],
"name": "lift",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "val",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "age",
"type": "uint256"
}
],
"name": "LogMedianPrice",
"type": "event"
},
{
"anonymous": true,
"inputs": [
{
"indexed": true,
"internalType": "bytes4",
"name": "sig",
"type": "bytes4"
},
{
"indexed": true,
"internalType": "address",
"name": "usr",
"type": "address"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "arg1",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "arg2",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "LogNote",
"type": "event"
},
{
"constant": false,
"inputs": [
{
"internalType": "uint256[]",
"name": "val_",
"type": "uint256[]"
},
{
"internalType": "uint256[]",
"name": "age_",
"type": "uint256[]"
},
{
"internalType": "uint8[]",
"name": "v",
"type": "uint8[]"
},
{
"internalType": "bytes32[]",
"name": "r",
"type": "bytes32[]"
},
{
"internalType": "bytes32[]",
"name": "s",
"type": "bytes32[]"
}
],
"name": "poke",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "address",
"name": "usr",
"type": "address"
}
],
"name": "rely",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"internalType": "uint256",
"name": "bar_",
"type": "uint256"
}
],
"name": "setBar",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "age",
"outputs": [
{
"internalType": "uint32",
"name": "",
"type": "uint32"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "bar",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "bud",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "orcl",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "peek",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
},
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "read",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"name": "slot",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "wards",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "wat",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment