UNPKG

@bithomp/xrpl-api

Version:

A Bithomp JavaScript/TypeScript library for interacting with the XRP Ledger

151 lines (150 loc) 6.42 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseOracleChanges = parseOracleChanges; exports.parsePriceDataSeries = parsePriceDataSeries; const bignumber_js_1 = __importDefault(require("bignumber.js")); const utils_1 = require("../utils"); const common_1 = require("../../common"); function parseOracleStatus(node) { if (node.diffType === "CreatedNode") { return "created"; } if (node.diffType === "ModifiedNode") { return "modified"; } if (node.diffType === "DeletedNode") { return "deleted"; } return undefined; } function hexPriceToBigNumber(hex) { if (hex === undefined) { return undefined; } if (typeof hex !== "string") { throw new Error("Price must be a string."); } return new bignumber_js_1.default(`0x${hex}`); } function getOriginalAssetPrice(assetPrice, scale) { if (assetPrice === undefined) { return undefined; } if (assetPrice.isZero()) { return assetPrice; } if (scale === 0 || scale === undefined) { return assetPrice; } return assetPrice.dividedBy(new bignumber_js_1.default(10).pow(scale)); } function parsePriceDataSeries(series) { const assetPrice = hexPriceToBigNumber(series.PriceData.AssetPrice); const scale = series.PriceData.Scale; const originalAssetPrice = getOriginalAssetPrice(assetPrice, scale); return (0, common_1.removeUndefined)({ baseAsset: series.PriceData.BaseAsset, quoteAsset: series.PriceData.QuoteAsset, assetPrice: assetPrice?.toString(), scale: series.PriceData.Scale, originalAssetPrice: originalAssetPrice?.toString(), }); } function summarizePriceDataSeriesChanges(node) { const final = node.diffType === "CreatedNode" ? node.newFields : node.finalFields; const prev = node.previousFields; const changes = final.PriceDataSeries.reduce((acc, series) => { const prevSeries = prev.PriceDataSeries.find((s) => s.PriceData.BaseAsset === series.PriceData.BaseAsset && s.PriceData.QuoteAsset === series.PriceData.QuoteAsset); const priceFinal = hexPriceToBigNumber(series.PriceData.AssetPrice) || new bignumber_js_1.default(0); const scaleFinal = series.PriceData.Scale || 0; const originalPriceFinal = getOriginalAssetPrice(priceFinal, scaleFinal); if (!prevSeries) { return acc.concat({ status: "added", baseAsset: series.PriceData.BaseAsset, quoteAsset: series.PriceData.QuoteAsset, assetPrice: priceFinal?.toString(), scale: scaleFinal, originalAssetPrice: originalPriceFinal?.toString(), }); } const pricePrev = hexPriceToBigNumber(prevSeries.PriceData.AssetPrice) || new bignumber_js_1.default(0); const scalePrev = prevSeries.PriceData.Scale || 0; const assetPriceChange = (priceFinal || new bignumber_js_1.default(0)).minus(pricePrev); const scaleChange = (scaleFinal ?? 0) - scalePrev; if (!assetPriceChange.isZero() || scaleChange !== 0) { const originalPricePrev = getOriginalAssetPrice(pricePrev, scalePrev) || new bignumber_js_1.default(0); const originalPriceChange = (originalPriceFinal || new bignumber_js_1.default(0)).minus(originalPricePrev); return acc.concat((0, common_1.removeUndefined)({ status: "modified", baseAsset: series.PriceData.BaseAsset, quoteAsset: series.PriceData.QuoteAsset, assetPrice: priceFinal?.toString(), scale: scaleFinal, originalAssetPrice: originalPriceFinal?.toString(), assetPriceChange: assetPriceChange.isZero() ? undefined : assetPriceChange?.toString(), scaleChange: scaleChange || undefined, originalPriceChange: originalPriceChange.isZero() ? undefined : originalPriceChange.toString(), })); } return acc; }, []); const removed = prev.PriceDataSeries.filter((s) => { return !final.PriceDataSeries.find((series) => series.PriceData.BaseAsset === s.PriceData.BaseAsset && series.PriceData.QuoteAsset === s.PriceData.QuoteAsset); }); if (removed.length > 0) { return changes.concat(removed.map((s) => { const price = hexPriceToBigNumber(s.PriceData.AssetPrice); return { status: "removed", baseAsset: s.PriceData.BaseAsset, quoteAsset: s.PriceData.QuoteAsset, assetPrice: price?.toString(), scale: s.PriceData.Scale, originalAssetPrice: getOriginalAssetPrice(price, s.PriceData.Scale), }; })); } if (changes.length === 0) { return undefined; } return changes; } function summarizeOracle(node) { const final = node.diffType === "CreatedNode" ? node.newFields : node.finalFields; const prev = node.previousFields; const summary = { status: parseOracleStatus(node), oracleID: node.ledgerIndex, oracleDocumentID: final.OracleDocumentID, provider: final.Provider, uri: final.URI, assetClass: final.AssetClass, lastUpdateTime: final.LastUpdateTime, priceDataSeries: final.PriceDataSeries.map(parsePriceDataSeries), }; if (prev.URI) { summary.uriChanges = final.URI; } if (prev.LastUpdateTime) { summary.lastUpdateTimeChanges = final.LastUpdateTime - (prev.LastUpdateTime || 0); } if (prev.PriceDataSeries) { summary.priceDataSeriesChanges = summarizePriceDataSeriesChanges(node); } return (0, common_1.removeUndefined)(summary); } function parseOracleChanges(metadata) { const affectedNodes = metadata.AffectedNodes.filter((affectedNode) => { const node = affectedNode.CreatedNode || affectedNode.ModifiedNode || affectedNode.DeletedNode; return node.LedgerEntryType === "Oracle"; }); if (affectedNodes.length !== 1) { return undefined; } const normalizedNode = (0, utils_1.normalizeNode)(affectedNodes[0]); return summarizeOracle(normalizedNode); }