Incorporate MPT Use Case 2 with Use Case 1

This commit is contained in:
Dennis Dawson
2025-03-20 14:00:46 -07:00
parent a1d8cb1063
commit 09826b9035
18 changed files with 1103 additions and 5 deletions

View File

@@ -0,0 +1,103 @@
// ******************************************************
// ************* Get the Preferred Network **************
// ******************************************************
function getNet() {
let net
if (document.getElementById("tn").checked) net = "wss://s.altnet.rippletest.net:51233"
if (document.getElementById("dn").checked) net = "wss://s.devnet.rippletest.net:51233"
return net
} // End of getNet()
// *******************************************************
// ************* Get Account *****************************
// *******************************************************
async function getAccount(type) {
let net = getNet()
const client = new xrpl.Client(net)
results = 'Connecting to ' + net + '....'
// This uses the default faucet for Testnet/Devnet
let faucetHost = null
if (type == 'left') {
leftResultField.value = results
} else {
rightResultField.value = results
}
await client.connect()
results += '\nConnected, funding wallet.'
if (type == 'left') {
leftResultField.value = results
} else {
rightResultField.value = results
}
// -----------------------------------Create and fund a test account wallet
const my_wallet = (await client.fundWallet(null, { faucetHost })).wallet
results += '\nGot a wallet.'
if (type == 'left') {
leftResultField.value = results
} else {
rightResultField.value = results
}
// ------------------------------------------------------Get the current balance.
const my_balance = (await client.getXrpBalance(my_wallet.address))
if (type == 'left') {
leftAccountField.value = my_wallet.address
leftBalanceField.value = (await client.getXrpBalance(my_wallet.address))
leftSeedField.value = my_wallet.seed
results += '\nStandby account created.'
leftResultField.value = results
} else {
rightAccountField.value = my_wallet.address
rightSeedField.value = my_wallet.seed
rightBalanceField.value = (await client.getXrpBalance(my_wallet.address))
results += '\nOperational account created.'
rightResultField.value = results
}
// --------------- Capture the seeds for both accounts for ease of reload.
seeds.value = leftSeedField.value + '\n' + rightSeedField.value
client.disconnect()
} // End of getAccount()
// *******************************************************
// ********** Get Accounts from Seeds ********************
// *******************************************************
async function getAccountsFromSeeds() {
let net = getNet()
const client = new xrpl.Client(net)
results = 'Connecting to ' + getNet() + '....'
leftResultField.value = results
await client.connect()
results += '\nConnected, finding wallets.\n'
leftResultField.value = results
// -------------------------------------------------Find the test account wallets.
var lines = seeds.value.split('\n')
const left_wallet = xrpl.Wallet.fromSeed(lines[0])
const right_wallet = xrpl.Wallet.fromSeed(lines[1])
// -------------------------------------------------------Get the current balance.
const left_balance = (await client.getXrpBalance(left_wallet.address))
const right_balance = (await client.getXrpBalance(right_wallet.address))
// ----------------------Populate the fields for Standby and Operational accounts.
leftAccountField.value = left_wallet.address
leftSeedField.value = left_wallet.seed
leftBalanceField.value = (await client.getXrpBalance(left_wallet.address))
rightAccountField.value = right_wallet.address
rightSeedField.value = right_wallet.seed
rightBalanceField.value = (await client.getXrpBalance(right_wallet.address))
client.disconnect()
} // End of getAccountsFromSeeds()

View File

@@ -0,0 +1,139 @@
body {
font-family: "Inter", sans-serif;
padding: 20px;
background: #abe2ff;
}
h1 {
font-weight: bold;
}
td {
padding-left: 25px;
vertical-align: top;
}
input,
button {
padding: 6px;
margin-bottom: 8px;
border: none
}
button {
font-weight: bold;
font-family: "Work Sans", sans-serif;
background-color: #006aff;
-webkit-text-fill-color: white;
}
td {
vertical-align: middle;
}
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked+.slider {
background-color: #2196F3;
}
input:focus+.slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked+.slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
.tooltip {
position: relative;
border-bottom: 1px dotted black;
}
.tooltip:before {
content: attr(tooltip-data);
position: absolute;
width: 250px;
background-color: #006aff;
color: #fff;
text-align: center;
padding: 15px;
line-height: 1.1;
border-radius: 5px;
z-index: 1;
opacity: 0;
transition: opacity .5s;
bottom: 125%;
left: 50%;
margin-left: -60px;
font-size: 0.70em;
visibility: hidden;
}
.tooltip:after {
content: "";
position: absolute;
bottom: 75%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
opacity: 0;
transition: opacity .5s;
border-color: #000 transparent transparent transparent;
visibility: hidden;
}
.tooltip:hover:before,
.tooltip:hover:after {
opacity: 1;
visibility: visible;
}

Binary file not shown.

View File

@@ -0,0 +1,211 @@
<html>
<head>
<title>Send MPT Test Harness</title>
<link href='https://fonts.googleapis.com/css?family=Work Sans' rel='stylesheet'>
<link href="mpt-generator.css" rel="stylesheet">
<script src='https://unpkg.com/xrpl@4.1.0/build/xrpl-latest.js'></script>
<script src='get-accounts.js'></script>
<script src='send-mpt.js'></script>
<script>
if (typeof module !== "undefined") {
const xrpl = require('xrpl')
}
</script>
</head>
<!-- ************************************************************** -->
<!-- ********************** The Form ****************************** -->
<!-- ************************************************************** -->
<body>
<h1>Send MPTs</h1>
<form id="theForm">
Choose your ledger instance:
&nbsp;&nbsp;
<input type="radio" id="tn" name="server"
value="wss://s.altnet.rippletest.net:51233" >
<label for="testnet">Testnet</label>
&nbsp;&nbsp;
<input type="radio" id="dn" name="server"
value="wss://s.devnet.rippletest.net:51233" checked>
<label for="devnet">Devnet</label>
<br/><br/>
<button type="button" onClick="getAccountsFromSeeds()">Get Accounts From Seeds</button>
<br/>
<textarea id="seeds" cols="40" rows= "2"></textarea>
<br/><br/>
<table>
<tr valign="top">
<td>
<table>
<tr valign="top">
<td>
<td>
<button type="button" onClick="getAccount('left')">Get New Left Account</button>
<table>
<tr valign="top">
<td align="right">
Left Account
</td>
<td>
<input type="text" id="leftAccountField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
Seed
</td>
<td>
<input type="text" id="leftSeedField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
XRP Balance
</td>
<td>
<input type="text" id="leftBalanceField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
Quantity
</td>
<td>
<input type="text" id="leftQuantityField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
Destination
</td>
<td>
<input type="text" id="leftDestinationField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
MPT Issuance ID
</td>
<td>
<input type="text" id="leftIssuanceIdField" size="40"></input>
</td>
</tr>
</table>
<p align="left">
<textarea id="leftResultField" cols="80" rows="20" ></textarea>
</p>
</td>
</td>
<td>
<table>
<tr valign="top">
<td align="center" valign="top">
<button type="button" onClick="MPTAuthorize()">Authorize MPTs</button>
<br/>
<button type="button" onClick="sendMPT()">Send MPT</button>
<br/>
<button type="button" onClick="getMPTs()">Get MPTs</button>
</td>
</tr>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
<td>
<table>
<tr>
<td>
<td>
<table>
<tr>
<td align="center" valign="top">
<button type="button" onClick="rightMPTAuthorize()">Authorize MPTs</button>
<br/>
<button type="button" onClick="rightSendMPT()">Send MPT</button>
<br/>
<button type="button" onClick="rightGetMPTs()">Get MPTs</button>
</td>
<td valign="top" align="right">
<button type="button" onClick="getAccount('right')">Get New Right Account</button>
<table>
<tr valign="top">
<td align="right">
Right Account
</td>
<td>
<input type="text" id="rightAccountField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
Seed
</td>
<td>
<input type="text" id="rightSeedField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
XRP Balance
</td>
<td>
<input type="text" id="rightBalanceField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
Quantity
</td>
<td>
<input type="text" id="rightQuantityField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
Destination
</td>
<td>
<input type="text" id="rightDestinationField" size="40"></input>
<br>
</td>
</tr>
<tr>
<td align="right">
MPT Issuance ID
</td>
<td>
<input type="text" id="rightIssuanceIdField" size="40"></input>
</td>
</tr>
</table>
<p align="right">
<textarea id="rightResultField" cols="80" rows="20" ></textarea>
</p>
</td>
</td>
</tr>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</form>
</body>
</html>

View File

@@ -0,0 +1,235 @@
// *******************************************************
// ********************* Send MPT ************************
// *******************************************************
async function sendMPT() {
let net = getNet()
const client = new xrpl.Client(net)
results = 'Connecting to ' + getNet() + '....'
document.getElementById('leftResultField').value = results
await client.connect()
results += '\nConnected.'
leftResultField.value = results
const left_wallet = xrpl.Wallet.fromSeed(leftSeedField.value)
const mpt_issuance_id = leftIssuanceIdField.value
const mpt_quantity = leftQuantityField.value
const send_mpt_tx = {
"TransactionType": "Payment",
"Account": left_wallet.address,
"Amount": {
"mpt_issuance_id": mpt_issuance_id,
"value": mpt_quantity,
},
"Destination": leftDestinationField.value,
}
const pay_prepared = await client.autofill(send_mpt_tx)
const pay_signed = left_wallet.sign(pay_prepared)
results += `\n\nSending ${mpt_quantity} ${mpt_issuance_id} to ${leftDestinationField.value} ...`
leftResultField.value = results
const pay_result = await client.submitAndWait(pay_signed.tx_blob)
if (pay_result.result.meta.TransactionResult == "tesSUCCESS") {
results += 'Transaction succeeded.\n\n'
results += JSON.stringify(pay_result.result, null, 2)
leftResultField.value = results
} else {
results += 'Transaction failed: See JavaScript console for details.'
results += JSON.stringify(pay_result.result, null, 2)
leftResultField.value = results
}
client.disconnect()
} // end of sendMPT()
// *******************************************************
// ******************** Get MPTs *************************
// *******************************************************
async function getMPTs() {
let net = getNet()
const client = new xrpl.Client(net)
results = 'Connecting to ' + getNet() + '....'
leftResultField.value = results
await client.connect()
const left_wallet = xrpl.Wallet.fromSeed(leftSeedField.value)
results += '\nConnected.'
leftResultField.value = results
const left_mpts = await client.request({
command: "account_objects",
account: left_wallet.address,
ledger_index: "validated",
type: "mptoken"
})
let JSONString = JSON.stringify(left_mpts.result, null, 2)
let JSONParse = JSON.parse(JSONString)
let numberOfMPTs = JSONParse.account_objects.length
console.log("length: " + numberOfMPTs)
let x = 0
while (x < numberOfMPTs){
results += "\n\nMPT Issuance ID: " + JSONParse.account_objects[x].MPTokenIssuanceID
+ "\nMPT Amount: " + JSONParse.account_objects[x].MPTAmount
x++
}
results += "\n\n" + JSONString
leftResultField.value = results
client.disconnect()
} // End of getMPTs()
// **********************************************************************
// ****** MPTAuthorize Transaction ***************************************
// **********************************************************************
async function MPTAuthorize() {
let net = getNet()
const client = new xrpl.Client(net)
results = 'Connecting to ' + getNet() + '....'
document.getElementById('leftResultField').value = results
await client.connect()
const left_wallet = xrpl.Wallet.fromSeed(leftSeedField.value)
const mpt_issuance_id = leftIssuanceIdField.value
const auth_mpt_tx = {
"TransactionType": "MPTokenAuthorize",
"Account": left_wallet.address,
"MPTokenIssuanceID": mpt_issuance_id,
}
const auth_prepared = await client.autofill(auth_mpt_tx)
const auth_signed = left_wallet.sign(auth_prepared)
results += `\n\nSending authorization...`
leftResultField.value = results
const auth_result = await client.submitAndWait(auth_signed.tx_blob)
if (auth_result.result.meta.TransactionResult == "tesSUCCESS") {
results += `Transaction succeeded`
leftResultField.value = results
} else {
results += 'Transaction failed: See JavaScript console for details.'
leftResultField.value = results
}
client.disconnect()
} // end of MPTAuthorize()
// **********************************************************************
// ****** Reciprocal Transactions ***************************************
// **********************************************************************
// *******************************************************
// ************* Right Send MPT ********
// *******************************************************
async function rightSendMPT() {
let net = getNet()
const client = new xrpl.Client(net)
results = 'Connecting to ' + getNet() + '....'
rightResultField.value = results
await client.connect()
results += '\nConnected.'
rightResultField.value = results
const right_wallet = xrpl.Wallet.fromSeed(rightSeedField.value)
const mpt_issuance_id = rightIssuanceIdField.value
const mpt_quantity = rightQuantityField.value
const send_mpt_tx = {
"TransactionType": "Payment",
"Account": right_wallet.address,
"Amount": {
"mpt_issuance_id": mpt_issuance_id,
"value": mpt_quantity,
},
"Destination": rightDestinationField.value,
}
const pay_prepared = await client.autofill(send_mpt_tx)
const pay_signed = right_wallet.sign(pay_prepared)
results += `\n\nSending ${mpt_quantity} ${mpt_issuance_id} to ${rightDestinationField.value} ...`
rightResultField.value = results
const pay_result = await client.submitAndWait(pay_signed.tx_blob)
if (pay_result.result.meta.TransactionResult == "tesSUCCESS") {
results += 'Transaction succeeded.\n\n'
results += JSON.stringify(pay_result.result, null, 2)
rightResultField.value = results
} else {
results += 'Transaction failed: See JavaScript console for details.'
results += JSON.stringify(pay_result.result, null, 2)
rightResultField.value = results
}
client.disconnect()
} // end of rightSendMPT()
// **********************************************************************
// ****** MPTAuthorize Transaction ***************************************
// **********************************************************************
async function rightMPTAuthorize() {
let net = getNet()
const client = new xrpl.Client(net)
results = 'Connecting to ' + getNet() + '....'
document.getElementById('rightResultField').value = results
await client.connect()
const right_wallet = xrpl.Wallet.fromSeed(rightSeedField.value)
const mpt_issuance_id = rightIssuanceIdField.value
const auth_mpt_tx = {
"TransactionType": "MPTokenAuthorize",
"Account": right_wallet.address,
"MPTokenIssuanceID": mpt_issuance_id,
}
const auth_prepared = await client.autofill(auth_mpt_tx)
const auth_signed = right_wallet.sign(auth_prepared)
results += `\n\nSending authorization...`
rightResultField.value = results
const auth_result = await client.submitAndWait(auth_signed.tx_blob)
console.log(JSON.stringify(auth_result.result, null, 2))
if (auth_result.result.meta.TransactionResult == "tesSUCCESS") {
results += `Transaction succeeded`
rightResultField.value = results
} else {
results += 'Transaction failed: See JavaScript console for details.'
rightResultField.value = results
}
client.disconnect()
} // end of rightMPTAuthorize()
// **********************************************************************
// ****** Right Get MPTs ***************************************
// **********************************************************************
async function rightGetMPTs() {
let net = getNet()
const client = new xrpl.Client(net)
results = 'Connecting to ' + getNet() + '....'
rightResultField.value = results
await client.connect()
const right_wallet = xrpl.Wallet.fromSeed(rightSeedField.value)
results += '\nConnected.'
rightResultField.value = results
const right_mpts = await client.request({
command: "account_objects",
account: right_wallet.address,
ledger_index: "validated",
type: "mptoken"
})
let JSONString = JSON.stringify(right_mpts.result, null, 2)
let JSONParse = JSON.parse(JSONString)
let numberOfMPTs = JSONParse.account_objects.length
let x = 0
while (x < numberOfMPTs){
results += "\n\nMPT Issuance ID: " + JSONParse.account_objects[x].MPTokenIssuanceID
+ "\nMPT Amount: " + JSONParse.account_objects[x].MPTAmount
x++
}
results += "\n\n" + JSONString
rightResultField.value = results
client.disconnect()
} // End of rightGetMPTs()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 KiB

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 320 KiB

After

Width:  |  Height:  |  Size: 253 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 528 KiB

After

Width:  |  Height:  |  Size: 456 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 KiB

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 523 KiB

After

Width:  |  Height:  |  Size: 440 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 324 KiB

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

View File

@@ -138,6 +138,7 @@ const transactionJson = {
} else {
successURLfield.value = "https://devnet.xrpl.org/ledgers/" + tx.result.ledger_index
}
mptIssuanceIdField.value = JSON.stringify(tx.result.meta.mpt_issuance_id)
} //End of sendTransaction()
</script>
@@ -340,6 +341,11 @@ const transactionJson = {
</div>
</div>
</div>
<div class="row">
<p><b>MPT Issuance ID</b><br/>
<input type="text" id="mptIssuanceIdField" size="40"></input>
</p>
</div>
</div>
</div>
</form>
@@ -374,6 +380,8 @@ The form sets the standard flags for an Issuer account and displays additional c
| **Signer Weights** | _int_ | The weight of each signer's signature, relative to other signers. |
| **Signer Quorum** | _int_ | The required minimum value of signer weights to approve a transaction. |
{% admonition type="info" name="Note" %}In practice, configuring signers for your issuing account is a best practice. To reduce complexity, this example does not use signer configuration.{% /admonition %}
#### Issuer Account Flag Settings
Use the sliders to configure the standard suggested flag settings. Overall, you want holders of your T-bill to be able to trade with other holders, so rippling is an essential function. You want to be careful about what other accounts are able to send to your account, so you should disallow most types of transfers. One exception is trust lines, which you do want other accounts to be able to create to your issuing account.
@@ -429,7 +437,7 @@ The metadata you provide is what distinguishes your token from other MPTs. The f
"ExternalUrl": "https://example.com/t-bill-token-metadata.json"
}
```
Once you've set your preferred values, click **Generate Code** to see the transaction syntax for your settings. The `Flags` field displays the sum of the flags you've selected, and the `MPTokenMetadata` is converted to a hexidecimal string.
Once you've set your preferred values, click **Generate Transaction** to see the transaction syntax for your settings. The `Flags` field displays the sum of the flags you've selected, and the `MPTokenMetadata` is converted to a hexidecimal string.
![Generated syntax for MPTokenIssuanceCreate transaction](../../img/uc-mpt1-t-bill-mpt-generator-generate-code.png)
@@ -437,6 +445,8 @@ To create your T-bill MPT, click **Send Transaction**. When your transaction suc
![Success link appended to the code field.](../../img/uc-mpt1-t-bill-create-success.png)
Follow the link and scroll down to find the `MPTokenIssuanceCreate` transaction for your new T-bill in the Explorer.
Be sure to copy and save the **Seed** field and the **MPT Issuance ID** so that you can try transferring the MPT to another account as shown in [Sending an MPT](./send-an-mpt.md).
Follow the link appended to the result field and scroll down to find the `MPTokenIssuanceCreate` transaction for your new T-bill in the Explorer.
![Explorer record of the new T-bill MPT.](../../img/uc-mpt1-t-bill-in-explorer.png)

View File

@@ -20,6 +20,10 @@ const useCases = [
description: "NFT Marketplace",
link: "/docs/use-cases/tokenization/nftoken-marketplace/",
},
{
description: "MPT Overview",
link: "/docs/use-cases/tokenization/mpt-overview/"
},
{
description: "Authorized Minter",
link: "/docs/use-cases/tokenization/authorized-minter/",

View File

@@ -0,0 +1,26 @@
---
seo:
description: Overview of Multi-purpose Token use cases.
labels:
- Tokenization
- MPT
- Multi-purpose Token
---
# Multi-purpose Tokens Overview
Multi-purpose Tokens (MPTs) let you take advantage of ready-to-use tokenization features with a few lines of code. You can create many token experiences from one token program itself. Notable features include:
- MPTs store their metadata directly on the XRPL blockchain.
- A 1024-byte URI field provides a metadata pointer that allows you to use an off-chain source for metadata in addition to the on-chain source. This lets your application access necessary information directly from the chain, prompting higher interoperability for tokens, without losing the ability to attach additional information.
- MPTs can have a fixed token supply where you set a cap on the maximum number of tokens that can be minted.
- You can define MPTs as non-transferable, tokens that can only be transferred back to the issuer, but not among tokenholders. Useful for cases such as issuing airline credits or loyalty rewards.
- Issuers can set transfer fees to collect on-chain revenue each time the token is traded among tokenholders.
- MPTs also have advanced compliance features:
- The ability to lock tokens held by a tokenholder to support compliance requirements.
- The ability to set a global lock for all MPT balances across all tokenholders.
- The issuer can configure MPTs that can be clawed back from tokenholder wallets, either to revoke them, or to reassign them in the case of lost wallet keys.
- An opt-in feature can allow only wallets authorized by the issuer to hold issued tokens.
- [Creating an Asset-based Multi-purpose Token](./creating-an-asset-backed-multi-purpose-token.md)
- [Sending an MPT](./send-an-mpt.md)

View File

@@ -1,6 +1,4 @@
---
html: nft-mkt-overview.html
parent: tokenization.html
seo:
description: Overview of NFT Marketplace use cases.
labels:

View File

@@ -0,0 +1,368 @@
---
seo:
description: Issue an asset-backed token such as a US Treasury bill using multi-purpose tokens.
labels:
- Tokens
- MPT
---
# Sending an MPT
_As an XRPL holder, I want to send multi-purpose tokens to another account in order to complete an offline transaction._
To send an MPT to another account, the receiving account must first authorize the receipt of the MPT, based on its MPToken Issuance ID. This is to prevent malicious users from spamming accounts with unwanted tokens that could negatively impact storage and XRP reserves.
## Send MPT Utility
The Send MPT utility embedded on the page below lets you create an account to receive an MPT, authorize it to receive a specific MPT issuance, then send an MPT from an issuer or holder account. (You can issue an MPT using the [MPT Generator](./creating-an-asset-backed-multi-purpose-token.md) utility.)
![MPT Generator Utility](../../img/uc-mpt2-mpt-sender-empty-form.png)
You can download a [standalone version of the MPT Sender](../../../_code-samples/mpt-sender/mpt-sender.zip) as sample code, or use the embedded form that follows.
<div>
<link href='https://fonts.googleapis.com/css?family=Work Sans' rel='stylesheet'>
<script src='https://unpkg.com/xrpl@4.1.0/build/xrpl-latest.js'></script>
<script>
if (typeof module !== "undefined") {
const xrpl = require("xrpl")
}
document.addEventListener("DOMContentLoaded", function() {
getHolderAccountFromSeedButton.addEventListener("click", getHolderFromSeed)
getReceiverAccountButton.addEventListener("click", getAccount)
getReceiverFromSeedButton.addEventListener("click", getReceiverFromSeed)
authorizeMPTButton.addEventListener("click", authorizeMPT)
sendMPTButton.addEventListener("click", sendMPT)
getMPTsButton.addEventListener("click", getMPTs)
})
function getNet() {
let net
if (document.getElementById("tn").checked) net = "wss://s.altnet.rippletest.net:51233"
if (document.getElementById("dn").checked) net = "wss://s.devnet.rippletest.net:51233"
return net
} // End of getNet()
// *******************************************************
// ************* Get Account *****************************
// *******************************************************
async function getAccount() {
let net = getNet()
const client = new xrpl.Client(net)
receiverAccountField.value = "Getting a new account..."
results = 'Connecting to ' + net + '....'
//-------------------------------This uses the default faucet for Testnet/Devnet.
let faucetHost = null
await client.connect()
results += '\nConnected, funding wallet.'
// ----------------------------------------Create and fund a test account wallet.
const my_wallet = (await client.fundWallet(null, { faucetHost })).wallet
results += '\nGot a wallet.'
// ------------------------------------------------------Get the current balance.
receiverAccountField.value = my_wallet.address
receiverSeedField.value = my_wallet.seed
results += '\nAccount created.'
console.log(results)
client.disconnect()
} // End of getAccount()
// **********************************************************
// *********** Get Holder from Seed *************************
// **********************************************************
async function getHolderFromSeed() {
let net = getNet()
const client = new xrpl.Client(net)
holderAccountField.value = "Getting holder account from seed..."
results = 'Connecting to ' + getNet() + '....'
await client.connect()
results += '\nConnected, finding wallets.\n'
console.log(results)
// --------------------------------------------------Find the test account wallet.
const my_wallet = xrpl.Wallet.fromSeed(holderSeedField.value)
// -------------------------------------------------------Get the current balance.
holderAccountField.value = my_wallet.address
holderSeedField.value = my_wallet.seed
client.disconnect()
} // End of getHolderFromSeed()
// **********************************************************
// *********** Get Receiver from Seed *************************
// **********************************************************
async function getReceiverFromSeed() {
let net = getNet()
const client = new xrpl.Client(net)
receiverAccountField.value = "Getting receiver account from seed..."
results = 'Connecting to ' + getNet() + '....'
await client.connect()
results += '\nConnected, finding wallets.\n'
resultsArea.value = results
// --------------------------------------------------Find the test account wallet.
const my_wallet = xrpl.Wallet.fromSeed(receiverSeedField.value)
// -------------------------------------------------------Get the current balance.
receiverAccountField.value = my_wallet.address
receiverSeedField.value = my_wallet.seed
resultsArea.value = results
client.disconnect()
} // End of getReceiverFromSeed()
// *******************************************************
// *************** Send MPT **********************
// *******************************************************
async function sendMPT() {
let net = getNet()
const client = new xrpl.Client(net)
results = 'Connecting to ' + getNet() + '....'
resultsArea.value = results
await client.connect()
results += '\nConnected.'
resultsArea.value = results
const holder_wallet = xrpl.Wallet.fromSeed(holderSeedField.value)
const mpt_issuance_id = mptIssuanceIDField.value
const mpt_quantity = quantityField.value
const send_mpt_tx = {
"TransactionType": "Payment",
"Account": holder_wallet.address,
"Amount": {
"mpt_issuance_id": mpt_issuance_id,
"value": mpt_quantity,
},
"Destination": receiverAccountField.value,
}
const pay_prepared = await client.autofill(send_mpt_tx)
const pay_signed = holder_wallet.sign(pay_prepared)
results += `\n\nSending ${mpt_quantity} ${mpt_issuance_id} to ${receiverAccountField.value} ...`
resultsArea.value = results
const pay_result = await client.submitAndWait(pay_signed.tx_blob)
if (pay_result.result.meta.TransactionResult == "tesSUCCESS") {
results += 'Transaction succeeded.\n\n'
results += JSON.stringify(pay_result.result, null, 2)
resultsArea.value = results
} else {
results += 'Transaction failed: See JavaScript console for details.'
results += JSON.stringify(pay_result.result, null, 2)
resultsArea.value = results
}
client.disconnect()
} // end of sendMPT()
// *******************************************************
// ******************** Get MPTs *************************
// *******************************************************
async function getMPTs() {
let net = getNet()
const client = new xrpl.Client(net)
results = 'Connecting to ' + getNet() + '....'
resultsArea.value = results
await client.connect()
const receiver_wallet = xrpl.Wallet.fromSeed(receiverSeedField.value)
results += '\nConnected.'
resultsArea.value = results
const mpts = await client.request({
command: "account_objects",
account: receiver_wallet.address,
ledger_index: "validated",
type: "mptoken"
})
let JSONString = JSON.stringify(mpts.result, null, 2)
let JSONParse = JSON.parse(JSONString)
let numberOfMPTs = JSONParse.account_objects.length
let x = 0
while (x < numberOfMPTs){
results += "\n\nMPT Issuance ID: " + JSONParse.account_objects[x].MPTokenIssuanceID
+ "\nMPT Amount: " + JSONParse.account_objects[x].MPTAmount
x++
}
results += "\n\n" + JSONString
resultsArea.value = results
client.disconnect()
} // End of getMPTs()
// **********************************************************************
// ****** MPTAuthorize Transaction ***************************************
// **********************************************************************
async function authorizeMPT() {
let net = getNet()
const client = new xrpl.Client(net)
results = 'Connecting to ' + getNet() + '....'
resultsArea.value = results
await client.connect()
const receiver_wallet = xrpl.Wallet.fromSeed(receiverSeedField.value)
const mpt_issuance_id = mptIssuanceIDField.value
const auth_mpt_tx = {
"TransactionType": "MPTokenAuthorize",
"Account": receiver_wallet.address,
"MPTokenIssuanceID": mpt_issuance_id,
}
const auth_prepared = await client.autofill(auth_mpt_tx)
const auth_signed = receiver_wallet.sign(auth_prepared)
results += `\n\nSending authorization...`
resultsArea.value = results
const auth_result = await client.submitAndWait(auth_signed.tx_blob)
console.log(JSON.stringify(auth_result.result, null, 2))
if (auth_result.result.meta.TransactionResult == "tesSUCCESS") {
results += `Transaction succeeded`
resultsArea.value = results
} else {
results += 'Transaction failed: See JavaScript console for details.'
resultsArea.value = results
}
client.disconnect()
} // end of MPTAuthorize()
</script>
<div>
<form>
<link href='https://fonts.googleapis.com/css?family=Work Sans' rel='stylesheet'>
<script src='https://unpkg.com/xrpl@4.1.0/build/xrpl-latest.js'></script>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<div class="container">
<div class="row">
<div class="col align-self-start">
<h4>MPT Sender</h4>
</div>
</div>
<div class="row">
<div class="col align-self-start">
<b>1. Choose your preferred network.</b>
</div>
<div class="col align-self-center">
<input type="radio" id="tn" name="server"
value="wss://s.altnet.rippletest.net:51233">
<label for="tn">Testnet</label>
<br/>
<input type="radio" id="dn" name="server"
value="wss://s.devnet.rippletest.net:51233" checked>
<label for="dn">Devnet</label>
</div>
</div>
<div class="row">
<div class="col align-self-start">
<b>2. Get the holder (or issuer) account from its seed.<br/>
</div>
</div>
<div class="row">
<div class="col align-self-start">
<label for="holderSeedField">Holder Seed</label>
</div>
</div>
<div class="row">
<div class="col align-self-start">
<input type="text" id="holderSeedField" size="40"></input>
<br/><br/>
</div>
</div>
<div class="row">
<div class="col align-self-start">
<label for="holderAccountField">Holder Account</label>
</div>
</div>
<div class="row">
<div class="col align-self-start">
<input type="text" id="holderAccountField" size="40"></input>
</div>
</div>
<br/>
</div>
<div class="row">
<div class="col align-self-start">
<button type="button" id="getHolderAccountFromSeedButton" class="btn btn-primary">Get Holder Account From Seed</button>
<br/><br/>
</div>
</div>
<div class="row">
<div class="col align-self-start">
<b>3. Get a new receiver account or retrieve one from its seed.</b>
<div class="row">
<div class="col align-self-start">
<label for="receiverSeedField">Receiver Seed</label>
</div>
</div>
<div class="row">
<div class="col align-self-start">
<input type="text" id="receiverSeedField" size="40"></input>
<br/><br/>
</div>
</div>
<div class="row">
<div class="col align-self-start">
<label for="receiverAccountField">Receiver Account</label>
</div>
</div>
<div class="row">
<div class="col align-self-start">
<input type="text" id="receiverAccountField" size="40"></input>
</div>
</div>
<div class="row">
<div class="col align-self-start">
<button type="button" id="getReceiverAccountButton" class="btn btn-primary">Get New Receiver Account</button>
</div>
<div class="col align-self-start">
<button type="button" id="getReceiverFromSeedButton" class="btn btn-primary">Get Receiver Account From Seed</button>
<br/><br/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col align-self-start">
<b>4. Enter the <i>MPT Issuance ID</i>.</b>
</div>
</div>
<div class="row">
<div class="col align-self-start">
<label for="mptIssuanceIDField">MPT Issuance ID</label>
</div>
</div>
<div class="row">
<div class="col align-self-start">
<input type="text" id="mptIssuanceIDField" size="40"></input>
<br/><br/>
</div>
</div>
<div class="row">
<div class="col align-self-start">
<b>5. Click <i>Authorize MPT</i> to authorize the MPT for the receiver.</b>
</div>
</div>
<div class="row">
<button type="button" id="authorizeMPTButton" class="btn btn-primary">Authorize MPT</button>
</div>
<br/>
</div>
<div class="row">
<div class="col align-self-start">
<b>5. Enter the <i>Quantity</i> of MPTs to send.</b>
</div>
</div>
<div class="row">
<div class="col align-self-start">
<label for="quantity">Quantity</label>
</div>
</div>
<div class="row">
<div class="col align-self-start">
<input type="text" id="quantityField" size="40"></input>
</div>
</div>
<div class="row">
<div class="col-align-items-left">
<br/>
<p><b>6. Click Send MPTs</b><br/>
<button type="button" id="sendMPTButton" class="btn btn-primary">Send MPTs</button>
</p>
</div>
</div>
<div class="row">
<div class="col-align-self-start">
<p><b>Results</b></p>
<textarea class="form-control" id="resultsArea" rows="18" cols="40"></textarea>
</div>
</div>
<div class="row">
<div class="col-align-self-start">
<br/>
<p><b>7. Click Get MPTs</b><br/>
<button type = "button" id="getMPTsButton" class="btn btn-primary">Get MPTs</button>
</p>
</div>
</div>
</div>
</div>
</form>
</div>
<hr/>

View File

@@ -26,7 +26,6 @@
expanded: false
items:
- page: docs/use-cases/tokenization/stablecoin-issuer.md
- page: docs/use-cases/tokenization/creating-an-asset-backed-multi-purpose-token.md
- page: docs/use-cases/tokenization/nft-mkt-overview.md
expanded: false
items:
@@ -34,6 +33,11 @@
- page: docs/use-cases/tokenization/authorized-minter.md
- page: docs/use-cases/tokenization/digital-artist.md
- page: docs/use-cases/tokenization/real-world-assets.page.tsx
- page: docs/use-cases/tokenization/mpt-overview.md
expanded: false
items:
- page: docs/use-cases/tokenization/creating-an-asset-backed-multi-purpose-token.md
- page: docs/use-cases/tokenization/send-an-mpt.md
- page: docs/use-cases/defi/index.md
expanded: false
items: