UNPKG

@bithomp/xrpl-api

Version:

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

105 lines (104 loc) 4.67 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseOrderbookChanges = parseOrderbookChanges; const lodash_1 = __importDefault(require("lodash")); const bignumber_js_1 = __importDefault(require("bignumber.js")); const BigNumber = bignumber_js_1.default.clone({ DECIMAL_PLACES: 40 }); const xrpl_1 = require("xrpl"); const common_1 = require("../../common"); const models_1 = require("../../models"); const utils_1 = require("../utils"); const orderbook_quality_1 = require("./orderbook_quality"); const currency_amount_1 = __importDefault(require("../ledger/currency-amount")); const offer_flags_1 = __importDefault(require("../ledger/offer-flags")); const client_1 = require("../../client"); function getExpirationTime(node) { const expirationTime = (node.finalFields.Expiration || node.newFields.Expiration); if (expirationTime === undefined) { return undefined; } return new Date((0, models_1.ledgerTimeToTimestamp)(expirationTime)).toISOString(); } function getQuality(node) { const takerGets = (node.finalFields.TakerGets || node.newFields.TakerGets); const takerPays = (node.finalFields.TakerPays || node.newFields.TakerPays); const takerGetsCurrency = takerGets.currency || (0, client_1.getNativeCurrency)(); const takerPaysCurrency = takerPays.currency || (0, client_1.getNativeCurrency)(); const bookDirectory = (node.finalFields.BookDirectory || node.newFields.BookDirectory); const qualityHex = bookDirectory.substring(bookDirectory.length - 16); return (0, orderbook_quality_1.parseOrderbookQuality)(qualityHex, takerGetsCurrency, takerPaysCurrency); } function parseOrderStatus(node) { if (node.diffType === "CreatedNode") { return "created"; } if (node.diffType === "ModifiedNode") { return "partially-filled"; } if (node.diffType === "DeletedNode") { if (node.previousFields.hasOwnProperty("TakerPays")) { return "filled"; } return "cancelled"; } return undefined; } function calculateDelta(finalAmount, previousAmount) { if (previousAmount) { const finalValue = new BigNumber(finalAmount.value); const previousValue = new BigNumber(previousAmount.value); return finalValue.minus(previousValue).abs().toString(); } return "0"; } function parseChangeAmount(node, type) { const status = parseOrderStatus(node); if (status === "cancelled") { return (0, currency_amount_1.default)(node.finalFields[type]); } else if (status === "created") { return (0, currency_amount_1.default)(node.newFields[type]); } const finalAmount = (0, currency_amount_1.default)(node.finalFields[type]); const previousAmount = (0, currency_amount_1.default)(node.previousFields[type]); const value = calculateDelta(finalAmount, previousAmount); return lodash_1.default.assign({}, finalAmount, { value: value }); } function parseOrderChange(node) { const flags = (0, offer_flags_1.default)(node.finalFields.Flags); const takerPays = parseChangeAmount(node, "TakerPays"); const takerGets = parseChangeAmount(node, "TakerGets"); const orderChange = (0, common_1.removeUndefined)({ flags, quantity: flags.sell === true ? takerGets : takerPays, totalPrice: flags.sell === true ? takerPays : takerGets, sequence: (node.finalFields.Sequence || node.newFields.Sequence), status: parseOrderStatus(node), makerExchangeRate: getQuality(node), expirationTime: getExpirationTime(node), direction: (node.finalFields.Flags & xrpl_1.LedgerEntry.OfferFlags.lsfSell) === 0 ? "buy" : "sell", }); Object.defineProperty(orderChange, "account", { value: node.finalFields.Account || node.newFields.Account, }); return orderChange; } function groupByAddress(orderChanges) { return lodash_1.default.groupBy(orderChanges, function (change) { return change.account; }); } function parseOrderbookChanges(metadata) { const affectedNodes = metadata.AffectedNodes.filter((affectedNode) => { const node = affectedNode.CreatedNode || affectedNode.ModifiedNode || affectedNode.DeletedNode; return node.LedgerEntryType === "Offer"; }); const orderChanges = affectedNodes.map((affectedNode) => { const normalizedNode = (0, utils_1.normalizeNode)(affectedNode); return parseOrderChange(normalizedNode); }); return groupByAddress(orderChanges); }