UNPKG

@iexec/iexec-oracle-factory-wrapper

Version:
99 lines 4.35 kB
import { ethers } from 'ethers'; import { getReaderDefaults } from '../config/config.js'; import { READ_ABI } from '../config/contract.js'; import { NoValueError, ValidationError, WorkflowError, } from '../utils/errors.js'; import { formatOracleGetNumber } from '../utils/format.js'; import { computeOracleId, isOracleId } from '../utils/hash.js'; import { getParamSet } from '../utils/utils.js'; import { readDataTypeSchema } from '../utils/validators.js'; /** * Reads data from an oracle based on the provided parameters. * @param paramSetOrCidOrOracleId Param set, CID, or oracle ID. * @param dataType Type of data to read. * @param ethersProvider Ethereum provider. * @param ipfsGateway IPFS gateway URL. * @param oracleContract Address of the oracle contract. * @returns Promise resolving to the Oracle data. * @throws {NoValueError} If no value is stored for the oracle. * @throws {ValidationError} If there is a validation error. * @throws {WorkflowError} If there is an unexpected workflow error. */ const readOracle = async ({ paramSetOrCidOrOracleId, dataType, ethersProvider, ipfsGateway, oracleContract, }) => { const chainId = await ethersProvider .getNetwork() .then((res) => `${res.chainId}`); const ORACLE_CONTRACT_ADDRESS = oracleContract || getReaderDefaults(Number(chainId)).ORACLE_CONTRACT_ADDRESS; let readDataType; let oracleId; if (isOracleId(paramSetOrCidOrOracleId)) { oracleId = paramSetOrCidOrOracleId; readDataType = await readDataTypeSchema().validate(!dataType ? 'raw' : dataType); } else { if (dataType) { throw Error('dataType option is only allowed when reading oracle from oracleId'); } const { paramSet } = await getParamSet({ paramSetOrCid: paramSetOrCidOrOracleId, ipfsGateway, }).catch((e) => { if (e instanceof ValidationError) { throw e; } else { throw new WorkflowError({ message: 'Failed to load paramSet', errorCause: e, }); } }); readDataType = paramSet.dataType; oracleId = await computeOracleId(paramSet); } const oracleSmartContract = new ethers.Contract(ORACLE_CONTRACT_ADDRESS, READ_ABI, ethersProvider); const [rawValue, rawDateBn] = await oracleSmartContract .getRaw(oracleId) .catch(() => { throw Error(`Failed to read value from oracle with oracleId ${oracleId}`); }); const rawDateNumber = parseInt(rawDateBn.toString()); if (rawDateNumber == 0) { throw new NoValueError(`No value stored for oracleId ${oracleId}`); } switch (readDataType) { case 'boolean': { const [result, dateBn] = await oracleSmartContract .getBool(oracleId) .catch(() => { throw Error(`Failed to read boolean from oracle with oracleId ${oracleId}\nThis may occur when:\n- No value is stored\n- Stored value is not boolean dataType`); }); return { value: result, date: parseInt(dateBn.toString()) }; } case 'number': { const [resultBn, dateBn] = await oracleSmartContract .getInt(oracleId) .catch(() => { throw Error(`Failed to read number from oracle with oracleId ${oracleId}\nThis may occur when:\n- No value is stored\n- Stored value is not number dataType`); }); const resultNumber = formatOracleGetNumber(resultBn); return { value: resultNumber, date: parseInt(dateBn.toString()) }; } case 'string': { const [resultString, dateBn] = await oracleSmartContract .getString(oracleId) .catch(() => { throw Error(`Failed to read string from oracle with oracleId ${oracleId}\nThis may occur when:\n- No value is stored\n- Stored value is not string dataType`); }); return { value: resultString, date: parseInt(dateBn.toString()) }; } default: { return { value: rawValue, date: rawDateNumber, }; } } }; export { readOracle }; //# sourceMappingURL=readOracle.js.map