mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2026-06-07 10:46:45 +00:00
Compare commits
20 Commits
selenium_l
...
add-public
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a28980ba69 | ||
|
|
7efd34ec28 | ||
|
|
66b53112ca | ||
|
|
1f13b68a34 | ||
|
|
3de10d242f | ||
|
|
f298b5a38b | ||
|
|
6c27a27ab2 | ||
|
|
22b015df0c | ||
|
|
356b91297a | ||
|
|
d7456276b9 | ||
|
|
22243abc7c | ||
|
|
a301253740 | ||
|
|
6a4b564fbc | ||
|
|
9f76d9efde | ||
|
|
994286cfb2 | ||
|
|
d66fa36f56 | ||
|
|
6c0fa9bf2d | ||
|
|
79419d0b49 | ||
|
|
0e510b349d | ||
|
|
087030b39a |
@@ -1,274 +0,0 @@
|
||||
---
|
||||
html: use-tickets.html
|
||||
parent: manage-account-settings.html
|
||||
seo:
|
||||
description: チケットは、通常のシーケンス順序以外でトランザクションを送信するために使用します。
|
||||
embed_xrpl_js: true
|
||||
filters:
|
||||
- interactive_steps
|
||||
labels:
|
||||
- アカウント
|
||||
steps: ['Generate', 'Connect', 'Check Sequence', 'Prepare & Sign', 'Submit', 'Wait', 'Intermission', 'Check Tickets', 'Prepare Ticketed Tx', 'Submit Ticketed Tx', 'Wait Again']
|
||||
---
|
||||
# チケットの使用
|
||||
|
||||
[チケット](../../../references/protocol/ledger-data/ledger-entry-types/ticket.md)は、通常の順序ではないトランザクションを送信する方法を提供します。このチュートリアルでは、チケットを作成し、それを使って別のトランザクションを送信する手順を説明します。
|
||||
|
||||
## 前提条件
|
||||
|
||||
<!-- 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を使ってみよう](/docs/tutorials/get-started/get-started-javascript.md)をご覧ください。
|
||||
|
||||
JavaScriptはWebブラウザ上で動作するため、セットアップなしで読み進められ、インタラクティブな手順を利用することができます。
|
||||
|
||||
|
||||
|
||||
## 手順
|
||||
|
||||
このチュートリアルはいくつかの段階に分かれています。
|
||||
|
||||
- (Steps 1-2) **準備:** XRP Ledgerのアドレスとシークレットが必要です。本番環境では、同じアドレスとシークレットを一貫して使用することができます。このチュートリアルでは、必要に応じて新しいテスト認証情報を生成することができます。また、ネットワークに接続されている必要があります。
|
||||
- (Steps 3-6) **チケットの作成:** トランザクションを送信して、いくつかのチケットを確保します。
|
||||
- (任意) **休憩:** チケットを作成した後、以下のステップの前、中、後にいつでも様々な他のトランザクションを送信することができます。
|
||||
- (Steps 7-10) **チケットの使用:** 設定されているチケットのうち1枚を使ってトランザクションを送信します。使用するチケットが1枚でも残っていれば、前の部分を飛ばしてこの手順を繰り返すことができます。
|
||||
|
||||
### 1. クレデンシャルの入手
|
||||
|
||||
XRP Ledgerでトランザクションを送信するには、アドレスと秘密鍵、そしてXRPが必要です。開発用には、[Testnet](../../../concepts/networks-and-servers/parallel-networks.md)で以下のようなインターフェースを使ってこれらを入手することができます。
|
||||
|
||||
{% partial file="/@l10n/ja/docs/_snippets/interactive-tutorials/generate-step.md" /%}
|
||||
|
||||
[本番環境のソフトウェアを作成する場合](/docs/tutorials)には、既存のアカウントを使用し、[安全な署名](../../../concepts/transactions/secure-signing.md)を使用して鍵を管理する必要があります。
|
||||
|
||||
|
||||
### 2. ネットワークへの接続
|
||||
|
||||
トランザクションをネットワークに送信するには、ネットワークに接続している必要があります。チケットは今のところDevnetでしか利用できないので、Devnetサーバに接続する必要があります。例えば、以下のようになります。
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="JavaScript" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/js/use-tickets.js" from="// Connect to" before="// Get credentials" language="js" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
{% admonition type="info" name="注記" %}このチュートリアルのコードサンプルでは、JavaScriptの[`async`/`await`パターン](https://javascript.info/async-await)を使用しています。`await`は`async`関数の中で使用する必要があるため、残りのコードサンプルはここから始まる`main()`関数の中で続けるように書かれています。なお、`async`/`await`の代わりにPromiseのメソッド`.then()`や`.catch()`を使うこともできます。{% /admonition %}
|
||||
|
||||
このチュートリアルでは、以下のボタンをクリックして接続します。
|
||||
|
||||
{% partial file="/@l10n/ja/docs/_snippets/interactive-tutorials/connect-step.md" /%}
|
||||
|
||||
|
||||
### 3. シーケンス番号の確認
|
||||
|
||||
チケットを作成する前に、自分のアカウントの[シーケンス番号][]を確認しておきましょう。次のステップのために現在のシーケンス番号が必要であり、設定されるチケットのシーケンス番号はこの番号から始まります。
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="JavaScript" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/js/use-tickets.js" from="// Check Sequence" before="// Prepare and Sign TicketCreate" language="js" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
{% interactive-block label="Check Sequence" steps=$frontmatter.steps %}
|
||||
|
||||
<button id="check-sequence" class="btn btn-primary previous-steps-required">Check Sequence Number</button>
|
||||
|
||||
{% loading-icon message="Querying..." /%}
|
||||
|
||||
<div class="output-area"></div>
|
||||
|
||||
{% /interactive-block %}
|
||||
|
||||
|
||||
|
||||
### 4. TicketCreateの準備と署名
|
||||
|
||||
前のステップで決定したシーケンス番号を使用して、[TicketCreateトランザクション][]を構築します。`TicketCount`フィールドを使って、作成するチケットの枚数を指定します。例えば、10枚のチケットを作成するトランザクションを準備するには、次のようにします。
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="JavaScript" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/js/use-tickets.js" from="// Prepare and Sign TicketCreate" before="// Submit TicketCreate" language="js" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
トランザクションのハッシュと`LastLedgerSequence`の値を記録しておけば、[後で検証されたかどうかを確認](../../../concepts/transactions/reliable-transaction-submission.md)することができます。
|
||||
|
||||
|
||||
{% 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>
|
||||
|
||||
{% /interactive-block %}
|
||||
|
||||
|
||||
|
||||
### 5. TicketCreateの提出
|
||||
|
||||
前のステップで作成した署名付きトランザクションBlobを送信します。例えば、以下のようになります。
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="JavaScript" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/js/use-tickets.js" from="// Submit TicketCreate" before="// Wait for Validation" language="js" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
{% 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>
|
||||
|
||||
{% loading-icon message="Sending..." /%}
|
||||
|
||||
<div class="output-area"></div>
|
||||
|
||||
{% /interactive-block %}
|
||||
|
||||
|
||||
### 6. 検証の待機
|
||||
|
||||
ほとんどのトランザクションは、送信された後に次の台帳のバージョンに受け入れられます。つまり、トランザクションの結果が確定するまでに4~7秒かかることがあります。XRP Ledgerが混雑している場合や、ネットワークの接続性が悪いためにトランザクションがネットワーク全体に中継されない場合は、トランザクションが確定するまでに時間がかかることがあります。(トランザクションの有効期限を設定する方法については、[信頼できるトランザクションの送信](../../../concepts/transactions/reliable-transaction-submission.md)をご覧ください)。
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="JavaScript" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/js/use-tickets.js" from="// Wait for Validation" before="// Check Available" language="js" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
{% partial file="/@l10n/ja/docs/_snippets/interactive-tutorials/wait-step.md" /%}
|
||||
|
||||
|
||||
### (任意) 休憩
|
||||
|
||||
チケットの強みは、チケットを使ったトランザクションの準備をしている間も、アカウントの業務を通常通り行うことができる点にあります。チケットを使用してトランザクションを送信する場合、別のチケットを使用しているものも含め、他のトランザクションの送信と並行して行うことができ、いつでもチケット付きトランザクションを送信することができます。唯一の制約は、1つのチケットは1回しか使用できないということです。
|
||||
|
||||
{% admonition type="success" name="ヒント" %}以下のステップの間または途中で、ここに戻ってきてシーケンス取引を送信することができますが、その際、チケット取引の成功を妨げることはありません。{% /admonition %}
|
||||
|
||||
{% 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>
|
||||
|
||||
{% /interactive-block %}
|
||||
|
||||
|
||||
|
||||
### 7. 有効なチケットの確認
|
||||
|
||||
チケット付きのトランザクションを送信したい場合、どのチケットシーケンス番号を使用するかを知る必要があります。アカウントを注意深く管理していれば、どのチケットを持っているかはすでにわかっていると思いますが、よくわからない場合は、[account_objectsメソッド][]を使って、利用可能なチケットを調べることができます。例えば、以下のようになります。
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="JavaScript" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/js/use-tickets.js" from="// Check Available Tickets" before="// Prepare and Sign Ticketed" language="js" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
|
||||
{% 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>
|
||||
|
||||
{% /interactive-block %}
|
||||
|
||||
{% admonition type="success" name="ヒント" %}チケットが残っている限り、ここから最後まで同じ手順を繰り返すことができます。{% /admonition %}
|
||||
|
||||
### 8. チケット付きトランザクションの準備
|
||||
|
||||
チケットが利用できるようになったので、それを使用するトランザクションを準備します。
|
||||
|
||||
ここでは、好きな[トランザクションのタイプ](../../../references/protocol/transactions/types/index.md)を使用することができます。次の例では、何も行わない[AccountSetトランザクション][]を使用していますが、これはレジャーに他の設定を必要としないからです。`Sequence`フィールドを`0`に設定して、利用可能なチケットの1つのチケットシーケンス番号を持つ`TicketSequence`フィールドを含めます。
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="JavaScript" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/js/use-tickets.js" from="// Prepare and Sign Ticketed" before="// Submit Ticketed Transaction" language="js" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
{% admonition type="success" name="ヒント" %}
|
||||
TicketCreateトランザクションをすぐに送信する予定がない場合は、トランザクションが期限切れにならないように、`LastLedgerSequence`を設定しないようにする必要があります。これを行う方法はライブラリによって異なります。
|
||||
|
||||
- **xrpl.js:** トランザクションの自動入力の際に、`"LastLedgerSequence": null`を指定する。
|
||||
- **`rippled`:** 用意された指示から`LastLedgerSequence`を省略します。サーバはデフォルトでは値を提供しません。
|
||||
{% /admonition %}
|
||||
|
||||
{% 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>
|
||||
|
||||
{% /interactive-block %}
|
||||
|
||||
|
||||
### 9. チケット付きトランザクションの送信
|
||||
|
||||
前のステップで作成した署名付きトランザクションBlobを送信します。例えば、以下のようになります。
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="JavaScript" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/js/use-tickets.js" from="// Submit Ticketed Transaction" before="// Wait for Validation (again)" language="js" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
{% 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>
|
||||
|
||||
{% /interactive-block %}
|
||||
|
||||
|
||||
### 10. 検証の待機
|
||||
|
||||
チケット付きトランザクションは、シーケンス付きトランザクションと同じようにコンセンサスプロセスを経ます。
|
||||
|
||||
{% partial file="/@l10n/ja/docs/_snippets/interactive-tutorials/wait-step.md" variables={label: "Wait Again"} /%}
|
||||
|
||||
## マルチシグで使用する
|
||||
|
||||
チケットの主な使用例としては、複数の[マルチシグ](../../../concepts/accounts/multi-signing.md)を並行して集めることができます。チケットを使用することで、複数署名されたトランザクションが完全に署名されて準備が整った時点で、どれが先に準備されるかを気にすることなく送信することができます。
|
||||
|
||||
このシナリオでは、[step8,「チケット付きトランザクションの準備」](#8-チケット付きトランザクションの準備)が若干異なります。準備と署名を一度に行うのではなく、[任意のマルチシグトランザクションの送信](../key-management/send-a-multi-signed-transaction.md)の手順に従うことになります。まずトランザクションを準備し、次に信頼できる署名者の間でトランザクションを循環させて署名を集め、最後に署名を組み合わせて最終的なマルチシグトランザクションを作成します。
|
||||
|
||||
複数の異なるトランザクションを処理する場合、それぞれが異なるチケットを使用する限り、この作業を並行して行うことができます。
|
||||
|
||||
|
||||
## 関連項目
|
||||
|
||||
- **Concepts:**
|
||||
- [チケット](../../../concepts/accounts/tickets.md)
|
||||
- [マルチシグ](../../../concepts/accounts/multi-signing.md)
|
||||
- **Tutorials:**
|
||||
- [マルチシグの設定](../key-management/set-up-multi-signing.md)
|
||||
- [信頼出来るトランザクションの送信](../../../concepts/transactions/reliable-transaction-submission.md)
|
||||
- **References:**
|
||||
- [account_objectsメソッド][]
|
||||
- [sign_forメソッド][]
|
||||
- [submit_multisignedメソッド][]
|
||||
- [TicketCreateトランザクション][]
|
||||
- [トランザクションの共通フィールド](../../../references/protocol/transactions/common-fields.md)
|
||||
|
||||
{% raw-partial file="/@l10n/ja/docs/_snippets/common-links.md" /%}
|
||||
@@ -1,3 +0,0 @@
|
||||
CLIENT="wss://s.altnet.rippletest.net:51233/"
|
||||
EXPLORER_NETWORK="testnet"
|
||||
SEED="s████████████████████████████"
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"trailingComma": "es5",
|
||||
"printWidth": 150,
|
||||
"tabWidth": 4,
|
||||
"singleQuote": true,
|
||||
"semi": true
|
||||
}
|
||||
3
_code-samples/build-a-browser-wallet/js/example.env
Normal file
3
_code-samples/build-a-browser-wallet/js/example.env
Normal file
@@ -0,0 +1,3 @@
|
||||
VITE_CLIENT="wss://s.altnet.rippletest.net:51233/"
|
||||
VITE_EXPLORER_NETWORK="testnet"
|
||||
VITE_SEED="s████████████████████████████"
|
||||
@@ -112,7 +112,7 @@ body {
|
||||
|
||||
button {
|
||||
padding: 5px 12px;
|
||||
background: inherit;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
border: 1px solid white;
|
||||
border-radius: 10px;
|
||||
@@ -145,4 +145,4 @@ button:hover {
|
||||
.tx_history_data th {
|
||||
border-bottom: 1px solid white;
|
||||
padding: 0 0 5px 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import getWalletDetails from './src/helpers/get-wallet-details.js';
|
||||
// Optional: Render the XRPL logo
|
||||
addXrplLogo();
|
||||
|
||||
const client = new Client(process.env.CLIENT); // Get the client from the environment variables
|
||||
const client = new Client(import.meta.env.VITE_CLIENT); // Get the client from the environment variables
|
||||
|
||||
// Get the elements from the DOM
|
||||
const sendXrpButton = document.querySelector('#send_xrp_button');
|
||||
@@ -51,7 +51,7 @@ txHistoryButton.addEventListener('click', () => {
|
||||
|
||||
// Redirect on View More link click
|
||||
walletElement.querySelector('#view_more_button').addEventListener('click', () => {
|
||||
window.open(`https://${process.env.EXPLORER_NETWORK}.xrpl.org/accounts/${address}`, '_blank');
|
||||
window.open(`https://${import.meta.env.VITE_EXPLORER_NETWORK}.xrpl.org/accounts/${address}`, '_blank');
|
||||
});
|
||||
|
||||
walletLoadingDiv.style.display = 'none';
|
||||
|
||||
@@ -1,19 +1,13 @@
|
||||
{
|
||||
"name": "simple-xrpl-wallet",
|
||||
"name": "browser-xrpl-wallet",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite"
|
||||
},
|
||||
"devDependencies": {
|
||||
"crypto-browserify": "^3.12.0",
|
||||
"events": "^3.3.0",
|
||||
"https-browserify": "^1.0.0",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"stream-http": "^3.2.0",
|
||||
"vite": "^4.5.14"
|
||||
"vite": "^8.0.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"dotenv": "^16.0.3",
|
||||
"xrpl": "^4.0.0"
|
||||
"xrpl": "^4.6.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Wallet, classicAddressToXAddress } from 'xrpl';
|
||||
|
||||
export default async function getWalletDetails({ client }) {
|
||||
const wallet = Wallet.fromSeed(process.env.SEED);
|
||||
const wallet = Wallet.fromSeed(import.meta.env.VITE_SEED);
|
||||
|
||||
// Get the wallet details
|
||||
const {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Wallet } from 'xrpl';
|
||||
export default async function submitTransaction({ client, tx }) {
|
||||
try {
|
||||
// Create a wallet using the seed
|
||||
const wallet = Wallet.fromSeed(process.env.SEED);
|
||||
const wallet = Wallet.fromSeed(import.meta.env.VITE_SEED);
|
||||
tx.Account = wallet.address;
|
||||
|
||||
// Sign and submit the transaction
|
||||
|
||||
@@ -8,14 +8,14 @@ import submitTransaction from '../helpers/submit-transaction';
|
||||
renderXrplLogo();
|
||||
|
||||
// Get the client from the environment variables
|
||||
const client = new Client(process.env.CLIENT);
|
||||
const client = new Client(import.meta.env.VITE_CLIENT);
|
||||
|
||||
// Self-invoking function to connect to the client
|
||||
(async () => {
|
||||
try {
|
||||
await client.connect();
|
||||
|
||||
const wallet = Wallet.fromSeed(process.env.SEED);
|
||||
const wallet = Wallet.fromSeed(import.meta.env.VITE_SEED);
|
||||
|
||||
// Subscribe to account transaction stream
|
||||
await client.request({
|
||||
|
||||
@@ -78,8 +78,8 @@ async function fetchTxHistory() {
|
||||
try {
|
||||
loadMore.textContent = 'Loading...';
|
||||
loadMore.disabled = true;
|
||||
const wallet = Wallet.fromSeed(process.env.SEED);
|
||||
const client = new Client(process.env.CLIENT);
|
||||
const wallet = Wallet.fromSeed(import.meta.env.VITE_SEED);
|
||||
const client = new Client(import.meta.env.VITE_CLIENT);
|
||||
|
||||
// Wait for the client to connect
|
||||
await client.connect();
|
||||
@@ -137,7 +137,7 @@ async function fetchTxHistory() {
|
||||
${renderAmount(value.delivered)}
|
||||
${value.TransactionType ? `<td>${value.TransactionType}</td>` : '-'}
|
||||
${value.result ? `<td>${value.result}</td>` : '-'}
|
||||
${value.Hash ? `<td><a href="https://${process.env.EXPLORER_NETWORK}.xrpl.org/transactions/${value.Hash}" target="_blank">View</a></td>` : '-'}`;
|
||||
${value.Hash ? `<td><a href="https://${import.meta.env.VITE_EXPLORER_NETWORK}.xrpl.org/transactions/${value.Hash}" target="_blank">View</a></td>` : '-'}`;
|
||||
// Add the row to the table
|
||||
txHistoryElement.appendChild(row);
|
||||
});
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import { defineConfig, loadEnv } from 'vite';
|
||||
|
||||
const viteConfig = ({ mode }) => {
|
||||
process.env = { ...process.env, ...loadEnv(mode, '', '') };
|
||||
return defineConfig({
|
||||
define: {
|
||||
'process.env': process.env,
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
ws: 'xrpl/dist/npm/client/WSWrapper',
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export default viteConfig;
|
||||
@@ -1,948 +0,0 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@esbuild/android-arm64@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622"
|
||||
integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==
|
||||
|
||||
"@esbuild/android-arm@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682"
|
||||
integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==
|
||||
|
||||
"@esbuild/android-x64@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2"
|
||||
integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==
|
||||
|
||||
"@esbuild/darwin-arm64@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz#08172cbeccf95fbc383399a7f39cfbddaeb0d7c1"
|
||||
integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==
|
||||
|
||||
"@esbuild/darwin-x64@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d"
|
||||
integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==
|
||||
|
||||
"@esbuild/freebsd-arm64@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54"
|
||||
integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==
|
||||
|
||||
"@esbuild/freebsd-x64@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e"
|
||||
integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==
|
||||
|
||||
"@esbuild/linux-arm64@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0"
|
||||
integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==
|
||||
|
||||
"@esbuild/linux-arm@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0"
|
||||
integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==
|
||||
|
||||
"@esbuild/linux-ia32@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7"
|
||||
integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==
|
||||
|
||||
"@esbuild/linux-loong64@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d"
|
||||
integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==
|
||||
|
||||
"@esbuild/linux-mips64el@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231"
|
||||
integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==
|
||||
|
||||
"@esbuild/linux-ppc64@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb"
|
||||
integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==
|
||||
|
||||
"@esbuild/linux-riscv64@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6"
|
||||
integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==
|
||||
|
||||
"@esbuild/linux-s390x@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071"
|
||||
integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==
|
||||
|
||||
"@esbuild/linux-x64@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz#c7690b3417af318a9b6f96df3031a8865176d338"
|
||||
integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==
|
||||
|
||||
"@esbuild/netbsd-x64@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1"
|
||||
integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==
|
||||
|
||||
"@esbuild/openbsd-x64@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae"
|
||||
integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==
|
||||
|
||||
"@esbuild/sunos-x64@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d"
|
||||
integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==
|
||||
|
||||
"@esbuild/win32-arm64@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9"
|
||||
integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==
|
||||
|
||||
"@esbuild/win32-ia32@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102"
|
||||
integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==
|
||||
|
||||
"@esbuild/win32-x64@0.18.20":
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d"
|
||||
integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==
|
||||
|
||||
"@noble/curves@^1.0.0", "@noble/curves@~1.8.1":
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.8.1.tgz#19bc3970e205c99e4bdb1c64a4785706bce497ff"
|
||||
integrity sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==
|
||||
dependencies:
|
||||
"@noble/hashes" "1.7.1"
|
||||
|
||||
"@noble/hashes@1.7.1", "@noble/hashes@^1.0.0", "@noble/hashes@~1.7.1":
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.7.1.tgz#5738f6d765710921e7a751e00c20ae091ed8db0f"
|
||||
integrity sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==
|
||||
|
||||
"@scure/base@^1.1.3", "@scure/base@~1.2.2", "@scure/base@~1.2.4":
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.2.4.tgz#002eb571a35d69bdb4c214d0995dff76a8dcd2a9"
|
||||
integrity sha512-5Yy9czTO47mqz+/J8GM6GIId4umdCk1wc1q8rKERQulIoc8VP9pzDcghv10Tl2E7R96ZUx/PhND3ESYUQX8NuQ==
|
||||
|
||||
"@scure/bip32@^1.3.1":
|
||||
version "1.6.2"
|
||||
resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.6.2.tgz#093caa94961619927659ed0e711a6e4bf35bffd0"
|
||||
integrity sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==
|
||||
dependencies:
|
||||
"@noble/curves" "~1.8.1"
|
||||
"@noble/hashes" "~1.7.1"
|
||||
"@scure/base" "~1.2.2"
|
||||
|
||||
"@scure/bip39@^1.2.1":
|
||||
version "1.5.4"
|
||||
resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.5.4.tgz#07fd920423aa671be4540d59bdd344cc1461db51"
|
||||
integrity sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==
|
||||
dependencies:
|
||||
"@noble/hashes" "~1.7.1"
|
||||
"@scure/base" "~1.2.4"
|
||||
|
||||
"@xrplf/isomorphic@^1.0.0", "@xrplf/isomorphic@^1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@xrplf/isomorphic/-/isomorphic-1.0.1.tgz#d7676e0ec0e55a39f37ddc1f3cc30eeab52e0739"
|
||||
integrity sha512-0bIpgx8PDjYdrLFeC3csF305QQ1L7sxaWnL5y71mCvhenZzJgku9QsA+9QCXBC1eNYtxWO/xR91zrXJy2T/ixg==
|
||||
dependencies:
|
||||
"@noble/hashes" "^1.0.0"
|
||||
eventemitter3 "5.0.1"
|
||||
ws "^8.13.0"
|
||||
|
||||
"@xrplf/secret-numbers@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@xrplf/secret-numbers/-/secret-numbers-1.0.0.tgz#cc19ff84236cc2737b38f2e42a29924f2b8ffc0e"
|
||||
integrity sha512-qsCLGyqe1zaq9j7PZJopK+iGTGRbk6akkg6iZXJJgxKwck0C5x5Gnwlb1HKYGOwPKyrXWpV6a2YmcpNpUFctGg==
|
||||
dependencies:
|
||||
"@xrplf/isomorphic" "^1.0.0"
|
||||
ripple-keypairs "^2.0.0"
|
||||
|
||||
asn1.js@^4.10.1:
|
||||
version "4.10.1"
|
||||
resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0"
|
||||
integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==
|
||||
dependencies:
|
||||
bn.js "^4.0.0"
|
||||
inherits "^2.0.1"
|
||||
minimalistic-assert "^1.0.0"
|
||||
|
||||
available-typed-arrays@^1.0.7:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846"
|
||||
integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==
|
||||
dependencies:
|
||||
possible-typed-array-names "^1.0.0"
|
||||
|
||||
bignumber.js@^9.0.0:
|
||||
version "9.1.2"
|
||||
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c"
|
||||
integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==
|
||||
|
||||
bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9:
|
||||
version "4.12.1"
|
||||
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.1.tgz#215741fe3c9dba2d7e12c001d0cfdbae43975ba7"
|
||||
integrity sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==
|
||||
|
||||
bn.js@^5.2.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70"
|
||||
integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==
|
||||
|
||||
brorand@^1.0.1, brorand@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
|
||||
integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==
|
||||
|
||||
browserify-aes@^1.0.4, browserify-aes@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48"
|
||||
integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==
|
||||
dependencies:
|
||||
buffer-xor "^1.0.3"
|
||||
cipher-base "^1.0.0"
|
||||
create-hash "^1.1.0"
|
||||
evp_bytestokey "^1.0.3"
|
||||
inherits "^2.0.1"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
browserify-cipher@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0"
|
||||
integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==
|
||||
dependencies:
|
||||
browserify-aes "^1.0.4"
|
||||
browserify-des "^1.0.0"
|
||||
evp_bytestokey "^1.0.0"
|
||||
|
||||
browserify-des@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c"
|
||||
integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==
|
||||
dependencies:
|
||||
cipher-base "^1.0.1"
|
||||
des.js "^1.0.0"
|
||||
inherits "^2.0.1"
|
||||
safe-buffer "^5.1.2"
|
||||
|
||||
browserify-rsa@^4.0.0, browserify-rsa@^4.1.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.1.tgz#06e530907fe2949dc21fc3c2e2302e10b1437238"
|
||||
integrity sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==
|
||||
dependencies:
|
||||
bn.js "^5.2.1"
|
||||
randombytes "^2.1.0"
|
||||
safe-buffer "^5.2.1"
|
||||
|
||||
browserify-sign@^4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.3.tgz#7afe4c01ec7ee59a89a558a4b75bd85ae62d4208"
|
||||
integrity sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==
|
||||
dependencies:
|
||||
bn.js "^5.2.1"
|
||||
browserify-rsa "^4.1.0"
|
||||
create-hash "^1.2.0"
|
||||
create-hmac "^1.1.7"
|
||||
elliptic "^6.5.5"
|
||||
hash-base "~3.0"
|
||||
inherits "^2.0.4"
|
||||
parse-asn1 "^5.1.7"
|
||||
readable-stream "^2.3.8"
|
||||
safe-buffer "^5.2.1"
|
||||
|
||||
buffer-xor@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
|
||||
integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==
|
||||
|
||||
builtin-status-codes@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
|
||||
integrity sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==
|
||||
|
||||
call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6"
|
||||
integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==
|
||||
dependencies:
|
||||
es-errors "^1.3.0"
|
||||
function-bind "^1.1.2"
|
||||
|
||||
call-bind@^1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.8.tgz#0736a9660f537e3388826f440d5ec45f744eaa4c"
|
||||
integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==
|
||||
dependencies:
|
||||
call-bind-apply-helpers "^1.0.0"
|
||||
es-define-property "^1.0.0"
|
||||
get-intrinsic "^1.2.4"
|
||||
set-function-length "^1.2.2"
|
||||
|
||||
call-bound@^1.0.3, call-bound@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a"
|
||||
integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==
|
||||
dependencies:
|
||||
call-bind-apply-helpers "^1.0.2"
|
||||
get-intrinsic "^1.3.0"
|
||||
|
||||
cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.6.tgz#8fe672437d01cd6c4561af5334e0cc50ff1955f7"
|
||||
integrity sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==
|
||||
dependencies:
|
||||
inherits "^2.0.4"
|
||||
safe-buffer "^5.2.1"
|
||||
|
||||
core-util-is@~1.0.0:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
|
||||
integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
|
||||
|
||||
create-ecdh@^4.0.4:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e"
|
||||
integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==
|
||||
dependencies:
|
||||
bn.js "^4.1.0"
|
||||
elliptic "^6.5.3"
|
||||
|
||||
create-hash@^1.1.0, create-hash@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196"
|
||||
integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==
|
||||
dependencies:
|
||||
cipher-base "^1.0.1"
|
||||
inherits "^2.0.1"
|
||||
md5.js "^1.3.4"
|
||||
ripemd160 "^2.0.1"
|
||||
sha.js "^2.4.0"
|
||||
|
||||
create-hash@~1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.3.tgz#606042ac8b9262750f483caddab0f5819172d8fd"
|
||||
integrity sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA==
|
||||
dependencies:
|
||||
cipher-base "^1.0.1"
|
||||
inherits "^2.0.1"
|
||||
ripemd160 "^2.0.0"
|
||||
sha.js "^2.4.0"
|
||||
|
||||
create-hmac@^1.1.7:
|
||||
version "1.1.7"
|
||||
resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff"
|
||||
integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==
|
||||
dependencies:
|
||||
cipher-base "^1.0.3"
|
||||
create-hash "^1.1.0"
|
||||
inherits "^2.0.1"
|
||||
ripemd160 "^2.0.0"
|
||||
safe-buffer "^5.0.1"
|
||||
sha.js "^2.4.8"
|
||||
|
||||
crypto-browserify@^3.12.0:
|
||||
version "3.12.1"
|
||||
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.1.tgz#bb8921bec9acc81633379aa8f52d69b0b69e0dac"
|
||||
integrity sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ==
|
||||
dependencies:
|
||||
browserify-cipher "^1.0.1"
|
||||
browserify-sign "^4.2.3"
|
||||
create-ecdh "^4.0.4"
|
||||
create-hash "^1.2.0"
|
||||
create-hmac "^1.1.7"
|
||||
diffie-hellman "^5.0.3"
|
||||
hash-base "~3.0.4"
|
||||
inherits "^2.0.4"
|
||||
pbkdf2 "^3.1.2"
|
||||
public-encrypt "^4.0.3"
|
||||
randombytes "^2.1.0"
|
||||
randomfill "^1.0.4"
|
||||
|
||||
define-data-property@^1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
|
||||
integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==
|
||||
dependencies:
|
||||
es-define-property "^1.0.0"
|
||||
es-errors "^1.3.0"
|
||||
gopd "^1.0.1"
|
||||
|
||||
des.js@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.1.0.tgz#1d37f5766f3bbff4ee9638e871a8768c173b81da"
|
||||
integrity sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==
|
||||
dependencies:
|
||||
inherits "^2.0.1"
|
||||
minimalistic-assert "^1.0.0"
|
||||
|
||||
diffie-hellman@^5.0.3:
|
||||
version "5.0.3"
|
||||
resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
|
||||
integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==
|
||||
dependencies:
|
||||
bn.js "^4.1.0"
|
||||
miller-rabin "^4.0.0"
|
||||
randombytes "^2.0.0"
|
||||
|
||||
dotenv@^16.0.3:
|
||||
version "16.4.7"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.7.tgz#0e20c5b82950140aa99be360a8a5f52335f53c26"
|
||||
integrity sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==
|
||||
|
||||
dunder-proto@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a"
|
||||
integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==
|
||||
dependencies:
|
||||
call-bind-apply-helpers "^1.0.1"
|
||||
es-errors "^1.3.0"
|
||||
gopd "^1.2.0"
|
||||
|
||||
elliptic@^6.5.3, elliptic@^6.5.5:
|
||||
version "6.6.1"
|
||||
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.6.1.tgz#3b8ffb02670bf69e382c7f65bf524c97c5405c06"
|
||||
integrity sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==
|
||||
dependencies:
|
||||
bn.js "^4.11.9"
|
||||
brorand "^1.1.0"
|
||||
hash.js "^1.0.0"
|
||||
hmac-drbg "^1.0.1"
|
||||
inherits "^2.0.4"
|
||||
minimalistic-assert "^1.0.1"
|
||||
minimalistic-crypto-utils "^1.0.1"
|
||||
|
||||
es-define-property@^1.0.0, es-define-property@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa"
|
||||
integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==
|
||||
|
||||
es-errors@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
|
||||
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
|
||||
|
||||
es-object-atoms@^1.0.0, es-object-atoms@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1"
|
||||
integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==
|
||||
dependencies:
|
||||
es-errors "^1.3.0"
|
||||
|
||||
esbuild@^0.18.10:
|
||||
version "0.18.20"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.20.tgz#4709f5a34801b43b799ab7d6d82f7284a9b7a7a6"
|
||||
integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==
|
||||
optionalDependencies:
|
||||
"@esbuild/android-arm" "0.18.20"
|
||||
"@esbuild/android-arm64" "0.18.20"
|
||||
"@esbuild/android-x64" "0.18.20"
|
||||
"@esbuild/darwin-arm64" "0.18.20"
|
||||
"@esbuild/darwin-x64" "0.18.20"
|
||||
"@esbuild/freebsd-arm64" "0.18.20"
|
||||
"@esbuild/freebsd-x64" "0.18.20"
|
||||
"@esbuild/linux-arm" "0.18.20"
|
||||
"@esbuild/linux-arm64" "0.18.20"
|
||||
"@esbuild/linux-ia32" "0.18.20"
|
||||
"@esbuild/linux-loong64" "0.18.20"
|
||||
"@esbuild/linux-mips64el" "0.18.20"
|
||||
"@esbuild/linux-ppc64" "0.18.20"
|
||||
"@esbuild/linux-riscv64" "0.18.20"
|
||||
"@esbuild/linux-s390x" "0.18.20"
|
||||
"@esbuild/linux-x64" "0.18.20"
|
||||
"@esbuild/netbsd-x64" "0.18.20"
|
||||
"@esbuild/openbsd-x64" "0.18.20"
|
||||
"@esbuild/sunos-x64" "0.18.20"
|
||||
"@esbuild/win32-arm64" "0.18.20"
|
||||
"@esbuild/win32-ia32" "0.18.20"
|
||||
"@esbuild/win32-x64" "0.18.20"
|
||||
|
||||
eventemitter3@5.0.1, eventemitter3@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4"
|
||||
integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==
|
||||
|
||||
events@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
|
||||
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
|
||||
|
||||
evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02"
|
||||
integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==
|
||||
dependencies:
|
||||
md5.js "^1.3.4"
|
||||
safe-buffer "^5.1.1"
|
||||
|
||||
for-each@^0.3.5:
|
||||
version "0.3.5"
|
||||
resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.5.tgz#d650688027826920feeb0af747ee7b9421a41d47"
|
||||
integrity sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==
|
||||
dependencies:
|
||||
is-callable "^1.2.7"
|
||||
|
||||
fsevents@~2.3.2:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
|
||||
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
|
||||
|
||||
function-bind@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
|
||||
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
|
||||
|
||||
get-intrinsic@^1.2.4, get-intrinsic@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01"
|
||||
integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==
|
||||
dependencies:
|
||||
call-bind-apply-helpers "^1.0.2"
|
||||
es-define-property "^1.0.1"
|
||||
es-errors "^1.3.0"
|
||||
es-object-atoms "^1.1.1"
|
||||
function-bind "^1.1.2"
|
||||
get-proto "^1.0.1"
|
||||
gopd "^1.2.0"
|
||||
has-symbols "^1.1.0"
|
||||
hasown "^2.0.2"
|
||||
math-intrinsics "^1.1.0"
|
||||
|
||||
get-proto@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1"
|
||||
integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==
|
||||
dependencies:
|
||||
dunder-proto "^1.0.1"
|
||||
es-object-atoms "^1.0.0"
|
||||
|
||||
gopd@^1.0.1, gopd@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
|
||||
integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
|
||||
|
||||
has-property-descriptors@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854"
|
||||
integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==
|
||||
dependencies:
|
||||
es-define-property "^1.0.0"
|
||||
|
||||
has-symbols@^1.0.3, has-symbols@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338"
|
||||
integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==
|
||||
|
||||
has-tostringtag@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc"
|
||||
integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
|
||||
dependencies:
|
||||
has-symbols "^1.0.3"
|
||||
|
||||
hash-base@^2.0.0:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-2.0.2.tgz#66ea1d856db4e8a5470cadf6fce23ae5244ef2e1"
|
||||
integrity sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw==
|
||||
dependencies:
|
||||
inherits "^2.0.1"
|
||||
|
||||
hash-base@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33"
|
||||
integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==
|
||||
dependencies:
|
||||
inherits "^2.0.4"
|
||||
readable-stream "^3.6.0"
|
||||
safe-buffer "^5.2.0"
|
||||
|
||||
hash-base@~3.0, hash-base@~3.0.4:
|
||||
version "3.0.5"
|
||||
resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.5.tgz#52480e285395cf7fba17dc4c9e47acdc7f248a8a"
|
||||
integrity sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==
|
||||
dependencies:
|
||||
inherits "^2.0.4"
|
||||
safe-buffer "^5.2.1"
|
||||
|
||||
hash.js@^1.0.0, hash.js@^1.0.3:
|
||||
version "1.1.7"
|
||||
resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42"
|
||||
integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==
|
||||
dependencies:
|
||||
inherits "^2.0.3"
|
||||
minimalistic-assert "^1.0.1"
|
||||
|
||||
hasown@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
|
||||
integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
|
||||
dependencies:
|
||||
function-bind "^1.1.2"
|
||||
|
||||
hmac-drbg@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
|
||||
integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==
|
||||
dependencies:
|
||||
hash.js "^1.0.3"
|
||||
minimalistic-assert "^1.0.0"
|
||||
minimalistic-crypto-utils "^1.0.1"
|
||||
|
||||
https-browserify@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
|
||||
integrity sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==
|
||||
|
||||
inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@~2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
is-callable@^1.2.7:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
|
||||
integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
|
||||
|
||||
is-typed-array@^1.1.14:
|
||||
version "1.1.15"
|
||||
resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.15.tgz#4bfb4a45b61cee83a5a46fba778e4e8d59c0ce0b"
|
||||
integrity sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==
|
||||
dependencies:
|
||||
which-typed-array "^1.1.16"
|
||||
|
||||
isarray@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
|
||||
integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
|
||||
|
||||
isarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
|
||||
|
||||
math-intrinsics@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9"
|
||||
integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==
|
||||
|
||||
md5.js@^1.3.4:
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
|
||||
integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==
|
||||
dependencies:
|
||||
hash-base "^3.0.0"
|
||||
inherits "^2.0.1"
|
||||
safe-buffer "^5.1.2"
|
||||
|
||||
miller-rabin@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
|
||||
integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==
|
||||
dependencies:
|
||||
bn.js "^4.0.0"
|
||||
brorand "^1.0.1"
|
||||
|
||||
minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
|
||||
integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
|
||||
|
||||
minimalistic-crypto-utils@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
|
||||
integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==
|
||||
|
||||
nanoid@^3.3.8:
|
||||
version "3.3.8"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf"
|
||||
integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==
|
||||
|
||||
parse-asn1@^5.0.0, parse-asn1@^5.1.7:
|
||||
version "5.1.7"
|
||||
resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.7.tgz#73cdaaa822125f9647165625eb45f8a051d2df06"
|
||||
integrity sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==
|
||||
dependencies:
|
||||
asn1.js "^4.10.1"
|
||||
browserify-aes "^1.2.0"
|
||||
evp_bytestokey "^1.0.3"
|
||||
hash-base "~3.0"
|
||||
pbkdf2 "^3.1.2"
|
||||
safe-buffer "^5.2.1"
|
||||
|
||||
pbkdf2@^3.1.2:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.3.tgz#8be674d591d65658113424592a95d1517318dd4b"
|
||||
integrity sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA==
|
||||
dependencies:
|
||||
create-hash "~1.1.3"
|
||||
create-hmac "^1.1.7"
|
||||
ripemd160 "=2.0.1"
|
||||
safe-buffer "^5.2.1"
|
||||
sha.js "^2.4.11"
|
||||
to-buffer "^1.2.0"
|
||||
|
||||
picocolors@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
|
||||
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
|
||||
|
||||
possible-typed-array-names@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz#93e3582bc0e5426586d9d07b79ee40fc841de4ae"
|
||||
integrity sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==
|
||||
|
||||
postcss@^8.4.27:
|
||||
version "8.5.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.1.tgz#e2272a1f8a807fafa413218245630b5db10a3214"
|
||||
integrity sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==
|
||||
dependencies:
|
||||
nanoid "^3.3.8"
|
||||
picocolors "^1.1.1"
|
||||
source-map-js "^1.2.1"
|
||||
|
||||
process-nextick-args@~2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
|
||||
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
|
||||
|
||||
public-encrypt@^4.0.3:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0"
|
||||
integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==
|
||||
dependencies:
|
||||
bn.js "^4.1.0"
|
||||
browserify-rsa "^4.0.0"
|
||||
create-hash "^1.1.0"
|
||||
parse-asn1 "^5.0.0"
|
||||
randombytes "^2.0.1"
|
||||
safe-buffer "^5.1.2"
|
||||
|
||||
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
|
||||
integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
|
||||
dependencies:
|
||||
safe-buffer "^5.1.0"
|
||||
|
||||
randomfill@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458"
|
||||
integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==
|
||||
dependencies:
|
||||
randombytes "^2.0.5"
|
||||
safe-buffer "^5.1.0"
|
||||
|
||||
readable-stream@^2.3.8:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b"
|
||||
integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
|
||||
dependencies:
|
||||
core-util-is "~1.0.0"
|
||||
inherits "~2.0.3"
|
||||
isarray "~1.0.0"
|
||||
process-nextick-args "~2.0.0"
|
||||
safe-buffer "~5.1.1"
|
||||
string_decoder "~1.1.1"
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
readable-stream@^3.5.0, readable-stream@^3.6.0:
|
||||
version "3.6.2"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967"
|
||||
integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==
|
||||
dependencies:
|
||||
inherits "^2.0.3"
|
||||
string_decoder "^1.1.1"
|
||||
util-deprecate "^1.0.1"
|
||||
|
||||
ripemd160@=2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.1.tgz#0f4584295c53a3628af7e6d79aca21ce57d1c6e7"
|
||||
integrity sha512-J7f4wutN8mdbV08MJnXibYpCOPHR+yzy+iQ/AsjMv2j8cLavQ8VGagDFUwwTAdF8FmRKVeNpbTTEwNHCW1g94w==
|
||||
dependencies:
|
||||
hash-base "^2.0.0"
|
||||
inherits "^2.0.1"
|
||||
|
||||
ripemd160@^2.0.0, ripemd160@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
|
||||
integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==
|
||||
dependencies:
|
||||
hash-base "^3.0.0"
|
||||
inherits "^2.0.1"
|
||||
|
||||
ripple-address-codec@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ripple-address-codec/-/ripple-address-codec-5.0.0.tgz#97059f7bba6f9ed7a52843de8aa427723fb529f6"
|
||||
integrity sha512-de7osLRH/pt5HX2xw2TRJtbdLLWHu0RXirpQaEeCnWKY5DYHykh3ETSkofvm0aX0LJiV7kwkegJxQkmbO94gWw==
|
||||
dependencies:
|
||||
"@scure/base" "^1.1.3"
|
||||
"@xrplf/isomorphic" "^1.0.0"
|
||||
|
||||
ripple-binary-codec@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ripple-binary-codec/-/ripple-binary-codec-2.2.0.tgz#c296b62c0638b0f02ea8a34b51f707140c1687b9"
|
||||
integrity sha512-93fvAW3oXux4NY5Xf79dUIOhud5DmyEcC5RrTYdl0BPaYOGXC/txCQl9FnwIVZGkVMtZFLcFwJfmH1zFgfRyKA==
|
||||
dependencies:
|
||||
"@xrplf/isomorphic" "^1.0.1"
|
||||
bignumber.js "^9.0.0"
|
||||
ripple-address-codec "^5.0.0"
|
||||
|
||||
ripple-keypairs@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ripple-keypairs/-/ripple-keypairs-2.0.0.tgz#4a1a8142e9a58c07e61b3cc6cfe7317db718d289"
|
||||
integrity sha512-b5rfL2EZiffmklqZk1W+dvSy97v3V/C7936WxCCgDynaGPp7GE6R2XO7EU9O2LlM/z95rj870IylYnOQs+1Rag==
|
||||
dependencies:
|
||||
"@noble/curves" "^1.0.0"
|
||||
"@xrplf/isomorphic" "^1.0.0"
|
||||
ripple-address-codec "^5.0.0"
|
||||
|
||||
rollup@^3.27.1:
|
||||
version "3.29.5"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.5.tgz#8a2e477a758b520fb78daf04bca4c522c1da8a54"
|
||||
integrity sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
||||
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
||||
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
||||
|
||||
set-function-length@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449"
|
||||
integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==
|
||||
dependencies:
|
||||
define-data-property "^1.1.4"
|
||||
es-errors "^1.3.0"
|
||||
function-bind "^1.1.2"
|
||||
get-intrinsic "^1.2.4"
|
||||
gopd "^1.0.1"
|
||||
has-property-descriptors "^1.0.2"
|
||||
|
||||
sha.js@^2.4.0, sha.js@^2.4.11, sha.js@^2.4.8:
|
||||
version "2.4.12"
|
||||
resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.12.tgz#eb8b568bf383dfd1867a32c3f2b74eb52bdbf23f"
|
||||
integrity sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==
|
||||
dependencies:
|
||||
inherits "^2.0.4"
|
||||
safe-buffer "^5.2.1"
|
||||
to-buffer "^1.2.0"
|
||||
|
||||
source-map-js@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
|
||||
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
|
||||
|
||||
stream-browserify@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f"
|
||||
integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==
|
||||
dependencies:
|
||||
inherits "~2.0.4"
|
||||
readable-stream "^3.5.0"
|
||||
|
||||
stream-http@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-3.2.0.tgz#1872dfcf24cb15752677e40e5c3f9cc1926028b5"
|
||||
integrity sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==
|
||||
dependencies:
|
||||
builtin-status-codes "^3.0.0"
|
||||
inherits "^2.0.4"
|
||||
readable-stream "^3.6.0"
|
||||
xtend "^4.0.2"
|
||||
|
||||
string_decoder@^1.1.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
|
||||
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
|
||||
dependencies:
|
||||
safe-buffer "~5.2.0"
|
||||
|
||||
string_decoder@~1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
|
||||
integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
|
||||
dependencies:
|
||||
safe-buffer "~5.1.0"
|
||||
|
||||
to-buffer@^1.2.0:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.2.1.tgz#2ce650cdb262e9112a18e65dc29dcb513c8155e0"
|
||||
integrity sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==
|
||||
dependencies:
|
||||
isarray "^2.0.5"
|
||||
safe-buffer "^5.2.1"
|
||||
typed-array-buffer "^1.0.3"
|
||||
|
||||
typed-array-buffer@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz#a72395450a4869ec033fd549371b47af3a2ee536"
|
||||
integrity sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==
|
||||
dependencies:
|
||||
call-bound "^1.0.3"
|
||||
es-errors "^1.3.0"
|
||||
is-typed-array "^1.1.14"
|
||||
|
||||
util-deprecate@^1.0.1, util-deprecate@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
|
||||
|
||||
vite@^4.5.14:
|
||||
version "4.5.14"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.14.tgz#2e652bc1d898265d987d6543ce866ecd65fa4086"
|
||||
integrity sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==
|
||||
dependencies:
|
||||
esbuild "^0.18.10"
|
||||
postcss "^8.4.27"
|
||||
rollup "^3.27.1"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
which-typed-array@^1.1.16:
|
||||
version "1.1.19"
|
||||
resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.19.tgz#df03842e870b6b88e117524a4b364b6fc689f956"
|
||||
integrity sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==
|
||||
dependencies:
|
||||
available-typed-arrays "^1.0.7"
|
||||
call-bind "^1.0.8"
|
||||
call-bound "^1.0.4"
|
||||
for-each "^0.3.5"
|
||||
get-proto "^1.0.1"
|
||||
gopd "^1.2.0"
|
||||
has-tostringtag "^1.0.2"
|
||||
|
||||
ws@^8.13.0:
|
||||
version "8.18.0"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc"
|
||||
integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==
|
||||
|
||||
xrpl@^4.0.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/xrpl/-/xrpl-4.1.0.tgz#3afc1e97544c678f8ada73f9757eee7a35e05740"
|
||||
integrity sha512-H/+BCEnFLyQOBUC6h4nMKg7I9AuxHe4kj9ZwQHX2zoL9n/ZOERc6B2U079pogI84zCbYdUWIn4DkoIYvjO/hpg==
|
||||
dependencies:
|
||||
"@scure/bip32" "^1.3.1"
|
||||
"@scure/bip39" "^1.2.1"
|
||||
"@xrplf/isomorphic" "^1.0.1"
|
||||
"@xrplf/secret-numbers" "^1.0.0"
|
||||
bignumber.js "^9.0.0"
|
||||
eventemitter3 "^5.0.1"
|
||||
ripple-address-codec "^5.0.0"
|
||||
ripple-binary-codec "^2.2.0"
|
||||
ripple-keypairs "^2.0.0"
|
||||
|
||||
xtend@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
|
||||
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
||||
@@ -1,5 +1,5 @@
|
||||
# Tickets
|
||||
# Use Tickets
|
||||
|
||||
Create a Ticket and use it to send a transaction out of the usual Sequence order.
|
||||
Create a batch of Tickets and use one to send a transaction outside the normal Sequence order.
|
||||
|
||||
For more context, see the interactive [Use Tickets tutorial](https://xrpl.org/use-tickets.html).
|
||||
For more context, see the [Use Tickets tutorial](https://xrpl.org/docs/tutorials/best-practices/transaction-sending/use-tickets).
|
||||
|
||||
17
_code-samples/use-tickets/go/README.md
Normal file
17
_code-samples/use-tickets/go/README.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# Use Tickets (Go)
|
||||
|
||||
Demonstrates how to use Tickets for out-of-order transaction submission on the XRP Ledger.
|
||||
|
||||
For more context, see the [Use Tickets tutorial](https://xrpl.org/docs/tutorials/best-practices/transaction-sending/use-tickets).
|
||||
|
||||
## Setup
|
||||
|
||||
```sh
|
||||
go mod download
|
||||
```
|
||||
|
||||
## Basic Ticket Usage
|
||||
|
||||
```sh
|
||||
go run main.go
|
||||
```
|
||||
@@ -1,21 +1,16 @@
|
||||
module github.com/XRPLF
|
||||
|
||||
go 1.24.0
|
||||
go 1.24.3
|
||||
|
||||
require github.com/Peersyst/xrpl-go v0.1.11
|
||||
require github.com/Peersyst/xrpl-go v0.1.18
|
||||
|
||||
require (
|
||||
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
|
||||
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
|
||||
github.com/bsv-blockchain/go-sdk v1.2.9 // indirect
|
||||
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
)
|
||||
|
||||
@@ -1,56 +1,30 @@
|
||||
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
|
||||
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
|
||||
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
|
||||
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
|
||||
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
|
||||
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
|
||||
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/Peersyst/xrpl-go v0.1.18 h1:PUIEGvnkO9oQ4yZRr6EHjglay1xmrjFhujQNVkXynqs=
|
||||
github.com/Peersyst/xrpl-go v0.1.18/go.mod h1:38j60Mr65poIHdhmjvNXnwbcUFNo8J7CBDot7ZWgrb8=
|
||||
github.com/bsv-blockchain/go-sdk v1.2.9 h1:LwFzuts+J5X7A+ECx0LNowtUgIahCkNNlXckdiEMSDk=
|
||||
github.com/bsv-blockchain/go-sdk v1.2.9/go.mod h1:KiHWa/hblo3Bzr+IsX11v0sn1E6elGbNX0VXl5mOq6E=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
|
||||
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1 h1:5RVFMOWjMyRy8cARdy79nAmgYw3hK/4HUq48LQ6Wwqo=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
|
||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
|
||||
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
|
||||
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
|
||||
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
|
||||
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=
|
||||
|
||||
@@ -1,123 +1,113 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||
"github.com/Peersyst/xrpl-go/xrpl/queries/account"
|
||||
"github.com/Peersyst/xrpl-go/xrpl/rpc"
|
||||
"github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||
"github.com/Peersyst/xrpl-go/xrpl/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cfg, err := rpc.NewClientConfig(
|
||||
"https://s.altnet.rippletest.net:51234/",
|
||||
rpc.WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Set up client and account
|
||||
client := websocket.NewClient(
|
||||
websocket.NewClientConfig().
|
||||
WithHost("wss://s.altnet.rippletest.net:51233").
|
||||
WithFaucetProvider(faucet.NewTestnetFaucetProvider()).
|
||||
WithMaxRetries(30),
|
||||
)
|
||||
defer client.Disconnect()
|
||||
|
||||
client := rpc.NewClient(cfg)
|
||||
if err := client.Connect(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
w, err := wallet.New(crypto.ED25519())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Fund wallet
|
||||
w, err := wallet.New(crypto.ED25519())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("Getting a wallet from the faucet...")
|
||||
if err := client.FundWallet(&w); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("Wallet address: %s\n", w.GetAddress())
|
||||
fmt.Println()
|
||||
|
||||
fmt.Println("Funding wallet...")
|
||||
if err := client.FundWallet(&w); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Create Tickets
|
||||
ticketCreate := &transaction.TicketCreate{
|
||||
BaseTx: transaction.BaseTx{
|
||||
Account: w.GetAddress(),
|
||||
},
|
||||
TicketCount: 10,
|
||||
}
|
||||
flatTc := ticketCreate.Flatten()
|
||||
if err := client.Autofill(&flatTc); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
blob, _, err := w.Sign(flatTc)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("Submitting TicketCreate transaction...")
|
||||
tcResult, err := client.SubmitTxBlobAndWait(blob, false)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("TicketCreate hash: %s, validated: %t\n", tcResult.Hash, tcResult.Validated)
|
||||
fmt.Println()
|
||||
|
||||
fmt.Println("Wallet funded")
|
||||
fmt.Println()
|
||||
// Check Available Tickets
|
||||
fmt.Println("Checking available tickets...")
|
||||
objects, err := client.GetAccountObjects(&account.ObjectsRequest{
|
||||
Account: w.GetAddress(),
|
||||
Type: account.TicketObject,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("Found %d Tickets\n", len(objects.AccountObjects))
|
||||
|
||||
info, err := client.GetAccountInfo(&account.InfoRequest{
|
||||
Account: w.GetAddress(),
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Choose an arbitrary Ticket to use
|
||||
useTicket := uint32(objects.AccountObjects[0]["TicketSequence"].(float64))
|
||||
fmt.Printf("Using Ticket Sequence: %d\n", useTicket)
|
||||
fmt.Println()
|
||||
|
||||
fmt.Println("Current wallet sequence:", info.AccountData.Sequence)
|
||||
fmt.Println()
|
||||
// Use a Ticket
|
||||
ticketedTx := &transaction.AccountSet{
|
||||
BaseTx: transaction.BaseTx{
|
||||
Account: w.GetAddress(),
|
||||
Sequence: 0,
|
||||
TicketSequence: useTicket,
|
||||
},
|
||||
}
|
||||
flatAs := ticketedTx.Flatten()
|
||||
if err := client.Autofill(&flatAs); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
blob, _, err = w.Sign(flatAs)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("Submitting ticketed AccountSet transaction...")
|
||||
ticketedResult, err := client.SubmitTxBlobAndWait(blob, false)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("Ticketed AccountSet hash: %s, validated: %t\n", ticketedResult.Hash, ticketedResult.Validated)
|
||||
fmt.Println()
|
||||
|
||||
fmt.Println("Submitting TicketCreate transaction...")
|
||||
tc := &transaction.TicketCreate{
|
||||
BaseTx: transaction.BaseTx{
|
||||
Account: w.GetAddress(),
|
||||
Sequence: info.AccountData.Sequence,
|
||||
},
|
||||
TicketCount: 10,
|
||||
}
|
||||
|
||||
flatTc := tc.Flatten()
|
||||
|
||||
if err := client.Autofill(&flatTc); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
blob, _, err := w.Sign(flatTc)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
res, err := client.SubmitTxBlobAndWait(blob, false)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println("TicketCreate transaction submitted")
|
||||
fmt.Printf("Hash: %s\n", res.Hash)
|
||||
fmt.Printf("Validated: %t\n", res.Validated)
|
||||
fmt.Println()
|
||||
|
||||
objects, err := client.GetAccountObjects(&account.ObjectsRequest{
|
||||
Account: w.GetAddress(),
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println("Account objects:", objects.AccountObjects[0]["TicketSequence"])
|
||||
|
||||
seq, err := objects.AccountObjects[0]["TicketSequence"].(json.Number).Int64()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println("Submitting AccountSet transaction...")
|
||||
as := &transaction.AccountSet{
|
||||
BaseTx: transaction.BaseTx{
|
||||
Account: w.GetAddress(),
|
||||
Sequence: 0,
|
||||
TicketSequence: uint32(seq),
|
||||
},
|
||||
}
|
||||
|
||||
flatAs := as.Flatten()
|
||||
|
||||
if err := client.Autofill(&flatAs); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
flatAs["Sequence"] = uint32(0)
|
||||
|
||||
blob, _, err = w.Sign(flatAs)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
res, err = client.SubmitTxBlobAndWait(blob, false)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println("AccountSet transaction submitted")
|
||||
fmt.Printf("Hash: %s\n", res.Hash)
|
||||
fmt.Printf("Validated: %t\n", res.Validated)
|
||||
// Recheck Available Tickets
|
||||
fmt.Println("Rechecking available tickets...")
|
||||
objectsAfter, err := client.GetAccountObjects(&account.ObjectsRequest{
|
||||
Account: w.GetAddress(),
|
||||
Type: account.TicketObject,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("Found %d Tickets\n", len(objectsAfter.AccountObjects))
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
Demonstrates how to use Tickets for out-of-order transaction submission on the XRP Ledger.
|
||||
|
||||
For more context, see the [Use Tickets tutorial](https://xrpl.org/docs/tutorials/best-practices/transaction-sending/use-tickets).
|
||||
|
||||
## Setup
|
||||
|
||||
```sh
|
||||
@@ -10,12 +12,6 @@ npm install
|
||||
|
||||
## Basic Ticket Usage
|
||||
|
||||
### Browser
|
||||
|
||||
Open `demo.html` in a web browser and check the browser console to see the logs.
|
||||
|
||||
Alternatively, you can run the code from the command line:
|
||||
|
||||
```sh
|
||||
node use-tickets.js
|
||||
```
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Code Sample - Use Tickets</title>
|
||||
<script src="https://unpkg.com/xrpl@4.0.0/build/xrpl-latest.js"></script>
|
||||
<script type="application/javascript" src="use-tickets.js"></script>
|
||||
</head>
|
||||
<body>Open your browser's console (F12) to see the logs.</body>
|
||||
</html>
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"xrpl": "^4.0.0"
|
||||
}
|
||||
|
||||
@@ -1,129 +1,74 @@
|
||||
if (typeof module !== "undefined") {
|
||||
// Use var here because const/let are block-scoped to the if statement.
|
||||
var xrpl = require('xrpl')
|
||||
}
|
||||
// List which Tickets are outstanding against one’s own account and use Tickets to collect signatures for multisign transactions
|
||||
// https://xrpl.org/use-tickets.html
|
||||
// https://xrpl.org/signerlistset.html#signerlistset
|
||||
// https://xrpl.org/multi-signing.html#multi-signing
|
||||
import xrpl from 'xrpl'
|
||||
|
||||
async function main() {
|
||||
// Connect to a testnet node
|
||||
console.log("Connecting to Testnet...")
|
||||
const client = new xrpl.Client('wss://s.altnet.rippletest.net:51233')
|
||||
await client.connect()
|
||||
|
||||
// Get account credentials from the Testnet Faucet
|
||||
console.log("Requesting account credentials from the Testnet faucet, this may take awhile...")
|
||||
const { wallet: main_wallet } = await client.fundWallet()
|
||||
// Use Tickets with multi-signing: each Ticket holds a Sequence slot for a
|
||||
// transaction while you collect signatures from multiple signers.
|
||||
|
||||
// Signer keys don't need to be funded on the ledger, it only needs to be cryptographically valid
|
||||
// Thus, we could generate keys and set them as signers without the need to fund their accounts
|
||||
// But we'll still fund them for testing purposes...
|
||||
const { wallet: wallet_1 } = await client.fundWallet()
|
||||
const { wallet: wallet_2 } = await client.fundWallet()
|
||||
const { wallet: wallet_3 } = await client.fundWallet()
|
||||
const client = new xrpl.Client('wss://s.altnet.rippletest.net:51233')
|
||||
await client.connect()
|
||||
|
||||
console.log(" Main Account: ", main_wallet.address)
|
||||
console.log(" Seed: ", main_wallet.seed)
|
||||
// Set up the main account and three signers ------------------------------
|
||||
// Signer accounts only need cryptographically valid keys; the addresses
|
||||
// don't need to be funded or exist on the ledger.
|
||||
console.log('Funding main account from the faucet...')
|
||||
const { wallet: mainWallet } = await client.fundWallet()
|
||||
const signer1 = xrpl.Wallet.generate()
|
||||
const signer2 = xrpl.Wallet.generate()
|
||||
const signer3 = xrpl.Wallet.generate()
|
||||
console.log(`Main account: ${mainWallet.address}`)
|
||||
|
||||
console.log("\n Signer 1: ", wallet_1.address)
|
||||
console.log(" Signer 2: ", wallet_2.address)
|
||||
console.log(" Signer 3: ", wallet_3.address)
|
||||
// Configure the signer list (quorum 2 of 3) -------------------------------
|
||||
console.log('Submitting SignerListSet...')
|
||||
const signerListResult = await client.submitAndWait({
|
||||
TransactionType: 'SignerListSet',
|
||||
Account: mainWallet.address,
|
||||
SignerQuorum: 2,
|
||||
SignerEntries: [
|
||||
{ SignerEntry: { Account: signer1.address, SignerWeight: 1 } },
|
||||
{ SignerEntry: { Account: signer2.address, SignerWeight: 1 } },
|
||||
{ SignerEntry: { Account: signer3.address, SignerWeight: 1 } }
|
||||
]
|
||||
}, { wallet: mainWallet, autofill: true })
|
||||
console.log(`SignerListSet hash: ${signerListResult.result.hash}`)
|
||||
|
||||
// Send SignerListSet transaction
|
||||
// Since each signer is given a signer weight of 1 and there are 3 signers, the maximum quorom would be 3
|
||||
// SignerQuorom is a target number for the signer weights
|
||||
// A multisig from this list is valid only if the sum weights of the signatures provided is greater than or equal to the SignerQuorom
|
||||
const signerLiSetSignerList_tx = {
|
||||
TransactionType: "SignerListSet",
|
||||
Account: main_wallet.classicAddress,
|
||||
SignerEntries: [
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: wallet_1.classicAddress,
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: wallet_2.classicAddress,
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: wallet_3.classicAddress,
|
||||
SignerWeight: 1,
|
||||
},
|
||||
}
|
||||
],
|
||||
SignerQuorum: 2,
|
||||
}
|
||||
// Create Tickets ----------------------------------------------------------
|
||||
console.log('Submitting TicketCreate (3 Tickets)...')
|
||||
const ticketCreateResult = await client.submitAndWait({
|
||||
TransactionType: 'TicketCreate',
|
||||
Account: mainWallet.address,
|
||||
TicketCount: 3
|
||||
}, { wallet: mainWallet, autofill: true })
|
||||
console.log(`TicketCreate hash: ${ticketCreateResult.result.hash}`)
|
||||
|
||||
const signerLiSetSignerList_tx_prepared = await client.autofill(signerLiSetSignerList_tx)
|
||||
const SetSignerList_tx_signed = main_wallet.sign(signerLiSetSignerList_tx_prepared)
|
||||
console.log(`\n SignerListSet Tx hash: ${SetSignerList_tx_signed.hash}`)
|
||||
|
||||
const setsignerlist_submit = await client.submitAndWait(SetSignerList_tx_signed.tx_blob)
|
||||
console.log(`\t Submit result: ${setsignerlist_submit.result.meta.TransactionResult}`)
|
||||
|
||||
const CreateTicket_tx = await client.autofill({
|
||||
TransactionType: "TicketCreate",
|
||||
Account: main_wallet.address,
|
||||
TicketCount: 3
|
||||
})
|
||||
|
||||
const CreateTicket_tx_signed = main_wallet.sign(CreateTicket_tx)
|
||||
console.log("\n CreateTicket Tx hash:", CreateTicket_tx_signed.hash)
|
||||
|
||||
const ticket_submit = await client.submitAndWait(CreateTicket_tx_signed.tx_blob)
|
||||
console.log(" Submit result:", ticket_submit.result.meta.TransactionResult)
|
||||
|
||||
const ticket_response = await client.request({
|
||||
command: "account_objects",
|
||||
account: main_wallet.address,
|
||||
ledger_index: "validated",
|
||||
type: "ticket"
|
||||
})
|
||||
// Pick a Ticket -----------------------------------------------------------
|
||||
const ticketsResponse = await client.request({
|
||||
command: 'account_objects',
|
||||
account: mainWallet.address,
|
||||
type: 'ticket'
|
||||
})
|
||||
const useTicket = ticketsResponse.result.account_objects[0].TicketSequence
|
||||
console.log(`Using Ticket Sequence: ${useTicket}`)
|
||||
|
||||
console.log(`\n- Tickets issued by ${main_wallet.address}:\n`)
|
||||
for (let i = 0; i < ticket_response.result.account_objects.length; i++) {
|
||||
console.log(`Ticket ${i+1}: ${ticket_response.result.account_objects[i].TicketSequence}`)
|
||||
}
|
||||
// Prepare a multi-signed transaction that consumes the Ticket.
|
||||
// Omit LastLedgerSequence so the transaction does not expire while
|
||||
// signatures are being collected.
|
||||
const preparedTx = await client.autofill({
|
||||
TransactionType: 'AccountSet',
|
||||
Account: mainWallet.address,
|
||||
TicketSequence: useTicket,
|
||||
LastLedgerSequence: null,
|
||||
Sequence: 0
|
||||
}, 3) // signersCount for multi-sig fee calculation
|
||||
|
||||
// We'll use this ticket on our tx
|
||||
const ticket_1 = ticket_response.result.account_objects[0].TicketSequence
|
||||
|
||||
console.log(`\n Ticket sequence ${ticket_1} will be used for our multi-sig transaction`)
|
||||
|
||||
const Payment_tx = {
|
||||
"TransactionType": "AccountSet",
|
||||
"Account": main_wallet.address,
|
||||
"TicketSequence": ticket_1,
|
||||
"LastLedgerSequence": null,
|
||||
"Sequence": 0
|
||||
}
|
||||
// In a real workflow you would share preparedTx with each signer and
|
||||
// receive their signed blobs back; here we sign in one process for clarity.
|
||||
const { tx_blob: signedBlob1 } = signer1.sign(preparedTx, true)
|
||||
const { tx_blob: signedBlob2 } = signer2.sign(preparedTx, true)
|
||||
const { tx_blob: signedBlob3 } = signer3.sign(preparedTx, true)
|
||||
|
||||
const Payment_tx_prepared = await client.autofill(Payment_tx, signersCount=3)
|
||||
|
||||
// Each signer will sign the prepared tx (AccountSet_tx) and their signatures will be combines into 1 multi-sig transaction
|
||||
const { tx_blob: Payment_tx_signed_1 } = wallet_1.sign(Payment_tx_prepared, multisign=true)
|
||||
const { tx_blob: Payment_tx_signed_2 } = wallet_2.sign(Payment_tx_prepared, multisign=true)
|
||||
const { tx_blob: Payment_tx_signed_3 } = wallet_3.sign(Payment_tx_prepared, multisign=true)
|
||||
|
||||
console.log("\n All signers have signed the transaction with their corresponding keys")
|
||||
const multisignedBlob = xrpl.multisign([signedBlob1, signedBlob2, signedBlob3])
|
||||
console.log('Submitting multi-signed AccountSet...')
|
||||
const multisigResult = await client.submitAndWait(multisignedBlob)
|
||||
console.log(`Multi-sig hash: ${multisigResult.result.hash}, result: ${multisigResult.result.meta.TransactionResult}`)
|
||||
|
||||
// Combine 3 of the signers' signatures to form a multi-sig transaction
|
||||
const multisignedTx = xrpl.multisign([Payment_tx_signed_1, Payment_tx_signed_2, Payment_tx_signed_3])
|
||||
|
||||
const multisig_submit = await client.submitAndWait(multisignedTx)
|
||||
console.log("\n Multi-sig Submit result:", multisig_submit.result.meta.TransactionResult)
|
||||
console.log("\n Multi-sig Tx Binary:", multisignedTx)
|
||||
|
||||
client.disconnect()
|
||||
|
||||
// End main()
|
||||
}
|
||||
|
||||
main()
|
||||
// Disconnect when done (If you omit this, Node.js won't end the process)
|
||||
await client.disconnect()
|
||||
|
||||
@@ -1,76 +1,55 @@
|
||||
// Dependencies for Node.js.
|
||||
// In browsers, use a <script> tag instead.
|
||||
if (typeof module !== "undefined") {
|
||||
// Use var here because const/let are block-scoped to the if statement.
|
||||
var xrpl = require('xrpl')
|
||||
}
|
||||
import xrpl from 'xrpl'
|
||||
|
||||
// Example credentials
|
||||
const wallet = xrpl.Wallet.fromSeed("sn3nxiW7v8KXzPzAqzyHXbSSKNuN9")
|
||||
// Set up client and account
|
||||
const client = new xrpl.Client('wss://s.altnet.rippletest.net:51233')
|
||||
await client.connect()
|
||||
|
||||
// Connect to Devnet (since that's where tickets are available)
|
||||
async function main() {
|
||||
const client = new xrpl.Client("wss://s.devnet.rippletest.net:51233")
|
||||
await client.connect()
|
||||
// Fund wallet --------------------------------------------------------------
|
||||
console.log('Getting a wallet from the faucet...')
|
||||
const { wallet } = await client.fundWallet()
|
||||
console.log("Wallet address:", wallet.address)
|
||||
|
||||
// Get credentials from the Testnet Faucet -----------------------------------
|
||||
console.log("Getting a wallet from the faucet...")
|
||||
const {wallet, balance} = await client.fundWallet()
|
||||
// Create Tickets -----------------------------------------------------------
|
||||
console.log('\nSubmitting TicketCreate transaction...')
|
||||
const ticketCreateResult = await client.submitAndWait({
|
||||
TransactionType: 'TicketCreate',
|
||||
Account: wallet.address,
|
||||
TicketCount: 10
|
||||
}, { wallet, autofill: true })
|
||||
console.log(`TicketCreate hash: ${ticketCreateResult.result.hash}, validated: ${ticketCreateResult.result.validated}`)
|
||||
|
||||
// Check Sequence Number -----------------------------------------------------
|
||||
const account_info = await client.request({
|
||||
"command": "account_info",
|
||||
"account": wallet.address
|
||||
})
|
||||
let current_sequence = account_info.result.account_data.Sequence
|
||||
// Check Available Tickets --------------------------------------------------
|
||||
console.log('\nChecking available tickets...')
|
||||
const ticketsResponse = await client.request({
|
||||
command: 'account_objects',
|
||||
account: wallet.address,
|
||||
type: 'ticket'
|
||||
})
|
||||
const tickets = ticketsResponse.result.account_objects
|
||||
console.log(`Found ${tickets.length} Tickets`)
|
||||
|
||||
// Prepare and Sign TicketCreate ---------------------------------------------
|
||||
const prepared = await client.autofill({
|
||||
"TransactionType": "TicketCreate",
|
||||
"Account": wallet.address,
|
||||
"TicketCount": 10,
|
||||
"Sequence": current_sequence
|
||||
})
|
||||
const signed = wallet.sign(prepared)
|
||||
console.log(`Prepared TicketCreate transaction ${signed.hash}`)
|
||||
// Choose an arbitrary Ticket to use
|
||||
const useTicket = tickets[0].TicketSequence
|
||||
console.log(`Using Ticket Sequence: ${useTicket}`)
|
||||
|
||||
// Submit TicketCreate -------------------------------------------------------
|
||||
const tx = await client.submitAndWait(signed.tx_blob)
|
||||
console.log(tx)
|
||||
// Use a Ticket -------------------------------------------------------------
|
||||
console.log('\nSubmitting ticketed AccountSet transaction...')
|
||||
const ticketedResult = await client.submitAndWait({
|
||||
TransactionType: 'AccountSet',
|
||||
Account: wallet.address,
|
||||
TicketSequence: useTicket,
|
||||
Sequence: 0
|
||||
}, { wallet, autofill: true })
|
||||
console.log(`Ticketed AccountSet hash: ${ticketedResult.result.hash}, validated: ${ticketedResult.result.validated}`)
|
||||
|
||||
// Wait for Validation -------------------------------------------------------
|
||||
// submitAndWait() handles this automatically, but it can take 4-7s.
|
||||
// Recheck Available Tickets ------------------------------------------------
|
||||
console.log('\nRechecking available tickets...')
|
||||
const ticketsAfterResponse = await client.request({
|
||||
command: 'account_objects',
|
||||
account: wallet.address,
|
||||
type: 'ticket'
|
||||
})
|
||||
console.log(`Found ${ticketsAfterResponse.result.account_objects.length} Tickets`)
|
||||
|
||||
// Check Available Tickets ---------------------------------------------------
|
||||
let response = await client.request({
|
||||
"command": "account_objects",
|
||||
"account": wallet.address,
|
||||
"type": "ticket"
|
||||
})
|
||||
console.log("Available Tickets:", response.result.account_objects)
|
||||
|
||||
// Choose an arbitrary Ticket to use
|
||||
use_ticket = response.result.account_objects[0].TicketSequence
|
||||
|
||||
// Prepare and Sign Ticketed Transaction -------------------------------------
|
||||
const prepared_t = await client.autofill({
|
||||
"TransactionType": "AccountSet",
|
||||
"Account": wallet.address,
|
||||
"TicketSequence": use_ticket,
|
||||
"LastLedgerSequence": null, // Never expire this transaction.
|
||||
"Sequence": 0
|
||||
})
|
||||
const signed_t = wallet.sign(prepared_t)
|
||||
console.log(`Prepared ticketed transaction ${signed_t.hash}`)
|
||||
|
||||
// Submit Ticketed Transaction -----------------------------------------------
|
||||
const tx_t = await client.submitAndWait(signed_t.tx_blob)
|
||||
console.log(tx_t)
|
||||
|
||||
// Wait for Validation (again) -----------------------------------------------
|
||||
|
||||
// Disconnect when done (If you omit this, Node.js won't end the process)
|
||||
await client.disconnect()
|
||||
}
|
||||
|
||||
main()
|
||||
// Disconnect when done (If you omit this, Node.js won't end the process)
|
||||
await client.disconnect()
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
Demonstrates how to use Tickets for out-of-order transaction submission on the XRP Ledger.
|
||||
|
||||
For more context, see the [Use Tickets tutorial](https://xrpl.org/docs/tutorials/best-practices/transaction-sending/use-tickets).
|
||||
|
||||
## Setup
|
||||
|
||||
```sh
|
||||
|
||||
@@ -1,136 +1,72 @@
|
||||
from xrpl.models.transactions import TicketCreate, AccountSet, SignerListSet, SignerEntry
|
||||
from xrpl.transaction import sign_and_submit, autofill, multisign, sign
|
||||
from xrpl.models.requests.account_objects import AccountObjects, AccountObjectType
|
||||
from xrpl.models.requests.submit_multisigned import SubmitMultisigned
|
||||
from xrpl.wallet import generate_faucet_wallet
|
||||
from xrpl.clients import JsonRpcClient
|
||||
from xrpl.models.requests import AccountObjects, AccountObjectType
|
||||
from xrpl.models.transactions import AccountSet, SignerEntry, SignerListSet, TicketCreate
|
||||
from xrpl.transaction import autofill, multisign, sign, submit_and_wait
|
||||
from xrpl.wallet import Wallet, generate_faucet_wallet
|
||||
|
||||
# This code sample shows how to use tickets with multisigning
|
||||
# to allow you to do a series of transactions in any order while you wait
|
||||
# for signers to come back with their signatures.
|
||||
# https://xrpl.org/tickets.html#tickets
|
||||
# https://xrpl.org/use-tickets.html
|
||||
# https://xrpl.org/set-up-multi-signing.html#set-up-multi-signing
|
||||
# https://xrpl.org/send-a-multi-signed-transaction.html#send-a-multi-signed-transaction
|
||||
# Use Tickets with multi-signing: each Ticket holds a Sequence slot for a
|
||||
# transaction while you collect signatures from multiple signers.
|
||||
|
||||
# Note that this will only work with xrpl-py version v2.0.0-beta.0 or later
|
||||
|
||||
# Connect to a testnet node
|
||||
JSON_RPC_URL = "https://s.altnet.rippletest.net:51234/"
|
||||
client = JsonRpcClient(JSON_RPC_URL)
|
||||
|
||||
# Generate a wallet and request faucet
|
||||
test_wallet = generate_faucet_wallet(client=client)
|
||||
myAddr = test_wallet.address
|
||||
# Set up the main account and three signers.
|
||||
# Signer accounts only need cryptographically valid keys; the addresses
|
||||
# don't need to be funded or exist on the ledger.
|
||||
print("Funding main account from the faucet...")
|
||||
main_wallet = generate_faucet_wallet(client=client)
|
||||
signer_1 = Wallet.create()
|
||||
signer_2 = Wallet.create()
|
||||
signer_3 = Wallet.create()
|
||||
print(f"Main account: {main_wallet.address}")
|
||||
|
||||
print("Setting up all the signers' accounts via the testnet faucet, this may take a while...")
|
||||
signer_1_wallet = generate_faucet_wallet(client=client)
|
||||
signer_2_wallet = generate_faucet_wallet(client=client)
|
||||
signer_3_wallet = generate_faucet_wallet(client=client)
|
||||
|
||||
# Set the list of accounts that are able to authorize transactions on behalf of our Account via a multi-sig transaction
|
||||
signers = [
|
||||
SignerEntry(account=signer_1_wallet.address, signer_weight=1),
|
||||
SignerEntry(account=signer_2_wallet.address, signer_weight=1),
|
||||
SignerEntry(account=signer_3_wallet.address, signer_weight=1)
|
||||
]
|
||||
|
||||
# Display all the signers' account address
|
||||
print("\nSigners:")
|
||||
signer_int = 1
|
||||
for signer in signers:
|
||||
print(f"{signer_int}. {signer}")
|
||||
signer_int += 1
|
||||
|
||||
# A multi-sig transaction is achievable by trusting a list of keys to authorize transactions on behalf of the account
|
||||
# Construct a SignerList transaction
|
||||
tx_set_signer_list = SignerListSet(
|
||||
account=myAddr,
|
||||
signer_quorum=3,
|
||||
signer_entries=signers
|
||||
# Configure the signer list (quorum 2 of 3)
|
||||
print("Submitting SignerListSet...")
|
||||
signer_list_set = SignerListSet(
|
||||
account=main_wallet.address,
|
||||
signer_quorum=2,
|
||||
signer_entries=[
|
||||
SignerEntry(account=signer_1.address, signer_weight=1),
|
||||
SignerEntry(account=signer_2.address, signer_weight=1),
|
||||
SignerEntry(account=signer_3.address, signer_weight=1),
|
||||
],
|
||||
)
|
||||
signer_list_result = submit_and_wait(signer_list_set, client, main_wallet)
|
||||
print(f"SignerListSet hash: {signer_list_result.result['hash']}")
|
||||
|
||||
# We'll set the signer_quorum to 3, each key will represent 1 signer weight
|
||||
# if 3 of the signers sign a particular transaction, it's an authorized transaction on the XRPL
|
||||
# Create Tickets
|
||||
print("Submitting TicketCreate (3 Tickets)...")
|
||||
ticket_create = TicketCreate(account=main_wallet.address, ticket_count=3)
|
||||
ticket_create_result = submit_and_wait(ticket_create, client, main_wallet)
|
||||
print(f"TicketCreate hash: {ticket_create_result.result['hash']}")
|
||||
|
||||
# Sign transaction locally and submit
|
||||
print("Submitting a SignerListSet transaction to update our account to use our new Signers...")
|
||||
tx_set_signer_list_signed = sign_and_submit(transaction=tx_set_signer_list, client=client, wallet=test_wallet)
|
||||
|
||||
# Construct a TicketCreate transaction, 3 tickets will be created
|
||||
tx_create_ticket = TicketCreate(
|
||||
account=myAddr,
|
||||
ticket_count=len(signers)
|
||||
)
|
||||
|
||||
# Sign transaction locally and submit
|
||||
print("Submitting a TicketCreate transaction to get Ticket Sequences for future transactions...")
|
||||
tx_create_ticket_signed = sign_and_submit(transaction=tx_create_ticket, client=client, wallet=test_wallet)
|
||||
|
||||
# Get a Ticket Sequence
|
||||
get_ticket_sequence = client.request(AccountObjects(
|
||||
account=myAddr,
|
||||
type=AccountObjectType.TICKET
|
||||
# Pick a Ticket
|
||||
tickets_response = client.request(AccountObjects(
|
||||
account=main_wallet.address,
|
||||
type=AccountObjectType.TICKET,
|
||||
))
|
||||
use_ticket = tickets_response.result["account_objects"][0]["TicketSequence"]
|
||||
print(f"Using Ticket Sequence: {use_ticket}")
|
||||
|
||||
# Since we created 3 Tickets previously, you're able to choose which Ticket you're going to use
|
||||
ticket1_sequence = get_ticket_sequence.result["account_objects"][0]["TicketSequence"]
|
||||
ticket2_sequence = get_ticket_sequence.result["account_objects"][1]["TicketSequence"]
|
||||
ticket3_sequence = get_ticket_sequence.result["account_objects"][2]["TicketSequence"]
|
||||
|
||||
print(f"\nTickets issued:\n"
|
||||
f"Ticket 1: {ticket1_sequence}\n"
|
||||
f"Ticket 2: {ticket2_sequence}\n"
|
||||
f"Ticket 3: {ticket3_sequence}")
|
||||
|
||||
ticket_sequence = int(input("\nPick 1 ticket sequence to use for your next multi-sig transaction: "))
|
||||
|
||||
# Construct AccountSet Transaction using a Ticket
|
||||
tx_1 = AccountSet(
|
||||
account=myAddr,
|
||||
fee="1000",
|
||||
# Prepare a multi-signed transaction that consumes the Ticket.
|
||||
# Omit last_ledger_sequence so the transaction doesn't expire while
|
||||
# signatures are being collected.
|
||||
account_set = AccountSet(
|
||||
account=main_wallet.address,
|
||||
ticket_sequence=use_ticket,
|
||||
sequence=0,
|
||||
last_ledger_sequence=None,
|
||||
ticket_sequence=ticket_sequence
|
||||
)
|
||||
prepared_tx = autofill(account_set, client, signers_count=3)
|
||||
|
||||
autofilled_account_set_tx = autofill(tx_1, client, len(signers))
|
||||
# In a real workflow you would share prepared_tx with each signer and
|
||||
# receive their signed transactions back; here we sign in one process for clarity.
|
||||
signed_1 = sign(prepared_tx, signer_1, multisign=True)
|
||||
signed_2 = sign(prepared_tx, signer_2, multisign=True)
|
||||
signed_3 = sign(prepared_tx, signer_3, multisign=True)
|
||||
|
||||
# Sign 'tx_1' using all the keys on signers[]
|
||||
# In a real app, you would share this transaction with key holders for them to sign
|
||||
# but since we own these accounts for test purposes, we can sign directly here.
|
||||
tx_result_1 = sign(transaction=autofilled_account_set_tx, wallet=signer_1_wallet, multisign=True)
|
||||
tx_result_2 = sign(transaction=autofilled_account_set_tx, wallet=signer_2_wallet, multisign=True)
|
||||
tx_result_3 = sign(transaction=autofilled_account_set_tx, wallet=signer_3_wallet, multisign=True)
|
||||
|
||||
print(f"\nTx signature by account 1: {tx_result_1.signers}")
|
||||
print(f"Tx signature by account 2: {tx_result_2.signers}")
|
||||
print(f"Tx signature by account 3: {tx_result_3.signers}")
|
||||
|
||||
# Combine all the signed transactions from the provided signed txs into a multi-sig transaction
|
||||
tx_1_filled = multisign(
|
||||
transaction=autofilled_account_set_tx,
|
||||
tx_list=[
|
||||
tx_result_1,
|
||||
tx_result_2,
|
||||
tx_result_3
|
||||
]
|
||||
)
|
||||
|
||||
response = client.request(SubmitMultisigned(tx_json=tx_1_filled))
|
||||
result = response.result
|
||||
|
||||
print(f"\n Account Set tx result: {result['engine_result']}"
|
||||
f"\n Tx content: {result}\n")
|
||||
|
||||
if result['engine_result'] == "tesSUCCESS":
|
||||
print("Multi-sig transaction using a Ticket was successful!")
|
||||
elif result == "terPRE_TICKET":
|
||||
print(f"The provided Ticket Sequence {ticket_sequence} does not exist in the ledger")
|
||||
elif result == "tefMAX_LEDGER":
|
||||
print("Transaction failed to achieve consensus")
|
||||
elif result == "tefPAST_SEQ":
|
||||
print("The sequence number is lower than the current sequence number of the account")
|
||||
elif result == "unknown":
|
||||
print("Transaction status unknown")
|
||||
print(f"The transaction's engine_result was {result['engine_result']}")
|
||||
multisigned_tx = multisign(prepared_tx, [signed_1, signed_2, signed_3])
|
||||
print("Submitting multi-signed AccountSet...")
|
||||
multisig_result = submit_and_wait(multisigned_tx, client, autofill=False, check_fee=False)
|
||||
print(f"Multi-sig hash: {multisig_result.result['hash']}, "
|
||||
f"result: {multisig_result.result['meta']['TransactionResult']}")
|
||||
|
||||
@@ -1,66 +1,54 @@
|
||||
from xrpl.clients import JsonRpcClient
|
||||
from xrpl.models.transactions import TicketCreate, AccountSet
|
||||
from xrpl.transaction import sign_and_submit
|
||||
from xrpl.models.requests import AccountObjects, AccountObjectType
|
||||
from xrpl.models.transactions import AccountSet, TicketCreate
|
||||
from xrpl.transaction import submit_and_wait
|
||||
from xrpl.wallet import generate_faucet_wallet
|
||||
from xrpl.models.requests.account_objects import AccountObjects, AccountObjectType
|
||||
|
||||
# Connect to a testnet node
|
||||
# Set up client and account
|
||||
JSON_RPC_URL = "https://s.altnet.rippletest.net:51234/"
|
||||
client = JsonRpcClient(JSON_RPC_URL)
|
||||
|
||||
# Generate a wallet and request faucet
|
||||
test_wallet = generate_faucet_wallet(client=client)
|
||||
myAddr = test_wallet.address
|
||||
# Fund wallet
|
||||
print("Getting a wallet from the faucet...")
|
||||
wallet = generate_faucet_wallet(client=client)
|
||||
print(f"Wallet address: {wallet.address}")
|
||||
|
||||
# Construct a TicketCreate transaction, 2 ticket created for future use
|
||||
tx = TicketCreate(
|
||||
account=myAddr,
|
||||
ticket_count=2
|
||||
# Create Tickets
|
||||
ticket_create = TicketCreate(
|
||||
account=wallet.address,
|
||||
ticket_count=10,
|
||||
)
|
||||
print("\nSubmitting TicketCreate transaction...")
|
||||
ticket_create_result = submit_and_wait(ticket_create, client, wallet)
|
||||
print(f"TicketCreate hash: {ticket_create_result.result['hash']}, validated: {ticket_create_result.result['validated']}")
|
||||
|
||||
# Sign transaction locally and submit
|
||||
my_tx_payment_signed = sign_and_submit(transaction=tx, client=client, wallet=test_wallet)
|
||||
# Check Available Tickets
|
||||
print("\nChecking available tickets...")
|
||||
tickets_response = client.request(AccountObjects(
|
||||
account=wallet.address,
|
||||
type=AccountObjectType.TICKET,
|
||||
))
|
||||
tickets = tickets_response.result["account_objects"]
|
||||
print(f"Found {len(tickets)} Tickets")
|
||||
|
||||
# Get a Ticket Sequence
|
||||
get_ticket_sequence = AccountObjects(
|
||||
account=myAddr,
|
||||
type=AccountObjectType.TICKET
|
||||
)
|
||||
# Choose an arbitrary Ticket to use
|
||||
use_ticket = tickets[0]["TicketSequence"]
|
||||
print(f"Using Ticket Sequence: {use_ticket}")
|
||||
|
||||
response = client.request(get_ticket_sequence)
|
||||
|
||||
# Since we created 2 Tickets previously, you're able to choose which Ticket you're going to use
|
||||
ticket1_sequence = response.result["account_objects"][0]["TicketSequence"]
|
||||
ticket2_sequence = response.result["account_objects"][1]["TicketSequence"]
|
||||
|
||||
print(f"Ticket 1: {ticket1_sequence}\n"
|
||||
f"Ticket 2: {ticket2_sequence}")
|
||||
|
||||
ticket_sequence = int(input("Pick a ticket sequence to use for your next transaction: "))
|
||||
|
||||
# Construct Transaction using a Ticket
|
||||
tx_1 = AccountSet(
|
||||
account=myAddr,
|
||||
fee="10",
|
||||
# Use a Ticket
|
||||
ticketed_tx = AccountSet(
|
||||
account=wallet.address,
|
||||
ticket_sequence=use_ticket,
|
||||
sequence=0,
|
||||
last_ledger_sequence=None,
|
||||
ticket_sequence=ticket_sequence
|
||||
)
|
||||
print("\nSubmitting ticketed AccountSet transaction...")
|
||||
ticketed_result = submit_and_wait(ticketed_tx, client, wallet)
|
||||
print(f"Ticketed AccountSet hash: {ticketed_result.result['hash']}, validated: {ticketed_result.result['validated']}")
|
||||
|
||||
# Send transaction (w/ Ticket)
|
||||
tx_result = sign_and_submit(transaction=tx_1, client=client, wallet=test_wallet)
|
||||
result = tx_result.result["engine_result"]
|
||||
|
||||
print(f"Account: {myAddr}")
|
||||
if result == "tesSUCCESS":
|
||||
print("Transaction successful!")
|
||||
elif result == "terPRE_TICKET":
|
||||
print("The provided Ticket Sequence does not exist in the ledger")
|
||||
elif result == "tefMAX_LEDGER":
|
||||
print("Transaction failed to achieve consensus")
|
||||
elif result == "tefPAST_SEQ":
|
||||
print("The sequence number is lower than the current sequence number of the account")
|
||||
elif result == "unknown":
|
||||
print("Transaction status unknown")
|
||||
else:
|
||||
print(f"Transaction failed with code {result}")
|
||||
# Recheck Available Tickets
|
||||
print("\nRechecking available tickets...")
|
||||
tickets_after_response = client.request(AccountObjects(
|
||||
account=wallet.address,
|
||||
type=AccountObjectType.TICKET,
|
||||
))
|
||||
print(f"Found {len(tickets_after_response.result['account_objects'])} Tickets")
|
||||
|
||||
495
blog/2026/rippled-3.2.0-b7.md
Normal file
495
blog/2026/rippled-3.2.0-b7.md
Normal file
@@ -0,0 +1,495 @@
|
||||
---
|
||||
category: 2026
|
||||
date: "2026-05-27"
|
||||
template: '../../@theme/templates/blogpost'
|
||||
seo:
|
||||
title: Introducing XRP Ledger version 3.2.0-b7
|
||||
description: This beta release retires many old amendments, enables the fixCleanup3_2_0 amendment, and includes a wide range of refactors, bug fixes, and build improvements.
|
||||
labels:
|
||||
- rippled Release Notes
|
||||
markdown:
|
||||
editPage:
|
||||
hide: true
|
||||
---
|
||||
# Introducing XRP Ledger version 3.2.0-b7
|
||||
|
||||
Version 3.2.0-b7 of `rippled`, the reference server implementation of the XRP Ledger protocol, is now available. This beta release retires a large number of long-activated amendments and enables the `fixCleanup3_2_0` amendment, which bundles stabilization fixes. It also introduces sweeping refactors as part of the ongoing modularization and `rippled` → `xrpld` renaming effort, plus a broad set of bug fixes, build system improvements, and dependency updates.
|
||||
|
||||
|
||||
## Action Required
|
||||
|
||||
If you run an XRP Ledger server, upgrade to version 3.2.0-b7 as soon as possible to ensure service continuity.
|
||||
|
||||
|
||||
## Install / Upgrade
|
||||
|
||||
On supported platforms, see the [instructions on installing or updating `rippled`](../../docs/infrastructure/installation/index.md).
|
||||
|
||||
| Package | SHA-256 |
|
||||
|:--------|:--------|
|
||||
| [RPM for Red Hat / CentOS (x86-64)](https://repos.ripple.com/repos/rippled-rpm/stable/rippled-3.2.0-b7-1.el9.x86_64.rpm) | `TODO` |
|
||||
| [DEB for Ubuntu / Debian (x86-64)](https://repos.ripple.com/repos/rippled-deb/pool/stable/rippled_3.2.0-b7-1_amd64.deb) | `TODO` |
|
||||
|
||||
For other platforms, please [build from source](https://github.com/XRPLF/rippled/blob/master/BUILD.md). The most recent commit in the git log should be the change setting the version:
|
||||
|
||||
```text
|
||||
commit dfb9b8ed9a0ad04c1da00c9957fe3c7454930835
|
||||
Author: Bart <bthomee@users.noreply.github.com>
|
||||
Date: Fri May 22 20:32:12 2026 +0100
|
||||
|
||||
release: Bump version to 3.2.0-b7 (#7316)
|
||||
```
|
||||
|
||||
|
||||
## Full Changelog
|
||||
|
||||
|
||||
### Amendments
|
||||
|
||||
- **CheckCashMakesTrustLine**: Retires the amendment, which has been activated for more than two years. ([#5974](https://github.com/XRPLF/rippled/pull/5974))
|
||||
- **Checks**: Retires the amendment, which has been activated for more than two years. ([#6055](https://github.com/XRPLF/rippled/pull/6055))
|
||||
- **CryptoConditionsSuite**: Retires the amendment, which has been activated for more than two years. ([#6036](https://github.com/XRPLF/rippled/pull/6036))
|
||||
- **DeletableAccounts**: Retires the amendment, which has been activated for more than two years. ([#6056](https://github.com/XRPLF/rippled/pull/6056))
|
||||
- **DepositAuth**, **DepositPreauth**: Retires both amendments, which have been activated for more than two years. ([#5978](https://github.com/XRPLF/rippled/pull/5978))
|
||||
- **DisallowIncoming**: Retires the amendment, which has been activated for more than two years. ([#6045](https://github.com/XRPLF/rippled/pull/6045))
|
||||
- **ExpandedSignerList**, **MultiSignReserve**: Retires both amendments, which have been activated for more than two years. ([#5981](https://github.com/XRPLF/rippled/pull/5981))
|
||||
- **fix1513**: Retires the amendment, which has been activated for more than two years. ([#5919](https://github.com/XRPLF/rippled/pull/5919))
|
||||
- **fix1515**: Retires the amendment, which has been activated for more than two years. ([#5920](https://github.com/XRPLF/rippled/pull/5920))
|
||||
- **fix1543**: Retires the amendment, which has been activated for more than two years. ([#5926](https://github.com/XRPLF/rippled/pull/5926))
|
||||
- **fix1571**: Retires the amendment, which has been activated for more than two years. ([#5925](https://github.com/XRPLF/rippled/pull/5925))
|
||||
- **fix1578**: Retires the amendment, which has been activated for more than two years. ([#5927](https://github.com/XRPLF/rippled/pull/5927))
|
||||
- **fix1623**: Retires the amendment, which has been activated for more than two years. ([#5928](https://github.com/XRPLF/rippled/pull/5928))
|
||||
- **fix1781**: Retires the amendment, which has been activated for more than two years. ([#5931](https://github.com/XRPLF/rippled/pull/5931))
|
||||
- **fixAmendmentMajorityCalc**: Retires the amendment, which has been activated for more than two years. ([#5961](https://github.com/XRPLF/rippled/pull/5961))
|
||||
- **fixCheckThreading**: Retires the amendment, which has been activated for more than two years. ([#5957](https://github.com/XRPLF/rippled/pull/5957))
|
||||
- **fixMasterKeyAsRegularKey**: Retires the amendment, which has been activated for more than two years. ([#5959](https://github.com/XRPLF/rippled/pull/5959))
|
||||
- **fixPayChanRecipientOwnerDir**: Retires the amendment, which has been activated for more than two years. ([#5946](https://github.com/XRPLF/rippled/pull/5946))
|
||||
- **fixQualityUpperBound**: Retires the amendment, which has been activated for more than two years. ([#5960](https://github.com/XRPLF/rippled/pull/5960))
|
||||
- **fixReducedOffersV1**: Retires the amendment, which has been activated for more than two years. ([#5972](https://github.com/XRPLF/rippled/pull/5972))
|
||||
- **fixRmSmallIncreasedQOffers**: Retires the amendment, which has been activated for more than two years. ([#5955](https://github.com/XRPLF/rippled/pull/5955))
|
||||
- **fixSTAmountCanonicalize**: Retires the amendment, which has been activated for more than two years. ([#5956](https://github.com/XRPLF/rippled/pull/5956))
|
||||
- **fixTakerDryOfferRemoval**: Retires the amendment, which has been activated for more than two years. ([#5958](https://github.com/XRPLF/rippled/pull/5958))
|
||||
- **fixTrustLinesToSelf**: Retires the amendment, which has been activated for more than two years. ([#5989](https://github.com/XRPLF/rippled/pull/5989))
|
||||
- **Flow**, **FlowSortStrands**: Retires both amendments, which have been activated for more than two years. ([#6054](https://github.com/XRPLF/rippled/pull/6054))
|
||||
- **HardenedValidations**: Retires the amendment, which has been activated for more than two years. ([#5988](https://github.com/XRPLF/rippled/pull/5988))
|
||||
- **ImmediateOfferKilled**: Retires the amendment, which has been activated for more than two years. ([#5973](https://github.com/XRPLF/rippled/pull/5973))
|
||||
- **NegativeUNL**: Retires the amendment, which has been activated for more than two years. ([#6033](https://github.com/XRPLF/rippled/pull/6033))
|
||||
- **NonFungibleTokensV1**, **NonFungibleTokensV1_1**, **fixNFTokenDirV1**, **fixNFTokenNegOffer**, **fixNFTokenRemint**, **fixNonFungibleTokensV1_2**: Retires the older NFT amendments, all activated for more than two years. ([#5971](https://github.com/XRPLF/rippled/pull/5971))
|
||||
- **RequireFullyCanonicalSig**: Retires the amendment, which has been activated for more than two years. ([#6035](https://github.com/XRPLF/rippled/pull/6035))
|
||||
- **TicketBatch**: Retires the amendment, which has been activated for more than two years. ([#6032](https://github.com/XRPLF/rippled/pull/6032))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
- Installed validator-keys as a CMake install target. ([#5841](https://github.com/XRPLF/rippled/pull/5841))
|
||||
- Added configurable NuDB block size feature. ([#5468](https://github.com/XRPLF/rippled/pull/5468))
|
||||
- Logged public key in addition to IP address. ([#5678](https://github.com/XRPLF/rippled/pull/5678))
|
||||
- Added `ledger_entry` options for fee, amendments, NUNL, and hashes. ([#5644](https://github.com/XRPLF/rippled/pull/5644))
|
||||
- Enforced feature name lengths and character set. ([#5555](https://github.com/XRPLF/rippled/pull/5555))
|
||||
- Added Formats and Flags to `server_definitions`. ([#6321](https://github.com/XRPLF/rippled/pull/6321))
|
||||
- Added a code generator for transactions and ledger entries. ([#6443](https://github.com/XRPLF/rippled/pull/6443))
|
||||
- Added a mutex wrapper from Clio. ([#6447](https://github.com/XRPLF/rippled/pull/6447))
|
||||
- Added GRPC TLS support. ([#6374](https://github.com/XRPLF/rippled/pull/6374))
|
||||
- Added `--definitions` flag and artifact. ([#6858](https://github.com/XRPLF/rippled/pull/6858))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Fixed the `xrpld` symlink that was renamed incorrectly. ([#6012](https://github.com/XRPLF/rippled/pull/6012))
|
||||
- Removed cryptographic libs from libxrpl Conan package. ([#6163](https://github.com/XRPLF/rippled/pull/6163))
|
||||
- Incremented sequence when accepting new manifests. ([#6059](https://github.com/XRPLF/rippled/pull/6059))
|
||||
- Stopped the embedded tests hanging forever on ARM by fixing the memory ordering issue. ([#6248](https://github.com/XRPLF/rippled/pull/6248))
|
||||
- Restored config changes that broke standalone mode. ([#6301](https://github.com/XRPLF/rippled/pull/6301))
|
||||
- Removed unneeded import and fixed log statement. ([#6532](https://github.com/XRPLF/rippled/pull/6532))
|
||||
- Marked SAV and Lending transactions as `NotDelegable`. ([#6489](https://github.com/XRPLF/rippled/pull/6489))
|
||||
- Removed a newline from logging statement in `changeSpotPrice` calculation. ([#6547](https://github.com/XRPLF/rippled/pull/6547))
|
||||
- Fixed memory leaks in HTTPClient. ([#6370](https://github.com/XRPLF/rippled/pull/6370))
|
||||
- Switched to `boost::coroutine2`. ([#6372](https://github.com/XRPLF/rippled/pull/6372))
|
||||
- Removed nonexistent `boost::coroutine2` library reference. ([#6561](https://github.com/XRPLF/rippled/pull/6561))
|
||||
- Disallowed empty permission list when Delegate object is absent. ([#6542](https://github.com/XRPLF/rippled/pull/6542))
|
||||
- Removed superfluous view update from credentials. ([#6545](https://github.com/XRPLF/rippled/pull/6545))
|
||||
- Decoupled reserve from fee in delegate payment. ([#6568](https://github.com/XRPLF/rippled/pull/6568))
|
||||
- Backported Permissioned Domains fixes. ([#7016](https://github.com/XRPLF/rippled/pull/7016))
|
||||
- Used account ledger entry when canceling token escrows. ([#6171](https://github.com/XRPLF/rippled/pull/6171))
|
||||
- Changed variable signedness and correctly handled `std::optional`. ([#6657](https://github.com/XRPLF/rippled/pull/6657))
|
||||
- Applied minor RPC fixes. ([#6730](https://github.com/XRPLF/rippled/pull/6730))
|
||||
- Handled WSClient write failure when server closes WebSocket. ([#6671](https://github.com/XRPLF/rippled/pull/6671))
|
||||
- Added description for `terLOCKED` error. ([#6811](https://github.com/XRPLF/rippled/pull/6811))
|
||||
- Changed AMMClawback return code to `tecNO_PERMISSION` on AllowTrustLineClawback and NoFreeze check. ([#6946](https://github.com/XRPLF/rippled/pull/6946))
|
||||
- Disallowed MPTClearRequireAuth if a domain is set. ([#6712](https://github.com/XRPLF/rippled/pull/6712))
|
||||
- Made assorted Payments fixes. ([#6585](https://github.com/XRPLF/rippled/pull/6585))
|
||||
- Made assorted RPC fixes. ([#6529](https://github.com/XRPLF/rippled/pull/6529))
|
||||
- Fixed `Workers::stop()` race between `m_allPaused` and `m_runningTaskCount`. ([#6574](https://github.com/XRPLF/rippled/pull/6574))
|
||||
- Fixed previous ledger size typo in RCLConsensus. ([#6696](https://github.com/XRPLF/rippled/pull/6696))
|
||||
- Guarded `Coro::resume()` against completed coroutines. ([#6608](https://github.com/XRPLF/rippled/pull/6608))
|
||||
- Fixed ubsan flagged issues. ([#6151](https://github.com/XRPLF/rippled/pull/6151))
|
||||
- Numerically-stable `(1+r)^n-1` in `computePaymentFactor`. ([#7033](https://github.com/XRPLF/rippled/pull/7033))
|
||||
- Prevented stale AuthAccounts from persisting after `tfTwoAssetIfEmpty` re-initialization. ([#6996](https://github.com/XRPLF/rippled/pull/6996))
|
||||
- Fixed regressions in `server_definitions`. ([#7008](https://github.com/XRPLF/rippled/pull/7008))
|
||||
- Set default peering port to 2459. ([#6848](https://github.com/XRPLF/rippled/pull/6848))
|
||||
- Fixed multisign and signfor to check for delegate. ([#7064](https://github.com/XRPLF/rippled/pull/7064))
|
||||
- Added a missing null check after `txRead()` in `iteratePriceData()`. ([#7305](https://github.com/XRPLF/rippled/pull/7305))
|
||||
- Reverted graceful peer disconnection and follow-up fix. ([#7296](https://github.com/XRPLF/rippled/pull/7296))
|
||||
- Added assorted MPT/DEX fixes. ([#7040](https://github.com/XRPLF/rippled/pull/7040))
|
||||
- Checked if the MPT first loss cover can be sent to the broker before deleting the broker. ([#7125](https://github.com/XRPLF/rippled/pull/7125))
|
||||
- Stored `Delegate` object in delegating and authorized account directories for proper deletion. ([#6681](https://github.com/XRPLF/rippled/pull/6681))
|
||||
|
||||
|
||||
### Refactors
|
||||
|
||||
- Replaced `fee().accountReserve(0)` with `fee().reserve`. ([#5843](https://github.com/XRPLF/rippled/pull/5843))
|
||||
- Refactored signature autofilling for Simulate RPC. ([#5852](https://github.com/XRPLF/rippled/pull/5852))
|
||||
- Moved `server_definitions` code to its own files. ([#5890](https://github.com/XRPLF/rippled/pull/5890))
|
||||
- Cleaned up `TxMeta`. ([#5845](https://github.com/XRPLF/rippled/pull/5845))
|
||||
- Modularised shamap and nodestore. ([#5668](https://github.com/XRPLF/rippled/pull/5668))
|
||||
- Moved API functions from `RPCHelpers.h` to `ApiVersion.h`. ([#5889](https://github.com/XRPLF/rippled/pull/5889))
|
||||
- Renamed `RIPPLE_` and `RIPPLED_` definitions to `XRPL_`. ([#5821](https://github.com/XRPLF/rippled/pull/5821))
|
||||
- Removed unnecessary copyright notices already covered by LICENSE.md. ([#5929](https://github.com/XRPLF/rippled/pull/5929))
|
||||
- Renamed cmake files and definitions. ([#5975](https://github.com/XRPLF/rippled/pull/5975))
|
||||
- Split up `RPCHelpers.h` into two. ([#6047](https://github.com/XRPLF/rippled/pull/6047))
|
||||
- Cleaned up `RPCHelpers`. ([#5684](https://github.com/XRPLF/rippled/pull/5684))
|
||||
- Renamed `LedgerInfo` to `LedgerHeader`. ([#6136](https://github.com/XRPLF/rippled/pull/6136))
|
||||
- Renamed `info()` to `header()`. ([#6138](https://github.com/XRPLF/rippled/pull/6138))
|
||||
- Renamed `rippled` binary to `xrpld`. ([#5983](https://github.com/XRPLF/rippled/pull/5983))
|
||||
- Moved JobQueue and related classes into xrpl.core module. ([#6121](https://github.com/XRPLF/rippled/pull/6121))
|
||||
- Renamed `ripple` namespace to `xrpl`. ([#5982](https://github.com/XRPLF/rippled/pull/5982))
|
||||
- Removed `Json::Object` and related files/classes. ([#5894](https://github.com/XRPLF/rippled/pull/5894))
|
||||
- Renamed `rippled.cfg` to `xrpld.cfg`. ([#6098](https://github.com/XRPLF/rippled/pull/6098))
|
||||
- Fixed typos in comments and set up cspell. ([#6164](https://github.com/XRPLF/rippled/pull/6164))
|
||||
- Fixed spelling issues in private/local variables and functions. ([#6182](https://github.com/XRPLF/rippled/pull/6182))
|
||||
- Fixed spelling issues in all variables/functions. ([#6184](https://github.com/XRPLF/rippled/pull/6184))
|
||||
- Removed unused credential signature hash prefix. ([#6186](https://github.com/XRPLF/rippled/pull/6186))
|
||||
- Fixed lots of typos and added cspell settings. ([#5719](https://github.com/XRPLF/rippled/pull/5719))
|
||||
- Cleaned up uses of `std::source_location`. ([#6272](https://github.com/XRPLF/rippled/pull/6272))
|
||||
- Updated Boost to 1.90. ([#6280](https://github.com/XRPLF/rippled/pull/6280))
|
||||
- Added ServiceRegistry to help migration. ([#6222](https://github.com/XRPLF/rippled/pull/6222))
|
||||
- Replaced include guards with `#pragma once`. ([#6322](https://github.com/XRPLF/rippled/pull/6322))
|
||||
- Removed unnecessary caches. ([#5439](https://github.com/XRPLF/rippled/pull/5439))
|
||||
- Followed up on threads renaming. ([#6336](https://github.com/XRPLF/rippled/pull/6336))
|
||||
- Modularised WalletDB and Manifest. ([#6223](https://github.com/XRPLF/rippled/pull/6223))
|
||||
- Modularised RelationalDB. ([#6224](https://github.com/XRPLF/rippled/pull/6224))
|
||||
- Modularised the NetworkOPs interface. ([#6225](https://github.com/XRPLF/rippled/pull/6225))
|
||||
- Modularised HashRouter, Conditions, and OrderBookDB. ([#6226](https://github.com/XRPLF/rippled/pull/6226))
|
||||
- Decoupled app/tx from Application and Config. ([#6227](https://github.com/XRPLF/rippled/pull/6227))
|
||||
- Modularised app/tx. ([#6228](https://github.com/XRPLF/rippled/pull/6228))
|
||||
- Explicitly trimmed the heap after cache sweeps. ([#6022](https://github.com/XRPLF/rippled/pull/6022))
|
||||
- Used `uint256` directly as key instead of void pointer. ([#6313](https://github.com/XRPLF/rippled/pull/6313))
|
||||
- Broke down InvariantCheck to multiple classes. ([#6440](https://github.com/XRPLF/rippled/pull/6440))
|
||||
- Fixed clang-tidy `bugprone-empty-catch` check. ([#6419](https://github.com/XRPLF/rippled/pull/6419))
|
||||
- Added Git information compile-time info to only one file. ([#6464](https://github.com/XRPLF/rippled/pull/6464))
|
||||
- Updated transaction folder structure. ([#6483](https://github.com/XRPLF/rippled/pull/6483))
|
||||
- Split combined transactor files into individual classes. ([#6495](https://github.com/XRPLF/rippled/pull/6495))
|
||||
- Removed dead code in `CreateOffer`. ([#6541](https://github.com/XRPLF/rippled/pull/6541))
|
||||
- Fixed typo in `freezeHandling` parameter name. ([#6543](https://github.com/XRPLF/rippled/pull/6543))
|
||||
- Simplified set/get call to use existing variable. ([#6534](https://github.com/XRPLF/rippled/pull/6534))
|
||||
- Deleted SecretKey compare op from library and moved it to tests module. ([#6503](https://github.com/XRPLF/rippled/pull/6503))
|
||||
- Used `hasExpired` in `CancelCheck`. ([#6533](https://github.com/XRPLF/rippled/pull/6533))
|
||||
- Renamed system name from 'ripple' to 'xrpld'. ([#6347](https://github.com/XRPLF/rippled/pull/6347))
|
||||
- Added no-ASAN macro for Throw statements. ([#6373](https://github.com/XRPLF/rippled/pull/6373))
|
||||
- Cleaned up `getFeePayer`, `mSourceBalance`, and `mPriorBalance`. ([#6478](https://github.com/XRPLF/rippled/pull/6478))
|
||||
- Applied assorted small DID fixes. ([#6552](https://github.com/XRPLF/rippled/pull/6552))
|
||||
- Removed dead code in escrow helper logic. ([#6553](https://github.com/XRPLF/rippled/pull/6553))
|
||||
- Added const qualifier to SLE in `verifyDepositPreauth` parameter. ([#6555](https://github.com/XRPLF/rippled/pull/6555))
|
||||
- Used ReadView instead of ApplyView in `authorizedDepositPreauth()`. ([#6560](https://github.com/XRPLF/rippled/pull/6560))
|
||||
- Replaced `!=`/`==` `tesSuccess` with `isTesSuccess`. ([#6409](https://github.com/XRPLF/rippled/pull/6409))
|
||||
- Renamed transactor files/classes to match the tx name. ([#6580](https://github.com/XRPLF/rippled/pull/6580))
|
||||
- Addressed remaining issue after clang-tidy merge. ([#6582](https://github.com/XRPLF/rippled/pull/6582))
|
||||
- Moved ledger entry helper functions from `View.h`/`View.cpp` to dedicated helper files. ([#6453](https://github.com/XRPLF/rippled/pull/6453))
|
||||
- Improved imports to only call the needed helpers. ([#6624](https://github.com/XRPLF/rippled/pull/6624))
|
||||
- Fixed more clang-tidy issues found after merging to develop. ([#6640](https://github.com/XRPLF/rippled/pull/6640))
|
||||
- Removed unused/unreachable `transactor` code. ([#6612](https://github.com/XRPLF/rippled/pull/6612))
|
||||
- Modularised ledger. ([#6536](https://github.com/XRPLF/rippled/pull/6536))
|
||||
- Made function naming in ServiceRegistry consistent. ([#6390](https://github.com/XRPLF/rippled/pull/6390))
|
||||
- Split LoanInvariant into LoanBrokerInvariant and LoanInvariant. ([#6674](https://github.com/XRPLF/rippled/pull/6674))
|
||||
- Addressed PR comments after the modularisation PRs. ([#6389](https://github.com/XRPLF/rippled/pull/6389))
|
||||
- Reorganized RPC handler files. ([#6628](https://github.com/XRPLF/rippled/pull/6628))
|
||||
- Moved more helper files into `libxrpl/ledger/helpers`. ([#6731](https://github.com/XRPLF/rippled/pull/6731))
|
||||
- Renamed non-functional uses of `ripple(d)` to `xrpl(d)`. ([#6676](https://github.com/XRPLF/rippled/pull/6676))
|
||||
- Combined `AMMHelpers` and `AMMUtils`. ([#6733](https://github.com/XRPLF/rippled/pull/6733))
|
||||
- Removed unused `notTooManyOffers` function from NFTokenUtils. ([#6737](https://github.com/XRPLF/rippled/pull/6737))
|
||||
- Removed empty `Taker.h`. ([#6984](https://github.com/XRPLF/rippled/pull/6984))
|
||||
- Added transaction-specific invariant checking. ([#6551](https://github.com/XRPLF/rippled/pull/6551))
|
||||
- Fixed more clang-tidy issues. ([#6992](https://github.com/XRPLF/rippled/pull/6992))
|
||||
- Removed seq from TMGetObjectByHash. ([#6976](https://github.com/XRPLF/rippled/pull/6976))
|
||||
- Resolved remaining clang-tidy unchecked optionals. ([#6979](https://github.com/XRPLF/rippled/pull/6979))
|
||||
- Cleaned up NetworkOPs. ([#6575](https://github.com/XRPLF/rippled/pull/6575))
|
||||
- Addressed code review comments regarding `boost::coroutine2`. ([#6977](https://github.com/XRPLF/rippled/pull/6977))
|
||||
- Reverted certain `Throw`s by `LogicError`s. ([#7036](https://github.com/XRPLF/rippled/pull/7036))
|
||||
- Added IWYU pragma for `boost::optional` to fix clang-tidy. ([#7088](https://github.com/XRPLF/rippled/pull/7088))
|
||||
- Applied more fixes for bad renames. ([#7092](https://github.com/XRPLF/rippled/pull/7092))
|
||||
- Used more scoped enums. ([#7086](https://github.com/XRPLF/rippled/pull/7086))
|
||||
- Used `isFlag` where possible instead of bitwise math. ([#7278](https://github.com/XRPLF/rippled/pull/7278))
|
||||
- Renamed static constants. ([#7120](https://github.com/XRPLF/rippled/pull/7120))
|
||||
- Cleaned up comments post-clang-tidy changes. ([#7283](https://github.com/XRPLF/rippled/pull/7283))
|
||||
- Renamed `account_` to `accountID_`. ([#7284](https://github.com/XRPLF/rippled/pull/7284))
|
||||
- Fixed `sfGeneric` and `sfInvalid` field names. ([#7300](https://github.com/XRPLF/rippled/pull/7300))
|
||||
- Removed dead `fetchBatch` code. ([#7309](https://github.com/XRPLF/rippled/pull/7309))
|
||||
- Updated default values of base and owner reserve to 1/0.2. ([#6382](https://github.com/XRPLF/rippled/pull/6382))
|
||||
- Sorted retired amendments to reduce conflicts. ([#5966](https://github.com/XRPLF/rippled/pull/5966))
|
||||
- Added `XRPL_RETIRE_FIX` and `XRPL_RETIRE_FEATURE`. ([#6014](https://github.com/XRPLF/rippled/pull/6014))
|
||||
- Removed unnecessary clang-format off/on directives. ([#6682](https://github.com/XRPLF/rippled/pull/6682))
|
||||
|
||||
|
||||
### Documentation
|
||||
|
||||
- Cleaned up misleading comments. ([#6031](https://github.com/XRPLF/rippled/pull/6031))
|
||||
- Updated instructions on how to (re)generate the `conan.lock` file. ([#6070](https://github.com/XRPLF/rippled/pull/6070))
|
||||
- Added XLS requirements to `CONTRIBUTING.md`. ([#6065](https://github.com/XRPLF/rippled/pull/6065))
|
||||
- Inferred version of patched Conan dependency to export. ([#6112](https://github.com/XRPLF/rippled/pull/6112))
|
||||
- Fixed docs README and cmake. ([#6122](https://github.com/XRPLF/rippled/pull/6122))
|
||||
- Fixed some minor issues in the comments. ([#6194](https://github.com/XRPLF/rippled/pull/6194))
|
||||
- Updated Ripple Bug Bounty public key. ([#6258](https://github.com/XRPLF/rippled/pull/6258))
|
||||
- Updated API changelog and added APIv2+APIv3 version documentation. ([#6308](https://github.com/XRPLF/rippled/pull/6308))
|
||||
- Fixed more minor issues in the comments. ([#6346](https://github.com/XRPLF/rippled/pull/6346))
|
||||
- Improved documentation for InvariantCheck. ([#6518](https://github.com/XRPLF/rippled/pull/6518))
|
||||
- Fixed minor issues in the comments. ([#6535](https://github.com/XRPLF/rippled/pull/6535))
|
||||
- Added a comment explaining why `ammLPHolds` is called twice. ([#6546](https://github.com/XRPLF/rippled/pull/6546))
|
||||
- Added a note about `clang-tidy` installation. ([#6634](https://github.com/XRPLF/rippled/pull/6634))
|
||||
- Updated LICENSE.md year to present. ([#6636](https://github.com/XRPLF/rippled/pull/6636))
|
||||
- Rewrote conan docs for custom recipes. ([#6647](https://github.com/XRPLF/rippled/pull/6647))
|
||||
- Marked empty transactor invariants as future work. ([#7080](https://github.com/XRPLF/rippled/pull/7080))
|
||||
- Updated bug bounty information. ([#7006](https://github.com/XRPLF/rippled/pull/7006))
|
||||
- Updated hybrid offer invariant comment. ([#7007](https://github.com/XRPLF/rippled/pull/7007))
|
||||
- Added explanatory comment to checkFee. ([#6631](https://github.com/XRPLF/rippled/pull/6631))
|
||||
- Removed repetitive word in multiple files. ([#6978](https://github.com/XRPLF/rippled/pull/6978))
|
||||
- Fixed some comments to improve readability. ([#7122](https://github.com/XRPLF/rippled/pull/7122))
|
||||
- Added `--parallel` flag to cmake build commands in `BUILD.md`. ([#7302](https://github.com/XRPLF/rippled/pull/7302))
|
||||
|
||||
|
||||
### Testing
|
||||
|
||||
- Added more tests for `ledger_entry` RPC. ([#5858](https://github.com/XRPLF/rippled/pull/5858))
|
||||
- Removed `failed` string from vault test. ([#6214](https://github.com/XRPLF/rippled/pull/6214))
|
||||
- Suppressed "parse failed" message in Batch tests. ([#6207](https://github.com/XRPLF/rippled/pull/6207))
|
||||
- Fixed the `xrpl.net` unit test. ([#6241](https://github.com/XRPLF/rippled/pull/6241))
|
||||
- Fixed typo in LendingHelpers unit-test. ([#6215](https://github.com/XRPLF/rippled/pull/6215))
|
||||
- Added file/line to `Env`. ([#6276](https://github.com/XRPLF/rippled/pull/6276))
|
||||
- Fixed spelling issues in tests. ([#6199](https://github.com/XRPLF/rippled/pull/6199))
|
||||
- Improved stability of Subscribe tests. ([#6420](https://github.com/XRPLF/rippled/pull/6420))
|
||||
- Fixed flaky subscribe tests. ([#6510](https://github.com/XRPLF/rippled/pull/6510))
|
||||
- Removed testline JTX helper class. ([#6539](https://github.com/XRPLF/rippled/pull/6539))
|
||||
- Fixed tests for clang-tidy `bugprone-unchecked-optional-access` check. ([#6502](https://github.com/XRPLF/rippled/pull/6502))
|
||||
- Created new transaction testing framework `TxTest`. ([#6537](https://github.com/XRPLF/rippled/pull/6537))
|
||||
- Fixed flaky CI tests. ([#7005](https://github.com/XRPLF/rippled/pull/7005))
|
||||
|
||||
|
||||
### CI/Build
|
||||
|
||||
- Updated Conan dependencies: OpenSSL. ([#5873](https://github.com/XRPLF/rippled/pull/5873))
|
||||
- Downgraded OpenSSL to 3.5.4. ([#5878](https://github.com/XRPLF/rippled/pull/5878))
|
||||
- Removed version number in `find_dependency` for OpenSSL. ([#5985](https://github.com/XRPLF/rippled/pull/5985))
|
||||
- Removed unnecessary creation of symlink in CMake install file. ([#6009](https://github.com/XRPLF/rippled/pull/6009))
|
||||
- Updated RocksDB, SQLite, Doctest. ([#6015](https://github.com/XRPLF/rippled/pull/6015))
|
||||
- Set version on develop to 3.1.0-b0. ([#5986](https://github.com/XRPLF/rippled/pull/5986))
|
||||
- Updated nudb recipe to remove linker warnings. ([#6038](https://github.com/XRPLF/rippled/pull/6038))
|
||||
- Updated lockfile. ([#6083](https://github.com/XRPLF/rippled/pull/6083))
|
||||
- Made conan generate script a script. ([#6085](https://github.com/XRPLF/rippled/pull/6085))
|
||||
- Added black pre-commit hook. ([#6086](https://github.com/XRPLF/rippled/pull/6086))
|
||||
- Replaced `ed25519-donna` source with Conan package. ([#6088](https://github.com/XRPLF/rippled/pull/6088))
|
||||
- Replaced `secp256k1` source with Conan package. ([#6089](https://github.com/XRPLF/rippled/pull/6089))
|
||||
- Re-enabled linux and macos matrix. ([#6107](https://github.com/XRPLF/rippled/pull/6107))
|
||||
- Updated Conan dependencies: protobuf and grpc. ([#5589](https://github.com/XRPLF/rippled/pull/5589))
|
||||
- Used updated secp256k1 recipe. ([#6118](https://github.com/XRPLF/rippled/pull/6118))
|
||||
- Cleaned up `.gitignore` and `.gitattributes`. ([#6001](https://github.com/XRPLF/rippled/pull/6001))
|
||||
- Updated shared actions. ([#6147](https://github.com/XRPLF/rippled/pull/6147))
|
||||
- Removed superfluous build directory creation. ([#6159](https://github.com/XRPLF/rippled/pull/6159))
|
||||
- Pinned `ruamel.yaml<0.19` in pre-commit-hooks. ([#6166](https://github.com/XRPLF/rippled/pull/6166))
|
||||
- Used ccache to cache build objects for speeding up building. ([#6104](https://github.com/XRPLF/rippled/pull/6104))
|
||||
- Moved variable into right place. ([#6179](https://github.com/XRPLF/rippled/pull/6179))
|
||||
- Used updated XRPLF workflow and action. ([#6188](https://github.com/XRPLF/rippled/pull/6188))
|
||||
- Changed `/Zi` to `/Z7` for ccache and removed debug symbols in CI. ([#6198](https://github.com/XRPLF/rippled/pull/6198))
|
||||
- Pinned pre-commit hooks to commit hashes. ([#6205](https://github.com/XRPLF/rippled/pull/6205))
|
||||
- Removed unnecessary version number and options in cmake `find_package`. ([#6169](https://github.com/XRPLF/rippled/pull/6169))
|
||||
- Updated actions/images to use cmake 4.2.1 and conan 2.24.0. ([#6209](https://github.com/XRPLF/rippled/pull/6209))
|
||||
- Updated Conan lock file with changed OpenSSL recipe. ([#6211](https://github.com/XRPLF/rippled/pull/6211))
|
||||
- Used gtest instead of doctest. ([#6216](https://github.com/XRPLF/rippled/pull/6216))
|
||||
- Added sanitizers to CI builds. ([#5996](https://github.com/XRPLF/rippled/pull/5996))
|
||||
- Removed 'master' branch as a trigger. ([#6234](https://github.com/XRPLF/rippled/pull/6234))
|
||||
- Uploaded Conan recipe for merges into develop and commits to release. ([#6235](https://github.com/XRPLF/rippled/pull/6235))
|
||||
- Added missing commit hash to Conan recipe version. ([#6256](https://github.com/XRPLF/rippled/pull/6256))
|
||||
- Ran on-trigger and on-pr when generate-version is modified. ([#6257](https://github.com/XRPLF/rippled/pull/6257))
|
||||
- Detected uninitialized variables in CMake files. ([#6247](https://github.com/XRPLF/rippled/pull/6247))
|
||||
- Used plus instead of hyphen for Conan recipe version suffix. ([#6261](https://github.com/XRPLF/rippled/pull/6261))
|
||||
- Explicitly set version when exporting the Conan recipe. ([#6264](https://github.com/XRPLF/rippled/pull/6264))
|
||||
- Properly propagated Conan credentials. ([#6265](https://github.com/XRPLF/rippled/pull/6265))
|
||||
- Passed missing sanitizers input to actions. ([#6266](https://github.com/XRPLF/rippled/pull/6266))
|
||||
- Uploaded Conan recipes for develop, release candidates, and releases. ([#6286](https://github.com/XRPLF/rippled/pull/6286))
|
||||
- Set ColumnLimit to 120 in clang-format. ([#6288](https://github.com/XRPLF/rippled/pull/6288))
|
||||
- Removed unnecessary `boost::system` requirement from conanfile. ([#6290](https://github.com/XRPLF/rippled/pull/6290))
|
||||
- Added cmake-format pre-commit hook. ([#6279](https://github.com/XRPLF/rippled/pull/6279))
|
||||
- Formatted all cmake files without comments. ([#6294](https://github.com/XRPLF/rippled/pull/6294))
|
||||
- Updated hashes of XRPLF/actions. ([#6316](https://github.com/XRPLF/rippled/pull/6316))
|
||||
- Added upper-case match for ARM64. ([#6315](https://github.com/XRPLF/rippled/pull/6315))
|
||||
- Added Zed IDE to `.gitignore`. ([#6317](https://github.com/XRPLF/rippled/pull/6317))
|
||||
- Removed unity builds. ([#6300](https://github.com/XRPLF/rippled/pull/6300))
|
||||
- Removed unnecessary script. ([#6326](https://github.com/XRPLF/rippled/pull/6326))
|
||||
- Updated secp256k1 and openssl. ([#6327](https://github.com/XRPLF/rippled/pull/6327))
|
||||
- Updated secp256k1 to 0.7.1. ([#6331](https://github.com/XRPLF/rippled/pull/6331))
|
||||
- Restored unity builds. ([#6328](https://github.com/XRPLF/rippled/pull/6328))
|
||||
- Removed `@xrplf/rpc-reviewers`. ([#6337](https://github.com/XRPLF/rippled/pull/6337))
|
||||
- Fixed `gcov` lib coverage build failure on macOS. ([#6350](https://github.com/XRPLF/rippled/pull/6350))
|
||||
- Updated clang-format to 21.1.8. ([#6352](https://github.com/XRPLF/rippled/pull/6352))
|
||||
- Added clang-tidy to CI. ([#6369](https://github.com/XRPLF/rippled/pull/6369))
|
||||
- Set cmake-format width to 100. ([#6386](https://github.com/XRPLF/rippled/pull/6386))
|
||||
- Set clang-format width to 100. ([#6387](https://github.com/XRPLF/rippled/pull/6387))
|
||||
- Added dependabot config. ([#6379](https://github.com/XRPLF/rippled/pull/6379))
|
||||
- Built docs in PRs and in private repos. ([#6400](https://github.com/XRPLF/rippled/pull/6400))
|
||||
- Bumped `codecov/codecov-action` from 5.4.3 to 5.5.2. ([#6398](https://github.com/XRPLF/rippled/pull/6398))
|
||||
- Bumped `tj-actions/changed-files` from 46.0.5 to 47.0.4. ([#6394](https://github.com/XRPLF/rippled/pull/6394))
|
||||
- Bumped `actions/setup-python` from 5.6.0 to 6.2.0. ([#6395](https://github.com/XRPLF/rippled/pull/6395))
|
||||
- Bumped `actions/checkout` from 4.3.0 to 6.0.2. ([#6397](https://github.com/XRPLF/rippled/pull/6397))
|
||||
- Bumped `actions/upload-artifact` from 4.6.2 to 6.0.0. ([#6396](https://github.com/XRPLF/rippled/pull/6396))
|
||||
- Added nix development environment. ([#6314](https://github.com/XRPLF/rippled/pull/6314))
|
||||
- Updated cleanup-workspace to delete old `.conan2` dir on macOS. ([#6412](https://github.com/XRPLF/rippled/pull/6412))
|
||||
- Enabled clang-tidy checks without issues. ([#6414](https://github.com/XRPLF/rippled/pull/6414))
|
||||
- Grepped for failures in CI. ([#6339](https://github.com/XRPLF/rippled/pull/6339))
|
||||
- Made nix hook optional. ([#6431](https://github.com/XRPLF/rippled/pull/6431))
|
||||
- Bumped `actions/upload-artifact` from 6.0.0 to 7.0.0. ([#6450](https://github.com/XRPLF/rippled/pull/6450))
|
||||
- Updated pre-commit hooks. ([#6460](https://github.com/XRPLF/rippled/pull/6460))
|
||||
- Enabled clang-tidy `bugprone-move-forwarding-reference` check. ([#6457](https://github.com/XRPLF/rippled/pull/6457))
|
||||
- Enabled clang-tidy `bugprone-return-const-ref-from-parameter` check. ([#6459](https://github.com/XRPLF/rippled/pull/6459))
|
||||
- Enabled clang-tidy `bugprone-sizeof-expression` check. ([#6466](https://github.com/XRPLF/rippled/pull/6466))
|
||||
- Stopped committing generated docs to prevent repo bloat. ([#6474](https://github.com/XRPLF/rippled/pull/6474))
|
||||
- Fixed docs deployment for pull requests. ([#6482](https://github.com/XRPLF/rippled/pull/6482))
|
||||
- Used `gersemi` instead of ancient cmake-format. ([#6486](https://github.com/XRPLF/rippled/pull/6486))
|
||||
- Added custom cmake definitions for gersemi. ([#6491](https://github.com/XRPLF/rippled/pull/6491))
|
||||
- Bumped `tj-actions/changed-files` from 47.0.4 to 47.0.5. ([#6501](https://github.com/XRPLF/rippled/pull/6501))
|
||||
- Enabled clang-tidy `bugprone-unused-local-non-trivial-variable` check. ([#6458](https://github.com/XRPLF/rippled/pull/6458))
|
||||
- Enabled clang-tidy `bugprone-suspicious-missing-comma` check. ([#6468](https://github.com/XRPLF/rippled/pull/6468))
|
||||
- Used check-pr-title from XRPLF/actions. ([#6506](https://github.com/XRPLF/rippled/pull/6506))
|
||||
- Fixed clang-tidy issues from merging `unused-local-non-trivial-variable`. ([#6509](https://github.com/XRPLF/rippled/pull/6509))
|
||||
- Enabled clang-tidy `bugprone-pointer-arithmetic-on-polymorphic-object` check. ([#6469](https://github.com/XRPLF/rippled/pull/6469))
|
||||
- Updated XRPLF/actions. ([#6508](https://github.com/XRPLF/rippled/pull/6508))
|
||||
- Enabled clang-tidy `bugprone-suspicious-stringview-data-usage` check. ([#6467](https://github.com/XRPLF/rippled/pull/6467))
|
||||
- Enabled clang-tidy `bugprone-too-small-loop-variable` check. ([#6473](https://github.com/XRPLF/rippled/pull/6473))
|
||||
- Enabled clang-tidy `bugprone-reserved-identifier` check. ([#6456](https://github.com/XRPLF/rippled/pull/6456))
|
||||
- Enabled clang-tidy `bugprone-optional-value-conversion` check. ([#6470](https://github.com/XRPLF/rippled/pull/6470))
|
||||
- Enabled clang-tidy `bugprone-unhandled-self-assignment` check. ([#6504](https://github.com/XRPLF/rippled/pull/6504))
|
||||
- Enabled clang-tidy `bugprone-unused-raii` check. ([#6505](https://github.com/XRPLF/rippled/pull/6505))
|
||||
- Enabled clang-tidy `bugprone-inc-dec-in-conditions` check. ([#6455](https://github.com/XRPLF/rippled/pull/6455))
|
||||
- Used CMake components for install. ([#6485](https://github.com/XRPLF/rippled/pull/6485))
|
||||
- Built voidstar on amd64 only. ([#6481](https://github.com/XRPLF/rippled/pull/6481))
|
||||
- Fixed rules used to determine when to upload Conan recipes. ([#6524](https://github.com/XRPLF/rippled/pull/6524))
|
||||
- Fixed how clang-tidy is run when `.clang-tidy` is changed. ([#6521](https://github.com/XRPLF/rippled/pull/6521))
|
||||
- Added missed clang-tidy `bugprone-inc-dec-conditions` check. ([#6526](https://github.com/XRPLF/rippled/pull/6526))
|
||||
- Moved Type of Change from PR template to CONTRIBUTING. ([#6522](https://github.com/XRPLF/rippled/pull/6522))
|
||||
- Replaced levelization shell script with python script. ([#6325](https://github.com/XRPLF/rippled/pull/6325))
|
||||
- Enabled clang-tidy `bugprone-unused-return-value` check. ([#6475](https://github.com/XRPLF/rippled/pull/6475))
|
||||
- Enabled clang-tidy check for CRTP constructor accessibility. ([#6452](https://github.com/XRPLF/rippled/pull/6452))
|
||||
- Enabled clang-tidy `switch-missing-default-case` check. ([#6461](https://github.com/XRPLF/rippled/pull/6461))
|
||||
- Moved sanitizer runtime options out to files. ([#6371](https://github.com/XRPLF/rippled/pull/6371))
|
||||
- Fixed build errors on windows. ([#6562](https://github.com/XRPLF/rippled/pull/6562))
|
||||
- Enabled remaining clang-tidy `cppcoreguidelines` checks. ([#6538](https://github.com/XRPLF/rippled/pull/6538))
|
||||
- Let required runs be triggered by merge group events. ([#6563](https://github.com/XRPLF/rippled/pull/6563))
|
||||
- Updated check-pr-title action hash. ([#6572](https://github.com/XRPLF/rippled/pull/6572))
|
||||
- Enabled clang-tidy `bugprone-use-after-move` check. ([#6476](https://github.com/XRPLF/rippled/pull/6476))
|
||||
- Added simple clang-tidy readability checks. ([#6556](https://github.com/XRPLF/rippled/pull/6556))
|
||||
- Didn't check PR title for drafts. ([#6573](https://github.com/XRPLF/rippled/pull/6573))
|
||||
- Used external action implementation of check-pr-title. ([#6578](https://github.com/XRPLF/rippled/pull/6578))
|
||||
- Used correct format and event for workflows for release tags. ([#6554](https://github.com/XRPLF/rippled/pull/6554))
|
||||
- Updated XRPLF/actions. ([#6594](https://github.com/XRPLF/rippled/pull/6594))
|
||||
- Checked for signed commits in PR. ([#6559](https://github.com/XRPLF/rippled/pull/6559))
|
||||
- Disallowed files more than 400kb to be added to the repo. ([#6597](https://github.com/XRPLF/rippled/pull/6597))
|
||||
- Updated `.git-blame-ignore-revs`. ([#6577](https://github.com/XRPLF/rippled/pull/6577))
|
||||
- Bumped `codecov/codecov-action` from 5.5.2 to 5.5.3. ([#6615](https://github.com/XRPLF/rippled/pull/6615))
|
||||
- Enabled more clang-tidy readability checks. ([#6595](https://github.com/XRPLF/rippled/pull/6595))
|
||||
- Removed the forward declarations that cause build errors when unity build is enabled. ([#6633](https://github.com/XRPLF/rippled/pull/6633))
|
||||
- Updated external dependencies due to upstream merge. ([#6630](https://github.com/XRPLF/rippled/pull/6630))
|
||||
- Updated some external dependencies. ([#6642](https://github.com/XRPLF/rippled/pull/6642))
|
||||
- Used unpatched version of soci. ([#6649](https://github.com/XRPLF/rippled/pull/6649))
|
||||
- Updated sqlite3 to 3.51.0, protobuf to 6.33.5, openssl to 3.6.1, grpc to 1.78.1. ([#6653](https://github.com/XRPLF/rippled/pull/6653))
|
||||
- Showed warning message if user may need to connect to VPN. ([#6619](https://github.com/XRPLF/rippled/pull/6619))
|
||||
- Added more AI tools to `.gitignore`. ([#6658](https://github.com/XRPLF/rippled/pull/6658))
|
||||
- Added conflicting-pr workflow. ([#6656](https://github.com/XRPLF/rippled/pull/6656))
|
||||
- Uploaded artifacts only in public repositories. ([#6670](https://github.com/XRPLF/rippled/pull/6670))
|
||||
- Didn't publish docs on release branches. ([#6673](https://github.com/XRPLF/rippled/pull/6673))
|
||||
- Bumped `codecov/codecov-action` from 5.5.3 to 6.0.0. ([#6685](https://github.com/XRPLF/rippled/pull/6685))
|
||||
- Bumped `actions/deploy-pages` from 4.0.5 to 5.0.0. ([#6684](https://github.com/XRPLF/rippled/pull/6684))
|
||||
- Fixed clang-tidy header filter. ([#6686](https://github.com/XRPLF/rippled/pull/6686))
|
||||
- Enabled remaining clang-tidy `performance` checks. ([#6648](https://github.com/XRPLF/rippled/pull/6648))
|
||||
- Only published docs in public repos. ([#6687](https://github.com/XRPLF/rippled/pull/6687))
|
||||
- Used `pull_request_target` to check for signed commits. ([#6697](https://github.com/XRPLF/rippled/pull/6697))
|
||||
- Enabled clang-tidy misc checks. ([#6655](https://github.com/XRPLF/rippled/pull/6655))
|
||||
- Used nudb recipe from the upstream. ([#6701](https://github.com/XRPLF/rippled/pull/6701))
|
||||
- Allowed uploading artifacts for XRPLF org. ([#6702](https://github.com/XRPLF/rippled/pull/6702))
|
||||
- Enabled clang-tidy `coreguidelines` checks. ([#6698](https://github.com/XRPLF/rippled/pull/6698))
|
||||
- Updated XRPLF/actions. ([#6713](https://github.com/XRPLF/rippled/pull/6713))
|
||||
- Changed conditions for uploading artifacts in public/private/org repos. ([#6734](https://github.com/XRPLF/rippled/pull/6734))
|
||||
- Enabled most clang-tidy bugprone checks. ([#6929](https://github.com/XRPLF/rippled/pull/6929))
|
||||
- Moved codegen venv setup into build stage. ([#6617](https://github.com/XRPLF/rippled/pull/6617))
|
||||
- Fixed unity build for book step. ([#6942](https://github.com/XRPLF/rippled/pull/6942))
|
||||
- Enabled clang-tidy readability checks. ([#6930](https://github.com/XRPLF/rippled/pull/6930))
|
||||
- Bumped `actions/upload-artifact` from 7.0.0 to 7.0.1. ([#6928](https://github.com/XRPLF/rippled/pull/6928))
|
||||
- Bumped `actions/upload-pages-artifact` from 4.0.0 to 5.0.0. ([#6927](https://github.com/XRPLF/rippled/pull/6927))
|
||||
- Enabled clang-tidy include cleaner. ([#6947](https://github.com/XRPLF/rippled/pull/6947))
|
||||
- Bumped `tj-actions/changed-files` from 47.0.5 to 47.0.6. ([#6973](https://github.com/XRPLF/rippled/pull/6973))
|
||||
- Added workflow to check PR description has been filled. ([#6965](https://github.com/XRPLF/rippled/pull/6965))
|
||||
- Uploaded clang-tidy git diff. ([#6983](https://github.com/XRPLF/rippled/pull/6983))
|
||||
- Enabled clang-tidy modernize checks. ([#6975](https://github.com/XRPLF/rippled/pull/6975))
|
||||
- Added `-fix` to clang-tidy invocation. ([#6990](https://github.com/XRPLF/rippled/pull/6990))
|
||||
- Added bashate pre-commit hook to unify bash style. ([#6994](https://github.com/XRPLF/rippled/pull/6994))
|
||||
- Optionally ran clang-tidy via pre-commit. ([#6680](https://github.com/XRPLF/rippled/pull/6680))
|
||||
- Added pre-commit hook to fix include style. ([#6995](https://github.com/XRPLF/rippled/pull/6995))
|
||||
- Resolved MSVC Debug build failure in `JobQueue.h` and re-enabled `_CRTDBG_MAP_ALLOC` in CI. ([#6993](https://github.com/XRPLF/rippled/pull/6993))
|
||||
- Enabled clang-tidy `modernize-use-nodiscard` check. ([#7015](https://github.com/XRPLF/rippled/pull/7015))
|
||||
- Enabled clang-tidy v21 new checks. ([#7031](https://github.com/XRPLF/rippled/pull/7031))
|
||||
- Used `print-env` from XRPLF/actions. ([#7052](https://github.com/XRPLF/rippled/pull/7052))
|
||||
- Gated `-mcmodel` flags to x86_64 in sanitizer builds. ([#7049](https://github.com/XRPLF/rippled/pull/7049))
|
||||
- Renamed `print-env` to `print-build-env`. ([#7061](https://github.com/XRPLF/rippled/pull/7061))
|
||||
- Enabled clang-tidy `readability-identifier-naming` check. ([#6571](https://github.com/XRPLF/rippled/pull/6571))
|
||||
- Ignored identifier-naming update in git blame. ([#7066](https://github.com/XRPLF/rippled/pull/7066))
|
||||
- Rewrote clang-tidy workflow(s) in a reusable manner. ([#7062](https://github.com/XRPLF/rippled/pull/7062))
|
||||
- Used `XRPLF/create-issue`. ([#7076](https://github.com/XRPLF/rippled/pull/7076))
|
||||
- Ran pre-commit on diff in clang-tidy workflow. ([#7078](https://github.com/XRPLF/rippled/pull/7078))
|
||||
- Did not duplicate sanitizer flags. ([#7058](https://github.com/XRPLF/rippled/pull/7058))
|
||||
- Updated `conan.lock`. ([#7081](https://github.com/XRPLF/rippled/pull/7081))
|
||||
- Updated zlib to 1.3.2, sqlite to 3.53.0, libarchive to 3.8.7, jemalloc to 5.3.1, and boost to 1.91.0. ([#7084](https://github.com/XRPLF/rippled/pull/7084))
|
||||
- Restored clang-tidy change to section name in config. ([#7091](https://github.com/XRPLF/rippled/pull/7091))
|
||||
- Upgraded Clang sanitizer to clang-22 and switched gcc-15 sanitizer to Release. ([#7079](https://github.com/XRPLF/rippled/pull/7079))
|
||||
- Made `.clang-tidy` style a bit more consistent with Clio. ([#7096](https://github.com/XRPLF/rippled/pull/7096))
|
||||
- Upgraded mako version. ([#7108](https://github.com/XRPLF/rippled/pull/7108))
|
||||
- Made `Show test failure summary` work with no build dir. ([#7124](https://github.com/XRPLF/rippled/pull/7124))
|
||||
- Limited nproc on Linux builds temporarily. ([#7132](https://github.com/XRPLF/rippled/pull/7132))
|
||||
- Implemented nix-based Dockerfile for CI. ([#7083](https://github.com/XRPLF/rippled/pull/7083))
|
||||
- Added Conan retry. ([#7147](https://github.com/XRPLF/rippled/pull/7147))
|
||||
- Updated XRPLF/actions. ([#7281](https://github.com/XRPLF/rippled/pull/7281))
|
||||
- Set version to 3.3.0-b0. ([#7280](https://github.com/XRPLF/rippled/pull/7280))
|
||||
- Added Linux package builds (DEB + RPM) to CI. ([#6639](https://github.com/XRPLF/rippled/pull/6639))
|
||||
- Only ran reusable package in public repos. ([#7293](https://github.com/XRPLF/rippled/pull/7293))
|
||||
- Bumped `actions/upload-artifact` from 7.0.0 to 7.0.1. ([#7286](https://github.com/XRPLF/rippled/pull/7286))
|
||||
- Applied more clang-tidy identifier renaming. ([#7290](https://github.com/XRPLF/rippled/pull/7290))
|
||||
- Re-enabled full nproc for Linux. ([#7315](https://github.com/XRPLF/rippled/pull/7315))
|
||||
- Fixed RPM prerelease ordering and started xrpld on DEB install. ([#7313](https://github.com/XRPLF/rippled/pull/7313))
|
||||
|
||||
|
||||
## Credits
|
||||
|
||||
The following RippleX teams and GitHub users contributed to this release:
|
||||
|
||||
- RippleX Engineering
|
||||
- RippleX Docs
|
||||
- RippleX Product
|
||||
- @Bronek
|
||||
- @Kassaking7
|
||||
- @box4wangjing
|
||||
- @chuanshanjida
|
||||
- @dangell7
|
||||
- @nuxtreact
|
||||
- @oncecelll
|
||||
- @ricky122-5
|
||||
- @shortthefomo
|
||||
- @sublimator
|
||||
- @tequdev
|
||||
- @treeol
|
||||
- @tsinglua
|
||||
- @xVet
|
||||
|
||||
|
||||
## Bug Bounties and Responsible Disclosures
|
||||
|
||||
We welcome reviews of the `rippled` code and urge researchers to responsibly disclose any issues they may find.
|
||||
|
||||
For more information, see:
|
||||
|
||||
- [Ripple's Bug Bounty Program](https://ripple.com/legal/bug-bounty/)
|
||||
- [`rippled` Security Policy](https://github.com/XRPLF/rippled/blob/develop/SECURITY.md)
|
||||
@@ -15,15 +15,15 @@ Creating a valid address is a strictly mathematical task starting with a key pai
|
||||
|
||||
## Special Addresses
|
||||
|
||||
Some addresses have special meaning, or historical uses, in the XRP Ledger. In many cases, these are "black hole" addresses, meaning the address is not derived from a known secret key. Since it is effectively impossible to guess a secret key from only an address, any XRP possessed by black hole addresses is lost forever.
|
||||
Some addresses have special meaning, or historical uses, in the XRP Ledger. In many cases, these are blackhole addresses, meaning the address is not derived from a known secret key. Since it is effectively impossible to guess a secret key from only an address, any XRP possessed by blackhole addresses is lost forever. See [Blackholed Accounts](blackholed-accounts.md).
|
||||
|
||||
|
||||
| Address | Name | Meaning | Black Hole? |
|
||||
| Address | Name | Meaning | Blackhole? |
|
||||
|-------------------------------|------|---------|-------------|
|
||||
| `rrrrrrrrrrrrrrrrrrrrrhoLvTp` | ACCOUNT\_ZERO | An address that is the XRP Ledger's [base58][] encoding of the value `0`. In peer-to-peer communications, `rippled` uses this address as the issuer for XRP. | Yes |
|
||||
| `rrrrrrrrrrrrrrrrrrrrBZbvji` | ACCOUNT\_ONE | An address that is the XRP Ledger's [base58][] encoding of the value `1`. In the ledger, [RippleState entries](../../references/protocol/ledger-data/ledger-entry-types/ripplestate.md) use this address as a placeholder for the issuer of a trust line balance. | Yes |
|
||||
| `rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh` | The genesis account | When `rippled` starts a new genesis ledger from scratch (for example, in stand-alone mode), this account holds all the XRP. This address is generated from the seed value `masterpassphrase` which is [hard-coded](https://github.com/XRPLF/rippled/blob/70d5c624e8cf732a362335642b2f5125ce4b43c1/src/xrpld/app/ledger/Ledger.cpp#L184). | No |
|
||||
| `rrrrrrrrrrrrrrrrrNAMEtxvNvQ` | Ripple Name reservation black-hole | In the past, Ripple asked users to send XRP to this account to reserve Ripple Names.| Yes |
|
||||
| `rrrrrrrrrrrrrrrrrNAMEtxvNvQ` | Ripple Name reservation blackhole | In the past, Ripple asked users to send XRP to this account to reserve Ripple Names.| Yes |
|
||||
| `rrrrrrrrrrrrrrrrrrrn5RM1rHd` | NaN Address | Old JavaScript client libraries generated this address when encoding the value [NaN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN) using the XRP Ledger's [base58][] string encoding format. | Yes |
|
||||
|
||||
|
||||
|
||||
61
docs/concepts/accounts/blackholed-accounts.md
Normal file
61
docs/concepts/accounts/blackholed-accounts.md
Normal file
@@ -0,0 +1,61 @@
|
||||
---
|
||||
seo:
|
||||
description: A blackholed account is an XRP Ledger account that can never send transactions again because its signing authority has been permanently removed.
|
||||
labels:
|
||||
- Accounts
|
||||
---
|
||||
# Blackholed Accounts
|
||||
|
||||
A blackholed account is an account whose signing authority has been permanently and verifiably removed. Once an account is blackholed, no one can ever send transactions from it again.
|
||||
|
||||
## Why Blackhole an Account
|
||||
|
||||
Blackholing an account is an extreme measure that most account owners will never need to consider. Use cases include:
|
||||
- **Proving a fixed token supply.** By blackholing an issuing account, the owner proves to users and token holders that the account can no longer mint additional tokens, change transfer fees, or freeze balances.
|
||||
- **Decommissioning an account that can't be deleted.** If an account has [deletion blockers](deleting-accounts.md#deletion-blockers), it cannot be deleted. Blackholing permanently removes the account's signing authority, preventing further activity. Unlike deletion, the account remains on the ledger and its reserves stay locked.
|
||||
|
||||
## Requirements
|
||||
|
||||
To be considered blackholed, an account must meet all of the following conditions:
|
||||
- The master key is disabled.
|
||||
- The regular key is set to a known [blackhole address](addresses.md#special-addresses).
|
||||
- The account has no [signer list](multi-signing.md).
|
||||
- The account has no [delegates](permission-delegation.md). {% amendment-disclaimer name="PermissionDelegation" /%}
|
||||
|
||||
## Checking Whether an Account Is Blackholed
|
||||
|
||||
There is no cryptographic certificate of blackholing. You can only verify that an account meets the conditions above.
|
||||
|
||||
To check, call the [account_info method][] and confirm all of the following:
|
||||
1. The `lsfDisableMaster` flag is set.
|
||||
2. The `RegularKey` field is set to a known [blackhole address](addresses.md#special-addresses) (either `rrrrrrrrrrrrrrrrrrrrrhoLvTp` for ACCOUNT_ZERO or `rrrrrrrrrrrrrrrrrrrrBZbvji` for ACCOUNT_ONE).
|
||||
3. No [SignerList entry][] exists for the account, confirmed by calling the [account_objects method][].
|
||||
4. No [Delegate ledger entry][] exists for the account, confirmed by calling the [account_objects method][].
|
||||
|
||||
ACCOUNT_ZERO and ACCOUNT_ONE are considered known blackhole addresses because they are derived from the integers 0 and 1 instead of a private key. This makes it effectively impossible for anyone to produce a matching private key.
|
||||
|
||||
If the regular key is set to an arbitrary address rather than a known blackhole address, there is no way to verify that no one holds the corresponding private key.
|
||||
|
||||
{% admonition type="info" name="Note" %}
|
||||
A blackholed account's transaction history will continue to show activity from other accounts using its tokens or completing transactions involving it. The blackholed account itself is not sending these transactions.
|
||||
{% /admonition %}
|
||||
|
||||
## Risks and Limitations
|
||||
|
||||
Blackholing is irreversible. Before blackholing an account, be aware of the following:
|
||||
- Any XRP held by the account is permanently lost and cannot be retrieved.
|
||||
- The account cannot send any transactions after blackholing. Any misconfigured settings (such as transfer fees, freeze authority, or rippling) are permanently locked in.
|
||||
- Existing ledger entries created before blackholing (such as open offers, escrows, payment channels, or checks) can still complete, meaning additional tokens could be issued or XRP could leave the account after blackholing.
|
||||
|
||||
## See Also
|
||||
|
||||
- **Concepts:**
|
||||
- [Deleting Accounts](deleting-accounts.md)
|
||||
- [Cryptographic Keys](cryptographic-keys.md)
|
||||
- [Multi-Signing](multi-signing.md)
|
||||
- [Special Addresses](addresses.md#special-addresses)
|
||||
- **Tutorials:**
|
||||
- [Disable Master Key Pair](../../tutorials/best-practices/key-management/disable-master-key-pair.md)
|
||||
- [Assign a Regular Key Pair](../../tutorials/best-practices/key-management/assign-a-regular-key-pair.md)
|
||||
|
||||
{% raw-partial file="/docs/_snippets/common-links.md" /%}
|
||||
@@ -36,7 +36,7 @@ An account's core data is stored in an [AccountRoot](../../references/protocol/l
|
||||
|
||||
There is not a dedicated "create account" transaction. The [Payment transaction][] automatically creates a new account if the payment sends enough XRP to a mathematically-valid address that does not already have an account. This is called _funding_ an account, and creates an [AccountRoot entry](../../references/protocol/ledger-data/ledger-entry-types/accountroot.md) in the ledger. No other transaction can create an account.
|
||||
|
||||
{% admonition type="warning" name="Caution" %}Funding an account **does not** give you any special privileges over that account. Whoever has the secret key corresponding to the account's address has full control over the account and all XRP it contains. For some addresses, it's possible that no one has the secret key, in which case the account is a [black hole](addresses.md#special-addresses) and the XRP is lost forever.{% /admonition %}
|
||||
{% admonition type="warning" name="Caution" %}Funding an account **does not** give you any special privileges over that account. Whoever has the secret key corresponding to the account's address has full control over the account and all XRP it contains. For some addresses, it's possible that no one has the secret key, in which case the account is a [blackholed account](blackholed-accounts.md) and the XRP is lost forever.{% /admonition %}
|
||||
|
||||
The typical way to get an account in the XRP Ledger is as follows:
|
||||
|
||||
@@ -56,6 +56,7 @@ The typical way to get an account in the XRP Ledger is as follows:
|
||||
- [Reserves](reserves.md)
|
||||
- [Cryptographic Keys](cryptographic-keys.md)
|
||||
- [Issuing and Operational Addresses](account-types.md)
|
||||
- [Blackholed Accounts](blackholed-accounts.md)
|
||||
- **References:**
|
||||
- [account_info method][]
|
||||
- [wallet_propose method][]
|
||||
|
||||
@@ -35,7 +35,9 @@ To participate in the XRP Ledger, `rippled` servers connect to arbitrary peers u
|
||||
|
||||
Ideally, the server should be able to send _and_ receive connections on the peer port. You should [forward the port used for the peer protocol through your firewall](../../infrastructure/configuration/peering/forward-ports-for-peering.md) to the `rippled` server.
|
||||
|
||||
IANA [has assigned port **2459**](https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=2459) for the XRP Ledger peer protocol, but for compatibility with legacy systems, the [default `rippled` config file](https://github.com/XRPLF/rippled/blob/master/cfg/rippled-example.cfg) listens for incoming peer protocol connections on **port 51235** on all network interfaces. If you run a server, you can configure which port(s) your server listens on using the `rippled.cfg` file.
|
||||
IANA [has assigned port **2459**](https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=2459) for the XRP Ledger peer protocol, and you can configure which port(s) your server uses in the `xrpld.cfg` file. The [example config file](https://github.com/XRPLF/rippled/blob/master/cfg/xrpld-example.cfg) now listens for incoming peer protocol connections on **port 2459** on all network interfaces. {% badge href="https://xrpl.org/blog/2026/rippled-3.2.0" %}Updated in: rippled 3.2.0{% /badge %}
|
||||
|
||||
Older servers may use the previous **port 51235**, so you might see peers on either port.
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
@@ -95,4 +95,4 @@ To create a fixed supply:
|
||||
1. Create a distribution wallet with settings similar to your issuing wallet.
|
||||
2. Set up a trust line between the issuing wallet and the distribution wallet.
|
||||
3. Send all tokens from the issuing wallet to the distribution wallet.
|
||||
4. Black hole the issuing account.
|
||||
4. Blackhole the issuing account.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
html: nft-fixed-supply.html
|
||||
parent: non-fungible-tokens.html
|
||||
seo:
|
||||
description: Use a new account to mint a fixed number of NFTs, then black hole the account.
|
||||
description: Use a new account to mint a fixed number of NFTs, then blackhole the account.
|
||||
labels:
|
||||
- Non-fungible Tokens, NFTs
|
||||
---
|
||||
@@ -16,8 +16,8 @@ To guarantee a fixed number of NFTs:
|
||||
1. Use `AccountSet` to assign your operational wallet as an authorized minter for the issuer. See [Authorizing Another Account to Mint Your NFTs](authorizing-another-minter.md).
|
||||
1. Use your operational account to mint the tokens using `NFTokenMint`. The operational wallet holds all of the tokens minted for the Issuer. See [Batch Minting](batch-minting.md).
|
||||
1. Use `AccountSet` to remove your operational wallet as an authorized minter for the Issuer.
|
||||
1. “Blackhole” the Issuer account. See [Disable Master Key Pair](../../../tutorials/best-practices/key-management/disable-master-key-pair.md).
|
||||
1. Blackhole the Issuer account. See [Blackholed Accounts](../../accounts/blackholed-accounts.md) and [Disable Master Key Pair](../../../tutorials/best-practices/key-management/disable-master-key-pair.md).
|
||||
|
||||
At this point, it is impossible for any new tokens to be minted with the issuer’s address as the issuing account.
|
||||
|
||||
{% admonition type="warning" name="Caution" %}Once you "blackhole" the account, no one, including you, receives transfer fees for future sales of the NFTs.{% /admonition %}
|
||||
{% admonition type="warning" name="Caution" %}Once you blackhole the account, no one, including you, receives transfer fees for future sales of the NFTs.{% /admonition %}
|
||||
|
||||
@@ -17,6 +17,7 @@ The `rippled` executable usually runs as a daemon that powers the XRP Ledger, al
|
||||
- **Help** - Use `-h` or `--help` to print a usage statement.
|
||||
- **Unit Tests** - Use `-u` or `--unittest` to run unit tests and print a summary of results. This can be helpful to confirm that you have compiled `rippled` successfully.
|
||||
- **Version statement** - Use `--version` to have `rippled` print its version number, Git commit hash, and Git build branch.
|
||||
- **Definitions** - Use `--definitions` to print the XRP Ledger protocol definitions (the same data returned by the [server_definitions method][]) as JSON, then exit. This lets you obtain updated definitions early in development. {% badge href="https://xrpl.org/blog/2026/rippled-3.2.0" %}New in: rippled 3.2.0{% /badge %}
|
||||
|
||||
## Generic Options
|
||||
|
||||
|
||||
@@ -38,14 +38,14 @@ Loading: "/etc/opt/ripple/rippled.cfg"
|
||||
}
|
||||
```
|
||||
|
||||
To allow incoming connections, configure your firewall to allow incoming traffic on the peer protocol port, which is served on **port 51235** in the default config file. The instructions to open a port depend on your firewall. If your server is behind a router that performs Network Address Translation (NAT), you must configure your router to forward the port to your server.
|
||||
To allow incoming connections, configure your firewall to allow incoming traffic on the peer protocol port, which is served on **port 2459** in the default config file. The instructions to open a port depend on your firewall. If your server is behind a router that performs Network Address Translation (NAT), you must configure your router to forward the port to your server.
|
||||
|
||||
If you use the `firewalld` software firewall on Red Hat Enterprise Linux, you can [use the `firewall-cmd` tool](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/security_guide/sec-using_zones_to_manage_incoming_traffic_depending_on_source) to open **port 51235** to all incoming traffic.
|
||||
If you use the `firewalld` software firewall on Red Hat Enterprise Linux, you can [use the `firewall-cmd` tool](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/security_guide/sec-using_zones_to_manage_incoming_traffic_depending_on_source) to open **port 2459** to all incoming traffic.
|
||||
|
||||
_Assuming `--zone=public` is your public [zone](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/security_guide/sec-working_with_zones#sec-Listing_Zones)._
|
||||
|
||||
```sh
|
||||
$ sudo firewall-cmd --zone=public --add-port=51235/tcp
|
||||
$ sudo firewall-cmd --zone=public --add-port=2459/tcp
|
||||
```
|
||||
|
||||
Then, restart the `rippled` server:
|
||||
@@ -57,7 +57,7 @@ $ sudo systemctl restart rippled.service
|
||||
To make it permanent:
|
||||
|
||||
```sh
|
||||
$ sudo firewall-cmd --zone=public --permanent --add-port=51235/tcp
|
||||
$ sudo firewall-cmd --zone=public --permanent --add-port=2459/tcp
|
||||
```
|
||||
|
||||
For other software and hardware firewalls, see the manufacturer's official documentation.
|
||||
|
||||
@@ -16,7 +16,7 @@ Use these steps to manually connect your server to a specific [peer](../../../co
|
||||
## Prerequisites
|
||||
|
||||
- You must know the IP address of the peer you want to connect to.
|
||||
- You must know what port the peer you want to connect to uses for the XRP Ledger [peer protocol](../../../concepts/networks-and-servers/peer-protocol.md). The default config file uses port 51235.
|
||||
- You must know what port the peer you want to connect to uses for the XRP Ledger [peer protocol](../../../concepts/networks-and-servers/peer-protocol.md). The default config file uses port 2459.
|
||||
- You must have a network connection from your server to the peer. For example, the peer server must [forward the appropriate port through its firewall](forward-ports-for-peering.md).
|
||||
- The peer server must have available peer slots. If the peer is already at its maximum number of peers, you can ask the peer server's operator to add a [peer reservation](use-a-peer-reservation.md) for your server.
|
||||
|
||||
@@ -31,7 +31,7 @@ To connect, use the [connect method][]. For example:
|
||||
{
|
||||
"command": "connect",
|
||||
"ip": "169.54.2.151",
|
||||
"port": 51235
|
||||
"port": 2459
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
@@ -43,7 +43,7 @@ To connect, use the [connect method][]. For example:
|
||||
"params": [
|
||||
{
|
||||
"ip": "169.54.2.151",
|
||||
"port": 51235
|
||||
"port": 2459
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -52,7 +52,7 @@ To connect, use the [connect method][]. For example:
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```
|
||||
rippled connect 169.54.2.151 51235
|
||||
rippled connect 169.54.2.151 2459
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ Connecting to 127.0.0.1:5005
|
||||
|
||||
### 4. Communicate the hub server's current IP address and peer port
|
||||
|
||||
The administrator of the hub server must tell their server's current IP address and peer port to the administrator of the stock server. If the hub server is behind a firewall that does network address translation (NAT), use the server's _external_ IP address. The default config file uses port 51235 for the peer protocol.
|
||||
The administrator of the hub server must tell their server's current IP address and peer port to the administrator of the stock server. If the hub server is behind a firewall that does network address translation (NAT), use the server's _external_ IP address. The default config file uses port 2459 for the peer protocol.
|
||||
|
||||
### 5. (Stock Server) Connect to the peer server
|
||||
|
||||
@@ -126,7 +126,7 @@ Use the [connect method][] to connect your server to the hub server. For example
|
||||
{
|
||||
"command": "connect",
|
||||
"ip": "169.54.2.151",
|
||||
"port": 51235
|
||||
"port": 2459
|
||||
}
|
||||
```
|
||||
{% /tab %}
|
||||
@@ -138,7 +138,7 @@ Use the [connect method][] to connect your server to the hub server. For example
|
||||
"params": [
|
||||
{
|
||||
"ip": "169.54.2.151",
|
||||
"port": 51235
|
||||
"port": 2459
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -147,7 +147,7 @@ Use the [connect method][] to connect your server to the hub server. For example
|
||||
|
||||
{% tab label="Commandline" %}
|
||||
```
|
||||
rippled connect 169.54.2.151 51235
|
||||
rippled connect 169.54.2.151 2459
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ For troubleshooting purposes, the most important fields are (from most commonly
|
||||
|
||||
- If you have 0 peers, your server may be unable to contact the network, or your system clock may be wrong. (Ripple recommends running an [NTP](http://www.ntp.org/) daemon on all servers to keep their clocks synced.)
|
||||
|
||||
- If you have exactly 10 peers, that may indicate that your `rippled` is unable to receive incoming connections through a router using [NAT](https://en.wikipedia.org/wiki/Network_address_translation). You can improve connectivity by configuring your router's firewall to forward the port used for peer-to-peer connections (port 51235 [by default](https://github.com/XRPLF/rippled/blob/8429dd67e60ba360da591bfa905b58a35638fda1/cfg/rippled-example.cfg#L1065)).
|
||||
- If you have exactly 10 peers, that may indicate that your `rippled` is unable to receive incoming connections through a router using [NAT](https://en.wikipedia.org/wiki/Network_address_translation). You can improve connectivity by configuring your router's firewall to forward the port used for peer-to-peer connections (port 2459 [by default](../../concepts/networks-and-servers/peer-protocol.md#peer-protocol-port)).
|
||||
|
||||
### No Response from Server
|
||||
|
||||
|
||||
@@ -15,20 +15,28 @@ This is an important step in [Diagnosing Problems](diagnosing-problems.md) with
|
||||
The following shows the format of the log file:
|
||||
|
||||
```text
|
||||
2020-Jul-08 20:10:17.372178946 UTC Peer:WRN [236] onReadMessage from n9J2CP7hZypxDJ27ZSxoy4VjbaSgsCNaRRJtJkNJM5KMdGaLdRy7 at 197.27.127.136:53046: stream truncated
|
||||
2020-Jul-08 20:11:13.582438263 UTC PeerFinder:ERR Logic testing 52.196.126.86:13308 with error, Connection timed out
|
||||
2020-Jul-08 20:11:57.728448343 UTC Peer:WRN [242] onReadMessage from n9J2CP7hZypxDJ27ZSxoy4VjbaSgsCNaRRJtJkNJM5KMdGaLdRy7 at 197.27.127.136:53366: stream truncated
|
||||
2020-Jul-08 20:12:12.075081020 UTC LoadMonitor:WRN Job: sweep run: 1172ms wait: 0ms
|
||||
2026-Jul-08 20:10:17.372178946 UTC Peer:WRN [IP Address: 197.27.127.136:53046, Public Key: n9J2CP7hZypxDJ27ZSxoy4VjbaSgsCNaRRJtJkNJM5KMdGaLdRy7, Id: 236] onReadMessage: stream truncated
|
||||
2026-Jul-08 20:11:13.582438263 UTC PeerFinder:ERR Logic testing 52.196.126.86:13308 with error, Connection timed out
|
||||
2026-Jul-08 20:11:57.728448343 UTC Peer:WRN [IP Address: 197.27.127.136:53366, Public Key: n9J2CP7hZypxDJ27ZSxoy4VjbaSgsCNaRRJtJkNJM5KMdGaLdRy7, Id: 242] onReadMessage: stream truncated
|
||||
2026-Jul-08 20:12:12.075081020 UTC LoadMonitor:WRN Job: sweep run: 1172ms wait: 0ms
|
||||
```
|
||||
|
||||
Each line represents one log entry, with the following parts in order, separated by spaces:
|
||||
|
||||
1. The date the log entry was written, such as `2020-Jul-08`.
|
||||
1. The date the log entry was written, such as `2026-Jul-08`.
|
||||
2. The time the log entry was written, such as `20:12:12.075081020`.
|
||||
3. The time zone indicator `UTC`. (Log dates are always in UTC.)
|
||||
4. The log partition and severity, such as `LoadMonitor:WRN`.
|
||||
5. The log message, such as `Job: sweep run: 1172ms wait: 0ms`.
|
||||
|
||||
Log entries about a peer-to-peer connection (such as those from the `Peer` partition) also include a bracketed identifier between the partition/severity and the message. {% badge href="https://xrpl.org/blog/2026/rippled-3.2.0" %}New in: rippled 3.2.0{% /badge %}
|
||||
|
||||
It contains the following fields:
|
||||
|
||||
- `IP Address`: The peer's IP address and port, such as `197.27.127.136:53046`.
|
||||
- `Public Key`: The base58-encoded [node public key](../../concepts/networks-and-servers/peer-protocol.md#node-key-pair) the peer uses to sign peer protocol messages, such as `n9J2CP7hZypxDJ27ZSxoy4VjbaSgsCNaRRJtJkNJM5KMdGaLdRy7`. This field is omitted if the peer's public key is not yet known, such as before the connection's handshake completes.
|
||||
- `Id`: The numeric ID the server assigns to the peer connection, such as `236`.
|
||||
|
||||
For simplicity, the examples in this page omit the date, time, and time zone indicator.
|
||||
|
||||
|
||||
@@ -104,7 +112,7 @@ This is not strictly a problem, but an old server version is likely to become [a
|
||||
The following log message indicates that a peer `rippled` server closed a connection:
|
||||
|
||||
```text
|
||||
Peer:WRN [012] onReadMessage: Connection reset by peer
|
||||
Peer:WRN [IP Address: 197.27.127.136:53046, Public Key: n9J2CP7hZypxDJ27ZSxoy4VjbaSgsCNaRRJtJkNJM5KMdGaLdRy7, Id: 12] onReadMessage: Connection reset by peer
|
||||
```
|
||||
|
||||
Losing connections from time to time is normal for any peer-to-peer network. **Occasional messages of this kind do not indicate a problem.**
|
||||
|
||||
@@ -12,6 +12,8 @@ labels:
|
||||
|
||||
The `server_definitions` command returns an SDK-compatible `definitions.json`, generated from the `rippled` instance currently running. You can use this to query a node in a network, quickly receiving the definitions necessary to serialize/deserialize its binary data.
|
||||
|
||||
You can also generate the same definitions without a running server using the [`--definitions`](../../../../infrastructure/commandline-usage.md) command-line flag.
|
||||
|
||||
|
||||
## Request Format
|
||||
An example of the request format:
|
||||
|
||||
@@ -22,7 +22,7 @@ Every [ledger version](../../../concepts/ledgers/index.md) has a unique header t
|
||||
| `close_time_resolution` | Number | Uint8 | An integer in the range \[2,120\] indicating the maximum number of seconds by which the `close_time` could be rounded. |
|
||||
| `closed` | Boolean | Boolean | If `true`, this ledger version is no longer accepting new transactions. (However, unless this ledger version is validated, it might be replaced by a different ledger version with a different set of transactions.) |
|
||||
| `parent_hash` | String | UInt256 | The `ledger_hash` value of the previous ledger version that is the direct predecessor of this one. If there are different versions of the previous ledger index, this indicates from which one the ledger was derived. |
|
||||
| `total_coins` | String | UInt64 | The total number of [drops of XRP][] owned by accounts in the ledger. This omits XRP that has been destroyed by transaction fees. The actual amount of XRP in circulation is lower because some accounts are "black holes" whose keys are not known by anyone. |
|
||||
| `total_coins` | String | UInt64 | The total number of [drops of XRP][] owned by accounts in the ledger. This omits XRP that has been destroyed by transaction fees. The actual amount of XRP in circulation is lower because some accounts are [blackholes](../../../concepts/accounts/blackholed-accounts.md) whose keys are not known by anyone. |
|
||||
| `transaction_hash` | String | UInt256 | The [SHA-512Half][] of the transactions included in this ledger. |
|
||||
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ Before you can disable the master key pair, your account must have another way o
|
||||
{% /tab %}
|
||||
{% /tabs %}
|
||||
|
||||
{% admonition type="success" name="Tip" %}If your goal is to make the account a [black hole](/docs/concepts/accounts/addresses#special-addresses) that cannot send transactions at all, you still need to set a regular key. Instead of generating a key pair, use a known black hole address such as **rrrrrrrrrrrrrrrrrrrrrhoLvTp**.{% /admonition %}
|
||||
{% admonition type="success" name="Tip" %}If your goal is to make the account a [blackhole](/docs/concepts/accounts/blackholed-accounts) that cannot send transactions at all, you still need to set a regular key. Instead of generating a key pair, use a known blackhole address such as **rrrrrrrrrrrrrrrrrrrrrhoLvTp**.{% /admonition %}
|
||||
|
||||
### 4. Disable the master key pair
|
||||
|
||||
|
||||
@@ -1,274 +1,185 @@
|
||||
---
|
||||
html: use-tickets.html
|
||||
parent: manage-account-settings.html
|
||||
seo:
|
||||
description: Use Tickets to send a transaction outside of normal Sequence order.
|
||||
embed_xrpl_js: true
|
||||
filters:
|
||||
- interactive_steps
|
||||
description: Use Tickets to send a transaction outside the normal Sequence order.
|
||||
labels:
|
||||
- Accounts
|
||||
steps: ['Generate', 'Connect', 'Check Sequence', 'Prepare & Sign', 'Submit', 'Wait', 'Intermission', 'Check Tickets', 'Prepare Ticketed Tx', 'Submit Ticketed Tx', 'Wait Again']
|
||||
- Transactions
|
||||
---
|
||||
# Use Tickets
|
||||
|
||||
[Tickets](../../../concepts/accounts/tickets.md) provide a way to send transactions out of the normal order. This tutorial walks through the steps of creating a Ticket, then using it to send another transaction.
|
||||
[Tickets](../../../concepts/accounts/tickets.md) let you reserve Sequence numbers in advance so you can send transactions out of order. This is useful when collecting signatures on multi-signed transactions while normal account activity continues, or queuing transactions for later submission.
|
||||
|
||||
This tutorial walks through creating a batch of Tickets, using one in a transaction, and applying the same pattern to multi-signed workflows.
|
||||
|
||||
{% amendment-disclaimer name="TicketBatch" /%}
|
||||
|
||||
## Goals
|
||||
|
||||
By the end of this tutorial, you will be able to:
|
||||
|
||||
- Create Tickets to reserve Sequence numbers for future use.
|
||||
- Use a Ticket to send a transaction outside the normal Sequence order.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
<!-- Source for this specific 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>
|
||||
To complete this tutorial, you need:
|
||||
|
||||
This page provides JavaScript examples that use the [xrpl.js](https://js.xrpl.org/) library. See [Get Started Using JavaScript](../../get-started/get-started-javascript.md) for setup instructions.
|
||||
|
||||
Since JavaScript works in the web browser, you can read along and use the interactive steps without any setup.
|
||||
- A basic understanding of the XRP Ledger.
|
||||
- A basic understanding of how [Sequence numbers](../../../references/protocol/data-types/basic-data-types.md#account-sequence) work in transactions.
|
||||
- An XRP Ledger [client library](../../../references/client-libraries.md) set up.
|
||||
- (Optional) A basic understanding of [multi-signing](../../../concepts/accounts/multi-signing.md), if you plan to combine it with Tickets.
|
||||
|
||||
## Source Code
|
||||
|
||||
You can find the complete source code for this tutorial's examples in the {% repo-link path="_code-samples/use-tickets/" %}code samples section of this website's repository{% /repo-link %}.
|
||||
|
||||
## Steps
|
||||
|
||||
This tutorial is divided into a few phases:
|
||||
### 1. Install dependencies
|
||||
|
||||
- (Steps 1-2) **Setup:** You need an XRP Ledger address and secret. For production, you can use the same address and secret consistently. For this tutorial, you can generate new test credentials as needed. You also need to be connected to the network.
|
||||
- (Steps 3-6) **Create Tickets:** Send a transaction to set aside some Tickets.
|
||||
- (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.
|
||||
|
||||
### 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 [Testnet](../../../concepts/networks-and-servers/parallel-networks.md) using the following interface:
|
||||
|
||||
{% partial file="/docs/_snippets/interactive-tutorials/generate-step.md" /%}
|
||||
|
||||
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).
|
||||
|
||||
|
||||
### 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:
|
||||
Install dependencies for your language from the code sample folder.
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="JavaScript" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/js/use-tickets.js" from="// Connect to" before="// Get credentials" language="js" /%}
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
{% /tab %}
|
||||
{% tab label="Python" %}
|
||||
```sh
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
{% /tab %}
|
||||
{% tab label="Go" %}
|
||||
```sh
|
||||
go mod download
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
{% admonition type="info" name="Note" %}The code samples in this tutorial use JavaScript's [`async`/`await` pattern](https://javascript.info/async-await). Since `await` needs to be used from within an `async` function, the remaining code samples are written to continue inside the `main()` function started here. You can also use Promise methods `.then()` and `.catch()` instead of `async`/`await` if you prefer.{% /admonition %}
|
||||
### 2. Set up client and account
|
||||
|
||||
For this tutorial, click the following button to connect:
|
||||
|
||||
{% partial file="/docs/_snippets/interactive-tutorials/connect-step.md" /%}
|
||||
|
||||
|
||||
### 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.
|
||||
Import the XRPL client library, connect to the network, and generate a test account funded by the [Testnet](../../../concepts/networks-and-servers/parallel-networks.md) faucet. Using a live test network lets you submit transactions without risking real XRP.
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="JavaScript" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/js/use-tickets.js" from="// Check Sequence" before="// Prepare and Sign TicketCreate" language="js" /%}
|
||||
{% code-snippet file="/_code-samples/use-tickets/js/use-tickets.js" before="// Create Tickets" language="js" /%}
|
||||
{% /tab %}
|
||||
{% tab label="Python" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/py/use-tickets.py" before="# Create Tickets" language="py" /%}
|
||||
{% /tab %}
|
||||
{% tab label="Go" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/go/main.go" before="// Create Tickets" language="go" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
{% interactive-block label="Check Sequence" steps=$frontmatter.steps %}
|
||||
|
||||
<button id="check-sequence" class="btn btn-primary previous-steps-required">Check Sequence Number</button>
|
||||
|
||||
{% loading-icon message="Querying..." /%}
|
||||
|
||||
<div class="output-area"></div>
|
||||
|
||||
{% /interactive-block %}
|
||||
|
||||
|
||||
|
||||
### 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:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="JavaScript" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/js/use-tickets.js" from="// Prepare and Sign TicketCreate" before="// Submit TicketCreate" language="js" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
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.
|
||||
|
||||
|
||||
{% 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>
|
||||
|
||||
{% /interactive-block %}
|
||||
|
||||
|
||||
|
||||
### 5. Submit TicketCreate
|
||||
|
||||
Submit the signed transaction blob that you created in the previous step. For example:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="JavaScript" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/js/use-tickets.js" from="// Submit TicketCreate" before="// Wait for Validation" language="js" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
{% 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>
|
||||
|
||||
{% loading-icon message="Sending..." /%}
|
||||
|
||||
<div class="output-area"></div>
|
||||
|
||||
{% /interactive-block %}
|
||||
|
||||
|
||||
### 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).)
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="JavaScript" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/js/use-tickets.js" from="// Wait for Validation" before="// Check Available" language="js" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
{% partial file="/docs/_snippets/interactive-tutorials/wait-step.md" /%}
|
||||
|
||||
|
||||
### (Optional) Intermission
|
||||
|
||||
The power of Tickets is that you can carry on with your account's business as usual while you are getting Ticketed transactions ready. When you want to send a transaction using a Ticket, you can do that in parallel with other sending transactions, including ones using different Tickets, and submit a Ticketed transaction at any time. The only constraint is that each Ticket can only be used once.
|
||||
|
||||
{% admonition type="success" name="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.{% /admonition %}
|
||||
|
||||
{% 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>
|
||||
|
||||
{% /interactive-block %}
|
||||
|
||||
|
||||
|
||||
### 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:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="JavaScript" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/js/use-tickets.js" from="// Check Available Tickets" before="// Prepare and Sign Ticketed" language="js" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
|
||||
{% 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>
|
||||
|
||||
{% /interactive-block %}
|
||||
|
||||
{% admonition type="success" name="Tip" %}You can repeat the steps from here through the end as long as you have Tickets left to be used!{% /admonition %}
|
||||
|
||||
### 8. Prepare Ticketed Transaction
|
||||
|
||||
Now that you have a Ticket available, you can prepare a transaction that uses it.
|
||||
|
||||
This can be any [type of transaction](../../../references/protocol/transactions/types/index.md) you like. The following example uses a no-op [AccountSet transaction][] since that doesn't require any other setup in the ledger. Set the `Sequence` field to `0` and include a `TicketSequence` field with the Ticket Sequence number of one of your available Tickets.
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="JavaScript" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/js/use-tickets.js" from="// Prepare and Sign Ticketed" before="// Submit Ticketed Transaction" language="js" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
{% admonition type="success" name="Tip" %}
|
||||
If you don't plan to submit the TicketCreate transaction right away, you should be sure not to set the `LastLedgerSequence` so that the transaction does not expire. The way you do this varies by library:
|
||||
|
||||
- **xrpl.js:** Specify `"LastLedgerSequence": null` when auto-filling the transaction.
|
||||
- **`rippled`:** Omit `LastLedgerSequence` from the prepared instructions. The server does not provide a value by default.
|
||||
{% admonition type="info" name="Note" %}
|
||||
When you're building production-ready software, use an existing account and manage your keys using a [secure signing configuration](../../../concepts/transactions/secure-signing.md).
|
||||
{% /admonition %}
|
||||
|
||||
{% interactive-block label="Prepare Ticketed Tx" steps=$frontmatter.steps %}
|
||||
### 3. Create Tickets
|
||||
|
||||
<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>
|
||||
Send a [TicketCreate transaction][] and set the `TicketCount` field to the number of Tickets you want to create (up to 250 per account). Each new Ticket reserves a future [Sequence Number][] you can use later. Each Ticket also counts toward your account's [owner reserve](../../../concepts/accounts/reserves.md), which is released when the Ticket is used. Tickets stay reserved on the ledger until you consume them, regardless of any other transactions your account sends.
|
||||
|
||||
{% /interactive-block %}
|
||||
|
||||
|
||||
### 9. Submit Ticketed Transaction
|
||||
|
||||
Submit the signed transaction blob that you created in the previous step. For example:
|
||||
Submit the transaction and wait for validation. For example, to create 10 Tickets:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="JavaScript" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/js/use-tickets.js" from="// Submit Ticketed Transaction" before="// Wait for Validation (again)" language="js" /%}
|
||||
{% code-snippet file="/_code-samples/use-tickets/js/use-tickets.js" from="// Create Tickets" before="// Check Available Tickets" language="js" /%}
|
||||
{% /tab %}
|
||||
{% tab label="Python" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/py/use-tickets.py" from="# Create Tickets" before="# Check Available Tickets" language="py" /%}
|
||||
{% /tab %}
|
||||
{% tab label="Go" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/go/main.go" from="// Create Tickets" before="// Check Available Tickets" language="go" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
{% interactive-block label="Submit Ticketed Tx" steps=$frontmatter.steps %}
|
||||
{% admonition type="info" name="Note" %}
|
||||
A transaction is not final until it is validated by [consensus](../../../concepts/consensus-protocol/index.md), which typically occurs 4-7 seconds after submission. The submit-and-wait call above blocks until validation completes, so the validated result is already available.
|
||||
|
||||
<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>
|
||||
For production code that needs to handle longer waits or transaction expiration, see [Reliable Transaction Submission](../../../concepts/transactions/reliable-transaction-submission.md).
|
||||
{% /admonition %}
|
||||
|
||||
{% /interactive-block %}
|
||||
### 4. Check available Tickets
|
||||
|
||||
To send a Ticketed transaction, you need a Ticket Sequence number. Use the [account_objects method][] to list your Tickets. See the method's [Response Format](../../../references/http-websocket-apis/public-api-methods/account-methods/account_objects.md#response-format) for the response shape.
|
||||
|
||||
### 10. Wait for Validation
|
||||
{% tabs %}
|
||||
{% tab label="JavaScript" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/js/use-tickets.js" from="// Check Available Tickets" before="// Use a Ticket" language="js" /%}
|
||||
{% /tab %}
|
||||
{% tab label="Python" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/py/use-tickets.py" from="# Check Available Tickets" before="# Use a Ticket" language="py" /%}
|
||||
{% /tab %}
|
||||
{% tab label="Go" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/go/main.go" from="// Check Available Tickets" before="// Use a Ticket" language="go" /%}
|
||||
{% /tab %}
|
||||
{% /tabs %}
|
||||
|
||||
Ticketed transactions go through the consensus process the same way that Sequenced transactions do.
|
||||
You can repeat the next step as long as you have unused Tickets.
|
||||
|
||||
{% partial file="/docs/_snippets/interactive-tutorials/wait-step.md" variables={label: "Wait Again"} /%}
|
||||
### 5. Use a Ticket
|
||||
|
||||
Now that you have a Ticket available, you can use it in a transaction. This can be any [type of transaction](../../../references/protocol/transactions/types/index.md). You can use Tickets in any order, but each can only be used once. For the multi-signing variant, see [With Multi-Signing](#with-multi-signing) below.
|
||||
|
||||
{% admonition type="info" name="The Ticket pattern" %}
|
||||
For any transaction that uses a Ticket, set the `Sequence` field to `0` and include a `TicketSequence` field with one of your available Ticket Sequence numbers.
|
||||
{% /admonition %}
|
||||
|
||||
The following example uses an [AccountSet transaction][] with no fields set, making it a no-op that requires no setup. Ticketed transactions go through the same [consensus](../../../concepts/consensus-protocol/index.md) process as Sequenced transactions.
|
||||
|
||||
{% tabs %}
|
||||
{% tab label="JavaScript" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/js/use-tickets.js" from="// Use a Ticket" language="js" /%}
|
||||
{% /tab %}
|
||||
{% tab label="Python" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/py/use-tickets.py" from="# Use a Ticket" language="py" /%}
|
||||
{% /tab %}
|
||||
{% tab label="Go" %}
|
||||
{% code-snippet file="/_code-samples/use-tickets/go/main.go" from="// Use a Ticket" language="go" /%}
|
||||
{% /tab %}
|
||||
{% /tabs %}
|
||||
|
||||
After the transaction is validated, the Ticket is consumed and removed from the ledger. The available Ticket count drops by one.
|
||||
|
||||
{% admonition type="success" name="Tip" %}
|
||||
You can use this same pattern to cancel an unused Ticket — just send a no-op AccountSet using the Ticket you no longer need.
|
||||
{% /admonition %}
|
||||
|
||||
## With Multi-Signing
|
||||
|
||||
One of the main use cases for Tickets is to be able to collect signatures for several [multi-signed transactions](../../../concepts/accounts/multi-signing.md) in parallel. By using a Ticket, you can send a multi-signed transaction as soon as it is fully signed and ready to go, without worrying about which one will be ready first. <!-- STYLE_OVERRIDE: will -->
|
||||
Reserve a Ticket for each [multi-signed transaction](../../../concepts/accounts/multi-signing.md) to hold its slot while you collect signatures. Then submit each transaction as soon as its signatures are complete, in any order.
|
||||
|
||||
In this scenario, [step 8, "Prepare Ticketed Transaction"](#8-prepare-ticketed-transaction) is slightly different. Instead of preparing and signing all at once, you would follow the steps for [sending any multi-signed transaction](../../best-practices/key-management/send-a-multi-signed-transaction.md): first prepare the transaction, then circulate it among trusted signers to collect their signatures, and finally combine the signatures into the final multi-signed transaction.
|
||||
In this scenario, [step 5: Use a Ticket](#5-use-a-ticket) becomes a multi-step process: prepare the transaction, circulate it among signers, and combine their signatures. See [Send a Multi-Signed Transaction](../../best-practices/key-management/send-a-multi-signed-transaction.md) for more details.
|
||||
|
||||
You could do this in parallel for several different potential transactions as long as each one uses a different Ticket.
|
||||
For complete working examples that combine Tickets and multi-signing, see `use-tickets-multisig.js` (JavaScript) or `use-tickets-to-multisign.py` (Python) in the [code samples directory](https://github.com/XRPLF/xrpl-dev-portal/tree/master/_code-samples/use-tickets/). A Go variant isn't currently available.
|
||||
|
||||
You can prepare multiple multi-signed transactions simultaneously, each using a different Ticket.
|
||||
|
||||
{% admonition type="success" name="Tip" %}
|
||||
For this scenario, omit the `LastLedgerSequence` field so that the transaction does not expire while you collect signatures. How you do this varies by library:
|
||||
|
||||
- **xrpl.js:** Specify `"LastLedgerSequence": null` when auto-filling the transaction.
|
||||
- **xrpl-py:** Set `last_ledger_sequence=None` on the transaction.
|
||||
- **xrpl-go:** Leave the field unset before signing.
|
||||
- **`rippled` directly:** Omit the field from the prepared instructions. The server doesn't provide a default.
|
||||
{% /admonition %}
|
||||
|
||||
## See Also
|
||||
|
||||
- **Concepts:**
|
||||
- [Tickets](../../../concepts/accounts/tickets.md)
|
||||
- [Multi-Signing](../../../concepts/accounts/multi-signing.md)
|
||||
- [Reliable Transaction Submission](../../../concepts/transactions/reliable-transaction-submission.md)
|
||||
- **Tutorials:**
|
||||
- [Set Up Multi-Signing](../../best-practices/key-management/set-up-multi-signing.md)
|
||||
- [Reliable Transaction Submission](../../../concepts/transactions/reliable-transaction-submission.md)
|
||||
- [Send a Multi-Signed Transaction](../../best-practices/key-management/send-a-multi-signed-transaction.md)
|
||||
- **References:**
|
||||
- [account_objects method][]
|
||||
- [sign_for method][]
|
||||
- [submit_multisigned method][]
|
||||
- [TicketCreate transaction][]
|
||||
- [Transaction Common Fields](../../../references/protocol/transactions/common-fields.md)
|
||||
- [Transaction Common Fields][common fields]
|
||||
|
||||
{% raw-partial file="/docs/_snippets/common-links.md" /%}
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
---
|
||||
html: build-a-browser-wallet-in-javascript.html
|
||||
parent: javascript.html
|
||||
targets:
|
||||
- en
|
||||
- ja # TODO: translate this page
|
||||
seo:
|
||||
description: Build a graphical browser wallet for the XRPL using Javascript.
|
||||
---
|
||||
# Build a Browser Wallet in JavaScript
|
||||
<!-- STYLE_OVERRIDE: wallet -->
|
||||
|
||||
This tutorial demonstrates how to build a browser wallet for the XRP Ledger using the Javascript programming language and various libraries. This application can be used as a starting point for building a more complete and powerful application, as a reference point for building comparable apps, or as a learning experience to better understand how to integrate XRP Ledger functionality into a larger project.
|
||||
|
||||
@@ -16,9 +10,8 @@ This tutorial demonstrates how to build a browser wallet for the XRP Ledger usin
|
||||
|
||||
To complete this tutorial, you should meet the following guidelines:
|
||||
|
||||
1. You have [Node.js](https://nodejs.org/en/download/) v14 or higher installed.
|
||||
2. You have [Yarn](https://yarnpkg.com/en/docs/install) (v1.17.3 or higher) installed.
|
||||
3. You are somewhat familiar with coding with JavaScript and have completed the [Get Started Using JavaScript](../get-started/get-started-javascript.md) tutorial.
|
||||
1. You have [Node.js](https://nodejs.org/en/download/) v20.19+ installed.
|
||||
2. You are somewhat familiar with coding with JavaScript and have completed the [Get Started Using JavaScript](../get-started/get-started-javascript.md) tutorial.
|
||||
|
||||
## Source Code
|
||||
|
||||
@@ -52,49 +45,31 @@ Before you begin, make sure you have the prerequisites installed. Check your nod
|
||||
1. Navigate to the directory that you want to create the project in.
|
||||
2. Create a new Vite project:
|
||||
|
||||
```bash
|
||||
yarn create vite simple-xrpl-wallet --template vanilla
|
||||
```sh
|
||||
npm create vite browser-xrpl-wallet --template vanilla
|
||||
```
|
||||
|
||||
3. Create or modify the file `package.json` to have the following contents:
|
||||
|
||||
{% code-snippet file="/_code-samples/build-a-browser-wallet/js/package.json" language="js" /%}
|
||||
|
||||
- Alternatively you can also do `yarn add <package-name>` for each individual package to add them to your `package.json` file.
|
||||
|
||||
4. Install dependencies:
|
||||
|
||||
```bash
|
||||
yarn
|
||||
npm install
|
||||
```
|
||||
|
||||
5. Create a new file `.env` in the root directory of the project and add the following variables:
|
||||
5. Create a new file `.env` in the root directory of the project to contain environment variables. You can copy the following values as a starting point:
|
||||
|
||||
```bash
|
||||
CLIENT="wss://s.altnet.rippletest.net:51233/"
|
||||
EXPLORER_NETWORK="testnet"
|
||||
SEED="s████████████████████████████"
|
||||
```
|
||||
{% code-snippet file="/_code-samples/build-a-browser-wallet/js/example.env" language="js" /%}
|
||||
|
||||
6. Change the seed to your own seed. You can get credentials from [the Testnet faucet](/resources/dev-tools/xrp-faucets).
|
||||
|
||||
7. Set up a Vite bundler. Create a file named `vite.config.js` in the root directory of the project and fill it with the following code:
|
||||
|
||||
{% code-snippet file="/_code-samples/build-a-browser-wallet/js/vite.config.js" language="js" /%}
|
||||
|
||||
8. Add script to `package.json`
|
||||
|
||||
In your `package.json` file, add the following section if it's not there already:
|
||||
|
||||
```json
|
||||
"scripts": {
|
||||
"dev": "vite"
|
||||
}
|
||||
```
|
||||
{% admonition type="danger" name="Warning" %}The `VITE_` prefix causes the environment variables to be available on the client side. In this example, this is OK because the user is expected to know the wallet seed. However, you cannot use this same architecture for apps where the end-user is not supposed to have full control over the XRPL account in question.{% /admonition %}
|
||||
|
||||
### 2. Create the Home Page (Displaying Account & Ledger Details)
|
||||
|
||||
In this step, we create a home page that displays account and ledger details.
|
||||
This step creates a home page that displays account and ledger details.
|
||||
|
||||

|
||||
|
||||
@@ -108,9 +83,9 @@ In this step, we create a home page that displays account and ledger details.
|
||||
|
||||
This basic setup creates a homepage and applies some visual styles. The goal is for the homepage to:
|
||||
|
||||
- Display our account info
|
||||
- Display account info
|
||||
- Show what's happening on the ledger
|
||||
- And add a little logo for fun
|
||||
- Display a logo, as an example of how to visually customize your app
|
||||
|
||||
To make that happen, we need to connect to the XRP Ledger and look up the account and the latest validated ledger.
|
||||
|
||||
@@ -118,22 +93,20 @@ To make that happen, we need to connect to the XRP Ledger and look up the accoun
|
||||
|
||||
{% code-snippet file="/_code-samples/build-a-browser-wallet/js/src/helpers/get-wallet-details.js" language="js" /%}
|
||||
|
||||
6. Now, let's add the code to `index.js` file to fetch the account and ledger details and display them on the home page. Copy the code written below to the `index.js` file. Here we render the wallet details using the function we defined in `get-wallet-details.js`. In order to make sure we have up to date ledger data, we are using the [ledger stream](../../references/http-websocket-apis/public-api-methods/subscription-methods/subscribe.md#ledger-stream) to listen for ledger close events.
|
||||
6. Now, add the code to `index.js` file to fetch the account and ledger details and display them on the home page. Copy the code written below to the `index.js` file. This renders the wallet details using the function we defined in `get-wallet-details.js`. To get up to date ledger data, it uses the [ledger stream](../../references/http-websocket-apis/public-api-methods/subscription-methods/subscribe.md#ledger-stream) to listen for ledger close events.
|
||||
|
||||
{% code-snippet file="/_code-samples/build-a-browser-wallet/js/index.js" language="js" /%}
|
||||
|
||||
7. In the `helpers` folder, add {% repo-link path="_code-samples/build-a-browser-wallet/js/src/helpers/render-xrpl-logo.js" %}render-xrpl-logo.js{% /repo-link %} to handle displaying a logo.
|
||||
|
||||
8. Finally create a new folder named `assets` in the `src/` directory and add the file {% repo-link path="_code-samples/build-a-browser-wallet/js/src/assets/xrpl.svg" %}`xrpl.svg`{% /repo-link %} there.
|
||||
8. Finally create a new folder named `assets` in the `src/` directory and add the file {% repo-link path="_code-samples/build-a-browser-wallet/js/src/assets/xrpl.svg" %}`xrpl.svg`{% /repo-link %} there. These files are used to render the XRPL logo.
|
||||
|
||||
These files are used to render the XRPL logo for aesthetic purposes.
|
||||
|
||||
The one other thing we do here is add events to two buttons - one to send XRP and one to view transaction history. They won't work just yet — we'll implement them in the next steps.
|
||||
The last part is to add events to two buttons: "Send XRP" and "Transaction History". They won't work just yet; the following steps implement those parts.
|
||||
|
||||
Now the application is ready to run. You can start it in dev mode using the following command:
|
||||
|
||||
```bash
|
||||
yarn dev
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Your terminal should output a URL which you can use to open your app in a browser. This dev site automatically updates to reflect any changes you make to the code.
|
||||
|
||||
@@ -179,11 +179,11 @@ See [Partial Payments](../../concepts/payment-types/partial-payments.md).
|
||||
|
||||
One way to manage the value of a token is to destroy, or _burn_ tokens, which reduces the number of tokens in circulation. On the XRP Ledger, fungible tokens are automatically "burned" when they are sent to the issuing address. However, the issuer can freely create more tokens.
|
||||
|
||||
To ensure a limited supply, you can "black hole" the issuer after issuing tokens, by setting its regular key to an address like `rrrrrrrrrrrrrrrrrrrrrhoLvTp` for which no one knows the private key, and disabling the master key pair.
|
||||
To ensure a limited supply, you can blackhole the issuer after issuing tokens, by setting its regular key to an address like `rrrrrrrrrrrrrrrrrrrrrhoLvTp` for which no one knows the private key, and disabling the master key pair.
|
||||
|
||||
{% admonition type="danger" name="Warning" %}A black hole account has no way to send transactions of any kind, so you cannot update any settings or do any maintenance on the account afterwards!{% /admonition %}
|
||||
{% admonition type="danger" name="Warning" %}A blackhole account has no way to send transactions of any kind, so you cannot update any settings or do any maintenance on the account afterwards!{% /admonition %}
|
||||
|
||||
See [Disable Master Key Pair](../../tutorials/best-practices/key-management/disable-master-key-pair.md).
|
||||
See [Blackholed Accounts](../../concepts/accounts/blackholed-accounts.md) and [Disable Master Key Pair](../../tutorials/best-practices/key-management/disable-master-key-pair.md).
|
||||
|
||||
### Reliable Transaction Submission
|
||||
|
||||
|
||||
@@ -89,12 +89,15 @@ const cards3 = [
|
||||
const features = [
|
||||
{
|
||||
chip: 'In Development',
|
||||
title: 'Smart Contracts',
|
||||
description:
|
||||
<>
|
||||
Hooks are small, efficient WebAssembly modules designed specifically for the XRPL. Check out the <a href='https://hooks-testnet.xrpl-labs.com/' target='_blank'>hooks amendment and public testnet</a> that enable smart contract functionality.
|
||||
</>,
|
||||
href: 'https://hooks-testnet.xrpl-labs.com/',
|
||||
title: 'Confidential Transfers',
|
||||
description: "Keep MPT balances and transaction amounts private on the public ledger, while enabling MPT issuers and designated auditors to decrypt these values offchain.",
|
||||
href: 'https://opensource.ripple.com/docs/xls-96-confidential-transfers/',
|
||||
},
|
||||
{
|
||||
chip: 'Open for Voting',
|
||||
title: 'Lending Protocol',
|
||||
description: "The XRPL-native lending protocol offers on-chain, fixed-term loans, utilizing pooled funds from single-asset vaults.",
|
||||
href: '/docs/concepts/tokens/lending-protocol/',
|
||||
},
|
||||
{
|
||||
chip: 'Enabled',
|
||||
|
||||
@@ -141,6 +141,7 @@ Use the following words and phrases as described:
|
||||
| Term | Terms to Avoid | Notes |
|
||||
|-------------------|----------------|-------|
|
||||
| API, APIs | API's, RPC | Application Programming Interface, a set of functions and definitions for software to connect to other software. |
|
||||
| blackhole, blackholed, blackholing | black hole, black-hole | An account is blackholed when its signing authority has been permanently and verifiably removed, so that no one can ever send transactions from it again. Always one word. |
|
||||
| core server, core XRP Ledger server | `rippled` | The `rippled` name is probably going to be retired in the near future, so it's better to refer to it by the more generic name. When necessary, refer to `rippled` in all lowercase and code font. (It's pronounced "ripple dee", and the "d" stands for "daemon" per UNIX tradition.)
|
||||
| financial institution | bank, FI, PSP (payment services provider) | This term encompasses a wider range of businesses than just _bank_ or other terms and does not rely on an understanding of industry jargon. |
|
||||
| ledger entry | ledger object, node | A single object inside the state data of the XRP Ledger. The term _ledger object_ could refer to one of these or to the whole ledger. The term _node_ was sometimes used for this case because the ledger's state data can be envisioned as a graph, but this is confusing because _node_ has other uses. |
|
||||
|
||||
@@ -21,7 +21,6 @@ The following is a list of [amendments](../docs/concepts/networks-and-servers/am
|
||||
|
||||
| Name | Status | Additional Information |
|
||||
|:----------------------------------|:------------------------------------------|:-------------------------------|
|
||||
| [Hooks][] | {% badge %}In Development: TBD{% /badge %} | [XRPL Hooks](https://hooks.xrpl.org/) |
|
||||
| [InvariantsV1_1][] | {% badge %}In Development: TBD{% /badge %} | |
|
||||
| [DynamicMPT][] | {% badge %}In Development: TBD{% /badge %} | [XLS-94 Dynamic MPTs](https://opensource.ripple.com/docs/xls-94-dynamic-mpts) |
|
||||
| [ConfidentialTransfer][] | {% badge %}In Development: TBD{% /badge %} | [XLS-96 Confidential Transfers](https://opensource.ripple.com/docs/xls-96-confidential-transfers) |
|
||||
@@ -1043,7 +1042,7 @@ Adds flag checks for `CredentialCreate`, `CredentialAccept`, `CredentialDelete`,
|
||||
|
||||
Fixes a bug where accounts can set their regular key pair to match their master key pair, but cannot send transactions signed by the key if the master key is disabled.
|
||||
|
||||
Without this fix, a user can unintentionally "black hole" their account by setting the regular key to match the master key, then disabling the master key. The network rejects transactions signed with the both-master-and-regular key pair because the code interprets them as being signed with the disabled master key before it recognizes that they are signed by the currently-enabled regular key.
|
||||
Without this fix, a user can unintentionally [blackhole](../docs/concepts/accounts/blackholed-accounts.md) their account by setting the regular key to match the master key, then disabling the master key. The network rejects transactions signed with the both-master-and-regular key pair because the code interprets them as being signed with the disabled master key before it recognizes that they are signed by the currently-enabled regular key.
|
||||
|
||||
With this amendment enabled, a SetRegularKey transaction cannot set the regular key to match the master key; such a transaction results in the transaction code `temBAD_REGKEY`. Additionally, this amendment changes the signature verification code so that accounts which _already_ have their regular key set to match their master key can send transactions successfully using the key pair.
|
||||
|
||||
@@ -1497,19 +1496,6 @@ This is a previous version of the [Flow](#flow) amendment. It was [rejected due
|
||||
Allows validators to include a new optional field in their validations to attest to the hash of the latest ledger that the validator considers to be fully validated. The consensus process can use this information to increase the robustness of consensus.
|
||||
|
||||
|
||||
### Hooks
|
||||
[Hooks]: #hooks
|
||||
|
||||
| Amendment | Hooks |
|
||||
|:-------------|:------|
|
||||
| Amendment ID | ECE6819DBA5DB528F1A241695F5A9811EF99467CDE22510954FD357780BBD078 |
|
||||
| Status | In Development |
|
||||
| Default Vote (Latest stable release) | No |
|
||||
| Pre-amendment functionality retired? | No |
|
||||
|
||||
Adds on-chain smart contracts in the form of small pieces of code that can run on an account before or after transactions. For more information, see the [Hooks Documentation](https://xrpl-hooks.readme.io/).
|
||||
|
||||
|
||||
### ImmediateOfferKilled
|
||||
[ImmediateOfferKilled]: #immediateofferkilled
|
||||
|
||||
|
||||
@@ -164,6 +164,7 @@
|
||||
- page: docs/concepts/accounts/account-types.md
|
||||
- page: docs/concepts/accounts/configuring-accounts.md
|
||||
- page: docs/concepts/accounts/deleting-accounts.md
|
||||
- page: docs/concepts/accounts/blackholed-accounts.md
|
||||
- page: docs/concepts/accounts/reserves.md
|
||||
- page: docs/concepts/accounts/addresses.md
|
||||
- page: docs/concepts/accounts/cryptographic-keys.md
|
||||
|
||||
@@ -1,216 +0,0 @@
|
||||
// 1. Generate
|
||||
// 2. Connect
|
||||
// The code for these steps is handled by interactive-tutorial.js
|
||||
onCurrentRouteLoaded(() => {
|
||||
const LLS_OFFSET = 75 // Expire unconfirmed transactions after about ~5 min
|
||||
|
||||
// 3. Check Sequence Number
|
||||
$("#check-sequence").click( async function(event) {
|
||||
const block = $(event.target).closest(".interactive-block")
|
||||
const address = get_address(event)
|
||||
if (!address) {return}
|
||||
|
||||
// Wipe previous output
|
||||
block.find(".output-area").html("")
|
||||
block.find(".loader").show()
|
||||
const account_info = await api.request({
|
||||
"command": "account_info", "account": address
|
||||
})
|
||||
block.find(".loader").hide()
|
||||
|
||||
block.find(".output-area").append(
|
||||
`<p>Current sequence:
|
||||
<code id="current_sequence">${account_info.result.account_data.Sequence}</code>
|
||||
</p>`)
|
||||
|
||||
complete_step("Check Sequence")
|
||||
})
|
||||
|
||||
// 4. Prepare and Sign TicketCreate --------------------------------------------
|
||||
$("#prepare-and-sign").click( async function(event) {
|
||||
const block = $(event.target).closest(".interactive-block")
|
||||
const wallet = get_wallet(event)
|
||||
if (!wallet) {return}
|
||||
let current_sequence
|
||||
try {
|
||||
current_sequence = parseInt($("#current_sequence").text())
|
||||
} catch (e) {
|
||||
current_sequence = null
|
||||
}
|
||||
|
||||
// Wipe previous output
|
||||
block.find(".output-area").html("")
|
||||
|
||||
if (!current_sequence) {
|
||||
show_error(block,
|
||||
`Couldn't get a valid sequence value. Check that the
|
||||
previous steps were completed successfully.`)
|
||||
return;
|
||||
}
|
||||
|
||||
const vli = await api.getLedgerIndex()
|
||||
const prepared = await api.autofill({
|
||||
"TransactionType": "TicketCreate",
|
||||
"Account": wallet.address,
|
||||
"TicketCount": 10,
|
||||
"Sequence": current_sequence,
|
||||
"LastLedgerSequence": vli+LLS_OFFSET
|
||||
})
|
||||
|
||||
block.find(".output-area").append(
|
||||
`<p>Prepared transaction:</p>
|
||||
<pre><code>${pretty_print(prepared)}</code></pre>`)
|
||||
|
||||
const {tx_blob, hash} = wallet.sign(prepared)
|
||||
block.find(".output-area").append(
|
||||
`<p>Transaction hash: <code id="tx_id">${hash}</code></p>`)
|
||||
block.find(".output-area").append(
|
||||
`<p>Signed blob:</p><pre class="tx-blob"><code id="tx_blob">${tx_blob}</code></pre>`)
|
||||
|
||||
complete_step("Prepare & Sign")
|
||||
|
||||
})
|
||||
|
||||
// 5. Submit TicketCreate ------------------------------------------------------
|
||||
$("#ticketcreate-submit").click( submit_handler )
|
||||
|
||||
// 6. Wait for Validation: handled by interactive-tutorial.js and by the
|
||||
// generic submit handler in the previous step. --------------------------------
|
||||
|
||||
// Intermission ----------------------------------------------------------------
|
||||
async function intermission_submit(event, tx_json) {
|
||||
const block = $(event.target).closest(".interactive-block")
|
||||
const wallet = get_wallet(event)
|
||||
if (!wallet) {return}
|
||||
const prepared = await api.autofill(tx_json)
|
||||
const {tx_blob, hash} = wallet.sign(prepared)
|
||||
const prelim = await api.request({
|
||||
"command": "submit",
|
||||
"tx_blob": tx_blob
|
||||
})
|
||||
|
||||
block.find(".output-area").append(`<p>${prepared.TransactionType}
|
||||
${prepared.Sequence}:
|
||||
<a href="https://devnet.xrpl.org/transactions/${hash}"
|
||||
target="_blank">${prelim.result.engine_result}</a></p>`)
|
||||
}
|
||||
|
||||
$("#intermission-payment").click( async function(event) {
|
||||
const address = get_address(event)
|
||||
if (!address) {return}
|
||||
|
||||
intermission_submit(event, {
|
||||
"TransactionType": "Payment",
|
||||
"Account": address,
|
||||
"Destination": "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe", // Testnet Faucet
|
||||
"Amount": xrpl.xrpToDrops("201")
|
||||
})
|
||||
|
||||
complete_step("Intermission")
|
||||
})
|
||||
|
||||
$("#intermission-escrowcreate").click( async function(event) {
|
||||
const address = get_address(event)
|
||||
if (!address) {return}
|
||||
|
||||
intermission_submit(event, {
|
||||
"TransactionType": "EscrowCreate",
|
||||
"Account": address,
|
||||
"Destination": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", // Genesis acct
|
||||
"Amount": xrpl.xrpToDrops("0.13"), // Arbitrary amount
|
||||
"FinishAfter": xrpl.isoTimeToRippleTime(Date()) + 30 // 30 seconds from now
|
||||
})
|
||||
|
||||
complete_step("Intermission")
|
||||
})
|
||||
|
||||
$("#intermission-accountset").click( async function(event) {
|
||||
const address = get_address(event)
|
||||
if (!address) {return}
|
||||
|
||||
intermission_submit(event, {
|
||||
"TransactionType": "AccountSet",
|
||||
"Account": address
|
||||
})
|
||||
|
||||
complete_step("Intermission")
|
||||
})
|
||||
|
||||
// 7. Check Available Tickets --------------------------------------------------
|
||||
$("#check-tickets").click( async function(event) {
|
||||
const block = $(event.target).closest(".interactive-block")
|
||||
const address = get_address(event)
|
||||
if (!address) {return}
|
||||
// Wipe previous output
|
||||
block.find(".output-area").html("")
|
||||
block.find(".loader").show()
|
||||
|
||||
let response = await api.request({
|
||||
"command": "account_objects",
|
||||
"account": address,
|
||||
"type": "ticket"
|
||||
})
|
||||
block.find(".output-area").html(
|
||||
`<pre><code>${pretty_print(response)}</code></pre>`)
|
||||
|
||||
block.find(".loader").hide()
|
||||
|
||||
// Reset the next step's form & add these tickets
|
||||
$("#ticket-selector .form-area").html("")
|
||||
response.result.account_objects.forEach((ticket, i) => {
|
||||
$("#ticket-selector .form-area").append(
|
||||
`<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" id="ticket${i}"
|
||||
name="ticket-radio-set" value="${ticket.TicketSequence}">
|
||||
<label class="form-check-label"
|
||||
for="ticket${i}">${ticket.TicketSequence}</label></div>`)
|
||||
})
|
||||
|
||||
complete_step("Check Tickets")
|
||||
})
|
||||
|
||||
// 8. Prepare Ticketed Transaction ---------------------------------------------
|
||||
$("#prepare-ticketed-tx").click(async function(event) {
|
||||
const wallet = get_wallet(event)
|
||||
if (!wallet) {return}
|
||||
|
||||
const block = $(event.target).closest(".interactive-block")
|
||||
block.find(".output-area").html("")
|
||||
const use_ticket = parseInt($('input[name="ticket-radio-set"]:checked').val())
|
||||
if (!use_ticket) {
|
||||
show_error(block, "You must choose a ticket first.")
|
||||
return
|
||||
}
|
||||
const vli = await api.getLedgerIndex()
|
||||
|
||||
const prepared_t = await api.autofill({
|
||||
"TransactionType": "AccountSet",
|
||||
"Account": wallet.address,
|
||||
"TicketSequence": use_ticket,
|
||||
"Sequence": 0,
|
||||
"LastLedgerSequence": vli+LLS_OFFSET
|
||||
})
|
||||
|
||||
block.find(".output-area").append(
|
||||
`<p>Prepared transaction:</p>
|
||||
<pre><code>${pretty_print(prepared_t)}</code></pre>`)
|
||||
|
||||
const {tx_blob, hash} = wallet.sign(prepared_t)
|
||||
block.find(".output-area").append(
|
||||
`<p>Transaction hash: <code id="tx_id_t">${hash}</code></p>`)
|
||||
|
||||
block.find(".output-area").append(
|
||||
`<pre style="visibility: none">
|
||||
<code id="tx_blob_t">${tx_blob}</code></pre>`)
|
||||
|
||||
// Update breadcrumbs & activate next step
|
||||
complete_step("Prepare Ticketed Tx")
|
||||
})
|
||||
|
||||
// 9. Submit Ticketed Transaction ----------------------------------------------
|
||||
$("#ticketedtx-submit").click( submit_handler )
|
||||
|
||||
// 10. Wait for Validation (Again): handled by interactive-tutorial.js and by
|
||||
// the generic submit handler in the previous step. --------------------------------
|
||||
|
||||
})
|
||||
Reference in New Issue
Block a user