import asyncio import json from xrpl.asyncio.clients import AsyncWebsocketClient from xrpl.asyncio.transaction import submit_and_wait from xrpl.asyncio.wallet import generate_faucet_wallet from xrpl.models import ( MPTokenAuthorize, MPTokenIssuanceCreate, MPTokenIssuanceCreateFlag, Payment, ) from xrpl.models.amounts import MPTAmount from xrpl.utils import encode_mptoken_metadata WSS_URL = "wss://s.altnet.rippletest.net:51233" TOTAL_STEPS = 4 async def main(): async with AsyncWebsocketClient(WSS_URL) as client: step = 1 # Fund issuer and sender in parallel print(f"Setting up tutorial: {step}/{TOTAL_STEPS}", end="\r") step += 1 issuer, sender = await asyncio.gather( generate_faucet_wallet(client), generate_faucet_wallet(client), ) # Issue MPT with Can Transfer flag print(f"Setting up tutorial: {step}/{TOTAL_STEPS}", end="\r") step += 1 # XLS-89 metadata, encoded to hex with the SDK utility. metadata = { "ticker": "TUTO", "name": "Tutorial Token", "desc": "Example MPT for the Send an MPT tutorial.", "icon": "https://example.org/tutorial-icon.png", "asset_class": "other", "issuer_name": "XRPL Tutorial Issuer", } issue_resp = await submit_and_wait( MPTokenIssuanceCreate( account=issuer.address, asset_scale=2, maximum_amount="1000000", transfer_fee=30, flags=MPTokenIssuanceCreateFlag.TF_MPT_CAN_TRANSFER, mptoken_metadata=encode_mptoken_metadata(metadata), ), client, issuer, autofill=True, ) if issue_resp.result["meta"]["TransactionResult"] != "tesSUCCESS": raise RuntimeError(f"MPTokenIssuanceCreate failed: {issue_resp.result['meta']['TransactionResult']}") mpt_issuance_id = issue_resp.result["meta"]["mpt_issuance_id"] # Sender authorizes the MPT print(f"Setting up tutorial: {step}/{TOTAL_STEPS}", end="\r") step += 1 auth_resp = await submit_and_wait( MPTokenAuthorize( account=sender.address, mptoken_issuance_id=mpt_issuance_id, ), client, sender, autofill=True, ) if auth_resp.result["meta"]["TransactionResult"] != "tesSUCCESS": raise RuntimeError(f"MPTokenAuthorize failed: {auth_resp.result['meta']['TransactionResult']}") # Issuer sends sender MPTs print(f"Setting up tutorial: {step}/{TOTAL_STEPS}", end="\r") seed_resp = await submit_and_wait( Payment( account=issuer.address, destination=sender.address, amount=MPTAmount(mpt_issuance_id=mpt_issuance_id, value="500"), ), client, issuer, autofill=True, ) if seed_resp.result["meta"]["TransactionResult"] != "tesSUCCESS": raise RuntimeError(f"Issuer seed payment failed: {seed_resp.result['meta']['TransactionResult']}") # Write setup data setup_data = { "description": "This file is auto-generated by send_mpt_setup.py. It stores XRPL account info and the MPT issuance ID for the send-an-mpt tutorial.", "issuer": {"address": issuer.address, "seed": issuer.seed}, "sender": {"address": sender.address, "seed": sender.seed}, "mpt_issuance_id": mpt_issuance_id, } with open("send_mpt_setup.json", "w") as f: json.dump(setup_data, f, indent=2) if __name__ == "__main__": asyncio.run(main())