diff --git a/CHANGELOG.md b/CHANGELOG.md index ee7d122d5..c8dfdf2e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [[Unreleased]] +### Added: +- Add function to parse the final account balances from a transaction's metadata ## [1.6.0] - 2022-06-02 ### Added: diff --git a/tests/unit/utils/txn_parser/test_get_final_balances.py b/tests/unit/utils/txn_parser/test_get_final_balances.py new file mode 100644 index 000000000..462cbd409 --- /dev/null +++ b/tests/unit/utils/txn_parser/test_get_final_balances.py @@ -0,0 +1,401 @@ +from __future__ import annotations + +import json +from unittest import TestCase + +from xrpl.utils import get_final_balances + +path_to_json = "tests/unit/utils/txn_parser/transaction_jsons/" +with open(path_to_json + "payment_iou_destination_no_balance.json", "r") as infile: + payment_iou_destination_no_balance = json.load(infile) +with open(path_to_json + "payment_iou_multipath.json", "r") as infile: + payment_iou_multipath = json.load(infile) +with open(path_to_json + "payment_iou_redeem_then_issue.json", "r") as infile: + payment_iou_redeem_then_issue = json.load(infile) +with open(path_to_json + "payment_iou_redeem.json", "r") as infile: + payment_iou_redeem = json.load(infile) +with open(path_to_json + "payment_iou_spend_full_balance.json", "r") as infile: + payment_iou_spend_full_balance = json.load(infile) +with open(path_to_json + "payment_iou.json", "r") as infile: + payment_iou = json.load(infile) +with open(path_to_json + "payment_xrp_create_account.json", "r") as infile: + payment_xrp_create_account = json.load(infile) +with open(path_to_json + "trustline_create.json", "r") as infile: + trustline_create = json.load(infile) +with open(path_to_json + "trustline_delete.json", "r") as infile: + trustline_delete = json.load(infile) +with open(path_to_json + "trustline_set_limit_zero.json", "r") as infile: + trustline_set_limit_zero = json.load(infile) +with open(path_to_json + "trustline_set_limit.json", "r") as infile: + trustline_set_limit = json.load(infile) +with open(path_to_json + "trustline_set_limit2.json", "r") as infile: + trustline_set_limit2 = json.load(infile) + + +class TestGetFinalBalances(TestCase): + def test_payment_iou_destination_no_balance(self: TestGetFinalBalances): + actual = get_final_balances(payment_iou_destination_no_balance["meta"]) + expected = [ + { + "account": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "balances": [ + { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "1.535330905250352", + }, + {"currency": "XRP", "value": "239.807992"}, + ], + }, + { + "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "balances": [ + { + "currency": "USD", + "issuer": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "value": "-1.535330905250352", + }, + { + "currency": "USD", + "issuer": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "value": "-0.01", + }, + ], + }, + { + "account": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "balances": [ + { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0.01", + } + ], + }, + ] + self.assertEqual(actual, expected) + + def test_payment_iou_multipath(self: TestGetFinalBalances): + actual = get_final_balances(payment_iou_multipath["meta"]) + expected = [ + { + "account": "r4nmQNH4Fhjfh6cHDbvVSsBv7KySbj4cBf", + "balances": [{"currency": "XRP", "value": "999.99999"}], + }, + { + "account": "rnYDWQaRdMb5neCGgvFfhw3MBoxmv5LtfH", + "balances": [ + { + "currency": "USD", + "issuer": "rJsaPnGdeo7BhMnHjuc3n44Mf7Ra1qkSVJ", + "value": "100", + }, + { + "currency": "USD", + "issuer": "rrnsYgWn13Z28GtRgznrSUsLfMkvsXCZSu", + "value": "100", + }, + { + "currency": "USD", + "issuer": "rGpeQzUWFu4fMhJHZ1Via5aqFC3A5twZUD", + "value": "100", + }, + ], + }, + { + "account": "rJsaPnGdeo7BhMnHjuc3n44Mf7Ra1qkSVJ", + "balances": [ + { + "currency": "USD", + "issuer": "rnYDWQaRdMb5neCGgvFfhw3MBoxmv5LtfH", + "value": "-100", + } + ], + }, + { + "account": "rrnsYgWn13Z28GtRgznrSUsLfMkvsXCZSu", + "balances": [ + { + "currency": "USD", + "issuer": "rnYDWQaRdMb5neCGgvFfhw3MBoxmv5LtfH", + "value": "-100", + } + ], + }, + { + "account": "rGpeQzUWFu4fMhJHZ1Via5aqFC3A5twZUD", + "balances": [ + { + "currency": "USD", + "issuer": "rnYDWQaRdMb5neCGgvFfhw3MBoxmv5LtfH", + "value": "-100", + } + ], + }, + ] + self.assertEqual(actual, expected) + + def test_payment_iou_redeem_then_issue(self: TestGetFinalBalances): + actual = get_final_balances(payment_iou_redeem_then_issue["meta"]) + expected = [ + { + "account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "balances": [ + { + "currency": "USD", + "issuer": "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK", + "value": "100", + } + ], + }, + { + "account": "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK", + "balances": [ + { + "currency": "USD", + "issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "value": "-100", + }, + {"currency": "XRP", "value": "999.99997"}, + ], + }, + ] + self.assertEqual(actual, expected) + + def test_payment_iou_redeem(self: TestGetFinalBalances): + actual = get_final_balances(payment_iou_redeem["meta"]) + expected = [ + { + "account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "balances": [ + { + "currency": "USD", + "issuer": "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK", + "value": "-100", + } + ], + }, + { + "account": "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK", + "balances": [ + { + "currency": "USD", + "issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", + "value": "100", + }, + {"currency": "XRP", "value": "999.99998"}, + ], + }, + ] + self.assertEqual(actual, expected) + + def test_payment_iou_spend_full_balance(self: TestGetFinalBalances): + actual = get_final_balances(payment_iou_spend_full_balance["meta"]) + expected = [ + { + "account": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "balances": [ + { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "1.545330905250352", + } + ], + }, + { + "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "balances": [ + { + "currency": "USD", + "issuer": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "value": "-1.545330905250352", + } + ], + }, + { + "account": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "balances": [{"currency": "XRP", "value": "99.976002"}], + }, + ] + self.assertEqual(actual, expected) + + def test_payment_iou(self: TestGetFinalBalances): + actual = get_final_balances(payment_iou["meta"]) + expected = [ + { + "account": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "balances": [ + { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "1.525330905250352", + }, + {"currency": "XRP", "value": "239.555992"}, + ], + }, + { + "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "balances": [ + { + "currency": "USD", + "issuer": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "value": "-1.525330905250352", + }, + { + "currency": "USD", + "issuer": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "value": "-0.02", + }, + ], + }, + { + "account": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "balances": [ + { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0.02", + } + ], + }, + ] + self.assertEqual(actual, expected) + + def test_payment_xrp_create_account(self: TestGetFinalBalances): + actual = get_final_balances(payment_xrp_create_account["meta"]) + expected = [ + { + "account": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "balances": [{"currency": "XRP", "value": "100"}], + }, + { + "account": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "balances": [{"currency": "XRP", "value": "339.903994"}], + }, + ] + self.assertEqual(actual, expected) + + def test_trustline_create(self: TestGetFinalBalances): + actual = get_final_balances(trustline_create["meta"]) + expected = [ + { + "account": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "balances": [ + { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "10", + }, + {"currency": "XRP", "value": "99.740302"}, + ], + }, + { + "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "balances": [ + { + "currency": "USD", + "issuer": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "value": "-10", + } + ], + }, + ] + self.assertEqual(actual, expected) + + def test_trustline_delete(self: TestGetFinalBalances): + actual = get_final_balances(trustline_delete["meta"]) + expected = [ + { + "account": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "balances": [ + { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "1.545330905250352", + } + ], + }, + { + "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "balances": [ + { + "currency": "USD", + "issuer": "rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc", + "value": "-1.545330905250352", + } + ], + }, + { + "account": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "balances": [{"currency": "XRP", "value": "99.752302"}], + }, + ] + self.assertEqual(actual, expected) + + def test_trustline_set_limit_zero(self: TestGetFinalBalances): + actual = get_final_balances(trustline_set_limit_zero["meta"]) + expected = [ + { + "account": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "balances": [ + { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0.02", + }, + {"currency": "XRP", "value": "99.940002"}, + ], + }, + { + "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "balances": [ + { + "currency": "USD", + "issuer": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "value": "-0.02", + } + ], + }, + ] + self.assertEqual(actual, expected) + + def test_trustline_set_limit(self: TestGetFinalBalances): + actual = get_final_balances(trustline_set_limit["meta"]) + expected = [ + { + "account": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "balances": [ + { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "value": "0.02", + }, + {"currency": "XRP", "value": "99.884302"}, + ], + }, + { + "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "balances": [ + { + "currency": "USD", + "issuer": "rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K", + "value": "-0.02", + } + ], + }, + ] + self.assertEqual(actual, expected) + + def test_trustline_set_limit2(self: TestGetFinalBalances): + actual = get_final_balances(trustline_set_limit2["meta"]) + expected = [ + { + "account": "rsApBGKJmMfExxZBrGnzxEXyq7TMhMRg4e", + "balances": [{"currency": "XRP", "value": "9248.902096"}], + }, + { + "account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "balances": [{"currency": "XRP", "value": "149.99998"}], + }, + ] + self.assertEqual(actual, expected) diff --git a/xrpl/utils/__init__.py b/xrpl/utils/__init__.py index f043462ac..fe292f4e2 100644 --- a/xrpl/utils/__init__.py +++ b/xrpl/utils/__init__.py @@ -9,7 +9,7 @@ ripple_time_to_datetime, ripple_time_to_posix, ) -from xrpl.utils.txn_parser import get_balance_changes +from xrpl.utils.txn_parser import get_balance_changes, get_final_balances from xrpl.utils.xrp_conversions import XRPRangeException, drops_to_xrp, xrp_to_drops __all__ = [ @@ -25,4 +25,5 @@ "XRPLTimeRangeException", "create_cross_chain_payment", "get_balance_changes", + "get_final_balances", ] diff --git a/xrpl/utils/txn_parser/__init__.py b/xrpl/utils/txn_parser/__init__.py index 10fb1cf06..e8a4cfc14 100644 --- a/xrpl/utils/txn_parser/__init__.py +++ b/xrpl/utils/txn_parser/__init__.py @@ -1,5 +1,6 @@ """Functions to parse a transaction.""" from xrpl.utils.txn_parser.get_balance_changes import get_balance_changes +from xrpl.utils.txn_parser.get_final_balances import get_final_balances -__all__ = ["get_balance_changes"] +__all__ = ["get_balance_changes", "get_final_balances"] diff --git a/xrpl/utils/txn_parser/get_balance_changes.py b/xrpl/utils/txn_parser/get_balance_changes.py index b7b239b78..c82511ace 100644 --- a/xrpl/utils/txn_parser/get_balance_changes.py +++ b/xrpl/utils/txn_parser/get_balance_changes.py @@ -5,16 +5,14 @@ from xrpl.models import TransactionMetadata from xrpl.utils.txn_parser.utils import ( - BalanceChanges, - get_node_balance_changes, + AccountBalances, + NormalizedNode, + derive_account_balances, get_value, - group_by_account, - normalize_nodes, ) -from xrpl.utils.txn_parser.utils.nodes import NormalizedNode -def get_balance_changes(metadata: TransactionMetadata) -> List[BalanceChanges]: +def get_balance_changes(metadata: TransactionMetadata) -> List[AccountBalances]: """ Parse all balance changes from a transaction's metadata. @@ -25,12 +23,7 @@ def get_balance_changes(metadata: TransactionMetadata) -> List[BalanceChanges]: All balance changes caused by a transaction. The balance changes are grouped by the affected account addresses. """ - quantities = [ - quantity - for node in normalize_nodes(metadata) - for quantity in get_node_balance_changes(node, _compute_balance_change(node)) - ] - return group_by_account(quantities) + return derive_account_balances(metadata, _compute_balance_change) def _compute_balance_change(node: NormalizedNode) -> Optional[Decimal]: diff --git a/xrpl/utils/txn_parser/get_final_balances.py b/xrpl/utils/txn_parser/get_final_balances.py new file mode 100644 index 000000000..0fa634a43 --- /dev/null +++ b/xrpl/utils/txn_parser/get_final_balances.py @@ -0,0 +1,52 @@ +"""Parse final balances of every account involved in the given transaction.""" + +from decimal import Decimal +from typing import List, Optional + +from xrpl.models import TransactionMetadata +from xrpl.utils.txn_parser.utils import ( + AccountBalances, + NormalizedNode, + derive_account_balances, + get_value, +) + + +def get_final_balances(metadata: TransactionMetadata) -> List[AccountBalances]: + """ + Parse all final balances from a transaction's metadata. + + Args: + metadata: Transactions metadata. + + Returns: + All final balances caused by a transaction. + The final balances are grouped by the affected account addresses. + """ + return derive_account_balances(metadata, _compute_final_balance) + + +def _compute_final_balance(node: NormalizedNode) -> Optional[Decimal]: + """ + Get the final balance from a node. + + Args: + node: The affected node. + + Returns: + The final balance. + """ + value: Optional[Decimal] = None + new_fields = node.get("NewFields") + final_fields = node.get("FinalFields") + if new_fields is not None: + balance = new_fields.get("Balance") + if balance is not None: + value = get_value(balance) + elif final_fields is not None: + balance = final_fields.get("Balance") + if balance is not None: + value = get_value(balance) + if value is None or value == Decimal(0): + return None + return value diff --git a/xrpl/utils/txn_parser/utils/__init__.py b/xrpl/utils/txn_parser/utils/__init__.py index ba22aae76..f730c658b 100644 --- a/xrpl/utils/txn_parser/utils/__init__.py +++ b/xrpl/utils/txn_parser/utils/__init__.py @@ -1,17 +1,16 @@ """Utility functions for the transaction parser.""" from xrpl.utils.txn_parser.utils.balance_parser import ( - get_node_balance_changes, + derive_account_balances, get_value, - group_by_account, ) -from xrpl.utils.txn_parser.utils.nodes import normalize_nodes -from xrpl.utils.txn_parser.utils.types import BalanceChanges +from xrpl.utils.txn_parser.utils.nodes import NormalizedNode, normalize_nodes +from xrpl.utils.txn_parser.utils.types import AccountBalances __all__ = [ - "get_node_balance_changes", "get_value", - "group_by_account", + "derive_account_balances", + "NormalizedNode", "normalize_nodes", - "BalanceChanges", + "AccountBalances", ] diff --git a/xrpl/utils/txn_parser/utils/balance_parser.py b/xrpl/utils/txn_parser/utils/balance_parser.py index 5cd447437..a649c551a 100644 --- a/xrpl/utils/txn_parser/utils/balance_parser.py +++ b/xrpl/utils/txn_parser/utils/balance_parser.py @@ -1,17 +1,18 @@ """Helper functions for balance parser.""" from decimal import Decimal -from typing import Dict, List, Optional, Union +from typing import Callable, Dict, List, Optional, Union -from xrpl.utils.txn_parser.utils.nodes import NormalizedNode -from xrpl.utils.txn_parser.utils.types import Balance, BalanceChange, BalanceChanges +from xrpl.models.transactions.metadata import TransactionMetadata +from xrpl.utils.txn_parser.utils.nodes import NormalizedNode, normalize_nodes +from xrpl.utils.txn_parser.utils.types import AccountBalance, AccountBalances, Balance from xrpl.utils.xrp_conversions import drops_to_xrp def _get_xrp_quantity( node: NormalizedNode, value: Optional[Decimal], -) -> Optional[BalanceChange]: +) -> Optional[AccountBalance]: if value is None: return None absolute_value = value.copy_abs() @@ -24,7 +25,7 @@ def _get_xrp_quantity( if final_fields is not None: account = final_fields.get("Account") if account is not None: - return BalanceChange( + return AccountBalance( account=account, balance=Balance( currency="XRP", @@ -35,7 +36,7 @@ def _get_xrp_quantity( if new_fields is not None: account = new_fields.get("Account") if account is not None: - return BalanceChange( + return AccountBalance( account=account, balance=Balance( currency="XRP", @@ -45,15 +46,15 @@ def _get_xrp_quantity( return None -def _flip_trustline_perspective(balance_change: BalanceChange) -> BalanceChange: - balance = balance_change["balance"] +def _flip_trustline_perspective(account_balance: AccountBalance) -> AccountBalance: + balance = account_balance["balance"] negated_value = Decimal(balance["value"]).copy_negate() issuer = balance["issuer"] - return BalanceChange( + return AccountBalance( account=issuer, balance=Balance( currency=balance["currency"], - issuer=balance_change["account"], + issuer=account_balance["account"], value=f"{negated_value.normalize():f}", ), ) @@ -62,17 +63,16 @@ def _flip_trustline_perspective(balance_change: BalanceChange) -> BalanceChange: def _get_trustline_quantity( node: NormalizedNode, value: Optional[Decimal], -) -> List[BalanceChange]: +) -> List[AccountBalance]: """ - Computes the complete list of every balance that changed in the ledger - as a result of the given transaction. + Computes the complete list of every balance affected by the transaction. Args: node: The affected node. value: The currency amount value. Returns: - A list of balance changes. + A list of computed balances. """ if value is None: return [] @@ -93,7 +93,7 @@ def _get_trustline_quantity( and balance_currency is not None and high_limit_issuer is not None ): - result = BalanceChange( + result = AccountBalance( account=low_limit_issuer, balance=Balance( currency=balance_currency, @@ -105,16 +105,16 @@ def _get_trustline_quantity( return [] -def _group_balance_changes( - balance_changes: List[BalanceChange], -) -> Dict[str, List[BalanceChange]]: - grouped_balance_changes: Dict[str, List[BalanceChange]] = {} - for change in balance_changes: - account = change["account"] - if account not in grouped_balance_changes: - grouped_balance_changes[account] = [] - grouped_balance_changes[account].append(change) - return grouped_balance_changes +def _group_balances( + account_balances: List[AccountBalance], +) -> Dict[str, List[AccountBalance]]: + grouped_balances: Dict[str, List[AccountBalance]] = {} + for balance in account_balances: + account = balance["account"] + if account not in grouped_balances: + grouped_balances[account] = [] + grouped_balances[account].append(balance) + return grouped_balances def get_value(balance: Union[Dict[str, str], str]) -> Decimal: @@ -132,19 +132,19 @@ def get_value(balance: Union[Dict[str, str], str]) -> Decimal: return Decimal(balance["value"]) -def get_node_balance_changes( +def _get_node_balances( node: NormalizedNode, value: Optional[Decimal], -) -> List[BalanceChange]: +) -> List[AccountBalance]: """ - Retrieve the balance changes from a node. + Retrieve the balance from a node. Args: node: The affected node. value: The currency amount's value Returns: - A list of balance changes. + A list of balances. """ if node["LedgerEntryType"] == "AccountRoot": xrp_quantity = _get_xrp_quantity(node, value) @@ -157,28 +157,51 @@ def get_node_balance_changes( return [] -def group_by_account( - balance_changes: List[BalanceChange], -) -> List[BalanceChanges]: +def _group_by_account( + account_balances: List[AccountBalance], +) -> List[AccountBalances]: """ - Groups the balance changes in one list for each account. + Groups the account balances in one list for each account. Args: - balance_changes: All balance changes cause by a transaction. + account_balance: All computed balances cause by a transaction. Returns: - The grouped balance changes. + The grouped computed balances. """ - grouped = _group_balance_changes(balance_changes) + grouped = _group_balances(account_balances) result = [] for account, account_balances in grouped.items(): balances: List[Balance] = [] for balance in account_balances: balances.append(balance["balance"]) result.append( - BalanceChanges( + AccountBalances( account=account, balances=balances, ) ) return result + + +def derive_account_balances( + metadata: TransactionMetadata, + parser: Callable[[NormalizedNode], Optional[Decimal]], +) -> List[AccountBalances]: + """ + Derives the account balances from a node. + + Args: + metadata: Transactions metadata. + parser: The balance parser. + + Returns: + All balances affected by the transaction. + The balances are grouped by their accounts. + """ + quantities = [ + quantity + for node in normalize_nodes(metadata) + for quantity in _get_node_balances(node, parser(node)) + ] + return _group_by_account(quantities) diff --git a/xrpl/utils/txn_parser/utils/types.py b/xrpl/utils/txn_parser/utils/types.py index c35de1e07..169895dfc 100644 --- a/xrpl/utils/txn_parser/utils/types.py +++ b/xrpl/utils/txn_parser/utils/types.py @@ -25,17 +25,17 @@ class Balance(OptionalIssuer): """The amount of the currency.""" -class BalanceChange(TypedDict): - """A single balance change.""" +class AccountBalance(TypedDict): + """A single account balance.""" account: str """The affected account.""" balance: Balance - """The balance change.""" + """The balance.""" -class BalanceChanges(TypedDict): - """A model representing an account's balance changes.""" +class AccountBalances(TypedDict): + """A model representing an account's balances.""" account: str balances: List[Balance]