UNPKG

@tracer-protocol/pools-js

Version:

Javascript library for interacting with Tracer's Perpetual Pools

154 lines (128 loc) 4.68 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _types = require("@tracer-protocol/perpetual-pools-contracts/types"); var _bignumber = _interopRequireDefault(require("bignumber.js")); var _multicall = require("@0xsequence/multicall"); var _ethers = require("ethers"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const defaultSMAOracle = { updateInterval: 60 * 60, // 1 hour numPeriods: 8 }; /** * SMAOracle class constructor inputs */ /** * SMAOracle class for interacting with ERC20 tokens * The constructor is private so must be instantiated with {@linkcode SMAOracle.Create} */ class SMAOracle { // assumes all SMA oracles use spot chainlink oracle wrapper //update interval in seconds // number of periods included in SMA calc /** * @private */ constructor() { this.address = ''; this.type = undefined; this.provider = undefined; this.multicallProvider = undefined; this.updateInterval = defaultSMAOracle.updateInterval; this.numPeriods = defaultSMAOracle.numPeriods; } /** * Replacement constructor pattern to support async initialisations * @param tokenINfo {@link ISMAOracle | ISMAOracle interface props} * @returns a Promise containing an initialised SMAOracle class ready to be used */ static Create = async oracleInfo => { const oracle = new SMAOracle(); await oracle.init(oracleInfo); return oracle; }; /** * Creates an empty SMAOracle that can be used as a default * @returns default constructed token */ static CreateDefault = () => { const oracle = new SMAOracle(); return oracle; }; /** * Private initialisation function called in {@link SMAOracle.Create} * @private * @param oracleInfo {@link ISMAOracle | ISMAOracle interface props} */ init = async oracleInfo => { this.provider = oracleInfo.provider; this.multicallProvider = new _multicall.providers.MulticallProvider(oracleInfo.provider); this.address = oracleInfo.address; const contract = _types.SMAOracle__factory.connect(oracleInfo.address, this.multicallProvider); this._contract = contract; // default values (if not SMA, will assume spot and use this) let updateInterval = 0; let numPeriods = 0; let type = 'Spot'; let underlyingOracleAddress = oracleInfo.address; try { const [_updateInterval, _numPeriods, _underlyingOracleAddress] = await Promise.all([contract.updateInterval(), contract.numPeriods(), contract.oracle()]); updateInterval = _updateInterval.toNumber(); numPeriods = _numPeriods.toNumber(); type = 'SMA'; underlyingOracleAddress = _underlyingOracleAddress; } catch (error) { console.log(`failed to init sma details for oracle ${oracleInfo.address}, assuming spot oracle`); } this._underlyingOracle = _types.ChainlinkOracleWrapper__factory.connect(underlyingOracleAddress, this.multicallProvider); this.updateInterval = updateInterval; this.numPeriods = numPeriods; this.type = type; }; /** * get the latest SMA price * @returns the average of the most recent price data points */ getPrice = async () => { if (!this._contract) { throw Error("Failed to fetch oracle price: Contract not defined"); } try { const price = await this._contract.getPrice(); // OracleWrapper always scales feed decimals to 18 places return new _bignumber.default(_ethers.ethers.utils.formatEther(price)); } catch (err) { throw Error(`Failed to fetch oracle price: ${err}`); } }; /** * get the current underlying spot price * @returns the current price reported by the underlying price oracle */ getSpotPrice = async () => { if (!this._underlyingOracle) { throw Error("Failed to fetch sma spot price: underlying oracle not defined"); } try { const price = await this._underlyingOracle.getPrice(); return new _bignumber.default(_ethers.ethers.utils.formatEther(price)); } catch (err) { throw Error(`Failed to fetch underlying oracle price: ${err}`); } }; /** * Replaces the provider and connects the contract instance * @param provider The new provider to connect to */ connect = provider => { if (!provider) { throw Error("Failed to connect SMAOracle: provider cannot be undefined"); } this.provider = provider; this.multicallProvider = new _multicall.providers.MulticallProvider(provider); this._contract = this._contract?.connect(this.multicallProvider); }; } exports.default = SMAOracle;