Migrate interactive tutorials (post realm v0.70)

Attempt migrating interactive tutorial again

Migrate interactive tutorial snippet syntax

Interactive tutorials: partially migrate send-xrp, no-freeze to new syntax

Fix Send XRP interactive tutorial

Interactive tutorials: fixes for Redocly incl. localization challenges

Interactive tutorials: switch defaultValue back to value in anticipation of Redocly bugfix

Fix document.ready→window.onRouteChange, cyclers, etc. in interactive
tutorials.
This commit is contained in:
mDuo13
2023-12-21 13:57:58 -08:00
parent 4c9a8c0bf9
commit ee8acbbd22
41 changed files with 671 additions and 540 deletions

View File

@@ -1,20 +1,17 @@
{% if use_network is undefined or use_network == "Testnet" %}
{% set ws_url = "wss://s.altnet.rippletest.net:51233" %}
{% set explorer_url = "https://testnet.xrpl.org" %}
{% set use_network = "Testnet" %}
{% elif use_network == "Devnet" %}
{% set ws_url = "wss://s.devnet.rippletest.net:51233" %}
{% set explorer_url = "https://devnet.xrpl.org" %}
{% elif use_network == "Mainnet" %}
{% set ws_url = "wss://xrplcluster.com" %}
{% set explorer_url = "https://livenet.xrpl.org" %}
{% endif %}
<!-- Interactive tutorials are hard-coded to Testnet for now due to Redocly
limitations. They'll be replaced with new-style tutorials next anyway.
Localized step names don't currently work due to problems with unicode
in regexes. -->
{{ start_step("Connect") }}
<button id="connect-button" class="btn btn-primary" data-wsurl="{{ws_url}}" data-explorer="{{explorer_url}}">{{use_network}}に接続する</button>
{% interactive-block label=default($label, "Connect") steps=$frontmatter.steps %}
<button id="connect-button" class="btn btn-primary" data-wsurl="wss://s.altnet.rippletest.net:51233" data-explorer="https://testnet.xrpl.org">Testnetに接続する</button>
<div>
<strong>接続ステータス:</strong>
<span id="connection-status">接続されていません</span>
<div class="loader collapse" id="loader-connect"><img class="throbber" src="assets/img/xrp-loader-96.png"></div>
{% loading-icon /%}
</div>
{{ end_step() }}
{% /interactive-block %}

View File

@@ -1,15 +1,9 @@
{% if use_network is undefined or use_network == "Testnet" %}
{% set use_network = "Testnet" %}
{% set faucet_url = "https://faucet.altnet.rippletest.net/accounts" %}
{% elif use_network == "Devnet" %}
{% set faucet_url = "https://faucet.devnet.rippletest.net/accounts" %}
{# No faucet for Mainnet! #}
{% endif %}
{% interactive-block label=default($label, "Generate") steps=$frontmatter.steps %}
{{ start_step("Generate") }}
<button id="generate-creds-button" class="btn btn-primary" data-fauceturl="{{faucet_url}}">{{use_network}}の暗号鍵を作成する</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">暗号鍵を作成しています…</div>
<button id="generate-creds-button" class="btn btn-primary" data-fauceturl="https://faucet.altnet.rippletest.net/accounts">Testnetの暗号鍵を作成する</button>
{% loading-icon message="暗号鍵を作成しています…" /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
**注意:** Rippleは[TestnetとDevnet](../../concepts/networks-and-servers/parallel-networks.md)をテストの目的でのみ運用しており、その状態とすべての残高を定期的にリセットしています。予防措置として、Testnet、DevnetとMainnetで同じアドレスを使用**しない**ことをお勧めします。

View File

@@ -1,12 +1,6 @@
{% if use_network is undefined or use_network == "Testnet" %}
{% set explorer_url = "https://testnet.xrpl.org" %}
{% elif use_network == "Devnet" %}
{% set explorer_url = "https://devnet.xrpl.org" %}
{% elif use_network == "Mainnet" %}
{% set explorer_url = "https://livenet.xrpl.org" %}
{% endif %}
{% interactive-block label=default($label, "Wait") steps=$frontmatter.steps %}
<table class="wait-step" data-explorerurl="{{explorer_url}}">
<table class="wait-step" data-explorerurl="https://testnet.xrpl.org">
<tr>
<th>トランザクションのID:</th>
<td class="waiting-for-tx">(無)</td>
@@ -25,3 +19,5 @@
<tr class="tx-validation-status">
</tr>
</table>
{% /interactive-block %}

View File

@@ -60,7 +60,7 @@ XRP Ledgerは、2011年から2012年初頭にかけて、Jed McCaleb、Arthur Br
| XRPの"X"ロゴ | Ripple社のトリスケリオン |
|:-------------------------------------|:-------------------------------------------|
| !["X"ロゴ](assets/img/xrp-x-logo.png) | ![トリスケリオン](/img/ripple-triskelion.png) |
| !["X"ロゴ](/img/xrp-x-logo.png) | ![トリスケリオン](/img/ripple-triskelion.png) |
### 商標

View File

@@ -2,6 +2,8 @@
html: ledger-data-formats.html
parent: protocol-reference.html
blurb: XRP Ledgerの共有状態を構成する個別のデータオブジェクトについて説明します。
metadata:
indexPage: true
---
# レジャーのデータ型
@@ -16,5 +18,4 @@ XRP Ledgerに各レジャーバージョンは3つの要素で構成されてい
{% partial file="/_snippets/ledger-objects-intro.md" /%}
{% from '_snippets/macros/page-children.md' import page_children with context %}
{{ page_children(pages|selectattr("html", "eq", "ledger-object-types.html")|first, 1, 1, True) }}
{% child-pages /%}

View File

@@ -22,8 +22,8 @@ WebSocketは、クライアントとサーバーが1つの接続を確立し、
- 丸め方によるエラーを発生させることなくXRPの価値を適切に処理するには、64ビット符号なし整数で計算できる数値タイプを使用できる必要があります。このチュートリアルの例では、[big.js](https://github.com/MikeMcl/big.js/)を使用しています。[トークン](../../concepts/tokens/index.md)を使用する場合は、さらに高い精度が求められます。詳細は、[通貨の精度](../../references/protocol/data-types/currency-formats.md#xrpの精度)を参照してください。
<!-- Helper for interactive tutorial breadcrumbs -->
<script type="application/javascript" src="assets/vendor/big.min.js"></script>
<script type="application/javascript" src="assets/js/interactive-tutorial.js"></script>
<script type="application/javascript" src="/vendor/big.min.js"></script>
<script type="application/javascript" src="/js/interactive-tutorial.js"></script>
<script type="application/javascript">
// Helper stuff for this interactive tutorial specifically
@@ -36,9 +36,7 @@ function writeToConsole(console_selector, message) {
</script>
{% set n = cycler(* range(1,99)) %}
## {{n.next()}}. XRP Ledgerへの接続
## 1. XRP Ledgerへの接続
着信ペイメントを監視する最初のステップとして、XRP Ledger、つまり`rippled`サーバーに接続します。
@@ -75,13 +73,15 @@ const socket = new WebSocket('ws://localhost:6006')
例:
{{ start_step("Connect") }}
{% interactive-block label="Connect" steps=$frontmatter.steps %}
<button id="connect-socket-button" class="btn btn-primary">Connect</button>
<strong>Connection status:</strong>
<span id="connection-status">Not connected</span>
<h5>Console:</h5>
<div class="ws-console" id="monitor-console-connect"><span class="placeholder">(Log is empty)</span></div>
{{ end_step() }}
{% /interactive-block %}
<script type="application/javascript">
let socket;
@@ -113,7 +113,7 @@ $("#connect-socket-button").click((event) => {
</script>
## {{n.next()}}. ハンドラーへの着信メッセージのディスパッチ
## 2. ハンドラーへの着信メッセージのディスパッチ
WebSocket接続では、複数のメッセージをどちらの方向にも送信することが可能で、リクエストとレスポンスの間に厳密な1:1の相互関係がないため、各着信メッセージに対応する処理を識別する必要があります。この処理をコーディングする際の優れたモデルとして、「ディスパッチャー」関数の設定が挙げられます。この関数は着信メッセージを読み取り、各メッセージを正しいコードのパスに中継して処理します。メッセージを適切にディスパッチできるように、`rippled`サーバーでは、すべてのWebSocketメッセージで`type`フィールドを使用できます。
@@ -190,12 +190,14 @@ async function pingpong() {
pingpong()
```
{{ start_step("Dispatch Messages") }}
{% interactive-block label="Dispatch Messages" steps=$frontmatter.steps %}
<button id="enable_dispatcher" class="btn btn-primary" disabled="disabled">Enable Dispatcher</button>
<button id="dispatch_ping" class="btn btn-primary" disabled="disabled">Ping!</button>
<h5>Responses</h5>
<div class="ws-console" id="monitor-console-ping"><span class="placeholder">(Log is empty)</span></div>
{{ end_step() }}
{% /interactive-block %}
<script type="application/javascript">
const AWAITING = {}
@@ -259,7 +261,7 @@ $("#dispatch_ping").click((event) => {
})
</script>
## {{n.next()}}. アカウントのサブスクライブ
## 3. アカウントのサブスクライブ
トランザクションがアカウントに影響を及ぼすたびに即座に通知を取得するには、[subscribeメソッド][]を使用してアカウントをサブスクライブします。実際には、このアカウントはあなた自身のアカウントでなくてもかまいません。すべてのトランザクションは公開されているため、任意のアカウントで、または複数のアカウントでもサブスクライブできます。
@@ -293,13 +295,15 @@ WS_HANDLERS["transaction"] = log_tx
以下の例では、別のウィンドウまたは別のデバイスで[Transaction Sender](/resources/dev-tools/tx-sender)を開くことと、サブスクライブしているアドレスへのトランザクションの送信を試みます。
{{ start_step("Subscribe") }}
{% interactive-block label="Subscribe" steps=$frontmatter.steps %}
<label for="subscribe_address">Test Net Address:</label>
<input type="text" class="form-control" id="subscribe_address" value="rUCzEr6jrEyMpjhs4wSdQdz4g8Y382NxfM">
<button id="tx_subscribe" class="btn btn-primary" disabled="disabled">Subscribe</button>
<h5>Transactions</h5>
<div class="ws-console" id="monitor-console-subscribe"><span class="placeholder">(Log is empty)</span></div>
{{ end_step() }}
{% /interactive-block %}
<script type="application/javascript">
async function do_subscribe() {
@@ -332,7 +336,7 @@ const log_tx = function(tx) {
WS_HANDLERS["transaction"] = log_tx
</script>
## {{n.next()}}. 着信ペイメントの読み取り
## 4. 着信ペイメントの読み取り
アカウントをサブスクライブすると、 _アカウントへのすべてのトランザクションとアカウントからのすべてのトランザクション_ 、および _アカウントに間接的に影響を及ぼすトランザクション_ に関するメッセージが表示されます。この例として、[トークン](../../concepts/tokens/index.md)の取引があります。アカウントが着信ペイメントを受け取った日時を認識することを目的とする場合、トランザクションストリームを絞り込んで、実際に支払われた額に基づいて支払いを処理する必要があります。以下の情報を探します。
@@ -364,11 +368,13 @@ WS_HANDLERS["transaction"] = log_tx
{% code-snippet file="/_code-samples/monitor-payments-websocket/js/read-amount-received.js" language="js" /%}
{{ start_step("Read Payments") }}
{% interactive-block label="Read Payments" steps=$frontmatter.steps %}
<button id="tx_read" class="btn btn-primary" disabled="disabled">Start Reading</button>
<h5>Transactions</h5>
<div class="ws-console" id="monitor-console-read"><span class="placeholder">(Log is empty)</span></div>
{{ end_step() }}
{% /interactive-block %}
<script type="application/javascript">
function CountXRPDifference(affected_nodes, address) {

View File

@@ -10,6 +10,7 @@ labels:
- 支払い
- XRP
top_nav_grouping: 人気ページ
steps: ['Generate', 'Connect', 'Prepare', 'Sign', 'Submit', 'Wait', 'Check']
---
# XRPの送金
@@ -18,8 +19,8 @@ top_nav_grouping: 人気ページ
## 前提条件
<!-- このチュートリアルのインタラクティブ部分のソースコード: -->
<script type="application/javascript" src="assets/js/tutorials/send-xrp.js"></script>
{% set use_network = "Testnet" %}
<script type="application/javascript" src="/js/interactive-tutorial.js"></script>
<script type="application/javascript" src="/js/tutorials/send-xrp.js"></script>
- このページでは、xrpl.jsライブラリーを使用するJavaScriptの例を紹介します。[xrpl.js入門ガイド](get-started-using-javascript.md)に、xrpl.jsを使用してJavaScriptからXRP Ledgerデータにアクセスする方法の説明があります。
@@ -28,9 +29,8 @@ top_nav_grouping: 人気ページ
{% partial file="/_snippets/interactive-tutorials/generate-step.md" /%}
## Testnetでの送金
{% set n = cycler(* range(1,99)) %}
### {{n.next()}}. Testnetサーバーへの接続
### 1. Testnetサーバーへの接続
必須の自動入力可能フィールドに入力されるようにするために、ripple-libを、アカウントの現在のステータスと共有レジャー自体を取得できるサーバーに接続する必要があります。セキュリティを高めるために、トランザクションの署名はオフライン中に行うことを推奨します。ただしその場合は、自動入力可能フィールドに手動で入力する必要があります。トランザクションの送信先となるネットワークに接続する必要があります。
@@ -58,7 +58,7 @@ top_nav_grouping: 人気ページ
{% partial file="/_snippets/interactive-tutorials/connect-step.md" /%}
### {{n.next()}}. トランザクションの準備
### 2. トランザクションの準備
通常は、XRP LedgerトランザクションをオブジェクトとしてJSON[トランザクションフォーマット](../../references/protocol/transactions/index.md)で作成します。以下の例に、必要最小限の送金仕様を示します。
@@ -96,7 +96,8 @@ XRP送金に対して指定する必要がある必要最小限の指示は次
{% /tabs %}
{{ start_step("Prepare") }}
{% interactive-block label="Prepare" steps=$frontmatter.steps %}
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">送金する額:</span>
@@ -110,9 +111,10 @@ XRP送金に対して指定する必要がある必要最小限の指示は次
</div>
<button id="prepare-button" class="btn btn-primary previous-steps-required">サンプルトランザクションを準備する</button>
<div class="output-area"></div>
{{ end_step() }}
### {{n.next()}}. トランザクションの指示への署名
{% /interactive-block %}
### 3. トランザクションの指示への署名
xrpl.jsの[Wallet.sign()メソッド](https://js.xrpl.org/classes/Wallet.html#sign)を使用して、トランザクションに署名します。最初の引数は、署名するJSONトランザクションの文字列バージョンです。
@@ -137,13 +139,15 @@ xrpl.jsの[Wallet.sign()メソッド](https://js.xrpl.org/classes/Wallet.html#si
署名APIは、トランザクションのID、つまり識別用ハッシュを返します。この識別用ハッシュは、後でトランザクションを検索する際に使用します。識別用ハッシュは、このトランザクションに固有の64文字の16進文字列です。
{{ start_step("Sign") }}
{% interactive-block label="Sign" steps=$frontmatter.steps %}
<button id="sign-button" class="btn btn-primary previous-steps-required">サンプルトランザクションに署名する</button>
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. 署名済みブロブの送信
### 4. 署名済みブロブの送信
トランザクションをネットワークに送信します。
@@ -174,13 +178,17 @@ xrpl.jsの[Wallet.sign()メソッド](https://js.xrpl.org/classes/Wallet.html#si
他の可能性については、[トランザクション結果](../../references/protocol/transactions/transaction-results/transaction-results.md)の完全なリストを参照してください。
{{ start_step("Submit") }}
<button id="submit-button" class="btn btn-primary previous-steps-required" data-tx-blob-from="#signed-tx-blob" data-wait-step-name="Wait">サンプルトランザクションを送信する</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png"> 送信中...</div>
<div class="output-area"></div>
{{ end_step() }}
{% interactive-block label="Submit" steps=$frontmatter.steps %}
### {{n.next()}}. 検証の待機
<button id="submit-button" class="btn btn-primary previous-steps-required" data-tx-blob-from="#signed-tx-blob" data-wait-step-name="Wait">サンプルトランザクションを送信する</button>
{% loading-icon message=" 送信中..." /%}
<div class="output-area"></div>
{% /interactive-block %}
### 5. 検証の待機
ほとんどのトランザクションは送信後の次のレジャーバージョンに承認されます。つまり、47秒でトランザクションの結果が最終的なものになる可能性があります。XRP Ledgerがビジーになっているか、ネットワーク接続の品質が悪いためにトランザクションをネットワーク内で中継する処理が遅延した場合は、トランザクション確定までにもう少し時間がかかることがあります。トランザクションの有効期限を設定する方法については、[信頼できるトランザクションの送信](../../concepts/transactions/reliable-transaction-submission.md)を参照してください。)
@@ -200,12 +208,10 @@ xrpl.jsの[Wallet.sign()メソッド](https://js.xrpl.org/classes/Wallet.html#si
{% /tabs %}
{{ start_step("Wait") }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" /%}
{{ end_step() }}
### {{n.next()}}. トランザクションステータスの確認
### 6. トランザクションステータスの確認
トランザクションが行った内容を正確に把握するために、トランザクションが検証済みレジャーバージョンに記録されたときにトランザクションの結果を調べる必要があります。例えば、[txメソッド][]を使用して、トランザクションのステータスを確認できます。
@@ -228,10 +234,12 @@ xrpl.jsの[Wallet.sign()メソッド](https://js.xrpl.org/classes/Wallet.html#si
**注意:** APIは、まだ検証されていないレジャーバージョンからの暫定的な結果を返す場合があります。例えば、`rippled` APIの[txメソッド][]を使用した場合は、レスポンス内の`"validated": true`を探して、データが検証済みレジャーバージョンからのものであることを確認してください。検証済みレジャーバージョンからのものではないトランザクション結果は、変わる可能性があります。詳細は、[結果のファイナリティー](../../concepts/transactions/finality-of-results/index.md)を参照してください。
{{ start_step("Check") }}
{% interactive-block label="Check" steps=$frontmatter.steps %}
<button id="get-tx-button" class="btn btn-primary previous-steps-required">トランザクションステータスを確認する</button>
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
## 本番環境の場合の相違点

View File

@@ -28,9 +28,7 @@ labels:
## 手順
{% set n = cycler(* range(1,99)) %}
### {{n.next()}}. トランザクションJSONの作成
### 1. トランザクションJSONの作成
アカウントから、`"SetValue": 4`のフィールドを持つ[AccountSet トランザクション][]を準備します。これは AccountSet フラグ "Disable Master" (`asfDisableMaster`) に対応する値です。このトランザクションの他の必須フィールドは、必須の[共通フィールド](../../references/protocol/transactions/common-fields.md)のみです。例えば、[自動入力可能なフィールド](../../references/protocol/transactions/common-fields.md#自動入力可能なフィールド) を省けば、以下のトランザクション指示で十分である。
@@ -44,7 +42,7 @@ labels:
**ヒント:** [予測可能な時間内にトランザクションの結果を確実に得る](../../concepts/transactions/reliable-transaction-submission.md)ために、`LastLedgerSequence`フィールドも提供することが強く推奨されています。
### {{n.next()}}. トランザクションへの署名
### 2. トランザクションへの署名
トランザクションの署名には、**マスターキーペア**を使用する必要があります。
@@ -182,7 +180,7 @@ Loading: "/etc/opt/ripple/rippled.cfg"
レスポンスに含まれる `tx_blob` の値をメモしておきます。これはネットワークに送信できる署名済みトランザクションバイナリである。
### {{n.next()}}. トランザクションの送信
### 3. トランザクションの送信
前のステップで署名されたトランザクションblobをXRP Ledgerに提出します。
@@ -308,11 +306,11 @@ Loading: "/etc/opt/ripple/rippled.cfg"
トランザクションが `tecNO_ALTERNATIVE_KEY` という結果で失敗した場合、あなたのアカウントでは現在トランザクションを認証するための別の方法が有効になっていません。[レギュラーキーペアを割り当てる](assign-a-regular-key-pair.md)か [マルチシグを設定](set-up-multi-signing.md) した後、再度マスターキーペアの無効化を試してみてください。
### {{n.next()}}. 検証の待機
### 4. 検証の待機
{% partial file="/_snippets/wait-for-validation.md" /%}
### {{n.next()}}. アカウントフラグの確認
### 5. アカウントフラグの確認
[account_infoメソッド][]で、アカウントのマスターキーが無効になっていることを確認します。以下のパラメータを必ず指定してください。

View File

@@ -26,9 +26,7 @@ labels:
## 手順
{% set n = cycler(* range(1,99)) %}
### {{n.next()}}. オフラインマシンの設定
### 1. オフラインマシンの設定
オフラインマシンには、安全な永続ストレージ(暗号化されたディスクドライブなど)と[トランザクションに署名する](../../concepts/transactions/secure-signing.md)ための方法が必要です。一般的には、必要なソフトウェアをオンラインマシンでダウンロードして、物理メディアを使ってオフラインマシンに転送します。オンラインマシン、物理メディア、ソフトウェア自体がマルウェアに感染していないことを確認する必要があります。
@@ -40,7 +38,7 @@ XRP Ledgerで署名するためのソフトウェアオプションは次のと
オフラインマシンでトランザクションの指示を生成するプロセスを容易にするために、カスタムソフトウェアを設定することもできます。例えば、ソフトウェアで次に使用する[シーケンス番号][]を追跡したり、送信するトランザクションのタイプに応じた設定済みテンプレートを含めるといったことが可能です。
### {{n.next()}}.暗号鍵の生成
### 2.暗号鍵の生成
**オフラインマシン**で、アカウントで使用する[暗号鍵](../../concepts/accounts/cryptographic-keys.md)のペアを生成します。鍵は、単純なパスフレーズやエントロピーが十分でないその他のソースから生成するのではなく、安全なランダム手続きで生成してください。(例えば、`rippled`の[wallet_proposeメソッド][]を使用することができます。)
@@ -79,7 +77,7 @@ Loading: "/etc/opt/ripple/rippled.cfg"
### {{n.next()}}.新しいアドレスへの資金の供給
### 3.新しいアドレスへの資金の供給
オンラインマシンから、ステップ1でメモした**アカウントアドレス** に十分なXRPを送金します。詳細は、[アカウントの作成](../../concepts/accounts/accounts.md#アカウントの作成)を参照してください。
@@ -87,7 +85,7 @@ Loading: "/etc/opt/ripple/rippled.cfg"
### {{n.next()}}.アカウントの詳細の確認
### 4.アカウントの詳細の確認
前のステップからのトランザクションがコンセンサスにより検証されたら、アカウントが作成されたことになります。オンラインマシンから、[account_infoメソッド][]を使用して、アカウントのステータスを確認します。レスポンスに`"validated": true`が含まれていることを確認し、この結果が最終的なものであることを確認します。
@@ -126,7 +124,7 @@ Loading: "/etc/opt/ripple/rippled.cfg"
{% /tabs %}
### {{n.next()}}.オフラインマシンでのシーケンス番号の入力
### 5.オフラインマシンでのシーケンス番号の入力
オフラインマシンでアカウントの開始シーケンス番号を保存します。オフラインマシンを使用してトランザクションを準備するときは、必ずこの保存されたシーケンス番号を使用し、シーケンス番号を1増やして、新しい値を保存します。
@@ -136,7 +134,7 @@ Loading: "/etc/opt/ripple/rippled.cfg"
### {{n.next()}}.初期設定トランザクションの署名(ある場合)
### 6.初期設定トランザクションの署名(ある場合)
オフラインマシンで、アカウントの設定用のトランザクションを準備して署名します。詳細は、アカウントを使用する目的によって異なります。例えば次のようなことができます。
@@ -187,13 +185,13 @@ Loading: "/etc/opt/ripple/rippled.cfg"
一定の時間内に _すべて_ のトランザクションで最終結果が得られるように、[`LastLedgerSequence`](../../concepts/transactions/reliable-transaction-submission.md#lastledgersequence)フィールドに入力してください。この値は、現行のレジャーインデックス(オンラインマシンから検索する必要がある)と、トランザクションを有効に保つ時間に基づいたものである必要があります。オンラインマシンからオフラインマシンへ、オフラインマシンからオンラインマシンへ切り替える時間を取れるだけの十分に大きな`LastLedgerSequence`値を設定するようにしてください。例えば、現行のレジャーインデックスより256大きな値では、トランザクションは約15分間有効になります。詳細は、[結果のファイナリティー](../../concepts/transactions/finality-of-results/index.md)と[信頼できるトランザクションの送信](../../concepts/transactions/reliable-transaction-submission.md)を参照してください。
### {{n.next()}}.オンラインマシンへのトランザクションのコピー
### 7.オンラインマシンへのトランザクションのコピー
トランザクションに署名したら、次のステップは署名済みのトランザクションデータをオンラインマシンに入れることです。その方法の例については、[前提条件](#前提条件)を参照してください。
### {{n.next()}}.設定したトランザクションの送信
### 8.設定したトランザクションの送信
次のステップはトランザクションの送信です。ほとんどのトランザクションは、送信後の次の検証済みレジャー約4秒後、またはキューに入っている場合はその後のレジャー10秒未満で最終結果が得られるはずです。トランザクションの最終結果を追跡する詳細な手順については、[信頼できるトランザクションの送信](../../concepts/transactions/reliable-transaction-submission.md)を参照してください。
@@ -238,7 +236,7 @@ Loading: "/etc/opt/ripple/rippled.cfg"
[最終的でない結果](../../concepts/transactions/finality-of-results/index.md)が得られて失敗したトランザクションの送信をやり直します。同じトランザクションが2回以上処理される可能性はありません。
### {{n.next()}}.トランザクションの最終ステータスの確認
### 9.トランザクションの最終ステータスの確認
送信した各トランザクションについて、トランザクションの[最終結果](../../concepts/transactions/finality-of-results/index.md)をメモします。例えば、[txメソッド][]を使用します。例:
@@ -311,7 +309,7 @@ Loading: "/etc/opt/ripple/rippled.cfg"
### {{n.next()}}.オフラインマシンのステータスの調整
### 10.オフラインマシンのステータスの調整
オフラインマシンに戻り、カスタムサーバーに保存されている設定に必要な変更を加えます。例えば次のような変更です。

View File

@@ -14,9 +14,9 @@ labels:
## 前提条件
<!-- Source for this specific tutorial's interactive bits: -->
<script type="application/javascript" src="assets/js/tutorials/use-tickets.js"></script>
{% set use_network = "Devnet" %}<!--TODO: change to Testnet eventually. NOTE, Testnet is a few days behind Mainnet in getting the amendment one enabled -->
<!-- Source for this tutorial's interactive bits: -->
<script type="application/javascript" src="/js/interactive-tutorial.js"></script>
<script type="application/javascript" src="/js/tutorials/use-tickets.js"></script>
このページでは、[xrpl.js](https://js.xrpl.org/)ライブラリを使用したJavaScriptのサンプルを提供しています。設定方法は、[JavaScriptを使ってみよう](../get-started/get-started-using-javascript.md)をご覧ください。
@@ -25,7 +25,6 @@ JavaScriptはWebブラウザ上で動作するため、セットアップなし
## 手順
{% set n = cycler(* range(1,99)) %}
このチュートリアルはいくつかの段階に分かれています。
@@ -34,7 +33,7 @@ JavaScriptはWebブラウザ上で動作するため、セットアップなし
- (任意) **休憩:** チケットを作成した後、以下のステップの前、中、後にいつでも様々な他のトランザクションを送信することができます。
- (Steps 7-10) **チケットの使用:** 設定されているチケットのうち1枚を使ってトランザクションを送信します。使用するチケットが1枚でも残っていれば、前の部分を飛ばしてこの手順を繰り返すことができます。
### {{n.next()}}. クレデンシャルの入手
### 1. クレデンシャルの入手
XRP Ledgerでトランザクションを送信するには、アドレスと秘密鍵、そしてXRPが必要です。開発用には、[{{use_network}}](../../concepts/networks-and-servers/parallel-networks.md)で以下のようなインターフェースを使ってこれらを入手することができます。
@@ -43,7 +42,7 @@ XRP Ledgerでトランザクションを送信するには、アドレスと秘
[本番環境のソフトウェアを作成する場合](/tutorials)には、既存のアカウントを使用し、[安全な署名](../../concepts/transactions/secure-signing.md)を使用して鍵を管理する必要があります。
### {{n.next()}}. ネットワークへの接続
### 2. ネットワークへの接続
トランザクションをネットワークに送信するには、ネットワークに接続している必要があります。チケットは今のところDevnetでしか利用できないので、Devnetサーバーに接続する必要があります。例えば、以下のようになります。
@@ -62,7 +61,7 @@ XRP Ledgerでトランザクションを送信するには、アドレスと秘
{% partial file="/_snippets/interactive-tutorials/connect-step.md" /%}
### {{n.next()}}. シーケンス番号の確認
### 3. シーケンス番号の確認
チケットを作成する前に、自分のアカウントの[シーケンス番号][]を確認しておきましょう。次のステップのために現在のシーケンス番号が必要であり、設定されるチケットのシーケンス番号はこの番号から始まります。
@@ -74,15 +73,19 @@ XRP Ledgerでトランザクションを送信するには、アドレスと秘
{% /tabs %}
{{ start_step("Check Sequence") }}
{% interactive-block label="Check Sequence" steps=$frontmatter.steps %}
<button id="check-sequence" class="btn btn-primary previous-steps-required">Check Sequence Number</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Querying...</div>
{% loading-icon message="Querying..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. TicketCreateの準備と署名
### 4. TicketCreateの準備と署名
前のステップで決定したシーケンス番号を使用して、[TicketCreate トランザクション][]を構築します。`TicketCount`フィールドを使って、作成するチケットの枚数を指定します。例えば、10枚のチケットを作成するトランザクションを準備するには、次のようにします。
@@ -97,14 +100,16 @@ XRP Ledgerでトランザクションを送信するには、アドレスと秘
トランザクションのハッシュと`LastLedgerSequence`の値を記録しておけば、[後で検証されたかどうかを確認](../../concepts/transactions/reliable-transaction-submission.md)することができます。
{{ start_step("Prepare & Sign") }}
{% interactive-block label="Prepare & Sign" steps=$frontmatter.steps %}
<button id="prepare-and-sign" class="btn btn-primary previous-steps-required">Prepare & Sign</button>
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. TicketCreateの提出
### 5. TicketCreateの提出
前のステップで作成した署名付きトランザクションBlobを送信します。例えば、以下のようになります。
@@ -116,14 +121,18 @@ XRP Ledgerでトランザクションを送信するには、アドレスと秘
{% /tabs %}
{{ start_step("Submit") }}
{% interactive-block label="Submit" steps=$frontmatter.steps %}
<button id="ticketcreate-submit" class="btn btn-primary previous-steps-required" data-tx-blob-from="#tx_blob" data-wait-step-name="Wait">Submit</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending...</div>
{% loading-icon message="Sending..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. 検証の待機
### 6. 検証の待機
ほとんどのトランザクションは、送信された後に次の台帳のバージョンに受け入れられます。つまり、トランザクションの結果が確定するまでに47秒かかることがあります。XRP Ledgerが混雑している場合や、ネットワークの接続性が悪いためにトランザクションがネットワーク全体に中継されない場合は、トランザクションが確定するまでに時間がかかることがあります。(トランザクションの有効期限を設定する方法については、[信頼できるトランザクションの送信](../../concepts/transactions/reliable-transaction-submission.md)を参照してください)。
@@ -135,9 +144,7 @@ XRP Ledgerでトランザクションを送信するには、アドレスと秘
{% /tabs %}
{{ start_step("Wait") }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" /%}
{{ end_step() }}
### (任意) 休憩
@@ -146,16 +153,18 @@ XRP Ledgerでトランザクションを送信するには、アドレスと秘
**ヒント:** 以下のステップの間または途中で、ここに戻ってきてシーケンス取引を送信することができますが、その際、チケット取引の成功を妨げることはありません。
{{ start_step("Intermission") }}
{% interactive-block label="Intermission" steps=$frontmatter.steps %}
<button id="intermission-payment" class="btn btn-primary previous-steps-required">Payment</button>
<button id="intermission-escrowcreate" class="btn btn-primary previous-steps-required">EscrowCreate</button>
<button id="intermission-accountset" class="btn btn-primary previous-steps-required">AccountSet</button>
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. 有効なチケットの確認
### 7. 有効なチケットの確認
チケット付きのトランザクションを送信したい場合、どのチケットシーケンス番号を使用するかを知る必要があります。アカウントを注意深く管理していれば、どのチケットを持っているかはすでにわかっていると思いますが、よくわからない場合は、[account_objects メソッド][]を使って、利用可能なチケットを調べることができます。例えば、以下のようになります。
@@ -168,14 +177,16 @@ XRP Ledgerでトランザクションを送信するには、アドレスと秘
{% /tabs %}
{{ start_step("Check Tickets") }}
{% interactive-block label="Check Tickets" steps=$frontmatter.steps %}
<button id="check-tickets" class="btn btn-primary previous-steps-required">Check Tickets</button>
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
**ヒント:** チケットが残っている限り、ここから最後まで同じ手順を繰り返すことができます。
### {{n.next()}}. チケット付きトランザクションの準備
### 8. チケット付きトランザクションの準備
チケットが利用できるようになったので、それを使用するトランザクションを準備します。
@@ -196,17 +207,19 @@ TicketCreateトランザクションをすぐに送信する予定がない場
- **`rippled`:** 用意された指示から`LastLedgerSequence`を省略します。サーバーはデフォルトでは値を提供しません。
{% /admonition %}
{{ start_step("Prepare Ticketed Tx") }}
{% interactive-block label="Prepare Ticketed Tx" steps=$frontmatter.steps %}
<div id="ticket-selector">
<h4>Select a Ticket:</h4>
<div class="form-area"></div>
</div>
<button id="prepare-ticketed-tx" class="btn btn-primary previous-steps-required">Prepare Ticketed Transaction</button>
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. チケット付きトランザクションの送信
### 9. チケット付きトランザクションの送信
前のステップで作成した署名付きトランザクションBlobを送信します。例えば、以下のようになります。
@@ -218,19 +231,19 @@ TicketCreateトランザクションをすぐに送信する予定がない場
{% /tabs %}
{{ start_step("Submit Ticketed Tx") }}
{% interactive-block label="Submit Ticketed Tx" steps=$frontmatter.steps %}
<button id="ticketedtx-submit" class="btn btn-primary previous-steps-required" data-tx-blob-from="#tx_blob_t" data-wait-step-name="Wait Again">Submit</button>
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. 検証の待機
### 10. 検証の待機
チケット付きトランザクションは、シーケンス付きトランザクションと同じようにコンセンサスプロセスを経ます。
{{ start_step("Wait Again") }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" /%}
{{ end_step() }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" variables={label: "Wait Again"} /%}
## マルチシグで使用する

View File

@@ -51,3 +51,16 @@ export function slugify(s) {
}
return s;
}
export function idify(s: string) {
// like slugify, but more unicode-friendly.
// for some reason the better version using \p gives an "s12 is undefined" TypeError sometimes,
// so it's disabled for now. With that fixed, we could use localized step names in interactive tutorials.
//s = s.replace(/[^\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\p{Join_Control}]/gu, '').trim().toLowerCase()
s = s.replace(/[^\w\s-]/gu, '').trim().toLowerCase()
s = s.replace(/[\s-]+/gu, '-')
if (!s) {
s = "_";
}
return s
}

View File

@@ -3,15 +3,10 @@ import * as React from 'react';
import dynamicReact from '@markdoc/markdoc/dist/react';
import { usePageSharedData } from '@portal/hooks';
import { Link } from '@portal/Link';
import { idify } from '../helpers';
export {default as XRPLoader} from '../components/XRPLoader';
function slugify(text: string) {
return text
.toLowerCase()
.replace(/ /g, '-')
.replace(/[^\w-]+/g, '');
}
export function IndexPageItems() {
const data = usePageSharedData('index-page-items') as any[];
@@ -29,9 +24,8 @@ export function IndexPageItems() {
);
}
export function StartStep(props: { children: React.ReactNode; stepIdx: number; steps: string[] }) {
const stepLabel = props.steps[props.stepIdx];
const stepId = slugify(stepLabel);
export function InteractiveBlock(props: { children: React.ReactNode; label: string; steps: string[] }) {
const stepId = idify(props.label);
return (
<div className="interactive-block" id={'interactive-' + stepId}>
@@ -40,11 +34,11 @@ export function StartStep(props: { children: React.ReactNode; stepIdx: number; s
<ul
className="breadcrumb tutorial-step-crumbs"
id={'bc-ul-' + stepId}
data-steplabel={stepLabel}
data-steplabel={props.label}
data-stepid={stepId}
>
{props.steps?.map((step, idx) => {
const iterStepId = slugify(step).toLowerCase();
const iterStepId = idify(step).toLowerCase();
let className = `breadcrumb-item bc-${iterStepId}`;
if (idx > 0) className += ' disabled';
if (iterStepId === stepId) className += ' current';

View File

@@ -56,10 +56,6 @@ export const interactiveBlock: Schema & { tagName: string } = {
type: 'String',
required: true,
},
stepIdx: {
type: 'Number',
required: true,
},
steps: {
type: 'Array',
required: true,

View File

@@ -1,20 +1,15 @@
{% if use_network is undefined or use_network == "Testnet" %}
{% set ws_url = "wss://s.altnet.rippletest.net:51233" %}
{% set explorer_url = "https://testnet.xrpl.org" %}
{% set use_network = "Testnet" %}
{% elif use_network == "Devnet" %}
{% set ws_url = "wss://s.devnet.rippletest.net:51233" %}
{% set explorer_url = "https://devnet.xrpl.org" %}
{% elif use_network == "Mainnet" %}
{% set ws_url = "wss://xrplcluster.com" %}
{% set explorer_url = "https://livenet.xrpl.org" %}
{% endif %}
<!-- Interactive tutorials are hard-coded to Testnet for now due to Redocly
limitations. They'll be replaced with new-style tutorials next anyway. -->
{{ start_step("Connect") }}
<button id="connect-button" class="btn btn-primary" data-wsurl="{{ws_url}}" data-explorer="{{explorer_url}}">Connect to {{use_network}}</button>
{% interactive-block label=default($label, "Connect") steps=$frontmatter.steps %}
<button id="connect-button" class="btn btn-primary" data-wsurl="wss://s.altnet.rippletest.net:51233" data-explorer="https://testnet.xrpl.org">Connect to Testnet</button>
<div>
<strong>Connection status:</strong>
<strong>Connection status: </strong>
<span id="connection-status">Not connected</span>
<div class="loader collapse" id="loader-connect"><img class="throbber" src="assets/img/xrp-loader-96.png"></div>
{% loading-icon /%}
</div>
{{ end_step() }}
{% /interactive-block %}

View File

@@ -1,15 +1,9 @@
{% if use_network is undefined or use_network == "Testnet" %}
{% set use_network = "Testnet" %}
{% set faucet_url = "https://faucet.altnet.rippletest.net/accounts" %}
{% elif use_network == "Devnet" %}
{% set faucet_url = "https://faucet.devnet.rippletest.net/accounts" %}
{# No faucet for Mainnet! #}
{% endif %}
{% interactive-block label=default($label, "Generate") steps=$frontmatter.steps %}
{{ start_step("Generate") }}
<button id="generate-creds-button" class="btn btn-primary" data-fauceturl="{{faucet_url}}">Get {{use_network}} credentials</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Generating Keys...</div>
<button id="generate-creds-button" class="btn btn-primary" data-fauceturl="https://faucet.altnet.rippletest.net/accounts">Get Testnet credentials</button>
{% loading-icon message="Generating Keys..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
**Caution:** Ripple provides the [Testnet and Devnet](../../concepts/networks-and-servers/parallel-networks.md) for testing purposes only, and sometimes resets the state of these test networks along with all balances. As a precaution, **do not** use the same addresses on Testnet/Devnet and Mainnet.

View File

@@ -1,12 +1,6 @@
{% if use_network is undefined or use_network == "Testnet" %}
{% set explorer_url = "https://testnet.xrpl.org" %}
{% elif use_network == "Devnet" %}
{% set explorer_url = "https://devnet.xrpl.org" %}
{% elif use_network == "Mainnet" %}
{% set explorer_url = "https://livenet.xrpl.org" %}
{% endif %}
{% interactive-block label=default($label, "Wait") steps=$frontmatter.steps %}
<table class="wait-step" data-explorerurl="{{explorer_url}}">
<table class="wait-step" data-explorerurl="https://testnet.xrpl.org"><tbody>
<tr>
<th>Transaction ID:</th>
<td class="waiting-for-tx">(None)</td>
@@ -24,4 +18,6 @@
</tr>
<tr class="tx-validation-status">
</tr>
</table>
</tbody></table>
{% /interactive-block %}

View File

@@ -61,7 +61,7 @@ Originally, the XRP Ledger was called "Ripple" for the way the technology allowe
| XRP "X" Logo | Ripple triskelion |
|:---------------------------------------|:------------------------------------|
| !["X" logo](assets/img/xrp-x-logo.png) | ![Triskelion](/img/ripple-triskelion.png) |
| !["X" logo](/img/xrp-x-logo.png) | ![Triskelion](/img/ripple-triskelion.png) |
### Trademark

View File

@@ -2,6 +2,8 @@
html: ledger-data-formats.html
parent: protocol-reference.html
blurb: Learn about individual entries that comprise the XRP Ledger's shared state data.
metadata:
indexPage: true
---
# Ledger Data Formats
@@ -15,5 +17,5 @@ Each [ledger version](../../../concepts/ledgers/index.md) in the XRP Ledger is m
{% partial file="/_snippets/ledger-objects-intro.md" /%}
{% from '_snippets/macros/page-children.md' import page_children with context %}
{{ page_children(pages|selectattr("html", "eq", "ledger-object-types.html")|first, 1, 1, True) }}
{% child-pages /%}

View File

@@ -38,8 +38,12 @@ LOCALES = {
* @return {String} The translated string, if one is available, or the provided
* key value if no translation is available.
*/
const current_locale = $("html").prop("lang")
function tl(key) {
let current_locale = $("html").prop("lang").substring(0,2)
if (!(current_locale in LOCALES)) {
console.warn("Interactive tutorials don't have translations for locale:", current_locale)
current_locale = "en"
}
let mesg = LOCALES[current_locale][key]
if (typeof mesg === "undefined") {
mesg = key
@@ -50,20 +54,17 @@ function tl(key) {
/**
* Convert a string of text into a "slug" form that is appropriate for use in
* URLs, HTML id and class attributes, and similar. This matches the equivalent
* function in filter_interactive_steps.py so that each step's ID is derived
* from the given step_name in a consistent way.
* function in @theme/helpers.js so that IDs can be found consistently.
* This version is more Unicode-friendly than the old version ('slugify')
* @param {String} s The text (step_name or similar) to convert into a
* @return {String} The "slug" version of the text, lowercase with no whitespace
* and with most non-alphanumeric characters removed.
*/
function slugify(s) {
const unacceptable_chars = /[^A-Za-z0-9._ ]+/g
const whitespace_regex = /\s+/g
s = s.replace(unacceptable_chars, "")
s = s.replace(whitespace_regex, "_")
s = s.toLowerCase()
function idify(s) {
s = s.replace(/[^\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\p{Join_Control}]/gu, '').trim().toLowerCase()
s = s.replace(/[\s-]+/gu, '-')
if (!s) {
s = "_"
s = "_";
}
return s
}
@@ -76,7 +77,7 @@ function slugify(s) {
* @return {Boolean} Whether or not this step has been marked complete.
*/
function is_complete(step_name) {
return is_complete_by_id(slugify(step_name))
return is_complete_by_id(idify(step_name))
}
/**
@@ -97,7 +98,7 @@ function is_complete_by_id(step_id) {
* start_step(step_name) function in the MD file.
*/
function complete_step(step_name) {
complete_step_by_id(slugify(step_name))
complete_step_by_id(idify(step_name))
}
/**
@@ -423,7 +424,7 @@ function setup_wait_steps() {
} else {
status_box.html(
`<th>${tl("Final Result:")}</th>
<td><img class="throbber" src="assets/img/xrp-loader-96.png">
<td><img class="throbber" src="/img/xrp-loader-96.png">
${tl("(Still pending...)")}</td>`)
}
@@ -453,7 +454,7 @@ function setup_wait_steps() {
* transaction blob via api.request({command: "submit", opts})
*/
async function activate_wait_step(step_name, prelim) {
const step_id = slugify(step_name)
const step_id = idify(step_name)
const wait_step = $(`#interactive-${step_id} .wait-step`)
const status_box = wait_step.find(".tx-validation-status")
const tx_id = prelim.result.tx_json.hash
@@ -628,7 +629,7 @@ async function show_log(block, msg) {
}
$(document).ready(() => {
window.onRouteChange(() => {
disable_followup_steps()
setup_generate_step()
setup_connect_step()

View File

@@ -1,7 +1,7 @@
// 1. Generate
// 2. Connect
// The code for these steps is handled by interactive-tutorial.js
$(document).ready(() => {
window.onRouteChange(() => {
const EXPLORER = $("#connect-button").data("explorer")

View File

@@ -1,7 +1,7 @@
// 1. Generate
// 2. Connect
// The code for these steps is handled by interactive-tutorial.js
$(document).ready(() => {
window.onRouteChange(() => {
// 3. Send AccountSet --------------------------------------------------------
$("#send-accountset").click( async (event) => {

View File

@@ -1,7 +1,7 @@
// 1. Generate
// 2. Connect
// The code for these steps is handled by interactive-tutorial.js
$(document).ready(() => {
window.onRouteChange(() => {
// 3. Send AccountSet to Start the Freeze ------------------------------------
// also 6. Send AccountSet to End the Freeze.

View File

@@ -55,7 +55,7 @@ window.after_connect.push(async () => {
trust_line_setup_done = true
})
$(document).ready(() => {
window.onRouteChange(() => {

View File

@@ -86,7 +86,7 @@ function domain_to_hex(s) {
return result.toUpperCase()
}
$(document).ready(() => {
window.onRouteChange(() => {
setup_2x_generate_step()
$("#cold-domain-text").keyup( (event) => {

View File

@@ -1,7 +1,7 @@
// 1. Generate
// 2. Connect
// The code for these steps is handled by interactive-tutorial.js
$(document).ready(() => {
window.onRouteChange(() => {
// 3. Send AccountSet --------------------------------------------------------
$("#send-accountset").click( async (event) => {

View File

@@ -2,7 +2,7 @@
// 1. Connect
// The code for these steps is handled by interactive-tutorial.js
$(document).ready(() => {
window.onRouteChange(() => {
// 2. Prepare Transaction ------------------------------------------------------
$("#prepare-button").click( async function(event) {

View File

@@ -3,7 +3,7 @@
// Get Credentials, Connect steps handled by the snippet
$(document).ready(() => {
window.onRouteChange(() => {
// Look Up Offers --------------------------------------------------------------

View File

@@ -1,7 +1,7 @@
// 1. Generate
// 2. Connect
// The code for these steps is handled by interactive-tutorial.js
$(document).ready(() => {
window.onRouteChange(() => {
const LLS_OFFSET = 75 // Expire unconfirmed transactions after about ~5 min
// 3. Check Sequence Number

View File

@@ -21,8 +21,10 @@ WebSocket follows a model where the client and server open one connection, then
- You need a stable internet connection and access to an XRP Ledger server. The embedded examples connect to Ripple's pool of public servers. If you [run your own `rippled` or Clio server](../../infrastructure/installation/index.md), you can also connect to that server locally.
- To properly handle XRP values without rounding errors, you need access to a number type that can do math on 64-bit unsigned integers. The examples in this tutorial use [big.js](https://github.com/MikeMcl/big.js/). If you are working with [tokens](../../concepts/tokens/index.md), you need even more precision. For more information, see [Currency Precision](../../references/protocol/data-types/currency-formats.md#xrp-precision).
<script type="application/javascript" src="/js/interactive-tutorial.js"></script>
<!-- Big number support -->
<script type="application/javascript" src="assets/vendor/big.min.js"></script>
<script type="application/javascript" src="/vendor/big.min.js"></script>
<script type="application/javascript">
// Helper stuff for this interactive tutorial specifically
@@ -72,13 +74,15 @@ const socket = new WebSocket('ws://localhost:6006')
Example:
{{ start_step("Connect") }}
{% interactive-block label="Connect" steps=$frontmatter.steps %}
<button id="connect-socket-button" class="btn btn-primary">Connect</button>
<strong>Connection status:</strong>
<span id="connection-status">Not connected</span>
<h5>Console:</h5>
<div class="ws-console" id="monitor-console-connect"><span class="placeholder">(Log is empty)</span></div>
{{ end_step() }}
{% /interactive-block %}
<script type="application/javascript">
let socket;
@@ -187,12 +191,14 @@ async function pingpong() {
// Add pingpong() to the 'open' listener for socket
```
{{ start_step("Dispatch Messages") }}
{% interactive-block label="Dispatch Messages" steps=$frontmatter.steps %}
<button id="enable_dispatcher" class="btn btn-primary" disabled="disabled">Enable Dispatcher</button>
<button id="dispatch_ping" class="btn btn-primary" disabled="disabled">Ping!</button>
<h5>Responses</h5>
<div class="ws-console" id="monitor-console-ping"><span class="placeholder">(Log is empty)</span></div>
{{ end_step() }}
{% /interactive-block %}
<script type="application/javascript">
const AWAITING = {}
@@ -290,13 +296,15 @@ WS_HANDLERS["transaction"] = log_tx
For the following example, try opening the [Transaction Sender](/resources/dev-tools/tx-sender) in a different window or even on a different device and sending transactions to the address you subscribed to:
{{ start_step("Subscribe") }}
{% interactive-block label="Subscribe" steps=$frontmatter.steps %}
<label for="subscribe_address">Test Net Address:</label>
<input type="text" class="form-control" id="subscribe_address" value="rUCzEr6jrEyMpjhs4wSdQdz4g8Y382NxfM">
<button id="tx_subscribe" class="btn btn-primary" disabled="disabled">Subscribe</button>
<h5>Transactions</h5>
<div class="ws-console" id="monitor-console-subscribe"><span class="placeholder">(Log is empty)</span></div>
{{ end_step() }}
{% /interactive-block %}
<script type="application/javascript">
async function do_subscribe() {
@@ -358,11 +366,13 @@ The following sample code looks at transaction metadata of all the above transac
{% code-snippet file="/_code-samples/monitor-payments-websocket/js/read-amount-received.js" language="js" /%}
{{ start_step("Read Payments") }}
{% interactive-block label="Read Payments" steps=$frontmatter.steps %}
<button id="tx_read" class="btn btn-primary" disabled="disabled">Start Reading</button>
<h5>Transactions</h5>
<div class="ws-console" id="monitor-console-read"><span class="placeholder">(Log is empty)</span></div>
{{ end_step() }}
{% /interactive-block %}
<script type="application/javascript">
function CountXRPDifference(affected_nodes, address) {

View File

@@ -3,13 +3,11 @@ html: send-xrp.html
parent: tasks.html
blurb: Learn how to send test payments right from your browser.
cta_text: Send XRP
embed_xrpl_js: true
filters:
- interactive_steps
labels:
- XRP
- Payments
top_nav_grouping: Popular Pages
steps: ['Generate', 'Connect', 'Prepare', 'Sign', 'Submit', 'Wait', 'Check']
---
# Send XRP
@@ -20,8 +18,8 @@ This tutorial explains how to send a direct XRP Payment using `xrpl.js` for Java
## Prerequisites
<!-- Source for this specific tutorial's interactive bits: -->
<script type="application/javascript" src="assets/js/tutorials/send-xrp.js"></script>
{% set use_network = "Testnet" %}
<script type="application/javascript" src="/js/interactive-tutorial.js"></script>
<script type="application/javascript" src="/js/tutorials/send-xrp.js"></script>
To interact with the XRP Ledger, you need to set up a dev environment with the necessary tools. This tutorial provides examples using the following options:
@@ -145,14 +143,15 @@ Here's an example of preparing the above payment:
{% /tabs %}
{{ start_step("Prepare") }}
{% interactive-block label="Prepare" steps=$frontmatter.steps %}
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">Send: </span>
</div>
<input type="number" class="form-control" value="22" id="xrp-amount"
aria-label="Amount of XRP, as a decimal" aria-describedby="xrp-amount-label"
min=".000001" max="100000000000" step="any">
min=".000001" max="100000000000" step="any" />
<div class="input-group-append">
<span class="input-group-text" id="xrp-amount-label"> XRP</span>
</div>
@@ -160,7 +159,8 @@ Here's an example of preparing the above payment:
<button id="prepare-button" class="btn btn-primary previous-steps-required">Prepare
example transaction</button>
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### 4. Sign the Transaction Instructions
@@ -199,11 +199,13 @@ The result of the signing operation is a transaction object containing a signatu
- In xrpl4j, `SignatureService.sign` returns a `SignedTransaction`, which contains the transaction's hash, which you can use to look up the transaction later.
- In `XRPL_PHP`, the signing API also returns the transaction's ID, or identifying hash, which you can use to look up the transaction later. This is a 64-character hexadecimal string that is unique to this transaction.
{{ start_step("Sign") }}
{% interactive-block label="Sign" steps=$frontmatter.steps %}
<button id="sign-button" class="btn btn-primary previous-steps-required">Sign
example transaction</button>
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### 5. Submit the Signed Blob
@@ -246,12 +248,16 @@ If you see any other result, you should check the following:
See the full list of [transaction results](../../references/protocol/transactions/transaction-results/transaction-results.md) for more possibilities.
{{ start_step("Submit") }}
{% interactive-block label="Submit" steps=$frontmatter.steps %}
<button id="submit-button" class="btn btn-primary previous-steps-required" data-tx-blob-from="#signed-tx-blob" data-wait-step-name="Wait">Submit
example transaction</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png"> Sending...</div>
{% loading-icon message="Sending..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### 6. Wait for Validation
@@ -286,9 +292,7 @@ Most transactions are accepted into the next ledger version after they're submit
{% /tabs %}
{{ start_step("Wait") }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" /%}
{{ end_step() }}
### 7. Check Transaction Status
@@ -327,10 +331,12 @@ To know for sure what a transaction did, you must look up the outcome of the tra
**Caution:** XRP Ledger APIs may return tentative results from ledger versions that have not yet been validated. For example, in [tx method][] response, be sure to look for `"validated": true` to confirm that the data comes from a validated ledger version. Transaction results that are not from a validated ledger version are subject to change. For more information, see [Finality of Results](../../concepts/transactions/finality-of-results/index.md).
{{ start_step("Check") }}
{% interactive-block label="Check" steps=$frontmatter.steps %}
<button id="get-tx-button" class="btn btn-primary previous-steps-required">Check transaction status</button>
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
## Differences for Production

View File

@@ -27,9 +27,7 @@ To disable the master key pair for an account, you must meet the following prere
## Steps
{% set n = cycler(* range(1,99)) %}
### {{n.next()}}. Construct Transaction JSON
### 1. Construct Transaction JSON
Prepare an [AccountSet transaction][] from your account with the field `"SetValue": 4`. This is the value for the AccountSet flag "Disable Master" (`asfDisableMaster`). The only other required fields for this transaction are the required [common fields](../../references/protocol/transactions/common-fields.md). For example, if you leave off the [auto-fillable fields](../../references/protocol/transactions/common-fields.md#auto-fillable-fields), the following transaction instructions are enough:
@@ -43,7 +41,7 @@ Prepare an [AccountSet transaction][] from your account with the field `"SetValu
**Tip:** It is strongly recommended to also provide the `LastLedgerSequence` field so that you can [reliably get the outcome of the transaction in a predictable amount of time](../../concepts/transactions/reliable-transaction-submission.md).
### {{n.next()}}. Sign Transaction
### 2. Sign Transaction
You must use the **master key pair** to sign the transaction.
@@ -181,7 +179,7 @@ Look for `"status": "success"` to indicate that the server successfully signed t
Take note of the `tx_blob` value from the response. This is a signed transaction binary you can submit to the network.
### {{n.next()}}. Submit Transaction
### 3. Submit Transaction
Submit the signed transaction blob from the previous step to the XRP Ledger.
@@ -307,11 +305,11 @@ Loading: "/etc/opt/ripple/rippled.cfg"
If the transaction fails with the result `tecNO_ALTERNATIVE_KEY`, your account does not have another method of authorizing transactions currently enabled. You must [assign a regular key pair](assign-a-regular-key-pair.md) or [set up multi-signing](set-up-multi-signing.md), then try again to disable the master key pair.
### {{n.next()}}. Wait for validation
### 4. Wait for validation
{% partial file="/_snippets/wait-for-validation.md" /%}
### {{n.next()}}. Confirm Account Flags
### 5. Confirm Account Flags
Confirm that your account's master key is disabled using the [account_info method][]. Be sure to specify the following parameters:

View File

@@ -26,9 +26,7 @@ To use offline signing, you must meet the following prerequisites:
## Steps
{% set n = cycler(* range(1,99)) %}
### {{n.next()}}. Set up offline machine
### 1. Set up offline machine
The offline machine needs secure persistent storage (for example, an encrypted disk drive) and a way to [sign transactions](../../concepts/transactions/secure-signing.md). For an offline machine, you typically use physical media to transfer any necessary software after downloading it from an online machine. You must be sure that the online machine, the physical media, and the software itself are not infected with malware.
@@ -41,7 +39,7 @@ Software options for signing on the XRP Ledger include:
You may want to set up custom software to help construct transaction instructions on the offline machine. For example, your software may track what [sequence number][] to use next, or contain preset templates for certain types of transactions you expect to send.
### {{n.next()}}. Generate cryptographic keys
### 2. Generate cryptographic keys
On the **offline machine**, generate a pair of [cryptographic keys](../../concepts/accounts/cryptographic-keys.md) to be used with your account. Be sure to generate the keys with a securely random procedure, not from a short passphrase or some other source that does not have enough entropy. For example, you can use the [wallet_propose method][] of `rippled`:
@@ -82,7 +80,7 @@ Take note of the following values:
### {{n.next()}}. Fund the new address
### 3. Fund the new address
From an online machine, send enough XRP to the **account address** you noted in step 1. For more information, see [Creating Accounts](../../concepts/accounts/accounts.md#creating-accounts).
@@ -90,7 +88,7 @@ From an online machine, send enough XRP to the **account address** you noted in
### {{n.next()}}. Confirm account details
### 4. Confirm account details
When the transaction from the previous step is validated by consensus, your account has been created. From the online machine, you can confirm the status of the account with the [account_info method][]. Make sure the response contains `"validated": true` to confirm that this result is final.
@@ -129,7 +127,7 @@ Loading: "/etc/opt/ripple/rippled.cfg"
{% /tabs %}
### {{n.next()}}. Enter the sequence number on the offline machine.
### 5. Enter the sequence number on the offline machine.
Save the account's starting sequence number on the offline machine. Whenever you prepare a transaction using the offline machine, use the saved sequence number, then increase the sequence number by 1 and save the new value.
@@ -139,7 +137,7 @@ Optionally, save the current ledger index to the offline machine. You can use th
### {{n.next()}}. Sign initial setup transactions, if any.
### 6. Sign initial setup transactions, if any.
On the offline machine, prepare and sign transactions for configuring your account. The details depend on how you intend to use your account. Some examples of things you might want to do include:
@@ -190,13 +188,13 @@ Loading: "/etc/opt/ripple/rippled.cfg"
To ensure _all_ transactions have a final outcome within a limited amount of time, provide a [`LastLedgerSequence`](../../concepts/transactions/reliable-transaction-submission.md#lastledgersequence) field. This value should be based on the current ledger index (which you must look up from an online machine) and the amount of time you want the transaction to remain valid. Be sure to set a large enough `LastLedgerSequence` value to allow for time spent switching from the online machine to the offline machine and back. For example, a value 256 higher than the current ledger index means that the transaction is valid for about 15 minutes. For more information, see [Finality of Results](../../concepts/transactions/finality-of-results/index.md) and [Reliable Transaction Submission](../../concepts/transactions/reliable-transaction-submission.md).
### {{n.next()}}. Copy transactions to online machine.
### 7. Copy transactions to online machine.
After you have signed the transactions, the next step is to get the signed transaction data to your online machine. See [Prerequisites](#prerequisites) for some examples of how to do this.
### {{n.next()}}. Submit setup transactions.
### 8. Submit setup transactions.
The next step is to submit the transactions. Most transactions should have a final outcome in the next validated ledger after submission (about 4 seconds later), or possibly the ledger after that if they get queued (less than 10 seconds). For detailed steps to track the final outcome of a transaction, see [Reliable Transaction Submission](../../concepts/transactions/reliable-transaction-submission.md).
@@ -241,7 +239,7 @@ Loading: "/etc/opt/ripple/rippled.cfg"
Retry submitting any transactions that failed with a [non-final outcome](../../concepts/transactions/finality-of-results/index.md). There is no chance of the same transaction being processed more than once.
### {{n.next()}}. Confirm the final status of the transactions.
### 9. Confirm the final status of the transactions.
For each transaction you submitted, note the transaction's [final outcome](../../concepts/transactions/finality-of-results/index.md), for example using the [tx method][]. For example:
@@ -314,7 +312,7 @@ For any transactions you decide to adjust or replace, note the details for when
### {{n.next()}}. Reconcile offline machine status.
### 10. Reconcile offline machine status.
Return to the offline machine and apply any necessary changes to your custom server's saved settings, such as:

View File

@@ -7,6 +7,7 @@ filters:
- interactive_steps
labels:
- Accounts
steps: ['Generate', 'Connect', 'Send AccountSet', 'Wait', 'Confirm Settings', 'Test Payments']
---
# Require Destination Tags
@@ -26,7 +27,8 @@ This tutorial demonstrates how to enable the Require Destination Tag flag on you
- You can also read along and use the interactive steps in your browser without any setup.
<!-- Source for this specific tutorial's interactive bits: -->
<script type="application/javascript" src="assets/js/tutorials/require-destination-tags.js"></script>
<script type="application/javascript" src="/js/interactive-tutorial.js"></script>
<script type="application/javascript" src="/js/tutorials/require-destination-tags.js"></script>
## Example Code
@@ -35,9 +37,8 @@ Complete sample code for all the steps of these tutorials is available under the
- See [Code Samples: Require Destination Tags](https://github.com/XRPLF/xrpl-dev-portal/tree/master/content/_code-samples/require-destination-tags/) in the source repository for this website.
## Steps
{% set n = cycler(* range(1,99)) %}
### {{n.next()}}. Get Credentials
### 1. Get Credentials
To transact on the XRP Ledger, you need an address and secret key, and some XRP. For development purposes, you can get these using the following interface:
@@ -45,7 +46,7 @@ To transact on the XRP Ledger, you need an address and secret key, and some XRP.
When you're building production-ready software, you should use an existing account, and manage your keys using a [secure signing configuration](../../concepts/transactions/secure-signing.md).
### {{n.next()}}. Connect to the Network
### 2. Connect to the Network
You must be connected to the network to submit transactions to it. The following code shows how to connect to a public XRP Ledger Testnet server a supported [client library](../../references/client-libraries.md):
@@ -65,7 +66,7 @@ For this tutorial, click the following button to connect:
{% partial file="/_snippets/interactive-tutorials/connect-step.md" /%}
### {{n.next()}}. Send AccountSet Transaction
### 3. Send AccountSet Transaction
To enable the `RequireDest` flag, set the [`asfRequireDest` value (`1`)](../../references/protocol/transactions/types/accountset.md#accountset-flags) in the `SetFlag` field of an [AccountSet transaction][]. To send the transaction, you first _prepare_ it to fill out all the necessary fields, then _sign_ it with your account's secret key, and finally _submit_ it to the network.
@@ -83,23 +84,25 @@ For example:
{% /tabs %}
{{ start_step("Send AccountSet") }}
{% interactive-block label="Send AccountSet" steps=$frontmatter.steps %}
<button id="send-accountset" class="btn btn-primary previous-steps-required" data-wait-step-name="Wait">Send AccountSet</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending...</div>
{% loading-icon message="Sending..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. Wait for Validation
### 4. Wait for Validation
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. If the XRP Ledger is busy or poor network connectivity delays a transaction from being relayed throughout the network, a transaction may take longer to be confirmed. (For information on how to set an expiration for transactions, see [Reliable Transaction Submission](../../concepts/transactions/reliable-transaction-submission.md).)
{{ start_step("Wait") }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" /%}
{{ end_step() }}
### {{n.next()}}. Confirm Account Settings
### 5. Confirm Account Settings
After the transaction is validated, you can check your account's settings to confirm that the Require Destination Tag flag is enabled.
@@ -117,20 +120,28 @@ After the transaction is validated, you can check your account's settings to con
{% /tabs %}
{{ start_step("Confirm Settings") }}
{% interactive-block label="Confirm Settings" steps=$frontmatter.steps %}
<button id="confirm-settings" class="btn btn-primary previous-steps-required">Confirm Settings</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending...</div>
{% loading-icon message="Sending..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
For further confirmation, you can send test transactions (from a different address) to confirm that the setting is working as you expect it to. If you a payment with a destination tag, it should succeed, and if you send one _without_ a destination tag, it should fail with the error code [`tecDST_TAG_NEEDED`](../../references/protocol/transactions/transaction-results/tec-codes.md).
{{ start_step("Test Payments") }}
{% interactive-block label="Test Payments" steps=$frontmatter.steps %}
<button class="test-payment btn btn-primary" data-dt="10">Send XRP (with Destination Tag)</button>
<button class="test-payment btn btn-primary" data-dt="">Send XRP (without Destination Tag)</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending...</div>
{% loading-icon message="Sending..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
## See Also

View File

@@ -7,6 +7,7 @@ filters:
- interactive_steps
labels:
- Accounts
steps: ['Generate', 'Connect', 'Check Sequence', 'Prepare & Sign', 'Submit', 'Wait', 'Intermission', 'Check Tickets', 'Prepare Ticketed Tx', 'Submit Ticketed Tx', 'Wait Again']
---
# Use Tickets
@@ -15,8 +16,8 @@ labels:
## Prerequisites
<!-- Source for this specific tutorial's interactive bits: -->
<script type="application/javascript" src="assets/js/tutorials/use-tickets.js"></script>
{% set use_network = "Testnet" %}
<script type="application/javascript" src="/js/interactive-tutorial.js"></script>
<script type="application/javascript" src="/js/tutorials/use-tickets.js"></script>
This page provides JavaScript examples that use the [xrpl.js](https://js.xrpl.org/) library. See [Get Started Using JavaScript](../get-started/get-started-using-javascript.md) for setup instructions.
@@ -25,7 +26,6 @@ Since JavaScript works in the web browser, you can read along and use the intera
## Steps
{% set n = cycler(* range(1,99)) %}
This tutorial is divided into a few phases:
@@ -34,7 +34,7 @@ This tutorial is divided into a few phases:
- (Optional) **Intermission:** After creating Tickets, you can send various other transactions at any time before, during, and after the following steps.
- (Steps 7-10) **Use Ticket:** Use one of your set-aside Tickets to send a transaction. You can repeat these steps while skipping the previous parts as long as you have at least one Ticket remaining to use.
### {{n.next()}}. Get Credentials
### 1. Get Credentials
To transact on the XRP Ledger, you need an address and secret key, and some XRP. For development purposes, you can get these on the [{{use_network}}](../../concepts/networks-and-servers/parallel-networks.md) using the following interface:
@@ -43,7 +43,7 @@ To transact on the XRP Ledger, you need an address and secret key, and some XRP.
When you're building production-ready software, you should use an existing account, and manage your keys using a [secure signing configuration](../../concepts/transactions/secure-signing.md).
### {{n.next()}}. Connect to Network
### 2. Connect to Network
You must be connected to the network to submit transactions to it. Since Tickets are only available on Devnet so far, you should connect to a Devnet server. For example:
@@ -62,7 +62,7 @@ For this tutorial, click the following button to connect:
{% partial file="/_snippets/interactive-tutorials/connect-step.md" /%}
### {{n.next()}}. Check Sequence Number
### 3. Check Sequence Number
Before you create any Tickets, you should check what [Sequence Number][] your account is at. You want the current Sequence number for the next step, and the Ticket Sequence numbers it sets aside start from this number.
@@ -74,15 +74,19 @@ Before you create any Tickets, you should check what [Sequence Number][] your ac
{% /tabs %}
{{ start_step("Check Sequence") }}
{% interactive-block label="Check Sequence" steps=$frontmatter.steps %}
<button id="check-sequence" class="btn btn-primary previous-steps-required">Check Sequence Number</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Querying...</div>
{% loading-icon message="Querying..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. Prepare and Sign TicketCreate
### 4. Prepare and Sign TicketCreate
Construct a [TicketCreate transaction][] using the sequence number you determined in the previous step. Use the `TicketCount` field to specify how many Tickets to create. For example, to prepare a transaction that would make 10 Tickets:
@@ -97,14 +101,16 @@ Construct a [TicketCreate transaction][] using the sequence number you determine
Record the transaction's hash and `LastLedgerSequence` value so you can [be sure whether or not it got validated](../../concepts/transactions/reliable-transaction-submission.md) later.
{{ start_step("Prepare & Sign") }}
{% interactive-block label="Prepare & Sign" steps=$frontmatter.steps %}
<button id="prepare-and-sign" class="btn btn-primary previous-steps-required">Prepare & Sign</button>
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. Submit TicketCreate
### 5. Submit TicketCreate
Submit the signed transaction blob that you created in the previous step. For example:
@@ -116,14 +122,18 @@ Submit the signed transaction blob that you created in the previous step. For ex
{% /tabs %}
{{ start_step("Submit") }}
{% interactive-block label="Submit" steps=$frontmatter.steps %}
<button id="ticketcreate-submit" class="btn btn-primary previous-steps-required" data-tx-blob-from="#tx_blob" data-wait-step-name="Wait">Submit</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending...</div>
{% loading-icon message="Sending..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. Wait for Validation
### 6. Wait for Validation
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. If the XRP Ledger is busy or poor network connectivity delays a transaction from being relayed throughout the network, a transaction may take longer to be confirmed. (For information on how to set an expiration for transactions, see [Reliable Transaction Submission](../../concepts/transactions/reliable-transaction-submission.md).)
@@ -135,9 +145,7 @@ Most transactions are accepted into the next ledger version after they're submit
{% /tabs %}
{{ start_step("Wait") }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" /%}
{{ end_step() }}
### (Optional) Intermission
@@ -146,16 +154,18 @@ The power of Tickets is that you can carry on with your account's business as us
**Tip:** You can come back here to send Sequenced transactions between or during any of the following steps, without interfering with the success of your Ticketed transaction.
{{ start_step("Intermission") }}
{% interactive-block label="Intermission" steps=$frontmatter.steps %}
<button id="intermission-payment" class="btn btn-primary previous-steps-required">Payment</button>
<button id="intermission-escrowcreate" class="btn btn-primary previous-steps-required">EscrowCreate</button>
<button id="intermission-accountset" class="btn btn-primary previous-steps-required">AccountSet</button>
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. Check Available Tickets
### 7. Check Available Tickets
When you want to send a Ticketed transaction, you need to know what Ticket Sequence number to use for it. If you've been keeping careful track of your account, you already know which Tickets you have, but if you're not sure, you can use the [account_objects method][] to look up your available tickets. For example:
@@ -168,14 +178,16 @@ When you want to send a Ticketed transaction, you need to know what Ticket Seque
{% /tabs %}
{{ start_step("Check Tickets") }}
{% interactive-block label="Check Tickets" steps=$frontmatter.steps %}
<button id="check-tickets" class="btn btn-primary previous-steps-required">Check Tickets</button>
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
**Tip:** You can repeat the steps from here through the end as long as you have Tickets left to be used!
### {{n.next()}}. Prepare Ticketed Transaction
### 8. Prepare Ticketed Transaction
Now that you have a Ticket available, you can prepare a transaction that uses it.
@@ -196,17 +208,19 @@ If you don't plan to submit the TicketCreate transaction right away, you should
- **`rippled`:** Omit `LastLedgerSequence` from the prepared instructions. The server does not provide a value by default.
{% /admonition %}
{{ start_step("Prepare Ticketed Tx") }}
{% interactive-block label="Prepare Ticketed Tx" steps=$frontmatter.steps %}
<div id="ticket-selector">
<h4>Select a Ticket:</h4>
<div class="form-area"></div>
</div>
<button id="prepare-ticketed-tx" class="btn btn-primary previous-steps-required">Prepare Ticketed Transaction</button>
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. Submit Ticketed Transaction
### 9. Submit Ticketed Transaction
Submit the signed transaction blob that you created in the previous step. For example:
@@ -218,19 +232,19 @@ Submit the signed transaction blob that you created in the previous step. For ex
{% /tabs %}
{{ start_step("Submit Ticketed Tx") }}
{% interactive-block label="Submit Ticketed Tx" steps=$frontmatter.steps %}
<button id="ticketedtx-submit" class="btn btn-primary previous-steps-required" data-tx-blob-from="#tx_blob_t" data-wait-step-name="Wait Again">Submit</button>
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. Wait for Validation
### 10. Wait for Validation
Ticketed transactions go through the consensus process the same way that Sequenced transactions do.
{{ start_step("Wait Again") }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" /%}
{{ end_step() }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" variables={label: "Wait Again"} /%}
## With Multi-Signing

View File

@@ -9,6 +9,7 @@ labels:
- Decentralized Exchange
- Tokens
- AMM
steps: ['Connect', 'Generate', 'Acquire tokens', 'Check for AMM', 'Look up AMMCreate cost', 'Create AMM', 'Check AMM info', 'Check trust lines']
---
# Create an Automated Market Maker
@@ -17,7 +18,8 @@ _(Requires the [AMM amendment][] {% not-enabled /%})_
An [Automated Market Maker (AMM)](../../concepts/tokens/decentralized-exchange/automated-market-makers.md) can be an efficient way to facilitate exchanges between two assets while earning its liquidity providers passive income. This tutorial shows how to create an AMM for a given asset pair.
<!-- Source for this specific tutorial's interactive bits: -->
<script type="application/javascript" src="assets/js/tutorials/create-amm.js"></script>
<script type="application/javascript" src="/js/interactive-tutorial.js"></script>
<script type="application/javascript" src="/js/tutorials/create-amm.js"></script>
## Prerequisites
@@ -37,10 +39,8 @@ Complete sample code for all of the steps of these tutorials is available under
## Steps
{% set n = cycler(* range(1,99)) %}
{% set use_network = "Devnet" %}
### {{n.next()}}. Connect to the network
### 1. Connect to the network
You must be connected to the network to query it and submit transactions. The following code shows how to connect to a public {{use_network}} server using a supported [client library](../../references/client-libraries.md):
@@ -56,7 +56,7 @@ For this tutorial, click the following button to connect:
{% partial file="/_snippets/interactive-tutorials/connect-step.md" /%}
### {{n.next()}}. Get credentials
### 2. Get credentials
To transact on the XRP Ledger, you need an address, a secret key, and some XRP. For development and testing purposes, you can get these on the [{{use_network}}](../../concepts/networks-and-servers/parallel-networks.md) using the following interface:
@@ -73,7 +73,7 @@ When you're building production-ready software, you should use an existing accou
{% /tabs %}
### {{n.next()}}. Select and acquire assets
### 3. Select and acquire assets
As the creator of an AMM, you are also the first liquidity provider and you have to supply it with a starting pool of assets. Other users of the XRP Ledger can also become liquidity providers by supplying assets after the AMM exists. It's crucial to choose assets carefully because, as a liquidity provider for an AMM, you are supplying some amounts of both for users to swap between. If one of the AMM's assets becomes worthless, other users can use the AMM to trade for the other asset, leaving the AMM (and thus, its liquidity providers including you) holding only the worthless one. Technically, the AMM always holds some positive amount of both assets, but the amounts can be very small.
@@ -101,14 +101,18 @@ The helper function for issuing follows an abbreviated version of the steps in t
{% /tabs %}
{{ start_step("Acquire tokens") }}
{% interactive-block label="Acquire tokens" steps=$frontmatter.steps %}
<button id="buy-tst" class="btn btn-primary previous-steps-required">Buy TST</button>
<button id="get-foo" class="btn btn-primary previous-steps-required">Get FOO</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Working...</div>
<div class="output-area"></div>
{{ end_step() }}
### {{n.next()}}. Check if the AMM exists
{% loading-icon message="Working..." /%}
<div class="output-area"></div>
{% /interactive-block %}
### 4. Check if the AMM exists
Since there can only be one AMM for a specific pair of assets, it's best to check first before trying to create one. Use the [amm_info method][] to check whether the AMM already exists. For the request, you specify the two assets. The response should be an `actNotFound` error if the AMM does not exist.
@@ -122,13 +126,17 @@ Since there can only be one AMM for a specific pair of assets, it's best to chec
If the AMM does already exist, you should double-check that you specified the right pair of assets. If someone else has already created this AMM, you can deposit to it instead. <!-- TODO: link to a tutorial about depositing to and withdrawing from an AMM when one exists -->
{{ start_step("Check for AMM") }}
<button id="check-for-amm" class="btn btn-primary previous-steps-required">Check AMM</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending...</div>
<div class="output-area"></div>
{{ end_step() }}
{% interactive-block label="Check for AMM" steps=$frontmatter.steps %}
### {{n.next()}}. Look up the AMMCreate transaction cost
<button id="check-for-amm" class="btn btn-primary previous-steps-required">Check AMM</button>
{% loading-icon message="Sending..." /%}
<div class="output-area"></div>
{% /interactive-block %}
### 5. Look up the AMMCreate transaction cost
Creating an AMM has a special [transaction cost][] to prevent spam: since it creates objects in the ledger that no one owns, you must burn at least one [owner reserve increment](../../concepts/accounts/reserves.md) of XRP to send the AMMCreate transaction. The exact value can change due to [fee voting](https://xrpl.org/fee-voting.html), so you should look up the current incremental reserve value using the [server_state method][].
@@ -142,14 +150,18 @@ It is also a good practice to display this value and give a human operator a cha
{% /tabs %}
{{ start_step("Look up AMMCreate cost") }}
{% interactive-block label="Look up AMMCreate cost" steps=$frontmatter.steps %}
<button id="look-up-ammcreate-cost" class="btn btn-primary previous-steps-required">Check cost</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending...</div>
{% loading-icon message="Sending..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. Send AMMCreate transaction
### 6. Send AMMCreate transaction
Send an [AMMCreate transaction][] to create the AMM. Important aspects of this transaction include:
@@ -172,7 +184,8 @@ For the two starting assets, it does not matter which is `Asset` and which is `A
{% /tabs %}
{{ start_step("Create AMM") }}
{% interactive-block label="Create AMM" steps=$frontmatter.steps %}
<form>
<div class="form-group row">
<label for="trading-fee" class="col-form-label col-sm-3">Trading Fee</label>
@@ -203,11 +216,14 @@ For the two starting assets, it does not matter which is `Asset` and which is `A
</div>
</form>
<button id="create-amm" class="btn btn-primary previous-steps-required">Create AMM</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending...</div>
<div class="output-area"></div>
{{ end_step() }}
### {{n.next()}}. Check AMM info
{% loading-icon message="Sending..." /%}
<div class="output-area"></div>
{% /interactive-block %}
### 7. Check AMM info
If the AMMCreate transaction succeeded, it creates the AMM and related objects in the ledger. You _could_ check the metadata of the AMMCreate transaction, but it is often easier to call the [amm_info method][] again to get the status of the newly-created AMM.
@@ -223,13 +239,17 @@ In the result, the `amm` object's `lp_token` field is particularly useful becaus
Initially, the AMM's total outstanding LP Tokens, reported in the `lp_token` field of the `amm_info` response, match the tokens you hold as its first liquidity provider. However, after other accounts deposit liquidity to the same AMM, the amount shown in `amm_info` updates to reflect the total issued to all liquidity providers. Since others can deposit at any time, even potentially in the same ledger version where the AMM was created, you shouldn't assume that this amount represents your personal LP Tokens balance.
{{ start_step("Check AMM info") }}
<button id="check-amm-info" class="btn btn-primary previous-steps-required">Check AMM</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending...</div>
<div class="output-area"></div>
{{ end_step() }}
{% interactive-block label="Check AMM info" steps=$frontmatter.steps %}
### {{n.next()}}. Check trust lines
<button id="check-amm-info" class="btn btn-primary previous-steps-required">Check AMM</button>
{% loading-icon message="Sending..." /%}
<div class="output-area"></div>
{% /interactive-block %}
### 8. Check trust lines
You can also use the [account_lines method][] to get an updated view of your token balances. Your balances should be decreased by the amounts you deposited, but you now have a balance of LP Tokens that you received from the AMM.
@@ -245,11 +265,15 @@ The `account_lines` response shows only the tokens held by the account you looke
**Tip:** If one of the assets in the AMM's pool is XRP, you need to call the [account_info method][] on your account to see the difference in your balance (the `Balance` field of the account object).
{{ start_step("Check trust lines") }}
{% interactive-block label="Check trust lines" steps=$frontmatter.steps %}
<button id="check-trust-lines" class="btn btn-primary previous-steps-required">Check trust lines</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending...</div>
{% loading-icon message="Sending..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
## Next Steps

View File

@@ -7,6 +7,7 @@ filters:
- interactive_steps
labels:
- Tokens
steps: ['Generate', 'Connect', 'Send AccountSet', 'Wait', 'Confirm Settings']
---
# Enable No Freeze
@@ -20,7 +21,8 @@ If you [issue tokens](../../concepts/tokens/index.md) in the XRP Ledger, can ena
- You don't need to have [issued a token](issue-a-fungible-token.md) in the XRP Ledger to enable No Freeze, but the main reason you would do so is if you intend to or have already issued such a token.
<!-- Source for this specific tutorial's interactive bits: -->
<script type="application/javascript" src="assets/js/tutorials/enable-no-freeze.js"></script>
<script type="application/javascript" src="/js/interactive-tutorial.js"></script>
<script type="application/javascript" src="/js/tutorials/enable-no-freeze.js"></script>
## Example Code
@@ -30,9 +32,8 @@ Complete sample code for all of the steps of this tutorial is available under th
- See [Code Samples: Freeze](https://github.com/XRPLF/xrpl-dev-portal/tree/master/content/_code-samples/freeze/) in the source repository for this website.
## Steps
{% set n = cycler(* range(1,99)) %}
### {{n.next()}}. Get Credentials
### 1. Get Credentials
To transact on the XRP Ledger, you need an address and secret key, and some XRP. If you use the best practice of having separate ["cold" and "hot" addresses](../../concepts/accounts/account-types.md), you need the **master keys** to the _cold address_, which is the **issuer** of the token. Only the issuer's No Freeze setting has any effect on a token.
@@ -45,7 +46,7 @@ For this tutorial, you can get credentials from the following interface:
When you're building production-ready software, you should use an existing account, and manage your keys using a [secure signing configuration](../../concepts/transactions/secure-signing.md).
### {{n.next()}}. Connect to the Network
### 2. Connect to the Network
You must be connected to the network to submit transactions to it. The following code shows how to connect to a public XRP Ledger Testnet server a supported [client library](../../references/client-libraries.md):
@@ -62,7 +63,7 @@ For this tutorial, click the following button to connect:
{% partial file="/_snippets/interactive-tutorials/connect-step.md" /%}
### {{n.next()}}. Send AccountSet Transaction
### 3. Send AccountSet Transaction
To enable the No Freeze setting, send an [AccountSet transaction][] with a `SetFlag` field containing the [`asfNoFreeze` value (`6`)](../../references/protocol/transactions/types/accountset.md#accountset-flags). To send the transaction, you first _prepare_ it to fill out all the necessary fields, then _sign_ it with your account's secret key, and finally _submit_ it to the network.
@@ -96,24 +97,26 @@ For example:
{% /tabs %}
{{ start_step("Send AccountSet") }}
{% interactive-block label="Send AccountSet" steps=$frontmatter.steps %}
<button id="send-accountset" class="btn btn-primary previous-steps-required" data-wait-step-name="Wait">Send AccountSet</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending...</div>
{% loading-icon message="Sending" /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. Wait for Validation
### 4. Wait for Validation
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. If the XRP Ledger is busy or poor network connectivity delays a transaction from being relayed throughout the network, a transaction may take longer to be confirmed. (For information on how to set an expiration for transactions, see [Reliable Transaction Submission](../../concepts/transactions/reliable-transaction-submission.md).)
{{ start_step("Wait") }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" /%}
{{ end_step() }}
### {{n.next()}}. Confirm Account Settings
### 5. Confirm Account Settings
After the transaction is validated, you can check your account's settings to confirm that the No Freeze flag is enabled. You can do this by calling the [account_info method][] and checking the value of the account's `Flags` field to see if the [`lsfNoFreeze` bit (`0x00200000`)](../../references/protocol/ledger-data/ledger-entry-types/accountroot.md#accountroot-flags) is enabled.
@@ -168,11 +171,15 @@ Response:
{% /tabs %}
{{ start_step("Confirm Settings") }}
{% interactive-block label="Confirm Settings" steps=$frontmatter.steps %}
<button id="confirm-settings" class="btn btn-primary previous-steps-required" data-wait-step-name="Wait">Confirm Settings</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending...</div>
{% loading-icon message="Sending" /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
## See Also

View File

@@ -8,6 +8,7 @@ filters:
labels:
- Tokens
- Security
steps: ['Generate', 'Connect', 'Send AccountSet (Start Freeze)', 'Wait', 'Confirm Settings', 'Send AccountSet (End Freeze)', 'Wait (again)', 'Confirm Settings (After Freeze)']
---
# Enact Global Freeze
@@ -23,7 +24,8 @@ If you [issue tokens](../../concepts/tokens/index.md) in the XRP Ledger, can ena
- You don't need to have [issued a token](issue-a-fungible-token.md) in the XRP Ledger to enact a Global Freeze, but the main reason you would do so is if you have already issued such a token.
<!-- Source for this specific tutorial's interactive bits: -->
<script type="application/javascript" src="assets/js/tutorials/enact-global-freeze.js"></script>
<script type="application/javascript" src="/js/interactive-tutorial.js"></script>
<script type="application/javascript" src="/js/tutorials/enact-global-freeze.js"></script>
## Example Code
@@ -32,10 +34,8 @@ Complete sample code for all of the steps of this tutorial is available under th
- See [Code Samples: Freeze](https://github.com/XRPLF/xrpl-dev-portal/tree/master/content/_code-samples/freeze/) in the source repository for this website.
## Steps
{% set n = cycler(* range(1,99)) %}
### {{n.next()}}. Get Credentials
### 1. Get Credentials
To transact on the XRP Ledger, you need an address and secret key, and some XRP. If you use the best practice of having separate ["cold" and "hot" addresses](../../concepts/accounts/account-types.md), you need the keys to the _cold address_, which is the **issuer** of the token. Only the issuer's Global Freeze setting has any effect on a token.
@@ -48,7 +48,7 @@ For this tutorial, you can get credentials from the following interface:
When you're building production-ready software, you should use an existing account, and manage your keys using a [secure signing configuration](../../concepts/transactions/secure-signing.md).
### {{n.next()}}. Connect to the Network
### 2. Connect to the Network
You must be connected to the network to submit transactions to it. The following code shows how to connect to a public XRP Ledger Testnet server a supported [client library](../../references/client-libraries.md):
@@ -65,7 +65,7 @@ For this tutorial, click the following button to connect:
{% partial file="/_snippets/interactive-tutorials/connect-step.md" /%}
### {{n.next()}}. Send AccountSet Transaction to Start the Freeze
### 3. Send AccountSet Transaction to Start the Freeze
To enable the Global Freeze setting, send an [AccountSet transaction][] with a `SetFlag` field containing the [`asfGlobalFreeze` value (`7`)](../../references/protocol/transactions/types/accountset.md#accountset-flags). To send the transaction, you first _prepare_ it to fill out all the necessary fields, then _sign_ it with your account's secret key, and finally _submit_ it to the network.
@@ -100,23 +100,29 @@ For example:
{% /tabs %}
{{ start_step("Send AccountSet (Start Freeze)") }}
{% interactive-block label="Send AccountSet (Start Freeze)" steps=$frontmatter.steps %}
<button class="btn btn-primary previous-steps-required send-accountset" data-wait-step-name="Wait" data-action="start_freeze">Send AccountSet</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending...</div>
{% loading-icon message="Sending..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. Wait for Validation
### 4. Wait for Validation
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. If the XRP Ledger is busy or poor network connectivity delays a transaction from being relayed throughout the network, a transaction may take longer to be confirmed. (For information on how to set an expiration for transactions, see [Reliable Transaction Submission](../../concepts/transactions/reliable-transaction-submission.md).)
{{ start_step("Wait") }}
{% interactive-block label="Wait" steps=$frontmatter.steps %}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" /%}
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. Confirm Account Settings
### 5. Confirm Account Settings
After the transaction is validated, you can check your issuing account's settings to confirm that the Global Freeze flag is enabled. You can do this by calling the [account_info method][] and checking the value of the account's `Flags` field to see if the [`lsfGlobalFreeze` bit (`0x00400000`)](../../references/protocol/ledger-data/ledger-entry-types/accountroot.md#accountroot-flags) is on.
@@ -171,11 +177,15 @@ Response:
{% /tabs %}
{{ start_step("Confirm Settings") }}
{% interactive-block label="Confirm Settings" steps=$frontmatter.steps %}
<button id="confirm-settings" class="btn btn-primary previous-steps-required">Confirm Settings</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending...</div>
{% loading-icon message="Sending..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### Intermission: While Frozen
@@ -191,7 +201,7 @@ If you use the [No Freeze setting](../../concepts/tokens/fungible-tokens/freezes
Otherwise, you can continue to the next step whenever you're ready.
### {{n.next()}}. Send AccountSet Transaction to End the Freeze
### 6. Send AccountSet Transaction to End the Freeze
To end the Global Freeze, send an [AccountSet transaction][] with a `ClearFlag` field containing the [`asfGlobalFreeze` value (`7`)](../../references/protocol/transactions/types/accountset.md#accountset-flags). As always, you first _prepare_ the transaction, _sign_ it, and finally _submit_ it to the network.
@@ -224,31 +234,37 @@ For example:
{% /tabs %}
{{ start_step("Send AccountSet (End Freeze)") }}
{% interactive-block label="Send AccountSet (End Freeze)" steps=$frontmatter.steps %}
<button class="btn btn-primary previous-steps-required send-accountset" data-wait-step-name="Wait (again)" data-action="end_freeze">Send AccountSet (end the freeze)</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending...</div>
{% loading-icon message="Sending..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. Wait for Validation
### 7. Wait for Validation
As before, wait for the previous transaction to be validated by consensus before continuing.
{{ start_step("Wait (again)") }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" /%}
{{ end_step() }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" variables={label: "Wait (again)"} /%}
### {{n.next()}}. Confirm Account Settings
### 8. Confirm Account Settings
After the transaction is validated, you can confirm the status of the Global Freeze flag in the same way as before: by calling the [account_info method][] and checking the value of the account's `Flags` field to see if the [`lsfGlobalFreeze` bit (`0x00400000`)](../../references/protocol/ledger-data/ledger-entry-types/accountroot.md#accountroot-flags) is **off**.
{{ start_step("Confirm Settings (After Freeze)") }}
{% interactive-block label="Confirm Settings (After Freeze)" steps=$frontmatter.steps %}
<button id="confirm-settings-end" class="btn btn-primary previous-steps-required">Confirm Settings (After Freeze)</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending...</div>
{% loading-icon message="Sending..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
## See Also

View File

@@ -8,6 +8,7 @@ filters:
labels:
- Tokens
- Security
steps: ['Generate', 'Connect', 'Choose Trust Line', 'Send TrustSet to Freeze', 'Wait', 'Check Freeze Status', 'Send TrustSet to End Freeze', 'Wait (again)']
---
# Freeze a Trust Line
@@ -25,7 +26,8 @@ This tutorial shows the steps to [freeze an individual trust line](../../concept
- You **cannot** have enabled the [No Freeze setting](../../concepts/tokens/fungible-tokens/freezes.md#no-freeze), which gives up your ability to freeze individual trust lines.
<!-- Source for this specific tutorial's interactive bits: -->
<script type="application/javascript" src="assets/js/tutorials/freeze-individual-line.js"></script>
<script type="application/javascript" src="/js/interactive-tutorial.js"></script>
<script type="application/javascript" src="/js/tutorials/freeze-individual-line.js"></script>
## Example Code
@@ -35,15 +37,14 @@ Complete sample code for all of the steps of this tutorial is available under th
- See [Code Samples: Freeze](https://github.com/XRPLF/xrpl-dev-portal/tree/master/content/_code-samples/freeze/) in the source repository for this website.
## Steps
{% set n = cycler(* range(1,99)) %}
### {{n.next()}}. Get Credentials
### 1. Get Credentials
To transact on the XRP Ledger, you need an address and secret key, and some XRP. If you use the best practice of having separate ["cold" and "hot" addresses](../../concepts/accounts/account-types.md), you need the keys to the _cold address_, which is the **issuer** of the token.
{% partial file="/_snippets/interactive-tutorials/generate-step.md" /%}
### {{n.next()}}. Connect to the Network
### 2. Connect to the Network
You must be connected to the network to submit transactions to it. The following code shows how to connect to a public XRP Ledger Testnet server a supported [client library](../../references/client-libraries.md):
@@ -66,7 +67,7 @@ For purposes of this tutorial, use the following interface to connect and perfor
{% partial file="/_snippets/interactive-tutorials/connect-step.md" /%}
### {{n.next()}}. Choose Trust Line
### 3. Choose Trust Line
You can only freeze one trust line per transaction, so you need to know which trust line you want. Each of your trust lines is uniquely identified by these 3 things:
@@ -125,16 +126,18 @@ Example Request:
For purposes of this tutorial, a second test address has created a trust line to the test address for the currency "FOO", which you can see in the following example:
{{ start_step("Choose Trust Line")}}
<div class="loader collapse" id="trust-line-setup-loader"><img class="throbber" src="assets/img/xrp-loader-96.png">Waiting for setup to complete...</div>
{% interactive-block label="Choose Trust Line" steps=$frontmatter.steps %}
<div class="loader collapse" id="trust-line-setup-loader"><img class="throbber" src="/img/xrp-loader-96.png">Waiting for setup to complete...</div>
<input type="hidden" id="peer-seed" value="" />
<button id="look-up-trust-lines" class="btn btn-primary" disabled="disabled" title="Wait for setup to complete...">Choose Trust Line</button>
<div class="loader loader-looking collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Looking...</div>
<div class="loader loader-looking collapse"><img class="throbber" src="/img/xrp-loader-96.png">Looking...</div>
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. Send TrustSet Transaction to Freeze the Trust Line
### 4. Send TrustSet Transaction to Freeze the Trust Line
To enable or disable an Individual Freeze on a specific trust line, send a [TrustSet transaction][] with the [`tfSetFreeze` flag enabled](../../references/protocol/transactions/types/trustset.md#trustset-flags). The fields of the transaction should be as follows:
@@ -181,24 +184,26 @@ As always, to send a transaction, you _prepare_ it by filling in all the necessa
{% /tabs %}
{{ start_step("Send TrustSet to Freeze") }}
{% interactive-block label="Send TrustSet to Freeze" steps=$frontmatter.steps %}
<button class="btn btn-primary previous-steps-required send-trustset" data-wait-step-name="Wait" data-action="start_freeze">Send TrustSet (Freeze)</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending...</div>
{% loading-icon message="Sending..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
**Note:** If you want to freeze multiple trust lines in different currencies with the same counterparty, repeat this step for each trust line. It is possible to send several transactions in a single ledger if you use a different [sequence number](../../references/protocol/data-types/basic-data-types.md#account-sequence) for each transaction. <!--{# TODO: link rapid/batch submission guidelines when https://github.com/XRPLF/xrpl-dev-portal/issues/1025 is done #}-->
### {{n.next()}}. Wait for Validation
### 5. Wait for Validation
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. If the XRP Ledger is busy or poor network connectivity delays a transaction from being relayed throughout the network, a transaction may take longer to be confirmed. (For information on how to set an expiration for transactions, see [Reliable Transaction Submission](../../concepts/transactions/reliable-transaction-submission.md).)
{{ start_step("Wait") }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" /%}
{{ end_step() }}
### {{n.next()}}. Check Trust Line Freeze Status
### 6. Check Trust Line Freeze Status
At this point, the trust line from the counterparty should be frozen. You can check the freeze status of any trust line using the [account_lines method][] with the following fields:
@@ -256,14 +261,18 @@ Example Response:
{% /tabs %}
{{ start_step("Check Freeze Status") }}
{% interactive-block label="Check Freeze Status" steps=$frontmatter.steps %}
<button id="confirm-settings" class="btn btn-primary previous-steps-required">Check Trust Line</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Checking...</div>
{% loading-icon message="Checking..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. (Optional) Send TrustSet Transaction to End the Freeze
### 7. (Optional) Send TrustSet Transaction to End the Freeze
If you decide that the trust line no longer needs to be frozen (for example, you investigated and decided that the suspicious activity was benign), you can end the individual freeze in almost the same way that you froze the trust line in the first place. To end an individual freeze, send a [TrustSet transaction][] with the [`tfClearFreeze` flag enabled](../../references/protocol/transactions/types/trustset.md#trustset-flags). The other fields of the transaction should be the same as when you froze the trust line:
@@ -310,20 +319,22 @@ As always, to send a transaction, you _prepare_ it by filling in all the necessa
{% /tabs %}
{{ start_step("Send TrustSet to End Freeze") }}
{% interactive-block label="Send TrustSet to End Freeze" steps=$frontmatter.steps %}
<button class="btn btn-primary previous-steps-required send-trustset" data-wait-step-name="Wait (again)" data-action="end_freeze">Send TrustSet (End Freeze)</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending...</div>
{% loading-icon message="Sending..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. Wait for Validation
### 8. Wait for Validation
As before, wait for the transaction to be validated by consensus.
{{ start_step("Wait (again)") }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" /%}
{{ end_step() }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" variables={label: "Wait (again)"} /%}

View File

@@ -7,6 +7,7 @@ filters:
- interactive_steps
labels:
- Tokens
steps: ['Generate', 'Connect', 'Configure Issuer', 'Wait (Issuer Setup)', 'Configure Hot Address', 'Wait (Hot Address Setup)', 'Make Trust Line', 'Wait (TrustSet)', 'Send Token', 'Wait (Payment)', 'Confirm Balances']
---
# Issue a Fungible Token
@@ -24,7 +25,8 @@ Anyone can issue various types of tokens in the XRP Ledger, ranging from informa
- You can also read along and use the interactive steps in your browser without any setup.
<!-- 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="/js/interactive-tutorial.js"></script>
<script type="application/javascript" src="/js/tutorials/issue-a-token.js"></script>
## Example Code
@@ -33,9 +35,8 @@ Complete sample code for all of the steps of these tutorials is available under
- 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
{% set n = cycler(* range(1,99)) %}
### {{n.next()}}. Get Credentials
### 1. Get Credentials
To transact on the XRP Ledger, you need an address and secret key, and some XRP. You also need one or more recipients who are willing to hold the tokens you issue: unlike in some other blockchains, in the XRP Ledger you cannot force someone to hold a token they do not want.
@@ -44,25 +45,23 @@ The best practice is to use ["cold" and "hot" addresses](../../concepts/accounts
In this tutorial, the hot address receives the tokens you issue from the cold address. You can get the keys for two addresses using the following interface.
<!-- Special version of generate-step.md for getting sender AND receiver credentials -->
{% if use_network is undefined or use_network == "Testnet" %}
{% set use_network = "Testnet" %}
{% set faucet_url = "https://faucet.altnet.rippletest.net/accounts" %}
{% elif use_network == "Devnet" %}
{% set faucet_url = "https://faucet.devnet.rippletest.net/accounts" %}
{# No faucet for Mainnet! #}
{% endif %}
{{ start_step("Generate") }}
<button id="generate-2x-creds-button" class="btn btn-primary" data-fauceturl="{{faucet_url}}">Get {{use_network}} credentials</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Generating Keys...</div>
{% interactive-block label="Generate" steps=$frontmatter.steps %}
<button id="generate-2x-creds-button" class="btn btn-primary" data-fauceturl="https://faucet.altnet.rippletest.net/accounts">Get Testnet credentials</button>
{% loading-icon message="Generating Keys..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
**Caution:** Ripple provides the [Testnet and Devnet](../../concepts/networks-and-servers/parallel-networks.md) for testing purposes only, and sometimes resets the state of these test networks along with all balances. As a precaution, **do not** use the same addresses on Testnet/Devnet and Mainnet.
When you're building production-ready software, you should use an existing account, and manage your keys using a [secure signing configuration](../../concepts/transactions/secure-signing.md).
### {{n.next()}}. Connect to the Network
### 2. Connect to the Network
You must be connected to the network to submit transactions to it. The following code shows how to connect to a public XRP Ledger Testnet server with a supported [client library](../../references/client-libraries.md):
@@ -90,7 +89,7 @@ For this tutorial, click the following button to connect:
{% partial file="/_snippets/interactive-tutorials/connect-step.md" /%}
### {{n.next()}}. Configure Issuer Settings
### 3. Configure Issuer Settings
First, configure the settings for your cold address (which will become the issuer of your token). Most settings can be reconfigured later, with the following exceptions: <!-- STYLE_OVERRIDE: will -->
@@ -139,7 +138,8 @@ The following code sample shows how to send an [AccountSet transaction][] to ena
{% /tabs %}
{{ start_step("Configure Issuer") }}
{% interactive-block label="Configure Issuer" steps=$frontmatter.steps %}
<form>
<div class="form-inline">
<div class="input-group form-check">
@@ -191,11 +191,14 @@ The following code sample shows how to send an [AccountSet transaction][] to ena
</div>
</form>
<button id="config-issuer-button" class="btn btn-primary previous-steps-required" data-wait-step-name="Wait (Issuer Setup)">Configure issuer</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending transaction...</div>
<div class="output-area"></div>
{{ end_step() }}
### {{n.next()}}. Wait for Validation
{% loading-icon message="Sending transaction..." /%}
<div class="output-area"></div>
{% /interactive-block %}
### 4. Wait for Validation
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](../../concepts/transactions/reliable-transaction-submission.md).
@@ -207,12 +210,10 @@ The code samples in this tutorial use helper functions to wait for validation wh
**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)") }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" /%}
{{ end_step() }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" variables={label: "Wait (Issuer Setup)"} /%}
### {{n.next()}}. Configure Hot Address Settings
### 5. Configure Hot Address Settings
The hot address does not strictly require any settings changes from the default, but the following are recommended as best practices:
@@ -242,7 +243,8 @@ The following code sample shows how to send an [AccountSet transaction][] to ena
{% /tabs %}
{{ start_step("Configure Hot Address") }}
{% interactive-block label="Configure Hot Address" steps=$frontmatter.steps %}
<form>
<div class="form-inline">
<div class="input-group form-check">
@@ -285,20 +287,21 @@ The following code sample shows how to send an [AccountSet transaction][] to ena
</div>
</form>
<button id="config-hot-address-button" class="btn btn-primary previous-steps-required" data-wait-step-name="Wait (Hot Address Setup)">Configure hot address</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending transaction...</div>
<div class="output-area"></div>
{{ end_step() }}
### {{n.next()}}. Wait for Validation
{% loading-icon message="Sending transaction..." /%}
<div class="output-area"></div>
{% /interactive-block %}
### 6. Wait for Validation
As before, wait for the previous transaction to be validated by consensus before continuing.
{{ start_step("Wait (Hot Address Setup)") }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" /%}
{{ end_step() }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" variables={label: "Wait (Hot Address Setup)"} /%}
### {{n.next()}}. Create Trust Line from Hot to Cold Address
### 7. Create Trust Line from Hot to Cold Address
Before you can receive tokens, you need to create a [trust line](../../concepts/tokens/fungible-tokens/index.md) to the token issuer. This trust line is specific to the [currency code](../../references/protocol/data-types/currency-formats.md#currency-codes) of the token you want to issue, such as USD or FOO. You can choose any currency code you want; each issuer's tokens are treated as separate in the XRP Ledger protocol. However, users' balances of tokens with the same currency code can [ripple](../../concepts/tokens/fungible-tokens/rippling.md) between different issuers if the users enable rippling settings.
@@ -335,7 +338,8 @@ The following code sample shows how to send a [TrustSet transaction][] from the
{% /tabs %}
{{ start_step("Make Trust Line") }}
{% interactive-block label="Make Trust Line" steps=$frontmatter.steps %}
<form>
<p>Currency code:</p>
<div class="container">
@@ -368,23 +372,24 @@ The following code sample shows how to send a [TrustSet transaction][] from the
</div>
</form>
<button id="create-trust-line-button" class="btn btn-primary previous-steps-required" data-wait-step-name="Wait (TrustSet)">Create Trust Line</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending transaction...</div>
{% loading-icon message="Sending transaction..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
**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](../../concepts/tokens/fungible-tokens/authorized-trust-lines.md#authorizing-trust-lines).
### {{n.next()}}. Wait for Validation
### 8. Wait for Validation
As before, wait for the previous transaction to be validated by consensus before continuing.
{{ start_step("Wait (TrustSet)") }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" /%}
{{ end_step() }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" variables={label: "Wait (TrustSet)"} /%}
### {{n.next()}}. Send Token
### 9. Send Token
Now you can create tokens by sending a [Payment transaction][] from the cold address to the hot address. This transaction should have the following attributes (dot notation indicates nested fields):
@@ -421,7 +426,8 @@ The following code sample shows how to send a [Payment transaction][] to issue 8
{% /tabs %}
{{ start_step("Send Token") }}
{% interactive-block label="Send Token" steps=$frontmatter.steps %}
<form>
<div class="form-inline mt-2">
<div class="input-group">
@@ -445,21 +451,22 @@ The following code sample shows how to send a [Payment transaction][] to issue 8
</div>
</form>
<button id="send-token-button" class="btn btn-primary previous-steps-required" data-wait-step-name="Wait (Payment)">Send Token</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending transaction...</div>
{% loading-icon message="Sending transaction..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. Wait for Validation
### 10. Wait for Validation
As before, wait for the previous transaction to be validated by consensus before continuing.
{{ start_step("Wait (Payment)") }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" /%}
{{ end_step() }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" variables={label: "Wait (Payment)"} /%}
### {{n.next()}}. Confirm Token Balances
### 11. Confirm Token Balances
You can check the balances of your token from the perspective of either the token issuer or the hot address. Tokens issued in the XRP Ledger always have balances that sum to 0: negative from the perspective of the issuer and positive from the perspective of the holder.
@@ -487,11 +494,15 @@ The following code sample shows how to use both methods:
{% /tabs %}
{{ start_step("Confirm Balances") }}
{% interactive-block label="Confirm Balances" steps=$frontmatter.steps %}
<button id="confirm-balances-button" class="btn btn-primary previous-steps-required">Confirm Balances</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Checking...</div>
{% loading-icon message="Checking..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### Next Steps

View File

@@ -7,6 +7,7 @@ filters:
labels:
- Decentralized Exchange
- Tokens
steps: ['Connect', 'Generate', 'Look Up Offers',' Send OfferCreate', 'Wait', 'Check Metadata', 'Check Balances and Offers']
---
# Trade in the Decentralized Exchange
@@ -21,8 +22,9 @@ This tutorial demonstrates how you can buy and sell tokens in the [decentralized
- You can also read along and use the interactive steps in your browser without any setup.
<!-- Source for this specific tutorial's interactive bits: -->
<script type="application/javascript" src="/js/interactive-tutorial.js"></script>
<script src='https://cdn.jsdelivr.net/npm/bignumber.js@9.0.2/bignumber.min.js'></script>
<script type="application/javascript" src="assets/js/tutorials/trade-in-the-dex.js"></script>
<script type="application/javascript" src="/js/tutorials/trade-in-the-dex.js"></script>
## Example Code
@@ -32,7 +34,6 @@ Complete sample code for all of the steps of this tutorial is available under th
## Steps
{% set n = cycler(* range(1,99)) %}
This tutorial demonstrates how to buy a fungible token in the decentralized exchange by selling XRP. (Other types of trades are possible, but selling a token, for example, requires you to have it first.) The example token used in this tutorial is as follows:
@@ -41,7 +42,7 @@ This tutorial demonstrates how to buy a fungible token in the decentralized exch
| TST | `rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd` | A test token pegged to XRP at a rate of approximately 10 XRP per 1 TST. The issuer has existing Offers on the XRP Ledger Testnet to buy and sell these tokens. |
### {{n.next()}}. Connect to Network
### 1. Connect to Network
You must be connected to the network to submit transactions to it. Additionally, some languages (including JavaScript) require a high-precision number library for performing calculations on currency amounts you may find in the ledger. The following code shows how to connect to a public XRP Ledger Testnet server a supported [client library](../../references/client-libraries.md) with the appropriate dependencies.
@@ -63,7 +64,7 @@ For this tutorial, click the following button to connect:
{% partial file="/_snippets/interactive-tutorials/connect-step.md" /%}
### {{n.next()}}. Get Credentials
### 2. Get Credentials
To transact on the XRP Ledger, you need an address, a secret key, and some XRP. For development purposes, you can get these on the [{{use_network}}](../../concepts/networks-and-servers/parallel-networks.md) using the following interface:
@@ -83,7 +84,7 @@ When you're building production-ready software, you should use an existing accou
{% /tabs %}
### {{n.next()}}. Look Up Offers
### 7. Look Up Offers
Before you buy or sell a token, you usually want to look up what others are buying and selling for, to get a sense of how others value it. In the XRP Ledger, you can look up existing offers for any currency pair using the [book_offers method][].
@@ -107,7 +108,8 @@ The following code shows how to look up existing Offers and compare them to a pr
The following block demonstrates these calculations in action:
{{ start_step("Look Up Offers") }}
{% interactive-block label="Look Up Offers" steps=$frontmatter.steps %}
<form>
<h5>TakerPays</h5>
<div class="form-group row">
@@ -146,11 +148,14 @@ The following block demonstrates these calculations in action:
</div>
</form>
<button id="look-up-offers" class="btn btn-primary previous-steps-required">Look Up Offers</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Querying...</div>
<div class="output-area"></div>
{{ end_step() }}
### {{n.next()}}. Send OfferCreate Transaction
{% loading-icon message="Querying..." /%}
<div class="output-area"></div>
{% /interactive-block %}
### 3. Send OfferCreate Transaction
To actually make a trade, send an [OfferCreate transaction][]. In this case, you want to buy TST using XRP, so you should set the parameters as follows:
@@ -175,21 +180,24 @@ The following code shows how to prepare, sign, and submit the transaction:
You can use this interface to send the transaction specified by the amounts in the previous step:
{{ start_step("Send OfferCreate") }}
<button id="send-offercreate" class="btn btn-primary previous-steps-required" data-wait-step-name="Wait">Send OfferCreate</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending...</div>
<div class="output-area"></div>
{{ end_step() }}
{% interactive-block label="Send OfferCreate" steps=$frontmatter.steps %}
### {{n.next()}}. Wait for Validation
<button id="send-offercreate" class="btn btn-primary previous-steps-required" data-wait-step-name="Wait">Send OfferCreate</button>
{% loading-icon message="Sending..." /%}
<div class="output-area"></div>
{% /interactive-block %}
### 4. Wait for Validation
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. If the XRP Ledger is busy or poor network connectivity delays a transaction from being relayed throughout the network, a transaction may take longer to be confirmed. (For information on how to set an expiration for transactions, see [Reliable Transaction Submission](../../concepts/transactions/reliable-transaction-submission.md).)
{{ start_step("Wait") }}
{% partial file="/_snippets/interactive-tutorials/wait-step.md" /%}
{{ end_step() }}
### {{n.next()}}. Check Metadata
### 5. Check Metadata
You can use the validated transaction's [metadata](../../references/protocol/transactions/metadata.md) to determine exactly what it did. (Don't use metadata from tentative transaction results, because it may be different from the [final result](../../concepts/transactions/finality-of-results/index.md), especially when using the decentralized exchange.) In case of an OfferCreate transaction, likely results include:
@@ -213,14 +221,18 @@ The following code demonstrates how to check the metadata of the transaction:
You can use this interface to test it out:
{{ start_step("Check Metadata") }}
{% interactive-block label="Check Metadata" steps=$frontmatter.steps %}
<button id="check-metadata" class="btn btn-primary previous-steps-required">Check Metadata</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Checking...</div>
{% loading-icon message="Checking..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
### {{n.next()}}. Check Balances and Offers
### 6. Check Balances and Offers
This is also a good time to look up the balances and outstanding Offers owned by your account as of the latest validated ledger. This shows any changes caused by your transaction as well as any others that executed in the same ledger version.
@@ -240,10 +252,13 @@ The following code demonstrates how to look up balances using the [account_lines
You can use this interface to test it out:
{{ start_step("Check Balances and Offers") }}
{% interactive-block label="Check Balances and Offers" steps=$frontmatter.steps %}
<button id="check-balances-and-offers" class="btn btn-primary previous-steps-required">Check Balances and Offers</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Checking...</div>
{% loading-icon message="Checking..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
{% raw-partial file="/_snippets/common-links.md" /%}

View File

@@ -1,6 +1,6 @@
# Interactive Tutorials
The site has code to aid development of interactive tutorials that connect to the live XRP Ledger (Mainnet, Testnet, or Devnet). This document explains how to use that code to create an interactive tutorial.
The site has code to aid development of interactive tutorials that connect to the live XRP Ledger (Mainnet, Testnet, or Devnet). This document explains how to use that code to create an interactive tutorial. **Note: This doc has been mostly updated to describe how the existing interactive tutorials work under Redocly, but the next phase of interactive tutorials will be different.**
## Limitations
@@ -51,21 +51,19 @@ For privacy reasons, the memo does not and MUST NOT include personally identifyi
An interactive tutorial is a page, so you add it to the `dactyl-config.yml` page like any other page. However, you need to add the following pieces to make the interactive stuff work:
1. Set page properties, either in the config file or the page's frontmatter. The `interactive_steps` Dactyl filter gives you access to the functions you use to demarcate the interactive bits in your markdown file. Most of the time, you'll also want to include xrpl.js and its dependencies as well; you can have the templates handle that for you by setting the field `embed_xrpl_js: true`. For example:
1. Set page properties, either in the config file or the page's frontmatter. You need to include an array of step names as the `steps` parameter in the frontmatter
html: use-tickets.html
parent: manage-account-settings.html
blurb: Use Tickets to send a transaction outside of normal Sequence order.
embed_xrpl_js: true
filters:
- interactive_steps
steps: ['Generate', 'Connect', 'Configure Issuer', 'Wait (Issuer Setup)', 'Configure Hot Address', 'Wait (Hot Address Setup)', 'Make Trust Line', 'Wait (TrustSet)', 'Send Token', 'Wait (Payment)', 'Confirm Balances']
Including the `interactive_steps` filter automatically causes the templates to load the [interactive-tutorial.js](../assets/js/interactive-tutorial.js) file on that page. This JavaScript file implements much of the functionality for interactive tutorials, and provides helper functions for a lot of other common things you might want to do.
The `steps` list must exactly match the list of step labels in the tutorial. Start with some steps you know you'll have like 'Generate' and keep the frontmatter updated as you add more.
The `interactive_steps` filter is no longer needed under Redocly.
2. For the tutorial, you're going to create (at least) two JavaScript files:
- **Example Code:** The example code that you'll display on the page. You want to make sure it actually runs correctly as shown to the user, after all. You should start by making this one. You should save this file as `content/_code-samples/{YOUR TUTORIAL}/{YOUR TUTORIAL}.js`.
- **Interactive Code:** A modified version of the same code that will actually run, and also interact with the user interface in the browser itself. You should adapt this one from the other version after you get the other one working. While working on this version, remember to backport any changes that are also applicable to the example code version. You should save this file as `assets/js/tutorials/{YOUR_TUTORIAL}.js`.
- **Interactive Code:** A modified version of the same code that will actually run, and also interact with the user interface in the browser itself. You should adapt this one from the other version after you get the other one working. While working on this version, remember to backport any changes that are also applicable to the example code version. You should save this file as `static/js/tutorials/{YOUR_TUTORIAL}.js`.
3. Start working on the Example Code file first.
@@ -75,15 +73,15 @@ An interactive tutorial is a page, so you add it to the `dactyl-config.yml` page
Use excerpts of the example code to demonstrate each step. You can gloss over certain parts of the sample code if they're tangential to the goal of the tutorial, like the nitty-gritty of getting credentials from the Testnet faucet.
This is where `include_code` comes in really handy. You can pull in just an excerpt of a code sample based on starting and ending bits. For example:
This is where `{% code-snippet %}` comes in really handy. You can pull in just an excerpt of a code sample based on starting and following bits (it goes up to but does not include the section you specify with `before`). For example:
{{ include_code("_code-samples/send-xrp/send-xrp.js",
start_with="// Connect", end_before="// Get credentials",
language="js") }}
```markdoc
{% tab label="JavaScript" %}
{% code-snippet file="/_code-samples/trade-in-the-decentralized-exchange/js/trade-in-the-dex.js" from="// Get credentials" before="// Define the proposed trade" language="js" /%}
{% /tab %}
```
Both `start_with` and `end_before` are optional; if you omit them, it'll all the way from the start of the file to the end. Alternatively, you can include specific lines of the file as described in the [Dactyl Include Code page](https://dactyl.link/extending-include_code.html). If you combine `start_with` and `lines` the line numbers will be renumbered based on the specified starting point.
The samples have any extra whitespace trimmed off the very beginning and end of the excerpt, but not from any lines in the middle. The `language` tag is optional but recommended so that syntax highlighting works properly.
Both `from` and `before` are optional; if you omit them, it'll all the way from the start of the file to the end. Tabs are also optional, but recommended if you have code in multiple languages.
5. Figure out what an interactive version of the tutorial looks like and where the user might interact with key steps.
@@ -96,17 +94,14 @@ An interactive tutorial is a page, so you add it to the `dactyl-config.yml` page
## How to Use the Interactive Bits
To run your custom interactive code on your tutorial page, add a script tag to the Markdown content of the page you're writing. Conventionally, this can be under the "Prerequisites" heading of the tutorial, but it's mostly invisible to the user so it can go almost anywhere. For example:
To run your custom interactive code on your tutorial page, add scripts tag to the Markdown content of the page you're writing. Conventionally, this can be under the "Prerequisites" heading of the tutorial, but it's mostly invisible to the user so it can go almost anywhere.
The two files you should include are the shared interactive tutorials code, and the specific code for your tutorial. For example:
```html
<!-- Source for this specific tutorial's interactive bits: -->
<script type="application/javascript" src="assets/js/tutorials/use-tickets.js"></script>
```
When you want to test changes to this code, you need a Dactyl-built version of the page. You can build just a single page using the following syntax, which also copies your updated version of the `assets/` JS to the out folder:
```sh
dactyl_build --only your-page.html
<!-- Source for this tutorial's interactive bits: -->
<script type="application/javascript" src="/js/interactive-tutorial.js"></script>
<script type="application/javascript" src="/js/tutorials/use-tickets.js"></script>
```
### Starting Snippets
@@ -115,30 +110,33 @@ There are also snippets that handle some of the most generic and repeated parts
For many tutorials, the first two steps are going to be "Connect to the Testnet" and "Get Credentials". The snippets for these are:
```jinja2
{% include '_snippets/interactive-tutorials/generate-step.md' %}
{% include '_snippets/interactive-tutorials/connect-step.md' %}
```markdoc
{% partial file="/_snippets/interactive-tutorials/generate-step.md" /%}
```
If you need to connect to Devnet or Mainnet, set the `use_network` Jinja variable _before_ including either of these snippets, for example in the "Prerequisites section". The code looks like this (case-sensitive!):
```jinja2
{% set use_network = "Devnet" %}
```
{% partial file="/_snippets/interactive-tutorials/connect-step.md" /%}
```
### Interactive Blocks
In your Markdown file, you'll use Jinja syntax to mark the start and end of the interactive code sections. By convention, it looks like this, though all the HTML is optional:
In your Markdown file, you'll use a Markdoc component to encapsulate the interactive code sections. By convention, it looks like this, though all the HTML is optional:
```markdoc
{% interactive-block label="Step Name" steps=$frontmatter.steps %}
```jinja2
{{ start_step("Step Name") }}
<button id="your-button-id" class="btn btn-primary previous-steps-required">Click this button</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png"> Doing stuff...</div>
{% loading-icon message=" Doing stuff..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
```
**Warning:** It won't work right if you don't leave empty lines between the HTML tags and the Markdoc tags (`{% %}`).
Things you'll want to customize for each section:
- Each step name (`Step Name` in this example) must be unique within the page. It's used in the interactive tutorial breadcrumbs, so it's best if it's short (one or two words). The names `Connect` and `Generate` are taken by their respective snippets.
@@ -154,24 +152,28 @@ Things you'll want to customize for each section:
If you have a step in your tutorial where you wait for a transaction to get validated, the "Wait" snippet is there for you. The "Wait" snippet should be used like this:
```jinja2
{{ start_step("Wait") }}
{% include '_snippets/interactive-tutorials/wait-step.md' %}
{{ end_step() }}
```markdoc
{% partial file="/_snippets/interactive-tutorials/wait-step.md" /%}
```
If you have multiple "Wait" steps, you need to give each one a unique name, as with all steps.
If you have multiple "Wait" steps, you need to give each one a unique name. To do that:
```markdoc
{% partial file="/_snippets/interactive-tutorials/wait-step.md" variables={label: "Wait (again)"} %}
```
### Step Code
The custom JavaScript code for your interactive tutorial should be wrapped in a function that runs it when the whole page is loaded, like this:
```js
$(document).ready(() => {
window.onRouteChange(() => {
// Your code here
})
```
**Warning:** Don't use `$(document).ready(() => {...})`. That callback doesn't work properly under Redocly/React.
Inside that block, the code for each individual block tends to follow a pattern: you make event handlers for the ways users should interact with the buttons and things in each step. Within the handlers, you can use the event to identify the block so that most of the code is very familiar. The following example is pulled from the "Use Tickets" interactive tutorial, with extra comments added to clarify the various pieces.
```js
@@ -252,12 +254,16 @@ $("#check-tickets").click( async function(event) {
One common pattern is that a step is sending a transaction from the account whose credentials you generated in the "Generate" step. There's a helper function for that. But first, you have to set up the interactive block in your Markdown file. Here's an example:
```jinja2
{{ start_step("Send AccountSet") }}
```markdoc
{% interactive-block label="Send AccountSet" steps=$frontmatter.steps %}
<button id="send-accountset" class="btn btn-primary previous-steps-required" data-wait-step-name="Wait">Send AccountSet</button>
<div class="loader collapse"><img class="throbber" src="assets/img/xrp-loader-96.png">Sending...</div>
{% loading-icon message="Sending..." /%}
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
```
Most parts—the start and end, loader, and output area—are exactly the same. But notice that the button has a new attribute: `data-wait-step-name="Wait"`. This basically is storing some information for the JavaScript code to use, and it tells it where to output the results of the transaction, in the form of a step using the "Wait Step" snippet, as described above. The value of the attribute is the exact name of the step, which (remember) has to be unique for each one. So if your tutorial involves sending multiple transactions, the first one might have its outcome displayed in a "Wait" step, and the other one might be in the "Wait Again" step, and so on. Usually the relevant wait step is the one immediately after the current step.
@@ -300,11 +306,13 @@ The `generic_full_send(event, transaction)` function handles the rest, including
For some tutorials, you might break up the steps of preparing and signing a transaction from the step where you submit it. In those cases, you can use a generic submit button handler provided by the interactive tutorials code. The block in the Markdown looks like this:
```jinja2
{{ start_step("Submit") }}
```markdoc
{% interactive-block label="Submit" steps=$frontmatter.steps %}
<button id="ticketcreate-submit" class="btn btn-primary previous-steps-required" data-tx-blob-from="#tx_blob" data-wait-step-name="Wait">Submit</button>
<div class="output-area"></div>
{{ end_step() }}
{% /interactive-block %}
```
There are _two_ data attributes that are important here:
@@ -343,7 +351,7 @@ There's also some translation stuff, but it's not ready to be used outside of th
## Examples
- **Send XRP** - The original interactive tutorial. (Much improved since its inception.) Uses the `include_code` to pull in the Example Code from an HTML file that also work as a stand-alone.
- **Send XRP** - The original interactive tutorial. (Much improved since its inception.) Uses `{% code-snippet %}` to pull in the Example Code from an HTML file that also work as a stand-alone.
- [Markdown](../content/tutorials/use-simple-xrp-payments/send-xrp.md)
- [Example Code](../content/_code-samples/send-xrp/)
- [Interactive Code](../assets/js/tutorials/send-xrp.js)