UNPKG

@bithomp/xrpl-api

Version:

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

143 lines (142 loc) 6.16 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createPaymentTransaction = createPaymentTransaction; const lodash_1 = __importDefault(require("lodash")); const xrpl_1 = require("xrpl"); const common_1 = require("../../common"); const utils_1 = require("../utils"); const memos_1 = require("../../parse/ledger/memos"); const client_1 = require("../../client"); function isMaxAdjustment(source) { return source.maxAmount != null; } function isMinAdjustment(destination) { return destination.minAmount != null; } function isXRPToXRPPayment(payment) { const { source, destination } = payment; const sourceCurrency = isMaxAdjustment(source) ? source.maxAmount.currency : source.amount.currency; const destinationCurrency = isMinAdjustment(destination) ? destination.minAmount.currency : destination.amount.currency; return ((sourceCurrency === (0, client_1.getNativeCurrency)() || sourceCurrency === "drops") && (destinationCurrency === (0, client_1.getNativeCurrency)() || destinationCurrency === "drops")); } function isIOUWithoutCounterparty(amount) { if (typeof amount === "object") { if ("currency" in amount && amount.currency !== (0, client_1.getNativeCurrency)() && amount.currency !== "drops") { return false; } if ("mpt_issuance_id" in amount && amount.mpt_issuance_id) { return false; } if (amount.issuer == null && amount.counterparty == null) { return true; } } return false; } function applyAnyCounterpartyEncoding(payment) { [payment.source, payment.destination].forEach((adjustment) => { ["amount", "minAmount", "maxAmount"].forEach((key) => { if (isIOUWithoutCounterparty(adjustment[key])) { adjustment[key].issuer = adjustment.address; } }); }); } function createMaximalAmount(amount) { const maxXRPValue = "100000000000"; const maxIOUValue = "999999999999999900000000000000000000000000000000000000000000000000000000000000000000000000000000"; let maxValue; if (amount.currency === (0, client_1.getNativeCurrency)()) { maxValue = maxXRPValue; } else if (amount.currency === "drops") { maxValue = (0, common_1.xrpToDrops)(maxXRPValue); } else { maxValue = maxIOUValue; } return Object.assign({}, amount, { value: maxValue }); } function validateAndNormalizeAddress(address, expectedTag) { const classicAddress = (0, utils_1.getClassicAccountAndTag)(address, expectedTag); classicAddress.tag = classicAddress.tag === false ? undefined : classicAddress.tag; return classicAddress; } function createPaymentTransaction(address, paymentArgument) { const payment = lodash_1.default.cloneDeep(paymentArgument); applyAnyCounterpartyEncoding(payment); const sourceAddressAndTag = validateAndNormalizeAddress(payment.source.address, payment.source.tag); const addressToVerifyAgainst = validateAndNormalizeAddress(address, undefined); if (addressToVerifyAgainst.classicAccount !== sourceAddressAndTag.classicAccount) { throw new Error("address must match payment.source.address"); } if (addressToVerifyAgainst.tag != null && sourceAddressAndTag.tag != null && addressToVerifyAgainst.tag !== sourceAddressAndTag.tag) { throw new Error("address includes a tag that does not match payment.source.tag"); } const destinationAddressAndTag = validateAndNormalizeAddress(payment.destination.address, payment.destination.tag); if ((isMaxAdjustment(payment.source) && isMinAdjustment(payment.destination)) || (!isMaxAdjustment(payment.source) && !isMinAdjustment(payment.destination))) { throw new Error("payment must specify either (source.maxAmount " + "and destination.amount) or (source.amount and destination.minAmount)"); } const destinationAmount = isMinAdjustment(payment.destination) ? payment.destination.minAmount : payment.destination.amount; const sourceAmount = isMaxAdjustment(payment.source) ? payment.source.maxAmount : payment.source.amount; const amount = isMinAdjustment(payment.destination) && !isXRPToXRPPayment(payment) ? createMaximalAmount(destinationAmount) : destinationAmount; const txJSON = { TransactionType: "Payment", Account: sourceAddressAndTag.classicAccount, Destination: destinationAddressAndTag.classicAccount, Amount: (0, utils_1.toRippledAmount)(amount), Flags: 0, }; if (payment.invoiceID != null) { txJSON.InvoiceID = payment.invoiceID; } if (sourceAddressAndTag.tag != null) { txJSON.SourceTag = sourceAddressAndTag.tag; } if (destinationAddressAndTag.tag != null) { txJSON.DestinationTag = destinationAddressAndTag.tag; } if (payment.networkID != null) { txJSON.NetworkID = payment.networkID; } if (payment.memos != null) { txJSON.Memos = payment.memos.map(memos_1.formattedMemoToMemo); } if (payment.noDirectRipple === true) { txJSON.Flags |= xrpl_1.PaymentFlags.tfNoRippleDirect; } if (payment.limitQuality === true) { txJSON.Flags |= xrpl_1.PaymentFlags.tfLimitQuality; } if (!isXRPToXRPPayment(payment)) { if (payment.allowPartialPayment || isMinAdjustment(payment.destination)) { txJSON.Flags |= xrpl_1.PaymentFlags.tfPartialPayment; } txJSON.SendMax = (0, utils_1.toRippledAmount)(sourceAmount); if (isMinAdjustment(payment.destination)) { txJSON.DeliverMin = (0, utils_1.toRippledAmount)(destinationAmount); } if (payment.paths != null) { txJSON.Paths = JSON.parse(payment.paths); } } else if (payment.allowPartialPayment === true) { throw new Error("XRP to XRP payments cannot be partial payments"); } return txJSON; }