UNPKG

@bithomp/xrpl-api

Version:

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

215 lines (214 loc) 9.02 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseAmmChanges = parseAmmChanges; const bignumber_js_1 = __importDefault(require("bignumber.js")); const common_1 = require("../../common"); const utils_1 = require("../utils"); const amount_1 = __importDefault(require("../ledger/amount")); const asset_1 = __importDefault(require("../ledger/asset")); const auth_accounts_1 = __importDefault(require("../ledger/auth-accounts")); const client_1 = require("../../client"); const models_1 = require("../../models"); function parseAmmStatus(node) { if (node.diffType === "CreatedNode") { return "created"; } if (node.diffType === "ModifiedNode") { return "modified"; } if (node.diffType === "DeletedNode") { return "deleted"; } return undefined; } function parseAuctionSlot(auctionSlot) { const slot = { account: auctionSlot.Account, authAccounts: (0, auth_accounts_1.default)(auctionSlot.AuthAccounts), discountedFee: auctionSlot.DiscountedFee, expiration: auctionSlot.Expiration ? (0, models_1.ledgerTimeToUnixTime)(auctionSlot.Expiration) : undefined, price: auctionSlot.Price, timeInterval: auctionSlot.TimeInterval, }; return (0, common_1.removeUndefined)(slot); } function parseVoteSlot(voteSlot) { return { account: voteSlot.VoteEntry.Account, tradingFee: voteSlot.VoteEntry.TradingFee, voteWeight: voteSlot.VoteEntry.VoteWeight, }; } function summarizeVoteSlotsChanges(node) { const final = node.diffType === "CreatedNode" ? node.newFields : node.finalFields; const prev = node.previousFields; const changes = final.VoteSlots.reduce((acc, slot) => { const prevSlot = prev.VoteSlots.find((s) => s.VoteEntry.Account === slot.VoteEntry.Account); if (!prevSlot) { return acc.concat({ status: "added", account: slot.VoteEntry.Account, tradingFee: slot.VoteEntry.TradingFee, voteWeight: slot.VoteEntry.VoteWeight, }); } const tradingFeeChange = slot.VoteEntry.TradingFee - prevSlot.VoteEntry.TradingFee; const voteWeightChange = slot.VoteEntry.VoteWeight - prevSlot.VoteEntry.VoteWeight; if (tradingFeeChange !== 0 || voteWeightChange !== 0) { return acc.concat((0, common_1.removeUndefined)({ status: "modified", account: slot.VoteEntry.Account, tradingFee: slot.VoteEntry.TradingFee, voteWeight: slot.VoteEntry.VoteWeight, tradingFeeChange: tradingFeeChange || undefined, voteWeightChange: voteWeightChange || undefined, })); } return acc; }, []); const removed = prev.VoteSlots.filter((s) => { return !final.VoteSlots.find((slot) => slot.VoteEntry.Account === s.VoteEntry.Account); }); if (removed.length > 0) { return changes.concat(removed.map((s) => { return { status: "removed", account: s.VoteEntry.Account, tradingFee: s.VoteEntry.TradingFee, voteWeight: s.VoteEntry.VoteWeight, }; })); } if (changes.length === 0) { return undefined; } return changes; } function summarizeActionSlotChanges(node) { const final = node.diffType === "CreatedNode" ? node.newFields : node.finalFields; const prev = node.previousFields; const changes = {}; if (prev.AuctionSlot) { if (final.AuctionSlot.Account !== prev.AuctionSlot.Account) { changes.accountChanges = final.AuctionSlot.Account; } if (final.AuctionSlot.DiscountedFee !== prev.AuctionSlot.DiscountedFee) { changes.discountedFeeChange = final.AuctionSlot.DiscountedFee - prev.AuctionSlot.DiscountedFee; } if (final.AuctionSlot.Expiration !== prev.AuctionSlot.Expiration) { changes.expirationChange = final.AuctionSlot.Expiration - prev.AuctionSlot.Expiration; } if (final.AuctionSlot.Price.value !== prev.AuctionSlot.Price.value) { changes.priceChange = { currency: final.AuctionSlot.Price.currency, issuer: final.AuctionSlot.Price.issuer, value: new bignumber_js_1.default(final.AuctionSlot.Price.value) .minus(new bignumber_js_1.default(prev.AuctionSlot.Price.value)) .toString(10), counterparty: final.AuctionSlot.Price.issuer, }; } if (final.AuctionSlot.TimeInterval !== prev.AuctionSlot.TimeInterval) { changes.timeIntervalChange = final.AuctionSlot.TimeInterval - prev.AuctionSlot.TimeInterval; } if (!isEqualAuthAccounts(final.AuctionSlot.AuthAccounts, prev.AuctionSlot.AuthAccounts)) { const prevAuthAccounts = prev.AuctionSlot.AuthAccounts || []; const finalAuthAccounts = final.AuctionSlot.AuthAccounts || []; let authAccountsChanges = finalAuthAccounts.map((auth) => { if (!prevAuthAccounts.includes(auth.AuthAccount.Account)) { return { status: "added", account: auth.AuthAccount.Account, }; } }); const removed = prevAuthAccounts.filter((auth) => { return !finalAuthAccounts.includes(auth.AuthAccount.Account); }); if (removed.length > 0) { authAccountsChanges = authAccountsChanges.concat(removed.map((account) => { return { status: "removed", account: account.AuthAccount.Account, }; })); } changes.authAccountsChanges = authAccountsChanges; } } if (Object.keys(changes).length === 0) { return undefined; } return (0, common_1.removeUndefined)(changes); } function isEqualAuthAccounts(obj1, obj2) { if (obj1 === undefined && obj2 === undefined) { return true; } if ((obj1 === undefined && obj2 !== undefined) || (obj1 !== undefined && obj2 === undefined)) { return false; } if (obj1.length !== obj2.length) { return false; } const obj1Sorted = obj1.sort((a, b) => a.AuthAccount.Account.localeCompare(b.AuthAccount.Account)); const obj2Sorted = obj2.sort((a, b) => a.AuthAccount.Account.localeCompare(b.AuthAccount.Account)); for (let i = 0; i < obj1Sorted.length; i++) { if (obj1Sorted[i].AuthAccount.Account !== obj2Sorted[i].AuthAccount.Account) { return false; } } return true; } function summarizeAmm(node) { const final = node.diffType === "CreatedNode" ? node.newFields : node.finalFields; const prev = node.previousFields; let asset = (0, asset_1.default)(final.Asset); if (node.diffType === "CreatedNode" && !asset) { asset = { currency: (0, client_1.getNativeCurrency)() }; } const summary = { status: parseAmmStatus(node), ammID: node.ledgerIndex, account: final.Account, asset: asset, asset2: (0, asset_1.default)(final.Asset2), auctionSlot: parseAuctionSlot(final.AuctionSlot), lpTokenBalance: (0, amount_1.default)(final.LPTokenBalance), tradingFee: final.TradingFee, ownerNode: final.OwnerNode, voteSlots: final.VoteSlots ? final.VoteSlots.map(parseVoteSlot) : undefined, }; if (prev.LPTokenBalance) { summary.lpTokenBalanceChange = { currency: final.LPTokenBalance.currency, issuer: final.LPTokenBalance.issuer, value: new bignumber_js_1.default(final.LPTokenBalance.value).minus(new bignumber_js_1.default(prev.LPTokenBalance.value)).toString(10), counterparty: final.LPTokenBalance.issuer, }; } if (prev.VoteSlots) { summary.voteSlotsChanges = summarizeVoteSlotsChanges(node); } if (prev.TradingFee) { summary.tradingFeeChanges = final.TradingFee - (prev.TradingFee || 0); } if (prev.AuctionSlot) { summary.auctionSlotChanges = summarizeActionSlotChanges(node); } return (0, common_1.removeUndefined)(summary); } function parseAmmChanges(metadata) { const affectedNodes = metadata.AffectedNodes.filter((affectedNode) => { const node = affectedNode.CreatedNode || affectedNode.ModifiedNode || affectedNode.DeletedNode; return node.LedgerEntryType === "AMM"; }); if (affectedNodes.length !== 1) { return undefined; } const normalizedNode = (0, utils_1.normalizeNode)(affectedNodes[0]); return summarizeAmm(normalizedNode); }