-
Notifications
You must be signed in to change notification settings - Fork 123
Support XLS-82d MPT-DEX #914
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 13 commits
daef7d7
64aed2a
89de601
8d012e8
c70ca64
9d31b13
c8e11ec
df6982b
96a3f07
c5fd778
af44d86
780b2d2
979ac66
b86aefa
72b8422
1e3e3ee
3dbcc95
ae07971
c80eeec
3cb8d1e
e7e8609
01b19a7
f13833e
0dfa1ee
e6d2634
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,15 +13,20 @@ | |
| from xrpl.asyncio.transaction import sign_and_submit as sign_and_submit_async | ||
| from xrpl.clients import Client, JsonRpcClient, WebsocketClient | ||
| from xrpl.clients.sync_client import SyncClient | ||
| from xrpl.constants import CryptoAlgorithm | ||
| from xrpl.constants import CryptoAlgorithm, XRPLException | ||
| from xrpl.models import GenericRequest, Payment, Request, Response, Transaction | ||
| from xrpl.models.amounts import MPTAmount | ||
| from xrpl.models.amounts.issued_currency_amount import IssuedCurrencyAmount | ||
| from xrpl.models.currencies.issued_currency import IssuedCurrency | ||
| from xrpl.models.currencies.mpt_currency import MPTCurrency | ||
| from xrpl.models.currencies.xrp import XRP | ||
| from xrpl.models.requests import Ledger | ||
| from xrpl.models.requests.account_objects import AccountObjects, AccountObjectType | ||
| from xrpl.models.transactions import MPTokenAuthorize, MPTokenIssuanceCreate | ||
| from xrpl.models.transactions import ( | ||
| MPTokenAuthorize, | ||
| MPTokenIssuanceCreate, | ||
| MPTokenIssuanceCreateFlag, | ||
| ) | ||
| from xrpl.models.transactions.account_set import AccountSet, AccountSetAsfFlag | ||
| from xrpl.models.transactions.amm_create import AMMCreate | ||
| from xrpl.models.transactions.oracle_set import OracleSet | ||
|
|
@@ -600,6 +605,10 @@ def create_mpt_token_and_authorize_source( | |
| ) | ||
|
|
||
| tx_resp = sign_and_reliable_submission(mp_token_issuance, issuer, client=client) | ||
| if tx_resp.result["engine_result"] != "tesSUCCESS": | ||
| raise XRPLException( | ||
| f"Unable to execute MPTokenIssuanceCreate Transaction: {tx_resp}" | ||
| ) | ||
| seq = tx_resp.result["tx_json"]["Sequence"] | ||
|
|
||
| response = client.request( | ||
|
|
@@ -622,7 +631,77 @@ def create_mpt_token_and_authorize_source( | |
| account=source.classic_address, | ||
| mptoken_issuance_id=mpt_issuance_id, | ||
| ) | ||
| sign_and_reliable_submission(authorize_tx, source, client=client) | ||
| response = sign_and_reliable_submission(authorize_tx, source, client=client) | ||
| if response.result["engine_result"] != "tesSUCCESS": | ||
| raise XRPLException( | ||
| f"Unable to execute MPTokenAuthorize Transaction: {response}" | ||
| ) | ||
|
|
||
| # Send some MPToken to the source wallet that can be used further. | ||
| payment_tx = Payment( | ||
| account=issuer.address, | ||
| destination=source.address, | ||
| amount=MPTAmount( | ||
| mpt_issuance_id=mpt_issuance_id, | ||
| value="100000", | ||
| ), | ||
| ) | ||
| response = sign_and_reliable_submission(payment_tx, issuer, client=client) | ||
| if response.result["engine_result"] != "tesSUCCESS": | ||
| raise XRPLException(f"Unable to execute Payment Transaction: {response}") | ||
|
|
||
| return mpt_issuance_id | ||
|
|
||
|
|
||
| async def create_mpt_token_and_authorize_source_async( | ||
| issuer: Wallet, | ||
| source: Wallet, | ||
| client: AsyncClient = ASYNC_JSON_RPC_CLIENT, | ||
| flags: Optional[List[int]] = None, | ||
| ) -> str: | ||
|
|
||
| mp_token_issuance = MPTokenIssuanceCreate( | ||
| account=issuer.classic_address, | ||
| flags=flags, | ||
| ) | ||
|
|
||
| tx_resp = await sign_and_reliable_submission_async( | ||
| mp_token_issuance, issuer, client=client | ||
| ) | ||
| if tx_resp.result["engine_result"] != "tesSUCCESS": | ||
| raise XRPLException( | ||
| f"Unable to execute MPTokenIssuanceCreate Transaction: {tx_resp}" | ||
| ) | ||
|
|
||
| seq = tx_resp.result["tx_json"]["Sequence"] | ||
|
|
||
| response = await client.request( | ||
| AccountObjects(account=issuer.address, type=AccountObjectType.MPT_ISSUANCE) | ||
| ) | ||
|
|
||
| mpt_issuance_id = "" | ||
| for obj in response.result["account_objects"]: | ||
| if obj.get("Issuer") == issuer.classic_address and obj.get("Sequence") == seq: | ||
| mpt_issuance_id = obj["mpt_issuance_id"] | ||
| break | ||
|
|
||
| if not mpt_issuance_id: | ||
| raise ValueError( | ||
| f"MPT issuance ID not found for issuer " | ||
| f"{issuer.classic_address} and sequence {seq}" | ||
| ) | ||
|
|
||
| authorize_tx = MPTokenAuthorize( | ||
| account=source.classic_address, | ||
| mptoken_issuance_id=mpt_issuance_id, | ||
| ) | ||
| response = await sign_and_reliable_submission_async( | ||
| authorize_tx, source, client=client | ||
| ) | ||
| if response.result["engine_result"] != "tesSUCCESS": | ||
| raise XRPLException( | ||
| f"Unable to execute MPTokenAuthorize Transaction: {response}" | ||
| ) | ||
|
|
||
| # Send some MPToken to the source wallet that can be used further. | ||
| payment_tx = Payment( | ||
|
|
@@ -633,6 +712,146 @@ def create_mpt_token_and_authorize_source( | |
| value="100000", | ||
| ), | ||
| ) | ||
| sign_and_reliable_submission(payment_tx, issuer, client=client) | ||
| response = await sign_and_reliable_submission_async( | ||
| payment_tx, issuer, client=client | ||
| ) | ||
| if response.result["engine_result"] != "tesSUCCESS": | ||
| raise XRPLException(f"Unable to execute Payment Transaction: {response}") | ||
|
|
||
| return mpt_issuance_id | ||
|
|
||
|
|
||
| def create_amm_pool_with_mpt(client: SyncClient = JSON_RPC_CLIENT) -> Dict[str, Any]: | ||
| issuer_wallet_1 = Wallet.create() | ||
| fund_wallet(issuer_wallet_1) | ||
| issuer_wallet_2 = Wallet.create() | ||
| fund_wallet(issuer_wallet_2) | ||
| lp_wallet = Wallet.create() | ||
| fund_wallet(lp_wallet) | ||
|
|
||
| # Create MPT tokens and authorize LP wallet for both | ||
| mpt_issuance_id_1 = create_mpt_token_and_authorize_source( | ||
| issuer=issuer_wallet_1, | ||
| source=lp_wallet, | ||
| client=client, | ||
| flags=[ | ||
| MPTokenIssuanceCreateFlag.TF_MPT_CAN_TRANSFER, | ||
| MPTokenIssuanceCreateFlag.TF_MPT_CAN_TRADE, | ||
| MPTokenIssuanceCreateFlag.TF_MPT_CAN_CLAWBACK, | ||
| ], | ||
| ) | ||
| mpt_issuance_id_2 = create_mpt_token_and_authorize_source( | ||
| issuer=issuer_wallet_2, | ||
| source=lp_wallet, | ||
| client=client, | ||
| flags=[ | ||
| MPTokenIssuanceCreateFlag.TF_MPT_CAN_TRANSFER, | ||
| MPTokenIssuanceCreateFlag.TF_MPT_CAN_TRADE, | ||
| MPTokenIssuanceCreateFlag.TF_MPT_CAN_CLAWBACK, | ||
| ], | ||
| ) | ||
|
|
||
| # Create the AMM pool with both MPT amounts | ||
| response = sign_and_reliable_submission( | ||
| AMMCreate( | ||
| account=lp_wallet.classic_address, | ||
| amount=MPTAmount( | ||
| mpt_issuance_id=mpt_issuance_id_1, | ||
| value="250", | ||
| ), | ||
| amount2=MPTAmount( | ||
| mpt_issuance_id=mpt_issuance_id_2, | ||
| value="250", | ||
| ), | ||
| trading_fee=12, | ||
| ), | ||
| lp_wallet, | ||
| client, | ||
| ) | ||
| if ( | ||
| not response.is_successful() | ||
| or response.result.get("engine_result") != "tesSUCCESS" | ||
| ): | ||
| raise ValueError( | ||
| f"AMMCreate transaction failed: {response.result.get('engine_result')}" | ||
| ) | ||
|
Comment on lines
+771
to
+777
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
🛠️ Proposed fix- raise ValueError(
- f"AMMCreate transaction failed: {response.result.get('engine_result')}"
- )
+ raise XRPLException(
+ f"AMMCreate transaction failed: {response.result.get('engine_result')}"
+ )Apply the same change at lines 844–846 in 🧰 Tools🪛 Ruff (0.15.1)[warning] 775-777: Avoid specifying long messages outside the exception class (TRY003) 🤖 Prompt for AI Agents |
||
|
|
||
| asset = MPTCurrency(mpt_issuance_id=mpt_issuance_id_1) | ||
| asset2 = MPTCurrency(mpt_issuance_id=mpt_issuance_id_2) | ||
|
|
||
| return { | ||
| "asset": asset, | ||
| "asset2": asset2, | ||
| "issuer_wallet_1": issuer_wallet_1, | ||
| "issuer_wallet_2": issuer_wallet_2, | ||
| "lp_wallet": lp_wallet, | ||
| } | ||
|
|
||
|
|
||
| async def create_amm_pool_with_mpt_async( | ||
| client: AsyncClient = ASYNC_JSON_RPC_CLIENT, | ||
| ) -> Dict[str, Any]: | ||
| issuer_wallet_1 = Wallet.create() | ||
| await fund_wallet_async(issuer_wallet_1) | ||
| issuer_wallet_2 = Wallet.create() | ||
| await fund_wallet_async(issuer_wallet_2) | ||
| lp_wallet = Wallet.create() | ||
| await fund_wallet_async(lp_wallet) | ||
|
|
||
| # Create MPT tokens and authorize LP wallet for both | ||
| mpt_issuance_id_1 = await create_mpt_token_and_authorize_source_async( | ||
| issuer=issuer_wallet_1, | ||
| source=lp_wallet, | ||
| client=client, | ||
| flags=[ | ||
| MPTokenIssuanceCreateFlag.TF_MPT_CAN_TRANSFER, | ||
| MPTokenIssuanceCreateFlag.TF_MPT_CAN_TRADE, | ||
| MPTokenIssuanceCreateFlag.TF_MPT_CAN_CLAWBACK, | ||
| ], | ||
| ) | ||
| mpt_issuance_id_2 = await create_mpt_token_and_authorize_source_async( | ||
| issuer=issuer_wallet_2, | ||
| source=lp_wallet, | ||
| client=client, | ||
| flags=[ | ||
| MPTokenIssuanceCreateFlag.TF_MPT_CAN_TRANSFER, | ||
| MPTokenIssuanceCreateFlag.TF_MPT_CAN_TRADE, | ||
| MPTokenIssuanceCreateFlag.TF_MPT_CAN_CLAWBACK, | ||
| ], | ||
| ) | ||
|
|
||
| # Create the AMM pool with both MPT amounts | ||
| response = await sign_and_reliable_submission_async( | ||
| AMMCreate( | ||
| account=lp_wallet.classic_address, | ||
| amount=MPTAmount( | ||
| mpt_issuance_id=mpt_issuance_id_1, | ||
| value="250", | ||
| ), | ||
| amount2=MPTAmount( | ||
| mpt_issuance_id=mpt_issuance_id_2, | ||
| value="250", | ||
| ), | ||
| trading_fee=12, | ||
| ), | ||
| lp_wallet, | ||
| client, | ||
| ) | ||
| if ( | ||
| not response.is_successful() | ||
| or response.result.get("engine_result") != "tesSUCCESS" | ||
| ): | ||
| raise ValueError( | ||
| f"AMMCreate transaction failed: {response.result.get('engine_result')}" | ||
| ) | ||
|
|
||
| asset = MPTCurrency(mpt_issuance_id=mpt_issuance_id_1) | ||
| asset2 = MPTCurrency(mpt_issuance_id=mpt_issuance_id_2) | ||
|
|
||
| return { | ||
| "asset": asset, | ||
| "asset2": asset2, | ||
| "issuer_wallet_1": issuer_wallet_1, | ||
| "issuer_wallet_2": issuer_wallet_2, | ||
| "lp_wallet": lp_wallet, | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,5 +1,8 @@ | ||||||||||||||||||||||
| from tests.integration.integration_test_case import IntegrationTestCase | ||||||||||||||||||||||
| from tests.integration.it_utils import test_async_and_sync | ||||||||||||||||||||||
| from tests.integration.it_utils import ( | ||||||||||||||||||||||
| create_amm_pool_with_mpt_async, | ||||||||||||||||||||||
| test_async_and_sync, | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
|
Comment on lines
+2
to
+5
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unused import causes pipeline failure — add
🔧 Proposed fix from tests.integration.it_utils import (
- create_amm_pool_with_mpt,
+ create_amm_pool_with_mpt, # noqa: F401 - used by test_async_and_sync generated sync code
create_amm_pool_with_mpt_async,
test_async_and_sync,
)📝 Committable suggestion
Suggested change
🧰 Tools🪛 Flake8 (7.3.0)[error] 2-2: 'tests.integration.it_utils.create_amm_pool_with_mpt' imported but unused (F401) 🪛 GitHub Actions: Unit test[error] 2-2: F401 'tests.integration.it_utils.create_amm_pool_with_mpt' imported but unused 🤖 Prompt for AI Agents
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this error has not been observed in the CI tests or the local integ tests.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Since the test only uses from tests.integration.it_utils import (
create_amm_pool_with_mpt_async,
test_async_and_sync,
)If CI isn't flagging it as a failure, you can leave it as-is or clean it up in a follow-up. Thank you for the correction! 🧠 Learnings used |
||||||||||||||||||||||
| from tests.integration.reusable_values import AMM_ASSET, AMM_ASSET2 | ||||||||||||||||||||||
| from xrpl.models.requests.amm_info import AMMInfo | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -26,3 +29,35 @@ async def test_basic_functionality(self, client): | |||||||||||||||||||||
| "value": "250", | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @test_async_and_sync(globals()) | ||||||||||||||||||||||
| async def test_amm_info_with_mpt_assets(self, client): | ||||||||||||||||||||||
| amm_pool = await create_amm_pool_with_mpt_async(client) | ||||||||||||||||||||||
| mpt_asset = amm_pool["asset"] | ||||||||||||||||||||||
| mpt_asset2 = amm_pool["asset2"] | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| amm_info = await client.request( | ||||||||||||||||||||||
| AMMInfo( | ||||||||||||||||||||||
| asset=mpt_asset, | ||||||||||||||||||||||
| asset2=mpt_asset2, | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| amm = amm_info.result["amm"] | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| self.assertEqual( | ||||||||||||||||||||||
| amm["amount"], | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| "mpt_issuance_id": mpt_asset.mpt_issuance_id, | ||||||||||||||||||||||
| "value": "250", | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
| self.assertEqual( | ||||||||||||||||||||||
| amm["amount2"], | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| "mpt_issuance_id": mpt_asset2.mpt_issuance_id, | ||||||||||||||||||||||
| "value": "250", | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
| self.assertEqual(amm["trading_fee"], 12) | ||||||||||||||||||||||
| self.assertIn("lp_token", amm) | ||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.