Last active
May 30, 2020 04:37
-
-
Save hbarcelos/05854cb1ab91bf9024d03456241492cc to your computer and use it in GitHub Desktop.
Getting the USD/ETH price from MakerDAO feed [off-chain only]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()); | |
})(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ | |
{ | |
"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