mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2025-11-20 11:45:50 +00:00
Issue a token: Incorporate Java code, clarify some details
This commit is contained in:
@@ -39,23 +39,20 @@ public class IssueToken {
|
|||||||
|
|
||||||
public static void main(String[] args)
|
public static void main(String[] args)
|
||||||
throws InterruptedException, JsonRpcClientErrorException, JsonProcessingException {
|
throws InterruptedException, JsonRpcClientErrorException, JsonProcessingException {
|
||||||
// -----------------------------------------------------------
|
// Construct a network client ----------------------------------------------
|
||||||
// Construct a network client
|
|
||||||
// -----------------------------------------------------------
|
|
||||||
HttpUrl rippledUrl = HttpUrl
|
HttpUrl rippledUrl = HttpUrl
|
||||||
.get("https://s.altnet.rippletest.net:51234/");
|
.get("https://s.altnet.rippletest.net:51234/");
|
||||||
XrplClient xrplClient = new XrplClient(rippledUrl);
|
XrplClient xrplClient = new XrplClient(rippledUrl);
|
||||||
|
// Get the current network fee
|
||||||
|
FeeResult feeResult = xrplClient.fee();
|
||||||
|
|
||||||
// -----------------------------------------------------------
|
|
||||||
// Create a cold and hot Wallet using a WalletFactory
|
// Create cold and hot Wallets using a WalletFactory -----------------------
|
||||||
// -----------------------------------------------------------
|
|
||||||
WalletFactory walletFactory = DefaultWalletFactory.getInstance();
|
WalletFactory walletFactory = DefaultWalletFactory.getInstance();
|
||||||
Wallet coldWallet = walletFactory.randomWallet(true).wallet();
|
Wallet coldWallet = walletFactory.randomWallet(true).wallet();
|
||||||
Wallet hotWallet = walletFactory.randomWallet(true).wallet();
|
Wallet hotWallet = walletFactory.randomWallet(true).wallet();
|
||||||
|
|
||||||
// -----------------------------------------------------------
|
// Fund the account using the testnet Faucet -------------------------------
|
||||||
// Fund the account using the testnet Faucet
|
|
||||||
// -----------------------------------------------------------
|
|
||||||
FaucetClient faucetClient = FaucetClient
|
FaucetClient faucetClient = FaucetClient
|
||||||
.construct(HttpUrl.get("https://faucet.altnet.rippletest.net"));
|
.construct(HttpUrl.get("https://faucet.altnet.rippletest.net"));
|
||||||
faucetClient.fundAccount(FundAccountRequest.of(coldWallet.classicAddress()));
|
faucetClient.fundAccount(FundAccountRequest.of(coldWallet.classicAddress()));
|
||||||
@@ -91,14 +88,7 @@ public class IssueToken {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------
|
// Configure issuer settings -----------------------------------------------
|
||||||
// Get the current network fee
|
|
||||||
// -----------------------------------------------------------
|
|
||||||
FeeResult feeResult = xrplClient.fee();
|
|
||||||
|
|
||||||
// -----------------------------------------------------------
|
|
||||||
// Configure cold wallet settings
|
|
||||||
// -----------------------------------------------------------
|
|
||||||
UnsignedInteger coldWalletSequence = xrplClient.accountInfo(
|
UnsignedInteger coldWalletSequence = xrplClient.accountInfo(
|
||||||
AccountInfoRequestParams.builder()
|
AccountInfoRequestParams.builder()
|
||||||
.ledgerIndex(LedgerIndex.CURRENT)
|
.ledgerIndex(LedgerIndex.CURRENT)
|
||||||
@@ -127,9 +117,7 @@ public class IssueToken {
|
|||||||
|
|
||||||
submitAndWaitForValidation(signedSetDefaultRipple, xrplClient);
|
submitAndWaitForValidation(signedSetDefaultRipple, xrplClient);
|
||||||
|
|
||||||
// -----------------------------------------------------------
|
// Configure hot address settings ------------------------------------------
|
||||||
// Configure hot wallet settings
|
|
||||||
// -----------------------------------------------------------
|
|
||||||
UnsignedInteger hotWalletSequence = xrplClient.accountInfo(
|
UnsignedInteger hotWalletSequence = xrplClient.accountInfo(
|
||||||
AccountInfoRequestParams.builder()
|
AccountInfoRequestParams.builder()
|
||||||
.ledgerIndex(LedgerIndex.CURRENT)
|
.ledgerIndex(LedgerIndex.CURRENT)
|
||||||
@@ -158,9 +146,7 @@ public class IssueToken {
|
|||||||
|
|
||||||
submitAndWaitForValidation(signedSetRequireAuth, xrplClient);
|
submitAndWaitForValidation(signedSetRequireAuth, xrplClient);
|
||||||
|
|
||||||
// -----------------------------------------------------------
|
// Create trust line -------------------------------------------------------
|
||||||
// Create TrustLine
|
|
||||||
// -----------------------------------------------------------
|
|
||||||
String currencyCode = "FOO";
|
String currencyCode = "FOO";
|
||||||
ImmutableTrustSet trustSet = TrustSet.builder()
|
ImmutableTrustSet trustSet = TrustSet.builder()
|
||||||
.account(hotWallet.classicAddress())
|
.account(hotWallet.classicAddress())
|
||||||
@@ -181,9 +167,7 @@ public class IssueToken {
|
|||||||
|
|
||||||
submitAndWaitForValidation(signedTrustSet, xrplClient);
|
submitAndWaitForValidation(signedTrustSet, xrplClient);
|
||||||
|
|
||||||
// -----------------------------------------------------------
|
// Send token --------------------------------------------------------------
|
||||||
// Send token
|
|
||||||
// -----------------------------------------------------------
|
|
||||||
Payment payment = Payment.builder()
|
Payment payment = Payment.builder()
|
||||||
.account(coldWallet.classicAddress())
|
.account(coldWallet.classicAddress())
|
||||||
.fee(feeResult.drops().openLedgerFee())
|
.fee(feeResult.drops().openLedgerFee())
|
||||||
@@ -204,9 +188,7 @@ public class IssueToken {
|
|||||||
|
|
||||||
submitAndWaitForValidation(signedPayment, xrplClient);
|
submitAndWaitForValidation(signedPayment, xrplClient);
|
||||||
|
|
||||||
// -----------------------------------------------------------
|
// Check balances ----------------------------------------------------------
|
||||||
// Check balances
|
|
||||||
// -----------------------------------------------------------
|
|
||||||
List<TrustLine> lines = xrplClient.accountLines(
|
List<TrustLine> lines = xrplClient.accountLines(
|
||||||
AccountLinesRequestParams.builder()
|
AccountLinesRequestParams.builder()
|
||||||
.account(hotWallet.classicAddress())
|
.account(hotWallet.classicAddress())
|
||||||
@@ -216,6 +198,7 @@ public class IssueToken {
|
|||||||
System.out.println("Hot wallet TrustLines: " + lines);
|
System.out.println("Hot wallet TrustLines: " + lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper methods ------------------------------------------------------------
|
||||||
private static UnsignedInteger computeLastLedgerSequence(XrplClient xrplClient)
|
private static UnsignedInteger computeLastLedgerSequence(XrplClient xrplClient)
|
||||||
throws JsonRpcClientErrorException {
|
throws JsonRpcClientErrorException {
|
||||||
// Get the latest validated ledger index
|
// Get the latest validated ledger index
|
||||||
|
|||||||
5
content/_code-samples/issue-a-token/java/README.md
Normal file
5
content/_code-samples/issue-a-token/java/README.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Issue a Token (Java sample code)
|
||||||
|
|
||||||
|
This code demonstrates how to issue a (fungible) token on the XRP Ledger. For a detailed explanation, see <https://xrpl.org/issue-a-fungible-token.html>.
|
||||||
|
|
||||||
|
The easiest way to run this code is from an IDE such as IntelliJ. For an example `pom.xml` file, see [Get Started Using Java](https://xrpl.org/get-started-using-java.html).
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# Issue a Token Sample Code
|
# Issue a Token Sample Code (JavaScript)
|
||||||
|
|
||||||
This code demonstrates how to issue a (fungible) token on the XRP Ledger. For a detailed explanation, see <https://xrpl.org/issue-a-fungible-token.html>.
|
This code demonstrates how to issue a (fungible) token on the XRP Ledger. For a detailed explanation, see <https://xrpl.org/issue-a-fungible-token.html>.
|
||||||
|
|
||||||
|
|||||||
@@ -18,12 +18,20 @@ 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. As shown in this tutorial, you can use public servers for testing.
|
- You need a connection to the XRP Ledger network. As shown in this tutorial, you can use public servers for testing.
|
||||||
|
- You should be familiar with the Getting Started instructions for your preferred client library. This page provides examples for the following:
|
||||||
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.
|
- ripple-lib for JavaScript [(Node.js)](get-started-with-rippleapi-for-javascript.html) or [in-browser](get-started.html)
|
||||||
|
- [xrpl-py for Python](get-started-using-python.html)
|
||||||
|
- [xrpl4j for Java](get-started-using-java.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>
|
||||||
|
|
||||||
|
## Example Code
|
||||||
|
|
||||||
|
Complete sample code for all of the steps of these tutorials is available under the [MIT license](https://github.com/XRPLF/xrpl-dev-portal/blob/master/LICENSE).
|
||||||
|
|
||||||
|
- See [Code Samples: Issue a Fungible Token](https://github.com/XRPLF/xrpl-dev-portal/tree/master/content/_code-samples/issue-a-token/) in the source repository for this website.
|
||||||
|
|
||||||
## Steps
|
## Steps
|
||||||
{% set n = cycler(* range(1,99)) %}
|
{% set n = cycler(* range(1,99)) %}
|
||||||
@@ -84,10 +92,14 @@ _Python_
|
|||||||
|
|
||||||
{{ include_code("_code-samples/issue-a-token/py/issue-a-token.py", start_with="# Connect", end_before="# Get credentials", language="py") }}
|
{{ include_code("_code-samples/issue-a-token/py/issue-a-token.py", start_with="# Connect", end_before="# Get credentials", language="py") }}
|
||||||
|
|
||||||
|
_Java_
|
||||||
|
|
||||||
|
{{ include_code("_code-samples/issue-a-token/java/IssueToken.java", start_with="// Construct a network client", end_before="// Create cold", language="java") }}
|
||||||
|
|
||||||
<!-- MULTICODE_BLOCK_END -->
|
<!-- 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 JavaScript code samples in this tutorial use the [`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:
|
||||||
|
|
||||||
@@ -120,6 +132,8 @@ Other settings you may want to, optionally, configure for your cold address (iss
|
|||||||
[Tick Size]: ticksize.html
|
[Tick Size]: ticksize.html
|
||||||
[Domain]: accountset.html#domain
|
[Domain]: accountset.html#domain
|
||||||
|
|
||||||
|
You can change these settings later as well.
|
||||||
|
|
||||||
**Note:** Many issuing settings apply equally to all tokens issued by an address, regardless of the currency code. If you want to issue multiple types of tokens in the XRP Ledger with different settings, you should use a different address to issue each different token.
|
**Note:** Many issuing settings apply equally to all tokens issued by an address, regardless of the currency code. If you want to issue multiple types of tokens in the XRP Ledger with different settings, you should use a different address to issue each different token.
|
||||||
|
|
||||||
The following code sample shows how to send an [AccountSet transaction][] to enable the recommended cold address settings:
|
The following code sample shows how to send an [AccountSet transaction][] to enable the recommended cold address settings:
|
||||||
@@ -135,6 +149,10 @@ _Python_
|
|||||||
|
|
||||||
{{ include_code("_code-samples/issue-a-token/py/issue-a-token.py", start_with="# Configure issuer", end_before="# Configure hot", language="py") }}
|
{{ include_code("_code-samples/issue-a-token/py/issue-a-token.py", start_with="# Configure issuer", end_before="# Configure hot", language="py") }}
|
||||||
|
|
||||||
|
_Java_
|
||||||
|
|
||||||
|
{{ include_code("_code-samples/issue-a-token/java/IssueToken.java", start_with="// Configure issuer", end_before="// Configure hot", language="java") }}
|
||||||
|
|
||||||
<!-- MULTICODE_BLOCK_END -->
|
<!-- MULTICODE_BLOCK_END -->
|
||||||
|
|
||||||
{{ start_step("Configure Issuer") }}
|
{{ start_step("Configure Issuer") }}
|
||||||
@@ -197,6 +215,12 @@ _Python_
|
|||||||
|
|
||||||
Most transactions are accepted into the next ledger version after they're submitted, which means it may take 4-7 seconds for a transaction's outcome to be final. You should wait for your earlier transactions to be fully validated before proceeding to the later steps, to avoid unexpected failures from things executing out of order. For more information, see [Reliable Transaction Submission](reliable-transaction-submission.html).
|
Most transactions are accepted into the next ledger version after they're submitted, which means it may take 4-7 seconds for a transaction's outcome to be final. You should wait for your earlier transactions to be fully validated before proceeding to the later steps, to avoid unexpected failures from things executing out of order. For more information, see [Reliable Transaction Submission](reliable-transaction-submission.html).
|
||||||
|
|
||||||
|
The code samples in this tutorial use helper functions to wait for validation when submitting a transaction:
|
||||||
|
|
||||||
|
- **JavaScript:** The `submit_and_verify()` function, as defined in the [submit-and-verify code sample](https://github.com/XRPLF/xrpl-dev-portal/tree/master/content/_code-samples/submit-and-verify).
|
||||||
|
- **Python:** The `send_reliable_submission()` [method of the xrpl-py library](https://xrpl-py.readthedocs.io/en/stable/source/xrpl.transaction.html#xrpl.transaction.send_reliable_submission).
|
||||||
|
- **Java:** The `submitAndWaitForValidation()` method in the [sample Java class](https://github.com/XRPLF/xrpl-dev-portal/blob/master/content/_code-samples/issue-a-token/java/IssueToken.java).
|
||||||
|
|
||||||
**Tip:** Technically, you can configure the hot address in parallel with configuring the issuer address. For simplicity, this tutorial waits for each transaction one at a time.
|
**Tip:** Technically, you can configure the hot address in parallel with configuring the issuer address. For simplicity, this tutorial waits for each transaction one at a time.
|
||||||
|
|
||||||
{{ start_step("Wait (Issuer Setup)") }}
|
{{ start_step("Wait (Issuer Setup)") }}
|
||||||
@@ -228,6 +252,10 @@ _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") }}
|
{{ include_code("_code-samples/issue-a-token/py/issue-a-token.py", start_with="# Configure hot address", end_before="# Create trust line", language="py") }}
|
||||||
|
|
||||||
|
_Java_
|
||||||
|
|
||||||
|
{{ include_code("_code-samples/issue-a-token/java/IssueToken.java", start_with="// Configure hot address", end_before="// Create trust line", language="java") }}
|
||||||
|
|
||||||
<!-- MULTICODE_BLOCK_END -->
|
<!-- MULTICODE_BLOCK_END -->
|
||||||
|
|
||||||
{{ start_step("Configure Hot Address") }}
|
{{ start_step("Configure Hot Address") }}
|
||||||
@@ -306,11 +334,15 @@ _Python_
|
|||||||
|
|
||||||
{{ include_code("_code-samples/issue-a-token/py/issue-a-token.py", start_with="# Create trust line", end_before="# Send token", language="py") }}
|
{{ include_code("_code-samples/issue-a-token/py/issue-a-token.py", start_with="# Create trust line", end_before="# Send token", language="py") }}
|
||||||
|
|
||||||
|
_Java_
|
||||||
|
|
||||||
|
{{ include_code("_code-samples/issue-a-token/java/IssueToken.java", start_with="// Create trust line", end_before="// Send token", language="java") }}
|
||||||
|
|
||||||
<!-- MULTICODE_BLOCK_END -->
|
<!-- MULTICODE_BLOCK_END -->
|
||||||
|
|
||||||
{{ start_step("Make Trust Line") }}
|
{{ start_step("Make Trust Line") }}
|
||||||
<form>
|
<form>
|
||||||
<h4>Currency code:</h4>
|
<p>Currency code:</p>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="input-group row">
|
<div class="input-group row">
|
||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
@@ -322,7 +354,7 @@ _Python_
|
|||||||
<input type="text" id="currency-code-std" pattern="[A-Za-z0-9?!@#$%*(){}|\x26\x3c\x3e]{3}" value="FOO" class="form-control col-lg-8" title="3 character code (letters, numbers, and some symbols)" />
|
<input type="text" id="currency-code-std" pattern="[A-Za-z0-9?!@#$%*(){}|\x26\x3c\x3e]{3}" value="FOO" class="form-control col-lg-8" title="3 character code (letters, numbers, and some symbols)" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="input-group row">
|
<div class="input-group row mt-2">
|
||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<div class="input-group-text form-check bg-transparent">
|
<div class="input-group-text form-check bg-transparent">
|
||||||
<input type="radio" id="use-hex-code" name="currency-code-type" />
|
<input type="radio" id="use-hex-code" name="currency-code-type" />
|
||||||
@@ -332,10 +364,7 @@ _Python_
|
|||||||
<input type="text" id="currency-code-hex" pattern="[0-9A-F]{40}" value="015841551A748AD2C1F76FF6ECB0CCCD00000000" title="40 hexadecimal characters" class="form-control col-lg-8" />
|
<input type="text" id="currency-code-hex" pattern="[0-9A-F]{40}" value="015841551A748AD2C1F76FF6ECB0CCCD00000000" title="40 hexadecimal characters" class="form-control col-lg-8" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="input-group row mt-2">
|
<div class="input-group row mt-4">
|
||||||
<div class="input-group-prepend col-lg-1">
|
|
||||||
<div class="input-group-text bg-transparent"> </div>
|
|
||||||
</div>
|
|
||||||
<label for="trust-limit" class="input-group-text col-lg-3">Limit:</label>
|
<label for="trust-limit" class="input-group-text col-lg-3">Limit:</label>
|
||||||
<input type="number" id="trust-limit" min="0" value="1000000000" title="Maximum amount the hot address can hold" class="form-control col-lg-9" />
|
<input type="number" id="trust-limit" min="0" value="1000000000" title="Maximum amount the hot address can hold" class="form-control col-lg-9" />
|
||||||
</div>
|
</div>
|
||||||
@@ -389,6 +418,10 @@ _Python_
|
|||||||
|
|
||||||
{{ include_code("_code-samples/issue-a-token/py/issue-a-token.py", start_with="# Send token", end_before="# Check balances", language="py") }}
|
{{ include_code("_code-samples/issue-a-token/py/issue-a-token.py", start_with="# Send token", end_before="# Check balances", language="py") }}
|
||||||
|
|
||||||
|
_Java_
|
||||||
|
|
||||||
|
{{ include_code("_code-samples/issue-a-token/java/IssueToken.java", start_with="// Send token", end_before="// Check balances", language="java") }}
|
||||||
|
|
||||||
<!-- MULTICODE_BLOCK_END -->
|
<!-- MULTICODE_BLOCK_END -->
|
||||||
|
|
||||||
{{ start_step("Send Token") }}
|
{{ start_step("Send Token") }}
|
||||||
@@ -451,6 +484,10 @@ _Python_
|
|||||||
|
|
||||||
{{ include_code("_code-samples/issue-a-token/py/issue-a-token.py", start_with="# Check balances", language="py") }}
|
{{ include_code("_code-samples/issue-a-token/py/issue-a-token.py", start_with="# Check balances", language="py") }}
|
||||||
|
|
||||||
|
_Java_
|
||||||
|
|
||||||
|
{{ include_code("_code-samples/issue-a-token/java/IssueToken.java", start_with="// Check balances", end_before="// Helper", language="java") }}
|
||||||
|
|
||||||
<!-- MULTICODE_BLOCK_END -->
|
<!-- MULTICODE_BLOCK_END -->
|
||||||
|
|
||||||
{{ start_step("Confirm Balances") }}
|
{{ start_step("Confirm Balances") }}
|
||||||
|
|||||||
Reference in New Issue
Block a user