From 58a5e6439c58be9dd14772d091e559f8c5e7d4fa Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Mon, 8 Aug 2022 13:19:03 -0400 Subject: [PATCH 01/88] add AMMInstanceCreate --- .../binarycodec/definitions/definitions.json | 43 +++++++++++- xrpl/models/transactions/__init__.py | 2 + .../transactions/amm_instance_create.py | 68 +++++++++++++++++++ xrpl/models/transactions/transaction.py | 1 + .../transactions/types/transaction_type.py | 1 + 5 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 xrpl/models/transactions/amm_instance_create.py diff --git a/xrpl/core/binarycodec/definitions/definitions.json b/xrpl/core/binarycodec/definitions/definitions.json index 317e1feb7..c030a64e6 100644 --- a/xrpl/core/binarycodec/definitions/definitions.json +++ b/xrpl/core/binarycodec/definitions/definitions.json @@ -2160,6 +2160,46 @@ "isSigningField": true, "type": "STArray" } + ], + [ + "AMMAccount", + { + "nth": 1, + "isVLEncoded": true, + "isSerialized": true, + "isSigningField": true, + "type": "AccountID" + } + ], + [ + "Asset1", + { + "nth": 2, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "Asset2", + { + "nth": 3, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "TradingFee", + { + "nth": 4, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } ] ], "TRANSACTION_RESULTS": { @@ -2332,6 +2372,7 @@ "NFTokenAcceptOffer": 29, "EnableAmendment": 100, "SetFee": 101, - "UNLModify": 102 + "UNLModify": 102, + "AMMInstanceCreate": 103 } } diff --git a/xrpl/models/transactions/__init__.py b/xrpl/models/transactions/__init__.py index cd040e508..57d0a5a25 100644 --- a/xrpl/models/transactions/__init__.py +++ b/xrpl/models/transactions/__init__.py @@ -9,6 +9,7 @@ AccountSetFlag, AccountSetFlagInterface, ) +from xrpl.models.transactions.amm_instance_create import AMMInstanceCreate from xrpl.models.transactions.check_cancel import CheckCancel from xrpl.models.transactions.check_cash import CheckCash from xrpl.models.transactions.check_create import CheckCreate @@ -59,6 +60,7 @@ "AccountSet", "AccountSetFlag", "AccountSetFlagInterface", + "AMMInstanceCreate", "CheckCancel", "CheckCash", "CheckCreate", diff --git a/xrpl/models/transactions/amm_instance_create.py b/xrpl/models/transactions/amm_instance_create.py new file mode 100644 index 000000000..510778cd6 --- /dev/null +++ b/xrpl/models/transactions/amm_instance_create.py @@ -0,0 +1,68 @@ +"""Model for AMMInstanceCreate transaction type.""" +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import Dict, Optional + +from typing_extensions import Final + +from xrpl.models.amounts import Amount +from xrpl.models.required import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import require_kwargs_on_init + +_MAX_TRADING_FEE: Final[int] = 65000 + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AMMInstanceCreate(Transaction): + """ + AMMInstanceCreate is used to create AccountRoot and the corresponding AMM ledger entries. + This allows for the creation of only one AMM instance per unique asset pair. + """ + + amm_account: str = REQUIRED + """ + TODO: Remove when Greg T updates his PR. + """ + + asset1: Amount = REQUIRED + """ + Asset1 specifies one of the pool assets (XRP or token) of the AMM instance. + """ + + asset2: Amount = REQUIRED + """ + Asset2 specifies the other pool asset of the AMM instance. + """ + + trading_fee: int = REQUIRED + """ + TradingFee specifies the fee, in basis point, to be charged to the traders for the trades executed against the AMM instance. + Trading fee is a percentage of the trading volume. + Valid values for this field are between 0 and 65000 inclusive. + A value of 1 is equivalent to 1/10 bps or 0.001%, allowing trading fee between 0% and 65%. + """ + + transaction_type: TransactionType = field( + default=TransactionType.AMM_INSTANCE_CREATE, + init=False, + ) + + def _get_errors(self: AMMInstanceCreate) -> Dict[str, str]: + return { + key: value + for key, value in { + **super()._get_errors(), + "trading_fee": self._get_trading_fee_error(), + }.items() + if value is not None + } + + def _get_trading_fee_error(self: AMMInstanceCreate) -> Optional[str]: + if self.trading_fee > _MAX_TRADING_FEE: + return f"Must not be greater than {_MAX_TRADING_FEE}" + return None + diff --git a/xrpl/models/transactions/transaction.py b/xrpl/models/transactions/transaction.py index 57125da1c..949188b35 100644 --- a/xrpl/models/transactions/transaction.py +++ b/xrpl/models/transactions/transaction.py @@ -22,6 +22,7 @@ # This is used to make exceptions when converting dictionary keys to xrpl JSON # keys. We snake case keys, but some keys are abbreviations. _ABBREVIATIONS: Final[Dict[str, str]] = { + "amm": "AMM", "unl": "UNL", "id": "ID", "uri": "URI", diff --git a/xrpl/models/transactions/types/transaction_type.py b/xrpl/models/transactions/types/transaction_type.py index 3b8a0c809..a4ca30d69 100644 --- a/xrpl/models/transactions/types/transaction_type.py +++ b/xrpl/models/transactions/types/transaction_type.py @@ -8,6 +8,7 @@ class TransactionType(str, Enum): ACCOUNT_DELETE = "AccountDelete" ACCOUNT_SET = "AccountSet" + AMM_INSTANCE_CREATE = "AMMInstanceCreate" CHECK_CANCEL = "CheckCancel" CHECK_CASH = "CheckCash" CHECK_CREATE = "CheckCreate" From caa698f15ef55e472d216e26583981c7caae2690 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 9 Aug 2022 15:42:36 -0400 Subject: [PATCH 02/88] update definitions to get AMMInstanceCreate working --- .../binarycodec/definitions/definitions.json | 430 ++++++++++++++---- xrpl/models/transactions/__init__.py | 4 +- .../transactions/amm_instance_create.py | 11 +- .../transactions/types/transaction_type.py | 2 +- 4 files changed, 361 insertions(+), 86 deletions(-) diff --git a/xrpl/core/binarycodec/definitions/definitions.json b/xrpl/core/binarycodec/definitions/definitions.json index c030a64e6..ec6680dc1 100644 --- a/xrpl/core/binarycodec/definitions/definitions.json +++ b/xrpl/core/binarycodec/definitions/definitions.json @@ -41,9 +41,10 @@ "PayChannel": 120, "Check": 67, "DepositPreauth": 112, - "NegativeUNL": 78, + "NegativeUnl": 78, "NFTokenPage": 80, "NFTokenOffer": 55, + "Amm": 121, "Any": -3, "Child": -2, "Nickname": 110, @@ -271,6 +272,16 @@ "type": "UInt16" } ], + [ + "TradingFee", + { + "nth": 5, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt16" + } + ], [ "Version", { @@ -761,6 +772,46 @@ "type": "UInt32" } ], + [ + "FeeVal", + { + "nth": 47, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "VoteWeight", + { + "nth": 48, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "TimeStamp", + { + "nth": 49, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "DiscountedFee", + { + "nth": 50, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], [ "IndexNext", { @@ -981,6 +1032,26 @@ "type": "Hash160" } ], + [ + "TokenCurrency", + { + "nth": 5, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Hash160" + } + ], + [ + "TokenIssuer", + { + "nth": 6, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Hash160" + } + ], [ "LedgerHash", { @@ -1111,6 +1182,16 @@ "type": "Hash256" } ], + [ + "AMMHash", + { + "nth": 14, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Hash256" + } + ], [ "BookDirectory", { @@ -1381,6 +1462,46 @@ "type": "Amount" } ], + [ + "Asset1", + { + "nth": 11, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "Asset2", + { + "nth": 12, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "MinSlotPrice", + { + "nth": 13, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "MaxSlotPrice", + { + "nth": 14, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], [ "MinimumOffer", { @@ -1421,6 +1542,86 @@ "type": "Amount" } ], + [ + "Asset1In", + { + "nth": 20, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "Asset2In", + { + "nth": 21, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "Asset1Out", + { + "nth": 22, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "Asset2Out", + { + "nth": 23, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "LPTokens", + { + "nth": 24, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "EPrice", + { + "nth": 25, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "Price", + { + "nth": 26, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "LPTokenBalance", + { + "nth": 27, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], [ "PublicKey", { @@ -1751,6 +1952,16 @@ "type": "AccountID" } ], + [ + "AMMAccount", + { + "nth": 11, + "isVLEncoded": true, + "isSerialized": true, + "isSigningField": true, + "type": "AccountID" + } + ], [ "HookAccount", { @@ -1941,6 +2152,16 @@ "type": "STObject" } ], + [ + "AMM", + { + "nth": 15, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "STObject" + } + ], [ "Signer", { @@ -2021,6 +2242,66 @@ "type": "STObject" } ], + [ + "VoteEntry", + { + "nth": 25, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "STObject" + } + ], + [ + "AuctionSlot", + { + "nth": 27, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "STObject" + } + ], + [ + "AuthAccount", + { + "nth": 28, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "STObject" + } + ], + [ + "AMMToken", + { + "nth": 29, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "STObject" + } + ], + [ + "Token1", + { + "nth": 30, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "STObject" + } + ], + [ + "Token2", + { + "nth": 31, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "STObject" + } + ], [ "Signers", { @@ -2112,9 +2393,9 @@ } ], [ - "Majorities", + "VoteSlots", { - "nth": 16, + "nth": 14, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -2122,9 +2403,9 @@ } ], [ - "DisabledValidators", + "AuthAccounts", { - "nth": 17, + "nth": 15, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -2132,9 +2413,9 @@ } ], [ - "HookExecutions", + "Majorities", { - "nth": 18, + "nth": 16, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -2142,9 +2423,9 @@ } ], [ - "HookParameters", + "DisabledValidators", { - "nth": 19, + "nth": 17, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -2152,9 +2433,9 @@ } ], [ - "HookGrants", + "HookExecutions", { - "nth": 20, + "nth": 18, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -2162,43 +2443,23 @@ } ], [ - "AMMAccount", - { - "nth": 1, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "AccountID" - } - ], - [ - "Asset1", - { - "nth": 2, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], - [ - "Asset2", + "HookParameters", { - "nth": 3, + "nth": 19, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "Amount" + "type": "STArray" } ], [ - "TradingFee", + "HookGrants", { - "nth": 4, + "nth": 20, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, - "type": "UInt32" + "type": "STArray" } ] ], @@ -2218,43 +2479,45 @@ "telCAN_NOT_QUEUE_FULL": -387, "temMALFORMED": -299, - "temBAD_AMOUNT": -298, - "temBAD_CURRENCY": -297, - "temBAD_EXPIRATION": -296, - "temBAD_FEE": -295, - "temBAD_ISSUER": -294, - "temBAD_LIMIT": -293, - "temBAD_OFFER": -292, - "temBAD_PATH": -291, - "temBAD_PATH_LOOP": -290, - "temBAD_REGKEY": -289, - "temBAD_SEND_XRP_LIMIT": -288, - "temBAD_SEND_XRP_MAX": -287, - "temBAD_SEND_XRP_NO_DIRECT": -286, - "temBAD_SEND_XRP_PARTIAL": -285, - "temBAD_SEND_XRP_PATHS": -284, - "temBAD_SEQUENCE": -283, - "temBAD_SIGNATURE": -282, - "temBAD_SRC_ACCOUNT": -281, - "temBAD_TRANSFER_RATE": -280, - "temDST_IS_SRC": -279, - "temDST_NEEDED": -278, - "temINVALID": -277, - "temINVALID_FLAG": -276, - "temREDUNDANT": -275, - "temRIPPLE_EMPTY": -274, - "temDISABLED": -273, - "temBAD_SIGNER": -272, - "temBAD_QUORUM": -271, - "temBAD_WEIGHT": -270, - "temBAD_TICK_SIZE": -269, - "temINVALID_ACCOUNT_ID": -268, - "temCANNOT_PREAUTH_SELF": -267, - "temINVALID_COUNT": -266, - "temUNCERTAIN": -265, - "temUNKNOWN": -264, - "temSEQ_AND_TICKET": -263, - "temBAD_NFTOKEN_TRANSFER_FEE": -262, + "temBAD_AMM_OPTIONS": -298, + "temBAD_AMM_TOKENS": -297, + "temBAD_AMOUNT": -296, + "temBAD_CURRENCY": -295, + "temBAD_EXPIRATION": -294, + "temBAD_FEE": -293, + "temBAD_ISSUER": -292, + "temBAD_LIMIT": -291, + "temBAD_OFFER": -290, + "temBAD_PATH": -289, + "temBAD_PATH_LOOP": -288, + "temBAD_REGKEY": -287, + "temBAD_SEND_XRP_LIMIT": -286, + "temBAD_SEND_XRP_MAX": -285, + "temBAD_SEND_XRP_NO_DIRECT": -284, + "temBAD_SEND_XRP_PARTIAL": -283, + "temBAD_SEND_XRP_PATHS": -282, + "temBAD_SEQUENCE": -281, + "temBAD_SIGNATURE": -280, + "temBAD_SRC_ACCOUNT": -279, + "temBAD_TRANSFER_RATE": -278, + "temDST_IS_SRC": -277, + "temDST_NEEDED": -276, + "temINVALID": -275, + "temINVALID_FLAG": -274, + "temREDUNDANT": -273, + "temRIPPLE_EMPTY": -272, + "temDISABLED": -271, + "temBAD_SIGNER": -270, + "temBAD_QUORUM": -269, + "temBAD_WEIGHT": -268, + "temBAD_TICK_SIZE": -267, + "temINVALID_ACCOUNT_ID": -266, + "temCANNOT_PREAUTH_SELF": -265, + "temINVALID_COUNT": -264, + "temUNCERTAIN": -263, + "temUNKNOWN": -262, + "temSEQ_AND_TICKET": -261, + "temBAD_NFTOKEN_TRANSFER_FEE": -260, "tefFAILURE": -199, "tefALREADY": -198, @@ -2338,7 +2601,16 @@ "tecCANT_ACCEPT_OWN_NFTOKEN_OFFER": 158, "tecINSUFFICIENT_FUNDS": 159, "tecOBJECT_NOT_FOUND": 160, - "tecINSUFFICIENT_PAYMENT": 161 + "tecINSUFFICIENT_PAYMENT": 161, + "tecUNFUNDED_AMM": 162, + "tecAMM_BALANCE": 163, + "tecAMM_FAILED_DEPOSIT": 164, + "tecAMM_FAILED_WITHDRAW": 165, + "tecAMM_INVALID_TOKENS": 166, + "tecAMM_EXISTS": 167, + "tecAMM_FAILED_BID": 168, + "tecAMM_DIRECT_PAYMENT": 169, + "tecAMM_FAILED_VOTE": 170 }, "TRANSACTION_TYPES": { "Invalid": -1, @@ -2370,9 +2642,13 @@ "NFTokenCreateOffer": 27, "NFTokenCancelOffer": 28, "NFTokenAcceptOffer": 29, + "AmmCreate": 35, + "AmmDeposit": 36, + "AmmWithdraw": 37, + "AmmVote": 38, + "AmmBid": 39, "EnableAmendment": 100, "SetFee": 101, - "UNLModify": 102, - "AMMInstanceCreate": 103 + "UNLModify": 102 } } diff --git a/xrpl/models/transactions/__init__.py b/xrpl/models/transactions/__init__.py index 57d0a5a25..795c68bd3 100644 --- a/xrpl/models/transactions/__init__.py +++ b/xrpl/models/transactions/__init__.py @@ -9,7 +9,7 @@ AccountSetFlag, AccountSetFlagInterface, ) -from xrpl.models.transactions.amm_instance_create import AMMInstanceCreate +from xrpl.models.transactions.amm_instance_create import AmmCreate from xrpl.models.transactions.check_cancel import CheckCancel from xrpl.models.transactions.check_cash import CheckCash from xrpl.models.transactions.check_create import CheckCreate @@ -60,7 +60,7 @@ "AccountSet", "AccountSetFlag", "AccountSetFlagInterface", - "AMMInstanceCreate", + "AmmCreate", "CheckCancel", "CheckCash", "CheckCreate", diff --git a/xrpl/models/transactions/amm_instance_create.py b/xrpl/models/transactions/amm_instance_create.py index 510778cd6..0e586bdc6 100644 --- a/xrpl/models/transactions/amm_instance_create.py +++ b/xrpl/models/transactions/amm_instance_create.py @@ -1,4 +1,4 @@ -"""Model for AMMInstanceCreate transaction type.""" +"""Model for AmmCreate transaction type.""" from __future__ import annotations from dataclasses import dataclass, field @@ -17,9 +17,9 @@ @require_kwargs_on_init @dataclass(frozen=True) -class AMMInstanceCreate(Transaction): +class AmmCreate(Transaction): """ - AMMInstanceCreate is used to create AccountRoot and the corresponding AMM ledger entries. + AmmCreate is used to create AccountRoot and the corresponding AMM ledger entries. This allows for the creation of only one AMM instance per unique asset pair. """ @@ -51,7 +51,7 @@ class AMMInstanceCreate(Transaction): init=False, ) - def _get_errors(self: AMMInstanceCreate) -> Dict[str, str]: + def _get_errors(self: AmmCreate) -> Dict[str, str]: return { key: value for key, value in { @@ -61,8 +61,7 @@ def _get_errors(self: AMMInstanceCreate) -> Dict[str, str]: if value is not None } - def _get_trading_fee_error(self: AMMInstanceCreate) -> Optional[str]: + def _get_trading_fee_error(self: AmmCreate) -> Optional[str]: if self.trading_fee > _MAX_TRADING_FEE: return f"Must not be greater than {_MAX_TRADING_FEE}" return None - diff --git a/xrpl/models/transactions/types/transaction_type.py b/xrpl/models/transactions/types/transaction_type.py index a4ca30d69..7f2ce6ec7 100644 --- a/xrpl/models/transactions/types/transaction_type.py +++ b/xrpl/models/transactions/types/transaction_type.py @@ -8,7 +8,7 @@ class TransactionType(str, Enum): ACCOUNT_DELETE = "AccountDelete" ACCOUNT_SET = "AccountSet" - AMM_INSTANCE_CREATE = "AMMInstanceCreate" + AMM_INSTANCE_CREATE = "AmmCreate" CHECK_CANCEL = "CheckCancel" CHECK_CASH = "CheckCash" CHECK_CREATE = "CheckCreate" From 0676bc11dba754e82c02c33649d9cb953ba3c706 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 9 Aug 2022 15:55:47 -0400 Subject: [PATCH 03/88] fix lint errors --- xrpl/models/transactions/amm_instance_create.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/xrpl/models/transactions/amm_instance_create.py b/xrpl/models/transactions/amm_instance_create.py index 0e586bdc6..c1c229e84 100644 --- a/xrpl/models/transactions/amm_instance_create.py +++ b/xrpl/models/transactions/amm_instance_create.py @@ -23,27 +23,29 @@ class AmmCreate(Transaction): This allows for the creation of only one AMM instance per unique asset pair. """ - amm_account: str = REQUIRED + amm_account: str = REQUIRED # type: ignore """ TODO: Remove when Greg T updates his PR. """ - asset1: Amount = REQUIRED + asset1: Amount = REQUIRED # type: ignore """ Asset1 specifies one of the pool assets (XRP or token) of the AMM instance. """ - asset2: Amount = REQUIRED + asset2: Amount = REQUIRED # type: ignore """ Asset2 specifies the other pool asset of the AMM instance. """ - trading_fee: int = REQUIRED + trading_fee: int = REQUIRED # type: ignore """ - TradingFee specifies the fee, in basis point, to be charged to the traders for the trades executed against the AMM instance. + TradingFee specifies the fee, in basis point, to be charged + to the traders for the trades executed against the AMM instance. Trading fee is a percentage of the trading volume. Valid values for this field are between 0 and 65000 inclusive. - A value of 1 is equivalent to 1/10 bps or 0.001%, allowing trading fee between 0% and 65%. + A value of 1 is equivalent to 1/10 bps or 0.001%, allowing trading fee + between 0% and 65%. """ transaction_type: TransactionType = field( From c1424f8ad006c397424fa7862514637d88f18ece Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 9 Aug 2022 16:03:23 -0400 Subject: [PATCH 04/88] add unit test for Instance Create --- .../transactions/test_amm_instance_create.py | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 tests/unit/models/transactions/test_amm_instance_create.py diff --git a/tests/unit/models/transactions/test_amm_instance_create.py b/tests/unit/models/transactions/test_amm_instance_create.py new file mode 100644 index 000000000..e90c7ef43 --- /dev/null +++ b/tests/unit/models/transactions/test_amm_instance_create.py @@ -0,0 +1,61 @@ +from sys import maxsize +from unittest import TestCase + +from xrpl.models.amounts import IssuedCurrencyAmount +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions import AmmCreate + +_ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" +_AMM_ACCOUNT = "rPvNKfdCNj9NpNxtFtqqfqCWtVzzbKrbL7" +_IOU_ISSUER = "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9" +_FEE = "0.00001" + + +class TestAMMInstanceCreate(TestCase): + def test_trading_fee_too_high(self): + with self.assertRaises(XRPLModelException): + AmmCreate( + account=_ACCOUNT, + amm_account=_AMM_ACCOUNT, + fee=_FEE, + asset1='1000', + asset2=IssuedCurrencyAmount( + currency="USD", + issuer=_IOU_ISSUER, + value="1000" + ), + trading_fee=maxsize, + ) + + def test_to_xrpl(self): + tx = AmmCreate( + account=_ACCOUNT, + amm_account=_AMM_ACCOUNT, + sequence=1337, + fee=_FEE, + asset1='1000', + asset2=IssuedCurrencyAmount( + currency="USD", + issuer=_IOU_ISSUER, + value="1000" + ), + trading_fee=12, + ) + expected = { + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "AMMAccount": "rPvNKfdCNj9NpNxtFtqqfqCWtVzzbKrbL7", + "Asset1": "1000", + "Asset2": { + "currency": "USD", + "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", + "value": "1000", + }, + "Fee": "0.00001", + "TransactionType": "AmmCreate", + "Sequence": 1337, + "SigningPubKey": "", + "TradingFee": 12, + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + From b90626f347b1a9cf1b6cc79adb53d2438bb30e63 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 9 Aug 2022 16:07:07 -0400 Subject: [PATCH 05/88] fix lint errors --- .../transactions/test_amm_instance_create.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/tests/unit/models/transactions/test_amm_instance_create.py b/tests/unit/models/transactions/test_amm_instance_create.py index e90c7ef43..f84d0c2f1 100644 --- a/tests/unit/models/transactions/test_amm_instance_create.py +++ b/tests/unit/models/transactions/test_amm_instance_create.py @@ -18,26 +18,22 @@ def test_trading_fee_too_high(self): account=_ACCOUNT, amm_account=_AMM_ACCOUNT, fee=_FEE, - asset1='1000', + asset1="1000", asset2=IssuedCurrencyAmount( - currency="USD", - issuer=_IOU_ISSUER, - value="1000" + currency="USD", issuer=_IOU_ISSUER, value="1000" ), trading_fee=maxsize, ) - + def test_to_xrpl(self): tx = AmmCreate( account=_ACCOUNT, amm_account=_AMM_ACCOUNT, sequence=1337, fee=_FEE, - asset1='1000', + asset1="1000", asset2=IssuedCurrencyAmount( - currency="USD", - issuer=_IOU_ISSUER, - value="1000" + currency="USD", issuer=_IOU_ISSUER, value="1000" ), trading_fee=12, ) @@ -58,4 +54,3 @@ def test_to_xrpl(self): "Flags": 0, } self.assertEqual(tx.to_xrpl(), expected) - From 1309478a562d8715f20a5165023105be7c317c9b Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 9 Aug 2022 18:22:56 -0400 Subject: [PATCH 06/88] fix definitions and change AmmCreate to AMMInstanceCreate --- .../models/transactions/test_amm_instance_create.py | 8 ++++---- xrpl/core/binarycodec/definitions/definitions.json | 10 +++++----- xrpl/models/transactions/__init__.py | 4 ++-- xrpl/models/transactions/amm_instance_create.py | 10 +++++----- xrpl/models/transactions/types/transaction_type.py | 2 +- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/unit/models/transactions/test_amm_instance_create.py b/tests/unit/models/transactions/test_amm_instance_create.py index f84d0c2f1..c1f1afec5 100644 --- a/tests/unit/models/transactions/test_amm_instance_create.py +++ b/tests/unit/models/transactions/test_amm_instance_create.py @@ -3,7 +3,7 @@ from xrpl.models.amounts import IssuedCurrencyAmount from xrpl.models.exceptions import XRPLModelException -from xrpl.models.transactions import AmmCreate +from xrpl.models.transactions import AMMInstanceCreate _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" _AMM_ACCOUNT = "rPvNKfdCNj9NpNxtFtqqfqCWtVzzbKrbL7" @@ -14,7 +14,7 @@ class TestAMMInstanceCreate(TestCase): def test_trading_fee_too_high(self): with self.assertRaises(XRPLModelException): - AmmCreate( + AMMInstanceCreate( account=_ACCOUNT, amm_account=_AMM_ACCOUNT, fee=_FEE, @@ -26,7 +26,7 @@ def test_trading_fee_too_high(self): ) def test_to_xrpl(self): - tx = AmmCreate( + tx = AMMInstanceCreate( account=_ACCOUNT, amm_account=_AMM_ACCOUNT, sequence=1337, @@ -47,7 +47,7 @@ def test_to_xrpl(self): "value": "1000", }, "Fee": "0.00001", - "TransactionType": "AmmCreate", + "TransactionType": "AMMInstanceCreate", "Sequence": 1337, "SigningPubKey": "", "TradingFee": 12, diff --git a/xrpl/core/binarycodec/definitions/definitions.json b/xrpl/core/binarycodec/definitions/definitions.json index ec6680dc1..9978633e0 100644 --- a/xrpl/core/binarycodec/definitions/definitions.json +++ b/xrpl/core/binarycodec/definitions/definitions.json @@ -2642,11 +2642,11 @@ "NFTokenCreateOffer": 27, "NFTokenCancelOffer": 28, "NFTokenAcceptOffer": 29, - "AmmCreate": 35, - "AmmDeposit": 36, - "AmmWithdraw": 37, - "AmmVote": 38, - "AmmBid": 39, + "AMMInstanceCreate": 35, + "AMMDeposit": 36, + "AMMWithdraw": 37, + "AMMVote": 38, + "AMMBid": 39, "EnableAmendment": 100, "SetFee": 101, "UNLModify": 102 diff --git a/xrpl/models/transactions/__init__.py b/xrpl/models/transactions/__init__.py index 795c68bd3..57d0a5a25 100644 --- a/xrpl/models/transactions/__init__.py +++ b/xrpl/models/transactions/__init__.py @@ -9,7 +9,7 @@ AccountSetFlag, AccountSetFlagInterface, ) -from xrpl.models.transactions.amm_instance_create import AmmCreate +from xrpl.models.transactions.amm_instance_create import AMMInstanceCreate from xrpl.models.transactions.check_cancel import CheckCancel from xrpl.models.transactions.check_cash import CheckCash from xrpl.models.transactions.check_create import CheckCreate @@ -60,7 +60,7 @@ "AccountSet", "AccountSetFlag", "AccountSetFlagInterface", - "AmmCreate", + "AMMInstanceCreate", "CheckCancel", "CheckCash", "CheckCreate", diff --git a/xrpl/models/transactions/amm_instance_create.py b/xrpl/models/transactions/amm_instance_create.py index c1c229e84..89dd8b06f 100644 --- a/xrpl/models/transactions/amm_instance_create.py +++ b/xrpl/models/transactions/amm_instance_create.py @@ -1,4 +1,4 @@ -"""Model for AmmCreate transaction type.""" +"""Model for AMMInstanceCreate transaction type.""" from __future__ import annotations from dataclasses import dataclass, field @@ -17,9 +17,9 @@ @require_kwargs_on_init @dataclass(frozen=True) -class AmmCreate(Transaction): +class AMMInstanceCreate(Transaction): """ - AmmCreate is used to create AccountRoot and the corresponding AMM ledger entries. + AMMInstanceCreate is used to create AccountRoot and the corresponding AMM ledger entries. This allows for the creation of only one AMM instance per unique asset pair. """ @@ -53,7 +53,7 @@ class AmmCreate(Transaction): init=False, ) - def _get_errors(self: AmmCreate) -> Dict[str, str]: + def _get_errors(self: AMMInstanceCreate) -> Dict[str, str]: return { key: value for key, value in { @@ -63,7 +63,7 @@ def _get_errors(self: AmmCreate) -> Dict[str, str]: if value is not None } - def _get_trading_fee_error(self: AmmCreate) -> Optional[str]: + def _get_trading_fee_error(self: AMMInstanceCreate) -> Optional[str]: if self.trading_fee > _MAX_TRADING_FEE: return f"Must not be greater than {_MAX_TRADING_FEE}" return None diff --git a/xrpl/models/transactions/types/transaction_type.py b/xrpl/models/transactions/types/transaction_type.py index 7f2ce6ec7..a4ca30d69 100644 --- a/xrpl/models/transactions/types/transaction_type.py +++ b/xrpl/models/transactions/types/transaction_type.py @@ -8,7 +8,7 @@ class TransactionType(str, Enum): ACCOUNT_DELETE = "AccountDelete" ACCOUNT_SET = "AccountSet" - AMM_INSTANCE_CREATE = "AmmCreate" + AMM_INSTANCE_CREATE = "AMMInstanceCreate" CHECK_CANCEL = "CheckCancel" CHECK_CASH = "CheckCash" CHECK_CREATE = "CheckCreate" From 514cda07934f15a6fc7961a8a7f5ae1781e31c7a Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 9 Aug 2022 18:26:50 -0400 Subject: [PATCH 07/88] fix lint error --- xrpl/models/transactions/amm_instance_create.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xrpl/models/transactions/amm_instance_create.py b/xrpl/models/transactions/amm_instance_create.py index 89dd8b06f..eed838956 100644 --- a/xrpl/models/transactions/amm_instance_create.py +++ b/xrpl/models/transactions/amm_instance_create.py @@ -19,7 +19,8 @@ @dataclass(frozen=True) class AMMInstanceCreate(Transaction): """ - AMMInstanceCreate is used to create AccountRoot and the corresponding AMM ledger entries. + AMMInstanceCreate is used to create AccountRoot and the corresponding AMM + ledger entries. This allows for the creation of only one AMM instance per unique asset pair. """ From 45e7e909f42abd66f71b3423bd35e6cb05847bd0 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 10 Aug 2022 00:53:53 -0400 Subject: [PATCH 08/88] add AMMInfo --- tests/unit/models/requests/test_amm_info.py | 42 +++++++++++++++++++++ xrpl/models/requests/__init__.py | 2 + xrpl/models/requests/amm_info.py | 37 ++++++++++++++++++ xrpl/models/requests/request.py | 3 ++ 4 files changed, 84 insertions(+) create mode 100644 tests/unit/models/requests/test_amm_info.py create mode 100644 xrpl/models/requests/amm_info.py diff --git a/tests/unit/models/requests/test_amm_info.py b/tests/unit/models/requests/test_amm_info.py new file mode 100644 index 000000000..1d503d5c9 --- /dev/null +++ b/tests/unit/models/requests/test_amm_info.py @@ -0,0 +1,42 @@ +from unittest import TestCase + +from xrpl.models.amounts import IssuedCurrencyAmount +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.requests import AMMInfo + +_AMM_HASH = "5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3" +_ASSET_1 = "1000" +_ASSET_2 = IssuedCurrencyAmount( + currency="USD", issuer="rN6zcSynkRnf8zcgTVrRL8K7r4ovE7J4Zj", value="100" +) + + +class TestAMMInfo(TestCase): + def test_amm_hash(self): + request = AMMInfo( + AMMHash=_AMM_HASH, + ) + self.assertTrue(request.is_valid()) + + def test_asset1_asset2(self): + request = AMMInfo( + Asset1=_ASSET_1, + Asset2=_ASSET_2, + ) + self.assertTrue(request.is_valid()) + + def test_no_params_is_invalid(self): + with self.assertRaises(XRPLModelException): + AMMInfo() + + def test_missing_asset1_is_invalid(self): + with self.assertRaises(XRPLModelException): + AMMInfo( + Asset2=_ASSET_2, + ) + + def test_missing_asset2_is_invalid(self): + with self.assertRaises(XRPLModelException): + AMMInfo( + Asset1=_ASSET_1, + ) diff --git a/xrpl/models/requests/__init__.py b/xrpl/models/requests/__init__.py index ae575b383..c61449c56 100644 --- a/xrpl/models/requests/__init__.py +++ b/xrpl/models/requests/__init__.py @@ -8,6 +8,7 @@ from xrpl.models.requests.account_objects import AccountObjects, AccountObjectType from xrpl.models.requests.account_offers import AccountOffers from xrpl.models.requests.account_tx import AccountTx +from xrpl.models.requests.amm_info import AMMInfo from xrpl.models.requests.book_offers import BookOffers from xrpl.models.requests.channel_authorize import ChannelAuthorize from xrpl.models.requests.channel_verify import ChannelVerify @@ -52,6 +53,7 @@ "AccountObjectType", "AccountOffers", "AccountTx", + "AMMInfo", "BookOffers", "ChannelAuthorize", "ChannelVerify", diff --git a/xrpl/models/requests/amm_info.py b/xrpl/models/requests/amm_info.py new file mode 100644 index 000000000..f558a9a08 --- /dev/null +++ b/xrpl/models/requests/amm_info.py @@ -0,0 +1,37 @@ +"""This request retrieves information about an AMM instance.""" +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import Dict, Optional + +from xrpl.models.amounts import Amount +from xrpl.models.requests.request import Request, RequestMethod +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AMMInfo(Request): + """This request retrieves information about an AMM instance.""" + + method: RequestMethod = field(default=RequestMethod.AMM_INFO, init=False) + AMMHash: Optional[str] = None + Asset1: Optional[Amount] = None + Asset2: Optional[Amount] = None + + def _get_errors(self: AMMInfo) -> Dict[str, str]: + errors = super()._get_errors() + if self.AMMHash is None: + if self.Asset1 is None and self.Asset2 is None: + errors[ + "AMMInfo" + ] = "Must set either `AMMHash` or both `Asset1` and `Asset2`" + elif self.Asset1 is None and self.Asset2 is not None: + errors[ + "AMMInfo" + ] = "Missing `Asset1`. Must set both `Asset1` and `Asset2`" + elif self.Asset1 is not None and self.Asset2 is None: + errors[ + "AMMInfo" + ] = "Missing `Asset2`. Must set both `Asset1` and `Asset2`" + return errors diff --git a/xrpl/models/requests/request.py b/xrpl/models/requests/request.py index 325ddd682..57324a473 100644 --- a/xrpl/models/requests/request.py +++ b/xrpl/models/requests/request.py @@ -76,6 +76,9 @@ class RequestMethod(str, Enum): # sidechain methods FEDERATOR_INFO = "federator_info" + # amm methods + AMM_INFO = "amm_info" + # generic unknown/unsupported request # (there is no XRPL analog, this model is specific to xrpl-py) GENERIC_REQUEST = "zzgeneric_request" From f451d3cf137408a6518897fd3a043536090b485e Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 10 Aug 2022 00:59:52 -0400 Subject: [PATCH 09/88] update AMMInfo docstring --- xrpl/models/requests/amm_info.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/xrpl/models/requests/amm_info.py b/xrpl/models/requests/amm_info.py index f558a9a08..12a126022 100644 --- a/xrpl/models/requests/amm_info.py +++ b/xrpl/models/requests/amm_info.py @@ -12,7 +12,11 @@ @require_kwargs_on_init @dataclass(frozen=True) class AMMInfo(Request): - """This request retrieves information about an AMM instance.""" + """ + This request retrieves information about an AMM instance. + + Must provide either AMMHash or both Asset1 and Asset2 params. + """ method: RequestMethod = field(default=RequestMethod.AMM_INFO, init=False) AMMHash: Optional[str] = None From 1614e1784b5cc1286341a09aa6daef24e6b1eb5c Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 10 Aug 2022 01:15:05 -0400 Subject: [PATCH 10/88] add docstring to AMMInfo params --- xrpl/models/requests/amm_info.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/xrpl/models/requests/amm_info.py b/xrpl/models/requests/amm_info.py index 12a126022..b5c965453 100644 --- a/xrpl/models/requests/amm_info.py +++ b/xrpl/models/requests/amm_info.py @@ -18,10 +18,22 @@ class AMMInfo(Request): Must provide either AMMHash or both Asset1 and Asset2 params. """ - method: RequestMethod = field(default=RequestMethod.AMM_INFO, init=False) AMMHash: Optional[str] = None + """ + AMMHash is a hash that uniquely identifies the AMM instance. + """ + Asset1: Optional[Amount] = None + """ + Asset1 specifies one of the pool assets (XRP or token) of the AMM instance. + """ + Asset2: Optional[Amount] = None + """ + Asset2 specifies the other pool asset of the AMM instance. + """ + + method: RequestMethod = field(default=RequestMethod.AMM_INFO, init=False) def _get_errors(self: AMMInfo) -> Dict[str, str]: errors = super()._get_errors() From d20830ea2220b9bbb53de0a2f115fdeec9d9c73b Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 10 Aug 2022 15:32:52 -0400 Subject: [PATCH 11/88] update definitions.json --- xrpl/core/binarycodec/definitions/definitions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xrpl/core/binarycodec/definitions/definitions.json b/xrpl/core/binarycodec/definitions/definitions.json index 9978633e0..18499a0e4 100644 --- a/xrpl/core/binarycodec/definitions/definitions.json +++ b/xrpl/core/binarycodec/definitions/definitions.json @@ -41,7 +41,7 @@ "PayChannel": 120, "Check": 67, "DepositPreauth": 112, - "NegativeUnl": 78, + "NegativeUNL": 78, "NFTokenPage": 80, "NFTokenOffer": 55, "Amm": 121, From 3c99f2d14abaf241b20554c40a693a4f83bd6253 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 10 Aug 2022 16:02:54 -0400 Subject: [PATCH 12/88] remove AMMAccount from AMMInstanceCreate model --- tests/unit/models/transactions/test_amm_instance_create.py | 4 ---- xrpl/core/binarycodec/definitions/definitions.json | 2 +- xrpl/models/transactions/amm_instance_create.py | 5 ----- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/tests/unit/models/transactions/test_amm_instance_create.py b/tests/unit/models/transactions/test_amm_instance_create.py index c1f1afec5..151f347db 100644 --- a/tests/unit/models/transactions/test_amm_instance_create.py +++ b/tests/unit/models/transactions/test_amm_instance_create.py @@ -6,7 +6,6 @@ from xrpl.models.transactions import AMMInstanceCreate _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" -_AMM_ACCOUNT = "rPvNKfdCNj9NpNxtFtqqfqCWtVzzbKrbL7" _IOU_ISSUER = "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9" _FEE = "0.00001" @@ -16,7 +15,6 @@ def test_trading_fee_too_high(self): with self.assertRaises(XRPLModelException): AMMInstanceCreate( account=_ACCOUNT, - amm_account=_AMM_ACCOUNT, fee=_FEE, asset1="1000", asset2=IssuedCurrencyAmount( @@ -28,7 +26,6 @@ def test_trading_fee_too_high(self): def test_to_xrpl(self): tx = AMMInstanceCreate( account=_ACCOUNT, - amm_account=_AMM_ACCOUNT, sequence=1337, fee=_FEE, asset1="1000", @@ -39,7 +36,6 @@ def test_to_xrpl(self): ) expected = { "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "AMMAccount": "rPvNKfdCNj9NpNxtFtqqfqCWtVzzbKrbL7", "Asset1": "1000", "Asset2": { "currency": "USD", diff --git a/xrpl/core/binarycodec/definitions/definitions.json b/xrpl/core/binarycodec/definitions/definitions.json index 18499a0e4..c3b6fce4f 100644 --- a/xrpl/core/binarycodec/definitions/definitions.json +++ b/xrpl/core/binarycodec/definitions/definitions.json @@ -2405,7 +2405,7 @@ [ "AuthAccounts", { - "nth": 15, + "nth": 21, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, diff --git a/xrpl/models/transactions/amm_instance_create.py b/xrpl/models/transactions/amm_instance_create.py index eed838956..49b94cf58 100644 --- a/xrpl/models/transactions/amm_instance_create.py +++ b/xrpl/models/transactions/amm_instance_create.py @@ -24,11 +24,6 @@ class AMMInstanceCreate(Transaction): This allows for the creation of only one AMM instance per unique asset pair. """ - amm_account: str = REQUIRED # type: ignore - """ - TODO: Remove when Greg T updates his PR. - """ - asset1: Amount = REQUIRED # type: ignore """ Asset1 specifies one of the pool assets (XRP or token) of the AMM instance. From 2644ade359cde4cbec1f9173d72263e24e9375da Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Sat, 13 Aug 2022 23:49:17 -0400 Subject: [PATCH 13/88] add AMMDeposit --- .../models/transactions/test_amm_deposit.py | 151 ++++++++++++++++++ xrpl/models/base_model.py | 2 +- xrpl/models/transactions/__init__.py | 2 + xrpl/models/transactions/amm_deposit.py | 70 ++++++++ xrpl/models/transactions/transaction.py | 5 +- .../transactions/types/transaction_type.py | 1 + 6 files changed, 228 insertions(+), 3 deletions(-) create mode 100644 tests/unit/models/transactions/test_amm_deposit.py create mode 100644 xrpl/models/transactions/amm_deposit.py diff --git a/tests/unit/models/transactions/test_amm_deposit.py b/tests/unit/models/transactions/test_amm_deposit.py new file mode 100644 index 000000000..746601c93 --- /dev/null +++ b/tests/unit/models/transactions/test_amm_deposit.py @@ -0,0 +1,151 @@ +from unittest import TestCase + +from xrpl.models.amounts import IssuedCurrencyAmount +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions import AMMDeposit + +_ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" +_AMM_HASH = "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883" +_AMOUNT = "1000" +_LPTOKEN_CURRENCY = "B3813FCAB4EE68B3D0D735D6849465A9113EE048" +_LPTOKEN_ISSUER = "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg" + + +class TestAMMDeposit(TestCase): + def test_to_xrpl_lptokens(self): + tx = AMMDeposit( + account=_ACCOUNT, + sequence=1337, + amm_hash=_AMM_HASH, + lptokens=IssuedCurrencyAmount( + currency=_LPTOKEN_CURRENCY, + issuer=_LPTOKEN_ISSUER, + value=_AMOUNT, + ), + ) + expected = { + "AMMHash": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "LPTokens": { + "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", + "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", + "value": "1000", + }, + "TransactionType": "AMMDeposit", + "Sequence": 1337, + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_asset1in(self): + tx = AMMDeposit( + account=_ACCOUNT, + sequence=1337, + amm_hash=_AMM_HASH, + asset1_in=_AMOUNT, + ) + expected = { + "AMMHash": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "Asset1In": "1000", + "TransactionType": "AMMDeposit", + "Sequence": 1337, + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_asset1in_asset2_in(self): + tx = AMMDeposit( + account=_ACCOUNT, + sequence=1337, + amm_hash=_AMM_HASH, + asset1_in=_AMOUNT, + asset2_in="500", + ) + expected = { + "AMMHash": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "Asset1In": "1000", + "Asset2In": "500", + "TransactionType": "AMMDeposit", + "Sequence": 1337, + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_asset1in_lptokens(self): + tx = AMMDeposit( + account=_ACCOUNT, + sequence=1337, + amm_hash=_AMM_HASH, + asset1_in=_AMOUNT, + lptokens=IssuedCurrencyAmount( + currency=_LPTOKEN_CURRENCY, + issuer=_LPTOKEN_ISSUER, + value="500", + ), + ) + expected = { + "AMMHash": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "Asset1In": "1000", + "LPTokens": { + "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", + "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", + "value": "500", + }, + "TransactionType": "AMMDeposit", + "Sequence": 1337, + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_asset1in_eprice(self): + tx = AMMDeposit( + account=_ACCOUNT, + sequence=1337, + amm_hash=_AMM_HASH, + asset1_in=_AMOUNT, + e_price="25", + ) + expected = { + "AMMHash": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "Asset1In": "1000", + "EPrice": "25", + "TransactionType": "AMMDeposit", + "Sequence": 1337, + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_undefined_asset1in_undefined_lptokens_invalid_combo(self): + with self.assertRaises(XRPLModelException): + AMMDeposit( + account=_ACCOUNT, + sequence=1337, + amm_hash=_AMM_HASH, + ) + + def test_undefined_asset1in_defined_asset2in_invalid_combo(self): + with self.assertRaises(XRPLModelException): + AMMDeposit( + account=_ACCOUNT, + sequence=1337, + amm_hash=_AMM_HASH, + asset2_in="500", + ) + + def test_undefined_asset1in_defined_eprice_invalid_combo(self): + with self.assertRaises(XRPLModelException): + AMMDeposit( + account=_ACCOUNT, + sequence=1337, + amm_hash=_AMM_HASH, + e_price="25", + ) diff --git a/xrpl/models/base_model.py b/xrpl/models/base_model.py index 829113f6f..0990d56ae 100644 --- a/xrpl/models/base_model.py +++ b/xrpl/models/base_model.py @@ -33,7 +33,7 @@ f"(?:{_CAMEL_CASE_LEADING_LOWER}|{_CAMEL_CASE_ABBREVIATION}|{_CAMEL_CASE_TYPICAL})" ) # used for converting special substrings inside CamelCase fields -SPECIAL_CAMELCASE_STRINGS = ["NFToken"] +SPECIAL_CAMELCASE_STRINGS = ["LPTokens", "NFToken"] BM = TypeVar("BM", bound="BaseModel") # any type inherited from BaseModel diff --git a/xrpl/models/transactions/__init__.py b/xrpl/models/transactions/__init__.py index 57d0a5a25..4c0f6b4ea 100644 --- a/xrpl/models/transactions/__init__.py +++ b/xrpl/models/transactions/__init__.py @@ -10,6 +10,7 @@ AccountSetFlagInterface, ) from xrpl.models.transactions.amm_instance_create import AMMInstanceCreate +from xrpl.models.transactions.amm_deposit import AMMDeposit from xrpl.models.transactions.check_cancel import CheckCancel from xrpl.models.transactions.check_cash import CheckCash from xrpl.models.transactions.check_create import CheckCreate @@ -61,6 +62,7 @@ "AccountSetFlag", "AccountSetFlagInterface", "AMMInstanceCreate", + "AMMDeposit", "CheckCancel", "CheckCash", "CheckCreate", diff --git a/xrpl/models/transactions/amm_deposit.py b/xrpl/models/transactions/amm_deposit.py new file mode 100644 index 000000000..064c0463c --- /dev/null +++ b/xrpl/models/transactions/amm_deposit.py @@ -0,0 +1,70 @@ +"""Model for AMMDeposit transaction type.""" +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import Dict, Optional + +from xrpl.models.amounts import Amount +from xrpl.models.required import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AMMDeposit(Transaction): + """ + AMDeposit is the deposit transaction used to add liquidity to the AMM instance pool, + thus obtaining some share of the instance's pools in the form of LPTokens. + + The following are the recommended valid combinations: + - LPTokens + - Asset1In + - Asset1In and Asset2In + - Asset1In and LPTokens + - Asset1In and EPrice + """ + + amm_hash: str = REQUIRED # type: ignore + """ + AMMHash is a hash that uniquely identifies the AMM instance. + """ + + lptokens: Optional[Amount] = None + """ + LPTokens specifies the amount of shares of the AMM instance pools that the trader + wants to redeem or trade in. + """ + + asset1_in: Optional[Amount] = None + """ + Asset1In specifies one of the pool assets (XRP or token) of the AMM instance to + deposit more of its value. + """ + + asset2_in: Optional[Amount] = None + """ + Asset2 specifies the other pool asset of the AMM instance to deposit more of its + value. + """ + + e_price: Optional[Amount] = None + """ + EPrice specifies the maximum effective-price that LPTokens can be traded out. + """ + + transaction_type: TransactionType = field( + default=TransactionType.AMM_DEPOSIT, + init=False, + ) + + def _get_errors(self: AMMDeposit) -> Dict[str, str]: + errors = super()._get_errors() + if self.lptokens is None and self.asset1_in is None: + errors["AMMDeposit"] = "Must set either or both `lptokens` and `asset1_in`" + elif self.asset2_in is not None and self.asset1_in is None: + errors["AMMDeposit"] = "Must set `asset1_in` with `asset2_in`" + elif self.e_price is not None and self.asset1_in is None: + errors["AMMDeposit"] = "Must set `asset1_in` with `e_price`" + return errors diff --git a/xrpl/models/transactions/transaction.py b/xrpl/models/transactions/transaction.py index 949188b35..a164d464c 100644 --- a/xrpl/models/transactions/transaction.py +++ b/xrpl/models/transactions/transaction.py @@ -23,10 +23,11 @@ # keys. We snake case keys, but some keys are abbreviations. _ABBREVIATIONS: Final[Dict[str, str]] = { "amm": "AMM", - "unl": "UNL", "id": "ID", - "uri": "URI", + "lptokens": "LPTokens", "nftoken": "NFToken", + "unl": "UNL", + "uri": "URI", } diff --git a/xrpl/models/transactions/types/transaction_type.py b/xrpl/models/transactions/types/transaction_type.py index a4ca30d69..f16979f06 100644 --- a/xrpl/models/transactions/types/transaction_type.py +++ b/xrpl/models/transactions/types/transaction_type.py @@ -9,6 +9,7 @@ class TransactionType(str, Enum): ACCOUNT_DELETE = "AccountDelete" ACCOUNT_SET = "AccountSet" AMM_INSTANCE_CREATE = "AMMInstanceCreate" + AMM_DEPOSIT = "AMMDeposit" CHECK_CANCEL = "CheckCancel" CHECK_CASH = "CheckCash" CHECK_CREATE = "CheckCreate" From 3b76ac813af26a9279015b5520086d84f8320de0 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Sat, 13 Aug 2022 23:57:40 -0400 Subject: [PATCH 14/88] fix lint errors --- tests/unit/models/transactions/test_amm_deposit.py | 12 ++++++------ xrpl/models/transactions/__init__.py | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/unit/models/transactions/test_amm_deposit.py b/tests/unit/models/transactions/test_amm_deposit.py index 746601c93..65d3b9c8b 100644 --- a/tests/unit/models/transactions/test_amm_deposit.py +++ b/tests/unit/models/transactions/test_amm_deposit.py @@ -24,7 +24,7 @@ def test_to_xrpl_lptokens(self): ), ) expected = { - "AMMHash": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "AMMHash": _AMM_HASH, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "LPTokens": { "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", @@ -46,7 +46,7 @@ def test_to_xrpl_asset1in(self): asset1_in=_AMOUNT, ) expected = { - "AMMHash": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "AMMHash": _AMM_HASH, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Asset1In": "1000", "TransactionType": "AMMDeposit", @@ -56,7 +56,7 @@ def test_to_xrpl_asset1in(self): } self.assertEqual(tx.to_xrpl(), expected) - def test_to_xrpl_asset1in_asset2_in(self): + def test_to_xrpl_asset1in_asset2in(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, @@ -65,7 +65,7 @@ def test_to_xrpl_asset1in_asset2_in(self): asset2_in="500", ) expected = { - "AMMHash": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "AMMHash": _AMM_HASH, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Asset1In": "1000", "Asset2In": "500", @@ -89,7 +89,7 @@ def test_to_xrpl_asset1in_lptokens(self): ), ) expected = { - "AMMHash": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "AMMHash": _AMM_HASH, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Asset1In": "1000", "LPTokens": { @@ -113,7 +113,7 @@ def test_to_xrpl_asset1in_eprice(self): e_price="25", ) expected = { - "AMMHash": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "AMMHash": _AMM_HASH, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Asset1In": "1000", "EPrice": "25", diff --git a/xrpl/models/transactions/__init__.py b/xrpl/models/transactions/__init__.py index 4c0f6b4ea..c94e4e127 100644 --- a/xrpl/models/transactions/__init__.py +++ b/xrpl/models/transactions/__init__.py @@ -9,8 +9,8 @@ AccountSetFlag, AccountSetFlagInterface, ) -from xrpl.models.transactions.amm_instance_create import AMMInstanceCreate from xrpl.models.transactions.amm_deposit import AMMDeposit +from xrpl.models.transactions.amm_instance_create import AMMInstanceCreate from xrpl.models.transactions.check_cancel import CheckCancel from xrpl.models.transactions.check_cash import CheckCash from xrpl.models.transactions.check_create import CheckCreate From 7e7aa3004c295e96215d6d103cb7477a099671d6 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Sun, 14 Aug 2022 16:51:21 -0400 Subject: [PATCH 15/88] add AMMWithdraw --- .../models/transactions/test_amm_withdraw.py | 151 ++++++++++++++++++ xrpl/models/transactions/__init__.py | 4 +- xrpl/models/transactions/amm_deposit.py | 2 +- xrpl/models/transactions/amm_withdraw.py | 75 +++++++++ .../transactions/types/transaction_type.py | 1 + 5 files changed, 231 insertions(+), 2 deletions(-) create mode 100644 tests/unit/models/transactions/test_amm_withdraw.py create mode 100644 xrpl/models/transactions/amm_withdraw.py diff --git a/tests/unit/models/transactions/test_amm_withdraw.py b/tests/unit/models/transactions/test_amm_withdraw.py new file mode 100644 index 000000000..a4e1c356d --- /dev/null +++ b/tests/unit/models/transactions/test_amm_withdraw.py @@ -0,0 +1,151 @@ +from unittest import TestCase + +from xrpl.models.amounts import IssuedCurrencyAmount +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions import AMMWithdraw + +_ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" +_AMM_HASH = "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883" +_AMOUNT = "1000" +_LPTOKEN_CURRENCY = "B3813FCAB4EE68B3D0D735D6849465A9113EE048" +_LPTOKEN_ISSUER = "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg" + + +class TestAMMWithdraw(TestCase): + def test_to_xrpl_lptokens(self): + tx = AMMWithdraw( + account=_ACCOUNT, + sequence=1337, + amm_hash=_AMM_HASH, + lptokens=IssuedCurrencyAmount( + currency=_LPTOKEN_CURRENCY, + issuer=_LPTOKEN_ISSUER, + value=_AMOUNT, + ), + ) + expected = { + "AMMHash": _AMM_HASH, + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "LPTokens": { + "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", + "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", + "value": "1000", + }, + "TransactionType": "AMMWithdraw", + "Sequence": 1337, + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_asset1out(self): + tx = AMMWithdraw( + account=_ACCOUNT, + sequence=1337, + amm_hash=_AMM_HASH, + asset1_out=_AMOUNT, + ) + expected = { + "AMMHash": _AMM_HASH, + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "Asset1Out": "1000", + "TransactionType": "AMMWithdraw", + "Sequence": 1337, + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_asset1out_asset2out(self): + tx = AMMWithdraw( + account=_ACCOUNT, + sequence=1337, + amm_hash=_AMM_HASH, + asset1_out=_AMOUNT, + asset2_out="500", + ) + expected = { + "AMMHash": _AMM_HASH, + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "Asset1Out": "1000", + "Asset2Out": "500", + "TransactionType": "AMMWithdraw", + "Sequence": 1337, + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_asset1out_lptokens(self): + tx = AMMWithdraw( + account=_ACCOUNT, + sequence=1337, + amm_hash=_AMM_HASH, + asset1_out=_AMOUNT, + lptokens=IssuedCurrencyAmount( + currency=_LPTOKEN_CURRENCY, + issuer=_LPTOKEN_ISSUER, + value="500", + ), + ) + expected = { + "AMMHash": _AMM_HASH, + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "Asset1Out": "1000", + "LPTokens": { + "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", + "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", + "value": "500", + }, + "TransactionType": "AMMWithdraw", + "Sequence": 1337, + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_asset1out_eprice(self): + tx = AMMWithdraw( + account=_ACCOUNT, + sequence=1337, + amm_hash=_AMM_HASH, + asset1_out=_AMOUNT, + e_price="25", + ) + expected = { + "AMMHash": _AMM_HASH, + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "Asset1Out": "1000", + "EPrice": "25", + "TransactionType": "AMMWithdraw", + "Sequence": 1337, + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_undefined_asset1out_undefined_lptokens_invalid_combo(self): + with self.assertRaises(XRPLModelException): + AMMWithdraw( + account=_ACCOUNT, + sequence=1337, + amm_hash=_AMM_HASH, + ) + + def test_undefined_asset1out_defined_asset2out_invalid_combo(self): + with self.assertRaises(XRPLModelException): + AMMWithdraw( + account=_ACCOUNT, + sequence=1337, + amm_hash=_AMM_HASH, + asset2_out="500", + ) + + def test_undefined_asset1out_defined_eprice_invalid_combo(self): + with self.assertRaises(XRPLModelException): + AMMWithdraw( + account=_ACCOUNT, + sequence=1337, + amm_hash=_AMM_HASH, + e_price="25", + ) diff --git a/xrpl/models/transactions/__init__.py b/xrpl/models/transactions/__init__.py index c94e4e127..fd3b93187 100644 --- a/xrpl/models/transactions/__init__.py +++ b/xrpl/models/transactions/__init__.py @@ -11,6 +11,7 @@ ) from xrpl.models.transactions.amm_deposit import AMMDeposit from xrpl.models.transactions.amm_instance_create import AMMInstanceCreate +from xrpl.models.transactions.amm_withdraw import AMMWithdraw from xrpl.models.transactions.check_cancel import CheckCancel from xrpl.models.transactions.check_cash import CheckCash from xrpl.models.transactions.check_create import CheckCreate @@ -61,8 +62,9 @@ "AccountSet", "AccountSetFlag", "AccountSetFlagInterface", - "AMMInstanceCreate", "AMMDeposit", + "AMMInstanceCreate", + "AMMWithdraw", "CheckCancel", "CheckCash", "CheckCreate", diff --git a/xrpl/models/transactions/amm_deposit.py b/xrpl/models/transactions/amm_deposit.py index 064c0463c..076337b64 100644 --- a/xrpl/models/transactions/amm_deposit.py +++ b/xrpl/models/transactions/amm_deposit.py @@ -45,7 +45,7 @@ class AMMDeposit(Transaction): asset2_in: Optional[Amount] = None """ - Asset2 specifies the other pool asset of the AMM instance to deposit more of its + Asset2In specifies the other pool asset of the AMM instance to deposit more of its value. """ diff --git a/xrpl/models/transactions/amm_withdraw.py b/xrpl/models/transactions/amm_withdraw.py new file mode 100644 index 000000000..37bfdc7bc --- /dev/null +++ b/xrpl/models/transactions/amm_withdraw.py @@ -0,0 +1,75 @@ +"""Model for AMMWithdraw transaction type.""" +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import Dict, Optional + +from xrpl.models.amounts import Amount +from xrpl.models.required import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AMMWithdraw(Transaction): + """ + AMMWithdraw is the withdraw transaction used to remove liquidity from the AMM + instance pool, thus redeeming some share of the pools that one owns in the form + of LPTokens. + + The following are the recommended valid combinations: + - LPTokens + - Asset1Out + - Asset1Out and Asset2Out + - Asset1Out and LPTokens + - Asset1Out and EPrice + """ + + amm_hash: str = REQUIRED # type: ignore + """ + AMMHash is a hash that uniquely identifies the AMM instance. + """ + + lptokens: Optional[Amount] = None + """ + LPTokens specifies the amount of shares of the AMM instance pools that the trader + wants to redeem or trade in. + """ + + asset1_out: Optional[Amount] = None + """ + Asset1Out specifies one of the pools assets that the trader wants to remove. + If the asset is XRP, then the Asset1Out is a string specifying the number of drops. + Otherwise it is an IssuedCurrencyAmount object. + """ + + asset2_out: Optional[Amount] = None + """ + Asset2Out specifies the other pool asset that the trader wants to remove. + """ + + e_price: Optional[Amount] = None + """ + EPrice specifies the effective-price of the token out after successful execution of + the transaction. + """ + + transaction_type: TransactionType = field( + default=TransactionType.AMM_WITHDRAW, + init=False, + ) + + def _get_errors(self: AMMWithdraw) -> Dict[str, str]: + errors = super()._get_errors() + if self.lptokens is None and self.asset1_out is None: + errors[ + "AMMWithdraw" + ] = "Must set either or both `lptokens` and \ + `asset1_out`" + elif self.asset2_out is not None and self.asset1_out is None: + errors["AMMWithdraw"] = "Must set `asset1_out` with `asset2_out`" + elif self.e_price is not None and self.asset1_out is None: + errors["AMMWithdraw"] = "Must set `asset1_out` with `e_price`" + return errors diff --git a/xrpl/models/transactions/types/transaction_type.py b/xrpl/models/transactions/types/transaction_type.py index f16979f06..c1fce6dcd 100644 --- a/xrpl/models/transactions/types/transaction_type.py +++ b/xrpl/models/transactions/types/transaction_type.py @@ -10,6 +10,7 @@ class TransactionType(str, Enum): ACCOUNT_SET = "AccountSet" AMM_INSTANCE_CREATE = "AMMInstanceCreate" AMM_DEPOSIT = "AMMDeposit" + AMM_WITHDRAW = "AMMWithdraw" CHECK_CANCEL = "CheckCancel" CHECK_CASH = "CheckCash" CHECK_CREATE = "CheckCreate" From 3e8362eeb9783240999eda5530446d1726b0ea10 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Sun, 14 Aug 2022 18:18:34 -0400 Subject: [PATCH 16/88] add AMMVote --- .../transactions/test_amm_instance_create.py | 6 -- .../unit/models/transactions/test_amm_vote.py | 35 +++++++++++ xrpl/models/transactions/__init__.py | 2 + xrpl/models/transactions/amm_vote.py | 58 +++++++++++++++++++ .../transactions/types/transaction_type.py | 1 + 5 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 tests/unit/models/transactions/test_amm_vote.py create mode 100644 xrpl/models/transactions/amm_vote.py diff --git a/tests/unit/models/transactions/test_amm_instance_create.py b/tests/unit/models/transactions/test_amm_instance_create.py index 151f347db..095f57a76 100644 --- a/tests/unit/models/transactions/test_amm_instance_create.py +++ b/tests/unit/models/transactions/test_amm_instance_create.py @@ -7,7 +7,6 @@ _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" _IOU_ISSUER = "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9" -_FEE = "0.00001" class TestAMMInstanceCreate(TestCase): @@ -15,7 +14,6 @@ def test_trading_fee_too_high(self): with self.assertRaises(XRPLModelException): AMMInstanceCreate( account=_ACCOUNT, - fee=_FEE, asset1="1000", asset2=IssuedCurrencyAmount( currency="USD", issuer=_IOU_ISSUER, value="1000" @@ -26,8 +24,6 @@ def test_trading_fee_too_high(self): def test_to_xrpl(self): tx = AMMInstanceCreate( account=_ACCOUNT, - sequence=1337, - fee=_FEE, asset1="1000", asset2=IssuedCurrencyAmount( currency="USD", issuer=_IOU_ISSUER, value="1000" @@ -42,9 +38,7 @@ def test_to_xrpl(self): "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", "value": "1000", }, - "Fee": "0.00001", "TransactionType": "AMMInstanceCreate", - "Sequence": 1337, "SigningPubKey": "", "TradingFee": 12, "Flags": 0, diff --git a/tests/unit/models/transactions/test_amm_vote.py b/tests/unit/models/transactions/test_amm_vote.py new file mode 100644 index 000000000..776d0f888 --- /dev/null +++ b/tests/unit/models/transactions/test_amm_vote.py @@ -0,0 +1,35 @@ +from sys import maxsize +from unittest import TestCase + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions import AMMVote + +_ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" +_AMM_HASH = "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883" +_FEE_VAL = 1234 + + +class TestAMMVote(TestCase): + def test_trading_fee_too_high(self): + with self.assertRaises(XRPLModelException): + AMMVote( + account=_ACCOUNT, + amm_hash=_AMM_HASH, + fee_val=maxsize, + ) + + def test_to_xrpl(self): + tx = AMMVote( + account=_ACCOUNT, + amm_hash=_AMM_HASH, + fee_val=_FEE_VAL, + ) + expected = { + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "AMMHash": _AMM_HASH, + "FeeVal": 1234, + "TransactionType": "AMMVote", + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) diff --git a/xrpl/models/transactions/__init__.py b/xrpl/models/transactions/__init__.py index fd3b93187..e2bbb6d50 100644 --- a/xrpl/models/transactions/__init__.py +++ b/xrpl/models/transactions/__init__.py @@ -11,6 +11,7 @@ ) from xrpl.models.transactions.amm_deposit import AMMDeposit from xrpl.models.transactions.amm_instance_create import AMMInstanceCreate +from xrpl.models.transactions.amm_vote import AMMVote from xrpl.models.transactions.amm_withdraw import AMMWithdraw from xrpl.models.transactions.check_cancel import CheckCancel from xrpl.models.transactions.check_cash import CheckCash @@ -64,6 +65,7 @@ "AccountSetFlagInterface", "AMMDeposit", "AMMInstanceCreate", + "AMMVote", "AMMWithdraw", "CheckCancel", "CheckCash", diff --git a/xrpl/models/transactions/amm_vote.py b/xrpl/models/transactions/amm_vote.py new file mode 100644 index 000000000..79538a24e --- /dev/null +++ b/xrpl/models/transactions/amm_vote.py @@ -0,0 +1,58 @@ +"""Model for AMMVote transaction type.""" +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import Dict, Optional + +from typing_extensions import Final + +from xrpl.models.required import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import require_kwargs_on_init + +_MAX_TRADING_FEE: Final[int] = 65000 + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AMMVote(Transaction): + """ + AMMVote is used for submitting a vote for the trading fee of an AMM Instance. + + Any XRPL account that holds LPTokens for an AMM instance may submit this + transaction to vote for the trading fee for that instance. + """ + + amm_hash: str = REQUIRED # type: ignore + """ + AMMHash is a hash that uniquely identifies the AMM instance. + """ + + fee_val: int = REQUIRED # type: ignore + """ + FeeVal specifies the fee, in basis point. + Valid values for this field are between 0 and 65000 inclusive. + A value of 1 is equivalent to 1/10 bps or 0.001%, allowing trading fee + between 0% and 65%. + """ + + transaction_type: TransactionType = field( + default=TransactionType.AMM_VOTE, + init=False, + ) + + def _get_errors(self: AMMVote) -> Dict[str, str]: + return { + key: value + for key, value in { + **super()._get_errors(), + "fee_val": self._get_fee_val_error(), + }.items() + if value is not None + } + + def _get_fee_val_error(self: AMMVote) -> Optional[str]: + if self.fee_val > _MAX_TRADING_FEE: + return f"Must not be greater than {_MAX_TRADING_FEE}" + return None diff --git a/xrpl/models/transactions/types/transaction_type.py b/xrpl/models/transactions/types/transaction_type.py index c1fce6dcd..f9b97c2dc 100644 --- a/xrpl/models/transactions/types/transaction_type.py +++ b/xrpl/models/transactions/types/transaction_type.py @@ -10,6 +10,7 @@ class TransactionType(str, Enum): ACCOUNT_SET = "AccountSet" AMM_INSTANCE_CREATE = "AMMInstanceCreate" AMM_DEPOSIT = "AMMDeposit" + AMM_VOTE = "AMMVote" AMM_WITHDRAW = "AMMWithdraw" CHECK_CANCEL = "CheckCancel" CHECK_CASH = "CheckCash" From 9b24c24bbe2702e2e461dac1c3eba22207841609 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Sun, 14 Aug 2022 21:02:28 -0400 Subject: [PATCH 17/88] add AMMBid --- .../unit/models/transactions/test_amm_bid.py | 43 ++++++++++++ xrpl/models/transactions/__init__.py | 2 + xrpl/models/transactions/amm_bid.py | 70 +++++++++++++++++++ .../transactions/types/transaction_type.py | 3 +- 4 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 tests/unit/models/transactions/test_amm_bid.py create mode 100644 xrpl/models/transactions/amm_bid.py diff --git a/tests/unit/models/transactions/test_amm_bid.py b/tests/unit/models/transactions/test_amm_bid.py new file mode 100644 index 000000000..baeb5dea8 --- /dev/null +++ b/tests/unit/models/transactions/test_amm_bid.py @@ -0,0 +1,43 @@ +from unittest import TestCase + +from xrpl.models.exceptions import XRPLModelException +from xrpl.models.transactions import AMMBid + +_ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" +_AMM_HASH = "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883" +_AUTH_ACCOUNTS = [ + "rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh", + "rfpFv97Dwu89FTyUwPjtpZBbuZxTqqgTmH", + "rzzYHPGb8Pa64oqxCzmuffm122bitq3Vb", + "rhwxHxaHok86fe4LykBom1jSJ3RYQJs1h4", +] + + +class TestAMMBid(TestCase): + def test_auth_accounts_length_error(self): + auth_accounts = _AUTH_ACCOUNTS.copy() + auth_accounts.append("r3X6noRsvaLapAKCG78zAtWcbhB3sggS1s") + with self.assertRaises(XRPLModelException): + AMMBid( + account=_ACCOUNT, + amm_hash=_AMM_HASH, + auth_accounts=auth_accounts, + ) + + def test_to_xrpl(self): + tx = AMMBid( + account=_ACCOUNT, + amm_hash=_AMM_HASH, + min_slot_price="25", + auth_accounts=_AUTH_ACCOUNTS, + ) + expected = { + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "AMMHash": _AMM_HASH, + "MinSlotPrice": "25", + "AuthAccounts": _AUTH_ACCOUNTS, + "TransactionType": "AMMBid", + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) diff --git a/xrpl/models/transactions/__init__.py b/xrpl/models/transactions/__init__.py index e2bbb6d50..f0b8a8ab0 100644 --- a/xrpl/models/transactions/__init__.py +++ b/xrpl/models/transactions/__init__.py @@ -9,6 +9,7 @@ AccountSetFlag, AccountSetFlagInterface, ) +from xrpl.models.transactions.amm_bid import AMMBid from xrpl.models.transactions.amm_deposit import AMMDeposit from xrpl.models.transactions.amm_instance_create import AMMInstanceCreate from xrpl.models.transactions.amm_vote import AMMVote @@ -63,6 +64,7 @@ "AccountSet", "AccountSetFlag", "AccountSetFlagInterface", + "AMMBid", "AMMDeposit", "AMMInstanceCreate", "AMMVote", diff --git a/xrpl/models/transactions/amm_bid.py b/xrpl/models/transactions/amm_bid.py new file mode 100644 index 000000000..c88e7017b --- /dev/null +++ b/xrpl/models/transactions/amm_bid.py @@ -0,0 +1,70 @@ +"""Model for AMMBid transaction type.""" +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import Dict, List, Optional + +from typing_extensions import Final + +from xrpl.models.amounts import Amount +from xrpl.models.required import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import require_kwargs_on_init + +_MAX_AUTH_ACCOUNTS: Final[int] = 4 + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AMMBid(Transaction): + """ + AMMBid is used to place a bid for the auction slot of obtaining trading advantages + of an AMM instance. + + An AMM instance auctions off the trading advantages to users (arbitrageurs) at a + discounted TradingFee for a 24 hour slot. + """ + + amm_hash: str = REQUIRED # type: ignore + """ + AMMHash is a hash that uniquely identifies the AMM instance. + """ + + min_slot_price: Optional[Amount] = None + """ + MinSlotPrice represents the minimum price that the bidder wants to pay for the slot. + It is specified in units of LPTokens. If specified let MinSlotPrice be X and let + the slot-price computed by price scheduling slgorithm be Y, then bidder always pays + the max(X, Y). + """ + + auth_accounts: Optional[List[str]] = None + """ + AuthAccounts represents an array of XRPL account IDs that are authorized to trade + at the discounted fee against the AMM instance. + A maximum of four accounts can be provided. + """ + + transaction_type: TransactionType = field( + default=TransactionType.AMM_BID, + init=False, + ) + + def _get_errors(self: AMMBid) -> Dict[str, str]: + return { + key: value + for key, value in { + **super()._get_errors(), + "auth_accounts": self._get_auth_accounts_error(), + }.items() + if value is not None + } + + def _get_auth_accounts_error(self: AMMBid) -> Optional[str]: + if ( + self.auth_accounts is not None + and len(self.auth_accounts) > _MAX_AUTH_ACCOUNTS + ): + return f"Must not be greater than {_MAX_AUTH_ACCOUNTS}" + return None diff --git a/xrpl/models/transactions/types/transaction_type.py b/xrpl/models/transactions/types/transaction_type.py index f9b97c2dc..617be49e0 100644 --- a/xrpl/models/transactions/types/transaction_type.py +++ b/xrpl/models/transactions/types/transaction_type.py @@ -8,8 +8,9 @@ class TransactionType(str, Enum): ACCOUNT_DELETE = "AccountDelete" ACCOUNT_SET = "AccountSet" - AMM_INSTANCE_CREATE = "AMMInstanceCreate" + AMM_BID = "AMMBid" AMM_DEPOSIT = "AMMDeposit" + AMM_INSTANCE_CREATE = "AMMInstanceCreate" AMM_VOTE = "AMMVote" AMM_WITHDRAW = "AMMWithdraw" CHECK_CANCEL = "CheckCancel" From e392a04d3dca3bdbf1ee8c32b3bcf8f6259e54fe Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Sun, 14 Aug 2022 21:12:11 -0400 Subject: [PATCH 18/88] fix typo --- xrpl/models/transactions/amm_bid.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xrpl/models/transactions/amm_bid.py b/xrpl/models/transactions/amm_bid.py index c88e7017b..2f0649086 100644 --- a/xrpl/models/transactions/amm_bid.py +++ b/xrpl/models/transactions/amm_bid.py @@ -35,7 +35,7 @@ class AMMBid(Transaction): """ MinSlotPrice represents the minimum price that the bidder wants to pay for the slot. It is specified in units of LPTokens. If specified let MinSlotPrice be X and let - the slot-price computed by price scheduling slgorithm be Y, then bidder always pays + the slot-price computed by price scheduling algorithm be Y, then bidder always pays the max(X, Y). """ From 06cc75460bb24b7a97b160828f32422e7f26c621 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Sun, 14 Aug 2022 21:56:49 -0400 Subject: [PATCH 19/88] update AMMBid test --- tests/unit/models/transactions/test_amm_bid.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/unit/models/transactions/test_amm_bid.py b/tests/unit/models/transactions/test_amm_bid.py index baeb5dea8..e6c2300c4 100644 --- a/tests/unit/models/transactions/test_amm_bid.py +++ b/tests/unit/models/transactions/test_amm_bid.py @@ -1,5 +1,6 @@ from unittest import TestCase +from xrpl.models.amounts import IssuedCurrencyAmount from xrpl.models.exceptions import XRPLModelException from xrpl.models.transactions import AMMBid @@ -28,13 +29,21 @@ def test_to_xrpl(self): tx = AMMBid( account=_ACCOUNT, amm_hash=_AMM_HASH, - min_slot_price="25", + min_slot_price=IssuedCurrencyAmount( + currency="5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", + issuer="r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", + value="25", + ), auth_accounts=_AUTH_ACCOUNTS, ) expected = { "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "AMMHash": _AMM_HASH, - "MinSlotPrice": "25", + "MinSlotPrice": { + "currency": "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", + "issuer": "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", + "value": "25", + }, "AuthAccounts": _AUTH_ACCOUNTS, "TransactionType": "AMMBid", "SigningPubKey": "", From 23e0758846b9c0207b8166dabe9ff4cfe9f74556 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Mon, 15 Aug 2022 16:27:28 -0400 Subject: [PATCH 20/88] add MaxSlotPrice param to AMMBid --- tests/unit/models/transactions/test_amm_bid.py | 10 ++++++++++ xrpl/models/transactions/amm_bid.py | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/tests/unit/models/transactions/test_amm_bid.py b/tests/unit/models/transactions/test_amm_bid.py index e6c2300c4..386c5b011 100644 --- a/tests/unit/models/transactions/test_amm_bid.py +++ b/tests/unit/models/transactions/test_amm_bid.py @@ -34,6 +34,11 @@ def test_to_xrpl(self): issuer="r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", value="25", ), + max_slot_price=IssuedCurrencyAmount( + currency="5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", + issuer="r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", + value="35", + ), auth_accounts=_AUTH_ACCOUNTS, ) expected = { @@ -44,6 +49,11 @@ def test_to_xrpl(self): "issuer": "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", "value": "25", }, + "MaxSlotPrice": { + "currency": "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", + "issuer": "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", + "value": "35", + }, "AuthAccounts": _AUTH_ACCOUNTS, "TransactionType": "AMMBid", "SigningPubKey": "", diff --git a/xrpl/models/transactions/amm_bid.py b/xrpl/models/transactions/amm_bid.py index 2f0649086..5fbf5c77b 100644 --- a/xrpl/models/transactions/amm_bid.py +++ b/xrpl/models/transactions/amm_bid.py @@ -39,6 +39,12 @@ class AMMBid(Transaction): the max(X, Y). """ + max_slot_price: Optional[Amount] = None + """ + MaxSlotPrice represents the maximum price that the bidder wants to pay for the slot. + It is specified in units of LPTokens. + """ + auth_accounts: Optional[List[str]] = None """ AuthAccounts represents an array of XRPL account IDs that are authorized to trade From 2a02fb68a16ae4a04e1977f4bdf4a9d63149df99 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Mon, 15 Aug 2022 16:31:33 -0400 Subject: [PATCH 21/88] refactor test --- tests/unit/models/transactions/test_amm_bid.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/unit/models/transactions/test_amm_bid.py b/tests/unit/models/transactions/test_amm_bid.py index 386c5b011..75c504bb5 100644 --- a/tests/unit/models/transactions/test_amm_bid.py +++ b/tests/unit/models/transactions/test_amm_bid.py @@ -12,6 +12,8 @@ "rzzYHPGb8Pa64oqxCzmuffm122bitq3Vb", "rhwxHxaHok86fe4LykBom1jSJ3RYQJs1h4", ] +_LPTOKENS_CURRENCY = "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A" +_LPTOKENS_ISSUER = "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw" class TestAMMBid(TestCase): @@ -30,13 +32,13 @@ def test_to_xrpl(self): account=_ACCOUNT, amm_hash=_AMM_HASH, min_slot_price=IssuedCurrencyAmount( - currency="5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", - issuer="r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", + currency=_LPTOKENS_CURRENCY, + issuer=_LPTOKENS_ISSUER, value="25", ), max_slot_price=IssuedCurrencyAmount( - currency="5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", - issuer="r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", + currency=_LPTOKENS_CURRENCY, + issuer=_LPTOKENS_ISSUER, value="35", ), auth_accounts=_AUTH_ACCOUNTS, From 7556fe3952e744761a229efe859bde912a092c99 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 16 Aug 2022 16:37:21 -0400 Subject: [PATCH 22/88] update definitions and replace AMMHash with AMMID --- tests/unit/models/requests/test_amm_info.py | 6 +- .../unit/models/transactions/test_amm_bid.py | 8 +- .../models/transactions/test_amm_deposit.py | 28 +++---- .../unit/models/transactions/test_amm_vote.py | 8 +- .../models/transactions/test_amm_withdraw.py | 28 +++---- .../binarycodec/definitions/definitions.json | 80 +++++++++---------- xrpl/models/base_model.py | 2 +- xrpl/models/requests/amm_info.py | 10 +-- xrpl/models/transactions/amm_bid.py | 4 +- xrpl/models/transactions/amm_deposit.py | 4 +- xrpl/models/transactions/amm_vote.py | 4 +- xrpl/models/transactions/amm_withdraw.py | 4 +- 12 files changed, 93 insertions(+), 93 deletions(-) diff --git a/tests/unit/models/requests/test_amm_info.py b/tests/unit/models/requests/test_amm_info.py index 1d503d5c9..c01f671ac 100644 --- a/tests/unit/models/requests/test_amm_info.py +++ b/tests/unit/models/requests/test_amm_info.py @@ -4,7 +4,7 @@ from xrpl.models.exceptions import XRPLModelException from xrpl.models.requests import AMMInfo -_AMM_HASH = "5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3" +_AMM_ID = "5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3" _ASSET_1 = "1000" _ASSET_2 = IssuedCurrencyAmount( currency="USD", issuer="rN6zcSynkRnf8zcgTVrRL8K7r4ovE7J4Zj", value="100" @@ -12,9 +12,9 @@ class TestAMMInfo(TestCase): - def test_amm_hash(self): + def test_amm_id(self): request = AMMInfo( - AMMHash=_AMM_HASH, + AMMID=_AMM_ID, ) self.assertTrue(request.is_valid()) diff --git a/tests/unit/models/transactions/test_amm_bid.py b/tests/unit/models/transactions/test_amm_bid.py index 75c504bb5..43250adb6 100644 --- a/tests/unit/models/transactions/test_amm_bid.py +++ b/tests/unit/models/transactions/test_amm_bid.py @@ -5,7 +5,7 @@ from xrpl.models.transactions import AMMBid _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" -_AMM_HASH = "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883" +_AMM_ID = "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883" _AUTH_ACCOUNTS = [ "rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh", "rfpFv97Dwu89FTyUwPjtpZBbuZxTqqgTmH", @@ -23,14 +23,14 @@ def test_auth_accounts_length_error(self): with self.assertRaises(XRPLModelException): AMMBid( account=_ACCOUNT, - amm_hash=_AMM_HASH, + amm_id=_AMM_ID, auth_accounts=auth_accounts, ) def test_to_xrpl(self): tx = AMMBid( account=_ACCOUNT, - amm_hash=_AMM_HASH, + amm_id=_AMM_ID, min_slot_price=IssuedCurrencyAmount( currency=_LPTOKENS_CURRENCY, issuer=_LPTOKENS_ISSUER, @@ -45,7 +45,7 @@ def test_to_xrpl(self): ) expected = { "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "AMMHash": _AMM_HASH, + "AMMID": _AMM_ID, "MinSlotPrice": { "currency": "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", "issuer": "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", diff --git a/tests/unit/models/transactions/test_amm_deposit.py b/tests/unit/models/transactions/test_amm_deposit.py index 65d3b9c8b..bb376ac84 100644 --- a/tests/unit/models/transactions/test_amm_deposit.py +++ b/tests/unit/models/transactions/test_amm_deposit.py @@ -5,7 +5,7 @@ from xrpl.models.transactions import AMMDeposit _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" -_AMM_HASH = "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883" +_AMM_ID = "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883" _AMOUNT = "1000" _LPTOKEN_CURRENCY = "B3813FCAB4EE68B3D0D735D6849465A9113EE048" _LPTOKEN_ISSUER = "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg" @@ -16,7 +16,7 @@ def test_to_xrpl_lptokens(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, - amm_hash=_AMM_HASH, + amm_id=_AMM_ID, lptokens=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, @@ -24,7 +24,7 @@ def test_to_xrpl_lptokens(self): ), ) expected = { - "AMMHash": _AMM_HASH, + "AMMID": _AMM_ID, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "LPTokens": { "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", @@ -42,11 +42,11 @@ def test_to_xrpl_asset1in(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, - amm_hash=_AMM_HASH, + amm_id=_AMM_ID, asset1_in=_AMOUNT, ) expected = { - "AMMHash": _AMM_HASH, + "AMMID": _AMM_ID, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Asset1In": "1000", "TransactionType": "AMMDeposit", @@ -60,12 +60,12 @@ def test_to_xrpl_asset1in_asset2in(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, - amm_hash=_AMM_HASH, + amm_id=_AMM_ID, asset1_in=_AMOUNT, asset2_in="500", ) expected = { - "AMMHash": _AMM_HASH, + "AMMID": _AMM_ID, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Asset1In": "1000", "Asset2In": "500", @@ -80,7 +80,7 @@ def test_to_xrpl_asset1in_lptokens(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, - amm_hash=_AMM_HASH, + amm_id=_AMM_ID, asset1_in=_AMOUNT, lptokens=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, @@ -89,7 +89,7 @@ def test_to_xrpl_asset1in_lptokens(self): ), ) expected = { - "AMMHash": _AMM_HASH, + "AMMID": _AMM_ID, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Asset1In": "1000", "LPTokens": { @@ -108,12 +108,12 @@ def test_to_xrpl_asset1in_eprice(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, - amm_hash=_AMM_HASH, + amm_id=_AMM_ID, asset1_in=_AMOUNT, e_price="25", ) expected = { - "AMMHash": _AMM_HASH, + "AMMID": _AMM_ID, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Asset1In": "1000", "EPrice": "25", @@ -129,7 +129,7 @@ def test_undefined_asset1in_undefined_lptokens_invalid_combo(self): AMMDeposit( account=_ACCOUNT, sequence=1337, - amm_hash=_AMM_HASH, + amm_id=_AMM_ID, ) def test_undefined_asset1in_defined_asset2in_invalid_combo(self): @@ -137,7 +137,7 @@ def test_undefined_asset1in_defined_asset2in_invalid_combo(self): AMMDeposit( account=_ACCOUNT, sequence=1337, - amm_hash=_AMM_HASH, + amm_id=_AMM_ID, asset2_in="500", ) @@ -146,6 +146,6 @@ def test_undefined_asset1in_defined_eprice_invalid_combo(self): AMMDeposit( account=_ACCOUNT, sequence=1337, - amm_hash=_AMM_HASH, + amm_id=_AMM_ID, e_price="25", ) diff --git a/tests/unit/models/transactions/test_amm_vote.py b/tests/unit/models/transactions/test_amm_vote.py index 776d0f888..d6365235c 100644 --- a/tests/unit/models/transactions/test_amm_vote.py +++ b/tests/unit/models/transactions/test_amm_vote.py @@ -5,7 +5,7 @@ from xrpl.models.transactions import AMMVote _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" -_AMM_HASH = "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883" +_AMM_ID = "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883" _FEE_VAL = 1234 @@ -14,19 +14,19 @@ def test_trading_fee_too_high(self): with self.assertRaises(XRPLModelException): AMMVote( account=_ACCOUNT, - amm_hash=_AMM_HASH, + amm_id=_AMM_ID, fee_val=maxsize, ) def test_to_xrpl(self): tx = AMMVote( account=_ACCOUNT, - amm_hash=_AMM_HASH, + amm_id=_AMM_ID, fee_val=_FEE_VAL, ) expected = { "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "AMMHash": _AMM_HASH, + "AMMID": _AMM_ID, "FeeVal": 1234, "TransactionType": "AMMVote", "SigningPubKey": "", diff --git a/tests/unit/models/transactions/test_amm_withdraw.py b/tests/unit/models/transactions/test_amm_withdraw.py index a4e1c356d..a007f2844 100644 --- a/tests/unit/models/transactions/test_amm_withdraw.py +++ b/tests/unit/models/transactions/test_amm_withdraw.py @@ -5,7 +5,7 @@ from xrpl.models.transactions import AMMWithdraw _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" -_AMM_HASH = "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883" +_AMM_ID = "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883" _AMOUNT = "1000" _LPTOKEN_CURRENCY = "B3813FCAB4EE68B3D0D735D6849465A9113EE048" _LPTOKEN_ISSUER = "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg" @@ -16,7 +16,7 @@ def test_to_xrpl_lptokens(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, - amm_hash=_AMM_HASH, + amm_id=_AMM_ID, lptokens=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, @@ -24,7 +24,7 @@ def test_to_xrpl_lptokens(self): ), ) expected = { - "AMMHash": _AMM_HASH, + "AMMID": _AMM_ID, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "LPTokens": { "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", @@ -42,11 +42,11 @@ def test_to_xrpl_asset1out(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, - amm_hash=_AMM_HASH, + amm_id=_AMM_ID, asset1_out=_AMOUNT, ) expected = { - "AMMHash": _AMM_HASH, + "AMMID": _AMM_ID, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Asset1Out": "1000", "TransactionType": "AMMWithdraw", @@ -60,12 +60,12 @@ def test_to_xrpl_asset1out_asset2out(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, - amm_hash=_AMM_HASH, + amm_id=_AMM_ID, asset1_out=_AMOUNT, asset2_out="500", ) expected = { - "AMMHash": _AMM_HASH, + "AMMID": _AMM_ID, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Asset1Out": "1000", "Asset2Out": "500", @@ -80,7 +80,7 @@ def test_to_xrpl_asset1out_lptokens(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, - amm_hash=_AMM_HASH, + amm_id=_AMM_ID, asset1_out=_AMOUNT, lptokens=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, @@ -89,7 +89,7 @@ def test_to_xrpl_asset1out_lptokens(self): ), ) expected = { - "AMMHash": _AMM_HASH, + "AMMID": _AMM_ID, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Asset1Out": "1000", "LPTokens": { @@ -108,12 +108,12 @@ def test_to_xrpl_asset1out_eprice(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, - amm_hash=_AMM_HASH, + amm_id=_AMM_ID, asset1_out=_AMOUNT, e_price="25", ) expected = { - "AMMHash": _AMM_HASH, + "AMMID": _AMM_ID, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Asset1Out": "1000", "EPrice": "25", @@ -129,7 +129,7 @@ def test_undefined_asset1out_undefined_lptokens_invalid_combo(self): AMMWithdraw( account=_ACCOUNT, sequence=1337, - amm_hash=_AMM_HASH, + amm_id=_AMM_ID, ) def test_undefined_asset1out_defined_asset2out_invalid_combo(self): @@ -137,7 +137,7 @@ def test_undefined_asset1out_defined_asset2out_invalid_combo(self): AMMWithdraw( account=_ACCOUNT, sequence=1337, - amm_hash=_AMM_HASH, + amm_id=_AMM_ID, asset2_out="500", ) @@ -146,6 +146,6 @@ def test_undefined_asset1out_defined_eprice_invalid_combo(self): AMMWithdraw( account=_ACCOUNT, sequence=1337, - amm_hash=_AMM_HASH, + amm_id=_AMM_ID, e_price="25", ) diff --git a/xrpl/core/binarycodec/definitions/definitions.json b/xrpl/core/binarycodec/definitions/definitions.json index c3b6fce4f..605dd2a2c 100644 --- a/xrpl/core/binarycodec/definitions/definitions.json +++ b/xrpl/core/binarycodec/definitions/definitions.json @@ -1183,7 +1183,7 @@ } ], [ - "AMMHash", + "AMMID", { "nth": 14, "isVLEncoded": false, @@ -2479,45 +2479,45 @@ "telCAN_NOT_QUEUE_FULL": -387, "temMALFORMED": -299, - "temBAD_AMM_OPTIONS": -298, - "temBAD_AMM_TOKENS": -297, - "temBAD_AMOUNT": -296, - "temBAD_CURRENCY": -295, - "temBAD_EXPIRATION": -294, - "temBAD_FEE": -293, - "temBAD_ISSUER": -292, - "temBAD_LIMIT": -291, - "temBAD_OFFER": -290, - "temBAD_PATH": -289, - "temBAD_PATH_LOOP": -288, - "temBAD_REGKEY": -287, - "temBAD_SEND_XRP_LIMIT": -286, - "temBAD_SEND_XRP_MAX": -285, - "temBAD_SEND_XRP_NO_DIRECT": -284, - "temBAD_SEND_XRP_PARTIAL": -283, - "temBAD_SEND_XRP_PATHS": -282, - "temBAD_SEQUENCE": -281, - "temBAD_SIGNATURE": -280, - "temBAD_SRC_ACCOUNT": -279, - "temBAD_TRANSFER_RATE": -278, - "temDST_IS_SRC": -277, - "temDST_NEEDED": -276, - "temINVALID": -275, - "temINVALID_FLAG": -274, - "temREDUNDANT": -273, - "temRIPPLE_EMPTY": -272, - "temDISABLED": -271, - "temBAD_SIGNER": -270, - "temBAD_QUORUM": -269, - "temBAD_WEIGHT": -268, - "temBAD_TICK_SIZE": -267, - "temINVALID_ACCOUNT_ID": -266, - "temCANNOT_PREAUTH_SELF": -265, - "temINVALID_COUNT": -264, - "temUNCERTAIN": -263, - "temUNKNOWN": -262, - "temSEQ_AND_TICKET": -261, - "temBAD_NFTOKEN_TRANSFER_FEE": -260, + "temBAD_AMOUNT": -298, + "temBAD_CURRENCY": -297, + "temBAD_EXPIRATION": -296, + "temBAD_FEE": -295, + "temBAD_ISSUER": -294, + "temBAD_LIMIT": -293, + "temBAD_OFFER": -292, + "temBAD_PATH": -291, + "temBAD_PATH_LOOP": -290, + "temBAD_REGKEY": -289, + "temBAD_SEND_XRP_LIMIT": -288, + "temBAD_SEND_XRP_MAX": -287, + "temBAD_SEND_XRP_NO_DIRECT": -286, + "temBAD_SEND_XRP_PARTIAL": -285, + "temBAD_SEND_XRP_PATHS": -284, + "temBAD_SEQUENCE": -283, + "temBAD_SIGNATURE": -282, + "temBAD_SRC_ACCOUNT": -281, + "temBAD_TRANSFER_RATE": -280, + "temDST_IS_SRC": -279, + "temDST_NEEDED": -278, + "temINVALID": -277, + "temINVALID_FLAG": -276, + "temREDUNDANT": -275, + "temRIPPLE_EMPTY": -274, + "temDISABLED": -273, + "temBAD_SIGNER": -272, + "temBAD_QUORUM": -271, + "temBAD_WEIGHT": -270, + "temBAD_TICK_SIZE": -269, + "temINVALID_ACCOUNT_ID": -268, + "temCANNOT_PREAUTH_SELF": -267, + "temINVALID_COUNT": -266, + "temUNCERTAIN": -265, + "temUNKNOWN": -264, + "temSEQ_AND_TICKET": -263, + "temBAD_NFTOKEN_TRANSFER_FEE": -262, + "temBAD_AMM_OPTIONS": -261, + "temBAD_AMM_TOKENS": -260, "tefFAILURE": -199, "tefALREADY": -198, diff --git a/xrpl/models/base_model.py b/xrpl/models/base_model.py index 0990d56ae..2edf54427 100644 --- a/xrpl/models/base_model.py +++ b/xrpl/models/base_model.py @@ -33,7 +33,7 @@ f"(?:{_CAMEL_CASE_LEADING_LOWER}|{_CAMEL_CASE_ABBREVIATION}|{_CAMEL_CASE_TYPICAL})" ) # used for converting special substrings inside CamelCase fields -SPECIAL_CAMELCASE_STRINGS = ["LPTokens", "NFToken"] +SPECIAL_CAMELCASE_STRINGS = ["NFToken", "LPTokens", "AMM"] BM = TypeVar("BM", bound="BaseModel") # any type inherited from BaseModel diff --git a/xrpl/models/requests/amm_info.py b/xrpl/models/requests/amm_info.py index b5c965453..fed0cd183 100644 --- a/xrpl/models/requests/amm_info.py +++ b/xrpl/models/requests/amm_info.py @@ -15,12 +15,12 @@ class AMMInfo(Request): """ This request retrieves information about an AMM instance. - Must provide either AMMHash or both Asset1 and Asset2 params. + Must provide either AMMID or both Asset1 and Asset2 params. """ - AMMHash: Optional[str] = None + AMMID: Optional[str] = None """ - AMMHash is a hash that uniquely identifies the AMM instance. + AMMID is a hash that uniquely identifies the AMM instance. """ Asset1: Optional[Amount] = None @@ -37,11 +37,11 @@ class AMMInfo(Request): def _get_errors(self: AMMInfo) -> Dict[str, str]: errors = super()._get_errors() - if self.AMMHash is None: + if self.AMMID is None: if self.Asset1 is None and self.Asset2 is None: errors[ "AMMInfo" - ] = "Must set either `AMMHash` or both `Asset1` and `Asset2`" + ] = "Must set either `AMMID` or both `Asset1` and `Asset2`" elif self.Asset1 is None and self.Asset2 is not None: errors[ "AMMInfo" diff --git a/xrpl/models/transactions/amm_bid.py b/xrpl/models/transactions/amm_bid.py index 5fbf5c77b..e64bc4020 100644 --- a/xrpl/models/transactions/amm_bid.py +++ b/xrpl/models/transactions/amm_bid.py @@ -26,9 +26,9 @@ class AMMBid(Transaction): discounted TradingFee for a 24 hour slot. """ - amm_hash: str = REQUIRED # type: ignore + amm_id: str = REQUIRED # type: ignore """ - AMMHash is a hash that uniquely identifies the AMM instance. + AMMID is a hash that uniquely identifies the AMM instance. """ min_slot_price: Optional[Amount] = None diff --git a/xrpl/models/transactions/amm_deposit.py b/xrpl/models/transactions/amm_deposit.py index 076337b64..c22bf83e3 100644 --- a/xrpl/models/transactions/amm_deposit.py +++ b/xrpl/models/transactions/amm_deposit.py @@ -26,9 +26,9 @@ class AMMDeposit(Transaction): - Asset1In and EPrice """ - amm_hash: str = REQUIRED # type: ignore + amm_id: str = REQUIRED # type: ignore """ - AMMHash is a hash that uniquely identifies the AMM instance. + AMMID is a hash that uniquely identifies the AMM instance. """ lptokens: Optional[Amount] = None diff --git a/xrpl/models/transactions/amm_vote.py b/xrpl/models/transactions/amm_vote.py index 79538a24e..3abeffed2 100644 --- a/xrpl/models/transactions/amm_vote.py +++ b/xrpl/models/transactions/amm_vote.py @@ -24,9 +24,9 @@ class AMMVote(Transaction): transaction to vote for the trading fee for that instance. """ - amm_hash: str = REQUIRED # type: ignore + amm_id: str = REQUIRED # type: ignore """ - AMMHash is a hash that uniquely identifies the AMM instance. + AMMID is a hash that uniquely identifies the AMM instance. """ fee_val: int = REQUIRED # type: ignore diff --git a/xrpl/models/transactions/amm_withdraw.py b/xrpl/models/transactions/amm_withdraw.py index 37bfdc7bc..9234eabb7 100644 --- a/xrpl/models/transactions/amm_withdraw.py +++ b/xrpl/models/transactions/amm_withdraw.py @@ -27,9 +27,9 @@ class AMMWithdraw(Transaction): - Asset1Out and EPrice """ - amm_hash: str = REQUIRED # type: ignore + amm_id: str = REQUIRED # type: ignore """ - AMMHash is a hash that uniquely identifies the AMM instance. + AMMID is a hash that uniquely identifies the AMM instance. """ lptokens: Optional[Amount] = None From cfe2ef30a05597852f216f98a71d7d5f440bd1c2 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 16 Aug 2022 16:58:13 -0400 Subject: [PATCH 23/88] update lptokens type to IssuedCurrencyAmount --- xrpl/models/transactions/amm_deposit.py | 4 ++-- xrpl/models/transactions/amm_withdraw.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/xrpl/models/transactions/amm_deposit.py b/xrpl/models/transactions/amm_deposit.py index c22bf83e3..715990df2 100644 --- a/xrpl/models/transactions/amm_deposit.py +++ b/xrpl/models/transactions/amm_deposit.py @@ -4,7 +4,7 @@ from dataclasses import dataclass, field from typing import Dict, Optional -from xrpl.models.amounts import Amount +from xrpl.models.amounts import Amount, IssuedCurrencyAmount from xrpl.models.required import REQUIRED from xrpl.models.transactions.transaction import Transaction from xrpl.models.transactions.types import TransactionType @@ -31,7 +31,7 @@ class AMMDeposit(Transaction): AMMID is a hash that uniquely identifies the AMM instance. """ - lptokens: Optional[Amount] = None + lptokens: Optional[IssuedCurrencyAmount] = None """ LPTokens specifies the amount of shares of the AMM instance pools that the trader wants to redeem or trade in. diff --git a/xrpl/models/transactions/amm_withdraw.py b/xrpl/models/transactions/amm_withdraw.py index 9234eabb7..1f054ae99 100644 --- a/xrpl/models/transactions/amm_withdraw.py +++ b/xrpl/models/transactions/amm_withdraw.py @@ -4,7 +4,7 @@ from dataclasses import dataclass, field from typing import Dict, Optional -from xrpl.models.amounts import Amount +from xrpl.models.amounts import Amount, IssuedCurrencyAmount from xrpl.models.required import REQUIRED from xrpl.models.transactions.transaction import Transaction from xrpl.models.transactions.types import TransactionType @@ -32,7 +32,7 @@ class AMMWithdraw(Transaction): AMMID is a hash that uniquely identifies the AMM instance. """ - lptokens: Optional[Amount] = None + lptokens: Optional[IssuedCurrencyAmount] = None """ LPTokens specifies the amount of shares of the AMM instance pools that the trader wants to redeem or trade in. From f1a9b704724185a94896c1501da16b56dfd9a1e1 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 16 Aug 2022 17:52:41 -0400 Subject: [PATCH 24/88] assert with error message --- tests/unit/models/transactions/test_amm_bid.py | 6 +++++- .../models/transactions/test_amm_deposit.py | 18 +++++++++++++++--- .../unit/models/transactions/test_amm_vote.py | 6 +++++- .../models/transactions/test_amm_withdraw.py | 18 +++++++++++++++--- xrpl/models/transactions/amm_deposit.py | 6 +++--- xrpl/models/transactions/amm_withdraw.py | 11 +++++------ 6 files changed, 48 insertions(+), 17 deletions(-) diff --git a/tests/unit/models/transactions/test_amm_bid.py b/tests/unit/models/transactions/test_amm_bid.py index 43250adb6..5e047de21 100644 --- a/tests/unit/models/transactions/test_amm_bid.py +++ b/tests/unit/models/transactions/test_amm_bid.py @@ -20,12 +20,16 @@ class TestAMMBid(TestCase): def test_auth_accounts_length_error(self): auth_accounts = _AUTH_ACCOUNTS.copy() auth_accounts.append("r3X6noRsvaLapAKCG78zAtWcbhB3sggS1s") - with self.assertRaises(XRPLModelException): + with self.assertRaises(XRPLModelException) as error: AMMBid( account=_ACCOUNT, amm_id=_AMM_ID, auth_accounts=auth_accounts, ) + self.assertEqual( + error.exception.args[0], + "{'auth_accounts': 'Must not be greater than 4'}", + ) def test_to_xrpl(self): tx = AMMBid( diff --git a/tests/unit/models/transactions/test_amm_deposit.py b/tests/unit/models/transactions/test_amm_deposit.py index bb376ac84..c1bd31ec0 100644 --- a/tests/unit/models/transactions/test_amm_deposit.py +++ b/tests/unit/models/transactions/test_amm_deposit.py @@ -125,27 +125,39 @@ def test_to_xrpl_asset1in_eprice(self): self.assertEqual(tx.to_xrpl(), expected) def test_undefined_asset1in_undefined_lptokens_invalid_combo(self): - with self.assertRaises(XRPLModelException): + with self.assertRaises(XRPLModelException) as error: AMMDeposit( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, ) + self.assertEqual( + error.exception.args[0], + "{'AMMDeposit': 'Must set either or both `lptokens` and `asset1_in`'}", + ) def test_undefined_asset1in_defined_asset2in_invalid_combo(self): - with self.assertRaises(XRPLModelException): + with self.assertRaises(XRPLModelException) as error: AMMDeposit( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, asset2_in="500", ) + self.assertEqual( + error.exception.args[0], + "{'AMMDeposit': 'Must set `asset1_in` with `asset2_in`'}", + ) def test_undefined_asset1in_defined_eprice_invalid_combo(self): - with self.assertRaises(XRPLModelException): + with self.assertRaises(XRPLModelException) as error: AMMDeposit( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, e_price="25", ) + self.assertEqual( + error.exception.args[0], + "{'AMMDeposit': 'Must set `asset1_in` with `e_price`'}", + ) diff --git a/tests/unit/models/transactions/test_amm_vote.py b/tests/unit/models/transactions/test_amm_vote.py index d6365235c..527cefe2f 100644 --- a/tests/unit/models/transactions/test_amm_vote.py +++ b/tests/unit/models/transactions/test_amm_vote.py @@ -11,12 +11,16 @@ class TestAMMVote(TestCase): def test_trading_fee_too_high(self): - with self.assertRaises(XRPLModelException): + with self.assertRaises(XRPLModelException) as error: AMMVote( account=_ACCOUNT, amm_id=_AMM_ID, fee_val=maxsize, ) + self.assertEqual( + error.exception.args[0], + "{'fee_val': 'Must not be greater than 65000'}", + ) def test_to_xrpl(self): tx = AMMVote( diff --git a/tests/unit/models/transactions/test_amm_withdraw.py b/tests/unit/models/transactions/test_amm_withdraw.py index a007f2844..1ed587684 100644 --- a/tests/unit/models/transactions/test_amm_withdraw.py +++ b/tests/unit/models/transactions/test_amm_withdraw.py @@ -125,27 +125,39 @@ def test_to_xrpl_asset1out_eprice(self): self.assertEqual(tx.to_xrpl(), expected) def test_undefined_asset1out_undefined_lptokens_invalid_combo(self): - with self.assertRaises(XRPLModelException): + with self.assertRaises(XRPLModelException) as error: AMMWithdraw( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, ) + self.assertEqual( + error.exception.args[0], + "{'AMMWithdraw': 'Must set either or both `lptokens` and `asset1_out`'}", + ) def test_undefined_asset1out_defined_asset2out_invalid_combo(self): - with self.assertRaises(XRPLModelException): + with self.assertRaises(XRPLModelException) as error: AMMWithdraw( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, asset2_out="500", ) + self.assertEqual( + error.exception.args[0], + "{'AMMWithdraw': 'Must set `asset1_out` with `asset2_out`'}", + ) def test_undefined_asset1out_defined_eprice_invalid_combo(self): - with self.assertRaises(XRPLModelException): + with self.assertRaises(XRPLModelException) as error: AMMWithdraw( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, e_price="25", ) + self.assertEqual( + error.exception.args[0], + "{'AMMWithdraw': 'Must set `asset1_out` with `e_price`'}", + ) diff --git a/xrpl/models/transactions/amm_deposit.py b/xrpl/models/transactions/amm_deposit.py index 715990df2..d81079b1c 100644 --- a/xrpl/models/transactions/amm_deposit.py +++ b/xrpl/models/transactions/amm_deposit.py @@ -61,10 +61,10 @@ class AMMDeposit(Transaction): def _get_errors(self: AMMDeposit) -> Dict[str, str]: errors = super()._get_errors() - if self.lptokens is None and self.asset1_in is None: - errors["AMMDeposit"] = "Must set either or both `lptokens` and `asset1_in`" - elif self.asset2_in is not None and self.asset1_in is None: + if self.asset2_in is not None and self.asset1_in is None: errors["AMMDeposit"] = "Must set `asset1_in` with `asset2_in`" elif self.e_price is not None and self.asset1_in is None: errors["AMMDeposit"] = "Must set `asset1_in` with `e_price`" + elif self.lptokens is None and self.asset1_in is None: + errors["AMMDeposit"] = "Must set either or both `lptokens` and `asset1_in`" return errors diff --git a/xrpl/models/transactions/amm_withdraw.py b/xrpl/models/transactions/amm_withdraw.py index 1f054ae99..40c780453 100644 --- a/xrpl/models/transactions/amm_withdraw.py +++ b/xrpl/models/transactions/amm_withdraw.py @@ -63,13 +63,12 @@ class AMMWithdraw(Transaction): def _get_errors(self: AMMWithdraw) -> Dict[str, str]: errors = super()._get_errors() - if self.lptokens is None and self.asset1_out is None: - errors[ - "AMMWithdraw" - ] = "Must set either or both `lptokens` and \ - `asset1_out`" - elif self.asset2_out is not None and self.asset1_out is None: + if self.asset2_out is not None and self.asset1_out is None: errors["AMMWithdraw"] = "Must set `asset1_out` with `asset2_out`" elif self.e_price is not None and self.asset1_out is None: errors["AMMWithdraw"] = "Must set `asset1_out` with `e_price`" + elif self.lptokens is None and self.asset1_out is None: + errors[ + "AMMWithdraw" + ] = "Must set either or both `lptokens` and `asset1_out`" return errors From 3b9c0d9e8ce532592d960a23494d7b0d2d6e61e2 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 16 Aug 2022 18:03:39 -0400 Subject: [PATCH 25/88] assert with error messages for AMMInstanceCreate and amm_info --- tests/unit/models/requests/test_amm_info.py | 18 +++++++++++++++--- .../transactions/test_amm_instance_create.py | 6 +++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/tests/unit/models/requests/test_amm_info.py b/tests/unit/models/requests/test_amm_info.py index c01f671ac..c5793322a 100644 --- a/tests/unit/models/requests/test_amm_info.py +++ b/tests/unit/models/requests/test_amm_info.py @@ -26,17 +26,29 @@ def test_asset1_asset2(self): self.assertTrue(request.is_valid()) def test_no_params_is_invalid(self): - with self.assertRaises(XRPLModelException): + with self.assertRaises(XRPLModelException) as error: AMMInfo() + self.assertEqual( + error.exception.args[0], + "{'AMMInfo': 'Must set either `AMMID` or both `Asset1` and `Asset2`'}", + ) def test_missing_asset1_is_invalid(self): - with self.assertRaises(XRPLModelException): + with self.assertRaises(XRPLModelException) as error: AMMInfo( Asset2=_ASSET_2, ) + self.assertEqual( + error.exception.args[0], + "{'AMMInfo': 'Missing `Asset1`. Must set both `Asset1` and `Asset2`'}", + ) def test_missing_asset2_is_invalid(self): - with self.assertRaises(XRPLModelException): + with self.assertRaises(XRPLModelException) as error: AMMInfo( Asset1=_ASSET_1, ) + self.assertEqual( + error.exception.args[0], + "{'AMMInfo': 'Missing `Asset2`. Must set both `Asset1` and `Asset2`'}", + ) diff --git a/tests/unit/models/transactions/test_amm_instance_create.py b/tests/unit/models/transactions/test_amm_instance_create.py index 095f57a76..8e32c3f91 100644 --- a/tests/unit/models/transactions/test_amm_instance_create.py +++ b/tests/unit/models/transactions/test_amm_instance_create.py @@ -11,7 +11,7 @@ class TestAMMInstanceCreate(TestCase): def test_trading_fee_too_high(self): - with self.assertRaises(XRPLModelException): + with self.assertRaises(XRPLModelException) as error: AMMInstanceCreate( account=_ACCOUNT, asset1="1000", @@ -20,6 +20,10 @@ def test_trading_fee_too_high(self): ), trading_fee=maxsize, ) + self.assertEqual( + error.exception.args[0], + "{'trading_fee': 'Must not be greater than 65000'}", + ) def test_to_xrpl(self): tx = AMMInstanceCreate( From a99ea40874c5087f6cd776e07621c971c289fce5 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 16 Aug 2022 18:33:30 -0400 Subject: [PATCH 26/88] move to_xrpl tests to test_base_model --- tests/unit/models/test_base_model.py | 317 ++++++++++++++++++ .../unit/models/transactions/test_amm_bid.py | 50 +-- .../models/transactions/test_amm_deposit.py | 76 +---- .../transactions/test_amm_instance_create.py | 35 +- .../unit/models/transactions/test_amm_vote.py | 24 +- .../models/transactions/test_amm_withdraw.py | 76 +---- 6 files changed, 372 insertions(+), 206 deletions(-) diff --git a/tests/unit/models/test_base_model.py b/tests/unit/models/test_base_model.py index ae5c9bff1..20211d66e 100644 --- a/tests/unit/models/test_base_model.py +++ b/tests/unit/models/test_base_model.py @@ -16,6 +16,11 @@ SubmitOnly, ) from xrpl.models.transactions import ( + AMMBid, + AMMDeposit, + AMMInstanceCreate, + AMMVote, + AMMWithdraw, CheckCreate, Memo, Payment, @@ -597,3 +602,315 @@ def test_to_xrpl_signer(self): ], } self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_amm_instance_create(self): + tx = AMMInstanceCreate( + account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + asset1="1000", + asset2=IssuedCurrencyAmount( + currency="USD", + issuer="rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", + value="1000", + ), + trading_fee=12, + ) + expected = { + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "Asset1": "1000", + "Asset2": { + "currency": "USD", + "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", + "value": "1000", + }, + "TransactionType": "AMMInstanceCreate", + "SigningPubKey": "", + "TradingFee": 12, + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_amm_deposit_lptokens(self): + tx = AMMDeposit( + account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + sequence=1337, + amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + lptokens=IssuedCurrencyAmount( + currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", + issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", + value="1000", + ), + ) + expected = { + "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "LPTokens": { + "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", + "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", + "value": "1000", + }, + "TransactionType": "AMMDeposit", + "Sequence": 1337, + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_amm_deposit_asset1in(self): + tx = AMMDeposit( + account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + sequence=1337, + amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + asset1_in="1000", + ) + expected = { + "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "Asset1In": "1000", + "TransactionType": "AMMDeposit", + "Sequence": 1337, + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_amm_deposit_asset1in_asset2in(self): + tx = AMMDeposit( + account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + sequence=1337, + amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + asset1_in="1000", + asset2_in="500", + ) + expected = { + "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "Asset1In": "1000", + "Asset2In": "500", + "TransactionType": "AMMDeposit", + "Sequence": 1337, + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_amm_deposit_asset1in_lptokens(self): + tx = AMMDeposit( + account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + sequence=1337, + amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + asset1_in="1000", + lptokens=IssuedCurrencyAmount( + currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", + issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", + value="500", + ), + ) + expected = { + "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "Asset1In": "1000", + "LPTokens": { + "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", + "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", + "value": "500", + }, + "TransactionType": "AMMDeposit", + "Sequence": 1337, + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_amm_deposit_asset1in_eprice(self): + tx = AMMDeposit( + account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + sequence=1337, + amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + asset1_in="1000", + e_price="25", + ) + expected = { + "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "Asset1In": "1000", + "EPrice": "25", + "TransactionType": "AMMDeposit", + "Sequence": 1337, + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_amm_withdraw_lptokens(self): + tx = AMMWithdraw( + account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + sequence=1337, + amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + lptokens=IssuedCurrencyAmount( + currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", + issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", + value="1000", + ), + ) + expected = { + "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "LPTokens": { + "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", + "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", + "value": "1000", + }, + "TransactionType": "AMMWithdraw", + "Sequence": 1337, + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_amm_withdraw_asset1out(self): + tx = AMMWithdraw( + account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + sequence=1337, + amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + asset1_out="1000", + ) + expected = { + "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "Asset1Out": "1000", + "TransactionType": "AMMWithdraw", + "Sequence": 1337, + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_amm_withdraw_asset1out_asset2out(self): + tx = AMMWithdraw( + account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + sequence=1337, + amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + asset1_out="1000", + asset2_out="500", + ) + expected = { + "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "Asset1Out": "1000", + "Asset2Out": "500", + "TransactionType": "AMMWithdraw", + "Sequence": 1337, + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_amm_withdraw_asset1out_lptokens(self): + tx = AMMWithdraw( + account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + sequence=1337, + amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + asset1_out="1000", + lptokens=IssuedCurrencyAmount( + currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", + issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", + value="500", + ), + ) + expected = { + "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "Asset1Out": "1000", + "LPTokens": { + "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", + "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", + "value": "500", + }, + "TransactionType": "AMMWithdraw", + "Sequence": 1337, + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_amm_withdraw_asset1out_eprice(self): + tx = AMMWithdraw( + account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + sequence=1337, + amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + asset1_out="1000", + e_price="25", + ) + expected = { + "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "Asset1Out": "1000", + "EPrice": "25", + "TransactionType": "AMMWithdraw", + "Sequence": 1337, + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_amm_vote(self): + tx = AMMVote( + account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + fee_val=1234, + ) + expected = { + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "FeeVal": 1234, + "TransactionType": "AMMVote", + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_amm_bid(self): + tx = AMMBid( + account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + min_slot_price=IssuedCurrencyAmount( + currency="5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", + issuer="r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", + value="25", + ), + max_slot_price=IssuedCurrencyAmount( + currency="5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", + issuer="r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", + value="35", + ), + auth_accounts=[ + "rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh", + "rfpFv97Dwu89FTyUwPjtpZBbuZxTqqgTmH", + "rzzYHPGb8Pa64oqxCzmuffm122bitq3Vb", + "rhwxHxaHok86fe4LykBom1jSJ3RYQJs1h4", + ], + ) + expected = { + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "MinSlotPrice": { + "currency": "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", + "issuer": "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", + "value": "25", + }, + "MaxSlotPrice": { + "currency": "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", + "issuer": "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", + "value": "35", + }, + "AuthAccounts": [ + "rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh", + "rfpFv97Dwu89FTyUwPjtpZBbuZxTqqgTmH", + "rzzYHPGb8Pa64oqxCzmuffm122bitq3Vb", + "rhwxHxaHok86fe4LykBom1jSJ3RYQJs1h4", + ], + "TransactionType": "AMMBid", + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) diff --git a/tests/unit/models/transactions/test_amm_bid.py b/tests/unit/models/transactions/test_amm_bid.py index 5e047de21..bf4f36241 100644 --- a/tests/unit/models/transactions/test_amm_bid.py +++ b/tests/unit/models/transactions/test_amm_bid.py @@ -17,21 +17,7 @@ class TestAMMBid(TestCase): - def test_auth_accounts_length_error(self): - auth_accounts = _AUTH_ACCOUNTS.copy() - auth_accounts.append("r3X6noRsvaLapAKCG78zAtWcbhB3sggS1s") - with self.assertRaises(XRPLModelException) as error: - AMMBid( - account=_ACCOUNT, - amm_id=_AMM_ID, - auth_accounts=auth_accounts, - ) - self.assertEqual( - error.exception.args[0], - "{'auth_accounts': 'Must not be greater than 4'}", - ) - - def test_to_xrpl(self): + def test_tx_valid(self): tx = AMMBid( account=_ACCOUNT, amm_id=_AMM_ID, @@ -47,22 +33,18 @@ def test_to_xrpl(self): ), auth_accounts=_AUTH_ACCOUNTS, ) - expected = { - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "AMMID": _AMM_ID, - "MinSlotPrice": { - "currency": "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", - "issuer": "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", - "value": "25", - }, - "MaxSlotPrice": { - "currency": "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", - "issuer": "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", - "value": "35", - }, - "AuthAccounts": _AUTH_ACCOUNTS, - "TransactionType": "AMMBid", - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) + self.assertTrue(tx.is_valid()) + + def test_auth_accounts_length_error(self): + auth_accounts = _AUTH_ACCOUNTS.copy() + auth_accounts.append("r3X6noRsvaLapAKCG78zAtWcbhB3sggS1s") + with self.assertRaises(XRPLModelException) as error: + AMMBid( + account=_ACCOUNT, + amm_id=_AMM_ID, + auth_accounts=auth_accounts, + ) + self.assertEqual( + error.exception.args[0], + "{'auth_accounts': 'Must not be greater than 4'}", + ) diff --git a/tests/unit/models/transactions/test_amm_deposit.py b/tests/unit/models/transactions/test_amm_deposit.py index c1bd31ec0..84ceb7fb2 100644 --- a/tests/unit/models/transactions/test_amm_deposit.py +++ b/tests/unit/models/transactions/test_amm_deposit.py @@ -12,7 +12,7 @@ class TestAMMDeposit(TestCase): - def test_to_xrpl_lptokens(self): + def test_tx_valid_xrpl_lptokens(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, @@ -23,40 +23,18 @@ def test_to_xrpl_lptokens(self): value=_AMOUNT, ), ) - expected = { - "AMMID": _AMM_ID, - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "LPTokens": { - "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", - "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", - "value": "1000", - }, - "TransactionType": "AMMDeposit", - "Sequence": 1337, - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) + self.assertTrue(tx.is_valid()) - def test_to_xrpl_asset1in(self): + def test_tx_valid_asset1in(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, asset1_in=_AMOUNT, ) - expected = { - "AMMID": _AMM_ID, - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset1In": "1000", - "TransactionType": "AMMDeposit", - "Sequence": 1337, - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) + self.assertTrue(tx.is_valid()) - def test_to_xrpl_asset1in_asset2in(self): + def test_tx_valid_asset1in_asset2in(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, @@ -64,19 +42,9 @@ def test_to_xrpl_asset1in_asset2in(self): asset1_in=_AMOUNT, asset2_in="500", ) - expected = { - "AMMID": _AMM_ID, - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset1In": "1000", - "Asset2In": "500", - "TransactionType": "AMMDeposit", - "Sequence": 1337, - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) + self.assertTrue(tx.is_valid()) - def test_to_xrpl_asset1in_lptokens(self): + def test_tx_valid_asset1in_lptokens(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, @@ -88,23 +56,9 @@ def test_to_xrpl_asset1in_lptokens(self): value="500", ), ) - expected = { - "AMMID": _AMM_ID, - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset1In": "1000", - "LPTokens": { - "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", - "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", - "value": "500", - }, - "TransactionType": "AMMDeposit", - "Sequence": 1337, - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) + self.assertTrue(tx.is_valid()) - def test_to_xrpl_asset1in_eprice(self): + def test_tx_valid_asset1in_eprice(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, @@ -112,17 +66,7 @@ def test_to_xrpl_asset1in_eprice(self): asset1_in=_AMOUNT, e_price="25", ) - expected = { - "AMMID": _AMM_ID, - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset1In": "1000", - "EPrice": "25", - "TransactionType": "AMMDeposit", - "Sequence": 1337, - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) + self.assertTrue(tx.is_valid()) def test_undefined_asset1in_undefined_lptokens_invalid_combo(self): with self.assertRaises(XRPLModelException) as error: diff --git a/tests/unit/models/transactions/test_amm_instance_create.py b/tests/unit/models/transactions/test_amm_instance_create.py index 8e32c3f91..ac8a6a3ef 100644 --- a/tests/unit/models/transactions/test_amm_instance_create.py +++ b/tests/unit/models/transactions/test_amm_instance_create.py @@ -10,6 +10,17 @@ class TestAMMInstanceCreate(TestCase): + def test_tx_is_valid(self): + tx = AMMInstanceCreate( + account=_ACCOUNT, + asset1="1000", + asset2=IssuedCurrencyAmount( + currency="USD", issuer=_IOU_ISSUER, value="1000" + ), + trading_fee=12, + ) + self.assertTrue(tx.is_valid()) + def test_trading_fee_too_high(self): with self.assertRaises(XRPLModelException) as error: AMMInstanceCreate( @@ -24,27 +35,3 @@ def test_trading_fee_too_high(self): error.exception.args[0], "{'trading_fee': 'Must not be greater than 65000'}", ) - - def test_to_xrpl(self): - tx = AMMInstanceCreate( - account=_ACCOUNT, - asset1="1000", - asset2=IssuedCurrencyAmount( - currency="USD", issuer=_IOU_ISSUER, value="1000" - ), - trading_fee=12, - ) - expected = { - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset1": "1000", - "Asset2": { - "currency": "USD", - "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", - "value": "1000", - }, - "TransactionType": "AMMInstanceCreate", - "SigningPubKey": "", - "TradingFee": 12, - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) diff --git a/tests/unit/models/transactions/test_amm_vote.py b/tests/unit/models/transactions/test_amm_vote.py index 527cefe2f..1f45e35a3 100644 --- a/tests/unit/models/transactions/test_amm_vote.py +++ b/tests/unit/models/transactions/test_amm_vote.py @@ -10,6 +10,14 @@ class TestAMMVote(TestCase): + def test_tx_valid(self): + tx = AMMVote( + account=_ACCOUNT, + amm_id=_AMM_ID, + fee_val=_FEE_VAL, + ) + self.assertTrue(tx.is_valid()) + def test_trading_fee_too_high(self): with self.assertRaises(XRPLModelException) as error: AMMVote( @@ -21,19 +29,3 @@ def test_trading_fee_too_high(self): error.exception.args[0], "{'fee_val': 'Must not be greater than 65000'}", ) - - def test_to_xrpl(self): - tx = AMMVote( - account=_ACCOUNT, - amm_id=_AMM_ID, - fee_val=_FEE_VAL, - ) - expected = { - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "AMMID": _AMM_ID, - "FeeVal": 1234, - "TransactionType": "AMMVote", - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) diff --git a/tests/unit/models/transactions/test_amm_withdraw.py b/tests/unit/models/transactions/test_amm_withdraw.py index 1ed587684..8bcb5bf21 100644 --- a/tests/unit/models/transactions/test_amm_withdraw.py +++ b/tests/unit/models/transactions/test_amm_withdraw.py @@ -12,7 +12,7 @@ class TestAMMWithdraw(TestCase): - def test_to_xrpl_lptokens(self): + def test_tx_valid_lptokens(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, @@ -23,40 +23,18 @@ def test_to_xrpl_lptokens(self): value=_AMOUNT, ), ) - expected = { - "AMMID": _AMM_ID, - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "LPTokens": { - "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", - "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", - "value": "1000", - }, - "TransactionType": "AMMWithdraw", - "Sequence": 1337, - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) + self.assertTrue(tx.is_valid()) - def test_to_xrpl_asset1out(self): + def test_tx_valid_asset1out(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, asset1_out=_AMOUNT, ) - expected = { - "AMMID": _AMM_ID, - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset1Out": "1000", - "TransactionType": "AMMWithdraw", - "Sequence": 1337, - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) + self.assertTrue(tx.is_valid()) - def test_to_xrpl_asset1out_asset2out(self): + def test_tx_valid_asset1out_asset2out(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, @@ -64,19 +42,9 @@ def test_to_xrpl_asset1out_asset2out(self): asset1_out=_AMOUNT, asset2_out="500", ) - expected = { - "AMMID": _AMM_ID, - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset1Out": "1000", - "Asset2Out": "500", - "TransactionType": "AMMWithdraw", - "Sequence": 1337, - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) + self.assertTrue(tx.is_valid()) - def test_to_xrpl_asset1out_lptokens(self): + def test_tx_valid_asset1out_lptokens(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, @@ -88,23 +56,9 @@ def test_to_xrpl_asset1out_lptokens(self): value="500", ), ) - expected = { - "AMMID": _AMM_ID, - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset1Out": "1000", - "LPTokens": { - "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", - "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", - "value": "500", - }, - "TransactionType": "AMMWithdraw", - "Sequence": 1337, - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) + self.assertTrue(tx.is_valid()) - def test_to_xrpl_asset1out_eprice(self): + def test_tx_valid_asset1out_eprice(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, @@ -112,17 +66,7 @@ def test_to_xrpl_asset1out_eprice(self): asset1_out=_AMOUNT, e_price="25", ) - expected = { - "AMMID": _AMM_ID, - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset1Out": "1000", - "EPrice": "25", - "TransactionType": "AMMWithdraw", - "Sequence": 1337, - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) + self.assertTrue(tx.is_valid()) def test_undefined_asset1out_undefined_lptokens_invalid_combo(self): with self.assertRaises(XRPLModelException) as error: From a79d1d1075bcb47d588a7da8f36b3fe502101ffd Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 16 Aug 2022 18:45:40 -0400 Subject: [PATCH 27/88] rename lptokens to lp_tokens --- tests/unit/models/test_base_model.py | 8 ++++---- tests/unit/models/transactions/test_amm_deposit.py | 6 +++--- tests/unit/models/transactions/test_amm_withdraw.py | 6 +++--- xrpl/models/base_model.py | 2 +- xrpl/models/transactions/amm_deposit.py | 6 +++--- xrpl/models/transactions/amm_withdraw.py | 6 +++--- xrpl/models/transactions/transaction.py | 2 +- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/unit/models/test_base_model.py b/tests/unit/models/test_base_model.py index 20211d66e..9b85c4668 100644 --- a/tests/unit/models/test_base_model.py +++ b/tests/unit/models/test_base_model.py @@ -634,7 +634,7 @@ def test_to_xrpl_amm_deposit_lptokens(self): account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", - lptokens=IssuedCurrencyAmount( + lp_tokens=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", value="1000", @@ -699,7 +699,7 @@ def test_to_xrpl_amm_deposit_asset1in_lptokens(self): sequence=1337, amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", asset1_in="1000", - lptokens=IssuedCurrencyAmount( + lp_tokens=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", value="500", @@ -746,7 +746,7 @@ def test_to_xrpl_amm_withdraw_lptokens(self): account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", - lptokens=IssuedCurrencyAmount( + lp_tokens=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", value="1000", @@ -811,7 +811,7 @@ def test_to_xrpl_amm_withdraw_asset1out_lptokens(self): sequence=1337, amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", asset1_out="1000", - lptokens=IssuedCurrencyAmount( + lp_tokens=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", value="500", diff --git a/tests/unit/models/transactions/test_amm_deposit.py b/tests/unit/models/transactions/test_amm_deposit.py index 84ceb7fb2..b7ed1b8b2 100644 --- a/tests/unit/models/transactions/test_amm_deposit.py +++ b/tests/unit/models/transactions/test_amm_deposit.py @@ -17,7 +17,7 @@ def test_tx_valid_xrpl_lptokens(self): account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, - lptokens=IssuedCurrencyAmount( + lp_tokens=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, value=_AMOUNT, @@ -50,7 +50,7 @@ def test_tx_valid_asset1in_lptokens(self): sequence=1337, amm_id=_AMM_ID, asset1_in=_AMOUNT, - lptokens=IssuedCurrencyAmount( + lp_tokens=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, value="500", @@ -77,7 +77,7 @@ def test_undefined_asset1in_undefined_lptokens_invalid_combo(self): ) self.assertEqual( error.exception.args[0], - "{'AMMDeposit': 'Must set either or both `lptokens` and `asset1_in`'}", + "{'AMMDeposit': 'Must set either or both `lp_tokens` and `asset1_in`'}", ) def test_undefined_asset1in_defined_asset2in_invalid_combo(self): diff --git a/tests/unit/models/transactions/test_amm_withdraw.py b/tests/unit/models/transactions/test_amm_withdraw.py index 8bcb5bf21..2fb4d09c0 100644 --- a/tests/unit/models/transactions/test_amm_withdraw.py +++ b/tests/unit/models/transactions/test_amm_withdraw.py @@ -17,7 +17,7 @@ def test_tx_valid_lptokens(self): account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, - lptokens=IssuedCurrencyAmount( + lp_tokens=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, value=_AMOUNT, @@ -50,7 +50,7 @@ def test_tx_valid_asset1out_lptokens(self): sequence=1337, amm_id=_AMM_ID, asset1_out=_AMOUNT, - lptokens=IssuedCurrencyAmount( + lp_tokens=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, value="500", @@ -77,7 +77,7 @@ def test_undefined_asset1out_undefined_lptokens_invalid_combo(self): ) self.assertEqual( error.exception.args[0], - "{'AMMWithdraw': 'Must set either or both `lptokens` and `asset1_out`'}", + "{'AMMWithdraw': 'Must set either or both `lp_tokens` and `asset1_out`'}", ) def test_undefined_asset1out_defined_asset2out_invalid_combo(self): diff --git a/xrpl/models/base_model.py b/xrpl/models/base_model.py index 2edf54427..d6e112bf9 100644 --- a/xrpl/models/base_model.py +++ b/xrpl/models/base_model.py @@ -33,7 +33,7 @@ f"(?:{_CAMEL_CASE_LEADING_LOWER}|{_CAMEL_CASE_ABBREVIATION}|{_CAMEL_CASE_TYPICAL})" ) # used for converting special substrings inside CamelCase fields -SPECIAL_CAMELCASE_STRINGS = ["NFToken", "LPTokens", "AMM"] +SPECIAL_CAMELCASE_STRINGS = ["NFToken", "AMM", "LP"] BM = TypeVar("BM", bound="BaseModel") # any type inherited from BaseModel diff --git a/xrpl/models/transactions/amm_deposit.py b/xrpl/models/transactions/amm_deposit.py index d81079b1c..b87d09d20 100644 --- a/xrpl/models/transactions/amm_deposit.py +++ b/xrpl/models/transactions/amm_deposit.py @@ -31,7 +31,7 @@ class AMMDeposit(Transaction): AMMID is a hash that uniquely identifies the AMM instance. """ - lptokens: Optional[IssuedCurrencyAmount] = None + lp_tokens: Optional[IssuedCurrencyAmount] = None """ LPTokens specifies the amount of shares of the AMM instance pools that the trader wants to redeem or trade in. @@ -65,6 +65,6 @@ def _get_errors(self: AMMDeposit) -> Dict[str, str]: errors["AMMDeposit"] = "Must set `asset1_in` with `asset2_in`" elif self.e_price is not None and self.asset1_in is None: errors["AMMDeposit"] = "Must set `asset1_in` with `e_price`" - elif self.lptokens is None and self.asset1_in is None: - errors["AMMDeposit"] = "Must set either or both `lptokens` and `asset1_in`" + elif self.lp_tokens is None and self.asset1_in is None: + errors["AMMDeposit"] = "Must set either or both `lp_tokens` and `asset1_in`" return errors diff --git a/xrpl/models/transactions/amm_withdraw.py b/xrpl/models/transactions/amm_withdraw.py index 40c780453..f3bcad78e 100644 --- a/xrpl/models/transactions/amm_withdraw.py +++ b/xrpl/models/transactions/amm_withdraw.py @@ -32,7 +32,7 @@ class AMMWithdraw(Transaction): AMMID is a hash that uniquely identifies the AMM instance. """ - lptokens: Optional[IssuedCurrencyAmount] = None + lp_tokens: Optional[IssuedCurrencyAmount] = None """ LPTokens specifies the amount of shares of the AMM instance pools that the trader wants to redeem or trade in. @@ -67,8 +67,8 @@ def _get_errors(self: AMMWithdraw) -> Dict[str, str]: errors["AMMWithdraw"] = "Must set `asset1_out` with `asset2_out`" elif self.e_price is not None and self.asset1_out is None: errors["AMMWithdraw"] = "Must set `asset1_out` with `e_price`" - elif self.lptokens is None and self.asset1_out is None: + elif self.lp_tokens is None and self.asset1_out is None: errors[ "AMMWithdraw" - ] = "Must set either or both `lptokens` and `asset1_out`" + ] = "Must set either or both `lp_tokens` and `asset1_out`" return errors diff --git a/xrpl/models/transactions/transaction.py b/xrpl/models/transactions/transaction.py index a164d464c..af46aa0d0 100644 --- a/xrpl/models/transactions/transaction.py +++ b/xrpl/models/transactions/transaction.py @@ -24,7 +24,7 @@ _ABBREVIATIONS: Final[Dict[str, str]] = { "amm": "AMM", "id": "ID", - "lptokens": "LPTokens", + "lp": "LP", "nftoken": "NFToken", "unl": "UNL", "uri": "URI", From eec65dcc7811d56de73cec813222e93e07bdf6fa Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 17 Aug 2022 11:20:30 -0400 Subject: [PATCH 28/88] update amm_info request params to be in snake_case --- tests/unit/models/requests/test_amm_info.py | 16 ++++++++-------- xrpl/models/requests/amm_info.py | 20 ++++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/unit/models/requests/test_amm_info.py b/tests/unit/models/requests/test_amm_info.py index c5793322a..919b11707 100644 --- a/tests/unit/models/requests/test_amm_info.py +++ b/tests/unit/models/requests/test_amm_info.py @@ -14,14 +14,14 @@ class TestAMMInfo(TestCase): def test_amm_id(self): request = AMMInfo( - AMMID=_AMM_ID, + amm_id=_AMM_ID, ) self.assertTrue(request.is_valid()) def test_asset1_asset2(self): request = AMMInfo( - Asset1=_ASSET_1, - Asset2=_ASSET_2, + asset1=_ASSET_1, + asset2=_ASSET_2, ) self.assertTrue(request.is_valid()) @@ -30,25 +30,25 @@ def test_no_params_is_invalid(self): AMMInfo() self.assertEqual( error.exception.args[0], - "{'AMMInfo': 'Must set either `AMMID` or both `Asset1` and `Asset2`'}", + "{'AMMInfo': 'Must set either `amm_id` or both `asset1` and `asset2`'}", ) def test_missing_asset1_is_invalid(self): with self.assertRaises(XRPLModelException) as error: AMMInfo( - Asset2=_ASSET_2, + asset2=_ASSET_2, ) self.assertEqual( error.exception.args[0], - "{'AMMInfo': 'Missing `Asset1`. Must set both `Asset1` and `Asset2`'}", + "{'AMMInfo': 'Missing `asset1`. Must set both `asset1` and `asset2`'}", ) def test_missing_asset2_is_invalid(self): with self.assertRaises(XRPLModelException) as error: AMMInfo( - Asset1=_ASSET_1, + asset1=_ASSET_1, ) self.assertEqual( error.exception.args[0], - "{'AMMInfo': 'Missing `Asset2`. Must set both `Asset1` and `Asset2`'}", + "{'AMMInfo': 'Missing `asset2`. Must set both `asset1` and `asset2`'}", ) diff --git a/xrpl/models/requests/amm_info.py b/xrpl/models/requests/amm_info.py index fed0cd183..b082a5cae 100644 --- a/xrpl/models/requests/amm_info.py +++ b/xrpl/models/requests/amm_info.py @@ -18,17 +18,17 @@ class AMMInfo(Request): Must provide either AMMID or both Asset1 and Asset2 params. """ - AMMID: Optional[str] = None + amm_id: Optional[str] = None """ AMMID is a hash that uniquely identifies the AMM instance. """ - Asset1: Optional[Amount] = None + asset1: Optional[Amount] = None """ Asset1 specifies one of the pool assets (XRP or token) of the AMM instance. """ - Asset2: Optional[Amount] = None + asset2: Optional[Amount] = None """ Asset2 specifies the other pool asset of the AMM instance. """ @@ -37,17 +37,17 @@ class AMMInfo(Request): def _get_errors(self: AMMInfo) -> Dict[str, str]: errors = super()._get_errors() - if self.AMMID is None: - if self.Asset1 is None and self.Asset2 is None: + if self.amm_id is None: + if self.asset1 is None and self.asset2 is None: errors[ "AMMInfo" - ] = "Must set either `AMMID` or both `Asset1` and `Asset2`" - elif self.Asset1 is None and self.Asset2 is not None: + ] = "Must set either `amm_id` or both `asset1` and `asset2`" + elif self.asset1 is None and self.asset2 is not None: errors[ "AMMInfo" - ] = "Missing `Asset1`. Must set both `Asset1` and `Asset2`" - elif self.Asset1 is not None and self.Asset2 is None: + ] = "Missing `asset1`. Must set both `asset1` and `asset2`" + elif self.asset1 is not None and self.asset2 is None: errors[ "AMMInfo" - ] = "Missing `Asset2`. Must set both `Asset1` and `Asset2`" + ] = "Missing `asset2`. Must set both `asset1` and `asset2`" return errors From 4fc1722e817e277417f540a1768a403de81922b3 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 17 Aug 2022 11:36:40 -0400 Subject: [PATCH 29/88] update docstrings --- xrpl/models/requests/amm_info.py | 6 +++--- xrpl/models/transactions/amm_bid.py | 8 ++++---- xrpl/models/transactions/amm_deposit.py | 10 +++++----- xrpl/models/transactions/amm_instance_create.py | 9 +++++---- xrpl/models/transactions/amm_vote.py | 6 +++--- xrpl/models/transactions/amm_withdraw.py | 10 +++++----- 6 files changed, 25 insertions(+), 24 deletions(-) diff --git a/xrpl/models/requests/amm_info.py b/xrpl/models/requests/amm_info.py index b082a5cae..3d7364814 100644 --- a/xrpl/models/requests/amm_info.py +++ b/xrpl/models/requests/amm_info.py @@ -20,17 +20,17 @@ class AMMInfo(Request): amm_id: Optional[str] = None """ - AMMID is a hash that uniquely identifies the AMM instance. + A hash that uniquely identifies the AMM instance. """ asset1: Optional[Amount] = None """ - Asset1 specifies one of the pool assets (XRP or token) of the AMM instance. + Specifies one of the pool assets (XRP or token) of the AMM instance. """ asset2: Optional[Amount] = None """ - Asset2 specifies the other pool asset of the AMM instance. + Specifies the other pool asset of the AMM instance. """ method: RequestMethod = field(default=RequestMethod.AMM_INFO, init=False) diff --git a/xrpl/models/transactions/amm_bid.py b/xrpl/models/transactions/amm_bid.py index e64bc4020..57ea2d667 100644 --- a/xrpl/models/transactions/amm_bid.py +++ b/xrpl/models/transactions/amm_bid.py @@ -28,12 +28,12 @@ class AMMBid(Transaction): amm_id: str = REQUIRED # type: ignore """ - AMMID is a hash that uniquely identifies the AMM instance. + A hash that uniquely identifies the AMM instance. This field is required. """ min_slot_price: Optional[Amount] = None """ - MinSlotPrice represents the minimum price that the bidder wants to pay for the slot. + This field represents the minimum price that the bidder wants to pay for the slot. It is specified in units of LPTokens. If specified let MinSlotPrice be X and let the slot-price computed by price scheduling algorithm be Y, then bidder always pays the max(X, Y). @@ -41,13 +41,13 @@ class AMMBid(Transaction): max_slot_price: Optional[Amount] = None """ - MaxSlotPrice represents the maximum price that the bidder wants to pay for the slot. + This field represents the maximum price that the bidder wants to pay for the slot. It is specified in units of LPTokens. """ auth_accounts: Optional[List[str]] = None """ - AuthAccounts represents an array of XRPL account IDs that are authorized to trade + This field represents an array of XRPL account IDs that are authorized to trade at the discounted fee against the AMM instance. A maximum of four accounts can be provided. """ diff --git a/xrpl/models/transactions/amm_deposit.py b/xrpl/models/transactions/amm_deposit.py index b87d09d20..27e728d32 100644 --- a/xrpl/models/transactions/amm_deposit.py +++ b/xrpl/models/transactions/amm_deposit.py @@ -28,30 +28,30 @@ class AMMDeposit(Transaction): amm_id: str = REQUIRED # type: ignore """ - AMMID is a hash that uniquely identifies the AMM instance. + A hash that uniquely identifies the AMM instance. This field is required. """ lp_tokens: Optional[IssuedCurrencyAmount] = None """ - LPTokens specifies the amount of shares of the AMM instance pools that the trader + Specifies the amount of shares of the AMM instance pools that the trader wants to redeem or trade in. """ asset1_in: Optional[Amount] = None """ - Asset1In specifies one of the pool assets (XRP or token) of the AMM instance to + Specifies one of the pool assets (XRP or token) of the AMM instance to deposit more of its value. """ asset2_in: Optional[Amount] = None """ - Asset2In specifies the other pool asset of the AMM instance to deposit more of its + Specifies the other pool asset of the AMM instance to deposit more of its value. """ e_price: Optional[Amount] = None """ - EPrice specifies the maximum effective-price that LPTokens can be traded out. + Specifies the maximum effective-price that LPTokens can be traded out. """ transaction_type: TransactionType = field( diff --git a/xrpl/models/transactions/amm_instance_create.py b/xrpl/models/transactions/amm_instance_create.py index 49b94cf58..6ebfb31c9 100644 --- a/xrpl/models/transactions/amm_instance_create.py +++ b/xrpl/models/transactions/amm_instance_create.py @@ -26,22 +26,23 @@ class AMMInstanceCreate(Transaction): asset1: Amount = REQUIRED # type: ignore """ - Asset1 specifies one of the pool assets (XRP or token) of the AMM instance. + Specifies one of the pool assets (XRP or token) of the AMM instance. + This field is required. """ asset2: Amount = REQUIRED # type: ignore """ - Asset2 specifies the other pool asset of the AMM instance. + Specifies the other pool asset of the AMM instance. This field is required. """ trading_fee: int = REQUIRED # type: ignore """ - TradingFee specifies the fee, in basis point, to be charged + Specifies the fee, in basis point, to be charged to the traders for the trades executed against the AMM instance. Trading fee is a percentage of the trading volume. Valid values for this field are between 0 and 65000 inclusive. A value of 1 is equivalent to 1/10 bps or 0.001%, allowing trading fee - between 0% and 65%. + between 0% and 65%. This field is required. """ transaction_type: TransactionType = field( diff --git a/xrpl/models/transactions/amm_vote.py b/xrpl/models/transactions/amm_vote.py index 3abeffed2..909f80958 100644 --- a/xrpl/models/transactions/amm_vote.py +++ b/xrpl/models/transactions/amm_vote.py @@ -26,15 +26,15 @@ class AMMVote(Transaction): amm_id: str = REQUIRED # type: ignore """ - AMMID is a hash that uniquely identifies the AMM instance. + A hash that uniquely identifies the AMM instance. This field is required. """ fee_val: int = REQUIRED # type: ignore """ - FeeVal specifies the fee, in basis point. + Specifies the fee, in basis point. Valid values for this field are between 0 and 65000 inclusive. A value of 1 is equivalent to 1/10 bps or 0.001%, allowing trading fee - between 0% and 65%. + between 0% and 65%. This field is required. """ transaction_type: TransactionType = field( diff --git a/xrpl/models/transactions/amm_withdraw.py b/xrpl/models/transactions/amm_withdraw.py index f3bcad78e..852c1cc91 100644 --- a/xrpl/models/transactions/amm_withdraw.py +++ b/xrpl/models/transactions/amm_withdraw.py @@ -29,30 +29,30 @@ class AMMWithdraw(Transaction): amm_id: str = REQUIRED # type: ignore """ - AMMID is a hash that uniquely identifies the AMM instance. + A hash that uniquely identifies the AMM instance. This field is required. """ lp_tokens: Optional[IssuedCurrencyAmount] = None """ - LPTokens specifies the amount of shares of the AMM instance pools that the trader + Specifies the amount of shares of the AMM instance pools that the trader wants to redeem or trade in. """ asset1_out: Optional[Amount] = None """ - Asset1Out specifies one of the pools assets that the trader wants to remove. + Specifies one of the pools assets that the trader wants to remove. If the asset is XRP, then the Asset1Out is a string specifying the number of drops. Otherwise it is an IssuedCurrencyAmount object. """ asset2_out: Optional[Amount] = None """ - Asset2Out specifies the other pool asset that the trader wants to remove. + Specifies the other pool asset that the trader wants to remove. """ e_price: Optional[Amount] = None """ - EPrice specifies the effective-price of the token out after successful execution of + Specifies the effective-price of the token out after successful execution of the transaction. """ From 46b782597f90c2a6f500fa96376d1b03ea6a0177 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 17 Aug 2022 11:40:00 -0400 Subject: [PATCH 30/88] reorder SPECIAL_CAMELCASE_STRINGS to alphabetical order --- xrpl/models/base_model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xrpl/models/base_model.py b/xrpl/models/base_model.py index d6e112bf9..15e03f262 100644 --- a/xrpl/models/base_model.py +++ b/xrpl/models/base_model.py @@ -33,7 +33,7 @@ f"(?:{_CAMEL_CASE_LEADING_LOWER}|{_CAMEL_CASE_ABBREVIATION}|{_CAMEL_CASE_TYPICAL})" ) # used for converting special substrings inside CamelCase fields -SPECIAL_CAMELCASE_STRINGS = ["NFToken", "AMM", "LP"] +SPECIAL_CAMELCASE_STRINGS = ["AMM", "LP", "NFToken"] BM = TypeVar("BM", bound="BaseModel") # any type inherited from BaseModel From d26a12b13c09813745466aa3be443ca06269a28c Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 17 Aug 2022 11:52:36 -0400 Subject: [PATCH 31/88] refactor ABBREVIATIONS to be set in one place --- xrpl/models/base_model.py | 14 +++++++++++--- xrpl/models/transactions/transaction.py | 16 +++------------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/xrpl/models/base_model.py b/xrpl/models/base_model.py index 15e03f262..8a34b0a22 100644 --- a/xrpl/models/base_model.py +++ b/xrpl/models/base_model.py @@ -32,8 +32,16 @@ _CAMEL_TO_SNAKE_CASE_REGEX: Final[Pattern[str]] = re.compile( f"(?:{_CAMEL_CASE_LEADING_LOWER}|{_CAMEL_CASE_ABBREVIATION}|{_CAMEL_CASE_TYPICAL})" ) -# used for converting special substrings inside CamelCase fields -SPECIAL_CAMELCASE_STRINGS = ["AMM", "LP", "NFToken"] +# This is used to make exceptions when converting dictionary keys to xrpl JSON +# keys. We snake case keys, but some keys are abbreviations. +ABBREVIATIONS: Final[Dict[str, str]] = { + "amm": "AMM", + "id": "ID", + "lp": "LP", + "nftoken": "NFToken", + "unl": "UNL", + "uri": "URI", +} BM = TypeVar("BM", bound="BaseModel") # any type inherited from BaseModel @@ -46,7 +54,7 @@ def _key_to_json(field: str) -> str: 3. 'URI' becomes 'uri' """ # convert all special CamelCase substrings to capitalized strings - for spec_str in SPECIAL_CAMELCASE_STRINGS: + for spec_str in ABBREVIATIONS.values(): if spec_str in field: field = field.replace(spec_str, spec_str.capitalize()) diff --git a/xrpl/models/transactions/transaction.py b/xrpl/models/transactions/transaction.py index af46aa0d0..86f437d99 100644 --- a/xrpl/models/transactions/transaction.py +++ b/xrpl/models/transactions/transaction.py @@ -9,7 +9,7 @@ from xrpl.core.binarycodec import encode from xrpl.models.amounts import IssuedCurrencyAmount -from xrpl.models.base_model import BaseModel +from xrpl.models.base_model import ABBREVIATIONS, BaseModel from xrpl.models.exceptions import XRPLModelException from xrpl.models.flags import check_false_flag_definition, interface_to_flag_list from xrpl.models.requests import PathStep @@ -19,16 +19,6 @@ from xrpl.models.utils import require_kwargs_on_init _TRANSACTION_HASH_PREFIX: Final[int] = 0x54584E00 -# This is used to make exceptions when converting dictionary keys to xrpl JSON -# keys. We snake case keys, but some keys are abbreviations. -_ABBREVIATIONS: Final[Dict[str, str]] = { - "amm": "AMM", - "id": "ID", - "lp": "LP", - "nftoken": "NFToken", - "unl": "UNL", - "uri": "URI", -} def transaction_json_to_binary_codec_form( @@ -57,11 +47,11 @@ def _key_to_tx_json(key: str) -> str: 1. 'transaction_type' becomes 'TransactionType' 2. 'URI' becomes 'uri' - Known abbreviations (example 2 above) need to be enumerated in _ABBREVIATIONS. + Known abbreviations (example 2 above) need to be enumerated in ABBREVIATIONS. """ return "".join( [ - _ABBREVIATIONS[word] if word in _ABBREVIATIONS else word.capitalize() + ABBREVIATIONS[word] if word in ABBREVIATIONS else word.capitalize() for word in key.split("_") ] ) From 8af2c7589004262d0c338b83d81d30204072646a Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 18 Aug 2022 13:36:34 -0400 Subject: [PATCH 32/88] rename LPTokens to LPToken --- tests/unit/models/test_base_model.py | 24 +++++++++---------- .../unit/models/transactions/test_amm_bid.py | 12 +++++----- .../models/transactions/test_amm_deposit.py | 12 +++++----- .../models/transactions/test_amm_withdraw.py | 12 +++++----- .../binarycodec/definitions/definitions.json | 2 +- xrpl/models/transactions/amm_bid.py | 4 ++-- xrpl/models/transactions/amm_deposit.py | 14 +++++------ xrpl/models/transactions/amm_vote.py | 2 +- xrpl/models/transactions/amm_withdraw.py | 12 +++++----- 9 files changed, 47 insertions(+), 47 deletions(-) diff --git a/tests/unit/models/test_base_model.py b/tests/unit/models/test_base_model.py index 9b85c4668..532917889 100644 --- a/tests/unit/models/test_base_model.py +++ b/tests/unit/models/test_base_model.py @@ -629,12 +629,12 @@ def test_to_xrpl_amm_instance_create(self): } self.assertEqual(tx.to_xrpl(), expected) - def test_to_xrpl_amm_deposit_lptokens(self): + def test_to_xrpl_amm_deposit_lptoken(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", - lp_tokens=IssuedCurrencyAmount( + lp_token=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", value="1000", @@ -643,7 +643,7 @@ def test_to_xrpl_amm_deposit_lptokens(self): expected = { "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "LPTokens": { + "LPToken": { "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000", @@ -693,13 +693,13 @@ def test_to_xrpl_amm_deposit_asset1in_asset2in(self): } self.assertEqual(tx.to_xrpl(), expected) - def test_to_xrpl_amm_deposit_asset1in_lptokens(self): + def test_to_xrpl_amm_deposit_asset1in_lptoken(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", asset1_in="1000", - lp_tokens=IssuedCurrencyAmount( + lp_token=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", value="500", @@ -709,7 +709,7 @@ def test_to_xrpl_amm_deposit_asset1in_lptokens(self): "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Asset1In": "1000", - "LPTokens": { + "LPToken": { "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "500", @@ -741,12 +741,12 @@ def test_to_xrpl_amm_deposit_asset1in_eprice(self): } self.assertEqual(tx.to_xrpl(), expected) - def test_to_xrpl_amm_withdraw_lptokens(self): + def test_to_xrpl_amm_withdraw_lptoken(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", - lp_tokens=IssuedCurrencyAmount( + lp_token=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", value="1000", @@ -755,7 +755,7 @@ def test_to_xrpl_amm_withdraw_lptokens(self): expected = { "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "LPTokens": { + "LPToken": { "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000", @@ -805,13 +805,13 @@ def test_to_xrpl_amm_withdraw_asset1out_asset2out(self): } self.assertEqual(tx.to_xrpl(), expected) - def test_to_xrpl_amm_withdraw_asset1out_lptokens(self): + def test_to_xrpl_amm_withdraw_asset1out_lptoken(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", asset1_out="1000", - lp_tokens=IssuedCurrencyAmount( + lp_token=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", value="500", @@ -821,7 +821,7 @@ def test_to_xrpl_amm_withdraw_asset1out_lptokens(self): "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Asset1Out": "1000", - "LPTokens": { + "LPToken": { "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "500", diff --git a/tests/unit/models/transactions/test_amm_bid.py b/tests/unit/models/transactions/test_amm_bid.py index bf4f36241..a93b7c0d5 100644 --- a/tests/unit/models/transactions/test_amm_bid.py +++ b/tests/unit/models/transactions/test_amm_bid.py @@ -12,8 +12,8 @@ "rzzYHPGb8Pa64oqxCzmuffm122bitq3Vb", "rhwxHxaHok86fe4LykBom1jSJ3RYQJs1h4", ] -_LPTOKENS_CURRENCY = "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A" -_LPTOKENS_ISSUER = "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw" +_LPTOKEN_CURRENCY = "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A" +_LPTOKEN_ISSUER = "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw" class TestAMMBid(TestCase): @@ -22,13 +22,13 @@ def test_tx_valid(self): account=_ACCOUNT, amm_id=_AMM_ID, min_slot_price=IssuedCurrencyAmount( - currency=_LPTOKENS_CURRENCY, - issuer=_LPTOKENS_ISSUER, + currency=_LPTOKEN_CURRENCY, + issuer=_LPTOKEN_ISSUER, value="25", ), max_slot_price=IssuedCurrencyAmount( - currency=_LPTOKENS_CURRENCY, - issuer=_LPTOKENS_ISSUER, + currency=_LPTOKEN_CURRENCY, + issuer=_LPTOKEN_ISSUER, value="35", ), auth_accounts=_AUTH_ACCOUNTS, diff --git a/tests/unit/models/transactions/test_amm_deposit.py b/tests/unit/models/transactions/test_amm_deposit.py index b7ed1b8b2..d49ba7fd5 100644 --- a/tests/unit/models/transactions/test_amm_deposit.py +++ b/tests/unit/models/transactions/test_amm_deposit.py @@ -12,12 +12,12 @@ class TestAMMDeposit(TestCase): - def test_tx_valid_xrpl_lptokens(self): + def test_tx_valid_xrpl_lptoken(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, - lp_tokens=IssuedCurrencyAmount( + lp_token=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, value=_AMOUNT, @@ -44,13 +44,13 @@ def test_tx_valid_asset1in_asset2in(self): ) self.assertTrue(tx.is_valid()) - def test_tx_valid_asset1in_lptokens(self): + def test_tx_valid_asset1in_lptoken(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, asset1_in=_AMOUNT, - lp_tokens=IssuedCurrencyAmount( + lp_token=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, value="500", @@ -68,7 +68,7 @@ def test_tx_valid_asset1in_eprice(self): ) self.assertTrue(tx.is_valid()) - def test_undefined_asset1in_undefined_lptokens_invalid_combo(self): + def test_undefined_asset1in_undefined_lptoken_invalid_combo(self): with self.assertRaises(XRPLModelException) as error: AMMDeposit( account=_ACCOUNT, @@ -77,7 +77,7 @@ def test_undefined_asset1in_undefined_lptokens_invalid_combo(self): ) self.assertEqual( error.exception.args[0], - "{'AMMDeposit': 'Must set either or both `lp_tokens` and `asset1_in`'}", + "{'AMMDeposit': 'Must set either or both `lp_token` and `asset1_in`'}", ) def test_undefined_asset1in_defined_asset2in_invalid_combo(self): diff --git a/tests/unit/models/transactions/test_amm_withdraw.py b/tests/unit/models/transactions/test_amm_withdraw.py index 2fb4d09c0..712252eed 100644 --- a/tests/unit/models/transactions/test_amm_withdraw.py +++ b/tests/unit/models/transactions/test_amm_withdraw.py @@ -12,12 +12,12 @@ class TestAMMWithdraw(TestCase): - def test_tx_valid_lptokens(self): + def test_tx_valid_lptoken(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, - lp_tokens=IssuedCurrencyAmount( + lp_token=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, value=_AMOUNT, @@ -44,13 +44,13 @@ def test_tx_valid_asset1out_asset2out(self): ) self.assertTrue(tx.is_valid()) - def test_tx_valid_asset1out_lptokens(self): + def test_tx_valid_asset1out_lptoken(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, asset1_out=_AMOUNT, - lp_tokens=IssuedCurrencyAmount( + lp_token=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, value="500", @@ -68,7 +68,7 @@ def test_tx_valid_asset1out_eprice(self): ) self.assertTrue(tx.is_valid()) - def test_undefined_asset1out_undefined_lptokens_invalid_combo(self): + def test_undefined_asset1out_undefined_lptoken_invalid_combo(self): with self.assertRaises(XRPLModelException) as error: AMMWithdraw( account=_ACCOUNT, @@ -77,7 +77,7 @@ def test_undefined_asset1out_undefined_lptokens_invalid_combo(self): ) self.assertEqual( error.exception.args[0], - "{'AMMWithdraw': 'Must set either or both `lp_tokens` and `asset1_out`'}", + "{'AMMWithdraw': 'Must set either or both `lp_token` and `asset1_out`'}", ) def test_undefined_asset1out_defined_asset2out_invalid_combo(self): diff --git a/xrpl/core/binarycodec/definitions/definitions.json b/xrpl/core/binarycodec/definitions/definitions.json index 605dd2a2c..ce449a517 100644 --- a/xrpl/core/binarycodec/definitions/definitions.json +++ b/xrpl/core/binarycodec/definitions/definitions.json @@ -1583,7 +1583,7 @@ } ], [ - "LPTokens", + "LPToken", { "nth": 24, "isVLEncoded": false, diff --git a/xrpl/models/transactions/amm_bid.py b/xrpl/models/transactions/amm_bid.py index 57ea2d667..246731c77 100644 --- a/xrpl/models/transactions/amm_bid.py +++ b/xrpl/models/transactions/amm_bid.py @@ -34,7 +34,7 @@ class AMMBid(Transaction): min_slot_price: Optional[Amount] = None """ This field represents the minimum price that the bidder wants to pay for the slot. - It is specified in units of LPTokens. If specified let MinSlotPrice be X and let + It is specified in units of LPToken. If specified let MinSlotPrice be X and let the slot-price computed by price scheduling algorithm be Y, then bidder always pays the max(X, Y). """ @@ -42,7 +42,7 @@ class AMMBid(Transaction): max_slot_price: Optional[Amount] = None """ This field represents the maximum price that the bidder wants to pay for the slot. - It is specified in units of LPTokens. + It is specified in units of LPToken. """ auth_accounts: Optional[List[str]] = None diff --git a/xrpl/models/transactions/amm_deposit.py b/xrpl/models/transactions/amm_deposit.py index 27e728d32..1d7186841 100644 --- a/xrpl/models/transactions/amm_deposit.py +++ b/xrpl/models/transactions/amm_deposit.py @@ -16,13 +16,13 @@ class AMMDeposit(Transaction): """ AMDeposit is the deposit transaction used to add liquidity to the AMM instance pool, - thus obtaining some share of the instance's pools in the form of LPTokens. + thus obtaining some share of the instance's pools in the form of LPToken. The following are the recommended valid combinations: - - LPTokens + - LPToken - Asset1In - Asset1In and Asset2In - - Asset1In and LPTokens + - Asset1In and LPToken - Asset1In and EPrice """ @@ -31,7 +31,7 @@ class AMMDeposit(Transaction): A hash that uniquely identifies the AMM instance. This field is required. """ - lp_tokens: Optional[IssuedCurrencyAmount] = None + lp_token: Optional[IssuedCurrencyAmount] = None """ Specifies the amount of shares of the AMM instance pools that the trader wants to redeem or trade in. @@ -51,7 +51,7 @@ class AMMDeposit(Transaction): e_price: Optional[Amount] = None """ - Specifies the maximum effective-price that LPTokens can be traded out. + Specifies the maximum effective-price that LPToken can be traded out. """ transaction_type: TransactionType = field( @@ -65,6 +65,6 @@ def _get_errors(self: AMMDeposit) -> Dict[str, str]: errors["AMMDeposit"] = "Must set `asset1_in` with `asset2_in`" elif self.e_price is not None and self.asset1_in is None: errors["AMMDeposit"] = "Must set `asset1_in` with `e_price`" - elif self.lp_tokens is None and self.asset1_in is None: - errors["AMMDeposit"] = "Must set either or both `lp_tokens` and `asset1_in`" + elif self.lp_token is None and self.asset1_in is None: + errors["AMMDeposit"] = "Must set either or both `lp_token` and `asset1_in`" return errors diff --git a/xrpl/models/transactions/amm_vote.py b/xrpl/models/transactions/amm_vote.py index 909f80958..8d1c44667 100644 --- a/xrpl/models/transactions/amm_vote.py +++ b/xrpl/models/transactions/amm_vote.py @@ -20,7 +20,7 @@ class AMMVote(Transaction): """ AMMVote is used for submitting a vote for the trading fee of an AMM Instance. - Any XRPL account that holds LPTokens for an AMM instance may submit this + Any XRPL account that holds LPToken for an AMM instance may submit this transaction to vote for the trading fee for that instance. """ diff --git a/xrpl/models/transactions/amm_withdraw.py b/xrpl/models/transactions/amm_withdraw.py index 852c1cc91..6763f9594 100644 --- a/xrpl/models/transactions/amm_withdraw.py +++ b/xrpl/models/transactions/amm_withdraw.py @@ -17,13 +17,13 @@ class AMMWithdraw(Transaction): """ AMMWithdraw is the withdraw transaction used to remove liquidity from the AMM instance pool, thus redeeming some share of the pools that one owns in the form - of LPTokens. + of LPToken. The following are the recommended valid combinations: - - LPTokens + - LPToken - Asset1Out - Asset1Out and Asset2Out - - Asset1Out and LPTokens + - Asset1Out and LPToken - Asset1Out and EPrice """ @@ -32,7 +32,7 @@ class AMMWithdraw(Transaction): A hash that uniquely identifies the AMM instance. This field is required. """ - lp_tokens: Optional[IssuedCurrencyAmount] = None + lp_token: Optional[IssuedCurrencyAmount] = None """ Specifies the amount of shares of the AMM instance pools that the trader wants to redeem or trade in. @@ -67,8 +67,8 @@ def _get_errors(self: AMMWithdraw) -> Dict[str, str]: errors["AMMWithdraw"] = "Must set `asset1_out` with `asset2_out`" elif self.e_price is not None and self.asset1_out is None: errors["AMMWithdraw"] = "Must set `asset1_out` with `e_price`" - elif self.lp_tokens is None and self.asset1_out is None: + elif self.lp_token is None and self.asset1_out is None: errors[ "AMMWithdraw" - ] = "Must set either or both `lp_tokens` and `asset1_out`" + ] = "Must set either or both `lp_token` and `asset1_out`" return errors From 9114274a268ce83bb3eed4c104dc71b9adac2a2a Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 18 Aug 2022 14:17:01 -0400 Subject: [PATCH 33/88] update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cba259dc0..30ee7cd7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Function to parse the final account balances from a transaction's metadata - Function to parse order book changes from a transaction's metadata - Support for Ed25519 seeds that don't use the `sEd` prefix +- Support for Automated Market Maker (AMM) ### Fixed: - Typing for factory classmethods on models From df5cc0f132a678b60000260cc55f38839f8171e2 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 18 Aug 2022 20:26:11 -0400 Subject: [PATCH 34/88] fix typo --- xrpl/models/transactions/amm_deposit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xrpl/models/transactions/amm_deposit.py b/xrpl/models/transactions/amm_deposit.py index 1d7186841..a16750401 100644 --- a/xrpl/models/transactions/amm_deposit.py +++ b/xrpl/models/transactions/amm_deposit.py @@ -15,7 +15,7 @@ @dataclass(frozen=True) class AMMDeposit(Transaction): """ - AMDeposit is the deposit transaction used to add liquidity to the AMM instance pool, + AMMDeposit is the deposit transaction used to add liquidity to the AMM instance pool, thus obtaining some share of the instance's pools in the form of LPToken. The following are the recommended valid combinations: From 9d8e7255045ce1e9cf29aecc9ddd89c4ce068f2c Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 18 Aug 2022 20:28:57 -0400 Subject: [PATCH 35/88] fix lint error --- xrpl/models/transactions/amm_deposit.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xrpl/models/transactions/amm_deposit.py b/xrpl/models/transactions/amm_deposit.py index a16750401..306c84656 100644 --- a/xrpl/models/transactions/amm_deposit.py +++ b/xrpl/models/transactions/amm_deposit.py @@ -15,8 +15,8 @@ @dataclass(frozen=True) class AMMDeposit(Transaction): """ - AMMDeposit is the deposit transaction used to add liquidity to the AMM instance pool, - thus obtaining some share of the instance's pools in the form of LPToken. + AMMDeposit is the deposit transaction used to add liquidity to the AMM instance + pool, thus obtaining some share of the instance's pools in the form of LPToken. The following are the recommended valid combinations: - LPToken From d53ab25edcb27cd48599bb140b1948024c5a50f8 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Fri, 19 Aug 2022 22:01:49 -0400 Subject: [PATCH 36/88] refactor max trading fee to be in one place --- xrpl/models/transactions/amm_instance_create.py | 6 +++--- xrpl/models/transactions/amm_vote.py | 9 +++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/xrpl/models/transactions/amm_instance_create.py b/xrpl/models/transactions/amm_instance_create.py index 6ebfb31c9..6241633b2 100644 --- a/xrpl/models/transactions/amm_instance_create.py +++ b/xrpl/models/transactions/amm_instance_create.py @@ -12,7 +12,7 @@ from xrpl.models.transactions.types import TransactionType from xrpl.models.utils import require_kwargs_on_init -_MAX_TRADING_FEE: Final[int] = 65000 +AMM_MAX_TRADING_FEE: Final[int] = 65000 @require_kwargs_on_init @@ -61,6 +61,6 @@ def _get_errors(self: AMMInstanceCreate) -> Dict[str, str]: } def _get_trading_fee_error(self: AMMInstanceCreate) -> Optional[str]: - if self.trading_fee > _MAX_TRADING_FEE: - return f"Must not be greater than {_MAX_TRADING_FEE}" + if self.trading_fee > AMM_MAX_TRADING_FEE: + return f"Must not be greater than {AMM_MAX_TRADING_FEE}" return None diff --git a/xrpl/models/transactions/amm_vote.py b/xrpl/models/transactions/amm_vote.py index 8d1c44667..fec8063fb 100644 --- a/xrpl/models/transactions/amm_vote.py +++ b/xrpl/models/transactions/amm_vote.py @@ -4,15 +4,12 @@ from dataclasses import dataclass, field from typing import Dict, Optional -from typing_extensions import Final - from xrpl.models.required import REQUIRED +from xrpl.models.transactions.amm_instance_create import AMM_MAX_TRADING_FEE from xrpl.models.transactions.transaction import Transaction from xrpl.models.transactions.types import TransactionType from xrpl.models.utils import require_kwargs_on_init -_MAX_TRADING_FEE: Final[int] = 65000 - @require_kwargs_on_init @dataclass(frozen=True) @@ -53,6 +50,6 @@ def _get_errors(self: AMMVote) -> Dict[str, str]: } def _get_fee_val_error(self: AMMVote) -> Optional[str]: - if self.fee_val > _MAX_TRADING_FEE: - return f"Must not be greater than {_MAX_TRADING_FEE}" + if self.fee_val > AMM_MAX_TRADING_FEE: + return f"Must not be greater than {AMM_MAX_TRADING_FEE}" return None From d2b98b001ee7fa81059231ee61a035fa41f3d16d Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Fri, 19 Aug 2022 22:19:29 -0400 Subject: [PATCH 37/88] update amm_bid error message --- tests/unit/models/transactions/test_amm_bid.py | 2 +- xrpl/models/transactions/amm_bid.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/models/transactions/test_amm_bid.py b/tests/unit/models/transactions/test_amm_bid.py index a93b7c0d5..4efcfefa1 100644 --- a/tests/unit/models/transactions/test_amm_bid.py +++ b/tests/unit/models/transactions/test_amm_bid.py @@ -46,5 +46,5 @@ def test_auth_accounts_length_error(self): ) self.assertEqual( error.exception.args[0], - "{'auth_accounts': 'Must not be greater than 4'}", + "{'auth_accounts': 'Length must not be greater than 4'}", ) diff --git a/xrpl/models/transactions/amm_bid.py b/xrpl/models/transactions/amm_bid.py index 246731c77..38b6d95ee 100644 --- a/xrpl/models/transactions/amm_bid.py +++ b/xrpl/models/transactions/amm_bid.py @@ -72,5 +72,5 @@ def _get_auth_accounts_error(self: AMMBid) -> Optional[str]: self.auth_accounts is not None and len(self.auth_accounts) > _MAX_AUTH_ACCOUNTS ): - return f"Must not be greater than {_MAX_AUTH_ACCOUNTS}" + return f"Length must not be greater than {_MAX_AUTH_ACCOUNTS}" return None From 09b2839510f8e90070e5b44dcc8aabe0fdf543f0 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Sat, 20 Aug 2022 10:16:09 -0400 Subject: [PATCH 38/88] add AuthAccount base model for AMMBid --- tests/unit/models/test_base_model.py | 33 +++++++--- .../unit/models/transactions/test_amm_bid.py | 23 +++++-- xrpl/models/transactions/amm_bid.py | 66 ++++++++++++++++++- 3 files changed, 107 insertions(+), 15 deletions(-) diff --git a/tests/unit/models/test_base_model.py b/tests/unit/models/test_base_model.py index 532917889..4218efa85 100644 --- a/tests/unit/models/test_base_model.py +++ b/tests/unit/models/test_base_model.py @@ -30,6 +30,7 @@ TrustSet, TrustSetFlag, ) +from xrpl.models.transactions.amm_bid import AuthAccount from xrpl.models.transactions.transaction import Transaction currency = "BTC" @@ -884,10 +885,10 @@ def test_to_xrpl_amm_bid(self): value="35", ), auth_accounts=[ - "rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh", - "rfpFv97Dwu89FTyUwPjtpZBbuZxTqqgTmH", - "rzzYHPGb8Pa64oqxCzmuffm122bitq3Vb", - "rhwxHxaHok86fe4LykBom1jSJ3RYQJs1h4", + AuthAccount(Account="rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh"), + AuthAccount(Account="rfpFv97Dwu89FTyUwPjtpZBbuZxTqqgTmH"), + AuthAccount(Account="rzzYHPGb8Pa64oqxCzmuffm122bitq3Vb"), + AuthAccount(Account="rhwxHxaHok86fe4LykBom1jSJ3RYQJs1h4"), ], ) expected = { @@ -904,10 +905,26 @@ def test_to_xrpl_amm_bid(self): "value": "35", }, "AuthAccounts": [ - "rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh", - "rfpFv97Dwu89FTyUwPjtpZBbuZxTqqgTmH", - "rzzYHPGb8Pa64oqxCzmuffm122bitq3Vb", - "rhwxHxaHok86fe4LykBom1jSJ3RYQJs1h4", + { + "AuthAccount": { + "Account": "rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh", + } + }, + { + "AuthAccount": { + "Account": "rfpFv97Dwu89FTyUwPjtpZBbuZxTqqgTmH", + } + }, + { + "AuthAccount": { + "Account": "rzzYHPGb8Pa64oqxCzmuffm122bitq3Vb", + } + }, + { + "AuthAccount": { + "Account": "rhwxHxaHok86fe4LykBom1jSJ3RYQJs1h4", + } + }, ], "TransactionType": "AMMBid", "SigningPubKey": "", diff --git a/tests/unit/models/transactions/test_amm_bid.py b/tests/unit/models/transactions/test_amm_bid.py index 4efcfefa1..c5e881947 100644 --- a/tests/unit/models/transactions/test_amm_bid.py +++ b/tests/unit/models/transactions/test_amm_bid.py @@ -3,14 +3,23 @@ from xrpl.models.amounts import IssuedCurrencyAmount from xrpl.models.exceptions import XRPLModelException from xrpl.models.transactions import AMMBid +from xrpl.models.transactions.amm_bid import AuthAccount _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" _AMM_ID = "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883" _AUTH_ACCOUNTS = [ - "rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh", - "rfpFv97Dwu89FTyUwPjtpZBbuZxTqqgTmH", - "rzzYHPGb8Pa64oqxCzmuffm122bitq3Vb", - "rhwxHxaHok86fe4LykBom1jSJ3RYQJs1h4", + AuthAccount( + Account="rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh", + ), + AuthAccount( + Account="rfpFv97Dwu89FTyUwPjtpZBbuZxTqqgTmH", + ), + AuthAccount( + Account="rzzYHPGb8Pa64oqxCzmuffm122bitq3Vb", + ), + AuthAccount( + Account="rhwxHxaHok86fe4LykBom1jSJ3RYQJs1h4", + ), ] _LPTOKEN_CURRENCY = "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A" _LPTOKEN_ISSUER = "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw" @@ -37,7 +46,11 @@ def test_tx_valid(self): def test_auth_accounts_length_error(self): auth_accounts = _AUTH_ACCOUNTS.copy() - auth_accounts.append("r3X6noRsvaLapAKCG78zAtWcbhB3sggS1s") + auth_accounts.append( + AuthAccount( + Account="r3X6noRsvaLapAKCG78zAtWcbhB3sggS1s", + ), + ) with self.assertRaises(XRPLModelException) as error: AMMBid( account=_ACCOUNT, diff --git a/xrpl/models/transactions/amm_bid.py b/xrpl/models/transactions/amm_bid.py index 38b6d95ee..ae9f82758 100644 --- a/xrpl/models/transactions/amm_bid.py +++ b/xrpl/models/transactions/amm_bid.py @@ -2,11 +2,12 @@ from __future__ import annotations from dataclasses import dataclass, field -from typing import Dict, List, Optional +from typing import Any, Dict, List, Optional, Type from typing_extensions import Final from xrpl.models.amounts import Amount +from xrpl.models.base_model import BaseModel from xrpl.models.required import REQUIRED from xrpl.models.transactions.transaction import Transaction from xrpl.models.transactions.types import TransactionType @@ -15,6 +16,67 @@ _MAX_AUTH_ACCOUNTS: Final[int] = 4 +@require_kwargs_on_init +@dataclass(frozen=True) +class AuthAccount(BaseModel): + """Represents one entry in a list of AuthAccounts used in AMMBid transaction.""" + + Account: str = REQUIRED # type: ignore + """ + This field is required. + + :meta hide-value: + """ + + @classmethod + def is_dict_of_model(cls: Type[AuthAccount], dictionary: Dict[str, Any]) -> bool: + """ + Returns True if the input dictionary was derived by the `to_dict` + method of an instance of this class. In other words, True if this is + a dictionary representation of an instance of this class. + + NOTE: does not account for model inheritance, IE will only return True + if dictionary represents an instance of this class, but not if + dictionary represents an instance of a subclass of this class. + + Args: + dictionary: The dictionary to check. + + Returns: + True if dictionary is a dict representation of an instance of this + class. + """ + return ( + isinstance(dictionary, dict) + and "auth_account" in dictionary + and super().is_dict_of_model(dictionary["auth_account"]) + ) + + @classmethod + def from_dict(cls: Type[AuthAccount], value: Dict[str, Any]) -> AuthAccount: + """ + Construct a new AuthAccount from a dictionary of parameters. + + Args: + value: The value to construct the AuthAccount from. + + Returns: + A new AuthAccount object, constructed using the given parameters. + """ + if len(value) == 1 and "auth_account" in value: + return super(AuthAccount, cls).from_dict(value["auth_account"]) + return super(AuthAccount, cls).from_dict(value) + + def to_dict(self: AuthAccount) -> Dict[str, Any]: + """ + Returns the dictionary representation of a AuthAccount. + + Returns: + The dictionary representation of a AuthAccount. + """ + return {"auth_account": super().to_dict()} + + @require_kwargs_on_init @dataclass(frozen=True) class AMMBid(Transaction): @@ -45,7 +107,7 @@ class AMMBid(Transaction): It is specified in units of LPToken. """ - auth_accounts: Optional[List[str]] = None + auth_accounts: Optional[List[AuthAccount]] = None """ This field represents an array of XRPL account IDs that are authorized to trade at the discounted fee against the AMM instance. From 5031bf596b5356a01c2d3117113b8459cda419e5 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 30 Aug 2022 17:52:28 -0400 Subject: [PATCH 39/88] update definitions to fix AMM in LEDGER_ENTRY_TYPES --- xrpl/core/binarycodec/definitions/definitions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xrpl/core/binarycodec/definitions/definitions.json b/xrpl/core/binarycodec/definitions/definitions.json index ce449a517..cc0fc1d04 100644 --- a/xrpl/core/binarycodec/definitions/definitions.json +++ b/xrpl/core/binarycodec/definitions/definitions.json @@ -44,7 +44,7 @@ "NegativeUNL": 78, "NFTokenPage": 80, "NFTokenOffer": 55, - "Amm": 121, + "AMM": 121, "Any": -3, "Child": -2, "Nickname": 110, From 04284526f4794199ce74b482b7d36efa7d075475 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 30 Aug 2022 18:57:36 -0400 Subject: [PATCH 40/88] update CHANGELOG.md to specify XLS-30 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30ee7cd7f..79bdbf926 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Function to parse the final account balances from a transaction's metadata - Function to parse order book changes from a transaction's metadata - Support for Ed25519 seeds that don't use the `sEd` prefix -- Support for Automated Market Maker (AMM) +- Support for Automated Market Maker (AMM) transactions and requests as defined in XLS-30. ### Fixed: - Typing for factory classmethods on models From 3c0e55b3c10140dcb2f09ac38fe53b95039ac6b3 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 30 Aug 2022 19:01:18 -0400 Subject: [PATCH 41/88] update wording on AMMDeposit & AMMWithdraw validation errors --- tests/unit/models/transactions/test_amm_deposit.py | 2 +- tests/unit/models/transactions/test_amm_withdraw.py | 2 +- xrpl/models/transactions/amm_deposit.py | 2 +- xrpl/models/transactions/amm_withdraw.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/models/transactions/test_amm_deposit.py b/tests/unit/models/transactions/test_amm_deposit.py index d49ba7fd5..ec487b693 100644 --- a/tests/unit/models/transactions/test_amm_deposit.py +++ b/tests/unit/models/transactions/test_amm_deposit.py @@ -77,7 +77,7 @@ def test_undefined_asset1in_undefined_lptoken_invalid_combo(self): ) self.assertEqual( error.exception.args[0], - "{'AMMDeposit': 'Must set either or both `lp_token` and `asset1_in`'}", + "{'AMMDeposit': 'Must set at least `lp_token` or `asset1_in`'}", ) def test_undefined_asset1in_defined_asset2in_invalid_combo(self): diff --git a/tests/unit/models/transactions/test_amm_withdraw.py b/tests/unit/models/transactions/test_amm_withdraw.py index 712252eed..ce6947764 100644 --- a/tests/unit/models/transactions/test_amm_withdraw.py +++ b/tests/unit/models/transactions/test_amm_withdraw.py @@ -77,7 +77,7 @@ def test_undefined_asset1out_undefined_lptoken_invalid_combo(self): ) self.assertEqual( error.exception.args[0], - "{'AMMWithdraw': 'Must set either or both `lp_token` and `asset1_out`'}", + "{'AMMWithdraw': 'Must set at least `lp_token` or `asset1_out`'}", ) def test_undefined_asset1out_defined_asset2out_invalid_combo(self): diff --git a/xrpl/models/transactions/amm_deposit.py b/xrpl/models/transactions/amm_deposit.py index 306c84656..faaecd494 100644 --- a/xrpl/models/transactions/amm_deposit.py +++ b/xrpl/models/transactions/amm_deposit.py @@ -66,5 +66,5 @@ def _get_errors(self: AMMDeposit) -> Dict[str, str]: elif self.e_price is not None and self.asset1_in is None: errors["AMMDeposit"] = "Must set `asset1_in` with `e_price`" elif self.lp_token is None and self.asset1_in is None: - errors["AMMDeposit"] = "Must set either or both `lp_token` and `asset1_in`" + errors["AMMDeposit"] = "Must set at least `lp_token` or `asset1_in`" return errors diff --git a/xrpl/models/transactions/amm_withdraw.py b/xrpl/models/transactions/amm_withdraw.py index 6763f9594..8804c8082 100644 --- a/xrpl/models/transactions/amm_withdraw.py +++ b/xrpl/models/transactions/amm_withdraw.py @@ -70,5 +70,5 @@ def _get_errors(self: AMMWithdraw) -> Dict[str, str]: elif self.lp_token is None and self.asset1_out is None: errors[ "AMMWithdraw" - ] = "Must set either or both `lp_token` and `asset1_out`" + ] = "Must set at least `lp_token` or `asset1_out`" return errors From 1ecea66a9df0191f85f44fd9fc7bf5412a82d4a8 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 30 Aug 2022 19:05:11 -0400 Subject: [PATCH 42/88] add negative FeeVal check --- tests/unit/models/transactions/test_amm_vote.py | 14 +++++++++++++- xrpl/models/transactions/amm_vote.py | 4 ++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/tests/unit/models/transactions/test_amm_vote.py b/tests/unit/models/transactions/test_amm_vote.py index 1f45e35a3..ba06cef18 100644 --- a/tests/unit/models/transactions/test_amm_vote.py +++ b/tests/unit/models/transactions/test_amm_vote.py @@ -27,5 +27,17 @@ def test_trading_fee_too_high(self): ) self.assertEqual( error.exception.args[0], - "{'fee_val': 'Must not be greater than 65000'}", + "{'fee_val': 'Must be between 0 and 65000'}", + ) + + def test_trading_fee_negative_number(self): + with self.assertRaises(XRPLModelException) as error: + AMMVote( + account=_ACCOUNT, + amm_id=_AMM_ID, + fee_val=-1, + ) + self.assertEqual( + error.exception.args[0], + "{'fee_val': 'Must be between 0 and 65000'}", ) diff --git a/xrpl/models/transactions/amm_vote.py b/xrpl/models/transactions/amm_vote.py index fec8063fb..4262f4fce 100644 --- a/xrpl/models/transactions/amm_vote.py +++ b/xrpl/models/transactions/amm_vote.py @@ -50,6 +50,6 @@ def _get_errors(self: AMMVote) -> Dict[str, str]: } def _get_fee_val_error(self: AMMVote) -> Optional[str]: - if self.fee_val > AMM_MAX_TRADING_FEE: - return f"Must not be greater than {AMM_MAX_TRADING_FEE}" + if self.fee_val < 0 or self.fee_val > AMM_MAX_TRADING_FEE: + return f"Must be between 0 and {AMM_MAX_TRADING_FEE}" return None From 6730f67cdfdc8ccac7e84effbb4692e1c962260e Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 30 Aug 2022 19:07:32 -0400 Subject: [PATCH 43/88] add negative TradingFee check --- .../transactions/test_amm_instance_create.py | 17 ++++++++++++++++- xrpl/models/transactions/amm_instance_create.py | 4 ++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/tests/unit/models/transactions/test_amm_instance_create.py b/tests/unit/models/transactions/test_amm_instance_create.py index ac8a6a3ef..197127c27 100644 --- a/tests/unit/models/transactions/test_amm_instance_create.py +++ b/tests/unit/models/transactions/test_amm_instance_create.py @@ -33,5 +33,20 @@ def test_trading_fee_too_high(self): ) self.assertEqual( error.exception.args[0], - "{'trading_fee': 'Must not be greater than 65000'}", + "{'trading_fee': 'Must be between 0 and 65000'}", + ) + + def test_trading_fee_negative_number(self): + with self.assertRaises(XRPLModelException) as error: + AMMInstanceCreate( + account=_ACCOUNT, + asset1="1000", + asset2=IssuedCurrencyAmount( + currency="USD", issuer=_IOU_ISSUER, value="1000" + ), + trading_fee=-1, + ) + self.assertEqual( + error.exception.args[0], + "{'trading_fee': 'Must be between 0 and 65000'}", ) diff --git a/xrpl/models/transactions/amm_instance_create.py b/xrpl/models/transactions/amm_instance_create.py index 6241633b2..653de8026 100644 --- a/xrpl/models/transactions/amm_instance_create.py +++ b/xrpl/models/transactions/amm_instance_create.py @@ -61,6 +61,6 @@ def _get_errors(self: AMMInstanceCreate) -> Dict[str, str]: } def _get_trading_fee_error(self: AMMInstanceCreate) -> Optional[str]: - if self.trading_fee > AMM_MAX_TRADING_FEE: - return f"Must not be greater than {AMM_MAX_TRADING_FEE}" + if self.trading_fee < 0 or self.trading_fee > AMM_MAX_TRADING_FEE: + return f"Must be between 0 and {AMM_MAX_TRADING_FEE}" return None From e66a41088875258143a7db08e5451050208079a0 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 30 Aug 2022 19:14:16 -0400 Subject: [PATCH 44/88] fix lint error --- xrpl/models/transactions/amm_withdraw.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/xrpl/models/transactions/amm_withdraw.py b/xrpl/models/transactions/amm_withdraw.py index 8804c8082..1a6da74cd 100644 --- a/xrpl/models/transactions/amm_withdraw.py +++ b/xrpl/models/transactions/amm_withdraw.py @@ -68,7 +68,5 @@ def _get_errors(self: AMMWithdraw) -> Dict[str, str]: elif self.e_price is not None and self.asset1_out is None: errors["AMMWithdraw"] = "Must set `asset1_out` with `e_price`" elif self.lp_token is None and self.asset1_out is None: - errors[ - "AMMWithdraw" - ] = "Must set at least `lp_token` or `asset1_out`" + errors["AMMWithdraw"] = "Must set at least `lp_token` or `asset1_out`" return errors From 368d557dc67298a5d214edd30103b42c441fe104 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 1 Sep 2022 13:37:30 -0400 Subject: [PATCH 45/88] export AuthAccount model --- tests/unit/models/test_base_model.py | 2 +- tests/unit/models/transactions/test_amm_bid.py | 3 +-- xrpl/models/transactions/__init__.py | 3 ++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/models/test_base_model.py b/tests/unit/models/test_base_model.py index 4218efa85..d60ba71ef 100644 --- a/tests/unit/models/test_base_model.py +++ b/tests/unit/models/test_base_model.py @@ -21,6 +21,7 @@ AMMInstanceCreate, AMMVote, AMMWithdraw, + AuthAccount, CheckCreate, Memo, Payment, @@ -30,7 +31,6 @@ TrustSet, TrustSetFlag, ) -from xrpl.models.transactions.amm_bid import AuthAccount from xrpl.models.transactions.transaction import Transaction currency = "BTC" diff --git a/tests/unit/models/transactions/test_amm_bid.py b/tests/unit/models/transactions/test_amm_bid.py index c5e881947..ee065c7a5 100644 --- a/tests/unit/models/transactions/test_amm_bid.py +++ b/tests/unit/models/transactions/test_amm_bid.py @@ -2,8 +2,7 @@ from xrpl.models.amounts import IssuedCurrencyAmount from xrpl.models.exceptions import XRPLModelException -from xrpl.models.transactions import AMMBid -from xrpl.models.transactions.amm_bid import AuthAccount +from xrpl.models.transactions import AMMBid, AuthAccount _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" _AMM_ID = "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883" diff --git a/xrpl/models/transactions/__init__.py b/xrpl/models/transactions/__init__.py index f0b8a8ab0..6ed90a18e 100644 --- a/xrpl/models/transactions/__init__.py +++ b/xrpl/models/transactions/__init__.py @@ -9,7 +9,7 @@ AccountSetFlag, AccountSetFlagInterface, ) -from xrpl.models.transactions.amm_bid import AMMBid +from xrpl.models.transactions.amm_bid import AMMBid, AuthAccount from xrpl.models.transactions.amm_deposit import AMMDeposit from xrpl.models.transactions.amm_instance_create import AMMInstanceCreate from xrpl.models.transactions.amm_vote import AMMVote @@ -69,6 +69,7 @@ "AMMInstanceCreate", "AMMVote", "AMMWithdraw", + "AuthAccount", "CheckCancel", "CheckCash", "CheckCreate", From a34fdccde8c36df6ce6b345fe22102d94ba9b15c Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 14 Sep 2022 18:27:00 -0400 Subject: [PATCH 46/88] add AuthAccount and refactor special case models check --- tests/unit/models/test_base_model.py | 28 ++++---- .../unit/models/transactions/test_amm_bid.py | 10 +-- xrpl/models/__init__.py | 2 + xrpl/models/auth_account.py | 70 +++++++++++++++++++ xrpl/models/path.py | 56 +-------------- xrpl/models/path_step.py | 63 +++++++++++++++++ xrpl/models/requests/__init__.py | 4 +- xrpl/models/transactions/amm_bid.py | 65 +---------------- xrpl/models/transactions/transaction.py | 9 ++- 9 files changed, 169 insertions(+), 138 deletions(-) create mode 100644 xrpl/models/auth_account.py create mode 100644 xrpl/models/path_step.py diff --git a/tests/unit/models/test_base_model.py b/tests/unit/models/test_base_model.py index d60ba71ef..e48bdd256 100644 --- a/tests/unit/models/test_base_model.py +++ b/tests/unit/models/test_base_model.py @@ -511,16 +511,16 @@ def test_from_xrpl_memos(self): self.assertEqual(Transaction.from_xrpl(tx), expected) def test_to_xrpl_paths(self): - paths_json = [ + path_steps = [ [ - {"account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", "type": 1}, - { - "currency": "USD", - "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "type": 48, - }, - {"account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", "type": 1}, - {"account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", "type": 1}, + PathStep(account="rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", type=1), + PathStep( + currency="USD", + issuer="rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + type=48, + ), + PathStep(account="rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", type=1), + PathStep(account="rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", type=1), ], ] @@ -537,7 +537,7 @@ def test_to_xrpl_paths(self): issuer="rweYz56rfmQ98cAdRaeTxQS9wVMGnrdsFp", value="0.0000002831214446", ), - paths=paths_json, + paths=path_steps, sequence=290, ) tx_json = p.to_xrpl() @@ -885,10 +885,10 @@ def test_to_xrpl_amm_bid(self): value="35", ), auth_accounts=[ - AuthAccount(Account="rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh"), - AuthAccount(Account="rfpFv97Dwu89FTyUwPjtpZBbuZxTqqgTmH"), - AuthAccount(Account="rzzYHPGb8Pa64oqxCzmuffm122bitq3Vb"), - AuthAccount(Account="rhwxHxaHok86fe4LykBom1jSJ3RYQJs1h4"), + AuthAccount(account="rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh"), + AuthAccount(account="rfpFv97Dwu89FTyUwPjtpZBbuZxTqqgTmH"), + AuthAccount(account="rzzYHPGb8Pa64oqxCzmuffm122bitq3Vb"), + AuthAccount(account="rhwxHxaHok86fe4LykBom1jSJ3RYQJs1h4"), ], ) expected = { diff --git a/tests/unit/models/transactions/test_amm_bid.py b/tests/unit/models/transactions/test_amm_bid.py index ee065c7a5..ed847103e 100644 --- a/tests/unit/models/transactions/test_amm_bid.py +++ b/tests/unit/models/transactions/test_amm_bid.py @@ -8,16 +8,16 @@ _AMM_ID = "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883" _AUTH_ACCOUNTS = [ AuthAccount( - Account="rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh", + account="rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh", ), AuthAccount( - Account="rfpFv97Dwu89FTyUwPjtpZBbuZxTqqgTmH", + account="rfpFv97Dwu89FTyUwPjtpZBbuZxTqqgTmH", ), AuthAccount( - Account="rzzYHPGb8Pa64oqxCzmuffm122bitq3Vb", + account="rzzYHPGb8Pa64oqxCzmuffm122bitq3Vb", ), AuthAccount( - Account="rhwxHxaHok86fe4LykBom1jSJ3RYQJs1h4", + account="rhwxHxaHok86fe4LykBom1jSJ3RYQJs1h4", ), ] _LPTOKEN_CURRENCY = "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A" @@ -47,7 +47,7 @@ def test_auth_accounts_length_error(self): auth_accounts = _AUTH_ACCOUNTS.copy() auth_accounts.append( AuthAccount( - Account="r3X6noRsvaLapAKCG78zAtWcbhB3sggS1s", + account="r3X6noRsvaLapAKCG78zAtWcbhB3sggS1s", ), ) with self.assertRaises(XRPLModelException) as error: diff --git a/xrpl/models/__init__.py b/xrpl/models/__init__.py index 059e5f355..bed239c57 100644 --- a/xrpl/models/__init__.py +++ b/xrpl/models/__init__.py @@ -1,6 +1,7 @@ """Top-level exports for the models package.""" from xrpl.models import amounts, currencies, requests, transactions from xrpl.models.amounts import * # noqa: F401, F403 +from xrpl.models.auth_account import AuthAccount from xrpl.models.currencies import * # noqa: F401, F403 from xrpl.models.exceptions import XRPLModelException from xrpl.models.path import Path, PathStep @@ -13,6 +14,7 @@ "XRPLModelException", "amounts", *amounts.__all__, + "AuthAccount", "currencies", *currencies.__all__, "requests", diff --git a/xrpl/models/auth_account.py b/xrpl/models/auth_account.py new file mode 100644 index 000000000..b9182cbed --- /dev/null +++ b/xrpl/models/auth_account.py @@ -0,0 +1,70 @@ +"""Model used in AMMBid transaction.""" +from __future__ import annotations + +from dataclasses import dataclass +from typing import Any, Dict, Type + +from xrpl.models.base_model import BaseModel +from xrpl.models.required import REQUIRED +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AuthAccount(BaseModel): + """Represents one entry in a list of AuthAccounts used in AMMBid transaction.""" + + account: str = REQUIRED # type: ignore + """ + This field is required. + + :meta hide-value: + """ + + @classmethod + def is_dict_of_model(cls: Type[AuthAccount], dictionary: Dict[str, Any]) -> bool: + """ + Returns True if the input dictionary was derived by the `to_dict` + method of an instance of this class. In other words, True if this is + a dictionary representation of an instance of this class. + + NOTE: does not account for model inheritance, IE will only return True + if dictionary represents an instance of this class, but not if + dictionary represents an instance of a subclass of this class. + + Args: + dictionary: The dictionary to check. + + Returns: + True if dictionary is a dict representation of an instance of this + class. + """ + return ( + isinstance(dictionary, dict) + and "auth_account" in dictionary + and super().is_dict_of_model(dictionary["auth_account"]) + ) + + @classmethod + def from_dict(cls: Type[AuthAccount], value: Dict[str, Any]) -> AuthAccount: + """ + Construct a new AuthAccount from a dictionary of parameters. + + Args: + value: The value to construct the AuthAccount from. + + Returns: + A new AuthAccount object, constructed using the given parameters. + """ + if len(value) == 1 and "auth_account" in value: + return super(AuthAccount, cls).from_dict(value["auth_account"]) + return super(AuthAccount, cls).from_dict(value) + + def to_dict(self: AuthAccount) -> Dict[str, Any]: + """ + Returns the dictionary representation of a AuthAccount. + + Returns: + The dictionary representation of a AuthAccount. + """ + return {"auth_account": super().to_dict()} diff --git a/xrpl/models/path.py b/xrpl/models/path.py index b43eef1ac..b3f411d9c 100644 --- a/xrpl/models/path.py +++ b/xrpl/models/path.py @@ -5,61 +5,9 @@ from __future__ import annotations -from dataclasses import dataclass -from typing import Dict, List, Optional - -from xrpl.models.base_model import BaseModel -from xrpl.models.utils import require_kwargs_on_init - - -@require_kwargs_on_init -@dataclass(frozen=True) -class PathStep(BaseModel): - """A PathStep represents an individual step along a Path.""" - - account: Optional[str] = None - currency: Optional[str] = None - issuer: Optional[str] = None - type: Optional[int] = None - type_hex: Optional[str] = None - - def _get_errors(self: PathStep) -> Dict[str, str]: - return { - key: value - for key, value in { - **super()._get_errors(), - "account": self._get_account_error(), - "currency": self._get_currency_error(), - "issuer": self._get_issuer_error(), - }.items() - if value is not None - } - - def _get_account_error(self: PathStep) -> Optional[str]: - if self.account is None: - return None - if self.currency is not None or self.issuer is not None: - return "Cannot set account if currency or issuer are set" - return None - - def _get_currency_error(self: PathStep) -> Optional[str]: - if self.currency is None: - return None - if self.account is not None: - return "Cannot set currency if account is set" - if self.issuer is not None and self.currency.upper() == "XRP": - return "Cannot set issuer if currency is XRP" - return None - - def _get_issuer_error(self: PathStep) -> Optional[str]: - if self.issuer is None: - return None - if self.account is not None: - return "Cannot set issuer if account is set" - if self.currency is not None and self.currency.upper() == "XRP": - return "Cannot set issuer if currency is XRP" - return None +from typing import List +from xrpl.models.path_step import PathStep Path = List[PathStep] """ diff --git a/xrpl/models/path_step.py b/xrpl/models/path_step.py new file mode 100644 index 000000000..ff4d4e8e0 --- /dev/null +++ b/xrpl/models/path_step.py @@ -0,0 +1,63 @@ +""" +A path is an ordered array. Each member of a path is an +object that specifies the step. +""" + +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import Dict, Optional + +from xrpl.models.base_model import BaseModel +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class PathStep(BaseModel): + """A PathStep represents an individual step along a Path.""" + + account: Optional[str] = None + currency: Optional[str] = None + issuer: Optional[str] = None + type: Optional[int] = None + type_hex: Optional[str] = None + + _special_model: str = field(default="PathStep", init=False) + + def _get_errors(self: PathStep) -> Dict[str, str]: + return { + key: value + for key, value in { + **super()._get_errors(), + "account": self._get_account_error(), + "currency": self._get_currency_error(), + "issuer": self._get_issuer_error(), + }.items() + if value is not None + } + + def _get_account_error(self: PathStep) -> Optional[str]: + if self.account is None: + return None + if self.currency is not None or self.issuer is not None: + return "Cannot set account if currency or issuer are set" + return None + + def _get_currency_error(self: PathStep) -> Optional[str]: + if self.currency is None: + return None + if self.account is not None: + return "Cannot set currency if account is set" + if self.issuer is not None and self.currency.upper() == "XRP": + return "Cannot set issuer if currency is XRP" + return None + + def _get_issuer_error(self: PathStep) -> Optional[str]: + if self.issuer is None: + return None + if self.account is not None: + return "Cannot set issuer if account is set" + if self.currency is not None and self.currency.upper() == "XRP": + return "Cannot set issuer if currency is XRP" + return None diff --git a/xrpl/models/requests/__init__.py b/xrpl/models/requests/__init__.py index c61449c56..ca15f53ac 100644 --- a/xrpl/models/requests/__init__.py +++ b/xrpl/models/requests/__init__.py @@ -1,5 +1,6 @@ """Request models.""" -from xrpl.models.path import PathStep +from xrpl.models.auth_account import AuthAccount +from xrpl.models.path_step import PathStep from xrpl.models.requests.account_channels import AccountChannels from xrpl.models.requests.account_currencies import AccountCurrencies from xrpl.models.requests.account_info import AccountInfo @@ -54,6 +55,7 @@ "AccountOffers", "AccountTx", "AMMInfo", + "AuthAccount", "BookOffers", "ChannelAuthorize", "ChannelVerify", diff --git a/xrpl/models/transactions/amm_bid.py b/xrpl/models/transactions/amm_bid.py index ae9f82758..cea690ed0 100644 --- a/xrpl/models/transactions/amm_bid.py +++ b/xrpl/models/transactions/amm_bid.py @@ -2,12 +2,12 @@ from __future__ import annotations from dataclasses import dataclass, field -from typing import Any, Dict, List, Optional, Type +from typing import Dict, List, Optional from typing_extensions import Final from xrpl.models.amounts import Amount -from xrpl.models.base_model import BaseModel +from xrpl.models.auth_account import AuthAccount from xrpl.models.required import REQUIRED from xrpl.models.transactions.transaction import Transaction from xrpl.models.transactions.types import TransactionType @@ -16,67 +16,6 @@ _MAX_AUTH_ACCOUNTS: Final[int] = 4 -@require_kwargs_on_init -@dataclass(frozen=True) -class AuthAccount(BaseModel): - """Represents one entry in a list of AuthAccounts used in AMMBid transaction.""" - - Account: str = REQUIRED # type: ignore - """ - This field is required. - - :meta hide-value: - """ - - @classmethod - def is_dict_of_model(cls: Type[AuthAccount], dictionary: Dict[str, Any]) -> bool: - """ - Returns True if the input dictionary was derived by the `to_dict` - method of an instance of this class. In other words, True if this is - a dictionary representation of an instance of this class. - - NOTE: does not account for model inheritance, IE will only return True - if dictionary represents an instance of this class, but not if - dictionary represents an instance of a subclass of this class. - - Args: - dictionary: The dictionary to check. - - Returns: - True if dictionary is a dict representation of an instance of this - class. - """ - return ( - isinstance(dictionary, dict) - and "auth_account" in dictionary - and super().is_dict_of_model(dictionary["auth_account"]) - ) - - @classmethod - def from_dict(cls: Type[AuthAccount], value: Dict[str, Any]) -> AuthAccount: - """ - Construct a new AuthAccount from a dictionary of parameters. - - Args: - value: The value to construct the AuthAccount from. - - Returns: - A new AuthAccount object, constructed using the given parameters. - """ - if len(value) == 1 and "auth_account" in value: - return super(AuthAccount, cls).from_dict(value["auth_account"]) - return super(AuthAccount, cls).from_dict(value) - - def to_dict(self: AuthAccount) -> Dict[str, Any]: - """ - Returns the dictionary representation of a AuthAccount. - - Returns: - The dictionary representation of a AuthAccount. - """ - return {"auth_account": super().to_dict()} - - @require_kwargs_on_init @dataclass(frozen=True) class AMMBid(Transaction): diff --git a/xrpl/models/transactions/transaction.py b/xrpl/models/transactions/transaction.py index 86f437d99..078e2480b 100644 --- a/xrpl/models/transactions/transaction.py +++ b/xrpl/models/transactions/transaction.py @@ -60,7 +60,14 @@ def _key_to_tx_json(key: str) -> str: def _value_to_tx_json(value: XRPL_VALUE_TYPE) -> XRPL_VALUE_TYPE: # IssuedCurrencyAmount and PathStep are special cases and should not be snake cased # and only contain primitive members - if IssuedCurrencyAmount.is_dict_of_model(value) or PathStep.is_dict_of_model(value): + _special_model = None + if isinstance(value, dict) and "_special_model" in value: + _special_model = value.pop("_special_model") + + if ( + _special_model == PathStep._special_model + or IssuedCurrencyAmount.is_dict_of_model(value) + ): return value if isinstance(value, dict): return transaction_json_to_binary_codec_form(value) From 391ef269cc4139788f91628df641832464f02dce Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 14 Sep 2022 21:01:37 -0400 Subject: [PATCH 47/88] revert Path and _value_to_tx_json() changes --- tests/unit/models/test_base_model.py | 20 ++++---- xrpl/models/path.py | 56 +++++++++++++++++++++- xrpl/models/path_step.py | 63 ------------------------- xrpl/models/requests/__init__.py | 2 +- xrpl/models/transactions/transaction.py | 9 +--- 5 files changed, 66 insertions(+), 84 deletions(-) delete mode 100644 xrpl/models/path_step.py diff --git a/tests/unit/models/test_base_model.py b/tests/unit/models/test_base_model.py index e48bdd256..f06f918f0 100644 --- a/tests/unit/models/test_base_model.py +++ b/tests/unit/models/test_base_model.py @@ -511,16 +511,16 @@ def test_from_xrpl_memos(self): self.assertEqual(Transaction.from_xrpl(tx), expected) def test_to_xrpl_paths(self): - path_steps = [ + paths_json = [ [ - PathStep(account="rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", type=1), - PathStep( - currency="USD", - issuer="rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - type=48, - ), - PathStep(account="rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", type=1), - PathStep(account="rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", type=1), + {"account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", "type": 1}, + { + "currency": "USD", + "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", + "type": 48, + }, + {"account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", "type": 1}, + {"account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", "type": 1}, ], ] @@ -537,7 +537,7 @@ def test_to_xrpl_paths(self): issuer="rweYz56rfmQ98cAdRaeTxQS9wVMGnrdsFp", value="0.0000002831214446", ), - paths=path_steps, + paths=paths_json, sequence=290, ) tx_json = p.to_xrpl() diff --git a/xrpl/models/path.py b/xrpl/models/path.py index b3f411d9c..b43eef1ac 100644 --- a/xrpl/models/path.py +++ b/xrpl/models/path.py @@ -5,9 +5,61 @@ from __future__ import annotations -from typing import List +from dataclasses import dataclass +from typing import Dict, List, Optional + +from xrpl.models.base_model import BaseModel +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class PathStep(BaseModel): + """A PathStep represents an individual step along a Path.""" + + account: Optional[str] = None + currency: Optional[str] = None + issuer: Optional[str] = None + type: Optional[int] = None + type_hex: Optional[str] = None + + def _get_errors(self: PathStep) -> Dict[str, str]: + return { + key: value + for key, value in { + **super()._get_errors(), + "account": self._get_account_error(), + "currency": self._get_currency_error(), + "issuer": self._get_issuer_error(), + }.items() + if value is not None + } + + def _get_account_error(self: PathStep) -> Optional[str]: + if self.account is None: + return None + if self.currency is not None or self.issuer is not None: + return "Cannot set account if currency or issuer are set" + return None + + def _get_currency_error(self: PathStep) -> Optional[str]: + if self.currency is None: + return None + if self.account is not None: + return "Cannot set currency if account is set" + if self.issuer is not None and self.currency.upper() == "XRP": + return "Cannot set issuer if currency is XRP" + return None + + def _get_issuer_error(self: PathStep) -> Optional[str]: + if self.issuer is None: + return None + if self.account is not None: + return "Cannot set issuer if account is set" + if self.currency is not None and self.currency.upper() == "XRP": + return "Cannot set issuer if currency is XRP" + return None -from xrpl.models.path_step import PathStep Path = List[PathStep] """ diff --git a/xrpl/models/path_step.py b/xrpl/models/path_step.py deleted file mode 100644 index ff4d4e8e0..000000000 --- a/xrpl/models/path_step.py +++ /dev/null @@ -1,63 +0,0 @@ -""" -A path is an ordered array. Each member of a path is an -object that specifies the step. -""" - -from __future__ import annotations - -from dataclasses import dataclass, field -from typing import Dict, Optional - -from xrpl.models.base_model import BaseModel -from xrpl.models.utils import require_kwargs_on_init - - -@require_kwargs_on_init -@dataclass(frozen=True) -class PathStep(BaseModel): - """A PathStep represents an individual step along a Path.""" - - account: Optional[str] = None - currency: Optional[str] = None - issuer: Optional[str] = None - type: Optional[int] = None - type_hex: Optional[str] = None - - _special_model: str = field(default="PathStep", init=False) - - def _get_errors(self: PathStep) -> Dict[str, str]: - return { - key: value - for key, value in { - **super()._get_errors(), - "account": self._get_account_error(), - "currency": self._get_currency_error(), - "issuer": self._get_issuer_error(), - }.items() - if value is not None - } - - def _get_account_error(self: PathStep) -> Optional[str]: - if self.account is None: - return None - if self.currency is not None or self.issuer is not None: - return "Cannot set account if currency or issuer are set" - return None - - def _get_currency_error(self: PathStep) -> Optional[str]: - if self.currency is None: - return None - if self.account is not None: - return "Cannot set currency if account is set" - if self.issuer is not None and self.currency.upper() == "XRP": - return "Cannot set issuer if currency is XRP" - return None - - def _get_issuer_error(self: PathStep) -> Optional[str]: - if self.issuer is None: - return None - if self.account is not None: - return "Cannot set issuer if account is set" - if self.currency is not None and self.currency.upper() == "XRP": - return "Cannot set issuer if currency is XRP" - return None diff --git a/xrpl/models/requests/__init__.py b/xrpl/models/requests/__init__.py index ca15f53ac..adde2698f 100644 --- a/xrpl/models/requests/__init__.py +++ b/xrpl/models/requests/__init__.py @@ -1,6 +1,6 @@ """Request models.""" from xrpl.models.auth_account import AuthAccount -from xrpl.models.path_step import PathStep +from xrpl.models.path import PathStep from xrpl.models.requests.account_channels import AccountChannels from xrpl.models.requests.account_currencies import AccountCurrencies from xrpl.models.requests.account_info import AccountInfo diff --git a/xrpl/models/transactions/transaction.py b/xrpl/models/transactions/transaction.py index 078e2480b..86f437d99 100644 --- a/xrpl/models/transactions/transaction.py +++ b/xrpl/models/transactions/transaction.py @@ -60,14 +60,7 @@ def _key_to_tx_json(key: str) -> str: def _value_to_tx_json(value: XRPL_VALUE_TYPE) -> XRPL_VALUE_TYPE: # IssuedCurrencyAmount and PathStep are special cases and should not be snake cased # and only contain primitive members - _special_model = None - if isinstance(value, dict) and "_special_model" in value: - _special_model = value.pop("_special_model") - - if ( - _special_model == PathStep._special_model - or IssuedCurrencyAmount.is_dict_of_model(value) - ): + if IssuedCurrencyAmount.is_dict_of_model(value) or PathStep.is_dict_of_model(value): return value if isinstance(value, dict): return transaction_json_to_binary_codec_form(value) From fc82cf335886d968a83fbdd9bc1eab35de3ced69 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 14 Sep 2022 20:10:29 -0500 Subject: [PATCH 48/88] fix AuthAccount capitalization issues (#432) Co-authored-by: Omar Khan --- xrpl/models/transactions/transaction.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/xrpl/models/transactions/transaction.py b/xrpl/models/transactions/transaction.py index 86f437d99..9fe54aeca 100644 --- a/xrpl/models/transactions/transaction.py +++ b/xrpl/models/transactions/transaction.py @@ -60,6 +60,8 @@ def _key_to_tx_json(key: str) -> str: def _value_to_tx_json(value: XRPL_VALUE_TYPE) -> XRPL_VALUE_TYPE: # IssuedCurrencyAmount and PathStep are special cases and should not be snake cased # and only contain primitive members + if isinstance(value, dict) and "auth_account" in value: + return _auth_account_value_to_tx_json(value) if IssuedCurrencyAmount.is_dict_of_model(value) or PathStep.is_dict_of_model(value): return value if isinstance(value, dict): @@ -69,6 +71,13 @@ def _value_to_tx_json(value: XRPL_VALUE_TYPE) -> XRPL_VALUE_TYPE: return value +def _auth_account_value_to_tx_json(value: Dict[str, Any]) -> Dict[str, Any]: + return { + _key_to_tx_json(key): transaction_json_to_binary_codec_form(val) + for (key, val) in value.items() + } + + @require_kwargs_on_init @dataclass(frozen=True) class Memo(BaseModel): From 05f633a1ebf7cff291edd89ff2f26959af440a59 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 15 Sep 2022 14:45:30 -0400 Subject: [PATCH 49/88] add AMMBid codec-fixture --- .../fixtures/data/codec-fixtures.json | 50 ++++++++++++++----- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json b/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json index be2e637a3..66049ce30 100644 --- a/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json +++ b/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json @@ -4435,20 +4435,44 @@ } } ], - "transactions": [{ - "binary": "1200002200000000240000003E6140000002540BE40068400000000000000A7321034AADB09CFF4A4804073701EC53C3510CDC95917C2BB0150FB742D0C66E6CEE9E74473045022022EB32AECEF7C644C891C19F87966DF9C62B1F34BABA6BE774325E4BB8E2DD62022100A51437898C28C2B297112DF8131F2BB39EA5FE613487DDD611525F17962646398114550FC62003E785DC231A1058A05E56E3F09CF4E68314D4CC8AB5B21D86A82C3E9E8D0ECF2404B77FECBA", - "json": { - "Account": "r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV", - "Destination": "rLQBHVhFnaC5gLEkgr6HgBJJ3bgeZHg9cj", - "TransactionType": "Payment", - "TxnSignature": "3045022022EB32AECEF7C644C891C19F87966DF9C62B1F34BABA6BE774325E4BB8E2DD62022100A51437898C28C2B297112DF8131F2BB39EA5FE613487DDD611525F1796264639", - "SigningPubKey": "034AADB09CFF4A4804073701EC53C3510CDC95917C2BB0150FB742D0C66E6CEE9E", - "Amount": "10000000000", - "Fee": "10", - "Flags": 0, - "Sequence": 62 + "transactions": [ + { + "binary": "1200002200000000240000003E6140000002540BE40068400000000000000A7321034AADB09CFF4A4804073701EC53C3510CDC95917C2BB0150FB742D0C66E6CEE9E74473045022022EB32AECEF7C644C891C19F87966DF9C62B1F34BABA6BE774325E4BB8E2DD62022100A51437898C28C2B297112DF8131F2BB39EA5FE613487DDD611525F17962646398114550FC62003E785DC231A1058A05E56E3F09CF4E68314D4CC8AB5B21D86A82C3E9E8D0ECF2404B77FECBA", + "json": { + "Account": "r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV", + "Destination": "rLQBHVhFnaC5gLEkgr6HgBJJ3bgeZHg9cj", + "TransactionType": "Payment", + "TxnSignature": "3045022022EB32AECEF7C644C891C19F87966DF9C62B1F34BABA6BE774325E4BB8E2DD62022100A51437898C28C2B297112DF8131F2BB39EA5FE613487DDD611525F1796264639", + "SigningPubKey": "034AADB09CFF4A4804073701EC53C3510CDC95917C2BB0150FB742D0C66E6CEE9E", + "Amount": "10000000000", + "Fee": "10", + "Flags": 0, + "Sequence": 62 + } + }, + { + "binary": "120027220000000024000000185E90C09DE74DB53F9737385AC45039CC1873501CA5333CB4518648524C7B14F15368400000000000000A6D40000000000000056E400000000000000A7321036FB8123857AA5E0CB94CBEDF5E10AAC3AB86B02F988D12B13E4BE4CDF54898D874473045022100F4CD0BC16ADFE1BD1C6C44E720C9F65D028D016677416C049E4F78CC3E8B90AD02204F42BC47CA9166928C2C46F94AC8F446BA21B628BAAAC6D763B116791220D4B181140B9DD29BC414ECC0EB0CBAB7969D360FCD0B0194F015E01C81149A91957F8F16BC57F3F200CD8C98375BF1791586E1F1", + "json": { + "AMMID": "90C09DE74DB53F9737385AC45039CC1873501CA5333CB4518648524C7B14F153", + "Account": "rphRVF5zFGwgMUMzPX1jdnEwfdnCYUoARC", + "AuthAccounts": [ + { "AuthAccount": + { + "Account": "rEaHTti4HZsMBpxTAF4ncWxkcdqDh1h6P7" + } + } + ], + "Fee": "10", + "Flags": 0, + "MaxSlotPrice": "10", + "MinSlotPrice": "5", + "Sequence": 24, + "SigningPubKey": "036FB8123857AA5E0CB94CBEDF5E10AAC3AB86B02F988D12B13E4BE4CDF54898D8", + "TransactionType": "AMMBid", + "TxnSignature": "3045022100F4CD0BC16ADFE1BD1C6C44E720C9F65D028D016677416C049E4F78CC3E8B90AD02204F42BC47CA9166928C2C46F94AC8F446BA21B628BAAAC6D763B116791220D4B1" + } } - }], + ], "ledgerData": [{ "binary": "01E91435016340767BF1C4A3EACEB081770D8ADE216C85445DD6FB002C6B5A2930F2DECE006DA18150CB18F6DD33F6F0990754C962A7CCE62F332FF9C13939B03B864117F0BDA86B6E9B4F873B5C3E520634D343EF5D9D9A4246643D64DAD278BA95DC0EAC6EB5350CF970D521276CDE21276CE60A00", "json": { From 5ad9b4478e268a63b31a7a1b679a08d5c25938b0 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 15 Sep 2022 15:16:19 -0400 Subject: [PATCH 50/88] add AMMInstanceCreate codec-fixture --- .../fixtures/data/codec-fixtures.json | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json b/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json index 66049ce30..d504ab6d0 100644 --- a/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json +++ b/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json @@ -4471,6 +4471,25 @@ "TransactionType": "AMMBid", "TxnSignature": "3045022100F4CD0BC16ADFE1BD1C6C44E720C9F65D028D016677416C049E4F78CC3E8B90AD02204F42BC47CA9166928C2C46F94AC8F446BA21B628BAAAC6D763B116791220D4B1" } + }, + { + "binary": "12002315000A2200000000240000001868400000000000000A6B40000000000027106CD5838D7EA4C680000000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C7321036FB8123857AA5E0CB94CBEDF5E10AAC3AB86B02F988D12B13E4BE4CDF54898D874473045022100B236A159E4086B61AB1FCB31C310E1B9AD043AB3ECE5E9DA3EDC405FF3AE26F202207C67DE108D1C8D224696E93CC33A854ABFE9F8CF9688C5C0CCF28BA560D5B40B81140B9DD29BC414ECC0EB0CBAB7969D360FCD0B0194", + "json": { + "Account": "rphRVF5zFGwgMUMzPX1jdnEwfdnCYUoARC", + "Asset1": "10000", + "Asset2": { + "currency": "ETH", + "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", + "value": "10000" + }, + "Fee": "10", + "Flags": 0, + "Sequence": 24, + "SigningPubKey": "036FB8123857AA5E0CB94CBEDF5E10AAC3AB86B02F988D12B13E4BE4CDF54898D8", + "TradingFee": 10, + "TransactionType": "AMMInstanceCreate", + "TxnSignature": "3045022100B236A159E4086B61AB1FCB31C310E1B9AD043AB3ECE5E9DA3EDC405FF3AE26F202207C67DE108D1C8D224696E93CC33A854ABFE9F8CF9688C5C0CCF28BA560D5B40B" + } } ], "ledgerData": [{ From d9b8bfeaaa496a306f87d3b40cbff3c889a0d0f5 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 15 Sep 2022 15:20:08 -0400 Subject: [PATCH 51/88] update definitions.json with different AuthAccounts number --- .../binarycodec/definitions/definitions.json | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/xrpl/core/binarycodec/definitions/definitions.json b/xrpl/core/binarycodec/definitions/definitions.json index cc0fc1d04..2c3b655c9 100644 --- a/xrpl/core/binarycodec/definitions/definitions.json +++ b/xrpl/core/binarycodec/definitions/definitions.json @@ -2402,16 +2402,6 @@ "type": "STArray" } ], - [ - "AuthAccounts", - { - "nth": 21, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STArray" - } - ], [ "Majorities", { @@ -2461,6 +2451,16 @@ "isSigningField": true, "type": "STArray" } + ], + [ + "AuthAccounts", + { + "nth": 26, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "STArray" + } ] ], "TRANSACTION_RESULTS": { From e9307f584e601644fdec5fc7b07145400c215ecf Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 15 Sep 2022 15:52:28 -0400 Subject: [PATCH 52/88] remove AMM codec-fixtures --- .../fixtures/data/codec-fixtures.json | 41 ------------------- 1 file changed, 41 deletions(-) diff --git a/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json b/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json index d504ab6d0..916454946 100644 --- a/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json +++ b/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json @@ -4449,47 +4449,6 @@ "Flags": 0, "Sequence": 62 } - }, - { - "binary": "120027220000000024000000185E90C09DE74DB53F9737385AC45039CC1873501CA5333CB4518648524C7B14F15368400000000000000A6D40000000000000056E400000000000000A7321036FB8123857AA5E0CB94CBEDF5E10AAC3AB86B02F988D12B13E4BE4CDF54898D874473045022100F4CD0BC16ADFE1BD1C6C44E720C9F65D028D016677416C049E4F78CC3E8B90AD02204F42BC47CA9166928C2C46F94AC8F446BA21B628BAAAC6D763B116791220D4B181140B9DD29BC414ECC0EB0CBAB7969D360FCD0B0194F015E01C81149A91957F8F16BC57F3F200CD8C98375BF1791586E1F1", - "json": { - "AMMID": "90C09DE74DB53F9737385AC45039CC1873501CA5333CB4518648524C7B14F153", - "Account": "rphRVF5zFGwgMUMzPX1jdnEwfdnCYUoARC", - "AuthAccounts": [ - { "AuthAccount": - { - "Account": "rEaHTti4HZsMBpxTAF4ncWxkcdqDh1h6P7" - } - } - ], - "Fee": "10", - "Flags": 0, - "MaxSlotPrice": "10", - "MinSlotPrice": "5", - "Sequence": 24, - "SigningPubKey": "036FB8123857AA5E0CB94CBEDF5E10AAC3AB86B02F988D12B13E4BE4CDF54898D8", - "TransactionType": "AMMBid", - "TxnSignature": "3045022100F4CD0BC16ADFE1BD1C6C44E720C9F65D028D016677416C049E4F78CC3E8B90AD02204F42BC47CA9166928C2C46F94AC8F446BA21B628BAAAC6D763B116791220D4B1" - } - }, - { - "binary": "12002315000A2200000000240000001868400000000000000A6B40000000000027106CD5838D7EA4C680000000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C7321036FB8123857AA5E0CB94CBEDF5E10AAC3AB86B02F988D12B13E4BE4CDF54898D874473045022100B236A159E4086B61AB1FCB31C310E1B9AD043AB3ECE5E9DA3EDC405FF3AE26F202207C67DE108D1C8D224696E93CC33A854ABFE9F8CF9688C5C0CCF28BA560D5B40B81140B9DD29BC414ECC0EB0CBAB7969D360FCD0B0194", - "json": { - "Account": "rphRVF5zFGwgMUMzPX1jdnEwfdnCYUoARC", - "Asset1": "10000", - "Asset2": { - "currency": "ETH", - "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", - "value": "10000" - }, - "Fee": "10", - "Flags": 0, - "Sequence": 24, - "SigningPubKey": "036FB8123857AA5E0CB94CBEDF5E10AAC3AB86B02F988D12B13E4BE4CDF54898D8", - "TradingFee": 10, - "TransactionType": "AMMInstanceCreate", - "TxnSignature": "3045022100B236A159E4086B61AB1FCB31C310E1B9AD043AB3ECE5E9DA3EDC405FF3AE26F202207C67DE108D1C8D224696E93CC33A854ABFE9F8CF9688C5C0CCF28BA560D5B40B" - } } ], "ledgerData": [{ From 18e440fcf5c67fa1e7e0b2aa547335fd0a8e0efd Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 9 Nov 2022 14:05:43 -0500 Subject: [PATCH 53/88] Change amm_info asset parameters to Currency type --- xrpl/models/requests/amm_info.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xrpl/models/requests/amm_info.py b/xrpl/models/requests/amm_info.py index 3d7364814..e4003b7b0 100644 --- a/xrpl/models/requests/amm_info.py +++ b/xrpl/models/requests/amm_info.py @@ -4,7 +4,7 @@ from dataclasses import dataclass, field from typing import Dict, Optional -from xrpl.models.amounts import Amount +from xrpl.models.currencies import Currency from xrpl.models.requests.request import Request, RequestMethod from xrpl.models.utils import require_kwargs_on_init @@ -23,12 +23,12 @@ class AMMInfo(Request): A hash that uniquely identifies the AMM instance. """ - asset1: Optional[Amount] = None + asset1: Optional[Currency] = None """ Specifies one of the pool assets (XRP or token) of the AMM instance. """ - asset2: Optional[Amount] = None + asset2: Optional[Currency] = None """ Specifies the other pool asset of the AMM instance. """ From 71a389eda37290c2285734d6834f0e6d97c1f6f8 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 9 Nov 2022 14:45:02 -0500 Subject: [PATCH 54/88] API name changes with updated definitions.json --- tests/unit/models/test_base_model.py | 80 +++++----- .../unit/models/transactions/test_amm_bid.py | 4 +- ..._instance_create.py => test_amm_create.py} | 22 +-- .../models/transactions/test_amm_deposit.py | 32 ++-- .../models/transactions/test_amm_withdraw.py | 32 ++-- .../binarycodec/definitions/definitions.json | 147 ++++-------------- xrpl/models/transactions/__init__.py | 4 +- xrpl/models/transactions/amm_bid.py | 4 +- .../{amm_instance_create.py => amm_create.py} | 16 +- xrpl/models/transactions/amm_deposit.py | 24 +-- xrpl/models/transactions/amm_vote.py | 2 +- xrpl/models/transactions/amm_withdraw.py | 26 ++-- .../transactions/types/transaction_type.py | 2 +- 13 files changed, 158 insertions(+), 237 deletions(-) rename tests/unit/models/transactions/{test_amm_instance_create.py => test_amm_create.py} (76%) rename xrpl/models/transactions/{amm_instance_create.py => amm_create.py} (79%) diff --git a/tests/unit/models/test_base_model.py b/tests/unit/models/test_base_model.py index f06f918f0..c5530d0d6 100644 --- a/tests/unit/models/test_base_model.py +++ b/tests/unit/models/test_base_model.py @@ -17,8 +17,8 @@ ) from xrpl.models.transactions import ( AMMBid, + AMMCreate, AMMDeposit, - AMMInstanceCreate, AMMVote, AMMWithdraw, AuthAccount, @@ -604,11 +604,11 @@ def test_to_xrpl_signer(self): } self.assertEqual(tx.to_xrpl(), expected) - def test_to_xrpl_amm_instance_create(self): - tx = AMMInstanceCreate( + def test_to_xrpl_amm_create(self): + tx = AMMCreate( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - asset1="1000", - asset2=IssuedCurrencyAmount( + amount="1000", + amount2=IssuedCurrencyAmount( currency="USD", issuer="rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", value="1000", @@ -617,13 +617,13 @@ def test_to_xrpl_amm_instance_create(self): ) expected = { "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset1": "1000", - "Asset2": { + "Amount": "1000", + "Amount2": { "currency": "USD", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", "value": "1000", }, - "TransactionType": "AMMInstanceCreate", + "TransactionType": "AMMCreate", "SigningPubKey": "", "TradingFee": 12, "Flags": 0, @@ -656,17 +656,17 @@ def test_to_xrpl_amm_deposit_lptoken(self): } self.assertEqual(tx.to_xrpl(), expected) - def test_to_xrpl_amm_deposit_asset1in(self): + def test_to_xrpl_amm_deposit_amount(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", - asset1_in="1000", + amount="1000", ) expected = { "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset1In": "1000", + "Amount": "1000", "TransactionType": "AMMDeposit", "Sequence": 1337, "SigningPubKey": "", @@ -674,19 +674,19 @@ def test_to_xrpl_amm_deposit_asset1in(self): } self.assertEqual(tx.to_xrpl(), expected) - def test_to_xrpl_amm_deposit_asset1in_asset2in(self): + def test_to_xrpl_amm_deposit_amount_amount2(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", - asset1_in="1000", - asset2_in="500", + amount="1000", + amount2="500", ) expected = { "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset1In": "1000", - "Asset2In": "500", + "Amount": "1000", + "Amount2": "500", "TransactionType": "AMMDeposit", "Sequence": 1337, "SigningPubKey": "", @@ -694,12 +694,12 @@ def test_to_xrpl_amm_deposit_asset1in_asset2in(self): } self.assertEqual(tx.to_xrpl(), expected) - def test_to_xrpl_amm_deposit_asset1in_lptoken(self): + def test_to_xrpl_amm_deposit_amount_lptoken(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", - asset1_in="1000", + amount="1000", lp_token=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", @@ -709,7 +709,7 @@ def test_to_xrpl_amm_deposit_asset1in_lptoken(self): expected = { "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset1In": "1000", + "Amount": "1000", "LPToken": { "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", @@ -722,18 +722,18 @@ def test_to_xrpl_amm_deposit_asset1in_lptoken(self): } self.assertEqual(tx.to_xrpl(), expected) - def test_to_xrpl_amm_deposit_asset1in_eprice(self): + def test_to_xrpl_amm_deposit_amount_eprice(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", - asset1_in="1000", + amount="1000", e_price="25", ) expected = { "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset1In": "1000", + "Amount": "1000", "EPrice": "25", "TransactionType": "AMMDeposit", "Sequence": 1337, @@ -768,17 +768,17 @@ def test_to_xrpl_amm_withdraw_lptoken(self): } self.assertEqual(tx.to_xrpl(), expected) - def test_to_xrpl_amm_withdraw_asset1out(self): + def test_to_xrpl_amm_withdraw_amount(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", - asset1_out="1000", + amount="1000", ) expected = { "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset1Out": "1000", + "Amount": "1000", "TransactionType": "AMMWithdraw", "Sequence": 1337, "SigningPubKey": "", @@ -786,19 +786,19 @@ def test_to_xrpl_amm_withdraw_asset1out(self): } self.assertEqual(tx.to_xrpl(), expected) - def test_to_xrpl_amm_withdraw_asset1out_asset2out(self): + def test_to_xrpl_amm_withdraw_amount_amount2(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", - asset1_out="1000", - asset2_out="500", + amount="1000", + amount2="500", ) expected = { "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset1Out": "1000", - "Asset2Out": "500", + "Amount": "1000", + "Amount2": "500", "TransactionType": "AMMWithdraw", "Sequence": 1337, "SigningPubKey": "", @@ -806,12 +806,12 @@ def test_to_xrpl_amm_withdraw_asset1out_asset2out(self): } self.assertEqual(tx.to_xrpl(), expected) - def test_to_xrpl_amm_withdraw_asset1out_lptoken(self): + def test_to_xrpl_amm_withdraw_amount_lptoken(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", - asset1_out="1000", + amount="1000", lp_token=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", @@ -821,7 +821,7 @@ def test_to_xrpl_amm_withdraw_asset1out_lptoken(self): expected = { "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset1Out": "1000", + "Amount": "1000", "LPToken": { "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", @@ -834,18 +834,18 @@ def test_to_xrpl_amm_withdraw_asset1out_lptoken(self): } self.assertEqual(tx.to_xrpl(), expected) - def test_to_xrpl_amm_withdraw_asset1out_eprice(self): + def test_to_xrpl_amm_withdraw_amount_eprice(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", - asset1_out="1000", + amount="1000", e_price="25", ) expected = { "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset1Out": "1000", + "Amount": "1000", "EPrice": "25", "TransactionType": "AMMWithdraw", "Sequence": 1337, @@ -874,12 +874,12 @@ def test_to_xrpl_amm_bid(self): tx = AMMBid( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", - min_slot_price=IssuedCurrencyAmount( + min_bid_price=IssuedCurrencyAmount( currency="5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", issuer="r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", value="25", ), - max_slot_price=IssuedCurrencyAmount( + max_bid_price=IssuedCurrencyAmount( currency="5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", issuer="r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", value="35", @@ -894,12 +894,12 @@ def test_to_xrpl_amm_bid(self): expected = { "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", - "MinSlotPrice": { + "MinBidPrice": { "currency": "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", "issuer": "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", "value": "25", }, - "MaxSlotPrice": { + "MaxBidPrice": { "currency": "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", "issuer": "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", "value": "35", diff --git a/tests/unit/models/transactions/test_amm_bid.py b/tests/unit/models/transactions/test_amm_bid.py index ed847103e..1e53d4348 100644 --- a/tests/unit/models/transactions/test_amm_bid.py +++ b/tests/unit/models/transactions/test_amm_bid.py @@ -29,12 +29,12 @@ def test_tx_valid(self): tx = AMMBid( account=_ACCOUNT, amm_id=_AMM_ID, - min_slot_price=IssuedCurrencyAmount( + min_bid_price=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, value="25", ), - max_slot_price=IssuedCurrencyAmount( + max_bid_price=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, value="35", diff --git a/tests/unit/models/transactions/test_amm_instance_create.py b/tests/unit/models/transactions/test_amm_create.py similarity index 76% rename from tests/unit/models/transactions/test_amm_instance_create.py rename to tests/unit/models/transactions/test_amm_create.py index 197127c27..88a8fa12b 100644 --- a/tests/unit/models/transactions/test_amm_instance_create.py +++ b/tests/unit/models/transactions/test_amm_create.py @@ -3,18 +3,18 @@ from xrpl.models.amounts import IssuedCurrencyAmount from xrpl.models.exceptions import XRPLModelException -from xrpl.models.transactions import AMMInstanceCreate +from xrpl.models.transactions import AMMCreate _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" _IOU_ISSUER = "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9" -class TestAMMInstanceCreate(TestCase): +class TestAMMCreate(TestCase): def test_tx_is_valid(self): - tx = AMMInstanceCreate( + tx = AMMCreate( account=_ACCOUNT, - asset1="1000", - asset2=IssuedCurrencyAmount( + amount="1000", + amount2=IssuedCurrencyAmount( currency="USD", issuer=_IOU_ISSUER, value="1000" ), trading_fee=12, @@ -23,10 +23,10 @@ def test_tx_is_valid(self): def test_trading_fee_too_high(self): with self.assertRaises(XRPLModelException) as error: - AMMInstanceCreate( + AMMCreate( account=_ACCOUNT, - asset1="1000", - asset2=IssuedCurrencyAmount( + amount="1000", + amount2=IssuedCurrencyAmount( currency="USD", issuer=_IOU_ISSUER, value="1000" ), trading_fee=maxsize, @@ -38,10 +38,10 @@ def test_trading_fee_too_high(self): def test_trading_fee_negative_number(self): with self.assertRaises(XRPLModelException) as error: - AMMInstanceCreate( + AMMCreate( account=_ACCOUNT, - asset1="1000", - asset2=IssuedCurrencyAmount( + amount="1000", + amount2=IssuedCurrencyAmount( currency="USD", issuer=_IOU_ISSUER, value="1000" ), trading_fee=-1, diff --git a/tests/unit/models/transactions/test_amm_deposit.py b/tests/unit/models/transactions/test_amm_deposit.py index ec487b693..a27b1c5ad 100644 --- a/tests/unit/models/transactions/test_amm_deposit.py +++ b/tests/unit/models/transactions/test_amm_deposit.py @@ -25,31 +25,31 @@ def test_tx_valid_xrpl_lptoken(self): ) self.assertTrue(tx.is_valid()) - def test_tx_valid_asset1in(self): + def test_tx_valid_amount(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, - asset1_in=_AMOUNT, + amount=_AMOUNT, ) self.assertTrue(tx.is_valid()) - def test_tx_valid_asset1in_asset2in(self): + def test_tx_valid_amount_amount2(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, - asset1_in=_AMOUNT, - asset2_in="500", + amount=_AMOUNT, + amount2="500", ) self.assertTrue(tx.is_valid()) - def test_tx_valid_asset1in_lptoken(self): + def test_tx_valid_amount_lptoken(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, - asset1_in=_AMOUNT, + amount=_AMOUNT, lp_token=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, @@ -58,17 +58,17 @@ def test_tx_valid_asset1in_lptoken(self): ) self.assertTrue(tx.is_valid()) - def test_tx_valid_asset1in_eprice(self): + def test_tx_valid_amount_eprice(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, - asset1_in=_AMOUNT, + amount=_AMOUNT, e_price="25", ) self.assertTrue(tx.is_valid()) - def test_undefined_asset1in_undefined_lptoken_invalid_combo(self): + def test_undefined_amount_undefined_lptoken_invalid_combo(self): with self.assertRaises(XRPLModelException) as error: AMMDeposit( account=_ACCOUNT, @@ -77,23 +77,23 @@ def test_undefined_asset1in_undefined_lptoken_invalid_combo(self): ) self.assertEqual( error.exception.args[0], - "{'AMMDeposit': 'Must set at least `lp_token` or `asset1_in`'}", + "{'AMMDeposit': 'Must set at least `lp_token` or `amount`'}", ) - def test_undefined_asset1in_defined_asset2in_invalid_combo(self): + def test_undefined_amount_defined_amount2_invalid_combo(self): with self.assertRaises(XRPLModelException) as error: AMMDeposit( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, - asset2_in="500", + amount2="500", ) self.assertEqual( error.exception.args[0], - "{'AMMDeposit': 'Must set `asset1_in` with `asset2_in`'}", + "{'AMMDeposit': 'Must set `amount` with `amount2`'}", ) - def test_undefined_asset1in_defined_eprice_invalid_combo(self): + def test_undefined_amount_defined_eprice_invalid_combo(self): with self.assertRaises(XRPLModelException) as error: AMMDeposit( account=_ACCOUNT, @@ -103,5 +103,5 @@ def test_undefined_asset1in_defined_eprice_invalid_combo(self): ) self.assertEqual( error.exception.args[0], - "{'AMMDeposit': 'Must set `asset1_in` with `e_price`'}", + "{'AMMDeposit': 'Must set `amount` with `e_price`'}", ) diff --git a/tests/unit/models/transactions/test_amm_withdraw.py b/tests/unit/models/transactions/test_amm_withdraw.py index ce6947764..65fd1e10d 100644 --- a/tests/unit/models/transactions/test_amm_withdraw.py +++ b/tests/unit/models/transactions/test_amm_withdraw.py @@ -25,31 +25,31 @@ def test_tx_valid_lptoken(self): ) self.assertTrue(tx.is_valid()) - def test_tx_valid_asset1out(self): + def test_tx_valid_amount(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, - asset1_out=_AMOUNT, + amount=_AMOUNT, ) self.assertTrue(tx.is_valid()) - def test_tx_valid_asset1out_asset2out(self): + def test_tx_valid_amount_amount2(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, - asset1_out=_AMOUNT, - asset2_out="500", + amount=_AMOUNT, + amount2="500", ) self.assertTrue(tx.is_valid()) - def test_tx_valid_asset1out_lptoken(self): + def test_tx_valid_amount_lptoken(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, - asset1_out=_AMOUNT, + amount=_AMOUNT, lp_token=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, @@ -58,17 +58,17 @@ def test_tx_valid_asset1out_lptoken(self): ) self.assertTrue(tx.is_valid()) - def test_tx_valid_asset1out_eprice(self): + def test_tx_valid_amount_eprice(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, - asset1_out=_AMOUNT, + amount=_AMOUNT, e_price="25", ) self.assertTrue(tx.is_valid()) - def test_undefined_asset1out_undefined_lptoken_invalid_combo(self): + def test_undefined_amount_undefined_lptoken_invalid_combo(self): with self.assertRaises(XRPLModelException) as error: AMMWithdraw( account=_ACCOUNT, @@ -77,23 +77,23 @@ def test_undefined_asset1out_undefined_lptoken_invalid_combo(self): ) self.assertEqual( error.exception.args[0], - "{'AMMWithdraw': 'Must set at least `lp_token` or `asset1_out`'}", + "{'AMMWithdraw': 'Must set at least `lp_token` or `amount`'}", ) - def test_undefined_asset1out_defined_asset2out_invalid_combo(self): + def test_undefined_amount_defined_amount2_invalid_combo(self): with self.assertRaises(XRPLModelException) as error: AMMWithdraw( account=_ACCOUNT, sequence=1337, amm_id=_AMM_ID, - asset2_out="500", + amount2="500", ) self.assertEqual( error.exception.args[0], - "{'AMMWithdraw': 'Must set `asset1_out` with `asset2_out`'}", + "{'AMMWithdraw': 'Must set `amount` with `amount2`'}", ) - def test_undefined_asset1out_defined_eprice_invalid_combo(self): + def test_undefined_amount_defined_eprice_invalid_combo(self): with self.assertRaises(XRPLModelException) as error: AMMWithdraw( account=_ACCOUNT, @@ -103,5 +103,5 @@ def test_undefined_asset1out_defined_eprice_invalid_combo(self): ) self.assertEqual( error.exception.args[0], - "{'AMMWithdraw': 'Must set `asset1_out` with `e_price`'}", + "{'AMMWithdraw': 'Must set `amount` with `e_price`'}", ) diff --git a/xrpl/core/binarycodec/definitions/definitions.json b/xrpl/core/binarycodec/definitions/definitions.json index 2c3b655c9..55bbac88a 100644 --- a/xrpl/core/binarycodec/definitions/definitions.json +++ b/xrpl/core/binarycodec/definitions/definitions.json @@ -21,6 +21,7 @@ "UInt192": 21, "UInt384": 22, "UInt512": 23, + "Issue": 24, "Transaction": 10001, "LedgerEntry": 10002, "Validation": 10003, @@ -772,30 +773,10 @@ "type": "UInt32" } ], - [ - "FeeVal", - { - "nth": 47, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], [ "VoteWeight", { - "nth": 48, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "TimeStamp", - { - "nth": 49, + "nth": 47, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -805,7 +786,7 @@ [ "DiscountedFee", { - "nth": 50, + "nth": 48, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1463,7 +1444,7 @@ } ], [ - "Asset1", + "Amount2", { "nth": 11, "isVLEncoded": false, @@ -1473,7 +1454,7 @@ } ], [ - "Asset2", + "MinBidPrice", { "nth": 12, "isVLEncoded": false, @@ -1483,7 +1464,7 @@ } ], [ - "MinSlotPrice", + "MaxBidPrice", { "nth": 13, "isVLEncoded": false, @@ -1492,16 +1473,6 @@ "type": "Amount" } ], - [ - "MaxSlotPrice", - { - "nth": 14, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], [ "MinimumOffer", { @@ -1543,7 +1514,7 @@ } ], [ - "Asset1In", + "LPTokenOut", { "nth": 20, "isVLEncoded": false, @@ -1553,7 +1524,7 @@ } ], [ - "Asset2In", + "LPTokenIn", { "nth": 21, "isVLEncoded": false, @@ -1562,40 +1533,10 @@ "type": "Amount" } ], - [ - "Asset1Out", - { - "nth": 22, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], - [ - "Asset2Out", - { - "nth": 23, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], - [ - "LPToken", - { - "nth": 24, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], [ "EPrice", { - "nth": 25, + "nth": 22, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1605,7 +1546,7 @@ [ "Price", { - "nth": 26, + "nth": 23, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1615,7 +1556,7 @@ [ "LPTokenBalance", { - "nth": 27, + "nth": 24, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -2022,6 +1963,26 @@ "type": "PathSet" } ], + [ + "Asset", + { + "nth": 1, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Issue" + } + ], + [ + "Asset2", + { + "nth": 2, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Issue" + } + ], [ "TransactionMetaData", { @@ -2152,16 +2113,6 @@ "type": "STObject" } ], - [ - "AMM", - { - "nth": 15, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" - } - ], [ "Signer", { @@ -2272,36 +2223,6 @@ "type": "STObject" } ], - [ - "AMMToken", - { - "nth": 29, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" - } - ], - [ - "Token1", - { - "nth": 30, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" - } - ], - [ - "Token2", - { - "nth": 31, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" - } - ], [ "Signers", { @@ -2553,6 +2474,7 @@ "terNO_RIPPLE": -90, "terQUEUED": -89, "terPRE_TICKET": -88, + "terNO_AMM": -87, "tesSUCCESS": 0, @@ -2609,8 +2531,7 @@ "tecAMM_INVALID_TOKENS": 166, "tecAMM_EXISTS": 167, "tecAMM_FAILED_BID": 168, - "tecAMM_DIRECT_PAYMENT": 169, - "tecAMM_FAILED_VOTE": 170 + "tecAMM_FAILED_VOTE": 169 }, "TRANSACTION_TYPES": { "Invalid": -1, @@ -2642,7 +2563,7 @@ "NFTokenCreateOffer": 27, "NFTokenCancelOffer": 28, "NFTokenAcceptOffer": 29, - "AMMInstanceCreate": 35, + "AMMCreate": 35, "AMMDeposit": 36, "AMMWithdraw": 37, "AMMVote": 38, diff --git a/xrpl/models/transactions/__init__.py b/xrpl/models/transactions/__init__.py index 6ed90a18e..46afafaf7 100644 --- a/xrpl/models/transactions/__init__.py +++ b/xrpl/models/transactions/__init__.py @@ -10,8 +10,8 @@ AccountSetFlagInterface, ) from xrpl.models.transactions.amm_bid import AMMBid, AuthAccount +from xrpl.models.transactions.amm_create import AMMCreate from xrpl.models.transactions.amm_deposit import AMMDeposit -from xrpl.models.transactions.amm_instance_create import AMMInstanceCreate from xrpl.models.transactions.amm_vote import AMMVote from xrpl.models.transactions.amm_withdraw import AMMWithdraw from xrpl.models.transactions.check_cancel import CheckCancel @@ -65,8 +65,8 @@ "AccountSetFlag", "AccountSetFlagInterface", "AMMBid", + "AMMCreate", "AMMDeposit", - "AMMInstanceCreate", "AMMVote", "AMMWithdraw", "AuthAccount", diff --git a/xrpl/models/transactions/amm_bid.py b/xrpl/models/transactions/amm_bid.py index cea690ed0..008a0a2bf 100644 --- a/xrpl/models/transactions/amm_bid.py +++ b/xrpl/models/transactions/amm_bid.py @@ -32,7 +32,7 @@ class AMMBid(Transaction): A hash that uniquely identifies the AMM instance. This field is required. """ - min_slot_price: Optional[Amount] = None + min_bid_price: Optional[Amount] = None """ This field represents the minimum price that the bidder wants to pay for the slot. It is specified in units of LPToken. If specified let MinSlotPrice be X and let @@ -40,7 +40,7 @@ class AMMBid(Transaction): the max(X, Y). """ - max_slot_price: Optional[Amount] = None + max_bid_price: Optional[Amount] = None """ This field represents the maximum price that the bidder wants to pay for the slot. It is specified in units of LPToken. diff --git a/xrpl/models/transactions/amm_instance_create.py b/xrpl/models/transactions/amm_create.py similarity index 79% rename from xrpl/models/transactions/amm_instance_create.py rename to xrpl/models/transactions/amm_create.py index 653de8026..c834264e5 100644 --- a/xrpl/models/transactions/amm_instance_create.py +++ b/xrpl/models/transactions/amm_create.py @@ -1,4 +1,4 @@ -"""Model for AMMInstanceCreate transaction type.""" +"""Model for AMMCreate transaction type.""" from __future__ import annotations from dataclasses import dataclass, field @@ -17,20 +17,20 @@ @require_kwargs_on_init @dataclass(frozen=True) -class AMMInstanceCreate(Transaction): +class AMMCreate(Transaction): """ - AMMInstanceCreate is used to create AccountRoot and the corresponding AMM + AMMCreate is used to create AccountRoot and the corresponding AMM ledger entries. This allows for the creation of only one AMM instance per unique asset pair. """ - asset1: Amount = REQUIRED # type: ignore + amount: Amount = REQUIRED # type: ignore """ Specifies one of the pool assets (XRP or token) of the AMM instance. This field is required. """ - asset2: Amount = REQUIRED # type: ignore + amount2: Amount = REQUIRED # type: ignore """ Specifies the other pool asset of the AMM instance. This field is required. """ @@ -46,11 +46,11 @@ class AMMInstanceCreate(Transaction): """ transaction_type: TransactionType = field( - default=TransactionType.AMM_INSTANCE_CREATE, + default=TransactionType.AMM_CREATE, init=False, ) - def _get_errors(self: AMMInstanceCreate) -> Dict[str, str]: + def _get_errors(self: AMMCreate) -> Dict[str, str]: return { key: value for key, value in { @@ -60,7 +60,7 @@ def _get_errors(self: AMMInstanceCreate) -> Dict[str, str]: if value is not None } - def _get_trading_fee_error(self: AMMInstanceCreate) -> Optional[str]: + def _get_trading_fee_error(self: AMMCreate) -> Optional[str]: if self.trading_fee < 0 or self.trading_fee > AMM_MAX_TRADING_FEE: return f"Must be between 0 and {AMM_MAX_TRADING_FEE}" return None diff --git a/xrpl/models/transactions/amm_deposit.py b/xrpl/models/transactions/amm_deposit.py index faaecd494..a0dfbd8a7 100644 --- a/xrpl/models/transactions/amm_deposit.py +++ b/xrpl/models/transactions/amm_deposit.py @@ -20,10 +20,10 @@ class AMMDeposit(Transaction): The following are the recommended valid combinations: - LPToken - - Asset1In - - Asset1In and Asset2In - - Asset1In and LPToken - - Asset1In and EPrice + - Amount + - Amount and Amount2 + - Amount and LPToken + - Amount and EPrice """ amm_id: str = REQUIRED # type: ignore @@ -37,13 +37,13 @@ class AMMDeposit(Transaction): wants to redeem or trade in. """ - asset1_in: Optional[Amount] = None + amount: Optional[Amount] = None """ Specifies one of the pool assets (XRP or token) of the AMM instance to deposit more of its value. """ - asset2_in: Optional[Amount] = None + amount2: Optional[Amount] = None """ Specifies the other pool asset of the AMM instance to deposit more of its value. @@ -61,10 +61,10 @@ class AMMDeposit(Transaction): def _get_errors(self: AMMDeposit) -> Dict[str, str]: errors = super()._get_errors() - if self.asset2_in is not None and self.asset1_in is None: - errors["AMMDeposit"] = "Must set `asset1_in` with `asset2_in`" - elif self.e_price is not None and self.asset1_in is None: - errors["AMMDeposit"] = "Must set `asset1_in` with `e_price`" - elif self.lp_token is None and self.asset1_in is None: - errors["AMMDeposit"] = "Must set at least `lp_token` or `asset1_in`" + if self.amount2 is not None and self.amount is None: + errors["AMMDeposit"] = "Must set `amount` with `amount2`" + elif self.e_price is not None and self.amount is None: + errors["AMMDeposit"] = "Must set `amount` with `e_price`" + elif self.lp_token is None and self.amount is None: + errors["AMMDeposit"] = "Must set at least `lp_token` or `amount`" return errors diff --git a/xrpl/models/transactions/amm_vote.py b/xrpl/models/transactions/amm_vote.py index 4262f4fce..e424916fd 100644 --- a/xrpl/models/transactions/amm_vote.py +++ b/xrpl/models/transactions/amm_vote.py @@ -5,7 +5,7 @@ from typing import Dict, Optional from xrpl.models.required import REQUIRED -from xrpl.models.transactions.amm_instance_create import AMM_MAX_TRADING_FEE +from xrpl.models.transactions.amm_create import AMM_MAX_TRADING_FEE from xrpl.models.transactions.transaction import Transaction from xrpl.models.transactions.types import TransactionType from xrpl.models.utils import require_kwargs_on_init diff --git a/xrpl/models/transactions/amm_withdraw.py b/xrpl/models/transactions/amm_withdraw.py index 1a6da74cd..0b66b4a60 100644 --- a/xrpl/models/transactions/amm_withdraw.py +++ b/xrpl/models/transactions/amm_withdraw.py @@ -21,10 +21,10 @@ class AMMWithdraw(Transaction): The following are the recommended valid combinations: - LPToken - - Asset1Out - - Asset1Out and Asset2Out - - Asset1Out and LPToken - - Asset1Out and EPrice + - Amount + - Amount and Amount2 + - Amount and LPToken + - Amount and EPrice """ amm_id: str = REQUIRED # type: ignore @@ -38,14 +38,14 @@ class AMMWithdraw(Transaction): wants to redeem or trade in. """ - asset1_out: Optional[Amount] = None + amount: Optional[Amount] = None """ Specifies one of the pools assets that the trader wants to remove. - If the asset is XRP, then the Asset1Out is a string specifying the number of drops. + If the asset is XRP, then the Amount is a string specifying the number of drops. Otherwise it is an IssuedCurrencyAmount object. """ - asset2_out: Optional[Amount] = None + amount2: Optional[Amount] = None """ Specifies the other pool asset that the trader wants to remove. """ @@ -63,10 +63,10 @@ class AMMWithdraw(Transaction): def _get_errors(self: AMMWithdraw) -> Dict[str, str]: errors = super()._get_errors() - if self.asset2_out is not None and self.asset1_out is None: - errors["AMMWithdraw"] = "Must set `asset1_out` with `asset2_out`" - elif self.e_price is not None and self.asset1_out is None: - errors["AMMWithdraw"] = "Must set `asset1_out` with `e_price`" - elif self.lp_token is None and self.asset1_out is None: - errors["AMMWithdraw"] = "Must set at least `lp_token` or `asset1_out`" + if self.amount2 is not None and self.amount is None: + errors["AMMWithdraw"] = "Must set `amount` with `amount2`" + elif self.e_price is not None and self.amount is None: + errors["AMMWithdraw"] = "Must set `amount` with `e_price`" + elif self.lp_token is None and self.amount is None: + errors["AMMWithdraw"] = "Must set at least `lp_token` or `amount`" return errors diff --git a/xrpl/models/transactions/types/transaction_type.py b/xrpl/models/transactions/types/transaction_type.py index 617be49e0..7bccc23c2 100644 --- a/xrpl/models/transactions/types/transaction_type.py +++ b/xrpl/models/transactions/types/transaction_type.py @@ -9,8 +9,8 @@ class TransactionType(str, Enum): ACCOUNT_DELETE = "AccountDelete" ACCOUNT_SET = "AccountSet" AMM_BID = "AMMBid" + AMM_CREATE = "AMMCreate" AMM_DEPOSIT = "AMMDeposit" - AMM_INSTANCE_CREATE = "AMMInstanceCreate" AMM_VOTE = "AMMVote" AMM_WITHDRAW = "AMMWithdraw" CHECK_CANCEL = "CheckCancel" From f6b1d2352a66e6f38dfae97a80d36aa03723a6e0 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 9 Nov 2022 14:53:31 -0500 Subject: [PATCH 55/88] rename amm_info param asset1 -> asset --- tests/unit/models/requests/test_amm_info.py | 14 +++++++------- xrpl/models/requests/amm_info.py | 16 ++++++++-------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/unit/models/requests/test_amm_info.py b/tests/unit/models/requests/test_amm_info.py index 919b11707..642f05284 100644 --- a/tests/unit/models/requests/test_amm_info.py +++ b/tests/unit/models/requests/test_amm_info.py @@ -18,9 +18,9 @@ def test_amm_id(self): ) self.assertTrue(request.is_valid()) - def test_asset1_asset2(self): + def test_asset_asset2(self): request = AMMInfo( - asset1=_ASSET_1, + asset=_ASSET_1, asset2=_ASSET_2, ) self.assertTrue(request.is_valid()) @@ -30,25 +30,25 @@ def test_no_params_is_invalid(self): AMMInfo() self.assertEqual( error.exception.args[0], - "{'AMMInfo': 'Must set either `amm_id` or both `asset1` and `asset2`'}", + "{'AMMInfo': 'Must set either `amm_id` or both `asset` and `asset2`'}", ) - def test_missing_asset1_is_invalid(self): + def test_missing_asset_is_invalid(self): with self.assertRaises(XRPLModelException) as error: AMMInfo( asset2=_ASSET_2, ) self.assertEqual( error.exception.args[0], - "{'AMMInfo': 'Missing `asset1`. Must set both `asset1` and `asset2`'}", + "{'AMMInfo': 'Missing `asset`. Must set both `asset` and `asset2`'}", ) def test_missing_asset2_is_invalid(self): with self.assertRaises(XRPLModelException) as error: AMMInfo( - asset1=_ASSET_1, + asset=_ASSET_1, ) self.assertEqual( error.exception.args[0], - "{'AMMInfo': 'Missing `asset2`. Must set both `asset1` and `asset2`'}", + "{'AMMInfo': 'Missing `asset2`. Must set both `asset` and `asset2`'}", ) diff --git a/xrpl/models/requests/amm_info.py b/xrpl/models/requests/amm_info.py index e4003b7b0..805f34af3 100644 --- a/xrpl/models/requests/amm_info.py +++ b/xrpl/models/requests/amm_info.py @@ -15,7 +15,7 @@ class AMMInfo(Request): """ This request retrieves information about an AMM instance. - Must provide either AMMID or both Asset1 and Asset2 params. + Must provide either AMMID or both Asset and Asset2 params. """ amm_id: Optional[str] = None @@ -23,7 +23,7 @@ class AMMInfo(Request): A hash that uniquely identifies the AMM instance. """ - asset1: Optional[Currency] = None + asset: Optional[Currency] = None """ Specifies one of the pool assets (XRP or token) of the AMM instance. """ @@ -38,16 +38,16 @@ class AMMInfo(Request): def _get_errors(self: AMMInfo) -> Dict[str, str]: errors = super()._get_errors() if self.amm_id is None: - if self.asset1 is None and self.asset2 is None: + if self.asset is None and self.asset2 is None: errors[ "AMMInfo" - ] = "Must set either `amm_id` or both `asset1` and `asset2`" - elif self.asset1 is None and self.asset2 is not None: + ] = "Must set either `amm_id` or both `asset` and `asset2`" + elif self.asset is None and self.asset2 is not None: errors[ "AMMInfo" - ] = "Missing `asset1`. Must set both `asset1` and `asset2`" - elif self.asset1 is not None and self.asset2 is None: + ] = "Missing `asset`. Must set both `asset` and `asset2`" + elif self.asset is not None and self.asset2 is None: errors[ "AMMInfo" - ] = "Missing `asset2`. Must set both `asset1` and `asset2`" + ] = "Missing `asset2`. Must set both `asset` and `asset2`" return errors From 37ea649d312cbaa6cda9e411a2310327fb1429c9 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 9 Nov 2022 15:02:22 -0500 Subject: [PATCH 56/88] change AMM_MAX_TRADING_FEE to 1% and rename fee_val to trading_fee --- tests/unit/models/test_base_model.py | 4 ++-- tests/unit/models/transactions/test_amm_create.py | 4 ++-- tests/unit/models/transactions/test_amm_vote.py | 12 ++++++------ xrpl/models/transactions/amm_create.py | 6 +++--- xrpl/models/transactions/amm_vote.py | 12 ++++++------ 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/unit/models/test_base_model.py b/tests/unit/models/test_base_model.py index c5530d0d6..de052617d 100644 --- a/tests/unit/models/test_base_model.py +++ b/tests/unit/models/test_base_model.py @@ -858,12 +858,12 @@ def test_to_xrpl_amm_vote(self): tx = AMMVote( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", - fee_val=1234, + trading_fee=234, ) expected = { "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", - "FeeVal": 1234, + "TradingFee": 234, "TransactionType": "AMMVote", "SigningPubKey": "", "Flags": 0, diff --git a/tests/unit/models/transactions/test_amm_create.py b/tests/unit/models/transactions/test_amm_create.py index 88a8fa12b..f8b3d392a 100644 --- a/tests/unit/models/transactions/test_amm_create.py +++ b/tests/unit/models/transactions/test_amm_create.py @@ -33,7 +33,7 @@ def test_trading_fee_too_high(self): ) self.assertEqual( error.exception.args[0], - "{'trading_fee': 'Must be between 0 and 65000'}", + "{'trading_fee': 'Must be between 0 and 1000'}", ) def test_trading_fee_negative_number(self): @@ -48,5 +48,5 @@ def test_trading_fee_negative_number(self): ) self.assertEqual( error.exception.args[0], - "{'trading_fee': 'Must be between 0 and 65000'}", + "{'trading_fee': 'Must be between 0 and 1000'}", ) diff --git a/tests/unit/models/transactions/test_amm_vote.py b/tests/unit/models/transactions/test_amm_vote.py index ba06cef18..624af549e 100644 --- a/tests/unit/models/transactions/test_amm_vote.py +++ b/tests/unit/models/transactions/test_amm_vote.py @@ -6,7 +6,7 @@ _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" _AMM_ID = "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883" -_FEE_VAL = 1234 +_TRADING_FEE = 234 class TestAMMVote(TestCase): @@ -14,7 +14,7 @@ def test_tx_valid(self): tx = AMMVote( account=_ACCOUNT, amm_id=_AMM_ID, - fee_val=_FEE_VAL, + trading_fee=_TRADING_FEE, ) self.assertTrue(tx.is_valid()) @@ -23,11 +23,11 @@ def test_trading_fee_too_high(self): AMMVote( account=_ACCOUNT, amm_id=_AMM_ID, - fee_val=maxsize, + trading_fee=maxsize, ) self.assertEqual( error.exception.args[0], - "{'fee_val': 'Must be between 0 and 65000'}", + "{'trading_fee': 'Must be between 0 and 1000'}", ) def test_trading_fee_negative_number(self): @@ -35,9 +35,9 @@ def test_trading_fee_negative_number(self): AMMVote( account=_ACCOUNT, amm_id=_AMM_ID, - fee_val=-1, + trading_fee=-1, ) self.assertEqual( error.exception.args[0], - "{'fee_val': 'Must be between 0 and 65000'}", + "{'trading_fee': 'Must be between 0 and 1000'}", ) diff --git a/xrpl/models/transactions/amm_create.py b/xrpl/models/transactions/amm_create.py index c834264e5..212be06df 100644 --- a/xrpl/models/transactions/amm_create.py +++ b/xrpl/models/transactions/amm_create.py @@ -12,7 +12,7 @@ from xrpl.models.transactions.types import TransactionType from xrpl.models.utils import require_kwargs_on_init -AMM_MAX_TRADING_FEE: Final[int] = 65000 +AMM_MAX_TRADING_FEE: Final[int] = 1000 @require_kwargs_on_init @@ -40,9 +40,9 @@ class AMMCreate(Transaction): Specifies the fee, in basis point, to be charged to the traders for the trades executed against the AMM instance. Trading fee is a percentage of the trading volume. - Valid values for this field are between 0 and 65000 inclusive. + Valid values for this field are between 0 and 1000 inclusive. A value of 1 is equivalent to 1/10 bps or 0.001%, allowing trading fee - between 0% and 65%. This field is required. + between 0% and 1%. This field is required. """ transaction_type: TransactionType = field( diff --git a/xrpl/models/transactions/amm_vote.py b/xrpl/models/transactions/amm_vote.py index e424916fd..6a841ae07 100644 --- a/xrpl/models/transactions/amm_vote.py +++ b/xrpl/models/transactions/amm_vote.py @@ -26,12 +26,12 @@ class AMMVote(Transaction): A hash that uniquely identifies the AMM instance. This field is required. """ - fee_val: int = REQUIRED # type: ignore + trading_fee: int = REQUIRED # type: ignore """ Specifies the fee, in basis point. - Valid values for this field are between 0 and 65000 inclusive. + Valid values for this field are between 0 and 1000 inclusive. A value of 1 is equivalent to 1/10 bps or 0.001%, allowing trading fee - between 0% and 65%. This field is required. + between 0% and 1%. This field is required. """ transaction_type: TransactionType = field( @@ -44,12 +44,12 @@ def _get_errors(self: AMMVote) -> Dict[str, str]: key: value for key, value in { **super()._get_errors(), - "fee_val": self._get_fee_val_error(), + "trading_fee": self._get_trading_fee_error(), }.items() if value is not None } - def _get_fee_val_error(self: AMMVote) -> Optional[str]: - if self.fee_val < 0 or self.fee_val > AMM_MAX_TRADING_FEE: + def _get_trading_fee_error(self: AMMVote) -> Optional[str]: + if self.trading_fee < 0 or self.trading_fee > AMM_MAX_TRADING_FEE: return f"Must be between 0 and {AMM_MAX_TRADING_FEE}" return None From c02aa8f32c9a369e6c87f71ff355ee0bc20781f8 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 9 Nov 2022 15:12:48 -0500 Subject: [PATCH 57/88] rename MinBidPrice -> BidMin and MaxBidPrice -> BidMax --- tests/unit/models/test_base_model.py | 8 ++++---- tests/unit/models/transactions/test_amm_bid.py | 4 ++-- xrpl/core/binarycodec/definitions/definitions.json | 4 ++-- xrpl/models/transactions/amm_bid.py | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/unit/models/test_base_model.py b/tests/unit/models/test_base_model.py index de052617d..f0d008dc3 100644 --- a/tests/unit/models/test_base_model.py +++ b/tests/unit/models/test_base_model.py @@ -874,12 +874,12 @@ def test_to_xrpl_amm_bid(self): tx = AMMBid( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", - min_bid_price=IssuedCurrencyAmount( + bid_min=IssuedCurrencyAmount( currency="5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", issuer="r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", value="25", ), - max_bid_price=IssuedCurrencyAmount( + bid_max=IssuedCurrencyAmount( currency="5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", issuer="r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", value="35", @@ -894,12 +894,12 @@ def test_to_xrpl_amm_bid(self): expected = { "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", - "MinBidPrice": { + "BidMin": { "currency": "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", "issuer": "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", "value": "25", }, - "MaxBidPrice": { + "BidMax": { "currency": "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", "issuer": "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", "value": "35", diff --git a/tests/unit/models/transactions/test_amm_bid.py b/tests/unit/models/transactions/test_amm_bid.py index 1e53d4348..c1142a07a 100644 --- a/tests/unit/models/transactions/test_amm_bid.py +++ b/tests/unit/models/transactions/test_amm_bid.py @@ -29,12 +29,12 @@ def test_tx_valid(self): tx = AMMBid( account=_ACCOUNT, amm_id=_AMM_ID, - min_bid_price=IssuedCurrencyAmount( + bid_min=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, value="25", ), - max_bid_price=IssuedCurrencyAmount( + bid_max=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, value="35", diff --git a/xrpl/core/binarycodec/definitions/definitions.json b/xrpl/core/binarycodec/definitions/definitions.json index 55bbac88a..b9aa434c7 100644 --- a/xrpl/core/binarycodec/definitions/definitions.json +++ b/xrpl/core/binarycodec/definitions/definitions.json @@ -1454,7 +1454,7 @@ } ], [ - "MinBidPrice", + "BidMin", { "nth": 12, "isVLEncoded": false, @@ -1464,7 +1464,7 @@ } ], [ - "MaxBidPrice", + "BidMax", { "nth": 13, "isVLEncoded": false, diff --git a/xrpl/models/transactions/amm_bid.py b/xrpl/models/transactions/amm_bid.py index 008a0a2bf..a2b5ad7e1 100644 --- a/xrpl/models/transactions/amm_bid.py +++ b/xrpl/models/transactions/amm_bid.py @@ -32,7 +32,7 @@ class AMMBid(Transaction): A hash that uniquely identifies the AMM instance. This field is required. """ - min_bid_price: Optional[Amount] = None + bid_min: Optional[Amount] = None """ This field represents the minimum price that the bidder wants to pay for the slot. It is specified in units of LPToken. If specified let MinSlotPrice be X and let @@ -40,7 +40,7 @@ class AMMBid(Transaction): the max(X, Y). """ - max_bid_price: Optional[Amount] = None + bid_max: Optional[Amount] = None """ This field represents the maximum price that the bidder wants to pay for the slot. It is specified in units of LPToken. From 91fe73efa1ac17fde32941c84e7fe9e29b512640 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 9 Nov 2022 15:19:08 -0500 Subject: [PATCH 58/88] update definitions to change Asset & Asset2 nth values to 3 & 4 --- xrpl/core/binarycodec/definitions/definitions.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xrpl/core/binarycodec/definitions/definitions.json b/xrpl/core/binarycodec/definitions/definitions.json index b9aa434c7..c9d2c4945 100644 --- a/xrpl/core/binarycodec/definitions/definitions.json +++ b/xrpl/core/binarycodec/definitions/definitions.json @@ -1966,7 +1966,7 @@ [ "Asset", { - "nth": 1, + "nth": 3, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1976,7 +1976,7 @@ [ "Asset2", { - "nth": 2, + "nth": 4, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, From 87cd9ae87f89959d98bb23af6a43b42d609f57a0 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 9 Nov 2022 16:14:00 -0500 Subject: [PATCH 59/88] Use asset/asset2 instead of amm_id for Deposit/Withdraw/Bid/Vote --- tests/unit/models/test_base_model.py | 132 ++++++++++++++---- .../unit/models/transactions/test_amm_bid.py | 9 +- .../models/transactions/test_amm_deposit.py | 27 ++-- .../unit/models/transactions/test_amm_vote.py | 12 +- .../models/transactions/test_amm_withdraw.py | 27 ++-- xrpl/models/transactions/amm_bid.py | 10 +- xrpl/models/transactions/amm_deposit.py | 10 +- xrpl/models/transactions/amm_vote.py | 10 +- xrpl/models/transactions/amm_withdraw.py | 10 +- 9 files changed, 190 insertions(+), 57 deletions(-) diff --git a/tests/unit/models/test_base_model.py b/tests/unit/models/test_base_model.py index f0d008dc3..9bd51fbed 100644 --- a/tests/unit/models/test_base_model.py +++ b/tests/unit/models/test_base_model.py @@ -634,7 +634,8 @@ def test_to_xrpl_amm_deposit_lptoken(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + asset={"currency": "XRP"}, + asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, lp_token=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", @@ -642,7 +643,13 @@ def test_to_xrpl_amm_deposit_lptoken(self): ), ) expected = { - "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Asset": { + "currency": "XRP" + }, + "Asset2": { + "currency": "ETH", + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "LPToken": { "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", @@ -660,11 +667,18 @@ def test_to_xrpl_amm_deposit_amount(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + asset={"currency": "XRP"}, + asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, amount="1000", ) expected = { - "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Asset": { + "currency": "XRP" + }, + "Asset2": { + "currency": "ETH", + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Amount": "1000", "TransactionType": "AMMDeposit", @@ -678,12 +692,19 @@ def test_to_xrpl_amm_deposit_amount_amount2(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + asset={"currency": "XRP"}, + asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, amount="1000", amount2="500", ) expected = { - "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Asset": { + "currency": "XRP" + }, + "Asset2": { + "currency": "ETH", + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Amount": "1000", "Amount2": "500", @@ -698,7 +719,8 @@ def test_to_xrpl_amm_deposit_amount_lptoken(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + asset={"currency": "XRP"}, + asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, amount="1000", lp_token=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", @@ -707,7 +729,13 @@ def test_to_xrpl_amm_deposit_amount_lptoken(self): ), ) expected = { - "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Asset": { + "currency": "XRP" + }, + "Asset2": { + "currency": "ETH", + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Amount": "1000", "LPToken": { @@ -726,12 +754,19 @@ def test_to_xrpl_amm_deposit_amount_eprice(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + asset={"currency": "XRP"}, + asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, amount="1000", e_price="25", ) expected = { - "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Asset": { + "currency": "XRP" + }, + "Asset2": { + "currency": "ETH", + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Amount": "1000", "EPrice": "25", @@ -746,7 +781,8 @@ def test_to_xrpl_amm_withdraw_lptoken(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + asset={"currency": "XRP"}, + asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, lp_token=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", @@ -754,7 +790,13 @@ def test_to_xrpl_amm_withdraw_lptoken(self): ), ) expected = { - "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Asset": { + "currency": "XRP" + }, + "Asset2": { + "currency": "ETH", + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "LPToken": { "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", @@ -772,11 +814,18 @@ def test_to_xrpl_amm_withdraw_amount(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + asset={"currency": "XRP"}, + asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, amount="1000", ) expected = { - "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Asset": { + "currency": "XRP" + }, + "Asset2": { + "currency": "ETH", + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Amount": "1000", "TransactionType": "AMMWithdraw", @@ -790,12 +839,19 @@ def test_to_xrpl_amm_withdraw_amount_amount2(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + asset={"currency": "XRP"}, + asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, amount="1000", amount2="500", ) expected = { - "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Asset": { + "currency": "XRP" + }, + "Asset2": { + "currency": "ETH", + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Amount": "1000", "Amount2": "500", @@ -810,7 +866,8 @@ def test_to_xrpl_amm_withdraw_amount_lptoken(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + asset={"currency": "XRP"}, + asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, amount="1000", lp_token=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", @@ -819,7 +876,13 @@ def test_to_xrpl_amm_withdraw_amount_lptoken(self): ), ) expected = { - "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Asset": { + "currency": "XRP" + }, + "Asset2": { + "currency": "ETH", + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Amount": "1000", "LPToken": { @@ -838,12 +901,19 @@ def test_to_xrpl_amm_withdraw_amount_eprice(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + asset={"currency": "XRP"}, + asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, amount="1000", e_price="25", ) expected = { - "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Asset": { + "currency": "XRP" + }, + "Asset2": { + "currency": "ETH", + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Amount": "1000", "EPrice": "25", @@ -857,12 +927,19 @@ def test_to_xrpl_amm_withdraw_amount_eprice(self): def test_to_xrpl_amm_vote(self): tx = AMMVote( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + asset={"currency": "XRP"}, + asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, trading_fee=234, ) expected = { "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Asset": { + "currency": "XRP" + }, + "Asset2": { + "currency": "ETH", + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + }, "TradingFee": 234, "TransactionType": "AMMVote", "SigningPubKey": "", @@ -873,7 +950,8 @@ def test_to_xrpl_amm_vote(self): def test_to_xrpl_amm_bid(self): tx = AMMBid( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - amm_id="24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + asset={"currency": "XRP"}, + asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, bid_min=IssuedCurrencyAmount( currency="5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", issuer="r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", @@ -893,7 +971,13 @@ def test_to_xrpl_amm_bid(self): ) expected = { "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "AMMID": "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883", + "Asset": { + "currency": "XRP" + }, + "Asset2": { + "currency": "ETH", + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + }, "BidMin": { "currency": "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", "issuer": "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", diff --git a/tests/unit/models/transactions/test_amm_bid.py b/tests/unit/models/transactions/test_amm_bid.py index c1142a07a..308247c12 100644 --- a/tests/unit/models/transactions/test_amm_bid.py +++ b/tests/unit/models/transactions/test_amm_bid.py @@ -5,7 +5,8 @@ from xrpl.models.transactions import AMMBid, AuthAccount _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" -_AMM_ID = "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883" +_ASSET = {"currency": "XRP"} +_ASSET2 = {"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"} _AUTH_ACCOUNTS = [ AuthAccount( account="rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh", @@ -28,7 +29,8 @@ class TestAMMBid(TestCase): def test_tx_valid(self): tx = AMMBid( account=_ACCOUNT, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, bid_min=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, @@ -53,7 +55,8 @@ def test_auth_accounts_length_error(self): with self.assertRaises(XRPLModelException) as error: AMMBid( account=_ACCOUNT, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, auth_accounts=auth_accounts, ) self.assertEqual( diff --git a/tests/unit/models/transactions/test_amm_deposit.py b/tests/unit/models/transactions/test_amm_deposit.py index a27b1c5ad..58753c06e 100644 --- a/tests/unit/models/transactions/test_amm_deposit.py +++ b/tests/unit/models/transactions/test_amm_deposit.py @@ -5,7 +5,8 @@ from xrpl.models.transactions import AMMDeposit _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" -_AMM_ID = "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883" +_ASSET = {"currency": "XRP"} +_ASSET2 = {"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"} _AMOUNT = "1000" _LPTOKEN_CURRENCY = "B3813FCAB4EE68B3D0D735D6849465A9113EE048" _LPTOKEN_ISSUER = "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg" @@ -16,7 +17,8 @@ def test_tx_valid_xrpl_lptoken(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, lp_token=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, @@ -29,7 +31,8 @@ def test_tx_valid_amount(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, amount=_AMOUNT, ) self.assertTrue(tx.is_valid()) @@ -38,7 +41,8 @@ def test_tx_valid_amount_amount2(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, amount=_AMOUNT, amount2="500", ) @@ -48,7 +52,8 @@ def test_tx_valid_amount_lptoken(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, amount=_AMOUNT, lp_token=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, @@ -62,7 +67,8 @@ def test_tx_valid_amount_eprice(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, amount=_AMOUNT, e_price="25", ) @@ -73,7 +79,8 @@ def test_undefined_amount_undefined_lptoken_invalid_combo(self): AMMDeposit( account=_ACCOUNT, sequence=1337, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, ) self.assertEqual( error.exception.args[0], @@ -85,7 +92,8 @@ def test_undefined_amount_defined_amount2_invalid_combo(self): AMMDeposit( account=_ACCOUNT, sequence=1337, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, amount2="500", ) self.assertEqual( @@ -98,7 +106,8 @@ def test_undefined_amount_defined_eprice_invalid_combo(self): AMMDeposit( account=_ACCOUNT, sequence=1337, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, e_price="25", ) self.assertEqual( diff --git a/tests/unit/models/transactions/test_amm_vote.py b/tests/unit/models/transactions/test_amm_vote.py index 624af549e..40df896bc 100644 --- a/tests/unit/models/transactions/test_amm_vote.py +++ b/tests/unit/models/transactions/test_amm_vote.py @@ -5,7 +5,8 @@ from xrpl.models.transactions import AMMVote _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" -_AMM_ID = "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883" +_ASSET = {"currency": "XRP"} +_ASSET2 = {"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"} _TRADING_FEE = 234 @@ -13,7 +14,8 @@ class TestAMMVote(TestCase): def test_tx_valid(self): tx = AMMVote( account=_ACCOUNT, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, trading_fee=_TRADING_FEE, ) self.assertTrue(tx.is_valid()) @@ -22,7 +24,8 @@ def test_trading_fee_too_high(self): with self.assertRaises(XRPLModelException) as error: AMMVote( account=_ACCOUNT, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, trading_fee=maxsize, ) self.assertEqual( @@ -34,7 +37,8 @@ def test_trading_fee_negative_number(self): with self.assertRaises(XRPLModelException) as error: AMMVote( account=_ACCOUNT, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, trading_fee=-1, ) self.assertEqual( diff --git a/tests/unit/models/transactions/test_amm_withdraw.py b/tests/unit/models/transactions/test_amm_withdraw.py index 65fd1e10d..c064f6e56 100644 --- a/tests/unit/models/transactions/test_amm_withdraw.py +++ b/tests/unit/models/transactions/test_amm_withdraw.py @@ -5,7 +5,8 @@ from xrpl.models.transactions import AMMWithdraw _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" -_AMM_ID = "24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883" +_ASSET = {"currency": "XRP"} +_ASSET2 = {"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"} _AMOUNT = "1000" _LPTOKEN_CURRENCY = "B3813FCAB4EE68B3D0D735D6849465A9113EE048" _LPTOKEN_ISSUER = "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg" @@ -16,7 +17,8 @@ def test_tx_valid_lptoken(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, lp_token=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, @@ -29,7 +31,8 @@ def test_tx_valid_amount(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, amount=_AMOUNT, ) self.assertTrue(tx.is_valid()) @@ -38,7 +41,8 @@ def test_tx_valid_amount_amount2(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, amount=_AMOUNT, amount2="500", ) @@ -48,7 +52,8 @@ def test_tx_valid_amount_lptoken(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, amount=_AMOUNT, lp_token=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, @@ -62,7 +67,8 @@ def test_tx_valid_amount_eprice(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, amount=_AMOUNT, e_price="25", ) @@ -73,7 +79,8 @@ def test_undefined_amount_undefined_lptoken_invalid_combo(self): AMMWithdraw( account=_ACCOUNT, sequence=1337, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, ) self.assertEqual( error.exception.args[0], @@ -85,7 +92,8 @@ def test_undefined_amount_defined_amount2_invalid_combo(self): AMMWithdraw( account=_ACCOUNT, sequence=1337, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, amount2="500", ) self.assertEqual( @@ -98,7 +106,8 @@ def test_undefined_amount_defined_eprice_invalid_combo(self): AMMWithdraw( account=_ACCOUNT, sequence=1337, - amm_id=_AMM_ID, + asset=_ASSET, + asset2=_ASSET2, e_price="25", ) self.assertEqual( diff --git a/xrpl/models/transactions/amm_bid.py b/xrpl/models/transactions/amm_bid.py index a2b5ad7e1..5be8062a4 100644 --- a/xrpl/models/transactions/amm_bid.py +++ b/xrpl/models/transactions/amm_bid.py @@ -7,6 +7,7 @@ from typing_extensions import Final from xrpl.models.amounts import Amount +from xrpl.models.currencies.currency import Currency from xrpl.models.auth_account import AuthAccount from xrpl.models.required import REQUIRED from xrpl.models.transactions.transaction import Transaction @@ -27,9 +28,14 @@ class AMMBid(Transaction): discounted TradingFee for a 24 hour slot. """ - amm_id: str = REQUIRED # type: ignore + asset: Currency = REQUIRED # type: ignore """ - A hash that uniquely identifies the AMM instance. This field is required. + Specifies one of the pool assets (XRP or token) of the AMM instance. + """ + + asset2: Currency = REQUIRED # type: ignore + """ + Specifies the other pool asset of the AMM instance. """ bid_min: Optional[Amount] = None diff --git a/xrpl/models/transactions/amm_deposit.py b/xrpl/models/transactions/amm_deposit.py index a0dfbd8a7..ba669ae39 100644 --- a/xrpl/models/transactions/amm_deposit.py +++ b/xrpl/models/transactions/amm_deposit.py @@ -5,6 +5,7 @@ from typing import Dict, Optional from xrpl.models.amounts import Amount, IssuedCurrencyAmount +from xrpl.models.currencies.currency import Currency from xrpl.models.required import REQUIRED from xrpl.models.transactions.transaction import Transaction from xrpl.models.transactions.types import TransactionType @@ -26,9 +27,14 @@ class AMMDeposit(Transaction): - Amount and EPrice """ - amm_id: str = REQUIRED # type: ignore + asset: Currency = REQUIRED # type: ignore """ - A hash that uniquely identifies the AMM instance. This field is required. + Specifies one of the pool assets (XRP or token) of the AMM instance. + """ + + asset2: Currency = REQUIRED # type: ignore + """ + Specifies the other pool asset of the AMM instance. """ lp_token: Optional[IssuedCurrencyAmount] = None diff --git a/xrpl/models/transactions/amm_vote.py b/xrpl/models/transactions/amm_vote.py index 6a841ae07..9ead1e3d4 100644 --- a/xrpl/models/transactions/amm_vote.py +++ b/xrpl/models/transactions/amm_vote.py @@ -4,6 +4,7 @@ from dataclasses import dataclass, field from typing import Dict, Optional +from xrpl.models.currencies.currency import Currency from xrpl.models.required import REQUIRED from xrpl.models.transactions.amm_create import AMM_MAX_TRADING_FEE from xrpl.models.transactions.transaction import Transaction @@ -21,9 +22,14 @@ class AMMVote(Transaction): transaction to vote for the trading fee for that instance. """ - amm_id: str = REQUIRED # type: ignore + asset: Currency = REQUIRED # type: ignore """ - A hash that uniquely identifies the AMM instance. This field is required. + Specifies one of the pool assets (XRP or token) of the AMM instance. + """ + + asset2: Currency = REQUIRED # type: ignore + """ + Specifies the other pool asset of the AMM instance. """ trading_fee: int = REQUIRED # type: ignore diff --git a/xrpl/models/transactions/amm_withdraw.py b/xrpl/models/transactions/amm_withdraw.py index 0b66b4a60..3f8423496 100644 --- a/xrpl/models/transactions/amm_withdraw.py +++ b/xrpl/models/transactions/amm_withdraw.py @@ -5,6 +5,7 @@ from typing import Dict, Optional from xrpl.models.amounts import Amount, IssuedCurrencyAmount +from xrpl.models.currencies.currency import Currency from xrpl.models.required import REQUIRED from xrpl.models.transactions.transaction import Transaction from xrpl.models.transactions.types import TransactionType @@ -27,9 +28,14 @@ class AMMWithdraw(Transaction): - Amount and EPrice """ - amm_id: str = REQUIRED # type: ignore + asset: Currency = REQUIRED # type: ignore """ - A hash that uniquely identifies the AMM instance. This field is required. + Specifies one of the pool assets (XRP or token) of the AMM instance. + """ + + asset2: Currency = REQUIRED # type: ignore + """ + Specifies the other pool asset of the AMM instance. """ lp_token: Optional[IssuedCurrencyAmount] = None From 02d5c899b2fa27618c85201956947a62f5abb589 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 16 Nov 2022 17:47:03 -0500 Subject: [PATCH 60/88] update definitions --- .../binarycodec/definitions/definitions.json | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/xrpl/core/binarycodec/definitions/definitions.json b/xrpl/core/binarycodec/definitions/definitions.json index c9d2c4945..ab3bc26fa 100644 --- a/xrpl/core/binarycodec/definitions/definitions.json +++ b/xrpl/core/binarycodec/definitions/definitions.json @@ -1013,26 +1013,6 @@ "type": "Hash160" } ], - [ - "TokenCurrency", - { - "nth": 5, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash160" - } - ], - [ - "TokenIssuer", - { - "nth": 6, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash160" - } - ], [ "LedgerHash", { From 559a8dc5ebd84a4dd23e0ac6a9545d37a9f9ba21 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 17 Nov 2022 09:21:22 -0500 Subject: [PATCH 61/88] add Issue type --- xrpl/core/binarycodec/types/__init__.py | 2 + xrpl/core/binarycodec/types/issue.py | 88 +++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 xrpl/core/binarycodec/types/issue.py diff --git a/xrpl/core/binarycodec/types/__init__.py b/xrpl/core/binarycodec/types/__init__.py index 9511fc29b..20ea1b4fb 100644 --- a/xrpl/core/binarycodec/types/__init__.py +++ b/xrpl/core/binarycodec/types/__init__.py @@ -7,6 +7,7 @@ from xrpl.core.binarycodec.types.hash128 import Hash128 from xrpl.core.binarycodec.types.hash160 import Hash160 from xrpl.core.binarycodec.types.hash256 import Hash256 +from xrpl.core.binarycodec.types.issue import Issue from xrpl.core.binarycodec.types.path_set import PathSet from xrpl.core.binarycodec.types.st_array import STArray from xrpl.core.binarycodec.types.st_object import STObject @@ -26,6 +27,7 @@ "Hash128", "Hash160", "Hash256", + "Issue", "PathSet", "STObject", "STArray", diff --git a/xrpl/core/binarycodec/types/issue.py b/xrpl/core/binarycodec/types/issue.py new file mode 100644 index 000000000..b4360b62a --- /dev/null +++ b/xrpl/core/binarycodec/types/issue.py @@ -0,0 +1,88 @@ +"""Codec for serializing and deserializing issued currency fields.""" + +from __future__ import annotations + +from typing import Any, Dict, Optional, Type, Union + +from xrpl.core.binarycodec.binary_wrappers.binary_parser import BinaryParser +from xrpl.core.binarycodec.exceptions import XRPLBinaryCodecException +from xrpl.core.binarycodec.types.account_id import AccountID +from xrpl.core.binarycodec.types.currency import Currency +from xrpl.core.binarycodec.types.serialized_type import SerializedType +from xrpl.models.currencies import XRP as XRPModel +from xrpl.models.currencies import IssuedCurrency as IssuedCurrencyModel + + +class Issue(SerializedType): + """Codec for serializing and deserializing issued currency fields.""" + + def __init__(self: Issue, buffer: bytes) -> None: + """Construct an Issue from given bytes.""" + super().__init__(buffer) + + @classmethod + def from_value(cls: Type[Issue], value: Dict[str, str]) -> Issue: + """ + Construct an Issue object from a string or dictionary representation + of an issued currency. + + Args: + value: The dictionary to construct an Issue object from. + + Returns: + An Issue object constructed from value. + + Raises: + XRPLBinaryCodecException: If the Issue representation is invalid. + """ + if XRPModel.is_dict_of_model(value): + currency_bytes = bytes(Currency.from_value(value["currency"])) + return cls(currency_bytes) + + if IssuedCurrencyModel.is_dict_of_model(value): + currency_bytes = bytes(Currency.from_value(value["currency"])) + issuer_bytes = bytes(AccountID.from_value(value["issuer"])) + return cls(currency_bytes + issuer_bytes) + + raise XRPLBinaryCodecException( + "Invalid type to construct an Issue: expected str or dict," + f" received {value.__class__.__name__}." + ) + + @classmethod + def from_parser( + cls: Type[Issue], + parser: BinaryParser, + length_hint: Optional[int] = None, + ) -> Issue: + """ + Construct an Issue object from an existing BinaryParser. + + Args: + parser: The parser to construct the Issue object from. + length_hint: The number of bytes to consume from the parser. + + Returns: + The Issue object constructed from a parser. + """ + currency = Currency.from_parser(parser) + if currency.to_json() == "XRP": + return cls(bytes(currency)) + + issuer = parser.read(20) # the length in bytes of an account ID + return cls(bytes(currency) + issuer) + + def to_json(self: Issue) -> Union[str, Dict[Any, Any]]: + """ + Returns the JSON representation of an issued currency. + + Returns: + The JSON representation of an Issue. + """ + parser = BinaryParser(str(self)) + currency: Union[str, Dict[Any, Any]] = Currency.from_parser(parser).to_json() + if currency == "XRP": + return {"currency": currency} + + issuer = AccountID.from_parser(parser) + return {"currency": currency, "issuer": issuer.to_json()} \ No newline at end of file From 10a242a096f8de16869a3da028fb4f7cde0894a2 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 17 Nov 2022 09:41:45 -0500 Subject: [PATCH 62/88] add flags to AMM deposit & withdraw --- .../models/transactions/test_amm_deposit.py | 6 +++++ .../models/transactions/test_amm_withdraw.py | 12 ++++++--- xrpl/models/flags.py | 16 ++++++++++++ xrpl/models/transactions/__init__.py | 16 ++++++++++-- xrpl/models/transactions/amm_deposit.py | 23 ++++++++++++++++ xrpl/models/transactions/amm_withdraw.py | 26 +++++++++++++++++++ 6 files changed, 94 insertions(+), 5 deletions(-) diff --git a/tests/unit/models/transactions/test_amm_deposit.py b/tests/unit/models/transactions/test_amm_deposit.py index 58753c06e..c7f993e7e 100644 --- a/tests/unit/models/transactions/test_amm_deposit.py +++ b/tests/unit/models/transactions/test_amm_deposit.py @@ -3,6 +3,7 @@ from xrpl.models.amounts import IssuedCurrencyAmount from xrpl.models.exceptions import XRPLModelException from xrpl.models.transactions import AMMDeposit +from xrpl.models.transactions.amm_deposit import AMMDepositFlag _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" _ASSET = {"currency": "XRP"} @@ -24,6 +25,7 @@ def test_tx_valid_xrpl_lptoken(self): issuer=_LPTOKEN_ISSUER, value=_AMOUNT, ), + flags=AMMDepositFlag.TF_LP_TOKEN, ) self.assertTrue(tx.is_valid()) @@ -34,6 +36,7 @@ def test_tx_valid_amount(self): asset=_ASSET, asset2=_ASSET2, amount=_AMOUNT, + flags=AMMDepositFlag.TF_SINGLE_ASSET, ) self.assertTrue(tx.is_valid()) @@ -45,6 +48,7 @@ def test_tx_valid_amount_amount2(self): asset2=_ASSET2, amount=_AMOUNT, amount2="500", + flags=AMMDepositFlag.TF_TWO_ASSET, ) self.assertTrue(tx.is_valid()) @@ -60,6 +64,7 @@ def test_tx_valid_amount_lptoken(self): issuer=_LPTOKEN_ISSUER, value="500", ), + flags=AMMDepositFlag.TF_ONE_ASSET_LP_TOKEN, ) self.assertTrue(tx.is_valid()) @@ -71,6 +76,7 @@ def test_tx_valid_amount_eprice(self): asset2=_ASSET2, amount=_AMOUNT, e_price="25", + flags=AMMDepositFlag.TF_LIMIT_LP_TOKEN, ) self.assertTrue(tx.is_valid()) diff --git a/tests/unit/models/transactions/test_amm_withdraw.py b/tests/unit/models/transactions/test_amm_withdraw.py index c064f6e56..c97e1eb08 100644 --- a/tests/unit/models/transactions/test_amm_withdraw.py +++ b/tests/unit/models/transactions/test_amm_withdraw.py @@ -3,6 +3,7 @@ from xrpl.models.amounts import IssuedCurrencyAmount from xrpl.models.exceptions import XRPLModelException from xrpl.models.transactions import AMMWithdraw +from xrpl.models.transactions.amm_withdraw import AMMWithdrawFlag _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" _ASSET = {"currency": "XRP"} @@ -24,6 +25,7 @@ def test_tx_valid_lptoken(self): issuer=_LPTOKEN_ISSUER, value=_AMOUNT, ), + flags=AMMWithdrawFlag.TF_LP_TOKEN, ) self.assertTrue(tx.is_valid()) @@ -34,6 +36,7 @@ def test_tx_valid_amount(self): asset=_ASSET, asset2=_ASSET2, amount=_AMOUNT, + flags=AMMWithdrawFlag.TF_SINGLE_ASSET, ) self.assertTrue(tx.is_valid()) @@ -45,6 +48,7 @@ def test_tx_valid_amount_amount2(self): asset2=_ASSET2, amount=_AMOUNT, amount2="500", + flags=AMMWithdrawFlag.TF_TWO_ASSET, ) self.assertTrue(tx.is_valid()) @@ -60,6 +64,7 @@ def test_tx_valid_amount_lptoken(self): issuer=_LPTOKEN_ISSUER, value="500", ), + flags=AMMWithdrawFlag.TF_ONE_ASSET_LP_TOKEN, ) self.assertTrue(tx.is_valid()) @@ -71,6 +76,7 @@ def test_tx_valid_amount_eprice(self): asset2=_ASSET2, amount=_AMOUNT, e_price="25", + flags=AMMWithdrawFlag.TF_LIMIT_LP_TOKEN, ) self.assertTrue(tx.is_valid()) @@ -80,7 +86,7 @@ def test_undefined_amount_undefined_lptoken_invalid_combo(self): account=_ACCOUNT, sequence=1337, asset=_ASSET, - asset2=_ASSET2, + asset2=_ASSET2, ) self.assertEqual( error.exception.args[0], @@ -93,7 +99,7 @@ def test_undefined_amount_defined_amount2_invalid_combo(self): account=_ACCOUNT, sequence=1337, asset=_ASSET, - asset2=_ASSET2, + asset2=_ASSET2, amount2="500", ) self.assertEqual( @@ -107,7 +113,7 @@ def test_undefined_amount_defined_eprice_invalid_combo(self): account=_ACCOUNT, sequence=1337, asset=_ASSET, - asset2=_ASSET2, + asset2=_ASSET2, e_price="25", ) self.assertEqual( diff --git a/xrpl/models/flags.py b/xrpl/models/flags.py index 78f4de22d..8cf3c86a3 100644 --- a/xrpl/models/flags.py +++ b/xrpl/models/flags.py @@ -21,6 +21,22 @@ "asf_require_auth": 0x00000002, "asf_require_dest": 0x00000001, }, + "AMMDeposit": { + "tf_lp_token": 0x00010000, + "tf_single_asset": 0x00080000, + "tf_two_asset": 0x00100000, + "tf_one_asset_lp_token": 0x00200000, + "tf_limit_lp_token": 0x00400000, + }, + "AMMWithdraw": { + "tf_lp_token": 0x00010000, + "tf_withdraw_all": 0x00020000, + "tf_one_asset_withdraw_all": 0x00040000, + "tf_single_asset": 0x00080000, + "tf_two_asset": 0x00100000, + "tf_one_asset_lp_token": 0x00200000, + "tf_limit_lp_token": 0x00400000, + }, "NFTokenCreateOffer": { "tf_sell_token": 0x00000001, }, diff --git a/xrpl/models/transactions/__init__.py b/xrpl/models/transactions/__init__.py index 46afafaf7..424b05200 100644 --- a/xrpl/models/transactions/__init__.py +++ b/xrpl/models/transactions/__init__.py @@ -11,9 +11,17 @@ ) from xrpl.models.transactions.amm_bid import AMMBid, AuthAccount from xrpl.models.transactions.amm_create import AMMCreate -from xrpl.models.transactions.amm_deposit import AMMDeposit +from xrpl.models.transactions.amm_deposit import ( + AMMDeposit, + AMMDepositFlag, + AMMDepositFlagInterface, +) from xrpl.models.transactions.amm_vote import AMMVote -from xrpl.models.transactions.amm_withdraw import AMMWithdraw +from xrpl.models.transactions.amm_withdraw import ( + AMMWithdraw, + AMMWithdrawFlag, + AMMWithdrawFlagInterface, +) from xrpl.models.transactions.check_cancel import CheckCancel from xrpl.models.transactions.check_cash import CheckCash from xrpl.models.transactions.check_create import CheckCreate @@ -67,8 +75,12 @@ "AMMBid", "AMMCreate", "AMMDeposit", + "AMMDepositFlag", + "AMMDepositFlagInterface", "AMMVote", "AMMWithdraw", + "AMMWithdrawFlag", + "AMMWithdrawFlagInterface", "AuthAccount", "CheckCancel", "CheckCash", diff --git a/xrpl/models/transactions/amm_deposit.py b/xrpl/models/transactions/amm_deposit.py index ba669ae39..e2cff1e9b 100644 --- a/xrpl/models/transactions/amm_deposit.py +++ b/xrpl/models/transactions/amm_deposit.py @@ -2,16 +2,39 @@ from __future__ import annotations from dataclasses import dataclass, field +from enum import Enum from typing import Dict, Optional from xrpl.models.amounts import Amount, IssuedCurrencyAmount from xrpl.models.currencies.currency import Currency +from xrpl.models.flags import FlagInterface from xrpl.models.required import REQUIRED from xrpl.models.transactions.transaction import Transaction from xrpl.models.transactions.types import TransactionType from xrpl.models.utils import require_kwargs_on_init +class AMMDepositFlag(int, Enum): + TF_LP_TOKEN = 0x00010000 + TF_SINGLE_ASSET = 0x00080000 + TF_TWO_ASSET = 0x00100000 + TF_ONE_ASSET_LP_TOKEN = 0x00200000 + TF_LIMIT_LP_TOKEN = 0x00400000 + + +class AMMDepositFlagInterface(FlagInterface): + """ + Transactions of the AMMDeposit type support additional values in the Flags field. + This TypedDict represents those options. + """ + + TF_LP_TOKEN: bool + TF_SINGLE_ASSET: bool + TF_TWO_ASSET: bool + TF_ONE_ASSET_LP_TOKEN: bool + TF_LIMIT_LP_TOKEN: bool + + @require_kwargs_on_init @dataclass(frozen=True) class AMMDeposit(Transaction): diff --git a/xrpl/models/transactions/amm_withdraw.py b/xrpl/models/transactions/amm_withdraw.py index 3f8423496..ced8058b7 100644 --- a/xrpl/models/transactions/amm_withdraw.py +++ b/xrpl/models/transactions/amm_withdraw.py @@ -2,16 +2,42 @@ from __future__ import annotations from dataclasses import dataclass, field +from enum import Enum from typing import Dict, Optional from xrpl.models.amounts import Amount, IssuedCurrencyAmount from xrpl.models.currencies.currency import Currency +from xrpl.models.flags import FlagInterface from xrpl.models.required import REQUIRED from xrpl.models.transactions.transaction import Transaction from xrpl.models.transactions.types import TransactionType from xrpl.models.utils import require_kwargs_on_init +class AMMWithdrawFlag(int, Enum): + TF_LP_TOKEN = 0x00010000 + TF_WITHDRAW_ALL = 0x00020000 + TF_ONE_ASSET_WITHDRAW_ALL = 0x00040000 + TF_SINGLE_ASSET = 0x00080000 + TF_TWO_ASSET = 0x00100000 + TF_ONE_ASSET_LP_TOKEN = 0x00200000 + TF_LIMIT_LP_TOKEN = 0x00400000 + + +class AMMWithdrawFlagInterface(FlagInterface): + """ + Transactions of the AMMWithdraw type support additional values in the Flags field. + This TypedDict represents those options. + """ + + TF_LP_TOKEN: bool + TF_WITHDRAW_ALL: bool + TF_ONE_ASSET_WITHDRAW_ALL: bool + TF_SINGLE_ASSET: bool + TF_TWO_ASSET: bool + TF_ONE_ASSET_LP_TOKEN: bool + TF_LIMIT_LP_TOKEN: bool + @require_kwargs_on_init @dataclass(frozen=True) class AMMWithdraw(Transaction): From 64dfe9e8200028c17b19c716ec67ab93eb1eafe4 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 17 Nov 2022 10:06:54 -0500 Subject: [PATCH 63/88] add Issue model --- tests/unit/models/requests/test_amm_info.py | 12 ++--- tests/unit/models/test_base_model.py | 49 ++++++++++--------- .../unit/models/transactions/test_amm_bid.py | 5 +- .../models/transactions/test_amm_deposit.py | 5 +- .../unit/models/transactions/test_amm_vote.py | 5 +- .../models/transactions/test_amm_withdraw.py | 5 +- xrpl/models/currencies/__init__.py | 2 + xrpl/models/currencies/issue.py | 49 +++++++++++++++++++ 8 files changed, 93 insertions(+), 39 deletions(-) create mode 100644 xrpl/models/currencies/issue.py diff --git a/tests/unit/models/requests/test_amm_info.py b/tests/unit/models/requests/test_amm_info.py index 642f05284..e793e6970 100644 --- a/tests/unit/models/requests/test_amm_info.py +++ b/tests/unit/models/requests/test_amm_info.py @@ -1,14 +1,12 @@ from unittest import TestCase -from xrpl.models.amounts import IssuedCurrencyAmount +from xrpl.models.currencies.issue import Issue from xrpl.models.exceptions import XRPLModelException from xrpl.models.requests import AMMInfo _AMM_ID = "5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3" -_ASSET_1 = "1000" -_ASSET_2 = IssuedCurrencyAmount( - currency="USD", issuer="rN6zcSynkRnf8zcgTVrRL8K7r4ovE7J4Zj", value="100" -) +_ASSET = Issue(currency="XRP") +_ASSET_2 = Issue(currency="USD", issuer="rN6zcSynkRnf8zcgTVrRL8K7r4ovE7J4Zj") class TestAMMInfo(TestCase): @@ -20,7 +18,7 @@ def test_amm_id(self): def test_asset_asset2(self): request = AMMInfo( - asset=_ASSET_1, + asset=_ASSET, asset2=_ASSET_2, ) self.assertTrue(request.is_valid()) @@ -46,7 +44,7 @@ def test_missing_asset_is_invalid(self): def test_missing_asset2_is_invalid(self): with self.assertRaises(XRPLModelException) as error: AMMInfo( - asset=_ASSET_1, + asset=_ASSET, ) self.assertEqual( error.exception.args[0], diff --git a/tests/unit/models/test_base_model.py b/tests/unit/models/test_base_model.py index 9bd51fbed..695843e63 100644 --- a/tests/unit/models/test_base_model.py +++ b/tests/unit/models/test_base_model.py @@ -4,6 +4,7 @@ from xrpl.models import XRPLModelException from xrpl.models.amounts import IssuedCurrencyAmount +from xrpl.models.currencies.issue import Issue from xrpl.models.requests import ( AccountChannels, BookOffers, @@ -634,8 +635,8 @@ def test_to_xrpl_amm_deposit_lptoken(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - asset={"currency": "XRP"}, - asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, + asset=Issue(currency="XRP"), + asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), lp_token=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", @@ -667,8 +668,8 @@ def test_to_xrpl_amm_deposit_amount(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - asset={"currency": "XRP"}, - asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, + asset=Issue(currency="XRP"), + asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), amount="1000", ) expected = { @@ -692,8 +693,8 @@ def test_to_xrpl_amm_deposit_amount_amount2(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - asset={"currency": "XRP"}, - asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, + asset=Issue(currency="XRP"), + asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), amount="1000", amount2="500", ) @@ -719,8 +720,8 @@ def test_to_xrpl_amm_deposit_amount_lptoken(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - asset={"currency": "XRP"}, - asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, + asset=Issue(currency="XRP"), + asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), amount="1000", lp_token=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", @@ -754,8 +755,8 @@ def test_to_xrpl_amm_deposit_amount_eprice(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - asset={"currency": "XRP"}, - asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, + asset=Issue(currency="XRP"), + asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), amount="1000", e_price="25", ) @@ -781,8 +782,8 @@ def test_to_xrpl_amm_withdraw_lptoken(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - asset={"currency": "XRP"}, - asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, + asset=Issue(currency="XRP"), + asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), lp_token=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", @@ -814,8 +815,8 @@ def test_to_xrpl_amm_withdraw_amount(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - asset={"currency": "XRP"}, - asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, + asset=Issue(currency="XRP"), + asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), amount="1000", ) expected = { @@ -839,8 +840,8 @@ def test_to_xrpl_amm_withdraw_amount_amount2(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - asset={"currency": "XRP"}, - asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, + asset=Issue(currency="XRP"), + asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), amount="1000", amount2="500", ) @@ -866,8 +867,8 @@ def test_to_xrpl_amm_withdraw_amount_lptoken(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - asset={"currency": "XRP"}, - asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, + asset=Issue(currency="XRP"), + asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), amount="1000", lp_token=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", @@ -901,8 +902,8 @@ def test_to_xrpl_amm_withdraw_amount_eprice(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - asset={"currency": "XRP"}, - asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, + asset=Issue(currency="XRP"), + asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), amount="1000", e_price="25", ) @@ -927,8 +928,8 @@ def test_to_xrpl_amm_withdraw_amount_eprice(self): def test_to_xrpl_amm_vote(self): tx = AMMVote( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - asset={"currency": "XRP"}, - asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, + asset=Issue(currency="XRP"), + asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), trading_fee=234, ) expected = { @@ -950,8 +951,8 @@ def test_to_xrpl_amm_vote(self): def test_to_xrpl_amm_bid(self): tx = AMMBid( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - asset={"currency": "XRP"}, - asset2={"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"}, + asset=Issue(currency="XRP"), + asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), bid_min=IssuedCurrencyAmount( currency="5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", issuer="r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", diff --git a/tests/unit/models/transactions/test_amm_bid.py b/tests/unit/models/transactions/test_amm_bid.py index 308247c12..d34654ec3 100644 --- a/tests/unit/models/transactions/test_amm_bid.py +++ b/tests/unit/models/transactions/test_amm_bid.py @@ -1,12 +1,13 @@ from unittest import TestCase from xrpl.models.amounts import IssuedCurrencyAmount +from xrpl.models.currencies.issue import Issue from xrpl.models.exceptions import XRPLModelException from xrpl.models.transactions import AMMBid, AuthAccount _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" -_ASSET = {"currency": "XRP"} -_ASSET2 = {"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"} +_ASSET = Issue(currency="XRP") +_ASSET2 = Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW") _AUTH_ACCOUNTS = [ AuthAccount( account="rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh", diff --git a/tests/unit/models/transactions/test_amm_deposit.py b/tests/unit/models/transactions/test_amm_deposit.py index c7f993e7e..300951f7a 100644 --- a/tests/unit/models/transactions/test_amm_deposit.py +++ b/tests/unit/models/transactions/test_amm_deposit.py @@ -1,13 +1,14 @@ from unittest import TestCase from xrpl.models.amounts import IssuedCurrencyAmount +from xrpl.models.currencies.issue import Issue from xrpl.models.exceptions import XRPLModelException from xrpl.models.transactions import AMMDeposit from xrpl.models.transactions.amm_deposit import AMMDepositFlag _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" -_ASSET = {"currency": "XRP"} -_ASSET2 = {"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"} +_ASSET = Issue(currency="XRP") +_ASSET2 = Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW") _AMOUNT = "1000" _LPTOKEN_CURRENCY = "B3813FCAB4EE68B3D0D735D6849465A9113EE048" _LPTOKEN_ISSUER = "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg" diff --git a/tests/unit/models/transactions/test_amm_vote.py b/tests/unit/models/transactions/test_amm_vote.py index 40df896bc..8b7b1271e 100644 --- a/tests/unit/models/transactions/test_amm_vote.py +++ b/tests/unit/models/transactions/test_amm_vote.py @@ -1,12 +1,13 @@ from sys import maxsize from unittest import TestCase +from xrpl.models.currencies.issue import Issue from xrpl.models.exceptions import XRPLModelException from xrpl.models.transactions import AMMVote _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" -_ASSET = {"currency": "XRP"} -_ASSET2 = {"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"} +_ASSET = Issue(currency="XRP") +_ASSET2 = Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW") _TRADING_FEE = 234 diff --git a/tests/unit/models/transactions/test_amm_withdraw.py b/tests/unit/models/transactions/test_amm_withdraw.py index c97e1eb08..0afab0e95 100644 --- a/tests/unit/models/transactions/test_amm_withdraw.py +++ b/tests/unit/models/transactions/test_amm_withdraw.py @@ -1,13 +1,14 @@ from unittest import TestCase from xrpl.models.amounts import IssuedCurrencyAmount +from xrpl.models.currencies.issue import Issue from xrpl.models.exceptions import XRPLModelException from xrpl.models.transactions import AMMWithdraw from xrpl.models.transactions.amm_withdraw import AMMWithdrawFlag _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" -_ASSET = {"currency": "XRP"} -_ASSET2 = {"currency": "ETH", "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"} +_ASSET = Issue(currency="XRP") +_ASSET2 = Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW") _AMOUNT = "1000" _LPTOKEN_CURRENCY = "B3813FCAB4EE68B3D0D735D6849465A9113EE048" _LPTOKEN_ISSUER = "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg" diff --git a/xrpl/models/currencies/__init__.py b/xrpl/models/currencies/__init__.py index 256b2b203..f883d153c 100644 --- a/xrpl/models/currencies/__init__.py +++ b/xrpl/models/currencies/__init__.py @@ -4,11 +4,13 @@ formats are different. """ from xrpl.models.currencies.currency import Currency +from xrpl.models.currencies.issue import Issue from xrpl.models.currencies.issued_currency import IssuedCurrency from xrpl.models.currencies.xrp import XRP __all__ = [ "Currency", + "Issue", "IssuedCurrency", "XRP", ] diff --git a/xrpl/models/currencies/issue.py b/xrpl/models/currencies/issue.py new file mode 100644 index 000000000..93fb4c41d --- /dev/null +++ b/xrpl/models/currencies/issue.py @@ -0,0 +1,49 @@ +""" +Specifies an Issue. +This format is used for AMM and sidechain requests. +""" +from __future__ import annotations + +from dataclasses import dataclass +from typing import Dict, Optional + +from xrpl.constants import HEX_CURRENCY_REGEX, ISO_CURRENCY_REGEX +from xrpl.models.base_model import BaseModel +from xrpl.models.required import REQUIRED +from xrpl.models.utils import require_kwargs_on_init + + +def _is_valid_currency(candidate: str) -> bool: + return bool( + ISO_CURRENCY_REGEX.fullmatch(candidate) + or HEX_CURRENCY_REGEX.fullmatch(candidate) + ) + + +@require_kwargs_on_init +@dataclass(frozen=True) +class Issue(BaseModel): + """ + Specifies an Issue. + This format is used for AMM and sidechain requests. + """ + + currency: str = REQUIRED # type: ignore + """ + This field is required. + + :meta hide-value: + """ + + issuer: Optional[str] = None + """ + The issuer of the currency. None if XRP is currency. + """ + + def _get_errors(self: Issue) -> Dict[str, str]: + errors = super()._get_errors() + if self.issuer is not None and self.currency.upper() == "XRP": + errors["currency"] = "Currency must not be XRP when issuer is set" + elif not _is_valid_currency(self.currency): + errors["currency"] = f"Invalid currency {self.currency}" + return errors From 15234d2acea3e7321927e236335b46601d83e509 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 17 Nov 2022 10:25:52 -0500 Subject: [PATCH 64/88] add Issue type to models with asset & asset2; remove amm_id --- tests/unit/models/requests/test_amm_info.py | 35 --------- tests/unit/models/test_base_model.py | 72 +++++++------------ .../unit/models/transactions/test_amm_vote.py | 2 +- xrpl/models/requests/amm_info.py | 29 ++------ xrpl/models/transactions/amm_bid.py | 6 +- xrpl/models/transactions/amm_deposit.py | 11 ++- xrpl/models/transactions/amm_vote.py | 6 +- xrpl/models/transactions/amm_withdraw.py | 12 +++- 8 files changed, 54 insertions(+), 119 deletions(-) diff --git a/tests/unit/models/requests/test_amm_info.py b/tests/unit/models/requests/test_amm_info.py index e793e6970..7e5d38432 100644 --- a/tests/unit/models/requests/test_amm_info.py +++ b/tests/unit/models/requests/test_amm_info.py @@ -4,49 +4,14 @@ from xrpl.models.exceptions import XRPLModelException from xrpl.models.requests import AMMInfo -_AMM_ID = "5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3" _ASSET = Issue(currency="XRP") _ASSET_2 = Issue(currency="USD", issuer="rN6zcSynkRnf8zcgTVrRL8K7r4ovE7J4Zj") class TestAMMInfo(TestCase): - def test_amm_id(self): - request = AMMInfo( - amm_id=_AMM_ID, - ) - self.assertTrue(request.is_valid()) - def test_asset_asset2(self): request = AMMInfo( asset=_ASSET, asset2=_ASSET_2, ) self.assertTrue(request.is_valid()) - - def test_no_params_is_invalid(self): - with self.assertRaises(XRPLModelException) as error: - AMMInfo() - self.assertEqual( - error.exception.args[0], - "{'AMMInfo': 'Must set either `amm_id` or both `asset` and `asset2`'}", - ) - - def test_missing_asset_is_invalid(self): - with self.assertRaises(XRPLModelException) as error: - AMMInfo( - asset2=_ASSET_2, - ) - self.assertEqual( - error.exception.args[0], - "{'AMMInfo': 'Missing `asset`. Must set both `asset` and `asset2`'}", - ) - - def test_missing_asset2_is_invalid(self): - with self.assertRaises(XRPLModelException) as error: - AMMInfo( - asset=_ASSET, - ) - self.assertEqual( - error.exception.args[0], - "{'AMMInfo': 'Missing `asset2`. Must set both `asset` and `asset2`'}", - ) diff --git a/tests/unit/models/test_base_model.py b/tests/unit/models/test_base_model.py index 695843e63..3e2f4cded 100644 --- a/tests/unit/models/test_base_model.py +++ b/tests/unit/models/test_base_model.py @@ -644,12 +644,10 @@ def test_to_xrpl_amm_deposit_lptoken(self): ), ) expected = { - "Asset": { - "currency": "XRP" - }, + "Asset": {"currency": "XRP"}, "Asset2": { "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "LPToken": { @@ -673,12 +671,10 @@ def test_to_xrpl_amm_deposit_amount(self): amount="1000", ) expected = { - "Asset": { - "currency": "XRP" - }, + "Asset": {"currency": "XRP"}, "Asset2": { "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Amount": "1000", @@ -699,12 +695,10 @@ def test_to_xrpl_amm_deposit_amount_amount2(self): amount2="500", ) expected = { - "Asset": { - "currency": "XRP" - }, + "Asset": {"currency": "XRP"}, "Asset2": { "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Amount": "1000", @@ -730,12 +724,10 @@ def test_to_xrpl_amm_deposit_amount_lptoken(self): ), ) expected = { - "Asset": { - "currency": "XRP" - }, + "Asset": {"currency": "XRP"}, "Asset2": { "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Amount": "1000", @@ -761,12 +753,10 @@ def test_to_xrpl_amm_deposit_amount_eprice(self): e_price="25", ) expected = { - "Asset": { - "currency": "XRP" - }, + "Asset": {"currency": "XRP"}, "Asset2": { "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Amount": "1000", @@ -791,12 +781,10 @@ def test_to_xrpl_amm_withdraw_lptoken(self): ), ) expected = { - "Asset": { - "currency": "XRP" - }, + "Asset": {"currency": "XRP"}, "Asset2": { "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "LPToken": { @@ -820,12 +808,10 @@ def test_to_xrpl_amm_withdraw_amount(self): amount="1000", ) expected = { - "Asset": { - "currency": "XRP" - }, + "Asset": {"currency": "XRP"}, "Asset2": { "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Amount": "1000", @@ -846,12 +832,10 @@ def test_to_xrpl_amm_withdraw_amount_amount2(self): amount2="500", ) expected = { - "Asset": { - "currency": "XRP" - }, + "Asset": {"currency": "XRP"}, "Asset2": { "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Amount": "1000", @@ -877,12 +861,10 @@ def test_to_xrpl_amm_withdraw_amount_lptoken(self): ), ) expected = { - "Asset": { - "currency": "XRP" - }, + "Asset": {"currency": "XRP"}, "Asset2": { "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Amount": "1000", @@ -908,12 +890,10 @@ def test_to_xrpl_amm_withdraw_amount_eprice(self): e_price="25", ) expected = { - "Asset": { - "currency": "XRP" - }, + "Asset": {"currency": "XRP"}, "Asset2": { "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Amount": "1000", @@ -934,12 +914,10 @@ def test_to_xrpl_amm_vote(self): ) expected = { "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset": { - "currency": "XRP" - }, + "Asset": {"currency": "XRP"}, "Asset2": { "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", }, "TradingFee": 234, "TransactionType": "AMMVote", @@ -972,12 +950,10 @@ def test_to_xrpl_amm_bid(self): ) expected = { "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset": { - "currency": "XRP" - }, + "Asset": {"currency": "XRP"}, "Asset2": { "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", }, "BidMin": { "currency": "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", diff --git a/tests/unit/models/transactions/test_amm_vote.py b/tests/unit/models/transactions/test_amm_vote.py index 8b7b1271e..b882b0b0f 100644 --- a/tests/unit/models/transactions/test_amm_vote.py +++ b/tests/unit/models/transactions/test_amm_vote.py @@ -1,7 +1,7 @@ from sys import maxsize from unittest import TestCase -from xrpl.models.currencies.issue import Issue +from xrpl.models.currencies.issue import Issue from xrpl.models.exceptions import XRPLModelException from xrpl.models.transactions import AMMVote diff --git a/xrpl/models/requests/amm_info.py b/xrpl/models/requests/amm_info.py index 805f34af3..2ac28d321 100644 --- a/xrpl/models/requests/amm_info.py +++ b/xrpl/models/requests/amm_info.py @@ -2,10 +2,11 @@ from __future__ import annotations from dataclasses import dataclass, field -from typing import Dict, Optional +from typing import Dict -from xrpl.models.currencies import Currency +from xrpl.models.currencies.issue import Issue from xrpl.models.requests.request import Request, RequestMethod +from xrpl.models.required import REQUIRED from xrpl.models.utils import require_kwargs_on_init @@ -15,20 +16,15 @@ class AMMInfo(Request): """ This request retrieves information about an AMM instance. - Must provide either AMMID or both Asset and Asset2 params. + Must provide Asset and Asset2 params. """ - amm_id: Optional[str] = None - """ - A hash that uniquely identifies the AMM instance. - """ - - asset: Optional[Currency] = None + asset: Issue = REQUIRED # type: ignore """ Specifies one of the pool assets (XRP or token) of the AMM instance. """ - asset2: Optional[Currency] = None + asset2: Issue = REQUIRED # type: ignore """ Specifies the other pool asset of the AMM instance. """ @@ -37,17 +33,4 @@ class AMMInfo(Request): def _get_errors(self: AMMInfo) -> Dict[str, str]: errors = super()._get_errors() - if self.amm_id is None: - if self.asset is None and self.asset2 is None: - errors[ - "AMMInfo" - ] = "Must set either `amm_id` or both `asset` and `asset2`" - elif self.asset is None and self.asset2 is not None: - errors[ - "AMMInfo" - ] = "Missing `asset`. Must set both `asset` and `asset2`" - elif self.asset is not None and self.asset2 is None: - errors[ - "AMMInfo" - ] = "Missing `asset2`. Must set both `asset` and `asset2`" return errors diff --git a/xrpl/models/transactions/amm_bid.py b/xrpl/models/transactions/amm_bid.py index 5be8062a4..f4b942c8d 100644 --- a/xrpl/models/transactions/amm_bid.py +++ b/xrpl/models/transactions/amm_bid.py @@ -7,8 +7,8 @@ from typing_extensions import Final from xrpl.models.amounts import Amount -from xrpl.models.currencies.currency import Currency from xrpl.models.auth_account import AuthAccount +from xrpl.models.currencies.issue import Issue from xrpl.models.required import REQUIRED from xrpl.models.transactions.transaction import Transaction from xrpl.models.transactions.types import TransactionType @@ -28,12 +28,12 @@ class AMMBid(Transaction): discounted TradingFee for a 24 hour slot. """ - asset: Currency = REQUIRED # type: ignore + asset: Issue = REQUIRED # type: ignore """ Specifies one of the pool assets (XRP or token) of the AMM instance. """ - asset2: Currency = REQUIRED # type: ignore + asset2: Issue = REQUIRED # type: ignore """ Specifies the other pool asset of the AMM instance. """ diff --git a/xrpl/models/transactions/amm_deposit.py b/xrpl/models/transactions/amm_deposit.py index e2cff1e9b..12046c292 100644 --- a/xrpl/models/transactions/amm_deposit.py +++ b/xrpl/models/transactions/amm_deposit.py @@ -6,7 +6,7 @@ from typing import Dict, Optional from xrpl.models.amounts import Amount, IssuedCurrencyAmount -from xrpl.models.currencies.currency import Currency +from xrpl.models.currencies.issue import Issue from xrpl.models.flags import FlagInterface from xrpl.models.required import REQUIRED from xrpl.models.transactions.transaction import Transaction @@ -15,6 +15,11 @@ class AMMDepositFlag(int, Enum): + """ + Transactions of the AMMDeposit type support additional values in the Flags field. + This enum represents those options. + """ + TF_LP_TOKEN = 0x00010000 TF_SINGLE_ASSET = 0x00080000 TF_TWO_ASSET = 0x00100000 @@ -50,12 +55,12 @@ class AMMDeposit(Transaction): - Amount and EPrice """ - asset: Currency = REQUIRED # type: ignore + asset: Issue = REQUIRED # type: ignore """ Specifies one of the pool assets (XRP or token) of the AMM instance. """ - asset2: Currency = REQUIRED # type: ignore + asset2: Issue = REQUIRED # type: ignore """ Specifies the other pool asset of the AMM instance. """ diff --git a/xrpl/models/transactions/amm_vote.py b/xrpl/models/transactions/amm_vote.py index 9ead1e3d4..3c095801e 100644 --- a/xrpl/models/transactions/amm_vote.py +++ b/xrpl/models/transactions/amm_vote.py @@ -4,7 +4,7 @@ from dataclasses import dataclass, field from typing import Dict, Optional -from xrpl.models.currencies.currency import Currency +from xrpl.models.currencies.issue import Issue from xrpl.models.required import REQUIRED from xrpl.models.transactions.amm_create import AMM_MAX_TRADING_FEE from xrpl.models.transactions.transaction import Transaction @@ -22,12 +22,12 @@ class AMMVote(Transaction): transaction to vote for the trading fee for that instance. """ - asset: Currency = REQUIRED # type: ignore + asset: Issue = REQUIRED # type: ignore """ Specifies one of the pool assets (XRP or token) of the AMM instance. """ - asset2: Currency = REQUIRED # type: ignore + asset2: Issue = REQUIRED # type: ignore """ Specifies the other pool asset of the AMM instance. """ diff --git a/xrpl/models/transactions/amm_withdraw.py b/xrpl/models/transactions/amm_withdraw.py index ced8058b7..25166ce93 100644 --- a/xrpl/models/transactions/amm_withdraw.py +++ b/xrpl/models/transactions/amm_withdraw.py @@ -6,7 +6,7 @@ from typing import Dict, Optional from xrpl.models.amounts import Amount, IssuedCurrencyAmount -from xrpl.models.currencies.currency import Currency +from xrpl.models.currencies.issue import Issue from xrpl.models.flags import FlagInterface from xrpl.models.required import REQUIRED from xrpl.models.transactions.transaction import Transaction @@ -15,6 +15,11 @@ class AMMWithdrawFlag(int, Enum): + """ + Transactions of the AMMWithdraw type support additional values in the Flags field. + This enum represents those options. + """ + TF_LP_TOKEN = 0x00010000 TF_WITHDRAW_ALL = 0x00020000 TF_ONE_ASSET_WITHDRAW_ALL = 0x00040000 @@ -38,6 +43,7 @@ class AMMWithdrawFlagInterface(FlagInterface): TF_ONE_ASSET_LP_TOKEN: bool TF_LIMIT_LP_TOKEN: bool + @require_kwargs_on_init @dataclass(frozen=True) class AMMWithdraw(Transaction): @@ -54,12 +60,12 @@ class AMMWithdraw(Transaction): - Amount and EPrice """ - asset: Currency = REQUIRED # type: ignore + asset: Issue = REQUIRED # type: ignore """ Specifies one of the pool assets (XRP or token) of the AMM instance. """ - asset2: Currency = REQUIRED # type: ignore + asset2: Issue = REQUIRED # type: ignore """ Specifies the other pool asset of the AMM instance. """ From 1f4e8caa9e6864a695245b03561f3dcfc04d025f Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 17 Nov 2022 10:30:04 -0500 Subject: [PATCH 65/88] resolve lint errors --- tests/unit/models/requests/test_amm_info.py | 1 - xrpl/core/binarycodec/types/issue.py | 10 ++++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/unit/models/requests/test_amm_info.py b/tests/unit/models/requests/test_amm_info.py index 7e5d38432..0f21394e2 100644 --- a/tests/unit/models/requests/test_amm_info.py +++ b/tests/unit/models/requests/test_amm_info.py @@ -1,7 +1,6 @@ from unittest import TestCase from xrpl.models.currencies.issue import Issue -from xrpl.models.exceptions import XRPLModelException from xrpl.models.requests import AMMInfo _ASSET = Issue(currency="XRP") diff --git a/xrpl/core/binarycodec/types/issue.py b/xrpl/core/binarycodec/types/issue.py index b4360b62a..1c5b5029a 100644 --- a/xrpl/core/binarycodec/types/issue.py +++ b/xrpl/core/binarycodec/types/issue.py @@ -17,7 +17,13 @@ class Issue(SerializedType): """Codec for serializing and deserializing issued currency fields.""" def __init__(self: Issue, buffer: bytes) -> None: - """Construct an Issue from given bytes.""" + """ + Construct an Issue from given bytes. + + Args: + buffer: The byte buffer that will be used to store the serialized + encoding of this field. + """ super().__init__(buffer) @classmethod @@ -85,4 +91,4 @@ def to_json(self: Issue) -> Union[str, Dict[Any, Any]]: return {"currency": currency} issuer = AccountID.from_parser(parser) - return {"currency": currency, "issuer": issuer.to_json()} \ No newline at end of file + return {"currency": currency, "issuer": issuer.to_json()} From e71e37e8b0279b4de622c89fb3dce443728b580c Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 17 Nov 2022 11:07:40 -0500 Subject: [PATCH 66/88] rename LPToken in amm deposit & withdraw --- tests/unit/models/test_base_model.py | 16 ++++++++-------- .../unit/models/transactions/test_amm_deposit.py | 6 +++--- .../models/transactions/test_amm_withdraw.py | 6 +++--- xrpl/models/transactions/amm_deposit.py | 8 ++++---- xrpl/models/transactions/amm_withdraw.py | 8 ++++---- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/tests/unit/models/test_base_model.py b/tests/unit/models/test_base_model.py index 3e2f4cded..db446769e 100644 --- a/tests/unit/models/test_base_model.py +++ b/tests/unit/models/test_base_model.py @@ -637,7 +637,7 @@ def test_to_xrpl_amm_deposit_lptoken(self): sequence=1337, asset=Issue(currency="XRP"), asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), - lp_token=IssuedCurrencyAmount( + lp_token_out=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", value="1000", @@ -650,7 +650,7 @@ def test_to_xrpl_amm_deposit_lptoken(self): "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "LPToken": { + "LPTokenOut": { "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000", @@ -717,7 +717,7 @@ def test_to_xrpl_amm_deposit_amount_lptoken(self): asset=Issue(currency="XRP"), asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), amount="1000", - lp_token=IssuedCurrencyAmount( + lp_token_out=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", value="500", @@ -731,7 +731,7 @@ def test_to_xrpl_amm_deposit_amount_lptoken(self): }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Amount": "1000", - "LPToken": { + "LPTokenOut": { "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "500", @@ -774,7 +774,7 @@ def test_to_xrpl_amm_withdraw_lptoken(self): sequence=1337, asset=Issue(currency="XRP"), asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), - lp_token=IssuedCurrencyAmount( + lp_token_in=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", value="1000", @@ -787,7 +787,7 @@ def test_to_xrpl_amm_withdraw_lptoken(self): "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "LPToken": { + "LPTokenIn": { "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000", @@ -854,7 +854,7 @@ def test_to_xrpl_amm_withdraw_amount_lptoken(self): asset=Issue(currency="XRP"), asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), amount="1000", - lp_token=IssuedCurrencyAmount( + lp_token_in=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", value="500", @@ -868,7 +868,7 @@ def test_to_xrpl_amm_withdraw_amount_lptoken(self): }, "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", "Amount": "1000", - "LPToken": { + "LPTokenIn": { "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "500", diff --git a/tests/unit/models/transactions/test_amm_deposit.py b/tests/unit/models/transactions/test_amm_deposit.py index 300951f7a..ad3523379 100644 --- a/tests/unit/models/transactions/test_amm_deposit.py +++ b/tests/unit/models/transactions/test_amm_deposit.py @@ -21,7 +21,7 @@ def test_tx_valid_xrpl_lptoken(self): sequence=1337, asset=_ASSET, asset2=_ASSET2, - lp_token=IssuedCurrencyAmount( + lp_token_out=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, value=_AMOUNT, @@ -60,7 +60,7 @@ def test_tx_valid_amount_lptoken(self): asset=_ASSET, asset2=_ASSET2, amount=_AMOUNT, - lp_token=IssuedCurrencyAmount( + lp_token_out=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, value="500", @@ -91,7 +91,7 @@ def test_undefined_amount_undefined_lptoken_invalid_combo(self): ) self.assertEqual( error.exception.args[0], - "{'AMMDeposit': 'Must set at least `lp_token` or `amount`'}", + "{'AMMDeposit': 'Must set at least `lp_token_out` or `amount`'}", ) def test_undefined_amount_defined_amount2_invalid_combo(self): diff --git a/tests/unit/models/transactions/test_amm_withdraw.py b/tests/unit/models/transactions/test_amm_withdraw.py index 0afab0e95..9bd0d9b15 100644 --- a/tests/unit/models/transactions/test_amm_withdraw.py +++ b/tests/unit/models/transactions/test_amm_withdraw.py @@ -21,7 +21,7 @@ def test_tx_valid_lptoken(self): sequence=1337, asset=_ASSET, asset2=_ASSET2, - lp_token=IssuedCurrencyAmount( + lp_token_in=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, value=_AMOUNT, @@ -60,7 +60,7 @@ def test_tx_valid_amount_lptoken(self): asset=_ASSET, asset2=_ASSET2, amount=_AMOUNT, - lp_token=IssuedCurrencyAmount( + lp_token_in=IssuedCurrencyAmount( currency=_LPTOKEN_CURRENCY, issuer=_LPTOKEN_ISSUER, value="500", @@ -91,7 +91,7 @@ def test_undefined_amount_undefined_lptoken_invalid_combo(self): ) self.assertEqual( error.exception.args[0], - "{'AMMWithdraw': 'Must set at least `lp_token` or `amount`'}", + "{'AMMWithdraw': 'Must set at least `lp_token_in` or `amount`'}", ) def test_undefined_amount_defined_amount2_invalid_combo(self): diff --git a/xrpl/models/transactions/amm_deposit.py b/xrpl/models/transactions/amm_deposit.py index 12046c292..4bd872605 100644 --- a/xrpl/models/transactions/amm_deposit.py +++ b/xrpl/models/transactions/amm_deposit.py @@ -48,7 +48,7 @@ class AMMDeposit(Transaction): pool, thus obtaining some share of the instance's pools in the form of LPToken. The following are the recommended valid combinations: - - LPToken + - LPTokenOut - Amount - Amount and Amount2 - Amount and LPToken @@ -65,7 +65,7 @@ class AMMDeposit(Transaction): Specifies the other pool asset of the AMM instance. """ - lp_token: Optional[IssuedCurrencyAmount] = None + lp_token_out: Optional[IssuedCurrencyAmount] = None """ Specifies the amount of shares of the AMM instance pools that the trader wants to redeem or trade in. @@ -99,6 +99,6 @@ def _get_errors(self: AMMDeposit) -> Dict[str, str]: errors["AMMDeposit"] = "Must set `amount` with `amount2`" elif self.e_price is not None and self.amount is None: errors["AMMDeposit"] = "Must set `amount` with `e_price`" - elif self.lp_token is None and self.amount is None: - errors["AMMDeposit"] = "Must set at least `lp_token` or `amount`" + elif self.lp_token_out is None and self.amount is None: + errors["AMMDeposit"] = "Must set at least `lp_token_out` or `amount`" return errors diff --git a/xrpl/models/transactions/amm_withdraw.py b/xrpl/models/transactions/amm_withdraw.py index 25166ce93..072aa1316 100644 --- a/xrpl/models/transactions/amm_withdraw.py +++ b/xrpl/models/transactions/amm_withdraw.py @@ -53,7 +53,7 @@ class AMMWithdraw(Transaction): of LPToken. The following are the recommended valid combinations: - - LPToken + - LPTokenIn - Amount - Amount and Amount2 - Amount and LPToken @@ -70,7 +70,7 @@ class AMMWithdraw(Transaction): Specifies the other pool asset of the AMM instance. """ - lp_token: Optional[IssuedCurrencyAmount] = None + lp_token_in: Optional[IssuedCurrencyAmount] = None """ Specifies the amount of shares of the AMM instance pools that the trader wants to redeem or trade in. @@ -105,6 +105,6 @@ def _get_errors(self: AMMWithdraw) -> Dict[str, str]: errors["AMMWithdraw"] = "Must set `amount` with `amount2`" elif self.e_price is not None and self.amount is None: errors["AMMWithdraw"] = "Must set `amount` with `e_price`" - elif self.lp_token is None and self.amount is None: - errors["AMMWithdraw"] = "Must set at least `lp_token` or `amount`" + elif self.lp_token_in is None and self.amount is None: + errors["AMMWithdraw"] = "Must set at least `lp_token_in` or `amount`" return errors From 08a32df4e5199e12c201577ed6f7d74668d33969 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 17 Nov 2022 11:08:31 -0500 Subject: [PATCH 67/88] update docstrings --- xrpl/models/transactions/amm_deposit.py | 2 +- xrpl/models/transactions/amm_withdraw.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/xrpl/models/transactions/amm_deposit.py b/xrpl/models/transactions/amm_deposit.py index 4bd872605..57d6c5c88 100644 --- a/xrpl/models/transactions/amm_deposit.py +++ b/xrpl/models/transactions/amm_deposit.py @@ -51,7 +51,7 @@ class AMMDeposit(Transaction): - LPTokenOut - Amount - Amount and Amount2 - - Amount and LPToken + - Amount and LPTokenOut - Amount and EPrice """ diff --git a/xrpl/models/transactions/amm_withdraw.py b/xrpl/models/transactions/amm_withdraw.py index 072aa1316..6ff148cd6 100644 --- a/xrpl/models/transactions/amm_withdraw.py +++ b/xrpl/models/transactions/amm_withdraw.py @@ -56,7 +56,7 @@ class AMMWithdraw(Transaction): - LPTokenIn - Amount - Amount and Amount2 - - Amount and LPToken + - Amount and LPTokenIn - Amount and EPrice """ From d2339add49b97d91e6b627bdb0586c8d6c95ba6c Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 17 Nov 2022 13:14:37 -0500 Subject: [PATCH 68/88] add AMM codec-fixtures --- .../fixtures/data/codec-fixtures.json | 207 ++++++++++++++++++ .../models/transactions/test_amm_deposit.py | 14 +- .../models/transactions/test_amm_withdraw.py | 14 +- 3 files changed, 225 insertions(+), 10 deletions(-) diff --git a/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json b/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json index 916454946..09903b832 100644 --- a/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json +++ b/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json @@ -4449,6 +4449,213 @@ "Flags": 0, "Sequence": 62 } + }, + { + "binary": "12002315000A220000000024000000026140000000000027106840000000000000016BD5838D7EA4C680000000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C7321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440913E39EC2BA0E5BC4C5DF1222B1AE9E76758F2B8FFEF1F056076147BB0ADC8117CD0296360DA08B3D48BE9EFC8693C03A253E0D9F166C19CA8D936F9E61A1100811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMCreate", + "TxnSignature": "913E39EC2BA0E5BC4C5DF1222B1AE9E76758F2B8FFEF1F056076147BB0ADC8117CD0296360DA08B3D48BE9EFC8693C03A253E0D9F166C19CA8D936F9E61A1100", + "Amount": "10000", + "Amount2": { + "currency": "ETH", + "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", + "value": "10000" + }, + "TradingFee": 10, + "Fee": "1", + "Flags": 0, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0" + } + }, + { + "binary": "120024220001000024000000026840000000000000016014D5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D074409EEE8CF88C668B955E7EEAB1B4A1B059EDF4F51B7F1546810F87E3E48B09237F015C651E37FB40A979E00EA21361D4E18D7A33DB7DD23070CEEAB2648AB3BB0D811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMDeposit", + "TxnSignature": "9EEE8CF88C668B955E7EEAB1B4A1B059EDF4F51B7F1546810F87E3E48B09237F015C651E37FB40A979E00EA21361D4E18D7A33DB7DD23070CEEAB2648AB3BB0D", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "LPTokenOut": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000"}, + "Fee": "1", + "Flags": 65536, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0" + } + }, + { + "binary": "120024220008000024000000026140000000000003E86840000000000000017321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440BD18A6E2B10B451F61CFADC32B59A0243702DC5DAAE556D51CB9C79981D40C78101FFA9DE6163CFBDF6E7578DF02F2AE3B8A5AB60697E0746D65064D91E8F90A811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMDeposit", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "Amount": "1000", + "Fee": "1", + "Flags": 524288, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "BD18A6E2B10B451F61CFADC32B59A0243702DC5DAAE556D51CB9C79981D40C78101FFA9DE6163CFBDF6E7578DF02F2AE3B8A5AB60697E0746D65064D91E8F90A" + } + }, + { + "binary": "120024220010000024000000026140000000000003E86840000000000000016BD511C37937E080000000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C7321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440E0B1AE32A0F731BF0CEF0D019295BD7F35B22F11A5962F65FA99EE4D38993B14B53DB11C15E36D756E282812E9015D38A6F225940A157693F43F9B795C59950F811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMDeposit", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "Amount": "1000", + "Amount2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", "value": "500"}, + "Fee": "1", + "Flags": 1048576, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "E0B1AE32A0F731BF0CEF0D019295BD7F35B22F11A5962F65FA99EE4D38993B14B53DB11C15E36D756E282812E9015D38A6F225940A157693F43F9B795C59950F" + } + }, + { + "binary": "120024220020000024000000026140000000000003E86840000000000000016014D5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440452BC59F9EE12C224EC983EFDF580F20C4A50E897105FD1FB13520D9753CFB02BD210599181574DF6AD0DB6A42C1EA48D9E48FC3D11B9008E4C76FBB163D5B00811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMDeposit", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "Amount": "1000", + "LPTokenOut": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000"}, + "Fee": "1", + "Flags": 2097152, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "452BC59F9EE12C224EC983EFDF580F20C4A50E897105FD1FB13520D9753CFB02BD210599181574DF6AD0DB6A42C1EA48D9E48FC3D11B9008E4C76FBB163D5B00" + } + }, + { + "binary": "120024220040000024000000026140000000000003E8684000000000000001601640000000000000197321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440DD6685DC586FAA6AD2D50D785900122EB147D4AC09A55D7080267A9B38180F87CEC44B823359FC3F0AC0104D47B53FFC6B80415664C3C4582672420A0100F70C811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMDeposit", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "Amount": "1000", + "EPrice": "25", + "Fee": "1", + "Flags": 4194304, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "DD6685DC586FAA6AD2D50D785900122EB147D4AC09A55D7080267A9B38180F87CEC44B823359FC3F0AC0104D47B53FFC6B80415664C3C4582672420A0100F70C" + } + }, + { + "binary": "120025220001000024000000026840000000000000016015D5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0744066944797E9F03808C9A00AAEFF786AD74FEB2E64B51A9601E89ABA820AAA15927C2E961A9CCA22C4B0D2A2B55E342BD6E297BD765B6F4D3FDCA578A3416BB505811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMWithdraw", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "LPTokenIn": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000"}, + "Fee": "1", + "Flags": 65536, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "66944797E9F03808C9A00AAEFF786AD74FEB2E64B51A9601E89ABA820AAA15927C2E961A9CCA22C4B0D2A2B55E342BD6E297BD765B6F4D3FDCA578A3416BB505" + } + }, + { + "binary": "120025220008000024000000026140000000000003E86840000000000000017321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440E30397CE7E99B13D35FFB5C66725B17F4F103675E10293C7B1D63C1BE3FA81B884BD3FBD31B52F6B811F99C5FBB5102D170EC379C268DF80DABF04E7F2DD4F0C811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMWithdraw", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "Amount": "1000", + "Fee": "1", + "Flags": 524288, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "E30397CE7E99B13D35FFB5C66725B17F4F103675E10293C7B1D63C1BE3FA81B884BD3FBD31B52F6B811F99C5FBB5102D170EC379C268DF80DABF04E7F2DD4F0C" + } + }, + { + "binary": "120025220010000024000000026140000000000003E86840000000000000016BD511C37937E080000000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C7321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440C0818312B269A4EF16C1C7EBBB74EFD1852A288BB214A714B8BE3B5F4B2F9CFDFF4F66C931B8434244A8016035B9EC9493B7CF5E0ACF4570A88DF808D79E4300811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMWithdraw", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "Amount": "1000", + "Amount2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", "value": "500"}, + "Fee": "1", + "Flags": 1048576, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "C0818312B269A4EF16C1C7EBBB74EFD1852A288BB214A714B8BE3B5F4B2F9CFDFF4F66C931B8434244A8016035B9EC9493B7CF5E0ACF4570A88DF808D79E4300" + } + }, + { + "binary": "120025220020000024000000026140000000000003E86840000000000000016015D5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0744073552B3DC7AE99DDF4E4FF0D60E6D0BE4688E3474D363603FA25DA6AD8BBA8F0E4E3EA82ADB2B57F5B9A6C379969E00095546DDA0E74FF3D0F0689351C2F8C06811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMWithdraw", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "Amount": "1000", + "LPTokenIn": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000"}, + "Fee": "1", + "Flags": 2097152, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "73552B3DC7AE99DDF4E4FF0D60E6D0BE4688E3474D363603FA25DA6AD8BBA8F0E4E3EA82ADB2B57F5B9A6C379969E00095546DDA0E74FF3D0F0689351C2F8C06" + } + }, + { + "binary": "120025220040000024000000026140000000000003E8684000000000000001601640000000000000197321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0744023BAFE5BFE58E7BF0B02B5875983D007C10796C8E62A190BF688EBE5D8A104DAD2DE7EDE995FE2E494883FD8140F38E22E3376A2F49C50EFCAA00C7499A4690E811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMWithdraw", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "Amount": "1000", + "EPrice": "25", + "Fee": "1", + "Flags": 4194304, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "23BAFE5BFE58E7BF0B02B5875983D007C10796C8E62A190BF688EBE5D8A104DAD2DE7EDE995FE2E494883FD8140F38E22E3376A2F49C50EFCAA00C7499A4690E" + } + }, + { + "binary": "120027220000000024000000026840000000000000016CD4C8E1BC9BF04000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0486DD4CC6F3B40B6C000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D074406B2A1548E6DC14681356C27CCBE7072CAB2AD8C72D0D7A045916FB0E0DBE6BF71A429CC519E9200172829D3EEF79100899D3A8710C1C3C1A2B664FD64086AD0A811462D4D845D20B4F09CFEA8BB4C01063D99FC9673EF01AE01C81149A91957F8F16BC57F3F200CD8C98375BF1791586E1F10318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMBid", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "AuthAccounts": [{"AuthAccount": {"Account": "rEaHTti4HZsMBpxTAF4ncWxkcdqDh1h6P7"}}], + "BidMax": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "35"}, + "BidMin": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "25"}, + "Fee": "1", + "Flags": 0, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "6B2A1548E6DC14681356C27CCBE7072CAB2AD8C72D0D7A045916FB0E0DBE6BF71A429CC519E9200172829D3EEF79100899D3A8710C1C3C1A2B664FD64086AD0A" + } + }, + { + "binary": "1200261500EA220000000024000000026840000000000000017321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0744072767CF9A0F5E9C9DA6BBB6E84905B0ECDF122D3E2D730843EFD377521E8E73664AD809D0A54E8C75CD1735ACB64E310BB49FDED10913FA150B8C006D4ACEC00811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMVote", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "TradingFee": 234, + "Fee": "1", + "Flags": 0, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "72767CF9A0F5E9C9DA6BBB6E84905B0ECDF122D3E2D730843EFD377521E8E73664AD809D0A54E8C75CD1735ACB64E310BB49FDED10913FA150B8C006D4ACEC00" + } } ], "ledgerData": [{ diff --git a/tests/unit/models/transactions/test_amm_deposit.py b/tests/unit/models/transactions/test_amm_deposit.py index ad3523379..63c39851d 100644 --- a/tests/unit/models/transactions/test_amm_deposit.py +++ b/tests/unit/models/transactions/test_amm_deposit.py @@ -15,7 +15,7 @@ class TestAMMDeposit(TestCase): - def test_tx_valid_xrpl_lptoken(self): + def test_tx_valid_xrpl_lptokenout(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, @@ -48,12 +48,14 @@ def test_tx_valid_amount_amount2(self): asset=_ASSET, asset2=_ASSET2, amount=_AMOUNT, - amount2="500", + amount2=IssuedCurrencyAmount( + currency=_ASSET2.currency, issuer=_ASSET2.issuer, value="500" + ), flags=AMMDepositFlag.TF_TWO_ASSET, ) self.assertTrue(tx.is_valid()) - def test_tx_valid_amount_lptoken(self): + def test_tx_valid_amount_lptokenout(self): tx = AMMDeposit( account=_ACCOUNT, sequence=1337, @@ -81,7 +83,7 @@ def test_tx_valid_amount_eprice(self): ) self.assertTrue(tx.is_valid()) - def test_undefined_amount_undefined_lptoken_invalid_combo(self): + def test_undefined_amount_undefined_lptokenout_invalid_combo(self): with self.assertRaises(XRPLModelException) as error: AMMDeposit( account=_ACCOUNT, @@ -101,7 +103,9 @@ def test_undefined_amount_defined_amount2_invalid_combo(self): sequence=1337, asset=_ASSET, asset2=_ASSET2, - amount2="500", + amount2=IssuedCurrencyAmount( + currency=_ASSET2.currency, issuer=_ASSET2.issuer, value="500" + ), ) self.assertEqual( error.exception.args[0], diff --git a/tests/unit/models/transactions/test_amm_withdraw.py b/tests/unit/models/transactions/test_amm_withdraw.py index 9bd0d9b15..7ed3145b0 100644 --- a/tests/unit/models/transactions/test_amm_withdraw.py +++ b/tests/unit/models/transactions/test_amm_withdraw.py @@ -15,7 +15,7 @@ class TestAMMWithdraw(TestCase): - def test_tx_valid_lptoken(self): + def test_tx_valid_lptokenin(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, @@ -48,12 +48,14 @@ def test_tx_valid_amount_amount2(self): asset=_ASSET, asset2=_ASSET2, amount=_AMOUNT, - amount2="500", + amount2=IssuedCurrencyAmount( + currency=_ASSET2.currency, issuer=_ASSET2.issuer, value="500" + ), flags=AMMWithdrawFlag.TF_TWO_ASSET, ) self.assertTrue(tx.is_valid()) - def test_tx_valid_amount_lptoken(self): + def test_tx_valid_amount_lptokenin(self): tx = AMMWithdraw( account=_ACCOUNT, sequence=1337, @@ -81,7 +83,7 @@ def test_tx_valid_amount_eprice(self): ) self.assertTrue(tx.is_valid()) - def test_undefined_amount_undefined_lptoken_invalid_combo(self): + def test_undefined_amount_undefined_lptokenin_invalid_combo(self): with self.assertRaises(XRPLModelException) as error: AMMWithdraw( account=_ACCOUNT, @@ -101,7 +103,9 @@ def test_undefined_amount_defined_amount2_invalid_combo(self): sequence=1337, asset=_ASSET, asset2=_ASSET2, - amount2="500", + amount2=IssuedCurrencyAmount( + currency=_ASSET2.currency, issuer=_ASSET2.issuer, value="500" + ), ) self.assertEqual( error.exception.args[0], From f47d6e57a94113f7aec87ff54f6d0c755ce114b5 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 17 Nov 2022 14:23:07 -0500 Subject: [PATCH 69/88] add one asset withdraw & withdraw all tests --- .../models/transactions/test_amm_withdraw.py | 30 ++++++++++++------- xrpl/models/transactions/amm_withdraw.py | 2 -- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/tests/unit/models/transactions/test_amm_withdraw.py b/tests/unit/models/transactions/test_amm_withdraw.py index 7ed3145b0..9129233a2 100644 --- a/tests/unit/models/transactions/test_amm_withdraw.py +++ b/tests/unit/models/transactions/test_amm_withdraw.py @@ -83,18 +83,26 @@ def test_tx_valid_amount_eprice(self): ) self.assertTrue(tx.is_valid()) - def test_undefined_amount_undefined_lptokenin_invalid_combo(self): - with self.assertRaises(XRPLModelException) as error: - AMMWithdraw( - account=_ACCOUNT, - sequence=1337, - asset=_ASSET, - asset2=_ASSET2, - ) - self.assertEqual( - error.exception.args[0], - "{'AMMWithdraw': 'Must set at least `lp_token_in` or `amount`'}", + def test_tx_valid_one_asset_withdraw_all(self): + tx = AMMWithdraw( + account=_ACCOUNT, + sequence=1337, + asset=_ASSET, + asset2=_ASSET2, + amount=_AMOUNT, + flags=AMMWithdrawFlag.TF_ONE_ASSET_WITHDRAW_ALL, + ) + self.assertTrue(tx.is_valid()) + + def test_tx_valid_withdraw_all(self): + tx = AMMWithdraw( + account=_ACCOUNT, + sequence=1337, + asset=_ASSET, + asset2=_ASSET2, + flags=AMMWithdrawFlag.TF_WITHDRAW_ALL, ) + self.assertTrue(tx.is_valid()) def test_undefined_amount_defined_amount2_invalid_combo(self): with self.assertRaises(XRPLModelException) as error: diff --git a/xrpl/models/transactions/amm_withdraw.py b/xrpl/models/transactions/amm_withdraw.py index 6ff148cd6..610e2c602 100644 --- a/xrpl/models/transactions/amm_withdraw.py +++ b/xrpl/models/transactions/amm_withdraw.py @@ -105,6 +105,4 @@ def _get_errors(self: AMMWithdraw) -> Dict[str, str]: errors["AMMWithdraw"] = "Must set `amount` with `amount2`" elif self.e_price is not None and self.amount is None: errors["AMMWithdraw"] = "Must set `amount` with `e_price`" - elif self.lp_token_in is None and self.amount is None: - errors["AMMWithdraw"] = "Must set at least `lp_token_in` or `amount`" return errors From dd20cd1800e0691eecad2983fe02681975e566ad Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Mon, 9 Jan 2023 17:30:31 -0500 Subject: [PATCH 70/88] update definitions.json with refactored error codes --- xrpl/core/binarycodec/definitions/definitions.json | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/xrpl/core/binarycodec/definitions/definitions.json b/xrpl/core/binarycodec/definitions/definitions.json index ab3bc26fa..e5ecefb48 100644 --- a/xrpl/core/binarycodec/definitions/definitions.json +++ b/xrpl/core/binarycodec/definitions/definitions.json @@ -2417,8 +2417,7 @@ "temUNKNOWN": -264, "temSEQ_AND_TICKET": -263, "temBAD_NFTOKEN_TRANSFER_FEE": -262, - "temBAD_AMM_OPTIONS": -261, - "temBAD_AMM_TOKENS": -260, + "temAMM_BAD_TOKENS": -261, "tefFAILURE": -199, "tefALREADY": -198, @@ -2504,14 +2503,13 @@ "tecINSUFFICIENT_FUNDS": 159, "tecOBJECT_NOT_FOUND": 160, "tecINSUFFICIENT_PAYMENT": 161, - "tecUNFUNDED_AMM": 162, + "tecAMM_UNFUNDED": 162, "tecAMM_BALANCE": 163, "tecAMM_FAILED_DEPOSIT": 164, "tecAMM_FAILED_WITHDRAW": 165, "tecAMM_INVALID_TOKENS": 166, - "tecAMM_EXISTS": 167, - "tecAMM_FAILED_BID": 168, - "tecAMM_FAILED_VOTE": 169 + "tecAMM_FAILED_BID": 167, + "tecAMM_FAILED_VOTE": 168 }, "TRANSACTION_TYPES": { "Invalid": -1, From 8a9d16fbfd33d5043f3695972e4f4706e5ee901a Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 15 Feb 2023 18:36:41 -0500 Subject: [PATCH 71/88] add Owner Reserve Fee for AMMCreate transaction --- xrpl/asyncio/transaction/main.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/xrpl/asyncio/transaction/main.py b/xrpl/asyncio/transaction/main.py index 803e887bf..4765e3381 100644 --- a/xrpl/asyncio/transaction/main.py +++ b/xrpl/asyncio/transaction/main.py @@ -25,7 +25,7 @@ _LEDGER_OFFSET: Final[int] = 20 # TODO: make this dynamic based on the current ledger fee -_ACCOUNT_DELETE_FEE: Final[int] = int(xrp_to_drops(2)) +_OWNER_RESERVE_FEE: Final[int] = int(xrp_to_drops(2)) async def sign_and_submit( @@ -355,11 +355,14 @@ async def _calculate_fee_per_transaction_type( base_fee = math.ceil(net_fee * (33 + (len(fulfillment_bytes) / 16))) # AccountDelete Transaction - if transaction.transaction_type == TransactionType.ACCOUNT_DELETE: + if ( + transaction.transaction_type == TransactionType.ACCOUNT_DELETE + or transaction.transaction_type == TransactionType.AMM_CREATE + ): if client is None: - base_fee = _ACCOUNT_DELETE_FEE + base_fee = _OWNER_RESERVE_FEE else: - base_fee = await _fetch_account_delete_fee(client) + base_fee = await _fetch_owner_reserve_fee(client) # Multi-signed Transaction # 10 drops × (1 + Number of Signatures Provided) @@ -369,7 +372,7 @@ async def _calculate_fee_per_transaction_type( return str(math.ceil(base_fee)) -async def _fetch_account_delete_fee(client: Client) -> int: +async def _fetch_owner_reserve_fee(client: Client) -> int: server_state = await client._request_impl(ServerState()) fee = server_state.result["state"]["validated_ledger"]["reserve_inc"] return int(fee) From 2899551d363147282a434c9486380e0f465284ac Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 23 Feb 2023 13:35:24 -0500 Subject: [PATCH 72/88] refactor asset pair to be Currency type --- tests/unit/models/transactions/test_amm_bid.py | 6 +++--- tests/unit/models/transactions/test_amm_deposit.py | 6 +++--- tests/unit/models/transactions/test_amm_vote.py | 6 +++--- tests/unit/models/transactions/test_amm_withdraw.py | 6 +++--- xrpl/models/transactions/amm_bid.py | 6 +++--- xrpl/models/transactions/amm_deposit.py | 6 +++--- xrpl/models/transactions/amm_vote.py | 6 +++--- xrpl/models/transactions/amm_withdraw.py | 6 +++--- 8 files changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/unit/models/transactions/test_amm_bid.py b/tests/unit/models/transactions/test_amm_bid.py index d34654ec3..21a33f9ba 100644 --- a/tests/unit/models/transactions/test_amm_bid.py +++ b/tests/unit/models/transactions/test_amm_bid.py @@ -1,13 +1,13 @@ from unittest import TestCase from xrpl.models.amounts import IssuedCurrencyAmount -from xrpl.models.currencies.issue import Issue +from xrpl.models.currencies import XRP, IssuedCurrency from xrpl.models.exceptions import XRPLModelException from xrpl.models.transactions import AMMBid, AuthAccount _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" -_ASSET = Issue(currency="XRP") -_ASSET2 = Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW") +_ASSET = XRP() +_ASSET2 = IssuedCurrency(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW") _AUTH_ACCOUNTS = [ AuthAccount( account="rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh", diff --git a/tests/unit/models/transactions/test_amm_deposit.py b/tests/unit/models/transactions/test_amm_deposit.py index 63c39851d..d39d94aeb 100644 --- a/tests/unit/models/transactions/test_amm_deposit.py +++ b/tests/unit/models/transactions/test_amm_deposit.py @@ -1,14 +1,14 @@ from unittest import TestCase from xrpl.models.amounts import IssuedCurrencyAmount -from xrpl.models.currencies.issue import Issue +from xrpl.models.currencies import XRP, IssuedCurrency from xrpl.models.exceptions import XRPLModelException from xrpl.models.transactions import AMMDeposit from xrpl.models.transactions.amm_deposit import AMMDepositFlag _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" -_ASSET = Issue(currency="XRP") -_ASSET2 = Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW") +_ASSET = XRP() +_ASSET2 = IssuedCurrency(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW") _AMOUNT = "1000" _LPTOKEN_CURRENCY = "B3813FCAB4EE68B3D0D735D6849465A9113EE048" _LPTOKEN_ISSUER = "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg" diff --git a/tests/unit/models/transactions/test_amm_vote.py b/tests/unit/models/transactions/test_amm_vote.py index b882b0b0f..45c28bc7e 100644 --- a/tests/unit/models/transactions/test_amm_vote.py +++ b/tests/unit/models/transactions/test_amm_vote.py @@ -1,13 +1,13 @@ from sys import maxsize from unittest import TestCase -from xrpl.models.currencies.issue import Issue +from xrpl.models.currencies import XRP, IssuedCurrency from xrpl.models.exceptions import XRPLModelException from xrpl.models.transactions import AMMVote _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" -_ASSET = Issue(currency="XRP") -_ASSET2 = Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW") +_ASSET = XRP() +_ASSET2 = IssuedCurrency(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW") _TRADING_FEE = 234 diff --git a/tests/unit/models/transactions/test_amm_withdraw.py b/tests/unit/models/transactions/test_amm_withdraw.py index 9129233a2..aae365a25 100644 --- a/tests/unit/models/transactions/test_amm_withdraw.py +++ b/tests/unit/models/transactions/test_amm_withdraw.py @@ -1,14 +1,14 @@ from unittest import TestCase from xrpl.models.amounts import IssuedCurrencyAmount -from xrpl.models.currencies.issue import Issue +from xrpl.models.currencies import XRP, IssuedCurrency from xrpl.models.exceptions import XRPLModelException from xrpl.models.transactions import AMMWithdraw from xrpl.models.transactions.amm_withdraw import AMMWithdrawFlag _ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" -_ASSET = Issue(currency="XRP") -_ASSET2 = Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW") +_ASSET = XRP() +_ASSET2 = IssuedCurrency(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW") _AMOUNT = "1000" _LPTOKEN_CURRENCY = "B3813FCAB4EE68B3D0D735D6849465A9113EE048" _LPTOKEN_ISSUER = "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg" diff --git a/xrpl/models/transactions/amm_bid.py b/xrpl/models/transactions/amm_bid.py index f4b942c8d..63dc6a9a5 100644 --- a/xrpl/models/transactions/amm_bid.py +++ b/xrpl/models/transactions/amm_bid.py @@ -8,7 +8,7 @@ from xrpl.models.amounts import Amount from xrpl.models.auth_account import AuthAccount -from xrpl.models.currencies.issue import Issue +from xrpl.models.currencies import Currency from xrpl.models.required import REQUIRED from xrpl.models.transactions.transaction import Transaction from xrpl.models.transactions.types import TransactionType @@ -28,12 +28,12 @@ class AMMBid(Transaction): discounted TradingFee for a 24 hour slot. """ - asset: Issue = REQUIRED # type: ignore + asset: Currency = REQUIRED # type: ignore """ Specifies one of the pool assets (XRP or token) of the AMM instance. """ - asset2: Issue = REQUIRED # type: ignore + asset2: Currency = REQUIRED # type: ignore """ Specifies the other pool asset of the AMM instance. """ diff --git a/xrpl/models/transactions/amm_deposit.py b/xrpl/models/transactions/amm_deposit.py index 57d6c5c88..f8c592e18 100644 --- a/xrpl/models/transactions/amm_deposit.py +++ b/xrpl/models/transactions/amm_deposit.py @@ -6,7 +6,7 @@ from typing import Dict, Optional from xrpl.models.amounts import Amount, IssuedCurrencyAmount -from xrpl.models.currencies.issue import Issue +from xrpl.models.currencies import Currency from xrpl.models.flags import FlagInterface from xrpl.models.required import REQUIRED from xrpl.models.transactions.transaction import Transaction @@ -55,12 +55,12 @@ class AMMDeposit(Transaction): - Amount and EPrice """ - asset: Issue = REQUIRED # type: ignore + asset: Currency = REQUIRED # type: ignore """ Specifies one of the pool assets (XRP or token) of the AMM instance. """ - asset2: Issue = REQUIRED # type: ignore + asset2: Currency = REQUIRED # type: ignore """ Specifies the other pool asset of the AMM instance. """ diff --git a/xrpl/models/transactions/amm_vote.py b/xrpl/models/transactions/amm_vote.py index 3c095801e..5a794a802 100644 --- a/xrpl/models/transactions/amm_vote.py +++ b/xrpl/models/transactions/amm_vote.py @@ -4,7 +4,7 @@ from dataclasses import dataclass, field from typing import Dict, Optional -from xrpl.models.currencies.issue import Issue +from xrpl.models.currencies import Currency from xrpl.models.required import REQUIRED from xrpl.models.transactions.amm_create import AMM_MAX_TRADING_FEE from xrpl.models.transactions.transaction import Transaction @@ -22,12 +22,12 @@ class AMMVote(Transaction): transaction to vote for the trading fee for that instance. """ - asset: Issue = REQUIRED # type: ignore + asset: Currency = REQUIRED # type: ignore """ Specifies one of the pool assets (XRP or token) of the AMM instance. """ - asset2: Issue = REQUIRED # type: ignore + asset2: Currency = REQUIRED # type: ignore """ Specifies the other pool asset of the AMM instance. """ diff --git a/xrpl/models/transactions/amm_withdraw.py b/xrpl/models/transactions/amm_withdraw.py index 610e2c602..d66876520 100644 --- a/xrpl/models/transactions/amm_withdraw.py +++ b/xrpl/models/transactions/amm_withdraw.py @@ -6,7 +6,7 @@ from typing import Dict, Optional from xrpl.models.amounts import Amount, IssuedCurrencyAmount -from xrpl.models.currencies.issue import Issue +from xrpl.models.currencies import Currency from xrpl.models.flags import FlagInterface from xrpl.models.required import REQUIRED from xrpl.models.transactions.transaction import Transaction @@ -60,12 +60,12 @@ class AMMWithdraw(Transaction): - Amount and EPrice """ - asset: Issue = REQUIRED # type: ignore + asset: Currency = REQUIRED # type: ignore """ Specifies one of the pool assets (XRP or token) of the AMM instance. """ - asset2: Issue = REQUIRED # type: ignore + asset2: Currency = REQUIRED # type: ignore """ Specifies the other pool asset of the AMM instance. """ From ac83c65dff737e69ecaeb8197d987a4b3dc980c6 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 23 Feb 2023 13:49:23 -0500 Subject: [PATCH 73/88] update amm_info asset pair to be Currency type and remove Issue model --- tests/unit/models/requests/test_amm_info.py | 6 +- tests/unit/models/test_base_model.py | 74 ++++++++++++++------- xrpl/models/currencies/__init__.py | 2 - xrpl/models/currencies/issue.py | 49 -------------- xrpl/models/requests/amm_info.py | 6 +- 5 files changed, 55 insertions(+), 82 deletions(-) delete mode 100644 xrpl/models/currencies/issue.py diff --git a/tests/unit/models/requests/test_amm_info.py b/tests/unit/models/requests/test_amm_info.py index 0f21394e2..a4d6a9e52 100644 --- a/tests/unit/models/requests/test_amm_info.py +++ b/tests/unit/models/requests/test_amm_info.py @@ -1,10 +1,10 @@ from unittest import TestCase -from xrpl.models.currencies.issue import Issue +from xrpl.models.currencies import XRP, IssuedCurrency from xrpl.models.requests import AMMInfo -_ASSET = Issue(currency="XRP") -_ASSET_2 = Issue(currency="USD", issuer="rN6zcSynkRnf8zcgTVrRL8K7r4ovE7J4Zj") +_ASSET = XRP() +_ASSET_2 = IssuedCurrency(currency="USD", issuer="rN6zcSynkRnf8zcgTVrRL8K7r4ovE7J4Zj") class TestAMMInfo(TestCase): diff --git a/tests/unit/models/test_base_model.py b/tests/unit/models/test_base_model.py index db446769e..e727ada65 100644 --- a/tests/unit/models/test_base_model.py +++ b/tests/unit/models/test_base_model.py @@ -4,7 +4,7 @@ from xrpl.models import XRPLModelException from xrpl.models.amounts import IssuedCurrencyAmount -from xrpl.models.currencies.issue import Issue +from xrpl.models.currencies import XRP, IssuedCurrency from xrpl.models.requests import ( AccountChannels, BookOffers, @@ -635,8 +635,10 @@ def test_to_xrpl_amm_deposit_lptoken(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - asset=Issue(currency="XRP"), - asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), + asset=XRP(), + asset2=IssuedCurrency( + currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + ), lp_token_out=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", @@ -666,8 +668,10 @@ def test_to_xrpl_amm_deposit_amount(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - asset=Issue(currency="XRP"), - asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), + asset=XRP(), + asset2=IssuedCurrency( + currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + ), amount="1000", ) expected = { @@ -689,8 +693,10 @@ def test_to_xrpl_amm_deposit_amount_amount2(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - asset=Issue(currency="XRP"), - asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), + asset=XRP(), + asset2=IssuedCurrency( + currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + ), amount="1000", amount2="500", ) @@ -714,8 +720,10 @@ def test_to_xrpl_amm_deposit_amount_lptoken(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - asset=Issue(currency="XRP"), - asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), + asset=XRP(), + asset2=IssuedCurrency( + currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + ), amount="1000", lp_token_out=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", @@ -747,8 +755,10 @@ def test_to_xrpl_amm_deposit_amount_eprice(self): tx = AMMDeposit( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - asset=Issue(currency="XRP"), - asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), + asset=XRP(), + asset2=IssuedCurrency( + currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + ), amount="1000", e_price="25", ) @@ -772,8 +782,10 @@ def test_to_xrpl_amm_withdraw_lptoken(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - asset=Issue(currency="XRP"), - asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), + asset=XRP(), + asset2=IssuedCurrency( + currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + ), lp_token_in=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", @@ -803,8 +815,10 @@ def test_to_xrpl_amm_withdraw_amount(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - asset=Issue(currency="XRP"), - asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), + asset=XRP(), + asset2=IssuedCurrency( + currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + ), amount="1000", ) expected = { @@ -826,8 +840,10 @@ def test_to_xrpl_amm_withdraw_amount_amount2(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - asset=Issue(currency="XRP"), - asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), + asset=XRP(), + asset2=IssuedCurrency( + currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + ), amount="1000", amount2="500", ) @@ -851,8 +867,10 @@ def test_to_xrpl_amm_withdraw_amount_lptoken(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - asset=Issue(currency="XRP"), - asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), + asset=XRP(), + asset2=IssuedCurrency( + currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + ), amount="1000", lp_token_in=IssuedCurrencyAmount( currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", @@ -884,8 +902,10 @@ def test_to_xrpl_amm_withdraw_amount_eprice(self): tx = AMMWithdraw( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", sequence=1337, - asset=Issue(currency="XRP"), - asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), + asset=XRP(), + asset2=IssuedCurrency( + currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + ), amount="1000", e_price="25", ) @@ -908,8 +928,10 @@ def test_to_xrpl_amm_withdraw_amount_eprice(self): def test_to_xrpl_amm_vote(self): tx = AMMVote( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - asset=Issue(currency="XRP"), - asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), + asset=XRP(), + asset2=IssuedCurrency( + currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + ), trading_fee=234, ) expected = { @@ -929,8 +951,10 @@ def test_to_xrpl_amm_vote(self): def test_to_xrpl_amm_bid(self): tx = AMMBid( account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - asset=Issue(currency="XRP"), - asset2=Issue(currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW"), + asset=XRP(), + asset2=IssuedCurrency( + currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + ), bid_min=IssuedCurrencyAmount( currency="5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", issuer="r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", diff --git a/xrpl/models/currencies/__init__.py b/xrpl/models/currencies/__init__.py index f883d153c..256b2b203 100644 --- a/xrpl/models/currencies/__init__.py +++ b/xrpl/models/currencies/__init__.py @@ -4,13 +4,11 @@ formats are different. """ from xrpl.models.currencies.currency import Currency -from xrpl.models.currencies.issue import Issue from xrpl.models.currencies.issued_currency import IssuedCurrency from xrpl.models.currencies.xrp import XRP __all__ = [ "Currency", - "Issue", "IssuedCurrency", "XRP", ] diff --git a/xrpl/models/currencies/issue.py b/xrpl/models/currencies/issue.py deleted file mode 100644 index 93fb4c41d..000000000 --- a/xrpl/models/currencies/issue.py +++ /dev/null @@ -1,49 +0,0 @@ -""" -Specifies an Issue. -This format is used for AMM and sidechain requests. -""" -from __future__ import annotations - -from dataclasses import dataclass -from typing import Dict, Optional - -from xrpl.constants import HEX_CURRENCY_REGEX, ISO_CURRENCY_REGEX -from xrpl.models.base_model import BaseModel -from xrpl.models.required import REQUIRED -from xrpl.models.utils import require_kwargs_on_init - - -def _is_valid_currency(candidate: str) -> bool: - return bool( - ISO_CURRENCY_REGEX.fullmatch(candidate) - or HEX_CURRENCY_REGEX.fullmatch(candidate) - ) - - -@require_kwargs_on_init -@dataclass(frozen=True) -class Issue(BaseModel): - """ - Specifies an Issue. - This format is used for AMM and sidechain requests. - """ - - currency: str = REQUIRED # type: ignore - """ - This field is required. - - :meta hide-value: - """ - - issuer: Optional[str] = None - """ - The issuer of the currency. None if XRP is currency. - """ - - def _get_errors(self: Issue) -> Dict[str, str]: - errors = super()._get_errors() - if self.issuer is not None and self.currency.upper() == "XRP": - errors["currency"] = "Currency must not be XRP when issuer is set" - elif not _is_valid_currency(self.currency): - errors["currency"] = f"Invalid currency {self.currency}" - return errors diff --git a/xrpl/models/requests/amm_info.py b/xrpl/models/requests/amm_info.py index 2ac28d321..44d00e221 100644 --- a/xrpl/models/requests/amm_info.py +++ b/xrpl/models/requests/amm_info.py @@ -4,7 +4,7 @@ from dataclasses import dataclass, field from typing import Dict -from xrpl.models.currencies.issue import Issue +from xrpl.models.currencies import Currency from xrpl.models.requests.request import Request, RequestMethod from xrpl.models.required import REQUIRED from xrpl.models.utils import require_kwargs_on_init @@ -19,12 +19,12 @@ class AMMInfo(Request): Must provide Asset and Asset2 params. """ - asset: Issue = REQUIRED # type: ignore + asset: Currency = REQUIRED # type: ignore """ Specifies one of the pool assets (XRP or token) of the AMM instance. """ - asset2: Issue = REQUIRED # type: ignore + asset2: Currency = REQUIRED # type: ignore """ Specifies the other pool asset of the AMM instance. """ From 771519fb5b5db8f331f0438a6a768fb195ecf1bc Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 23 May 2023 16:26:37 -0400 Subject: [PATCH 74/88] update definitions and codec-fixtures --- .../fixtures/data/codec-fixtures.json | 156 +++++++++--------- .../binarycodec/definitions/definitions.json | 85 +++++++--- 2 files changed, 142 insertions(+), 99 deletions(-) diff --git a/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json b/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json index 09903b832..14082315e 100644 --- a/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json +++ b/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json @@ -4451,11 +4451,11 @@ } }, { - "binary": "12002315000A220000000024000000026140000000000027106840000000000000016BD5838D7EA4C680000000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C7321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440913E39EC2BA0E5BC4C5DF1222B1AE9E76758F2B8FFEF1F056076147BB0ADC8117CD0296360DA08B3D48BE9EFC8693C03A253E0D9F166C19CA8D936F9E61A1100811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E", + "binary": "12002315000A2200000000240015DAE161400000000000271068400000000000000A6BD5838D7EA4C680000000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C7321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440B3154D968314FCEB58001E1B0C3A4CFB33DF9FF6C73207E5EAEB9BD07E2747672168E1A2786D950495C38BD8DEE3391BF45F3008DD36F4B12E7C07D82CA5250E8114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A", "json": { - "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw", "TransactionType": "AMMCreate", - "TxnSignature": "913E39EC2BA0E5BC4C5DF1222B1AE9E76758F2B8FFEF1F056076147BB0ADC8117CD0296360DA08B3D48BE9EFC8693C03A253E0D9F166C19CA8D936F9E61A1100", + "TxnSignature": "B3154D968314FCEB58001E1B0C3A4CFB33DF9FF6C73207E5EAEB9BD07E2747672168E1A2786D950495C38BD8DEE3391BF45F3008DD36F4B12E7C07D82CA5250E", "Amount": "10000", "Amount2": { "currency": "ETH", @@ -4463,198 +4463,198 @@ "value": "10000" }, "TradingFee": 10, - "Fee": "1", + "Fee": "10", "Flags": 0, - "Sequence": 2, - "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0" + "Sequence": 1432289, + "SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8" } }, { - "binary": "120024220001000024000000026840000000000000016014D5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D074409EEE8CF88C668B955E7EEAB1B4A1B059EDF4F51B7F1546810F87E3E48B09237F015C651E37FB40A979E00EA21361D4E18D7A33DB7DD23070CEEAB2648AB3BB0D811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "binary": "1200242200010000240015DAE168400000000000000A6019D5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B874408073C588E7EF672DD171E414638D9AF8DBE9A1359E030DE3E1C9AA6A38A2CE9E138CB56482BB844F7228D48B1E4AD7D09BB7E9F639C115958EEEA374749CA00B8114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", "json": { - "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw", "TransactionType": "AMMDeposit", - "TxnSignature": "9EEE8CF88C668B955E7EEAB1B4A1B059EDF4F51B7F1546810F87E3E48B09237F015C651E37FB40A979E00EA21361D4E18D7A33DB7DD23070CEEAB2648AB3BB0D", + "TxnSignature": "8073C588E7EF672DD171E414638D9AF8DBE9A1359E030DE3E1C9AA6A38A2CE9E138CB56482BB844F7228D48B1E4AD7D09BB7E9F639C115958EEEA374749CA00B", "Asset": {"currency": "XRP"}, "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, "LPTokenOut": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000"}, - "Fee": "1", + "Fee": "10", "Flags": 65536, - "Sequence": 2, - "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0" + "Sequence": 1432289, + "SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8" } }, { - "binary": "120024220008000024000000026140000000000003E86840000000000000017321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440BD18A6E2B10B451F61CFADC32B59A0243702DC5DAAE556D51CB9C79981D40C78101FFA9DE6163CFBDF6E7578DF02F2AE3B8A5AB60697E0746D65064D91E8F90A811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "binary": "1200242200080000240015DAE16140000000000003E868400000000000000A7321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8744096CA066F42871C55088D2758D64148921B1ACAA5C6C648D0F7D675BBF47F87DF711F17C5BD172666D5AEC257520C587A849A6E063345609D91E121A78816EB048114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", "json": { - "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw", "TransactionType": "AMMDeposit", "Asset": {"currency": "XRP"}, "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, "Amount": "1000", - "Fee": "1", + "Fee": "10", "Flags": 524288, - "Sequence": 2, - "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", - "TxnSignature": "BD18A6E2B10B451F61CFADC32B59A0243702DC5DAAE556D51CB9C79981D40C78101FFA9DE6163CFBDF6E7578DF02F2AE3B8A5AB60697E0746D65064D91E8F90A" + "Sequence": 1432289, + "SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8", + "TxnSignature": "96CA066F42871C55088D2758D64148921B1ACAA5C6C648D0F7D675BBF47F87DF711F17C5BD172666D5AEC257520C587A849A6E063345609D91E121A78816EB04" } }, { - "binary": "120024220010000024000000026140000000000003E86840000000000000016BD511C37937E080000000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C7321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440E0B1AE32A0F731BF0CEF0D019295BD7F35B22F11A5962F65FA99EE4D38993B14B53DB11C15E36D756E282812E9015D38A6F225940A157693F43F9B795C59950F811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "binary": "1200242200100000240015DAE16140000000000003E868400000000000000A6BD511C37937E080000000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C7321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440FC22B16A098C236ED7EDB3EBC983026DFD218A03C8BAA848F3E1D5389D5B8B00473C1178C5BA257BFA2DCD433C414690A430A5CFD71C1C0A7F7BF725EC1759018114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", "json": { - "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw", "TransactionType": "AMMDeposit", "Asset": {"currency": "XRP"}, "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, "Amount": "1000", "Amount2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", "value": "500"}, - "Fee": "1", + "Fee": "10", "Flags": 1048576, - "Sequence": 2, - "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", - "TxnSignature": "E0B1AE32A0F731BF0CEF0D019295BD7F35B22F11A5962F65FA99EE4D38993B14B53DB11C15E36D756E282812E9015D38A6F225940A157693F43F9B795C59950F" + "Sequence": 1432289, + "SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8", + "TxnSignature": "FC22B16A098C236ED7EDB3EBC983026DFD218A03C8BAA848F3E1D5389D5B8B00473C1178C5BA257BFA2DCD433C414690A430A5CFD71C1C0A7F7BF725EC175901" } }, { - "binary": "120024220020000024000000026140000000000003E86840000000000000016014D5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440452BC59F9EE12C224EC983EFDF580F20C4A50E897105FD1FB13520D9753CFB02BD210599181574DF6AD0DB6A42C1EA48D9E48FC3D11B9008E4C76FBB163D5B00811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "binary": "1200242200200000240015DAE16140000000000003E868400000000000000A6019D5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440117CF90F9B113AD3BD638B6DB63562B37C287D5180F278B3CCF58FC14A5BAEE98307EA0F6DFE19E2FBA887C92955BA5D1A04F92ADAAEB309DE89C3610D074C098114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", "json": { - "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw", "TransactionType": "AMMDeposit", "Asset": {"currency": "XRP"}, "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, "Amount": "1000", "LPTokenOut": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000"}, - "Fee": "1", + "Fee": "10", "Flags": 2097152, - "Sequence": 2, - "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", - "TxnSignature": "452BC59F9EE12C224EC983EFDF580F20C4A50E897105FD1FB13520D9753CFB02BD210599181574DF6AD0DB6A42C1EA48D9E48FC3D11B9008E4C76FBB163D5B00" + "Sequence": 1432289, + "SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8", + "TxnSignature": "117CF90F9B113AD3BD638B6DB63562B37C287D5180F278B3CCF58FC14A5BAEE98307EA0F6DFE19E2FBA887C92955BA5D1A04F92ADAAEB309DE89C3610D074C09" } }, { - "binary": "120024220040000024000000026140000000000003E8684000000000000001601640000000000000197321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440DD6685DC586FAA6AD2D50D785900122EB147D4AC09A55D7080267A9B38180F87CEC44B823359FC3F0AC0104D47B53FFC6B80415664C3C4582672420A0100F70C811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "binary": "1200242200400000240015DAE16140000000000003E868400000000000000A601B40000000000000197321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B874405E51EBC6B52A7C3BA5D0AE2FC8F62E779B80182009B3108A87AB6D770D68F56053C193DB0640128E4765565970625B1E2878E116AC854E6DED412202CCDE0B0D8114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", "json": { - "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw", "TransactionType": "AMMDeposit", "Asset": {"currency": "XRP"}, "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, "Amount": "1000", "EPrice": "25", - "Fee": "1", + "Fee": "10", "Flags": 4194304, - "Sequence": 2, - "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", - "TxnSignature": "DD6685DC586FAA6AD2D50D785900122EB147D4AC09A55D7080267A9B38180F87CEC44B823359FC3F0AC0104D47B53FFC6B80415664C3C4582672420A0100F70C" + "Sequence": 1432289, + "SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8", + "TxnSignature": "5E51EBC6B52A7C3BA5D0AE2FC8F62E779B80182009B3108A87AB6D770D68F56053C193DB0640128E4765565970625B1E2878E116AC854E6DED412202CCDE0B0D" } }, { - "binary": "120025220001000024000000026840000000000000016015D5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0744066944797E9F03808C9A00AAEFF786AD74FEB2E64B51A9601E89ABA820AAA15927C2E961A9CCA22C4B0D2A2B55E342BD6E297BD765B6F4D3FDCA578A3416BB505811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "binary": "1200252200010000240015DAE168400000000000000A601AD5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B874409D4F41FC452526C0AD17191959D9B6D04A3C73B3A6C29E0F34C8459675A83A7A7D6E3021390EC8C9BE6C93E11C167E12016465E523F64F9EB3194B0A52E418028114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", "json": { - "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw", "TransactionType": "AMMWithdraw", "Asset": {"currency": "XRP"}, "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, "LPTokenIn": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000"}, - "Fee": "1", + "Fee": "10", "Flags": 65536, - "Sequence": 2, - "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", - "TxnSignature": "66944797E9F03808C9A00AAEFF786AD74FEB2E64B51A9601E89ABA820AAA15927C2E961A9CCA22C4B0D2A2B55E342BD6E297BD765B6F4D3FDCA578A3416BB505" + "Sequence": 1432289, + "SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8", + "TxnSignature": "9D4F41FC452526C0AD17191959D9B6D04A3C73B3A6C29E0F34C8459675A83A7A7D6E3021390EC8C9BE6C93E11C167E12016465E523F64F9EB3194B0A52E41802" } }, { - "binary": "120025220008000024000000026140000000000003E86840000000000000017321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440E30397CE7E99B13D35FFB5C66725B17F4F103675E10293C7B1D63C1BE3FA81B884BD3FBD31B52F6B811F99C5FBB5102D170EC379C268DF80DABF04E7F2DD4F0C811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "binary": "1200252200080000240015DAE16140000000000003E868400000000000000A7321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440E2C60D56C337D6D73E4B7D53579C93C666605494E82A89DD58CFDE79E2A4866BCF52370A2146877A2EF748E98168373710001133A51B645D89491849079035018114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", "json": { - "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw", "TransactionType": "AMMWithdraw", "Asset": {"currency": "XRP"}, "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, "Amount": "1000", - "Fee": "1", + "Fee": "10", "Flags": 524288, - "Sequence": 2, - "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", - "TxnSignature": "E30397CE7E99B13D35FFB5C66725B17F4F103675E10293C7B1D63C1BE3FA81B884BD3FBD31B52F6B811F99C5FBB5102D170EC379C268DF80DABF04E7F2DD4F0C" + "Sequence": 1432289, + "SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8", + "TxnSignature": "E2C60D56C337D6D73E4B7D53579C93C666605494E82A89DD58CFDE79E2A4866BCF52370A2146877A2EF748E98168373710001133A51B645D8949184907903501" } }, { - "binary": "120025220010000024000000026140000000000003E86840000000000000016BD511C37937E080000000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C7321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440C0818312B269A4EF16C1C7EBBB74EFD1852A288BB214A714B8BE3B5F4B2F9CFDFF4F66C931B8434244A8016035B9EC9493B7CF5E0ACF4570A88DF808D79E4300811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "binary": "1200252200100000240015DAE16140000000000003E868400000000000000A6BD511C37937E080000000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C7321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440D2FCD7D03E53358BC6188BA88A7BA4FF2519B639C3B5C0EBCBDCB704426CA2837111430E92A6003D1CD0D81C63682C74839320539EC4F89B82AA5607714952028114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", "json": { - "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw", "TransactionType": "AMMWithdraw", "Asset": {"currency": "XRP"}, "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, "Amount": "1000", "Amount2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", "value": "500"}, - "Fee": "1", + "Fee": "10", "Flags": 1048576, - "Sequence": 2, - "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", - "TxnSignature": "C0818312B269A4EF16C1C7EBBB74EFD1852A288BB214A714B8BE3B5F4B2F9CFDFF4F66C931B8434244A8016035B9EC9493B7CF5E0ACF4570A88DF808D79E4300" + "Sequence": 1432289, + "SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8", + "TxnSignature": "D2FCD7D03E53358BC6188BA88A7BA4FF2519B639C3B5C0EBCBDCB704426CA2837111430E92A6003D1CD0D81C63682C74839320539EC4F89B82AA560771495202" } }, { - "binary": "120025220020000024000000026140000000000003E86840000000000000016015D5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0744073552B3DC7AE99DDF4E4FF0D60E6D0BE4688E3474D363603FA25DA6AD8BBA8F0E4E3EA82ADB2B57F5B9A6C379969E00095546DDA0E74FF3D0F0689351C2F8C06811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "binary": "1200252200200000240015DAE16140000000000003E868400000000000000A601AD5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8744042DA5620E924E2D2059BBB4E0C4F03244140ACED93B543136FEEDF802165F814D09F45C7E2A4618468442516F4712A23B1D3332D5DBDBAE830337F39F259C90F8114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", "json": { - "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw", "TransactionType": "AMMWithdraw", "Asset": {"currency": "XRP"}, "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, "Amount": "1000", "LPTokenIn": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000"}, - "Fee": "1", + "Fee": "10", "Flags": 2097152, - "Sequence": 2, - "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", - "TxnSignature": "73552B3DC7AE99DDF4E4FF0D60E6D0BE4688E3474D363603FA25DA6AD8BBA8F0E4E3EA82ADB2B57F5B9A6C379969E00095546DDA0E74FF3D0F0689351C2F8C06" + "Sequence": 1432289, + "SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8", + "TxnSignature": "42DA5620E924E2D2059BBB4E0C4F03244140ACED93B543136FEEDF802165F814D09F45C7E2A4618468442516F4712A23B1D3332D5DBDBAE830337F39F259C90F" } }, { - "binary": "120025220040000024000000026140000000000003E8684000000000000001601640000000000000197321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0744023BAFE5BFE58E7BF0B02B5875983D007C10796C8E62A190BF688EBE5D8A104DAD2DE7EDE995FE2E494883FD8140F38E22E3376A2F49C50EFCAA00C7499A4690E811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "binary": "1200252200400000240015DAE16140000000000003E868400000000000000A601B40000000000000197321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8744045BCEE5A12E5F5F1FB085A24F2F7FD962BBCB0D89A44A5319E3F7E3799E1870341880B6F684132971DDDF2E6B15356B3F407962D6D4E8DE10989F3B16E3CB90D8114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", "json": { - "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw", "TransactionType": "AMMWithdraw", "Asset": {"currency": "XRP"}, "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, "Amount": "1000", "EPrice": "25", - "Fee": "1", + "Fee": "10", "Flags": 4194304, - "Sequence": 2, - "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", - "TxnSignature": "23BAFE5BFE58E7BF0B02B5875983D007C10796C8E62A190BF688EBE5D8A104DAD2DE7EDE995FE2E494883FD8140F38E22E3376A2F49C50EFCAA00C7499A4690E" + "Sequence": 1432289, + "SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8", + "TxnSignature": "45BCEE5A12E5F5F1FB085A24F2F7FD962BBCB0D89A44A5319E3F7E3799E1870341880B6F684132971DDDF2E6B15356B3F407962D6D4E8DE10989F3B16E3CB90D" } }, { - "binary": "120027220000000024000000026840000000000000016CD4C8E1BC9BF04000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0486DD4CC6F3B40B6C000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D074406B2A1548E6DC14681356C27CCBE7072CAB2AD8C72D0D7A045916FB0E0DBE6BF71A429CC519E9200172829D3EEF79100899D3A8710C1C3C1A2B664FD64086AD0A811462D4D845D20B4F09CFEA8BB4C01063D99FC9673EF01AE01C81149A91957F8F16BC57F3F200CD8C98375BF1791586E1F10318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "binary": "1200272200000000240015DAE168400000000000000A6CD4C8E1BC9BF04000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0486DD4CC6F3B40B6C000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440F8EAAFB5EC1A69275167589969F0B9764BACE6BC8CC81482C2FC5ACCE691EDBD0D88D141137B1253BB1B9AC90A8A52CB37F5B6F7E1028B06DD06F91BE06F5A0F8114F92F27CC5EE2F2760278FE096D0CBE32BDD3653AF015E01B81149A91957F8F16BC57F3F200CD8C98375BF1791586E1F10318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", "json": { - "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw", "TransactionType": "AMMBid", "Asset": {"currency": "XRP"}, "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, "AuthAccounts": [{"AuthAccount": {"Account": "rEaHTti4HZsMBpxTAF4ncWxkcdqDh1h6P7"}}], "BidMax": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "35"}, "BidMin": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "25"}, - "Fee": "1", + "Fee": "10", "Flags": 0, - "Sequence": 2, - "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", - "TxnSignature": "6B2A1548E6DC14681356C27CCBE7072CAB2AD8C72D0D7A045916FB0E0DBE6BF71A429CC519E9200172829D3EEF79100899D3A8710C1C3C1A2B664FD64086AD0A" + "Sequence": 1432289, + "SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8", + "TxnSignature": "F8EAAFB5EC1A69275167589969F0B9764BACE6BC8CC81482C2FC5ACCE691EDBD0D88D141137B1253BB1B9AC90A8A52CB37F5B6F7E1028B06DD06F91BE06F5A0F" } }, { - "binary": "1200261500EA220000000024000000026840000000000000017321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0744072767CF9A0F5E9C9DA6BBB6E84905B0ECDF122D3E2D730843EFD377521E8E73664AD809D0A54E8C75CD1735ACB64E310BB49FDED10913FA150B8C006D4ACEC00811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "binary": "1200261500EA2200000000240015DAE168400000000000000A7321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440BC2F6E76969E3747E9BDE183C97573B086212F09D5387460E6EE2F32953E85EAEB9618FBBEF077276E30E59D619FCF7C7BDCDDDD9EB94D7CE1DD5CE9246B21078114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", "json": { - "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw", "TransactionType": "AMMVote", "Asset": {"currency": "XRP"}, "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, "TradingFee": 234, - "Fee": "1", + "Fee": "10", "Flags": 0, - "Sequence": 2, - "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", - "TxnSignature": "72767CF9A0F5E9C9DA6BBB6E84905B0ECDF122D3E2D730843EFD377521E8E73664AD809D0A54E8C75CD1735ACB64E310BB49FDED10913FA150B8C006D4ACEC00" + "Sequence": 1432289, + "SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8", + "TxnSignature": "BC2F6E76969E3747E9BDE183C97573B086212F09D5387460E6EE2F32953E85EAEB9618FBBEF077276E30E59D619FCF7C7BDCDDDD9EB94D7CE1DD5CE9246B2107" } } ], diff --git a/xrpl/core/binarycodec/definitions/definitions.json b/xrpl/core/binarycodec/definitions/definitions.json index e5ecefb48..402df6973 100644 --- a/xrpl/core/binarycodec/definitions/definitions.json +++ b/xrpl/core/binarycodec/definitions/definitions.json @@ -333,6 +333,16 @@ "type": "UInt16" } ], + [ + "NetworkID", + { + "nth": 1, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], [ "Flags", { @@ -776,7 +786,7 @@ [ "VoteWeight", { - "nth": 47, + "nth": 48, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -786,7 +796,17 @@ [ "DiscountedFee", { - "nth": 48, + "nth": 49, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "FirstNFTokenSequence", + { + "nth": 50, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1493,10 +1513,40 @@ "type": "Amount" } ], + [ + "BaseFeeDrops", + { + "nth": 22, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "ReserveBaseDrops", + { + "nth": 23, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "ReserveIncrementDrops", + { + "nth": 24, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], [ "LPTokenOut", { - "nth": 20, + "nth": 25, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1506,7 +1556,7 @@ [ "LPTokenIn", { - "nth": 21, + "nth": 26, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1516,7 +1566,7 @@ [ "EPrice", { - "nth": 22, + "nth": 27, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1526,7 +1576,7 @@ [ "Price", { - "nth": 23, + "nth": 28, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1536,7 +1586,7 @@ [ "LPTokenBalance", { - "nth": 24, + "nth": 31, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1873,16 +1923,6 @@ "type": "AccountID" } ], - [ - "AMMAccount", - { - "nth": 11, - "isVLEncoded": true, - "isSerialized": true, - "isSigningField": true, - "type": "AccountID" - } - ], [ "HookAccount", { @@ -2186,7 +2226,7 @@ [ "AuctionSlot", { - "nth": 27, + "nth": 26, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -2196,7 +2236,7 @@ [ "AuthAccount", { - "nth": 28, + "nth": 27, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -2296,7 +2336,7 @@ [ "VoteSlots", { - "nth": 14, + "nth": 12, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -2356,7 +2396,7 @@ [ "AuthAccounts", { - "nth": 26, + "nth": 21, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -2378,6 +2418,9 @@ "telCAN_NOT_QUEUE_BLOCKED": -389, "telCAN_NOT_QUEUE_FEE": -388, "telCAN_NOT_QUEUE_FULL": -387, + "telWRONG_NETWORK": -386, + "telREQUIRES_NETWORK_ID": -385, + "telNETWORK_ID_MAKES_TX_NON_CANONICAL": -384, "temMALFORMED": -299, "temBAD_AMOUNT": -298, From a8fa396732de5c555e9fcdd9a7c7fcbbd7d38a4b Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 6 Jun 2023 18:05:43 -0400 Subject: [PATCH 75/88] update DiscountedFee definition --- .../binarycodec/definitions/definitions.json | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/xrpl/core/binarycodec/definitions/definitions.json b/xrpl/core/binarycodec/definitions/definitions.json index 402df6973..7c7e97630 100644 --- a/xrpl/core/binarycodec/definitions/definitions.json +++ b/xrpl/core/binarycodec/definitions/definitions.json @@ -283,6 +283,16 @@ "type": "UInt16" } ], + [ + "DiscountedFee", + { + "nth": 6, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt16" + } + ], [ "Version", { @@ -793,16 +803,6 @@ "type": "UInt32" } ], - [ - "DiscountedFee", - { - "nth": 49, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], [ "FirstNFTokenSequence", { From 7c98ea971f787c81d572b1a0f4df6ded1eb7e3e3 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 7 Jun 2023 14:39:49 -0400 Subject: [PATCH 76/88] update definitions and codec-fixtures --- .../unit/core/binarycodec/fixtures/data/codec-fixtures.json | 2 +- xrpl/core/binarycodec/definitions/definitions.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json b/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json index 14082315e..f5b5a5976 100644 --- a/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json +++ b/tests/unit/core/binarycodec/fixtures/data/codec-fixtures.json @@ -4626,7 +4626,7 @@ } }, { - "binary": "1200272200000000240015DAE168400000000000000A6CD4C8E1BC9BF04000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0486DD4CC6F3B40B6C000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440F8EAAFB5EC1A69275167589969F0B9764BACE6BC8CC81482C2FC5ACCE691EDBD0D88D141137B1253BB1B9AC90A8A52CB37F5B6F7E1028B06DD06F91BE06F5A0F8114F92F27CC5EE2F2760278FE096D0CBE32BDD3653AF015E01B81149A91957F8F16BC57F3F200CD8C98375BF1791586E1F10318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "binary": "1200272200000000240015DAE168400000000000000A6CD4C8E1BC9BF04000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0486DD4CC6F3B40B6C000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440F8EAAFB5EC1A69275167589969F0B9764BACE6BC8CC81482C2FC5ACCE691EDBD0D88D141137B1253BB1B9AC90A8A52CB37F5B6F7E1028B06DD06F91BE06F5A0F8114F92F27CC5EE2F2760278FE096D0CBE32BDD3653AF019E01B81149A91957F8F16BC57F3F200CD8C98375BF1791586E1F10318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", "json": { "Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw", "TransactionType": "AMMBid", diff --git a/xrpl/core/binarycodec/definitions/definitions.json b/xrpl/core/binarycodec/definitions/definitions.json index 7c7e97630..3bf5a024a 100644 --- a/xrpl/core/binarycodec/definitions/definitions.json +++ b/xrpl/core/binarycodec/definitions/definitions.json @@ -2396,7 +2396,7 @@ [ "AuthAccounts", { - "nth": 21, + "nth": 25, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -2460,7 +2460,7 @@ "temUNKNOWN": -264, "temSEQ_AND_TICKET": -263, "temBAD_NFTOKEN_TRANSFER_FEE": -262, - "temAMM_BAD_TOKENS": -261, + "temBAD_AMM_TOKENS": -261, "tefFAILURE": -199, "tefALREADY": -198, @@ -2546,7 +2546,7 @@ "tecINSUFFICIENT_FUNDS": 159, "tecOBJECT_NOT_FOUND": 160, "tecINSUFFICIENT_PAYMENT": 161, - "tecAMM_UNFUNDED": 162, + "tecUNFUNDED_AMM": 162, "tecAMM_BALANCE": 163, "tecAMM_FAILED_DEPOSIT": 164, "tecAMM_FAILED_WITHDRAW": 165, From 31aee69a18df08e9aca30bc619e1681e61ae6e5f Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Fri, 9 Jun 2023 16:54:18 -0400 Subject: [PATCH 77/88] update definitions --- xrpl/core/binarycodec/definitions/definitions.json | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/xrpl/core/binarycodec/definitions/definitions.json b/xrpl/core/binarycodec/definitions/definitions.json index 3bf5a024a..f6d5f43fa 100644 --- a/xrpl/core/binarycodec/definitions/definitions.json +++ b/xrpl/core/binarycodec/definitions/definitions.json @@ -2548,11 +2548,8 @@ "tecINSUFFICIENT_PAYMENT": 161, "tecUNFUNDED_AMM": 162, "tecAMM_BALANCE": 163, - "tecAMM_FAILED_DEPOSIT": 164, - "tecAMM_FAILED_WITHDRAW": 165, - "tecAMM_INVALID_TOKENS": 166, - "tecAMM_FAILED_BID": 167, - "tecAMM_FAILED_VOTE": 168 + "tecAMM_FAILED": 164, + "tecAMM_INVALID_TOKENS": 165 }, "TRANSACTION_TYPES": { "Invalid": -1, From 14f158b5d42320baf538832650fa4a1f0f2c9e9e Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Mon, 17 Jul 2023 18:06:54 -0400 Subject: [PATCH 78/88] remove sidechain method --- xrpl/models/requests/request.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/xrpl/models/requests/request.py b/xrpl/models/requests/request.py index 5a2ff48b6..a91c4e2b8 100644 --- a/xrpl/models/requests/request.py +++ b/xrpl/models/requests/request.py @@ -75,9 +75,6 @@ class RequestMethod(str, Enum): PING = "ping" RANDOM = "random" - # sidechain methods - FEDERATOR_INFO = "federator_info" - # amm methods AMM_INFO = "amm_info" From 0dcaf8c09ad1baecdf8eb22fd1041797b7d21f6f Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Mon, 17 Jul 2023 18:13:04 -0400 Subject: [PATCH 79/88] small refactor --- xrpl/asyncio/transaction/main.py | 6 +++--- xrpl/models/requests/amm_info.py | 5 ----- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/xrpl/asyncio/transaction/main.py b/xrpl/asyncio/transaction/main.py index 4ee7a4c3b..42b812e1f 100644 --- a/xrpl/asyncio/transaction/main.py +++ b/xrpl/asyncio/transaction/main.py @@ -467,9 +467,9 @@ async def _calculate_fee_per_transaction_type( base_fee = math.ceil(net_fee * (33 + (len(fulfillment_bytes) / 16))) # AccountDelete Transaction - if ( - transaction.transaction_type == TransactionType.ACCOUNT_DELETE - or transaction.transaction_type == TransactionType.AMM_CREATE + if transaction.transaction_type in ( + TransactionType.ACCOUNT_DELETE, + TransactionType.AMM_CREATE, ): if client is None: base_fee = _OWNER_RESERVE_FEE diff --git a/xrpl/models/requests/amm_info.py b/xrpl/models/requests/amm_info.py index 44d00e221..2473a2157 100644 --- a/xrpl/models/requests/amm_info.py +++ b/xrpl/models/requests/amm_info.py @@ -2,7 +2,6 @@ from __future__ import annotations from dataclasses import dataclass, field -from typing import Dict from xrpl.models.currencies import Currency from xrpl.models.requests.request import Request, RequestMethod @@ -30,7 +29,3 @@ class AMMInfo(Request): """ method: RequestMethod = field(default=RequestMethod.AMM_INFO, init=False) - - def _get_errors(self: AMMInfo) -> Dict[str, str]: - errors = super()._get_errors() - return errors From 1b14fd3f9e49f028a5f6290b5f6f410f4e844221 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Mon, 17 Jul 2023 18:38:41 -0400 Subject: [PATCH 80/88] update docstrings --- xrpl/models/requests/amm_info.py | 11 +++---- xrpl/models/transactions/amm_bid.py | 32 +++++++++--------- xrpl/models/transactions/amm_create.py | 34 +++++++++++++------- xrpl/models/transactions/amm_deposit.py | 41 ++++++++++++------------ xrpl/models/transactions/amm_vote.py | 19 +++++------ xrpl/models/transactions/amm_withdraw.py | 40 +++++++++-------------- 6 files changed, 91 insertions(+), 86 deletions(-) diff --git a/xrpl/models/requests/amm_info.py b/xrpl/models/requests/amm_info.py index 2473a2157..cf0c7dd10 100644 --- a/xrpl/models/requests/amm_info.py +++ b/xrpl/models/requests/amm_info.py @@ -1,4 +1,4 @@ -"""This request retrieves information about an AMM instance.""" +"""This request gets information about an Automated Market Maker (AMM) instance.""" from __future__ import annotations from dataclasses import dataclass, field @@ -13,19 +13,18 @@ @dataclass(frozen=True) class AMMInfo(Request): """ - This request retrieves information about an AMM instance. - - Must provide Asset and Asset2 params. + The `amm_info` method gets information about an Automated Market Maker + (AMM) instance. """ asset: Currency = REQUIRED # type: ignore """ - Specifies one of the pool assets (XRP or token) of the AMM instance. + One of the assets of the AMM pool to look up. This field is required. """ asset2: Currency = REQUIRED # type: ignore """ - Specifies the other pool asset of the AMM instance. + The other asset of the AMM pool. This field is required. """ method: RequestMethod = field(default=RequestMethod.AMM_INFO, init=False) diff --git a/xrpl/models/transactions/amm_bid.py b/xrpl/models/transactions/amm_bid.py index 63dc6a9a5..edf21f1bd 100644 --- a/xrpl/models/transactions/amm_bid.py +++ b/xrpl/models/transactions/amm_bid.py @@ -21,42 +21,44 @@ @dataclass(frozen=True) class AMMBid(Transaction): """ - AMMBid is used to place a bid for the auction slot of obtaining trading advantages - of an AMM instance. + Bid on an Automated Market Maker's (AMM's) auction slot. - An AMM instance auctions off the trading advantages to users (arbitrageurs) at a - discounted TradingFee for a 24 hour slot. + If you win, you can trade against the AMM at a discounted fee until you are outbid + or 24 hours have passed. + If you are outbid before 24 hours have passed, you are refunded part of the cost + of your bid based on how much time remains. + You bid using the AMM's LP Tokens; the amount of a winning bid is returned + to the AMM, decreasing the outstanding balance of LP Tokens. """ asset: Currency = REQUIRED # type: ignore """ - Specifies one of the pool assets (XRP or token) of the AMM instance. + The definition for one of the assets in the AMM's pool. This field is required. """ asset2: Currency = REQUIRED # type: ignore """ - Specifies the other pool asset of the AMM instance. + The definition for the other asset in the AMM's pool. This field is required. """ bid_min: Optional[Amount] = None """ - This field represents the minimum price that the bidder wants to pay for the slot. - It is specified in units of LPToken. If specified let MinSlotPrice be X and let - the slot-price computed by price scheduling algorithm be Y, then bidder always pays - the max(X, Y). + Pay at least this amount for the slot. + Setting this value higher makes it harder for others to outbid you. + If omitted, pay the minimum necessary to win the bid. """ bid_max: Optional[Amount] = None """ - This field represents the maximum price that the bidder wants to pay for the slot. - It is specified in units of LPToken. + Pay at most this amount for the slot. + If the cost to win the bid is higher than this amount, the transaction fails. + If omitted, pay as much as necessary to win the bid. """ auth_accounts: Optional[List[AuthAccount]] = None """ - This field represents an array of XRPL account IDs that are authorized to trade - at the discounted fee against the AMM instance. - A maximum of four accounts can be provided. + A list of up to 4 additional accounts that you allow to trade at the discounted fee. + This cannot include the address of the transaction sender. """ transaction_type: TransactionType = field( diff --git a/xrpl/models/transactions/amm_create.py b/xrpl/models/transactions/amm_create.py index 212be06df..1fed0bcf5 100644 --- a/xrpl/models/transactions/amm_create.py +++ b/xrpl/models/transactions/amm_create.py @@ -19,30 +19,42 @@ @dataclass(frozen=True) class AMMCreate(Transaction): """ - AMMCreate is used to create AccountRoot and the corresponding AMM - ledger entries. - This allows for the creation of only one AMM instance per unique asset pair. + Create a new Automated Market Maker (AMM) instance for trading a pair of + assets (fungible tokens or XRP). + + Creates both an AMM object and a special AccountRoot object to represent the AMM. + Also transfers ownership of the starting balance of both assets from the sender to + the created AccountRoot and issues an initial balance of liquidity provider + tokens (LP Tokens) from the AMM account to the sender. + + Caution: When you create the AMM, you should fund it with (approximately) + equal-value amounts of each asset. + Otherwise, other users can profit at your expense by trading with + this AMM (performing arbitrage). + The currency risk that liquidity providers take on increases with the + volatility (potential for imbalance) of the asset pair. + The higher the trading fee, the more it offsets this risk, + so it's best to set the trading fee based on the volatility of the asset pair. """ amount: Amount = REQUIRED # type: ignore """ - Specifies one of the pool assets (XRP or token) of the AMM instance. + The first of the two assets to fund this AMM with. This must be a positive amount. This field is required. """ amount2: Amount = REQUIRED # type: ignore """ - Specifies the other pool asset of the AMM instance. This field is required. + The second of the two assets to fund this AMM with. This must be a positive amount. + This field is required. """ trading_fee: int = REQUIRED # type: ignore """ - Specifies the fee, in basis point, to be charged - to the traders for the trades executed against the AMM instance. - Trading fee is a percentage of the trading volume. - Valid values for this field are between 0 and 1000 inclusive. - A value of 1 is equivalent to 1/10 bps or 0.001%, allowing trading fee - between 0% and 1%. This field is required. + The fee to charge for trades against this AMM instance, in units of 1/100,000; + a value of 1 is equivalent to 0.001%. + The maximum value is 1000, indicating a 1% fee. + The minimum value is 0. """ transaction_type: TransactionType = field( diff --git a/xrpl/models/transactions/amm_deposit.py b/xrpl/models/transactions/amm_deposit.py index f8c592e18..6a8b273f8 100644 --- a/xrpl/models/transactions/amm_deposit.py +++ b/xrpl/models/transactions/amm_deposit.py @@ -44,48 +44,47 @@ class AMMDepositFlagInterface(FlagInterface): @dataclass(frozen=True) class AMMDeposit(Transaction): """ - AMMDeposit is the deposit transaction used to add liquidity to the AMM instance - pool, thus obtaining some share of the instance's pools in the form of LPToken. + Deposit funds into an Automated Market Maker (AMM) instance + and receive the AMM's liquidity provider tokens (LP Tokens) in exchange. - The following are the recommended valid combinations: - - LPTokenOut - - Amount - - Amount and Amount2 - - Amount and LPTokenOut - - Amount and EPrice + You can deposit one or both of the assets in the AMM's pool. + If successful, this transaction creates a trust line to the AMM Account (limit 0) + to hold the LP Tokens. """ asset: Currency = REQUIRED # type: ignore """ - Specifies one of the pool assets (XRP or token) of the AMM instance. + The definition for one of the assets in the AMM's pool. This field is required. """ asset2: Currency = REQUIRED # type: ignore """ - Specifies the other pool asset of the AMM instance. - """ - - lp_token_out: Optional[IssuedCurrencyAmount] = None - """ - Specifies the amount of shares of the AMM instance pools that the trader - wants to redeem or trade in. + The definition for the other asset in the AMM's pool. This field is required. """ amount: Optional[Amount] = None """ - Specifies one of the pool assets (XRP or token) of the AMM instance to - deposit more of its value. + The amount of one asset to deposit to the AMM. + If present, this must match the type of one of the assets (tokens or XRP) + in the AMM's pool. """ amount2: Optional[Amount] = None """ - Specifies the other pool asset of the AMM instance to deposit more of its - value. + The amount of another asset to add to the AMM. + If present, this must match the type of the other asset in the AMM's pool + and cannot be the same asset as Amount. """ e_price: Optional[Amount] = None """ - Specifies the maximum effective-price that LPToken can be traded out. + The maximum effective price, in the deposit asset, to pay + for each LP Token received. + """ + + lp_token_out: Optional[IssuedCurrencyAmount] = None + """ + How many of the AMM's LP Tokens to buy. """ transaction_type: TransactionType = field( diff --git a/xrpl/models/transactions/amm_vote.py b/xrpl/models/transactions/amm_vote.py index 5a794a802..e955aefaa 100644 --- a/xrpl/models/transactions/amm_vote.py +++ b/xrpl/models/transactions/amm_vote.py @@ -16,28 +16,29 @@ @dataclass(frozen=True) class AMMVote(Transaction): """ - AMMVote is used for submitting a vote for the trading fee of an AMM Instance. + Vote on the trading fee for an Automated Market Maker (AMM) instance. - Any XRPL account that holds LPToken for an AMM instance may submit this - transaction to vote for the trading fee for that instance. + Up to 8 accounts can vote in proportion to the amount of the AMM's LP Tokens + they hold. + Each new vote re-calculates the AMM's trading fee based on a weighted average + of the votes. """ asset: Currency = REQUIRED # type: ignore """ - Specifies one of the pool assets (XRP or token) of the AMM instance. + The definition for one of the assets in the AMM's pool. This field is required. """ asset2: Currency = REQUIRED # type: ignore """ - Specifies the other pool asset of the AMM instance. + The definition for the other asset in the AMM's pool. This field is required. """ trading_fee: int = REQUIRED # type: ignore """ - Specifies the fee, in basis point. - Valid values for this field are between 0 and 1000 inclusive. - A value of 1 is equivalent to 1/10 bps or 0.001%, allowing trading fee - between 0% and 1%. This field is required. + The proposed fee to vote for, in units of 1/100,000; a value of 1 is equivalent + to 0.001%. + The maximum value is 1000, indicating a 1% fee. This field is required. """ transaction_type: TransactionType = field( diff --git a/xrpl/models/transactions/amm_withdraw.py b/xrpl/models/transactions/amm_withdraw.py index d66876520..2c09bb386 100644 --- a/xrpl/models/transactions/amm_withdraw.py +++ b/xrpl/models/transactions/amm_withdraw.py @@ -48,50 +48,42 @@ class AMMWithdrawFlagInterface(FlagInterface): @dataclass(frozen=True) class AMMWithdraw(Transaction): """ - AMMWithdraw is the withdraw transaction used to remove liquidity from the AMM - instance pool, thus redeeming some share of the pools that one owns in the form - of LPToken. - - The following are the recommended valid combinations: - - LPTokenIn - - Amount - - Amount and Amount2 - - Amount and LPTokenIn - - Amount and EPrice + Withdraw assets from an Automated Market Maker (AMM) instance by returning the + AMM's liquidity provider tokens (LP Tokens). """ asset: Currency = REQUIRED # type: ignore """ - Specifies one of the pool assets (XRP or token) of the AMM instance. + The definition for one of the assets in the AMM's pool. This field is required. """ asset2: Currency = REQUIRED # type: ignore """ - Specifies the other pool asset of the AMM instance. - """ - - lp_token_in: Optional[IssuedCurrencyAmount] = None - """ - Specifies the amount of shares of the AMM instance pools that the trader - wants to redeem or trade in. + The definition for the other asset in the AMM's pool. This field is required. """ amount: Optional[Amount] = None """ - Specifies one of the pools assets that the trader wants to remove. - If the asset is XRP, then the Amount is a string specifying the number of drops. - Otherwise it is an IssuedCurrencyAmount object. + The amount of one asset to withdraw from the AMM. + This must match the type of one of the assets (tokens or XRP) in the AMM's pool. """ amount2: Optional[Amount] = None """ - Specifies the other pool asset that the trader wants to remove. + The amount of another asset to withdraw from the AMM. + If present, this must match the type of the other asset in the AMM's pool + and cannot be the same type as Amount. """ e_price: Optional[Amount] = None """ - Specifies the effective-price of the token out after successful execution of - the transaction. + The minimum effective price, in LP Token returned, to pay per unit of the asset + to withdraw. + """ + + lp_token_in: Optional[IssuedCurrencyAmount] = None + """ + How many of the AMM's LP Tokens to redeem. """ transaction_type: TransactionType = field( From 846c2b54f598edd695ae1c9b238532183468232f Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 27 Jul 2023 21:47:53 -0400 Subject: [PATCH 81/88] refactor _value_to_tx_json to remove special case for auth_account --- xrpl/models/transactions/transaction.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/xrpl/models/transactions/transaction.py b/xrpl/models/transactions/transaction.py index acded63bd..8a8148f44 100644 --- a/xrpl/models/transactions/transaction.py +++ b/xrpl/models/transactions/transaction.py @@ -61,9 +61,9 @@ def _key_to_tx_json(key: str) -> str: def _value_to_tx_json(value: XRPL_VALUE_TYPE) -> XRPL_VALUE_TYPE: # IssuedCurrencyAmount and PathStep are special cases and should not be snake cased # and only contain primitive members - if isinstance(value, dict) and "auth_account" in value: - return _auth_account_value_to_tx_json(value) - if IssuedCurrencyAmount.is_dict_of_model(value) or PathStep.is_dict_of_model(value): + if isinstance(value, list) and all(PathStep.is_dict_of_model(v) for v in value): + return value + if IssuedCurrencyAmount.is_dict_of_model(value): return value if isinstance(value, dict): return transaction_json_to_binary_codec_form(value) @@ -72,13 +72,6 @@ def _value_to_tx_json(value: XRPL_VALUE_TYPE) -> XRPL_VALUE_TYPE: return value -def _auth_account_value_to_tx_json(value: Dict[str, Any]) -> Dict[str, Any]: - return { - _key_to_tx_json(key): transaction_json_to_binary_codec_form(val) - for (key, val) in value.items() - } - - @require_kwargs_on_init @dataclass(frozen=True) class Memo(NestedModel): From 907955ee59504064bf9bf981f28f8cb1374e3257 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 27 Jul 2023 22:04:03 -0400 Subject: [PATCH 82/88] refactor AuthAccount to be a NestedModel --- xrpl/models/auth_account.py | 53 ++----------------------------------- 1 file changed, 2 insertions(+), 51 deletions(-) diff --git a/xrpl/models/auth_account.py b/xrpl/models/auth_account.py index b9182cbed..96cebabbb 100644 --- a/xrpl/models/auth_account.py +++ b/xrpl/models/auth_account.py @@ -2,16 +2,15 @@ from __future__ import annotations from dataclasses import dataclass -from typing import Any, Dict, Type -from xrpl.models.base_model import BaseModel +from xrpl.models.nested_model import NestedModel from xrpl.models.required import REQUIRED from xrpl.models.utils import require_kwargs_on_init @require_kwargs_on_init @dataclass(frozen=True) -class AuthAccount(BaseModel): +class AuthAccount(NestedModel): """Represents one entry in a list of AuthAccounts used in AMMBid transaction.""" account: str = REQUIRED # type: ignore @@ -20,51 +19,3 @@ class AuthAccount(BaseModel): :meta hide-value: """ - - @classmethod - def is_dict_of_model(cls: Type[AuthAccount], dictionary: Dict[str, Any]) -> bool: - """ - Returns True if the input dictionary was derived by the `to_dict` - method of an instance of this class. In other words, True if this is - a dictionary representation of an instance of this class. - - NOTE: does not account for model inheritance, IE will only return True - if dictionary represents an instance of this class, but not if - dictionary represents an instance of a subclass of this class. - - Args: - dictionary: The dictionary to check. - - Returns: - True if dictionary is a dict representation of an instance of this - class. - """ - return ( - isinstance(dictionary, dict) - and "auth_account" in dictionary - and super().is_dict_of_model(dictionary["auth_account"]) - ) - - @classmethod - def from_dict(cls: Type[AuthAccount], value: Dict[str, Any]) -> AuthAccount: - """ - Construct a new AuthAccount from a dictionary of parameters. - - Args: - value: The value to construct the AuthAccount from. - - Returns: - A new AuthAccount object, constructed using the given parameters. - """ - if len(value) == 1 and "auth_account" in value: - return super(AuthAccount, cls).from_dict(value["auth_account"]) - return super(AuthAccount, cls).from_dict(value) - - def to_dict(self: AuthAccount) -> Dict[str, Any]: - """ - Returns the dictionary representation of a AuthAccount. - - Returns: - The dictionary representation of a AuthAccount. - """ - return {"auth_account": super().to_dict()} From 325b9ef71dad7ae5c7924df29fba4e50f9ee7975 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 27 Jul 2023 22:08:23 -0400 Subject: [PATCH 83/88] remove test_base_model tests for amm --- tests/unit/models/test_base_model.py | 419 --------------------------- 1 file changed, 419 deletions(-) diff --git a/tests/unit/models/test_base_model.py b/tests/unit/models/test_base_model.py index e727ada65..ae5c9bff1 100644 --- a/tests/unit/models/test_base_model.py +++ b/tests/unit/models/test_base_model.py @@ -4,7 +4,6 @@ from xrpl.models import XRPLModelException from xrpl.models.amounts import IssuedCurrencyAmount -from xrpl.models.currencies import XRP, IssuedCurrency from xrpl.models.requests import ( AccountChannels, BookOffers, @@ -17,12 +16,6 @@ SubmitOnly, ) from xrpl.models.transactions import ( - AMMBid, - AMMCreate, - AMMDeposit, - AMMVote, - AMMWithdraw, - AuthAccount, CheckCreate, Memo, Payment, @@ -604,415 +597,3 @@ def test_to_xrpl_signer(self): ], } self.assertEqual(tx.to_xrpl(), expected) - - def test_to_xrpl_amm_create(self): - tx = AMMCreate( - account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - amount="1000", - amount2=IssuedCurrencyAmount( - currency="USD", - issuer="rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", - value="1000", - ), - trading_fee=12, - ) - expected = { - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Amount": "1000", - "Amount2": { - "currency": "USD", - "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", - "value": "1000", - }, - "TransactionType": "AMMCreate", - "SigningPubKey": "", - "TradingFee": 12, - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) - - def test_to_xrpl_amm_deposit_lptoken(self): - tx = AMMDeposit( - account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - sequence=1337, - asset=XRP(), - asset2=IssuedCurrency( - currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" - ), - lp_token_out=IssuedCurrencyAmount( - currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", - issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", - value="1000", - ), - ) - expected = { - "Asset": {"currency": "XRP"}, - "Asset2": { - "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", - }, - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "LPTokenOut": { - "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", - "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", - "value": "1000", - }, - "TransactionType": "AMMDeposit", - "Sequence": 1337, - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) - - def test_to_xrpl_amm_deposit_amount(self): - tx = AMMDeposit( - account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - sequence=1337, - asset=XRP(), - asset2=IssuedCurrency( - currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" - ), - amount="1000", - ) - expected = { - "Asset": {"currency": "XRP"}, - "Asset2": { - "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", - }, - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Amount": "1000", - "TransactionType": "AMMDeposit", - "Sequence": 1337, - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) - - def test_to_xrpl_amm_deposit_amount_amount2(self): - tx = AMMDeposit( - account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - sequence=1337, - asset=XRP(), - asset2=IssuedCurrency( - currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" - ), - amount="1000", - amount2="500", - ) - expected = { - "Asset": {"currency": "XRP"}, - "Asset2": { - "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", - }, - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Amount": "1000", - "Amount2": "500", - "TransactionType": "AMMDeposit", - "Sequence": 1337, - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) - - def test_to_xrpl_amm_deposit_amount_lptoken(self): - tx = AMMDeposit( - account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - sequence=1337, - asset=XRP(), - asset2=IssuedCurrency( - currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" - ), - amount="1000", - lp_token_out=IssuedCurrencyAmount( - currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", - issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", - value="500", - ), - ) - expected = { - "Asset": {"currency": "XRP"}, - "Asset2": { - "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", - }, - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Amount": "1000", - "LPTokenOut": { - "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", - "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", - "value": "500", - }, - "TransactionType": "AMMDeposit", - "Sequence": 1337, - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) - - def test_to_xrpl_amm_deposit_amount_eprice(self): - tx = AMMDeposit( - account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - sequence=1337, - asset=XRP(), - asset2=IssuedCurrency( - currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" - ), - amount="1000", - e_price="25", - ) - expected = { - "Asset": {"currency": "XRP"}, - "Asset2": { - "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", - }, - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Amount": "1000", - "EPrice": "25", - "TransactionType": "AMMDeposit", - "Sequence": 1337, - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) - - def test_to_xrpl_amm_withdraw_lptoken(self): - tx = AMMWithdraw( - account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - sequence=1337, - asset=XRP(), - asset2=IssuedCurrency( - currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" - ), - lp_token_in=IssuedCurrencyAmount( - currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", - issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", - value="1000", - ), - ) - expected = { - "Asset": {"currency": "XRP"}, - "Asset2": { - "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", - }, - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "LPTokenIn": { - "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", - "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", - "value": "1000", - }, - "TransactionType": "AMMWithdraw", - "Sequence": 1337, - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) - - def test_to_xrpl_amm_withdraw_amount(self): - tx = AMMWithdraw( - account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - sequence=1337, - asset=XRP(), - asset2=IssuedCurrency( - currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" - ), - amount="1000", - ) - expected = { - "Asset": {"currency": "XRP"}, - "Asset2": { - "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", - }, - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Amount": "1000", - "TransactionType": "AMMWithdraw", - "Sequence": 1337, - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) - - def test_to_xrpl_amm_withdraw_amount_amount2(self): - tx = AMMWithdraw( - account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - sequence=1337, - asset=XRP(), - asset2=IssuedCurrency( - currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" - ), - amount="1000", - amount2="500", - ) - expected = { - "Asset": {"currency": "XRP"}, - "Asset2": { - "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", - }, - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Amount": "1000", - "Amount2": "500", - "TransactionType": "AMMWithdraw", - "Sequence": 1337, - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) - - def test_to_xrpl_amm_withdraw_amount_lptoken(self): - tx = AMMWithdraw( - account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - sequence=1337, - asset=XRP(), - asset2=IssuedCurrency( - currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" - ), - amount="1000", - lp_token_in=IssuedCurrencyAmount( - currency="B3813FCAB4EE68B3D0D735D6849465A9113EE048", - issuer="rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", - value="500", - ), - ) - expected = { - "Asset": {"currency": "XRP"}, - "Asset2": { - "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", - }, - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Amount": "1000", - "LPTokenIn": { - "currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", - "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", - "value": "500", - }, - "TransactionType": "AMMWithdraw", - "Sequence": 1337, - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) - - def test_to_xrpl_amm_withdraw_amount_eprice(self): - tx = AMMWithdraw( - account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - sequence=1337, - asset=XRP(), - asset2=IssuedCurrency( - currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" - ), - amount="1000", - e_price="25", - ) - expected = { - "Asset": {"currency": "XRP"}, - "Asset2": { - "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", - }, - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Amount": "1000", - "EPrice": "25", - "TransactionType": "AMMWithdraw", - "Sequence": 1337, - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) - - def test_to_xrpl_amm_vote(self): - tx = AMMVote( - account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - asset=XRP(), - asset2=IssuedCurrency( - currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" - ), - trading_fee=234, - ) - expected = { - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset": {"currency": "XRP"}, - "Asset2": { - "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", - }, - "TradingFee": 234, - "TransactionType": "AMMVote", - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) - - def test_to_xrpl_amm_bid(self): - tx = AMMBid( - account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - asset=XRP(), - asset2=IssuedCurrency( - currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" - ), - bid_min=IssuedCurrencyAmount( - currency="5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", - issuer="r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", - value="25", - ), - bid_max=IssuedCurrencyAmount( - currency="5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", - issuer="r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", - value="35", - ), - auth_accounts=[ - AuthAccount(account="rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh"), - AuthAccount(account="rfpFv97Dwu89FTyUwPjtpZBbuZxTqqgTmH"), - AuthAccount(account="rzzYHPGb8Pa64oqxCzmuffm122bitq3Vb"), - AuthAccount(account="rhwxHxaHok86fe4LykBom1jSJ3RYQJs1h4"), - ], - ) - expected = { - "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", - "Asset": {"currency": "XRP"}, - "Asset2": { - "currency": "ETH", - "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", - }, - "BidMin": { - "currency": "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", - "issuer": "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", - "value": "25", - }, - "BidMax": { - "currency": "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", - "issuer": "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", - "value": "35", - }, - "AuthAccounts": [ - { - "AuthAccount": { - "Account": "rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh", - } - }, - { - "AuthAccount": { - "Account": "rfpFv97Dwu89FTyUwPjtpZBbuZxTqqgTmH", - } - }, - { - "AuthAccount": { - "Account": "rzzYHPGb8Pa64oqxCzmuffm122bitq3Vb", - } - }, - { - "AuthAccount": { - "Account": "rhwxHxaHok86fe4LykBom1jSJ3RYQJs1h4", - } - }, - ], - "TransactionType": "AMMBid", - "SigningPubKey": "", - "Flags": 0, - } - self.assertEqual(tx.to_xrpl(), expected) From f2b7513b279a090dbc7e72b2c210a5784ebf8361 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Fri, 28 Jul 2023 11:39:10 -0400 Subject: [PATCH 84/88] add test_to_xrpl_auth_accounts --- tests/unit/models/test_base_model.py | 72 ++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/tests/unit/models/test_base_model.py b/tests/unit/models/test_base_model.py index ae5c9bff1..ceaec1a03 100644 --- a/tests/unit/models/test_base_model.py +++ b/tests/unit/models/test_base_model.py @@ -4,6 +4,7 @@ from xrpl.models import XRPLModelException from xrpl.models.amounts import IssuedCurrencyAmount +from xrpl.models.currencies import XRP, IssuedCurrency from xrpl.models.requests import ( AccountChannels, BookOffers, @@ -16,6 +17,8 @@ SubmitOnly, ) from xrpl.models.transactions import ( + AMMBid, + AuthAccount, CheckCreate, Memo, Payment, @@ -597,3 +600,72 @@ def test_to_xrpl_signer(self): ], } self.assertEqual(tx.to_xrpl(), expected) + + def test_to_xrpl_auth_accounts(self): + tx = AMMBid( + account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + asset=XRP(), + asset2=IssuedCurrency( + currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + ), + bid_min=IssuedCurrencyAmount( + currency="5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", + issuer="r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", + value="25", + ), + bid_max=IssuedCurrencyAmount( + currency="5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", + issuer="r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", + value="35", + ), + auth_accounts=[ + AuthAccount(account="rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh"), + AuthAccount(account="rfpFv97Dwu89FTyUwPjtpZBbuZxTqqgTmH"), + AuthAccount(account="rzzYHPGb8Pa64oqxCzmuffm122bitq3Vb"), + AuthAccount(account="rhwxHxaHok86fe4LykBom1jSJ3RYQJs1h4"), + ], + ) + expected = { + "Account": "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + "Asset": {"currency": "XRP"}, + "Asset2": { + "currency": "ETH", + "issuer": "rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW", + }, + "BidMin": { + "currency": "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", + "issuer": "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", + "value": "25", + }, + "BidMax": { + "currency": "5475B6C930B7BDD81CDA8FBA5CED962B11218E5A", + "issuer": "r3628pXjRqfw5zfwGfhSusjZTvE3BoxEBw", + "value": "35", + }, + "AuthAccounts": [ + { + "AuthAccount": { + "Account": "rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh", + } + }, + { + "AuthAccount": { + "Account": "rfpFv97Dwu89FTyUwPjtpZBbuZxTqqgTmH", + } + }, + { + "AuthAccount": { + "Account": "rzzYHPGb8Pa64oqxCzmuffm122bitq3Vb", + } + }, + { + "AuthAccount": { + "Account": "rhwxHxaHok86fe4LykBom1jSJ3RYQJs1h4", + } + }, + ], + "TransactionType": "AMMBid", + "SigningPubKey": "", + "Flags": 0, + } + self.assertEqual(tx.to_xrpl(), expected) From 494ea6ceb0fb6d7d7794408a57c5badeb61b75df Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Fri, 28 Jul 2023 11:42:41 -0400 Subject: [PATCH 85/88] fix indentation with tests --- .../unit/models/transactions/test_amm_bid.py | 8 +++---- .../models/transactions/test_amm_create.py | 16 ++++++------- .../models/transactions/test_amm_deposit.py | 24 +++++++++---------- .../unit/models/transactions/test_amm_vote.py | 16 ++++++------- .../models/transactions/test_amm_withdraw.py | 16 ++++++------- 5 files changed, 40 insertions(+), 40 deletions(-) diff --git a/tests/unit/models/transactions/test_amm_bid.py b/tests/unit/models/transactions/test_amm_bid.py index 21a33f9ba..b93c243d1 100644 --- a/tests/unit/models/transactions/test_amm_bid.py +++ b/tests/unit/models/transactions/test_amm_bid.py @@ -60,7 +60,7 @@ def test_auth_accounts_length_error(self): asset2=_ASSET2, auth_accounts=auth_accounts, ) - self.assertEqual( - error.exception.args[0], - "{'auth_accounts': 'Length must not be greater than 4'}", - ) + self.assertEqual( + error.exception.args[0], + "{'auth_accounts': 'Length must not be greater than 4'}", + ) diff --git a/tests/unit/models/transactions/test_amm_create.py b/tests/unit/models/transactions/test_amm_create.py index f8b3d392a..04e237653 100644 --- a/tests/unit/models/transactions/test_amm_create.py +++ b/tests/unit/models/transactions/test_amm_create.py @@ -31,10 +31,10 @@ def test_trading_fee_too_high(self): ), trading_fee=maxsize, ) - self.assertEqual( - error.exception.args[0], - "{'trading_fee': 'Must be between 0 and 1000'}", - ) + self.assertEqual( + error.exception.args[0], + "{'trading_fee': 'Must be between 0 and 1000'}", + ) def test_trading_fee_negative_number(self): with self.assertRaises(XRPLModelException) as error: @@ -46,7 +46,7 @@ def test_trading_fee_negative_number(self): ), trading_fee=-1, ) - self.assertEqual( - error.exception.args[0], - "{'trading_fee': 'Must be between 0 and 1000'}", - ) + self.assertEqual( + error.exception.args[0], + "{'trading_fee': 'Must be between 0 and 1000'}", + ) diff --git a/tests/unit/models/transactions/test_amm_deposit.py b/tests/unit/models/transactions/test_amm_deposit.py index d39d94aeb..c8a2612c7 100644 --- a/tests/unit/models/transactions/test_amm_deposit.py +++ b/tests/unit/models/transactions/test_amm_deposit.py @@ -91,10 +91,10 @@ def test_undefined_amount_undefined_lptokenout_invalid_combo(self): asset=_ASSET, asset2=_ASSET2, ) - self.assertEqual( - error.exception.args[0], - "{'AMMDeposit': 'Must set at least `lp_token_out` or `amount`'}", - ) + self.assertEqual( + error.exception.args[0], + "{'AMMDeposit': 'Must set at least `lp_token_out` or `amount`'}", + ) def test_undefined_amount_defined_amount2_invalid_combo(self): with self.assertRaises(XRPLModelException) as error: @@ -107,10 +107,10 @@ def test_undefined_amount_defined_amount2_invalid_combo(self): currency=_ASSET2.currency, issuer=_ASSET2.issuer, value="500" ), ) - self.assertEqual( - error.exception.args[0], - "{'AMMDeposit': 'Must set `amount` with `amount2`'}", - ) + self.assertEqual( + error.exception.args[0], + "{'AMMDeposit': 'Must set `amount` with `amount2`'}", + ) def test_undefined_amount_defined_eprice_invalid_combo(self): with self.assertRaises(XRPLModelException) as error: @@ -121,7 +121,7 @@ def test_undefined_amount_defined_eprice_invalid_combo(self): asset2=_ASSET2, e_price="25", ) - self.assertEqual( - error.exception.args[0], - "{'AMMDeposit': 'Must set `amount` with `e_price`'}", - ) + self.assertEqual( + error.exception.args[0], + "{'AMMDeposit': 'Must set `amount` with `e_price`'}", + ) diff --git a/tests/unit/models/transactions/test_amm_vote.py b/tests/unit/models/transactions/test_amm_vote.py index 45c28bc7e..7adcd5c78 100644 --- a/tests/unit/models/transactions/test_amm_vote.py +++ b/tests/unit/models/transactions/test_amm_vote.py @@ -29,10 +29,10 @@ def test_trading_fee_too_high(self): asset2=_ASSET2, trading_fee=maxsize, ) - self.assertEqual( - error.exception.args[0], - "{'trading_fee': 'Must be between 0 and 1000'}", - ) + self.assertEqual( + error.exception.args[0], + "{'trading_fee': 'Must be between 0 and 1000'}", + ) def test_trading_fee_negative_number(self): with self.assertRaises(XRPLModelException) as error: @@ -42,7 +42,7 @@ def test_trading_fee_negative_number(self): asset2=_ASSET2, trading_fee=-1, ) - self.assertEqual( - error.exception.args[0], - "{'trading_fee': 'Must be between 0 and 1000'}", - ) + self.assertEqual( + error.exception.args[0], + "{'trading_fee': 'Must be between 0 and 1000'}", + ) diff --git a/tests/unit/models/transactions/test_amm_withdraw.py b/tests/unit/models/transactions/test_amm_withdraw.py index aae365a25..6c9635dcc 100644 --- a/tests/unit/models/transactions/test_amm_withdraw.py +++ b/tests/unit/models/transactions/test_amm_withdraw.py @@ -115,10 +115,10 @@ def test_undefined_amount_defined_amount2_invalid_combo(self): currency=_ASSET2.currency, issuer=_ASSET2.issuer, value="500" ), ) - self.assertEqual( - error.exception.args[0], - "{'AMMWithdraw': 'Must set `amount` with `amount2`'}", - ) + self.assertEqual( + error.exception.args[0], + "{'AMMWithdraw': 'Must set `amount` with `amount2`'}", + ) def test_undefined_amount_defined_eprice_invalid_combo(self): with self.assertRaises(XRPLModelException) as error: @@ -129,7 +129,7 @@ def test_undefined_amount_defined_eprice_invalid_combo(self): asset2=_ASSET2, e_price="25", ) - self.assertEqual( - error.exception.args[0], - "{'AMMWithdraw': 'Must set `amount` with `e_price`'}", - ) + self.assertEqual( + error.exception.args[0], + "{'AMMWithdraw': 'Must set `amount` with `e_price`'}", + ) From 3ef57c5d45b0873f59222251659832827de68364 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Mon, 7 Aug 2023 21:08:51 -0400 Subject: [PATCH 86/88] update definitions --- xrpl/core/binarycodec/definitions/definitions.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/xrpl/core/binarycodec/definitions/definitions.json b/xrpl/core/binarycodec/definitions/definitions.json index f073128bf..1ab810e44 100644 --- a/xrpl/core/binarycodec/definitions/definitions.json +++ b/xrpl/core/binarycodec/definitions/definitions.json @@ -2549,7 +2549,11 @@ "tecUNFUNDED_AMM": 162, "tecAMM_BALANCE": 163, "tecAMM_FAILED": 164, - "tecAMM_INVALID_TOKENS": 165 + "tecAMM_INVALID_TOKENS": 165, + "tecAMM_EMPTY": 166, + "tecAMM_NOT_EMPTY": 167, + "tecAMM_ACCOUNT": 168, + "tecINCOMPLETE": 169 }, "TRANSACTION_TYPES": { "Invalid": -1, @@ -2581,12 +2585,13 @@ "NFTokenCreateOffer": 27, "NFTokenCancelOffer": 28, "NFTokenAcceptOffer": 29, - "Clawback":30, + "Clawback": 30, "AMMCreate": 35, "AMMDeposit": 36, "AMMWithdraw": 37, "AMMVote": 38, "AMMBid": 39, + "AMMDelete": 40, "EnableAmendment": 100, "SetFee": 101, "UNLModify": 102 From 0fbedec8eeadd2f563a2a158f28bafd516e3934f Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Mon, 7 Aug 2023 22:51:25 -0400 Subject: [PATCH 87/88] add AMMDelete --- .../models/transactions/test_amm_delete.py | 17 ++++++++++ xrpl/models/transactions/__init__.py | 2 ++ xrpl/models/transactions/amm_delete.py | 31 +++++++++++++++++++ .../transactions/types/transaction_type.py | 1 + 4 files changed, 51 insertions(+) create mode 100644 tests/unit/models/transactions/test_amm_delete.py create mode 100644 xrpl/models/transactions/amm_delete.py diff --git a/tests/unit/models/transactions/test_amm_delete.py b/tests/unit/models/transactions/test_amm_delete.py new file mode 100644 index 000000000..37ff6b9f6 --- /dev/null +++ b/tests/unit/models/transactions/test_amm_delete.py @@ -0,0 +1,17 @@ +from unittest import TestCase + +from xrpl.models.currencies import XRP, IssuedCurrency +from xrpl.models.transactions import AMMDelete + + +class TestAMMDeposit(TestCase): + def test_tx_valid(self): + tx = AMMDelete( + account="r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", + sequence=1337, + asset=XRP(), + asset2=IssuedCurrency( + currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" + ), + ) + self.assertTrue(tx.is_valid()) diff --git a/xrpl/models/transactions/__init__.py b/xrpl/models/transactions/__init__.py index d34512cf8..ef2e7835b 100644 --- a/xrpl/models/transactions/__init__.py +++ b/xrpl/models/transactions/__init__.py @@ -12,6 +12,7 @@ ) from xrpl.models.transactions.amm_bid import AMMBid, AuthAccount from xrpl.models.transactions.amm_create import AMMCreate +from xrpl.models.transactions.amm_delete import AMMDelete from xrpl.models.transactions.amm_deposit import ( AMMDeposit, AMMDepositFlag, @@ -77,6 +78,7 @@ "AccountSetFlagInterface", "AMMBid", "AMMCreate", + "AMMDelete", "AMMDeposit", "AMMDepositFlag", "AMMDepositFlagInterface", diff --git a/xrpl/models/transactions/amm_delete.py b/xrpl/models/transactions/amm_delete.py new file mode 100644 index 000000000..dae7f7eab --- /dev/null +++ b/xrpl/models/transactions/amm_delete.py @@ -0,0 +1,31 @@ +"""Model for AMMDelete transaction type.""" +from __future__ import annotations + +from dataclasses import dataclass, field + +from xrpl.models.currencies import Currency +from xrpl.models.required import REQUIRED +from xrpl.models.transactions.transaction import Transaction +from xrpl.models.transactions.types import TransactionType +from xrpl.models.utils import require_kwargs_on_init + + +@require_kwargs_on_init +@dataclass(frozen=True) +class AMMDelete(Transaction): + """TODO: Fill in when docs are ready.""" + + asset: Currency = REQUIRED # type: ignore + """ + The definition for one of the assets in the AMM's pool. This field is required. + """ + + asset2: Currency = REQUIRED # type: ignore + """ + The definition for the other asset in the AMM's pool. This field is required. + """ + + transaction_type: TransactionType = field( + default=TransactionType.AMM_DELETE, + init=False, + ) diff --git a/xrpl/models/transactions/types/transaction_type.py b/xrpl/models/transactions/types/transaction_type.py index 50f0e97a0..691f797ac 100644 --- a/xrpl/models/transactions/types/transaction_type.py +++ b/xrpl/models/transactions/types/transaction_type.py @@ -10,6 +10,7 @@ class TransactionType(str, Enum): ACCOUNT_SET = "AccountSet" AMM_BID = "AMMBid" AMM_CREATE = "AMMCreate" + AMM_DELETE = "AMMDelete" AMM_DEPOSIT = "AMMDeposit" AMM_VOTE = "AMMVote" AMM_WITHDRAW = "AMMWithdraw" From a1c08179098d00b39f61a0c731bd2d3bb206fccf Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 16 Aug 2023 15:23:26 -0400 Subject: [PATCH 88/88] add AMMDelete docstring --- xrpl/models/transactions/amm_delete.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/xrpl/models/transactions/amm_delete.py b/xrpl/models/transactions/amm_delete.py index dae7f7eab..c13e65ca8 100644 --- a/xrpl/models/transactions/amm_delete.py +++ b/xrpl/models/transactions/amm_delete.py @@ -13,7 +13,19 @@ @require_kwargs_on_init @dataclass(frozen=True) class AMMDelete(Transaction): - """TODO: Fill in when docs are ready.""" + """ + Delete an empty Automated Market Maker (AMM) instance that could not be fully + deleted automatically. + + Tip: The AMMWithdraw transaction automatically tries to delete an AMM, along with + associated ledger entries such as empty trust lines, if it withdrew all the assets + from the AMM's pool. However, if there are too many trust lines to the AMM account + to remove in one transaction, it may stop before fully removing the AMM. Similarly, + an AMMDelete transaction removes up to a maximum number of trust lines; in extreme + cases, it may take several AMMDelete transactions to fully delete the trust lines + and the associated AMM. In all cases, the AMM ledger entry and AMM account are + deleted by the last such transaction. + """ asset: Currency = REQUIRED # type: ignore """