mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2025-11-20 11:45:50 +00:00
Issue a Token improvements: python, UI fixes, etc.
- Display some errors without marking the step as complete (Also applied to Require Destination Tags tutorial) - Add Python equivalent script
This commit is contained in:
@@ -114,6 +114,7 @@ function complete_step_by_id(step_id) {
|
|||||||
".interactive-block").eq(0).find(".previous-steps-required")
|
".interactive-block").eq(0).find(".previous-steps-required")
|
||||||
next_ui.prop("title", "")
|
next_ui.prop("title", "")
|
||||||
next_ui.prop("disabled", false)
|
next_ui.prop("disabled", false)
|
||||||
|
next_ui.removeClass("disabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -360,7 +361,6 @@ function setup_wait_steps() {
|
|||||||
min_ledger,
|
min_ledger,
|
||||||
max_ledger
|
max_ledger
|
||||||
})
|
})
|
||||||
console.log(tx_result)
|
|
||||||
|
|
||||||
if (tx_result.validated) {
|
if (tx_result.validated) {
|
||||||
status_box.html(
|
status_box.html(
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ $(document).ready(() => {
|
|||||||
"Flags": flags
|
"Flags": flags
|
||||||
}
|
}
|
||||||
|
|
||||||
generic_full_send(event, cold_settings_tx, cold_secret)
|
await generic_full_send(event, cold_settings_tx, cold_secret)
|
||||||
complete_step("Configure Issuer")
|
complete_step("Configure Issuer")
|
||||||
|
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
@@ -212,7 +212,7 @@ $(document).ready(() => {
|
|||||||
"Flags": flags
|
"Flags": flags
|
||||||
}
|
}
|
||||||
|
|
||||||
generic_full_send(event, hot_settings_tx, hot_secret)
|
await generic_full_send(event, hot_settings_tx, hot_secret)
|
||||||
complete_step("Configure Hot Address")
|
complete_step("Configure Hot Address")
|
||||||
|
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
@@ -256,7 +256,7 @@ $(document).ready(() => {
|
|||||||
"value": limit
|
"value": limit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
generic_full_send(event, trust_set_tx, hot_secret)
|
await generic_full_send(event, trust_set_tx, hot_secret)
|
||||||
complete_step("Make Trust Line")
|
complete_step("Make Trust Line")
|
||||||
|
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
@@ -301,7 +301,7 @@ $(document).ready(() => {
|
|||||||
if (use_dest_tag) {
|
if (use_dest_tag) {
|
||||||
send_token_tx["DestinationTag"] = dest_tag
|
send_token_tx["DestinationTag"] = dest_tag
|
||||||
}
|
}
|
||||||
generic_full_send(event, send_token_tx, cold_secret)
|
await generic_full_send(event, send_token_tx, cold_secret)
|
||||||
complete_step("Send Token")
|
complete_step("Send Token")
|
||||||
|
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
|
|||||||
@@ -4,16 +4,21 @@
|
|||||||
$(document).ready(() => {
|
$(document).ready(() => {
|
||||||
|
|
||||||
// 3. Send AccountSet --------------------------------------------------------
|
// 3. Send AccountSet --------------------------------------------------------
|
||||||
$("#send-accountset").click( (event) => {
|
$("#send-accountset").click( async (event) => {
|
||||||
const address = get_address(event)
|
const address = get_address(event)
|
||||||
if (!address) {return}
|
if (!address) {return}
|
||||||
|
|
||||||
generic_full_send(event, {
|
try {
|
||||||
"TransactionType": "AccountSet",
|
await generic_full_send(event, {
|
||||||
"Account": address,
|
"TransactionType": "AccountSet",
|
||||||
"SetFlag": 1 // RequireDest
|
"Account": address,
|
||||||
})
|
"SetFlag": 1 // RequireDest
|
||||||
complete_step("Send AccountSet")
|
})
|
||||||
|
complete_step("Send AccountSet")
|
||||||
|
} catch(err) {
|
||||||
|
block.find(".loader").hide()
|
||||||
|
show_error(block, err)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 4. Wait for Validation: handled by interactive-tutorial.js and by the
|
// 4. Wait for Validation: handled by interactive-tutorial.js and by the
|
||||||
|
|||||||
108
content/_code-samples/issue-a-token/py/issue-a-token.py
Normal file
108
content/_code-samples/issue-a-token/py/issue-a-token.py
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
# Stand-alone code sample for the "issue a token" tutorial:
|
||||||
|
# https://xrpl.org/issue-a-fungible-token.html
|
||||||
|
# License: https://github.com/XRPLF/xrpl-dev-portal/blob/master/LICENSE
|
||||||
|
|
||||||
|
# Connect ----------------------------------------------------------------------
|
||||||
|
import xrpl
|
||||||
|
testnet_url = "https://s.altnet.rippletest.net:51234"
|
||||||
|
client = xrpl.clients.JsonRpcClient(testnet_url)
|
||||||
|
|
||||||
|
|
||||||
|
# Get credentials from the Testnet Faucet --------------------------------------
|
||||||
|
# For production, instead create a Wallet instance
|
||||||
|
faucet_url = "https://faucet.altnet.rippletest.net/accounts"
|
||||||
|
print("Getting 2 new accounts from the Testnet faucet...")
|
||||||
|
from xrpl.wallet import generate_faucet_wallet
|
||||||
|
cold_wallet = generate_faucet_wallet(client, debug=True)
|
||||||
|
hot_wallet = generate_faucet_wallet(client, debug=True)
|
||||||
|
|
||||||
|
|
||||||
|
# Configure issuer (cold address) settings -------------------------------------
|
||||||
|
cold_settings_tx = xrpl.models.transactions.AccountSet(
|
||||||
|
account=cold_wallet.classic_address,
|
||||||
|
transfer_rate=0,
|
||||||
|
tick_size=5,
|
||||||
|
domain=bytes.hex("example.com".encode("ASCII")),
|
||||||
|
set_flag=xrpl.models.transactions.AccountSetFlag.ASF_DEFAULT_RIPPLE,
|
||||||
|
)
|
||||||
|
cst_prepared = xrpl.transaction.safe_sign_and_autofill_transaction(
|
||||||
|
transaction=cold_settings_tx,
|
||||||
|
wallet=cold_wallet,
|
||||||
|
client=client,
|
||||||
|
)
|
||||||
|
print("Sending cold address AccountSet transaction...")
|
||||||
|
response = xrpl.transaction.send_reliable_submission(cst_prepared, client)
|
||||||
|
print(response)
|
||||||
|
|
||||||
|
|
||||||
|
# Configure hot address settings -----------------------------------------------
|
||||||
|
hot_settings_tx = xrpl.models.transactions.AccountSet(
|
||||||
|
account=hot_wallet.classic_address,
|
||||||
|
set_flag=xrpl.models.transactions.AccountSetFlag.ASF_REQUIRE_AUTH,
|
||||||
|
)
|
||||||
|
hst_prepared = xrpl.transaction.safe_sign_and_autofill_transaction(
|
||||||
|
transaction=hot_settings_tx,
|
||||||
|
wallet=hot_wallet,
|
||||||
|
client=client,
|
||||||
|
)
|
||||||
|
print("Sending hot address AccountSet transaction...")
|
||||||
|
response = xrpl.transaction.send_reliable_submission(hst_prepared, client)
|
||||||
|
print(response)
|
||||||
|
|
||||||
|
|
||||||
|
# Create trust line from hot to cold address -----------------------------------
|
||||||
|
currency_code = "FOO"
|
||||||
|
trust_set_tx = xrpl.models.transactions.TrustSet(
|
||||||
|
account=hot_wallet.classic_address,
|
||||||
|
limit_amount=xrpl.models.amounts.issued_currency_amount.IssuedCurrencyAmount(
|
||||||
|
currency=currency_code,
|
||||||
|
issuer=cold_wallet.classic_address,
|
||||||
|
value="10000000000", # Large limit, arbitrarily chosen
|
||||||
|
)
|
||||||
|
)
|
||||||
|
ts_prepared = xrpl.transaction.safe_sign_and_autofill_transaction(
|
||||||
|
transaction=trust_set_tx,
|
||||||
|
wallet=hot_wallet,
|
||||||
|
client=client,
|
||||||
|
)
|
||||||
|
print("Creating trust line from hot address to issuer...")
|
||||||
|
response = xrpl.transaction.send_reliable_submission(ts_prepared, client)
|
||||||
|
print(response)
|
||||||
|
|
||||||
|
|
||||||
|
# Send token -------------------------------------------------------------------
|
||||||
|
issue_quantity = "3840"
|
||||||
|
send_token_tx = xrpl.models.transactions.Payment(
|
||||||
|
account=cold_wallet.classic_address,
|
||||||
|
destination=hot_wallet.classic_address,
|
||||||
|
amount=xrpl.models.amounts.issued_currency_amount.IssuedCurrencyAmount(
|
||||||
|
currency=currency_code,
|
||||||
|
issuer=cold_wallet.classic_address,
|
||||||
|
value=issue_quantity
|
||||||
|
)
|
||||||
|
)
|
||||||
|
pay_prepared = xrpl.transaction.safe_sign_and_autofill_transaction(
|
||||||
|
transaction=send_token_tx,
|
||||||
|
wallet=cold_wallet,
|
||||||
|
client=client,
|
||||||
|
)
|
||||||
|
print(f"Sending {issue_quantity} {currency_code} to {hot_wallet.classic_address}...")
|
||||||
|
response = xrpl.transaction.send_reliable_submission(pay_prepared, client)
|
||||||
|
print(response)
|
||||||
|
|
||||||
|
|
||||||
|
# Check balances ---------------------------------------------------------------
|
||||||
|
print("Getting hot address balances...")
|
||||||
|
response = client.request(xrpl.models.requests.AccountLines(
|
||||||
|
account=hot_wallet.classic_address,
|
||||||
|
ledger_index="validated",
|
||||||
|
))
|
||||||
|
print(response)
|
||||||
|
|
||||||
|
print("Getting cold address balances...")
|
||||||
|
response = client.request(xrpl.models.requests.GatewayBalances(
|
||||||
|
account=cold_wallet.classic_address,
|
||||||
|
ledger_index="validated",
|
||||||
|
hotwallet=[hot_wallet.classic_address]
|
||||||
|
))
|
||||||
|
print(response)
|
||||||
@@ -17,9 +17,9 @@ Anyone can issue various types of tokens in the XRP Ledger, ranging from informa
|
|||||||
|
|
||||||
- You need two funded XRP Ledger accounts, each with an address, secret key, and some XRP. For this tutorial, you can generate new test credentials as needed.
|
- You need two funded XRP Ledger accounts, each with an address, secret key, and some XRP. For this tutorial, you can generate new test credentials as needed.
|
||||||
- Each address needs enough XRP to satisfy the [reserve requirement](reserves.html) including the additional reserve for a trust line.
|
- Each address needs enough XRP to satisfy the [reserve requirement](reserves.html) including the additional reserve for a trust line.
|
||||||
- You need a connection to the XRP Ledger network.
|
- You need a connection to the XRP Ledger network. As shown in this tutorial, you can use public servers for testing.
|
||||||
|
|
||||||
This page provides examples that use [ripple-lib for JavaScript](get-started-with-rippleapi-for-javascript.html). Since JavaScript works in the web browser, you can read along and use the interactive steps without any setup.
|
This page provides examples that use [ripple-lib for JavaScript](get-started-with-rippleapi-for-javascript.html) or [xrpl-py for Python](get-started-using-python.html). You can also read along and use the interactive steps in your browser without any setup.
|
||||||
|
|
||||||
<!-- Source for this specific tutorial's interactive bits: -->
|
<!-- Source for this specific tutorial's interactive bits: -->
|
||||||
<script type="application/javascript" src="assets/js/tutorials/issue-a-token.js"></script>
|
<script type="application/javascript" src="assets/js/tutorials/issue-a-token.js"></script>
|
||||||
@@ -59,7 +59,11 @@ When you're [building actual production-ready software](production-readiness.htm
|
|||||||
|
|
||||||
You must be connected to the network to submit transactions to it.
|
You must be connected to the network to submit transactions to it.
|
||||||
|
|
||||||
The following code uses a [ripple-lib for JavaScript](rippleapi-reference.html) instance to connect to a public XRP Ledger Testnet server:
|
The following code shows how to connect to a public XRP Ledger Testnet server a supported [client library](client-libraries.html):
|
||||||
|
|
||||||
|
<!-- MULTICODE_BLOCK_START -->
|
||||||
|
|
||||||
|
_JavaScript_
|
||||||
|
|
||||||
```js
|
```js
|
||||||
ripple = require('ripple-lib') // Node.js only. Use a <script> tag in browsers.
|
ripple = require('ripple-lib') // Node.js only. Use a <script> tag in browsers.
|
||||||
@@ -69,11 +73,20 @@ async function main() {
|
|||||||
await api.connect()
|
await api.connect()
|
||||||
|
|
||||||
// Code in the following examples continues here...
|
// Code in the following examples continues here...
|
||||||
|
|
||||||
|
api.disconnect() // When done. This lets Node.js stop running.
|
||||||
}
|
}
|
||||||
|
|
||||||
main()
|
main()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
_Python_
|
||||||
|
|
||||||
|
{{ include_code("_code-samples/issue-a-token/py/issue-a-token.py", start_with="# Connect", end_before="# Get credentials", language="py") }}
|
||||||
|
|
||||||
|
<!-- MULTICODE_BLOCK_END -->
|
||||||
|
|
||||||
|
|
||||||
**Note:** The code samples in this tutorial use JavaScript's [`async`/`await` pattern](https://javascript.info/async-await). Since `await` needs to be used from within an `async` function, the remaining code samples are written to continue inside the `main()` function started here. You can also use Promise methods `.then()` and `.catch()` instead of `async`/`await` if you prefer.
|
**Note:** The code samples in this tutorial use JavaScript's [`async`/`await` pattern](https://javascript.info/async-await). Since `await` needs to be used from within an `async` function, the remaining code samples are written to continue inside the `main()` function started here. You can also use Promise methods `.then()` and `.catch()` instead of `async`/`await` if you prefer.
|
||||||
|
|
||||||
For this tutorial, you can connect directly from your browser by pressing the following button:
|
For this tutorial, you can connect directly from your browser by pressing the following button:
|
||||||
@@ -116,7 +129,11 @@ The following code sample shows how to send an [AccountSet transaction][] to ena
|
|||||||
|
|
||||||
_JavaScript_
|
_JavaScript_
|
||||||
|
|
||||||
{{ include_code("_code-samples/issue-a-token/issue-a-token.js", start_with="// Configure issuer", end_before="// Configure hot", language="js") }}
|
{{ include_code("_code-samples/issue-a-token/js/issue-a-token.js", start_with="// Configure issuer", end_before="// Configure hot", language="js") }}
|
||||||
|
|
||||||
|
_Python_
|
||||||
|
|
||||||
|
{{ include_code("_code-samples/issue-a-token/py/issue-a-token.py", start_with="# Configure issuer", end_before="# Configure hot", language="py") }}
|
||||||
|
|
||||||
<!-- MULTICODE_BLOCK_END -->
|
<!-- MULTICODE_BLOCK_END -->
|
||||||
|
|
||||||
@@ -205,7 +222,11 @@ The following code sample shows how to send an [AccountSet transaction][] to ena
|
|||||||
|
|
||||||
_JavaScript_
|
_JavaScript_
|
||||||
|
|
||||||
{{ include_code("_code-samples/issue-a-token/issue-a-token.js", start_with="// Configure hot address", end_before="// Create trust line", language="js") }}
|
{{ include_code("_code-samples/issue-a-token/js/issue-a-token.js", start_with="// Configure hot address", end_before="// Create trust line", language="js") }}
|
||||||
|
|
||||||
|
_Python_
|
||||||
|
|
||||||
|
{{ include_code("_code-samples/issue-a-token/py/issue-a-token.py", start_with="# Configure hot address", end_before="# Create trust line", language="py") }}
|
||||||
|
|
||||||
<!-- MULTICODE_BLOCK_END -->
|
<!-- MULTICODE_BLOCK_END -->
|
||||||
|
|
||||||
@@ -279,7 +300,11 @@ The following code sample shows how to send a [TrustSet transaction][] from the
|
|||||||
|
|
||||||
_JavaScript_
|
_JavaScript_
|
||||||
|
|
||||||
{{ include_code("_code-samples/issue-a-token/issue-a-token.js", start_with="// Create trust line", end_before="// Send token", language="js") }}
|
{{ include_code("_code-samples/issue-a-token/js/issue-a-token.js", start_with="// Create trust line", end_before="// Send token", language="js") }}
|
||||||
|
|
||||||
|
_Python_
|
||||||
|
|
||||||
|
{{ include_code("_code-samples/issue-a-token/py/issue-a-token.py", start_with="# Create trust line", end_before="# Send token", language="py") }}
|
||||||
|
|
||||||
<!-- MULTICODE_BLOCK_END -->
|
<!-- MULTICODE_BLOCK_END -->
|
||||||
|
|
||||||
@@ -321,7 +346,7 @@ _JavaScript_
|
|||||||
<div class="output-area"></div>
|
<div class="output-area"></div>
|
||||||
{{ end_step() }}
|
{{ end_step() }}
|
||||||
|
|
||||||
**Note**: If you use [Authorized Trust Lines][], there is an extra step after this one: the cold address must approve the trust line from the hot address. For details of how to do this, see [Authorizing Trust Lines](authorized-trust-lines.html#authorizing-trust-lines).
|
**Note:** If you use [Authorized Trust Lines][], there is an extra step after this one: the cold address must approve the trust line from the hot address. For details of how to do this, see [Authorizing Trust Lines](authorized-trust-lines.html#authorizing-trust-lines).
|
||||||
|
|
||||||
|
|
||||||
### {{n.next()}}. Wait for Validation
|
### {{n.next()}}. Wait for Validation
|
||||||
@@ -358,7 +383,11 @@ The following code sample shows how to send a [Payment transaction][] to issue 8
|
|||||||
|
|
||||||
_JavaScript_
|
_JavaScript_
|
||||||
|
|
||||||
{{ include_code("_code-samples/issue-a-token/issue-a-token.js", start_with="// Send token", end_before="// Check balances", language="js") }}
|
{{ include_code("_code-samples/issue-a-token/js/issue-a-token.js", start_with="// Send token", end_before="// Check balances", language="js") }}
|
||||||
|
|
||||||
|
_Python_
|
||||||
|
|
||||||
|
{{ include_code("_code-samples/issue-a-token/py/issue-a-token.py", start_with="# Send token", end_before="# Check balances", language="py") }}
|
||||||
|
|
||||||
<!-- MULTICODE_BLOCK_END -->
|
<!-- MULTICODE_BLOCK_END -->
|
||||||
|
|
||||||
@@ -416,7 +445,11 @@ The following code sample shows how to use both methods:
|
|||||||
|
|
||||||
_JavaScript_
|
_JavaScript_
|
||||||
|
|
||||||
{{ include_code("_code-samples/issue-a-token/issue-a-token.js", start_with="// Check balances", end_before="// End of", language="js") }}
|
{{ include_code("_code-samples/issue-a-token/js/issue-a-token.js", start_with="// Check balances", end_before="// End of", language="js") }}
|
||||||
|
|
||||||
|
_Python_
|
||||||
|
|
||||||
|
{{ include_code("_code-samples/issue-a-token/py/issue-a-token.py", start_with="# Check balances", language="py") }}
|
||||||
|
|
||||||
<!-- MULTICODE_BLOCK_END -->
|
<!-- MULTICODE_BLOCK_END -->
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user