diff --git a/src/models/transactions/metadata.ts b/src/models/transactions/metadata.ts index e1bf03f2..92e784f7 100644 --- a/src/models/transactions/metadata.ts +++ b/src/models/transactions/metadata.ts @@ -12,8 +12,8 @@ interface ModifiedNode { ModifiedNode: { LedgerEntryType: string LedgerIndex: string - FinalFields: { [field: string]: unknown } - PreviousFields: { [field: string]: unknown } + FinalFields?: { [field: string]: unknown } + PreviousFields?: { [field: string]: unknown } PreviousTxnID?: string PreviouTxnLgrSeq?: number } @@ -27,12 +27,13 @@ interface DeletedNode { } } -type Node = CreatedNode | ModifiedNode | DeletedNode +export type Node = CreatedNode | ModifiedNode | DeletedNode export default interface TransactionMetadata { AffectedNodes: Node[] DeliveredAmount?: Amount - delivered_amount?: Amount + // "unavailable" possible for transactions before 2014-01-20 + delivered_amount?: Amount | 'unavailable' TransactionIndex: number TransactionResult: string } diff --git a/src/utils/balanceChanges.ts b/src/utils/balanceChanges.ts new file mode 100644 index 00000000..c754d162 --- /dev/null +++ b/src/utils/balanceChanges.ts @@ -0,0 +1,183 @@ +import BigNumber from 'bignumber.js' +import _ from 'lodash' + +import { Amount, IssuedCurrencyAmount } from '../models/common' +import TransactionMetadata, { Node } from '../models/transactions/metadata' + +import { dropsToXrp } from './xrpConversion' + +interface Balance { + currency: string + issuer?: string + value: string +} + +interface BalanceChange { + account: string + balance: Balance +} + +interface BalanceChanges { + account: string + balances: Balance[] +} + +interface Fields { + Account?: string + Balance?: Amount + LowLimit?: IssuedCurrencyAmount + HighLimit?: IssuedCurrencyAmount + // eslint-disable-next-line @typescript-eslint/member-ordering -- okay here, just some of the fields are typed to make it easier + [field: string]: unknown +} + +interface NormalizedNode { + // 'CreatedNode' | 'ModifiedNode' | 'DeletedNode' + NodeType: string + LedgerEntryType: string + LedgerIndex: string + NewFields?: Fields + FinalFields?: Fields + PreviousFields?: Fields + PreviousTxnID?: string + PreviouTxnLgrSeq?: number +} + +function normalizeNode(affectedNode: Node): NormalizedNode { + const diffType = Object.keys(affectedNode)[0] + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- not quite right, but close enough + const node = affectedNode[diffType] as NormalizedNode + return { + ...node, + NodeType: diffType, + LedgerEntryType: node.LedgerEntryType, + LedgerIndex: node.LedgerIndex, + NewFields: node.NewFields, + FinalFields: node.FinalFields, + PreviousFields: node.PreviousFields, + } +} + +function normalizeNodes(metadata: TransactionMetadata): NormalizedNode[] { + if (metadata.AffectedNodes.length === 0) { + return [] + } + return metadata.AffectedNodes.map(normalizeNode) +} + +function groupByAccount(balanceChanges: BalanceChange[]): BalanceChanges[] { + const grouped = _.groupBy(balanceChanges, (node) => node.account) + return Object.entries(grouped).map(([account, items]) => { + return { account, balances: items.map((item) => item.balance) } + }) +} + +function getValue(balance: Amount): BigNumber { + if (typeof balance === 'string') { + return new BigNumber(balance) + } + return new BigNumber(balance.value) +} + +function computeBalanceChange(node: NormalizedNode): BigNumber | null { + let value: BigNumber | null = null + if (node.NewFields?.Balance) { + value = getValue(node.NewFields.Balance) + } else if (node.PreviousFields?.Balance && node.FinalFields?.Balance) { + value = getValue(node.FinalFields.Balance).minus( + getValue(node.PreviousFields.Balance), + ) + } + if (value === null || value.isZero()) { + return null + } + return value +} + +function getXRPQuantity( + node: NormalizedNode, +): { account: string; balance: Balance } | null { + const value = computeBalanceChange(node) + + if (value === null) { + return null + } + + return { + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- okay here + account: (node.FinalFields?.Account ?? node.NewFields?.Account) as string, + balance: { + currency: 'XRP', + value: dropsToXrp(value).toString(), + }, + } +} + +function flipTrustlinePerspective(balanceChange: BalanceChange): BalanceChange { + const negatedBalance = new BigNumber(balanceChange.balance.value).negated() + return { + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- we know this is true + account: balanceChange.balance.issuer as string, + balance: { + issuer: balanceChange.account, + currency: balanceChange.balance.currency, + value: negatedBalance.toString(), + }, + } +} + +function getTrustlineQuantity(node: NormalizedNode): BalanceChange[] | null { + const value = computeBalanceChange(node) + + if (value === null) { + return null + } + + // A trustline can be created with a non-zero starting balance + // If an offer is placed to acquire an asset with no existing trustline, + // the trustline can be created when the offer is taken. + const fields = node.NewFields == null ? node.FinalFields : node.NewFields + + // the balance is always from low node's perspective + const result = { + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- we know that this is true + account: fields?.LowLimit?.issuer as string, + balance: { + issuer: fields?.HighLimit?.issuer, + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- we know that this is true + currency: (fields?.Balance as IssuedCurrencyAmount).currency, + value: value.toString(), + }, + } + return [result, flipTrustlinePerspective(result)] +} + +/** + * Computes the complete list of every balance that changed in the ledger + * as a result of the given transaction. + * + * @param metadata - Transaction metada. + * @returns Parsed balance changes. + */ +export default function getBalanceChanges( + metadata: TransactionMetadata, +): BalanceChanges[] { + const quantities = normalizeNodes(metadata).map((node) => { + if (node.LedgerEntryType === 'AccountRoot') { + const xrpQuantity = getXRPQuantity(node) + if (xrpQuantity == null) { + return [] + } + return [xrpQuantity] + } + if (node.LedgerEntryType === 'RippleState') { + const trustlineQuantity = getTrustlineQuantity(node) + if (trustlineQuantity == null) { + return [] + } + return trustlineQuantity + } + return [] + }) + return groupByAccount(_.flatten(quantities)) +} diff --git a/src/utils/index.ts b/src/utils/index.ts index 1beb3d7c..44d4e5a6 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -15,6 +15,7 @@ import { xAddressToClassicAddress, } from 'ripple-address-codec' +import getBalanceChanges from './balanceChanges' import { deriveKeypair, deriveXAddress } from './derive' import { generateXAddress } from './generateAddress' import { @@ -97,6 +98,7 @@ function convertStringToHex(string: string): string { } export { + getBalanceChanges, dropsToXrp, xrpToDrops, removeUndefined, diff --git a/test/fixtures/utils/paymentToken.json b/test/fixtures/utils/paymentToken.json new file mode 100644 index 00000000..6ed1c600 --- /dev/null +++ b/test/fixtures/utils/paymentToken.json @@ -0,0 +1,123 @@ +{ + "engine_result": "tesSUCCESS", + "engine_result_code": 0, + "engine_result_message": "The transaction was applied.", + "ledger_hash": "F3F1416BF2E813396AB01FAA38E9F1023AC4D2368D94B0D52B2BC603CEEC01C3", + "ledger_index": 10459371, + "status": "closed", + "type": "transaction", + "validated": true, + "metadata": { + "AffectedNodes": [ + { + "ModifiedNode": { + "FinalFields": { + "Balance": { + "currency": "USD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value": "1.525330905250352" + }, + "Flags": 1114112, + "HighLimit": { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0" + }, + "HighNode": "00000000000001E8", + "LowLimit": { + "currency": "USD", + "issuer": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "value": "1000000000" + }, + "LowNode": "0000000000000000" + }, + "LedgerEntryType": "RippleState", + "LedgerIndex": "2F323020B4288ACD4066CC64C89DAD2E4D5DFC2D44571942A51C005BF79D6E25", + "PreviousFields": { + "Balance": { + "currency": "USD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value": "1.535330905250352" + } + }, + "PreviousTxnID": "DC061E6F47B1B6E9A496A31B1AF87194B4CB24B2EBF8A59F35E31E12509238BD", + "PreviousTxnLgrSeq": 10459364 + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Balance": { + "currency": "USD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value": "0.02" + }, + "Flags": 1114112, + "HighLimit": { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0" + }, + "HighNode": "00000000000001E8", + "LowLimit": { + "currency": "USD", + "issuer": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "value": "1000000000" + }, + "LowNode": "0000000000000000" + }, + "LedgerEntryType": "RippleState", + "LedgerIndex": "AAE13AF5192EFBFD49A8EEE5869595563FEB73228C0B38FED9CC3D20EE74F399", + "PreviousFields": { + "Balance": { + "currency": "USD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value": "0.01" + } + }, + "PreviousTxnID": "DC061E6F47B1B6E9A496A31B1AF87194B4CB24B2EBF8A59F35E31E12509238BD", + "PreviousTxnLgrSeq": 10459364 + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Account": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "Balance": "239555992", + "Flags": 0, + "OwnerCount": 1, + "Sequence": 38 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "E9A39B0BA8703D5FFD05D9EAD01EE6C0E7A15CF33C2C6B7269107BD2BD535818", + "PreviousFields": { + "Balance": "239567992", + "Sequence": 37 + }, + "PreviousTxnID": "DC061E6F47B1B6E9A496A31B1AF87194B4CB24B2EBF8A59F35E31E12509238BD", + "PreviousTxnLgrSeq": 10459364 + } + } + ], + "TransactionIndex": 2, + "TransactionResult": "tesSUCCESS" + }, + "tx_json": { + "Account": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "Amount": { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0.01" + }, + "Destination": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "Fee": "12000", + "Flags": 2147483648, + "LastLedgerSequence": 10459379, + "Sequence": 37, + "SigningPubKey": "03F16A52EBDCA6EBF5D99828E1E6918C64D45E6F136476A8F4757512FE553D18F0", + "TransactionType": "Payment", + "TxnSignature": "3044022031D6AB55CDFD17E06DA0BAD6D6B7DC9B5CA8FFF50405F2FCD3ED8D3893B1835E02200524CC1E7D70AE3F00C9F94405C55EE179C363F534905168AE8B5BA01CF568A0", + "date": 471644150, + "hash": "34671C179737CC89E0F8BBAA83C313885ED1733488FC0F3088BAE16A3D9A5B1B" + } +} diff --git a/test/fixtures/utils/paymentTokenDestinationNoBalance.json b/test/fixtures/utils/paymentTokenDestinationNoBalance.json new file mode 100644 index 00000000..aabf8cf0 --- /dev/null +++ b/test/fixtures/utils/paymentTokenDestinationNoBalance.json @@ -0,0 +1,123 @@ +{ + "engine_result": "tesSUCCESS", + "engine_result_code": 0, + "engine_result_message": "The transaction was applied.", + "ledger_hash": "1B549453005A924A4EEF6DA9E1BA7D8D1E51D7B685CE8DE072667321FBA792C8", + "ledger_index": 10425094, + "status": "closed", + "type": "transaction", + "validated": true, + "metadata": { + "AffectedNodes": [ + { + "ModifiedNode": { + "FinalFields": { + "Balance": { + "currency": "USD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value": "1.535330905250352" + }, + "Flags": 1114112, + "HighLimit": { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0" + }, + "HighNode": "00000000000001E8", + "LowLimit": { + "currency": "USD", + "issuer": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "value": "1000000000" + }, + "LowNode": "0000000000000000" + }, + "LedgerEntryType": "RippleState", + "LedgerIndex": "2F323020B4288ACD4066CC64C89DAD2E4D5DFC2D44571942A51C005BF79D6E25", + "PreviousFields": { + "Balance": { + "currency": "USD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value": "1.545330905250352" + } + }, + "PreviousTxnID": "CEB7B6040C2989B9849C8D7E49F710457EDDE1D95ECDF1E298FD30CF2AC5BE11", + "PreviousTxnLgrSeq": 10424776 + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Balance": { + "currency": "USD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value": "0.01" + }, + "Flags": 1114112, + "HighLimit": { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0" + }, + "HighNode": "00000000000001E8", + "LowLimit": { + "currency": "USD", + "issuer": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "value": "1000000000" + }, + "LowNode": "0000000000000000" + }, + "LedgerEntryType": "RippleState", + "LedgerIndex": "AAE13AF5192EFBFD49A8EEE5869595563FEB73228C0B38FED9CC3D20EE74F399", + "PreviousFields": { + "Balance": { + "currency": "USD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value": "0" + } + }, + "PreviousTxnID": "A788447CF5FD7108CBF49416E2335F95ED3F5A9FC016686C8F9EFB34BBEA613A", + "PreviousTxnLgrSeq": 10425088 + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Account": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "Balance": "239807992", + "Flags": 0, + "OwnerCount": 1, + "Sequence": 17 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "E9A39B0BA8703D5FFD05D9EAD01EE6C0E7A15CF33C2C6B7269107BD2BD535818", + "PreviousFields": { + "Balance": "239819992", + "Sequence": 16 + }, + "PreviousTxnID": "3109F5A0F891CCA20B4D891EB7437973F40A7664C5176092EB2E5C0A949992AD", + "PreviousTxnLgrSeq": 10424942 + } + } + ], + "TransactionIndex": 3, + "TransactionResult": "tesSUCCESS" + }, + "tx_json": { + "Account": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "Amount": { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0.01" + }, + "Destination": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "Fee": "12000", + "Flags": 2147483648, + "LastLedgerSequence": 10425102, + "Sequence": 16, + "SigningPubKey": "03F16A52EBDCA6EBF5D99828E1E6918C64D45E6F136476A8F4757512FE553D18F0", + "TransactionType": "Payment", + "TxnSignature": "3044022017DC45606103FF2CCE5D63E340D1E2B302BE16C206673B99712058CA0DBD2CC5022074A19CF5AF9CDFCEC821650A4C22E83E49E14956E1F2A094181E8E14F6881200", + "date": 471494760, + "hash": "D038C9D95926EACAA9FBDF3E6CA0675ACF1700B3CE13FF4CA52B463B58860BBA" + } +} diff --git a/test/fixtures/utils/paymentTokenMultipath.json b/test/fixtures/utils/paymentTokenMultipath.json new file mode 100644 index 00000000..4ba29adf --- /dev/null +++ b/test/fixtures/utils/paymentTokenMultipath.json @@ -0,0 +1,287 @@ +{ + "result" : { + "Account" : "r4nmQNH4Fhjfh6cHDbvVSsBv7KySbj4cBf", + "Amount" : { + "currency" : "USD", + "issuer" : "rnYDWQaRdMb5neCGgvFfhw3MBoxmv5LtfH", + "value" : "300" + }, + "Destination" : "rnYDWQaRdMb5neCGgvFfhw3MBoxmv5LtfH", + "Fee" : "10", + "Flags" : 0, + "Paths" : [ + [ + { + "account" : "rJsaPnGdeo7BhMnHjuc3n44Mf7Ra1qkSVJ", + "currency" : "USD", + "issuer" : "rJsaPnGdeo7BhMnHjuc3n44Mf7Ra1qkSVJ", + "type" : 49, + "type_hex" : "0000000000000031" + } + ], + [ + { + "account" : "rGpeQzUWFu4fMhJHZ1Via5aqFC3A5twZUD", + "currency" : "USD", + "issuer" : "rGpeQzUWFu4fMhJHZ1Via5aqFC3A5twZUD", + "type" : 49, + "type_hex" : "0000000000000031" + } + ], + [ + { + "account" : "rrnsYgWn13Z28GtRgznrSUsLfMkvsXCZSu", + "currency" : "USD", + "issuer" : "rrnsYgWn13Z28GtRgznrSUsLfMkvsXCZSu", + "type" : 49, + "type_hex" : "0000000000000031" + } + ] + ], + "Sequence" : 4, + "SigningPubKey" : "0324CAAFA2212D2AEAB9D42D481535614AED486293E1FB1380FF070C3DD7FB4264", + "TransactionType" : "Payment", + "TxnSignature" : "3044022007192E2113C236D541BA72FE628F2BDAA467120F3F61F588B63023E4EAE79E06022051813E7809F3DB07B29AEA65D61C1DD1B830C130840A15A67718ADC6FD94C44B", + "date" : 472608260, + "hash" : "029E6CF9C7962A324BD52A90732184991309DD964E7E8B2D52CAF138CB92CB29", + "inLedger" : 8, + "ledger_index" : 8, + "meta" : { + "AffectedNodes" : [ + { + "ModifiedNode" : { + "FinalFields" : { + "Balance" : { + "currency" : "USD", + "issuer" : "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value" : "0" + }, + "Flags" : 131072, + "HighLimit" : { + "currency" : "USD", + "issuer" : "r4nmQNH4Fhjfh6cHDbvVSsBv7KySbj4cBf", + "value" : "100" + }, + "HighNode" : "0000000000000000", + "LowLimit" : { + "currency" : "USD", + "issuer" : "rrnsYgWn13Z28GtRgznrSUsLfMkvsXCZSu", + "value" : "0" + }, + "LowNode" : "0000000000000000" + }, + "LedgerEntryType" : "RippleState", + "LedgerIndex" : "1AC76982771D3660656D83FA7CCE8E833C42DA797BECAAB30F36D6EEF73BE91B", + "PreviousFields" : { + "Balance" : { + "currency" : "USD", + "issuer" : "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value" : "-100" + } + }, + "PreviousTxnID" : "5E732D1DCC74EC0A5658FADC3B0FF7BBDDB83F630A04527A82DB671B04180FAD", + "PreviousTxnLgrSeq" : 5 + } + }, + { + "ModifiedNode" : { + "FinalFields" : { + "Account" : "r4nmQNH4Fhjfh6cHDbvVSsBv7KySbj4cBf", + "Balance" : "999999990", + "Flags" : 0, + "OwnerCount" : 3, + "Sequence" : 5 + }, + "LedgerEntryType" : "AccountRoot", + "LedgerIndex" : "5302F37F1D9290D8D92A31651FF71531504183695C2C43EC136B1CF4AC7E08FA", + "PreviousFields" : { + "Balance" : "1000000000", + "Sequence" : 4 + }, + "PreviousTxnID" : "60357254ABC66B61EA9B13851A2862B55D7B5CF4EBE1D5682E95EBE217037B3A", + "PreviousTxnLgrSeq" : 4 + } + }, + { + "ModifiedNode" : { + "FinalFields" : { + "Balance" : { + "currency" : "USD", + "issuer" : "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value" : "0" + }, + "Flags" : 131072, + "HighLimit" : { + "currency" : "USD", + "issuer" : "r4nmQNH4Fhjfh6cHDbvVSsBv7KySbj4cBf", + "value" : "100" + }, + "HighNode" : "0000000000000000", + "LowLimit" : { + "currency" : "USD", + "issuer" : "rJsaPnGdeo7BhMnHjuc3n44Mf7Ra1qkSVJ", + "value" : "0" + }, + "LowNode" : "0000000000000000" + }, + "LedgerEntryType" : "RippleState", + "LedgerIndex" : "9D9CE283FB821F2A2DA5BCA55DFB2FD7758D129F3060B1F7834B7784AF4CD15C", + "PreviousFields" : { + "Balance" : { + "currency" : "USD", + "issuer" : "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value" : "-100" + } + }, + "PreviousTxnID" : "84EE2961C88A4B87A0F234CDF4C66BB488781DA2FF823814381473B40875C2AA", + "PreviousTxnLgrSeq" : 5 + } + }, + { + "ModifiedNode" : { + "FinalFields" : { + "Balance" : { + "currency" : "USD", + "issuer" : "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value" : "0" + }, + "Flags" : 131072, + "HighLimit" : { + "currency" : "USD", + "issuer" : "r4nmQNH4Fhjfh6cHDbvVSsBv7KySbj4cBf", + "value" : "100" + }, + "HighNode" : "0000000000000000", + "LowLimit" : { + "currency" : "USD", + "issuer" : "rGpeQzUWFu4fMhJHZ1Via5aqFC3A5twZUD", + "value" : "0" + }, + "LowNode" : "0000000000000000" + }, + "LedgerEntryType" : "RippleState", + "LedgerIndex" : "C5F104A35DB835AF4A4C4664BCDA57A88873DCEF23DF567485654FAEE5645949", + "PreviousFields" : { + "Balance" : { + "currency" : "USD", + "issuer" : "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value" : "-100" + } + }, + "PreviousTxnID" : "CC0817117A0C9055E26FB2E482AC0EF8B4321D874D55428F5F22DEAEE18E0931", + "PreviousTxnLgrSeq" : 5 + } + }, + { + "ModifiedNode" : { + "FinalFields" : { + "Balance" : { + "currency" : "USD", + "issuer" : "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value" : "100" + }, + "Flags" : 65536, + "HighLimit" : { + "currency" : "USD", + "issuer" : "rJsaPnGdeo7BhMnHjuc3n44Mf7Ra1qkSVJ", + "value" : "0" + }, + "HighNode" : "0000000000000000", + "LowLimit" : { + "currency" : "USD", + "issuer" : "rnYDWQaRdMb5neCGgvFfhw3MBoxmv5LtfH", + "value" : "1000" + }, + "LowNode" : "0000000000000000" + }, + "LedgerEntryType" : "RippleState", + "LedgerIndex" : "CC07E55B7114FAD14663E5BDD16458E3EFA300C2C139E4E0FC9E2635E3D8099E", + "PreviousFields" : { + "Balance" : { + "currency" : "USD", + "issuer" : "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value" : "0" + } + }, + "PreviousTxnID" : "8A8DE047F4A1886A2A1E8231AE3D66D162BA0ADD00B781CAAFF946F104474E63", + "PreviousTxnLgrSeq" : 4 + } + }, + { + "ModifiedNode" : { + "FinalFields" : { + "Balance" : { + "currency" : "USD", + "issuer" : "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value" : "-100" + }, + "Flags" : 131072, + "HighLimit" : { + "currency" : "USD", + "issuer" : "rnYDWQaRdMb5neCGgvFfhw3MBoxmv5LtfH", + "value" : "1000" + }, + "HighNode" : "0000000000000000", + "LowLimit" : { + "currency" : "USD", + "issuer" : "rrnsYgWn13Z28GtRgznrSUsLfMkvsXCZSu", + "value" : "0" + }, + "LowNode" : "0000000000000000" + }, + "LedgerEntryType" : "RippleState", + "LedgerIndex" : "FBCA655A6C287E90234BF96E8CF950B8B0DE4438C95F408A0E55D256EA2A8DD1", + "PreviousFields" : { + "Balance" : { + "currency" : "USD", + "issuer" : "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value" : "0" + } + }, + "PreviousTxnID" : "CDF04C313E841ACA1103B3E2D360E5EB18236808D281B645A2BC72426FDC8EA6", + "PreviousTxnLgrSeq" : 4 + } + }, + { + "ModifiedNode" : { + "FinalFields" : { + "Balance" : { + "currency" : "USD", + "issuer" : "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value" : "100" + }, + "Flags" : 65536, + "HighLimit" : { + "currency" : "USD", + "issuer" : "rGpeQzUWFu4fMhJHZ1Via5aqFC3A5twZUD", + "value" : "0" + }, + "HighNode" : "0000000000000000", + "LowLimit" : { + "currency" : "USD", + "issuer" : "rnYDWQaRdMb5neCGgvFfhw3MBoxmv5LtfH", + "value" : "1000" + }, + "LowNode" : "0000000000000000" + }, + "LedgerEntryType" : "RippleState", + "LedgerIndex" : "FDBBB8BF83FF697C7F68E67AAA06A9E0774CB2727B53E95E63B6416AF0B1A2A7", + "PreviousFields" : { + "Balance" : { + "currency" : "USD", + "issuer" : "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value" : "0" + } + }, + "PreviousTxnID" : "8BF77D4762500ED72F291B19D75489397EBF23D870C975B33B3C114E54F36740", + "PreviousTxnLgrSeq" : 4 + } + } + ], + "TransactionIndex" : 0, + "TransactionResult" : "tesSUCCESS" + }, + "status" : "success", + "validated" : true + } +} diff --git a/test/fixtures/utils/paymentTokenRedeem.json b/test/fixtures/utils/paymentTokenRedeem.json new file mode 100644 index 00000000..4f7d3851 --- /dev/null +++ b/test/fixtures/utils/paymentTokenRedeem.json @@ -0,0 +1,83 @@ +{ + "result" : { + "Account" : "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK", + "Amount" : { + "currency" : "USD", + "issuer" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "value" : "100" + }, + "Destination" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "Fee" : "10", + "Flags" : 2147483648, + "Sequence" : 2, + "SigningPubKey" : "02691AC5AE1C4C333AE5DF8A93BDC495F0EEBFC6DB0DA7EB6EF808F3AFC006E3FE", + "TransactionType" : "Payment", + "TxnSignature" : "304402205523DC0073C7F7DB92765367526A7A2CF1B6E2A42C6B102E96F58FC69689CBF60220371264F1472C6694F8453506503351B256722274CE1324E2B3B1885C18485D59", + "date" : 472366860, + "hash" : "44AA46A2728AD7A7E856B27D8815D935D174F63CAA60E4BD90C5CC74D440E753", + "inLedger" : 6, + "ledger_index" : 6, + "meta" : { + "AffectedNodes" : [ + { + "ModifiedNode" : { + "FinalFields" : { + "Balance" : { + "currency" : "USD", + "issuer" : "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value" : "-100" + }, + "Flags" : 131072, + "HighLimit" : { + "currency" : "USD", + "issuer" : "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK", + "value" : "500" + }, + "HighNode" : "0000000000000000", + "LowLimit" : { + "currency" : "USD", + "issuer" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "value" : "0" + }, + "LowNode" : "0000000000000000" + }, + "LedgerEntryType" : "RippleState", + "LedgerIndex" : "88DA36A0E2F92E2E3504DC7936FDB719769486A6BE1BEC4F1E3B580538D28B4A", + "PreviousFields" : { + "Balance" : { + "currency" : "USD", + "issuer" : "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value" : "-200" + } + }, + "PreviousTxnID" : "C0AA2D9C82E68C06F81340B633D36EA983A834F6377FA18139D4EE7AA6A2973D", + "PreviousTxnLgrSeq" : 5 + } + }, + { + "ModifiedNode" : { + "FinalFields" : { + "Account" : "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK", + "Balance" : "999999980", + "Flags" : 0, + "OwnerCount" : 1, + "Sequence" : 3 + }, + "LedgerEntryType" : "AccountRoot", + "LedgerIndex" : "DE3BE7FDF6864FB024807B36BFCB4607E7CDA7D4C155C7AFB4B0973D638938BF", + "PreviousFields" : { + "Balance" : "999999990", + "Sequence" : 2 + }, + "PreviousTxnID" : "88CD25B9BF28097156E1EA79281994FFD002EE3D3F67E99ED791C38DA3967CB6", + "PreviousTxnLgrSeq" : 4 + } + } + ], + "TransactionIndex" : 0, + "TransactionResult" : "tesSUCCESS" + }, + "status" : "success", + "validated" : true + } +} diff --git a/test/fixtures/utils/paymentTokenRedeemThenIssue.json b/test/fixtures/utils/paymentTokenRedeemThenIssue.json new file mode 100644 index 00000000..8ec22fb9 --- /dev/null +++ b/test/fixtures/utils/paymentTokenRedeemThenIssue.json @@ -0,0 +1,83 @@ +{ + "result" : { + "Account" : "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK", + "Amount" : { + "currency" : "USD", + "issuer" : "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK", + "value" : "200" + }, + "Destination" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "Fee" : "10", + "Flags" : 2147483648, + "Sequence" : 3, + "SigningPubKey" : "02691AC5AE1C4C333AE5DF8A93BDC495F0EEBFC6DB0DA7EB6EF808F3AFC006E3FE", + "TransactionType" : "Payment", + "TxnSignature" : "304402207068EDB074FE388DB198A5D3B51A2846BB937F76F558D2D9245B11A20DFD5DAF022055A5B5D65C637A34C48361AFD0E97780D6FAED98A4221CE0838EE3598C0EECDE", + "date" : 472374260, + "hash" : "8EE52E8CC50AB0841A34E755E882BBC50F855A750AC954D7E7050E71672BE77E", + "inLedger" : 8, + "ledger_index" : 8, + "meta" : { + "AffectedNodes" : [ + { + "ModifiedNode" : { + "FinalFields" : { + "Balance" : { + "currency" : "USD", + "issuer" : "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value" : "100" + }, + "Flags" : 196608, + "HighLimit" : { + "currency" : "USD", + "issuer" : "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK", + "value" : "500" + }, + "HighNode" : "0000000000000000", + "LowLimit" : { + "currency" : "USD", + "issuer" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "value" : "500" + }, + "LowNode" : "0000000000000000" + }, + "LedgerEntryType" : "RippleState", + "LedgerIndex" : "88DA36A0E2F92E2E3504DC7936FDB719769486A6BE1BEC4F1E3B580538D28B4A", + "PreviousFields" : { + "Balance" : { + "currency" : "USD", + "issuer" : "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value" : "-100" + } + }, + "PreviousTxnID" : "951C7AB715ECF4E2B2254F336D9529783AE924E8B4784884E45EA0697ED78B61", + "PreviousTxnLgrSeq" : 7 + } + }, + { + "ModifiedNode" : { + "FinalFields" : { + "Account" : "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK", + "Balance" : "999999970", + "Flags" : 0, + "OwnerCount" : 1, + "Sequence" : 4 + }, + "LedgerEntryType" : "AccountRoot", + "LedgerIndex" : "DE3BE7FDF6864FB024807B36BFCB4607E7CDA7D4C155C7AFB4B0973D638938BF", + "PreviousFields" : { + "Balance" : "999999980", + "Sequence" : 3 + }, + "PreviousTxnID" : "8D380F8548020FAF6CD42D0E9EDA92B51D4D7DDC4327644893CA1F24688F3715", + "PreviousTxnLgrSeq" : 6 + } + } + ], + "TransactionIndex" : 0, + "TransactionResult" : "tesSUCCESS" + }, + "status" : "success", + "validated" : true + } +} diff --git a/test/fixtures/utils/paymentTokenSpendFullBalance.json b/test/fixtures/utils/paymentTokenSpendFullBalance.json new file mode 100644 index 00000000..f60acc76 --- /dev/null +++ b/test/fixtures/utils/paymentTokenSpendFullBalance.json @@ -0,0 +1,124 @@ +{ + "engine_result": "tesSUCCESS", + "engine_result_code": 0, + "engine_result_message": "The transaction was applied.", + "ledger_hash": "605F02CC71269E0C3253FC582503D0A69533DF9E744F1613CB132A67261527F2", + "ledger_index": 10458307, + "status": "closed", + "type": "transaction", + "validated": true, + "metadata": { + "AffectedNodes": [ + { + "ModifiedNode": { + "FinalFields": { + "Balance": { + "currency": "USD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value": "1.545330905250352" + }, + "Flags": 1114112, + "HighLimit": { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0" + }, + "HighNode": "00000000000001E8", + "LowLimit": { + "currency": "USD", + "issuer": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "value": "1000000000" + }, + "LowNode": "0000000000000000" + }, + "LedgerEntryType": "RippleState", + "LedgerIndex": "2F323020B4288ACD4066CC64C89DAD2E4D5DFC2D44571942A51C005BF79D6E25", + "PreviousFields": { + "Balance": { + "currency": "USD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value": "1.345330905250352" + } + }, + "PreviousTxnID": "24525F80080EAC8857F1A29A47AEF23FD2B0A52DAF7DC3900A4E31831187FCB1", + "PreviousTxnLgrSeq": 10443886 + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Balance": { + "currency": "USD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value": "0" + }, + "Flags": 1114112, + "HighLimit": { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0" + }, + "HighNode": "00000000000001E8", + "LowLimit": { + "currency": "USD", + "issuer": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "value": "1000000000" + }, + "LowNode": "0000000000000000" + }, + "LedgerEntryType": "RippleState", + "LedgerIndex": "AAE13AF5192EFBFD49A8EEE5869595563FEB73228C0B38FED9CC3D20EE74F399", + "PreviousFields": { + "Balance": { + "currency": "USD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value": "0.2" + } + }, + "PreviousTxnID": "24525F80080EAC8857F1A29A47AEF23FD2B0A52DAF7DC3900A4E31831187FCB1", + "PreviousTxnLgrSeq": 10443886 + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Account": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "Balance": "99976002", + "Flags": 0, + "OwnerCount": 1, + "Sequence": 3 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "C24354B286600B8F28E51233B4AC41A3B4DDD0FDC9BCF96BB171573F6B40A4AE", + "PreviousFields": { + "Balance": "99988002", + "Sequence": 2 + }, + "PreviousTxnID": "A788447CF5FD7108CBF49416E2335F95ED3F5A9FC016686C8F9EFB34BBEA613A", + "PreviousTxnLgrSeq": 10425088 + } + } + ], + "TransactionIndex": 3, + "TransactionResult": "tesSUCCESS" + }, + "tx_json": { + "Account": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "Amount": { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0.2" + }, + "Destination": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "Fee": "12000", + "Flags": 2147483648, + "LastLedgerSequence": 10458314, + "Sequence": 2, + "SigningPubKey": "039371D0465097AC8F9C02EB60D5599AAD08AADBD623D6D40D642CF2D7C0481B83", + "TransactionType": "Payment", + "TxnSignature": "304502210097A62D87FF08A050F1832B974F06FB4F0C83F6661CC916AE190A439C8DB3863202204CD27C5C6A9067BA5A1DA9BB940FDF3F7C6B073225911E567B1E37E9C29E99D4", + "date": 471639670, + "hash": "5AC7632779C3AE649236F728C2C6811D7ADDE6CCC5018B8754C6EB953FCB1BC5" + } +} + diff --git a/test/fixtures/utils/paymentXrpCreateAccount.json b/test/fixtures/utils/paymentXrpCreateAccount.json new file mode 100644 index 00000000..6f111e19 --- /dev/null +++ b/test/fixtures/utils/paymentXrpCreateAccount.json @@ -0,0 +1,60 @@ +{ + "engine_result": "tesSUCCESS", + "engine_result_code": 0, + "engine_result_message": "The transaction was applied.", + "ledger_hash": "5FA9BBBE9EF6CE4BF9BB56CC3A70106C1475EA4C02EDE26651710FAA46E81F60", + "ledger_index": 10424084, + "metadata": { + "AffectedNodes": [ + { + "CreatedNode": { + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "C24354B286600B8F28E51233B4AC41A3B4DDD0FDC9BCF96BB171573F6B40A4AE", + "NewFields": { + "Account": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "Balance": "100000000", + "Sequence": 1 + } + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Account": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "Balance": "339903994", + "Flags": 0, + "OwnerCount": 0, + "Sequence": 9 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "E9A39B0BA8703D5FFD05D9EAD01EE6C0E7A15CF33C2C6B7269107BD2BD535818", + "PreviousFields": { + "Balance": "439915994", + "Sequence": 8 + }, + "PreviousTxnID": "0E6CF1A13C6A804BE50B08C1D0446C7405D8461254CC6B62337CA9FEA4DF13EC", + "PreviousTxnLgrSeq": 10424064 + } + } + ], + "TransactionIndex": 3, + "TransactionResult": "tesSUCCESS" + }, + "status": "closed", + "transaction": { + "Account": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "Amount": "100000000", + "Destination": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "Fee": "12000", + "Flags": 2147483648, + "LastLedgerSequence": 10424091, + "Sequence": 8, + "SigningPubKey": "03F16A52EBDCA6EBF5D99828E1E6918C64D45E6F136476A8F4757512FE553D18F0", + "TransactionType": "Payment", + "TxnSignature": "304402207676FE35FF0D01E01F13531760658ADECC493181A4EF618A970E4C209FC989C102206660147F17B46469864E9E10152844C4DA62363DB70B5F610E6DAEA87A6781A9", + "date": 471490400, + "hash": "43CAAC76C95358CA2F84EA8BF5BFC327B90B21039A3C69EC4EAC7FEDC54CDB9F" + }, + "type": "transaction", + "validated": true +} diff --git a/test/fixtures/utils/trustlineCreate.json b/test/fixtures/utils/trustlineCreate.json new file mode 100644 index 00000000..6d0cdfe3 --- /dev/null +++ b/test/fixtures/utils/trustlineCreate.json @@ -0,0 +1,108 @@ +{ + "engine_result": "tesSUCCESS", + "engine_result_code": 0, + "engine_result_message": "The transaction was applied.", + "ledger_hash": "CA4C25E271FDB00836A091E8073F6692784BEB116B33675533F9511B17FC2B72", + "ledger_index": 10483144, + "status": "closed", + "type": "transaction", + "validated": true, + "metadata": { + "AffectedNodes": [ + { + "ModifiedNode": { + "FinalFields": { + "Flags": 0, + "IndexPrevious": "00000000000001F1", + "Owner": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "RootIndex": "6319526CE8F9A8A44D7A870A89DC1B4AD848AA4F066FCB5390A9A268F6E16AEA" + }, + "LedgerEntryType": "DirectoryNode", + "LedgerIndex": "58E06162628C5E2292DA172A97573FA5613C4A223810686428BF8431B3D67C58" + } + }, + { + "CreatedNode": { + "LedgerEntryType": "DirectoryNode", + "LedgerIndex": "84C8F98961F2F10CB1B5C4FB649C18B05A9D3FC20C3A78B75C86CD30D7EAC39C", + "NewFields": { + "Owner": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "RootIndex": "84C8F98961F2F10CB1B5C4FB649C18B05A9D3FC20C3A78B75C86CD30D7EAC39C" + } + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "A3C1529122C3DBD6C96B9DF009FF4896023FE6B4E05A508B1E81F3DCD9A6274B", + "PreviousTxnID": "CA4BD65D1E29552B17041B219105E1BC0FE00837C798DE9F9E2EA670097ACE33", + "PreviousTxnLgrSeq": 10483128 + } + }, + { + "CreatedNode": { + "LedgerEntryType": "RippleState", + "LedgerIndex": "AAE13AF5192EFBFD49A8EEE5869595563FEB73228C0B38FED9CC3D20EE74F399", + "NewFields": { + "Balance": { + "currency": "USD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value": "10" + }, + "Flags": 65536, + "HighLimit": { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0" + }, + "HighNode": "00000000000001F2", + "LowLimit": { + "currency": "USD", + "issuer": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "value": "100" + } + } + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Account": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "Balance": "99740302", + "Flags": 0, + "OwnerCount": 1, + "Sequence": 23 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "C24354B286600B8F28E51233B4AC41A3B4DDD0FDC9BCF96BB171573F6B40A4AE", + "PreviousFields": { + "Balance": "99752302", + "OwnerCount": 0, + "Sequence": 22 + }, + "PreviousTxnID": "8A3F4CA1D349B4BE896DFDED6B6D0F0DCA4FCA75E082C30A4175813DDB9BCDA6", + "PreviousTxnLgrSeq": 10482869 + } + } + ], + "TransactionIndex": 10, + "TransactionResult": "tesSUCCESS" + }, + "tx_json": { + "Account": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "Fee": "12000", + "Flags": 2147483648, + "LastLedgerSequence": 10483152, + "LimitAmount": { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "100" + }, + "Sequence": 22, + "SigningPubKey": "039371D0465097AC8F9C02EB60D5599AAD08AADBD623D6D40D642CF2D7C0481B83", + "TransactionType": "TrustSet", + "TxnSignature": "3044022048862FBF688AFFA81E8A08DB08C2559BB5D7E935B5E4597EE6ADF2E901BC9A6402200B7CDBAD2001CB9797AD56E22D9DA1C23F7F5DC1BB8DB22F013DEE78EAC46BE4", + "date": 471748760, + "hash": "8375C1ED96BB4DD66FD697F34755F9B03DB62CD098627B834028728670CF93EF" + } +} diff --git a/test/fixtures/utils/trustlineDelete.json b/test/fixtures/utils/trustlineDelete.json new file mode 100644 index 00000000..d83139e3 --- /dev/null +++ b/test/fixtures/utils/trustlineDelete.json @@ -0,0 +1,157 @@ +{ + "engine_result": "tesSUCCESS", + "engine_result_code": 0, + "engine_result_message": "The transaction was applied.", + "ledger_hash": "BFD12A293442E8C083A98092C7A8A199A3732B2360643E40BB8704DE3DF8EA5E", + "ledger_index": 10482869, + "status": "closed", + "type": "transaction", + "validated": true, + "metadata": { + "AffectedNodes": [ + { + "ModifiedNode": { + "FinalFields": { + "Balance": { + "currency": "USD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value": "1.545330905250352" + }, + "Flags": 1114112, + "HighLimit": { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0" + }, + "HighNode": "00000000000001E8", + "LowLimit": { + "currency": "USD", + "issuer": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "value": "1000000000" + }, + "LowNode": "0000000000000000" + }, + "LedgerEntryType": "RippleState", + "LedgerIndex": "2F323020B4288ACD4066CC64C89DAD2E4D5DFC2D44571942A51C005BF79D6E25", + "PreviousFields": { + "Balance": { + "currency": "USD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value": "1.525330905250352" + } + }, + "PreviousTxnID": "D1B2B5508585E1BB48E1D76629C59F6368AAB9568457D058486DCC4DCAECCE30", + "PreviousTxnLgrSeq": 10482855 + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Flags": 0, + "IndexPrevious": "00000000000001F1", + "Owner": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "RootIndex": "6319526CE8F9A8A44D7A870A89DC1B4AD848AA4F066FCB5390A9A268F6E16AEA" + }, + "LedgerEntryType": "DirectoryNode", + "LedgerIndex": "58E06162628C5E2292DA172A97573FA5613C4A223810686428BF8431B3D67C58" + } + }, + { + "DeletedNode": { + "FinalFields": { + "Flags": 0, + "Owner": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "RootIndex": "84C8F98961F2F10CB1B5C4FB649C18B05A9D3FC20C3A78B75C86CD30D7EAC39C" + }, + "LedgerEntryType": "DirectoryNode", + "LedgerIndex": "84C8F98961F2F10CB1B5C4FB649C18B05A9D3FC20C3A78B75C86CD30D7EAC39C" + } + }, + { + "ModifiedNode": { + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "A3C1529122C3DBD6C96B9DF009FF4896023FE6B4E05A508B1E81F3DCD9A6274B", + "PreviousTxnID": "758E69A2A2F5E7713ACCA70DC82DD89D7B45B9E020A7E19B9312F0C49A8834BA", + "PreviousTxnLgrSeq": 10482869 + } + }, + { + "DeletedNode": { + "FinalFields": { + "Balance": { + "currency": "USD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value": "0" + }, + "Flags": 0, + "HighLimit": { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0" + }, + "HighNode": "00000000000001F2", + "LowLimit": { + "currency": "USD", + "issuer": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "value": "0" + }, + "LowNode": "0000000000000000", + "PreviousTxnID": "CA491349DAF4D4EB1E5D2EF1DD4BBC84640C22B4C94C3C9AD40B190151A7878B", + "PreviousTxnLgrSeq": 10482862 + }, + "LedgerEntryType": "RippleState", + "LedgerIndex": "AAE13AF5192EFBFD49A8EEE5869595563FEB73228C0B38FED9CC3D20EE74F399", + "PreviousFields": { + "Balance": { + "currency": "USD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value": "0.02" + }, + "Flags": 65536 + } + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Account": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "Balance": "99752302", + "Flags": 0, + "OwnerCount": 0, + "Sequence": 22 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "C24354B286600B8F28E51233B4AC41A3B4DDD0FDC9BCF96BB171573F6B40A4AE", + "PreviousFields": { + "Balance": "99764302", + "OwnerCount": 1, + "Sequence": 21 + }, + "PreviousTxnID": "CA491349DAF4D4EB1E5D2EF1DD4BBC84640C22B4C94C3C9AD40B190151A7878B", + "PreviousTxnLgrSeq": 10482862 + } + } + ], + "TransactionIndex": 9, + "TransactionResult": "tesSUCCESS" + }, + "tx_json": { + "Account": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "Amount": { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0.02" + }, + "Destination": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "Fee": "12000", + "Flags": 2147483648, + "LastLedgerSequence": 10482877, + "Sequence": 21, + "SigningPubKey": "039371D0465097AC8F9C02EB60D5599AAD08AADBD623D6D40D642CF2D7C0481B83", + "TransactionType": "Payment", + "TxnSignature": "3045022100E718DDE0149F89CF58FAD1847ED7AD9D61D833E07969A71FA7918D2F6D414AAE022041226ADCB68C2B64CA37AAB4C268922F2EE09DFBF8B234B282E9104643C6351D", + "date": 471747550, + "hash": "8A3F4CA1D349B4BE896DFDED6B6D0F0DCA4FCA75E082C30A4175813DDB9BCDA6" + } +} + diff --git a/test/fixtures/utils/trustlineSetLimit.json b/test/fixtures/utils/trustlineSetLimit.json new file mode 100644 index 00000000..21f753ed --- /dev/null +++ b/test/fixtures/utils/trustlineSetLimit.json @@ -0,0 +1,88 @@ +{ + "engine_result": "tesSUCCESS", + "engine_result_code": 0, + "engine_result_message": "The transaction was applied.", + "ledger_hash": "BB1814E087367EB56D7EBF0DB99481291894A53FF8B155511C6CC45D57F42E27", + "ledger_index": 10479523, + "status": "closed", + "type": "transaction", + "validated": true, + "metadata": { + "AffectedNodes": [ + { + "ModifiedNode": { + "FinalFields": { + "Balance": { + "currency": "USD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value": "0.02" + }, + "Flags": 1114112, + "HighLimit": { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0" + }, + "HighNode": "00000000000001E8", + "LowLimit": { + "currency": "USD", + "issuer": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "value": "200" + }, + "LowNode": "0000000000000000" + }, + "LedgerEntryType": "RippleState", + "LedgerIndex": "AAE13AF5192EFBFD49A8EEE5869595563FEB73228C0B38FED9CC3D20EE74F399", + "PreviousFields": { + "LowLimit": { + "currency": "USD", + "issuer": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "value": "100" + } + }, + "PreviousTxnID": "A9A654F03855FEBD714E49B2C190A62C310081339AA0AA49C38F0B734E81C173", + "PreviousTxnLgrSeq": 10479514 + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Account": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "Balance": "99884302", + "Flags": 0, + "OwnerCount": 1, + "Sequence": 11 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "C24354B286600B8F28E51233B4AC41A3B4DDD0FDC9BCF96BB171573F6B40A4AE", + "PreviousFields": { + "Balance": "99896302", + "Sequence": 10 + }, + "PreviousTxnID": "BD850F01540CE35B68C1125E2055BBFEEF961D65AEFBC0CE39CF814685144117", + "PreviousTxnLgrSeq": 10479508 + } + } + ], + "TransactionIndex": 10, + "TransactionResult": "tesSUCCESS" + }, + "tx_json": { + "Account": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "Fee": "12000", + "Flags": 2147483648, + "LastLedgerSequence": 10479530, + "LimitAmount": { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "200" + }, + "Sequence": 10, + "SigningPubKey": "039371D0465097AC8F9C02EB60D5599AAD08AADBD623D6D40D642CF2D7C0481B83", + "TransactionType": "TrustSet", + "TxnSignature": "304502210088A7B69070516F1456AE93CC7189C213E60F1E5276F0FFEB64419CFD3A75FDBA02202E852593523240D5BD59B4DF3FAC97E112F75DF712B07E9C9FC64D824E2E0CB2", + "date": 471732720, + "hash": "9F54793122AD0CF1552A4E76991CB481E6FAD467176976500E11EA76CAC9D9EA" + } +} + diff --git a/test/fixtures/utils/trustlineSetLimit2.json b/test/fixtures/utils/trustlineSetLimit2.json new file mode 100644 index 00000000..b1347e04 --- /dev/null +++ b/test/fixtures/utils/trustlineSetLimit2.json @@ -0,0 +1,107 @@ +{ + "Account": "rsApBGKJmMfExxZBrGnzxEXyq7TMhMRg4e", + "Fee": "10", + "Flags": 0, + "LimitAmount": { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "300" + }, + "Sequence": 10, + "SigningPubKey": "0337930D40B5A285B7ABC75574FAEC947D1221ABD0155E0D393223DFDA5A7905B2", + "TransactionType": "TrustSet", + "TxnSignature": "30450221009E1A07D8FD71276D776712EDCD044769C7DB0590FDFA90EC405BBFFA2A5B658402207280B2F1DFDFAEF4A52C14D3EB726CF0520FB2B79B4037C0F5FD0DF9D4166A62", + "date": 424538770, + "hash": "09A89A9DB790C553441637C677FF26D3A606C9EDF688447273B2C0B83D98383C", + "inLedger": 1046325, + "ledger_index": 1046325, + "metadata": { + "AffectedNodes": [ + { + "ModifiedNode": { + "FinalFields": { + "Flags": 0, + "Owner": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "RootIndex": "6319526CE8F9A8A44D7A870A89DC1B4AD848AA4F066FCB5390A9A268F6E16AEA" + }, + "LedgerEntryType": "DirectoryNode", + "LedgerIndex": "6319526CE8F9A8A44D7A870A89DC1B4AD848AA4F066FCB5390A9A268F6E16AEA" + } + }, + { + "CreatedNode": { + "LedgerEntryType": "RippleState", + "LedgerIndex": "791DCC45D985B40DC7E3BFB7394B5287E8027BCFCE07F5A55A2492738724F97B", + "NewFields": { + "Balance": { + "currency": "USD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value": "0" + }, + "Flags": 65536, + "HighLimit": { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0" + }, + "LowLimit": { + "currency": "USD", + "issuer": "rsApBGKJmMfExxZBrGnzxEXyq7TMhMRg4e", + "value": "300" + } + } + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Account": "rsApBGKJmMfExxZBrGnzxEXyq7TMhMRg4e", + "Balance": "9248902096", + "Flags": 0, + "OwnerCount": 2, + "Sequence": 11 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "96E491543BAA99142135D2C304174585C285FA44A2896970BAA66EA460F15479", + "PreviousFields": { + "Balance": "9248902106", + "OwnerCount": 1, + "Sequence": 10 + }, + "PreviousTxnID": "C6175CC7CF4B4C875DE991AA2812ABA00EE795CE5547FD70023E3B170BD1030F", + "PreviousTxnLgrSeq": 1043147 + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "Balance": "149999980", + "Flags": 0, + "OwnerCount": 0, + "Sequence": 3, + "TransferRate": 1002000000 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "A3C1529122C3DBD6C96B9DF009FF4896023FE6B4E05A508B1E81F3DCD9A6274B", + "PreviousTxnID": "5F338A7BF4C38633C75BED1672E146898904FC8272B45DA7D188716D998B71C5", + "PreviousTxnLgrSeq": 1045132 + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Flags": 0, + "Owner": "rsApBGKJmMfExxZBrGnzxEXyq7TMhMRg4e", + "RootIndex": "AB72F278F646031B4531BE7EC45A78F3693B9375BEA7B2A794ECC32742C87843" + }, + "LedgerEntryType": "DirectoryNode", + "LedgerIndex": "AB72F278F646031B4531BE7EC45A78F3693B9375BEA7B2A794ECC32742C87843" + } + } + ], + "TransactionIndex": 0, + "TransactionResult": "tesSUCCESS" + }, + "validated": true +} diff --git a/test/fixtures/utils/trustlineSetLimitZero.json b/test/fixtures/utils/trustlineSetLimitZero.json new file mode 100644 index 00000000..f441addb --- /dev/null +++ b/test/fixtures/utils/trustlineSetLimitZero.json @@ -0,0 +1,87 @@ +{ + "engine_result": "tesSUCCESS", + "engine_result_code": 0, + "engine_result_message": "The transaction was applied.", + "ledger_hash": "BCA3403873155ECFEB616ED9923D94430CB26EA7206CBCC4F86EACE47B33F950", + "ledger_index": 10460919, + "status": "closed", + "type": "transaction", + "validated": true, + "metadata": { + "AffectedNodes": [ + { + "ModifiedNode": { + "FinalFields": { + "Balance": { + "currency": "USD", + "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", + "value": "0.02" + }, + "Flags": 1114112, + "HighLimit": { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0" + }, + "HighNode": "00000000000001E8", + "LowLimit": { + "currency": "USD", + "issuer": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "value": "0" + }, + "LowNode": "0000000000000000" + }, + "LedgerEntryType": "RippleState", + "LedgerIndex": "AAE13AF5192EFBFD49A8EEE5869595563FEB73228C0B38FED9CC3D20EE74F399", + "PreviousFields": { + "LowLimit": { + "currency": "USD", + "issuer": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "value": "100" + } + }, + "PreviousTxnID": "1BBAC938211E7C2B5A0DD00153557E0A47B38F93AF0F1831C4ECE0E6387B8B96", + "PreviousTxnLgrSeq": 10460914 + } + }, + { + "ModifiedNode": { + "FinalFields": { + "Account": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "Balance": "99940002", + "Flags": 0, + "OwnerCount": 1, + "Sequence": 6 + }, + "LedgerEntryType": "AccountRoot", + "LedgerIndex": "C24354B286600B8F28E51233B4AC41A3B4DDD0FDC9BCF96BB171573F6B40A4AE", + "PreviousFields": { + "Balance": "99952002", + "Sequence": 5 + }, + "PreviousTxnID": "1BBAC938211E7C2B5A0DD00153557E0A47B38F93AF0F1831C4ECE0E6387B8B96", + "PreviousTxnLgrSeq": 10460914 + } + } + ], + "TransactionIndex": 8, + "TransactionResult": "tesSUCCESS" + }, + "tx_json": { + "Account": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "Fee": "12000", + "Flags": 2147483648, + "LastLedgerSequence": 10460926, + "LimitAmount": { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0" + }, + "Sequence": 5, + "SigningPubKey": "039371D0465097AC8F9C02EB60D5599AAD08AADBD623D6D40D642CF2D7C0481B83", + "TransactionType": "TrustSet", + "TxnSignature": "3045022100CAF0DD8A64B68CC9CD44166A381FE07B69AAC5219BB3E90D5A2BD73FB9919DBA022071BE14E0E8ABB0B1841A7A4D1A983C8AC32CFA0E7C9A45FA3565AE5477C076A8", + "date": 471650760, + "hash": "B836ADBA4D77638C5F8C99B5FC0FC6A92D5F82FF3C90759F44773835BAD2AB86" + } +} diff --git a/test/utils/getBalanceChanges.ts b/test/utils/getBalanceChanges.ts new file mode 100644 index 00000000..d78df840 --- /dev/null +++ b/test/utils/getBalanceChanges.ts @@ -0,0 +1,454 @@ +import { assert } from 'chai' + +import { getBalanceChanges } from '../../src/utils' +import paymentToken from '../fixtures/utils/paymentToken.json' +import paymentTokenDestinationNoBalance from '../fixtures/utils/paymentTokenDestinationNoBalance.json' +import paymentTokenMultipath from '../fixtures/utils/paymentTokenMultipath.json' +import paymentTokenRedeem from '../fixtures/utils/paymentTokenRedeem.json' +import paymentTokenRedeemThenIssue from '../fixtures/utils/paymentTokenRedeemThenIssue.json' +import paymentTokenSpendFullBalance from '../fixtures/utils/paymentTokenSpendFullBalance.json' +import paymentXrpCreateAccount from '../fixtures/utils/paymentXrpCreateAccount.json' +import trustlineCreate from '../fixtures/utils/trustlineCreate.json' +import trustlineDelete from '../fixtures/utils/trustlineDelete.json' +import trustlineSetLimit from '../fixtures/utils/trustlineSetLimit.json' +import trustlineSetLimit2 from '../fixtures/utils/trustlineSetLimit2.json' +import trustlineSetLimitZero from '../fixtures/utils/trustlineSetLimitZero.json' + +describe('getBalanceChanges', function () { + it('XRP create account', function () { + const result = getBalanceChanges(paymentXrpCreateAccount.metadata) + const expected = [ + { + account: 'rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K', + balances: [{ currency: 'XRP', value: '100' }], + }, + { + account: 'rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc', + balances: [{ currency: 'XRP', value: '-100.012' }], + }, + ] + assert.deepStrictEqual(result, expected) + }) + + it('USD payment to account with no USD', function () { + const result = getBalanceChanges(paymentTokenDestinationNoBalance.metadata) + const expected = [ + { + account: 'rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc', + balances: [ + { + value: '-0.01', + currency: 'USD', + issuer: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q', + }, + { + value: '-0.012', + currency: 'XRP', + }, + ], + }, + { + account: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q', + balances: [ + { + issuer: 'rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc', + currency: 'USD', + value: '0.01', + }, + { + issuer: 'rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K', + currency: 'USD', + value: '-0.01', + }, + ], + }, + { + account: 'rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K', + balances: [ + { + issuer: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q', + currency: 'USD', + value: '0.01', + }, + ], + }, + ] + assert.deepStrictEqual(result, expected) + }) + + it('USD payment of all USD in source account', function () { + const result = getBalanceChanges(paymentTokenSpendFullBalance.metadata) + const expected = [ + { + account: 'rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc', + balances: [ + { + value: '0.2', + currency: 'USD', + issuer: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q', + }, + ], + }, + { + account: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q', + balances: [ + { + value: '-0.2', + currency: 'USD', + issuer: 'rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc', + }, + { + value: '0.2', + currency: 'USD', + issuer: 'rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K', + }, + ], + }, + { + account: 'rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K', + balances: [ + { + value: '-0.2', + currency: 'USD', + issuer: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q', + }, + { + value: '-0.012', + currency: 'XRP', + }, + ], + }, + ] + + assert.deepStrictEqual(result, expected) + }) + + it('USD payment to account with USD', function () { + const result = getBalanceChanges(paymentToken.metadata) + const expected = [ + { + account: 'rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc', + balances: [ + { + value: '-0.01', + currency: 'USD', + issuer: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q', + }, + { + value: '-0.012', + currency: 'XRP', + }, + ], + }, + { + account: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q', + balances: [ + { + issuer: 'rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc', + currency: 'USD', + value: '0.01', + }, + { + issuer: 'rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K', + currency: 'USD', + value: '-0.01', + }, + ], + }, + { + account: 'rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K', + balances: [ + { + issuer: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q', + currency: 'USD', + value: '0.01', + }, + ], + }, + ] + assert.deepStrictEqual(result, expected) + }) + + it('Set trust limit to 0 with balance remaining', function () { + const result = getBalanceChanges(trustlineSetLimitZero.metadata) + const expected = [ + { + account: 'rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K', + balances: [ + { + value: '-0.012', + currency: 'XRP', + }, + ], + }, + ] + assert.deepStrictEqual(result, expected) + }) + + it('Create trustline', function () { + const result = getBalanceChanges(trustlineCreate.metadata) + const expected = [ + { + account: 'rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K', + balances: [ + { + issuer: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q', + currency: 'USD', + value: '10', + }, + { + currency: 'XRP', + value: '-0.012', + }, + ], + }, + { + account: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q', + balances: [ + { + issuer: 'rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K', + currency: 'USD', + value: '-10', + }, + ], + }, + ] + assert.deepStrictEqual(result, expected) + }) + + it('Set trustline', function () { + const result = getBalanceChanges(trustlineSetLimit.metadata) + const expected = [ + { + account: 'rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K', + balances: [ + { + value: '-0.012', + currency: 'XRP', + }, + ], + }, + ] + assert.deepStrictEqual(result, expected) + }) + + it('Set trustline 2', function () { + const result = getBalanceChanges(trustlineSetLimit2.metadata) + const expected = [ + { + account: 'rsApBGKJmMfExxZBrGnzxEXyq7TMhMRg4e', + balances: [ + { + currency: 'XRP', + value: '-0.00001', + }, + ], + }, + ] + assert.deepStrictEqual(result, expected) + }) + + it('Delete trustline', function () { + const result = getBalanceChanges(trustlineDelete.metadata) + const expected = [ + { + account: 'rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc', + balances: [ + { + value: '0.02', + currency: 'USD', + issuer: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q', + }, + ], + }, + { + account: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q', + balances: [ + { + value: '-0.02', + currency: 'USD', + issuer: 'rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc', + }, + { + value: '0.02', + currency: 'USD', + issuer: 'rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K', + }, + ], + }, + { + account: 'rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K', + balances: [ + { + value: '-0.02', + currency: 'USD', + issuer: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q', + }, + { + value: '-0.012', + currency: 'XRP', + }, + ], + }, + ] + assert.deepStrictEqual(result, expected) + }) + + it('Redeem USD', function () { + const result = getBalanceChanges(paymentTokenRedeem.result.meta) + const expected = [ + { + account: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', + balances: [ + { + currency: 'USD', + issuer: 'rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK', + value: '100', + }, + ], + }, + { + account: 'rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK', + balances: [ + { + currency: 'USD', + issuer: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', + value: '-100', + }, + { + currency: 'XRP', + value: '-0.00001', + }, + ], + }, + ] + assert.deepStrictEqual(result, expected) + }) + + it('Redeem then issue USD', function () { + const result = getBalanceChanges(paymentTokenRedeemThenIssue.result.meta) + const expected = [ + { + account: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', + balances: [ + { + currency: 'USD', + issuer: 'rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK', + value: '200', + }, + ], + }, + { + account: 'rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK', + balances: [ + { + currency: 'USD', + issuer: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', + value: '-200', + }, + { + currency: 'XRP', + value: '-0.00001', + }, + ], + }, + ] + assert.deepStrictEqual(result, expected) + }) + + it('Multipath USD payment', function () { + const result = getBalanceChanges(paymentTokenMultipath.result.meta) + const expected = [ + { + account: 'rrnsYgWn13Z28GtRgznrSUsLfMkvsXCZSu', + balances: [ + { + issuer: 'r4nmQNH4Fhjfh6cHDbvVSsBv7KySbj4cBf', + currency: 'USD', + value: '100', + }, + { + issuer: 'rnYDWQaRdMb5neCGgvFfhw3MBoxmv5LtfH', + currency: 'USD', + value: '-100', + }, + ], + }, + { + account: 'r4nmQNH4Fhjfh6cHDbvVSsBv7KySbj4cBf', + balances: [ + { + issuer: 'rrnsYgWn13Z28GtRgznrSUsLfMkvsXCZSu', + currency: 'USD', + value: '-100', + }, + { + currency: 'XRP', + value: '-0.00001', + }, + { + issuer: 'rJsaPnGdeo7BhMnHjuc3n44Mf7Ra1qkSVJ', + currency: 'USD', + value: '-100', + }, + { + issuer: 'rGpeQzUWFu4fMhJHZ1Via5aqFC3A5twZUD', + currency: 'USD', + value: '-100', + }, + ], + }, + { + account: 'rJsaPnGdeo7BhMnHjuc3n44Mf7Ra1qkSVJ', + balances: [ + { + issuer: 'r4nmQNH4Fhjfh6cHDbvVSsBv7KySbj4cBf', + currency: 'USD', + value: '100', + }, + { + issuer: 'rnYDWQaRdMb5neCGgvFfhw3MBoxmv5LtfH', + currency: 'USD', + value: '-100', + }, + ], + }, + { + account: 'rGpeQzUWFu4fMhJHZ1Via5aqFC3A5twZUD', + balances: [ + { + issuer: 'r4nmQNH4Fhjfh6cHDbvVSsBv7KySbj4cBf', + currency: 'USD', + value: '100', + }, + { + issuer: 'rnYDWQaRdMb5neCGgvFfhw3MBoxmv5LtfH', + currency: 'USD', + value: '-100', + }, + ], + }, + { + account: 'rnYDWQaRdMb5neCGgvFfhw3MBoxmv5LtfH', + balances: [ + { + issuer: 'rJsaPnGdeo7BhMnHjuc3n44Mf7Ra1qkSVJ', + currency: 'USD', + value: '100', + }, + { + issuer: 'rrnsYgWn13Z28GtRgznrSUsLfMkvsXCZSu', + currency: 'USD', + value: '100', + }, + { + issuer: 'rGpeQzUWFu4fMhJHZ1Via5aqFC3A5twZUD', + currency: 'USD', + value: '100', + }, + ], + }, + ] + assert.deepStrictEqual(result, expected) + }) +})