From my experience with Harbinger I believe it's best practice to pull the data from the Normalizer contracts, as opposed to the Storage contracts. The Normalizer contract gives you a volume weighted average so you know the numbers won't be skewed.
Here's how I pulled the price feed with async/await syntax:
// Ping Oracle contract
const contract = await Tezos.contract.at(exchange ?? "KT1P7D7jt3PfjMpsEKPyao1kHQR93t7XR5zh");
// Grab contract storage
const contractStorage: { [key: string]: any } = await contract.storage();
// Get asset codes (ex: XTZ-USD, BTC-USD etc)
const { assetCodes } = contractStorage;
// Grab the computed prices from the BigMap
const assetsWithPrices = await Promise.all(
assetCodes.map(async (assetCode: string) => {
const { computedPrice } = await contractStorage["assetMap"].get(assetCode);
// Computed price comes without decimal so add decimal
const bigNumberPrice = computedPrice.c[0];
const bigNumberPriceString = bigNumberPrice.toString().split("");
bigNumberPriceString.splice(bigNumberPriceString.length - 6, 0, ".");
const price = Number(bigNumberPriceString.join("").toString());
return { [assetCode]: price };
})
);
If you'd like to see it in action you can visit https://oracles.vercel.app
The github repo for this, which includes the above code, can be found at https://github.com/sean-magin/oracles if you'd like to inspect the code closer.