mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2026-01-25 00:55:19 +00:00
Compare commits
15 Commits
go/primary
...
section/ca
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5e7fceb21 | ||
|
|
7be7ad4806 | ||
|
|
7a6aab6493 | ||
|
|
a992f0ddf3 | ||
|
|
3853484deb | ||
|
|
c9a560441f | ||
|
|
a789936ad2 | ||
|
|
5455108464 | ||
|
|
2b1216012e | ||
|
|
8f853ffb0b | ||
|
|
ba7a756e39 | ||
|
|
24ba1687f9 | ||
|
|
e4aa7010d9 | ||
|
|
4eeb2d2d49 | ||
|
|
e4cdb7ccea |
@@ -124,9 +124,9 @@ XRP Ledgerは、スパム対策として、需要に基づいて[トランザク
|
||||
|
||||
XRP Ledgerネットワークはオープンネットワークであり、すべての取引はオープンに公開されています。
|
||||
|
||||
Rippleは Ledgerネットワーク全体のAMLフラグを監視・報告し、該当する疑わしい活動をFinCENに報告することにコミットしています。
|
||||
Rippleは XRP Ledgerネットワーク全体のAMLフラグを監視・報告し、該当する疑わしい活動をFinCENに報告することにコミットしています。
|
||||
|
||||
[XRP Forensics / xrplorer](https://xrplorer.com/)は、XRP Ledgerのマネーロンダリング、詐欺、詐欺、不正使用を追跡し、最小限に抑えるための勧告リストを維持しています。取引所やその他のサービス・プロバイダは、金融犯罪を防止し対応するためにこのサービスを利用することができます。
|
||||
[XRP Forensics / xrplorer](https://xrplorer.com/)は、XRP Ledgerのマネーロンダリング、詐欺、不正使用を追跡し、最小限に抑えるための勧告リストを維持しています。取引所やその他のサービス・プロバイダは、金融犯罪を防止し対応するためにこのサービスを利用することができます。
|
||||
|
||||
|
||||
## セキュリティ上の懸念
|
||||
|
||||
@@ -26,14 +26,14 @@ labels:
|
||||
- `RippleState`
|
||||
- `Check`
|
||||
- アカウントがレジャー内に所有するオブジェクトが1000個未満であること。
|
||||
- トランザクションの送信時、少なくとも1つ分の[所有者準備金](reserves.md)(現在2XRP)に相当する特別な[トランザクションコスト][]を支払う必要があります。
|
||||
- トランザクションの送信時、少なくとも1つ分の[所有者準備金](reserves.md)(現在{% $env.PUBLIC_OWNER_RESERVE %})に相当する特別な[トランザクションコスト][]を支払う必要があります。
|
||||
|
||||
|
||||
## 削除コスト
|
||||
|
||||
{% admonition type="warning" name="注意" %}アカウントの削除要件を満たしていないためにトランザクションが失敗した場合でも、[AccountDeleteトランザクション][]のトランザクションコストは、トランザクションが検証済みレジャーに含まれる場合常に発生します。アカウントを削除できなかった場合に高いトランザクションコストを支払う可能性を減らすには、AccountDeleteトランザクションを送信するときに`fail_hard`オプションを使用してください。{% /admonition %}
|
||||
|
||||
ビットコインや他の多くの暗号通貨とは異なり、XRP Ledgerの公開レジャーチェーンのそれぞれの新しいレジャーバージョンは、レジャーの完全な状態を含んでおり、新しいアカウントが増えるごとにサイズが増加します。そのため、必要な場合を除き、新しいXRP Ledgerアカウントを作成すべきではありません。アカウントを削除することで、アカウントの10XRPの[準備金](reserves.md)の一部を回復することができますが、そのためには少なくとも2XRPを破棄する必要があります。
|
||||
ビットコインや他の多くの暗号通貨とは異なり、XRP Ledgerの公開レジャーチェーンのそれぞれの新しいレジャーバージョンは、レジャーの完全な状態を含んでおり、新しいアカウントが増えるごとにサイズが増加します。そのため、必要な場合を除き、新しいXRP Ledgerアカウントを作成すべきではありません。アカウントを削除することで、アカウントの{% $env.PUBLIC_BASE_RESERVE %}の[準備金](reserves.md)の一部を回復することができますが、そのためには少なくとも{% $env.PUBLIC_OWNER_RESERVE %}を破棄する必要があります。
|
||||
|
||||
取引所など、多くのユーザのために価値の送受信を行う組織は、[**送信元タグ**と**宛先タグ**](../transactions/source-and-destination-tags.md)を使用することで、XRP Ledgerのアカウントを1つだけ(または少数)使用するだけで、ユーザの支払いを区別することができます。
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ Deposit Authorizationが有効化されているアカウントの特徴は次
|
||||
|
||||
- [Paymentトランザクション][]の送信先には**できません**。ただし**以下の例外**は除きます。
|
||||
- 送金先により、支払の送金元が[事前承認](#事前承認)されている場合。{% amendment-disclaimer name="DepositPreauth" /%}
|
||||
- アカウントのXRP残高がアカウントの最低[必要準備金](reserves.md)以下で、XRP PaymentのAmountがアカウントの最低準備金(現時点では10XRP)以下である場合は、このアカウントを送金先に指定できます。これにより、アカウントがトランザクションを送信することも、XRPを受領することもできずに操作不可能な状態になるのを防ぎます。この場合、アカウントの所有者の準備金は関係ありません。
|
||||
- アカウントのXRP残高がアカウントの最低[必要準備金](reserves.md)以下で、XRP PaymentのAmountがアカウントの最低準備金(現時点では{% $env.PUBLIC_BASE_RESERVE %})以下である場合は、このアカウントを送金先に指定できます。これにより、アカウントがトランザクションを送信することも、XRPを受領することもできずに操作不可能な状態になるのを防ぎます。この場合、アカウントの所有者の準備金は関係ありません。
|
||||
- **以下に該当する場合にのみ**[PaymentChannelClaimトランザクション][]からXRPを受領できます。
|
||||
- PaymentChannelClaimトランザクションの送金元がPayment Channelの送金先である場合。
|
||||
- PaymentChannelClaimトランザクションの送金先がPaymentChannelClaimの送金元を[事前承認している](#事前承認)場合。{% amendment-disclaimer name="DepositPreauth" /%}
|
||||
|
||||
@@ -46,7 +46,7 @@ XRP Ledgerでアカウントを取得する一般的な方法は次のとおり
|
||||
|
||||
- 例えば、一般的な取引所でXRPを購入し、その取引所から、指定したアドレスにXRPを出金することができます。
|
||||
|
||||
{% admonition type="warning" name="注意" %}自身のXRP Ledgerアドレスで初めてXRPを受け取る場合は[アカウントの準備金](reserves.md)(現在は10XRP)を支払う必要があります。この金額のXRPは無期限に使用できなくなります。一方で、一般的な取引所では通常、顧客のXRPはすべて、共有されたいくつかのXRP Ledgerアカウントに保有されているため、顧客はその取引所で個々のアカウントの準備金を支払う必要はありません。引き出す前に、XRP Ledgerに直接アカウントを保有することが、金額に見合う価値があるかどうかを検討してください。{% /admonition %}
|
||||
{% admonition type="warning" name="注意" %}自身のXRP Ledgerアドレスで初めてXRPを受け取る場合は[アカウントの準備金](reserves.md)(現在は{% $env.PUBLIC_BASE_RESERVE %})を支払う必要があります。この金額のXRPは無期限に使用できなくなります。一方で、一般的な取引所では通常、顧客のXRPはすべて、共有されたいくつかのXRP Ledgerアカウントに保有されているため、顧客はその取引所で個々のアカウントの準備金を支払う必要はありません。引き出す前に、XRP Ledgerに直接アカウントを保有することが、金額に見合う価値があるかどうかを検討してください。{% /admonition %}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ XRP Ledgerのチケットは、取引をすぐに送信せずに、その取引
|
||||
|
||||
上記の例では、シーケンス番号105または作成した3つのチケットのいずれかを使用してトランザクションを送信できます。チケット103を使ってトランザクションを送信すると、それによってチケット103は元帳から削除されます。その後の次のトランザクションでは、シーケンス番号105、チケット102、またはチケット104を使用できます。
|
||||
|
||||
{% admonition type="warning" name="注意" %}チケットは1枚ごとに[所有者準備金](reserves.md#所有者準備金)としてカウントされますので、チケット1枚につき2XRPを確保する必要があります。 (このXRPは、チケットを使用した後に再び使用可能になります)一度に多くのチケットを作成すると、このコストはすぐに膨れ上がります。{% /admonition %}
|
||||
{% admonition type="warning" name="注意" %}チケットは1枚ごとに[所有者準備金](reserves.md#所有者準備金)としてカウントされますので、チケット1枚につき{% $env.PUBLIC_OWNER_RESERVE %}を確保する必要があります。 (このXRPは、チケットを使用した後に再び使用可能になります)一度に多くのチケットを作成すると、このコストはすぐに膨れ上がります。{% /admonition %}
|
||||
|
||||
シーケンス番号と同様に、トランザクションの送信は、そのトランザクションが[コンセンサス](../consensus-protocol/index.md)によって確認された場合にのみ、チケットを使用します。しかし、意図した通りにならなかった取引でも、[`tec`クラスの結果コード](../../references/protocol/transactions/transaction-results/tec-codes.md)を用いてコンセンサスで確認することができます。
|
||||
|
||||
@@ -51,7 +51,7 @@ XRP Ledgerのチケットは、取引をすぐに送信せずに、その取引
|
||||
- 各チケットは一度しか使用できません。同じチケットシーケンスを使用する複数の異なるトランザクション候補があることは可能ですが、コンセンサスで検証できるのはそのうちの1つだけです。
|
||||
- 各アカウントでは、一度に250枚以上のチケットをレジャーに登録することはできません。また、一度に250枚以上のチケットを作成することもできません。
|
||||
- チケットを使って別のチケットを作ることは _できます_。その場合、使用したチケットは、一度に所持できるチケットの合計数にはカウントされません。
|
||||
- 各チケットは[所有者準備金](reserves.md#所有者準備金)にカウントされるため、まだ使用していないチケット1枚につき2XRPを確保する必要があります。このXRPは、チケットを使用した後、再び使用することができます。
|
||||
- 各チケットは[所有者準備金](reserves.md#所有者準備金)にカウントされるため、まだ使用していないチケット1枚につき{% $env.PUBLIC_OWNER_RESERVE %}を確保する必要があります。このXRPは、チケットを使用した後、再び使用することができます。
|
||||
- 個々の元帳の中では、チケットを使用した取引は、同じ送信者からの他の取引の後に実行されます。1つのアカウントが同じ元帳のバージョンでTicketを使用する複数のトランザクションを持つ場合、それらのTicketは最も低いTicket Sequenceから最も高いTicket Sequenceの順に実行されます。 (詳細については、コンセンサスの[正規順序](../consensus-protocol/consensus-structure.md#xrp-ledgerプロトコル-コンセンサスと検証)に関するドキュメントをご覧ください)。
|
||||
- 個々の元帳の中では、チケットを使用した取引は、同じ送信者からの他の取引の後に実行されます。1つのアカウントが同じ元帳のバージョンでチケットを使用する複数のトランザクションを持つ場合、それらのチケットは最も低いチケット シーケンス番号から最も高いチケット シーケンス番号の順に実行されます。 (詳細については、コンセンサスの[正規順序](../consensus-protocol/consensus-structure.md#xrp-ledgerプロトコル-コンセンサスと検証)に関するドキュメントをご覧ください)。
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
html: consensus-protections.html
|
||||
parent: consensus.html
|
||||
seo:
|
||||
description: Learn how the XRP Ledger Consensus Protocol is protected against various problems and attacks that may occur in a decentralized financial system. #TODO: translate
|
||||
description: 分散型金融システムで発生する可能性のあるさまざまな問題や攻撃から、XRP Ledgerコンセンサスプロトコルがどのように保護されているかを学びます。
|
||||
labels:
|
||||
- ブロックチェーン
|
||||
---
|
||||
|
||||
@@ -12,11 +12,11 @@ NFTをミントし、保有し、販売するためには、XRPを準備金と
|
||||
|
||||
## 基本準備金
|
||||
|
||||
アカウントでは、基本準備金(現在10XRP)を用意する必要があります。基本準備金のXRPの金額は変更される可能性があります。[基本準備金と所有者準備金](../../accounts/reserves.md#基本準備金と所有者準備金)をご覧ください。
|
||||
アカウントでは、基本準備金(現在{% $env.PUBLIC_BASE_RESERVE %})を用意する必要があります。基本準備金のXRPの金額は変更される可能性があります。[基本準備金と所有者準備金](../../accounts/reserves.md#基本準備金と所有者準備金)をご覧ください。
|
||||
|
||||
## 所有者準備金
|
||||
|
||||
XRP Ledgerで所有する各オブジェクトには、現在2XRPの所有者準備金が必要とされています。これは、ユーザが不必要なデータで台帳にスパムをかけることを抑制し、不要になったデータを削除することを促すためのものです。所有者準備金の額は変更される可能性があります。[基本準備金と所有者準備金](../../accounts/reserves.md#基本準備金と所有者準備金)をご覧ください。
|
||||
XRP Ledgerで所有する各オブジェクトには、現在{% $env.PUBLIC_OWNER_RESERVE %}の所有者準備金が必要とされています。これは、ユーザが不必要なデータで台帳にスパムをかけることを抑制し、不要になったデータを削除することを促すためのものです。所有者準備金の額は変更される可能性があります。[基本準備金と所有者準備金](../../accounts/reserves.md#基本準備金と所有者準備金)をご覧ください。
|
||||
|
||||
NFTの場合、 _オブジェクト_ はそれぞれのNFTを指すのではなく、アカウントが所有する`NFTokenPage`オブジェクトを指します。`NFTokenPage`オブジェクトは最大32個のNFTを格納することができます。
|
||||
|
||||
@@ -38,7 +38,7 @@ NFTの保有枚数や保有ページ数によって、所有者準備金の総
|
||||
|
||||
## `NFTokenOffer`の準備金
|
||||
|
||||
各`NFTokenOffer`オブジェクトは、オファーを出すアカウントに対して準備金の1つの増加を必要とします。この記事の執筆時点では、準備金の増分は2XRPです。準備金は、オファーをキャンセルすることで取り戻すことができます。また、オファーが受け入れられると、XRP Ledgerからオファーが削除され、準備金は取り戻されます。
|
||||
各`NFTokenOffer`オブジェクトは、オファーを出すアカウントに対して準備金の1つの増加を必要とします。この記事の執筆時点では、準備金の増分は{% $env.PUBLIC_OWNER_RESERVE %}です。準備金は、オファーをキャンセルすることで取り戻すことができます。また、オファーが受け入れられると、XRP Ledgerからオファーが削除され、準備金は取り戻されます。
|
||||
|
||||
## Practical Considerations
|
||||
|
||||
@@ -55,7 +55,7 @@ NFTをミントし、保有し、売買のオファーをする場合、必要
|
||||
|
||||
{% admonition type="info" name="注記" %}準備金要件ではありませんが、ミントと売却のプロセスにおけるトランザクションの些細な手数料(通常12drops、または.000012XRP)を負担するために、少なくとも必要準備金より1XRPより多く用意しておきくべきです。{% /admonition %}
|
||||
|
||||
仮に200個のNFTをミントし、それぞれに「NFTokenSellOffer」を作成すると、436XRPもの準備金が必要になります。
|
||||
仮に200個のNFTをミントし、それぞれに「NFTokenSellOffer」を作成すると、43.6XRPもの準備金が必要になります。
|
||||
|
||||
| 準備金の種類 | 準備金の額 |
|
||||
|:--------------------|--------:|
|
||||
|
||||
@@ -72,7 +72,7 @@ labels:
|
||||
|
||||
### `NFTokenOffer`の準備金
|
||||
|
||||
各`NFTokenOffer`オブジェクトは、オファーを出すアカウントに1つ分の準備金の増額を要求します。執筆時点では、準備金の増分は2XRPです。この準備金は、オファーをキャンセルすることで取り戻すことができます。
|
||||
各`NFTokenOffer`オブジェクトは、オファーを出すアカウントに1つ分の準備金の増額を要求します。執筆時点では、準備金の増分は{% $env.PUBLIC_OWNER_RESERVE %}です。この準備金は、オファーをキャンセルすることで取り戻すことができます。
|
||||
|
||||
|
||||
### `NFTokenOfferID`のフォーマット
|
||||
|
||||
@@ -48,7 +48,7 @@ AMMを表す[AMMエントリ][]と[特殊なAccountRootエントリ](../../ledge
|
||||
|
||||
## 特殊なトランザクションコスト
|
||||
|
||||
各AMMインスタンスはAccountRootレジャーエントリ、AMMレジャーエントリ、プール内の各トークンのトラストラインを含むため、AMMCreateトランザクションは台帳スパムを抑止するために通常よりもはるかに高い[トランザクションコスト][]を必要とします。標準的な最低0.00001XRPの代わりに、AMMCreateは少なくとも所有者準備金の増分(現在は2XRP)を破棄しなければなりません。これは[AccountDeleteトランザクション][]と同じ特別なトランザクションコストです。
|
||||
各AMMインスタンスはAccountRootレジャーエントリ、AMMレジャーエントリ、プール内の各トークンのトラストラインを含むため、AMMCreateトランザクションは台帳スパムを抑止するために通常よりもはるかに高い[トランザクションコスト][]を必要とします。標準的な最低0.00001XRPの代わりに、AMMCreateは少なくとも所有者準備金の増分(現在は{% $env.PUBLIC_OWNER_RESERVE %})を破棄しなければなりません。これは[AccountDeleteトランザクション][]と同じ特別なトランザクションコストです。
|
||||
|
||||
## エラーケース
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ labels:
|
||||
|
||||
- トランザクションを送信するための十分なXRPが供給されていて、新しい署名者リストの[必要準備金](../../../concepts/accounts/reserves.md)を満たしている資金供給のあるXRP Ledger[アドレス](../../../concepts/accounts/index.md)が必要です。
|
||||
|
||||
- [MultiSignReserve Amendment][]が有効な場合、マルチシグを使用するには、使用する署名と署名者の数に関わらず、アカウントの準備金として2 XRPが必要です。(MultiSignReserve Amendmentは**2019年4月7日**以降、本番環境のXRP Ledgerで有効になっています。)
|
||||
- [MultiSignReserve Amendment][]が有効な場合、マルチシグを使用するには、使用する署名と署名者の数に関わらず、アカウントの準備金として{% $env.PUBLIC_OWNER_RESERVE %}が必要です。(MultiSignReserve Amendmentは**2019年4月7日**以降、本番環境のXRP Ledgerで有効になっています。)
|
||||
|
||||
- [MultiSignReserve Amendment][]が有効ではないテストネットワークでは、マルチシグを使用するには[アカウント準備金](../../../concepts/accounts/reserves.md)に通常よりも多くのXRPが必要となります。必要額は、リストの署名者の数に応じて増加します。
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ XRP Ledgerの分散型取引所(DEX)には、「アルゴリズムトレード
|
||||
|
||||
裁定取引を行うには、XRP Ledgerの内部と関連する部分の両方で、多くの方法があります。以下の例は潜在的な戦略を説明するためのものですが、他の方法も可能です。
|
||||
|
||||
**循環支払い**を利用して、マルチアセットトレードを完了し利益を得ることができます。XRP Ledgerは、XRPが真ん中のアセットである3つのアセットセットセットと同様に、アセットペア間の重複した取引を自動的に接続します。しかし、XRP Ledgerのプロトコルは、他のより長い、あるいはより複雑な経路のトレードを自動的に見つけて競うことはしません。(可能な限り最善の経路を見つけることは、計算集約型な問題のカテゴリとして知られています。)したがって、XRP Ledgerが独自の経路を見つける場合、XRP Ledgerのプロトコルは自動的に他の、より長い、あるいはより複雑な経路の取引を見つけ、競争させることはありません。したがって、自分で経路探索(PathFinding)を行えば、このような有益な裁定取引の機会を見つけることが可能です。その場合は、[Paymentトランザクション](../../references/protocol/transactions/types/payment.md)でそれらの[経路(Paths)](../../concepts/tokens/fungible-tokens/paths.md)を明示的に指定できます。1つのFOOを使って2つのBARを買い、その2つのBARを使って3つのTSTを買い、最後に3つのTSTを使って1.1 FOOを買えば、0.1 FOOから取引に関わるトークンの[送金手数料](../../concepts/tokens/fungible-tokens/transfer-fees.md)などのコストを差し引いた利益を得ることができます。
|
||||
**循環支払い**を利用して、マルチアセットトレードを完了し利益を得ることができます。XRP Ledgerは、XRPが真ん中のアセットである3つのアセットセットと同様に、アセットペア間の重複した取引を自動的に接続します。しかし、XRP Ledgerのプロトコルは、他のより長い、あるいはより複雑な経路のトレードを自動的に見つけて競うことはしません。(可能な限り最善の経路を見つけることは、計算集約型な問題のカテゴリとして知られています。)したがって、自分で経路探索(PathFinding)を行えば、このような有益な裁定取引の機会を見つけることが可能です。その場合は、[Paymentトランザクション](../../references/protocol/transactions/types/payment.md)でそれらの[経路(Paths)](../../concepts/tokens/fungible-tokens/paths.md)を明示的に指定できます。1つのFOOを使って2つのBARを買い、その2つのBARを使って3つのTSTを買い、最後に3つのTSTを使って1.1 FOOを買えば、0.1 FOOから取引に関わるトークンの[送金手数料](../../concepts/tokens/fungible-tokens/transfer-fees.md)などのコストを差し引いた利益を得ることができます。
|
||||
|
||||
資産の価格が異なる複数の取引所(CEX)に口座を持っている場合、**取引所間の裁定取引**を行うことができます。例えば、ACME取引所でXRPを1XRPあたり0.45ドルで購入し、そのXRPをWayGate取引所に移動して1XRPあたり0.50ドルで売却した場合、XRPあたり0.05ドルの利益を得ることができます。より複雑な例として、ACME取引所でBTC:ETHの価格が変動し、BTCに対してETHが安くなった場合、ある取引所でETH→XRPを売却し、そのXRPをACME取引所に移動し、XRP→BTC→ETHを取引して利益を得ることで、この価格変動を利用できる可能性があります。XRP Ledgerの取引は数秒で決済されますが、イーサリアムの取引は数分、ビットコインの取引は数時間かかることがあるため、XRPをブリッジ通貨として使用することで、ACME取引所でETH→BTC→BTC→ETHと取引するよりも早くこの機会を利用できる可能性があります。(これはもちろん、XRPへの交換が利益以上のコストにならないだけの十分な流動性と狭いスプレッドがある場合にのみ機能します)
|
||||
|
||||
@@ -48,7 +48,7 @@ XRP Ledgerの分散型取引所(DEX)には、「アルゴリズムトレード
|
||||
|
||||
## テストとよくある間違い
|
||||
|
||||
どのような取引でもそうですが、アルゴリズムトレー ドは確実に儲かる方法ではありません。手作業によるトレードと比べると、アルゴリズムトレードはエラーの余地が非常に少なくなります。小さなミスを犯しても、そのミスを大量のトレードで倍増させようとすれば、問題を修正する前に損失があっという間に膨らんでしまいます。したがって、自分のトレード戦略が実際に利益を上げるかどうかを確認するために、さまざまなテストを行うのが賢明です。戦略やその実際の実装(よく _ボット_ と呼ばれます)をテストするために、次のようなことを行うことができます。
|
||||
どのような取引でもそうですが、アルゴリズムトレードは確実に儲かる方法ではありません。手作業によるトレードと比べると、アルゴリズムトレードはエラーの余地が非常に少なくなります。小さなミスを犯しても、そのミスを大量のトレードで倍増させようとすれば、問題を修正する前に損失があっという間に膨らんでしまいます。したがって、自分のトレード戦略が実際に利益を上げるかどうかを確認するために、さまざまなテストを行うのが賢明です。戦略やその実際の実装(よく _ボット_ と呼ばれます)をテストするために、次のようなことを行うことができます。
|
||||
|
||||
- 現在のレジャーの状態または過去のトレードに基づいて、潜在的な利益を手動で計算します。
|
||||
- 過去のデータを記録してボットに送り、ボットがどのようなアクションを取ったかを記録し、実際の過去の値動きと結果を比較します。
|
||||
@@ -61,7 +61,7 @@ XRP Ledgerの分散型取引所(DEX)には、「アルゴリズムトレード
|
||||
- 通常、四捨五入の違いや、計算時と約定時の値動きの違いを考慮し、金額を調整する必要があります。この金額は「スリッページ」と呼ばれ、適切な金額を設定することが重要です。スリッページが低すぎると、トレードがまったく約定しない可能性があります。一方、スリッページが高すぎると、フロントランニングの影響を受けやすくなり、スリッページが高ければ高いほど、値動きによって利益が削られる可能性が高くなります。
|
||||
- **余分なコストと遅延を考慮しないこと**: 例えば、2つのステーブルコインの裏付けが米ドルであるにもかかわらず、ある発行者が0.5%の送金手数料を請求し、別の発行者が0.25%の[送金手数料](../../concepts/tokens/fungible-tokens/transfer-fees.md)を請求した場合、そのステーブルコインの取引価格には約0.25%の差が生じます。トランザクションを送信するためのコストは、通常は少額ですが、その他の潜在的な遅延の影響も忘れないでください。例えば、オフレジャーの取引所が現時点で有利な価格を示していたとしても、その取引所の入金処理に数時間から数日かかる場合、その取引所で事前に流動性を持っていない限り、その価格を利用することはできません。
|
||||
- **稀な事象を考慮していないこと**: 前例のない出来事(「ブラック・スワン」)はさておき、個々の異常値によって計算結果がゆがむことがあります。一例として(これは実話ですが)、あるトレーダーが、ある戦略の潜在的な利益を特定の時間帯で計算したところ、利益の80%以上が、他のユーザが誤って価格にゼロを追加してしまった1つの「入力ミス」の取引によるものであったと報じました。同じ戦略を、これらの異常値の取引を含まない時間範囲に対して計算すると、利益ははるかに少なくなりました。
|
||||
- **トランザクションのフラグを確認しないこ**と: XRP Ledgerのトランザクションのフラグは、そのトランザクションの処理方法や、プロトコルがそれを「成功」とマークするタイミングに大きな影響を与える可能性があります。例えば、"Offer"トランザクションのフラグは、全額がすぐに得られる場合にのみトレードされる"Fill or Kill"注文にすることができます。"Payment"トランザクションのフラグは、意図した宛先に全額を届けることができなくても成功する[partial payments](../../concepts/payment-types/partial-payments.md)にすることができます。トランザクションの`Flags`フィールドを解析するためにビット演算をする必要がありますが、それをスキップしてしまうと、予想と結果が全く異なったものとなってしまう可能性があります。
|
||||
- **トランザクションのフラグを確認しないこと**: XRP Ledgerのトランザクションのフラグは、そのトランザクションの処理方法や、プロトコルがそれを「成功」とマークするタイミングに大きな影響を与える可能性があります。例えば、"Offer"トランザクションのフラグは、全額がすぐに得られる場合にのみトレードされる"Fill or Kill"注文にすることができます。"Payment"トランザクションのフラグは、意図した宛先に全額を届けることができなくても成功する[partial payments](../../concepts/payment-types/partial-payments.md)にすることができます。トランザクションの`Flags`フィールドを解析するためにビット演算をする必要がありますが、それをスキップしてしまうと、予想と結果が全く異なったものとなってしまう可能性があります。
|
||||
|
||||
## 税金とライセンス
|
||||
|
||||
@@ -72,7 +72,7 @@ XRP Ledgerの分散型取引所(DEX)には、「アルゴリズムトレード
|
||||
|
||||
### トレードの発注
|
||||
|
||||
XRP Ledgerの分散型取引所で _代替可能_ トークンとXRPを売買するには、通常[OfferCreateトランザクション](../../references/protocol/transactions/types/offercreate.md)を送信します。この方法でトレードを行うためのコードと技術的ステップの詳細なウォークスルーについては、[分散型取引所でのトレード](../../tutorials/how-tos/use-tokens/trade-in-the-decentralized-exchange.md)をご覧ください。[Paymentトランザクション](../../references/protocol/transactions/types/payment.md)を使用して通貨を両替することも可能です。[クロスカレンしー支払い](../../concepts/payment-types/cross-currency-payments.md)を他のユーザに送ったり、長い[パス](../../concepts/tokens/fungible-tokens/paths.md)を使って裁定取引の機会を1つの操作にまとめることで、自分自身に送り返すこともできます。
|
||||
XRP Ledgerの分散型取引所で _代替可能_ トークンとXRPを売買するには、通常[OfferCreateトランザクション](../../references/protocol/transactions/types/offercreate.md)を送信します。この方法でトレードを行うためのコードと技術的ステップの詳細なウォークスルーについては、[分散型取引所でのトレード](../../tutorials/how-tos/use-tokens/trade-in-the-decentralized-exchange.md)をご覧ください。[Paymentトランザクション](../../references/protocol/transactions/types/payment.md)を使用して通貨を両替することも可能です。[クロスカレンシー支払い](../../concepts/payment-types/cross-currency-payments.md)を他のユーザに送ったり、長い[パス](../../concepts/tokens/fungible-tokens/paths.md)を使って裁定取引の機会を1つの操作にまとめることで、自分自身に送り返すこともできます。
|
||||
|
||||
NFTをトレードするためのコードと技術的な手順については、[JavaScriptを使用したNFTokenの送信](../../tutorials/javascript/nfts/transfer-nfts.md)をご覧ください。
|
||||
|
||||
|
||||
@@ -48,9 +48,9 @@ NFTをオークション形式で販売することができます。[NFTオー
|
||||
|
||||
### 準備金要件
|
||||
|
||||
販売用のNFTをミントする際には、XRPの準備金が必要となります。各NFTokenページには、2XRPの準備金が必要です。NFTokenページは16~32個のNFTを保管することができます。
|
||||
販売用のNFTをミントする際には、XRPの準備金が必要となります。各NFTokenページには、{% $env.PUBLIC_OWNER_RESERVE %}の準備金が必要です。NFTokenページは16~32個のNFTを保管することができます。
|
||||
|
||||
各`NFTokenOffer`オブジェクトは、2XRPの準備金が必要です。
|
||||
各`NFTokenOffer`オブジェクトは、{% $env.PUBLIC_OWNER_RESERVE %}の準備金が必要です。
|
||||
|
||||
`NFTokenOffer`を作成したり、NFTを売却したりする際には、些細な送金手数料(およそ6000ドロップ、または0.006 XRP)が発生します。大量に販売する場合、こうした少額の手数料はすぐにかさみますので、ビジネスのコストとして考慮する必要があります。
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ NFTokenのURLは、NFTのコンテンツが保存されている場所へのリ
|
||||
|
||||
[認可Minter](../../concepts/tokens/nfts/authorizing-another-minter.md)をご覧ください。
|
||||
|
||||
ミント済みのNFTは、`NFTokenPage`に記録されます。アカウント上の`NFTokenPage`1つにつき2XRPの準備金が必要です。[NFT準備金](../../concepts/tokens/nfts/reserve-requirements.md)をご覧ください。
|
||||
ミント済みのNFTは、`NFTokenPage`に記録されます。アカウント上の`NFTokenPage`1つにつき{% $env.PUBLIC_OWNER_RESERVE %}の準備金が必要です。[NFT準備金](../../concepts/tokens/nfts/reserve-requirements.md)をご覧ください。
|
||||
|
||||
各「NFTokenPage」は16~32個のNFTを保持します。大量のNFTをミントすると、あなたのXRPを大量に準備金としてロックすることになります。オンデマンドミント(または _遅延ミント_ )を行うことで、XRPを柔軟に維持することができます。[遅延ミント](../../concepts/tokens/nfts/batch-minting.md#mint-on-demand-lazy-minting)と[スクリプトミント](../../concepts/tokens/nfts/batch-minting.md#scripted-minting)をご覧下さい。
|
||||
|
||||
@@ -89,9 +89,9 @@ NFTをオークション形式で販売することができます。[NFTオー
|
||||
|
||||
#### 準備金要件
|
||||
|
||||
販売用のNFTをミントする際には、XRPの準備金が必要となります。各NFTokenページには、2XRPの準備金が必要です。NFTokenページは16~32個のNFTを保管することができます。
|
||||
販売用のNFTをミントする際には、XRPの準備金が必要となります。各NFTokenページには、{% $env.PUBLIC_OWNER_RESERVE %}の準備金が必要です。NFTokenページは16~32個のNFTを保管することができます。
|
||||
|
||||
各`NFTokenOffer`オブジェクトは、2XRPの準備金が必要です。
|
||||
各`NFTokenOffer`オブジェクトは、{% $env.PUBLIC_OWNER_RESERVE %}の準備金が必要です。
|
||||
|
||||
`NFTokenOffer`を作成したり、NFTを売却したりする際には、些細な送金手数料(およそ6000ドロップ、または0.006 XRP)が発生します。大量に販売する場合、こうした少額の手数料はすぐにかさみますので、ビジネスのコストとして考慮する必要があります。
|
||||
|
||||
|
||||
@@ -44,9 +44,9 @@ NFTをオークション形式で販売することができます。[NFTオー
|
||||
|
||||
### 準備金要件
|
||||
|
||||
販売用のNFTをミントする際には、XRPの準備金が必要となります。各NFTokenページには、2XRPの準備金が必要です。NFTokenページは16~32個のNFTを保管することができます。
|
||||
販売用のNFTをミントする際には、XRPの準備金が必要となります。各NFTokenページには、{% $env.PUBLIC_OWNER_RESERVE %}の準備金が必要です。NFTokenページは16~32個のNFTを保管することができます。
|
||||
|
||||
各`NFTokenOffer`オブジェクトは、2XRPの準備金が必要です。
|
||||
各`NFTokenOffer`オブジェクトは、{% $env.PUBLIC_OWNER_RESERVE %}の準備金が必要です。
|
||||
|
||||
`NFTokenOffer`を作成したり、NFTを売却したりする際には、些細な送金手数料(およそ6000ドロップ、または0.006 XRP)が発生します。大量に販売する場合、こうした少額の手数料はすぐにかさみますので、ビジネスのコストとして考慮する必要があります。
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ metadata:
|
||||
---
|
||||
# リソース
|
||||
|
||||
XRP Ledgerの理解や開発ためのリソース。Other resources to help understand the XRPL and develop on it.
|
||||
XRP Ledgerの理解や開発ためのリソース。
|
||||
|
||||
|
||||
{% child-pages /%}
|
||||
|
||||
262
about/card-stats-showcase.page.tsx
Normal file
262
about/card-stats-showcase.page.tsx
Normal file
@@ -0,0 +1,262 @@
|
||||
import { PageGrid, PageGridRow, PageGridCol } from "shared/components/PageGrid/page-grid";
|
||||
import { CardStats } from "shared/patterns/CardStats";
|
||||
import { Divider } from "shared/components/Divider";
|
||||
|
||||
export const frontmatter = {
|
||||
seo: {
|
||||
title: 'CardStats Pattern Showcase',
|
||||
description: "A comprehensive showcase of the CardStats pattern component demonstrating different configurations and color variants in the XRPL.org Design System.",
|
||||
}
|
||||
};
|
||||
|
||||
// Sample cards data matching Figma design (node 32051:2839)
|
||||
const sampleCards = [
|
||||
{
|
||||
statistic: "12",
|
||||
superscript: "+" as const,
|
||||
label: "Continuous uptime years",
|
||||
variant: "lilac" as const,
|
||||
primaryButton: { label: "Learn More", href: "#uptime" },
|
||||
},
|
||||
{
|
||||
statistic: "6M",
|
||||
superscript: "2" as const,
|
||||
label: "Active wallets",
|
||||
variant: "light-gray" as const,
|
||||
primaryButton: { label: "Explore", href: "#wallets" },
|
||||
},
|
||||
{
|
||||
statistic: "$1T",
|
||||
superscript: "+" as const,
|
||||
label: "Value transferred",
|
||||
variant: "green" as const,
|
||||
primaryButton: { label: "View Stats", href: "#value" },
|
||||
},
|
||||
{
|
||||
statistic: "3-5s",
|
||||
label: "Transaction finality",
|
||||
variant: "green" as const,
|
||||
primaryButton: { label: "Learn More", href: "#speed" },
|
||||
},
|
||||
{
|
||||
statistic: "70",
|
||||
superscript: "+" as const,
|
||||
label: "Ecosystem partners",
|
||||
variant: "dark-gray" as const,
|
||||
primaryButton: { label: "Meet Partners", href: "#partners" },
|
||||
},
|
||||
{
|
||||
statistic: "100K",
|
||||
superscript: "+" as const,
|
||||
label: "Developer community",
|
||||
variant: "lilac" as const,
|
||||
primaryButton: { label: "Join Us", href: "#community" },
|
||||
},
|
||||
];
|
||||
|
||||
export default function CardStatsShowcase() {
|
||||
return (
|
||||
<div className="landing">
|
||||
<div className="overflow-hidden">
|
||||
{/* Hero Section */}
|
||||
<section className="py-26 text-center">
|
||||
<div className="col-lg-8 mx-auto">
|
||||
<h6 className="eyebrow mb-3">Pattern Showcase</h6>
|
||||
<h1 className="mb-4">CardStats Pattern</h1>
|
||||
<p className="longform">
|
||||
A section pattern that displays a heading, optional description, and a responsive
|
||||
grid of CardStat components. Designed for showcasing key statistics and metrics.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Design Tokens Info */}
|
||||
<PageGrid className="py-10">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Design Specifications</h2>
|
||||
<div className="d-flex flex-wrap gap-6">
|
||||
<div style={{ flex: '1 1 250px' }}>
|
||||
<h6 className="mb-3">Typography</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Heading:</strong> heading-md (Tobias Light)</li>
|
||||
<li><strong>Description:</strong> body-l (Booton Light)</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 250px' }}>
|
||||
<h6 className="mb-3">Grid Layout</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Mobile:</strong> 2 columns</li>
|
||||
<li><strong>Tablet:</strong> 2 columns</li>
|
||||
<li><strong>Desktop:</strong> 3 columns</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style={{ flex: '1 1 250px' }}>
|
||||
<h6 className="mb-3">Color Variants</h6>
|
||||
<ul className="mb-0">
|
||||
<li><strong>Lilac:</strong> #C0A7FF</li>
|
||||
<li><strong>Green:</strong> #21E46B</li>
|
||||
<li><strong>Light Gray:</strong> #E6EAF0</li>
|
||||
<li><strong>Dark Gray:</strong> #CAD4DF</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
<Divider />
|
||||
|
||||
{/* Full Example - 6 Cards with Heading and Description */}
|
||||
<section>
|
||||
<CardStats
|
||||
heading="Blockchain Trusted at Scale"
|
||||
description="Streamline development and build powerful RWA tokenization solutions with XRP Ledger's comprehensive developer toolset."
|
||||
cards={sampleCards}
|
||||
/>
|
||||
</section>
|
||||
|
||||
<Divider />
|
||||
|
||||
{/* Heading Only - No Description */}
|
||||
<section>
|
||||
<CardStats
|
||||
heading="XRPL Network Statistics"
|
||||
cards={sampleCards.slice(0, 3)}
|
||||
/>
|
||||
</section>
|
||||
|
||||
<Divider />
|
||||
|
||||
{/* 4 Cards Example */}
|
||||
<section>
|
||||
<CardStats
|
||||
heading="Why Build on XRPL?"
|
||||
description="The XRP Ledger provides enterprise-grade infrastructure for building the future of finance."
|
||||
cards={sampleCards.slice(0, 4)}
|
||||
/>
|
||||
</section>
|
||||
|
||||
<Divider />
|
||||
|
||||
{/* Two Buttons Example */}
|
||||
<PageGrid className="py-10">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-4">Two Button Cards</h2>
|
||||
<p className="mb-8">Cards can include both primary and secondary buttons for multiple CTAs.</p>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
<section>
|
||||
<CardStats
|
||||
heading="Get Started with XRPL"
|
||||
description="Explore the XRP Ledger ecosystem with comprehensive documentation and developer resources."
|
||||
cards={[
|
||||
{
|
||||
statistic: "12",
|
||||
superscript: "+" as const,
|
||||
label: "Continuous uptime years",
|
||||
variant: "lilac" as const,
|
||||
primaryButton: { label: "Learn More", href: "#learn" },
|
||||
secondaryButton: { label: "View Docs", href: "#docs" },
|
||||
},
|
||||
{
|
||||
statistic: "6M",
|
||||
superscript: "+" as const,
|
||||
label: "Active wallets",
|
||||
variant: "green" as const,
|
||||
primaryButton: { label: "Get Started", href: "#start" },
|
||||
secondaryButton: { label: "Explore", href: "#explore" },
|
||||
},
|
||||
{
|
||||
statistic: "$1T",
|
||||
superscript: "+" as const,
|
||||
label: "Value transferred",
|
||||
variant: "light-gray" as const,
|
||||
primaryButton: { label: "View Stats", href: "#stats" },
|
||||
secondaryButton: { label: "Learn More", href: "#about" },
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</section>
|
||||
|
||||
<Divider />
|
||||
|
||||
{/* Code Examples */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-8">Code Examples</h2>
|
||||
|
||||
<h5 className="mb-4">Basic Usage</h5>
|
||||
<div className="p-4 mb-8 br-4" style={{ backgroundColor: '#f5f5f7', fontFamily: 'monospace', fontSize: '14px' }}>
|
||||
<pre style={{ margin: 0, whiteSpace: 'pre-wrap', color: '#000' }}>{`import { CardStats } from 'shared/patterns/CardStats';
|
||||
|
||||
<CardStats
|
||||
heading="Blockchain Trusted at Scale"
|
||||
description="Optional description text here."
|
||||
cards={[
|
||||
{
|
||||
statistic: "12",
|
||||
superscript: "+",
|
||||
label: "Continuous uptime years",
|
||||
variant: "lilac",
|
||||
primaryButton: { label: "Learn More", href: "/docs" }
|
||||
},
|
||||
{
|
||||
statistic: "6M",
|
||||
label: "Active wallets",
|
||||
variant: "green"
|
||||
},
|
||||
// ... more cards
|
||||
]}
|
||||
/>`}</pre>
|
||||
</div>
|
||||
|
||||
<h5 className="mb-4">Without Description</h5>
|
||||
<div className="p-4 mb-8 br-4" style={{ backgroundColor: '#f5f5f7', fontFamily: 'monospace', fontSize: '14px' }}>
|
||||
<pre style={{ margin: 0, whiteSpace: 'pre-wrap', color: '#000' }}>{`<CardStats
|
||||
heading="XRPL Network Statistics"
|
||||
cards={statsCards}
|
||||
/>`}</pre>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
|
||||
<Divider />
|
||||
|
||||
{/* Design References */}
|
||||
<PageGrid className="py-26">
|
||||
<PageGridRow>
|
||||
<PageGridCol span={12}>
|
||||
<h2 className="h4 mb-6">Design References</h2>
|
||||
<div className="d-flex flex-column gap-3">
|
||||
<div>
|
||||
<strong>Figma Design:</strong>{' '}
|
||||
<a href="https://www.figma.com/design/drnQQXnK9Q67MTPPKQsY9l/Section-Cards---Stats?node-id=32051-2839&m=dev" target="_blank" rel="noopener noreferrer">
|
||||
Section Cards - Stats (Figma)
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<strong>Pattern Location:</strong>{' '}
|
||||
<code>shared/patterns/CardStats/</code>
|
||||
</div>
|
||||
<div>
|
||||
<strong>Component Used:</strong>{' '}
|
||||
<code>shared/components/CardStat/</code>
|
||||
</div>
|
||||
<div>
|
||||
<strong>Color Tokens:</strong>{' '}
|
||||
<code>styles/_colors.scss</code>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
---
|
||||
html: private-network-with-docker.html
|
||||
name: Run a Private Network with Docker
|
||||
parent: use-stand-alone-mode.html
|
||||
seo:
|
||||
description: Learn how to set up your own XRP private ledger network with Docker and Docker Compose.
|
||||
description: Learn how to set up your own XRP private ledger network with Docker and Docker Compose.
|
||||
labels:
|
||||
- Core Server
|
||||
---
|
||||
@@ -261,17 +259,25 @@ For each validator node, follow these steps:
|
||||
|
||||
Now that you have created the configuration files for your validators, you need to add a `validator.txt` file. This file defines which validators are trusted by your network.
|
||||
|
||||
For each node, follow these steps:
|
||||
Follow these steps to add validator configuration files to each validator:
|
||||
|
||||
1. Create a `validators.txt` file in the configuration directory.
|
||||
1. Create a `validators.txt` file.
|
||||
2. Copy the public keys from the `validator-keys.json` files that you generated at the [beginning](#generate-the-validator-keys) of the tutorial.
|
||||
3. Add the public keys of _all_ the validators. For example:
|
||||
|
||||
```
|
||||
[validators]
|
||||
nHBgaEDL8buUECuk4Rck4QBYtmUgbAoeYJLpWLzG9iXsznTRYrQu
|
||||
nHBCHX7iLDTyap3LumqBNuKgG7JLA5tc6MSJxpLs3gjkwpu836mY
|
||||
nHU5STUKTgWdreVqJDx6TopLUymzRUZshTSGcWNtjfByJkYdiiRc
|
||||
nHBgaEDL8buUECuk4Rck4QBYtmUgbAoeYJLpWLzG9iXsznTRYrQu
|
||||
nHBCHX7iLDTyap3LumqBNuKgG7JLA5tc6MSJxpLs3gjkwpu836mY
|
||||
nHU5STUKTgWdreVqJDx6TopLUymzRUZshTSGcWNtjfByJkYdiiRc
|
||||
```
|
||||
|
||||
4. Copy the same `validators.txt` file into the `config` directory for _each_ validator.
|
||||
|
||||
```sh
|
||||
cp validators.txt validator_1/config/
|
||||
cp validators.txt validator_2/config/
|
||||
cp validators.txt validator_3/config/
|
||||
```
|
||||
|
||||
## Start the Network
|
||||
@@ -285,7 +291,6 @@ To start running your private network, follow these steps:
|
||||
1. Create a `docker-compose.yml` file in the root of the private network directory, `xrpl-private-network`, and add the following content:
|
||||
|
||||
```
|
||||
version: "3.9"
|
||||
services:
|
||||
validator_1:
|
||||
platform: linux/amd64
|
||||
@@ -338,9 +343,15 @@ To start running your private network, follow these steps:
|
||||
|
||||
Now that the private ledger network is up, you need to verify that **each** validator node is running as expected:
|
||||
|
||||
1. In your terminal, run `docker exec -it <validator_name> bin/bash` to execute commands in the validator Docker container. Replace `<validator_name>` with the name of the container (e.g., `validator_1`).
|
||||
1. Open a terminal in the validator_1 container:
|
||||
|
||||
2. Run the `rippled server_info` command to check the state of the validator:
|
||||
```
|
||||
docker exec -it validator_1 bin/bash
|
||||
```
|
||||
|
||||
{% admonition type="success" name="Tip" %}You can use the same syntax to execute commands in the other Docker containers. Replace `bin/bash` with the command to run and `validator_1` with the name of the container.{% /admonition %}
|
||||
|
||||
3. Run the `rippled server_info` command to check the state of the validator:
|
||||
|
||||
```
|
||||
rippled server_info | grep server_state
|
||||
@@ -354,7 +365,7 @@ Now that the private ledger network is up, you need to verify that **each** vali
|
||||
|
||||
{% admonition type="info" name="Note" %}If the state is not updated to **proposing**, repeat step **2** after a few minutes as the ledger can take some time to update.{% /admonition %}
|
||||
|
||||
3. Verify the number of peers connected to the validator.
|
||||
4. Verify the number of peers connected to the validator.
|
||||
|
||||
```
|
||||
rippled server_info | grep peers
|
||||
@@ -366,10 +377,10 @@ Now that the private ledger network is up, you need to verify that **each** vali
|
||||
"peers" : 2
|
||||
```
|
||||
|
||||
4. Run the following command to check the genesis account information:
|
||||
5. Run the following command to check the genesis account information:
|
||||
|
||||
```
|
||||
rippled account_info rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh validated strict
|
||||
rippled account_info rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh validated
|
||||
```
|
||||
|
||||
Sample Output:
|
||||
@@ -396,7 +407,9 @@ Now that the private ledger network is up, you need to verify that **each** vali
|
||||
}
|
||||
```
|
||||
|
||||
5. To leave the Docker container shell, enter `exit` in the terminal.
|
||||
If the ledger does not have `"validated": true`, double check that you put matching `validators.txt` files with all three public keys in each container's config directory, and restart the container if you need to make changes.
|
||||
|
||||
6. To leave the Docker container shell, enter `exit` in the terminal.
|
||||
|
||||
### Perform a test transaction
|
||||
|
||||
@@ -439,7 +452,7 @@ Perform a **test** transaction to ensure you can send money to an account.
|
||||
|
||||
```
|
||||
docker exec -it validator_1 \
|
||||
rippled account_info r9wRwVgL2vWVnKhTPdtxva5vdH7FNw1zPs validated strict
|
||||
rippled account_info r9wRwVgL2vWVnKhTPdtxva5vdH7FNw1zPs validated
|
||||
```
|
||||
|
||||
Sample Output:
|
||||
|
||||
@@ -57,6 +57,7 @@ Flags are properties or other options associated with the `NFToken` object.
|
||||
| `lsfTrustLine` | `0x0004` | **DEPRECATED** If enabled, automatically create [trust lines](../../../concepts/tokens/fungible-tokens/index.md) to hold transfer fees. Otherwise, buying or selling this `NFToken` for a fungible token amount fails if the issuer does not have a trust line for that token. The [fixRemoveNFTokenAutoTrustLine amendment][] makes it invalid to enable this flag. |
|
||||
| `lsfTransferable` | `0x0008` | If enabled, this `NFToken` can be transferred from one holder to another. Otherwise, it can only be transferred to or from the issuer. |
|
||||
| `lsfReservedFlag` | `0x8000` | This flag is reserved for future use. Attempts to set this flag fail. |
|
||||
| `lsfMutable` | `0x0010` | If enabled, the `URI` field of the `NFToken` can be updated using the `NFTokenModify` transaction. |
|
||||
|
||||
`NFToken` flags are immutable: they can only be set during the [NFTokenMint transaction][] and cannot be changed later.
|
||||
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
|
||||
// Color variants
|
||||
$bds-card-stat-lilac-bg: $lilac-300;
|
||||
$bds-card-stat-green-bg: $green-300; // #EAFCF1
|
||||
$bds-card-stat-light-gray-bg: #E6EAF0; // Light gray
|
||||
$bds-card-stat-dark-gray-bg: #CAD4DF; // Dark gray
|
||||
$bds-card-stat-green-bg: $green-300; // #EAFCF1
|
||||
$bds-card-stat-light-gray-bg: #E6EAF0; // Light gray
|
||||
$bds-card-stat-dark-gray-bg: #CAD4DF; // Dark gray
|
||||
|
||||
// Text colors
|
||||
$bds-card-stat-text: $black; // Neutral black
|
||||
$bds-card-stat-text: $black; // Neutral black
|
||||
|
||||
// Spacing
|
||||
$bds-card-stat-gap: 8px;
|
||||
@@ -44,16 +44,16 @@ $bds-card-stat-transition-timing: cubic-bezier(0.98, 0.12, 0.12, 0.98);
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
min-height: 200px;
|
||||
|
||||
|
||||
// Visual
|
||||
background-color: $bds-card-stat-lilac-bg; // Default
|
||||
|
||||
|
||||
// Typography
|
||||
color: $bds-card-stat-text;
|
||||
|
||||
|
||||
// Transitions
|
||||
transition: transform $bds-card-stat-transition-duration $bds-card-stat-transition-timing;
|
||||
|
||||
|
||||
// Content wrapper
|
||||
&__content {
|
||||
display: flex;
|
||||
@@ -62,35 +62,43 @@ $bds-card-stat-transition-timing: cubic-bezier(0.98, 0.12, 0.12, 0.98);
|
||||
flex: 1;
|
||||
padding: 8px;
|
||||
gap: 4px;
|
||||
|
||||
|
||||
// Tablet (md) breakpoint
|
||||
@include media-breakpoint-up(md) {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
|
||||
// Desktop (lg+) breakpoint
|
||||
@include media-breakpoint-up(lg) {
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Text section
|
||||
&__text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
|
||||
// Statistic (large number)
|
||||
&__statistic {
|
||||
@include type(display-lg);
|
||||
margin-bottom: 0;
|
||||
|
||||
sup {
|
||||
top: -0.4em;
|
||||
font-size: 0.7em;
|
||||
|
||||
// Numeric superscript modifier - smaller size for numbers
|
||||
&.bds-card-stat__superscript--numeric {
|
||||
font-size: 0.5em;
|
||||
top: -0.75em;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Buttons section
|
||||
&__buttons {
|
||||
display: flex;
|
||||
@@ -130,11 +138,12 @@ $bds-card-stat-transition-timing: cubic-bezier(0.98, 0.12, 0.12, 0.98);
|
||||
|
||||
html.dark {
|
||||
.bds-card-stat {
|
||||
|
||||
// Light gray variant gets dark-gray background in dark mode
|
||||
&--light-gray {
|
||||
background-color: $bds-card-stat-dark-gray-bg; // Darker gray for dark mode
|
||||
}
|
||||
|
||||
|
||||
// Dark gray variant gets darker gray background in dark mode
|
||||
&--dark-gray {
|
||||
background-color: #8A919A; // Darker gray for dark mode
|
||||
@@ -149,11 +158,12 @@ html.dark {
|
||||
.bds-card-stat {
|
||||
// Base (mobile) - ~200px height
|
||||
min-height: 200px;
|
||||
|
||||
|
||||
// Tablet (md) - ~208px height
|
||||
@include media-breakpoint-up(md) {
|
||||
min-height: 208px;
|
||||
}
|
||||
|
||||
// Desktop (lg+) - ~298px height (more vertical space)
|
||||
@include media-breakpoint-up(lg) {
|
||||
min-height: 298px;
|
||||
|
||||
@@ -13,8 +13,8 @@ interface ButtonConfig {
|
||||
export interface CardStatProps {
|
||||
/** The main statistic to display (e.g., "6 Million+") */
|
||||
statistic: string;
|
||||
/** Superscript text for the statistic */
|
||||
superscript?: '*' | '+' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '0';
|
||||
/** Superscript text for the statistic (symbols like '*', '+' or numeric strings like '1', '12') */
|
||||
superscript?: string;
|
||||
/** Descriptive label for the statistic */
|
||||
label: string;
|
||||
/** Background color variant
|
||||
@@ -72,52 +72,43 @@ export const CardStat: React.FC<CardStatProps> = ({
|
||||
|
||||
const hasButtons = primaryButton || secondaryButton;
|
||||
|
||||
// Check if superscript is a number (one or more digits), excluding + or - signs
|
||||
const isNumericSuperscript = superscript && /^[0-9]+$/.test(superscript);
|
||||
|
||||
return (
|
||||
<div className={classNames}>
|
||||
<div className="bds-card-stat__content">
|
||||
{/* Text section */}
|
||||
<div className="bds-card-stat__text">
|
||||
<div className="bds-card-stat__statistic">
|
||||
{statistic}{superscript && <sup>{superscript}</sup>}</div>
|
||||
{statistic}{superscript && <sup className={isNumericSuperscript ? 'bds-card-stat__superscript--numeric' : ''}>{superscript}</sup>}</div>
|
||||
<div className="body-r">{label}</div>
|
||||
</div>
|
||||
|
||||
{/* Buttons section */}
|
||||
{/* Buttons section */}
|
||||
{hasButtons && (
|
||||
<div className="bds-card-stat__buttons">
|
||||
{primaryButton && (
|
||||
primaryButton.href ? (
|
||||
<a href={primaryButton.href}>
|
||||
<Button variant="primary" color="black">
|
||||
{primaryButton.label}
|
||||
</Button>
|
||||
</a>
|
||||
) : (
|
||||
<Button
|
||||
variant="primary"
|
||||
color="black"
|
||||
onClick={primaryButton.onClick}
|
||||
>
|
||||
{primaryButton.label}
|
||||
</Button>
|
||||
)
|
||||
<Button
|
||||
forceColor
|
||||
variant="primary"
|
||||
color="black"
|
||||
href={primaryButton.href}
|
||||
onClick={primaryButton.onClick}
|
||||
>
|
||||
{primaryButton.label}
|
||||
</Button>
|
||||
)}
|
||||
{secondaryButton && (
|
||||
secondaryButton.href ? (
|
||||
<a href={secondaryButton.href}>
|
||||
<Button variant="secondary" color="black">
|
||||
{secondaryButton.label}
|
||||
</Button>
|
||||
</a>
|
||||
) : (
|
||||
<Button
|
||||
variant="secondary"
|
||||
color="black"
|
||||
onClick={secondaryButton.onClick}
|
||||
>
|
||||
{secondaryButton.label}
|
||||
</Button>
|
||||
)
|
||||
<Button
|
||||
forceColor
|
||||
variant="secondary"
|
||||
color="black"
|
||||
href={secondaryButton.href}
|
||||
onClick={secondaryButton.onClick}
|
||||
>
|
||||
{secondaryButton.label}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
154
shared/patterns/CardStats/CardStats.md
Normal file
154
shared/patterns/CardStats/CardStats.md
Normal file
@@ -0,0 +1,154 @@
|
||||
# CardStats Pattern
|
||||
|
||||
A section pattern that displays a heading, optional description, and a responsive grid of `CardStat` components. Designed for showcasing key statistics and metrics on landing pages.
|
||||
|
||||
## Features
|
||||
|
||||
- Responsive grid layout (2 columns mobile/tablet, 3 columns desktop)
|
||||
- Heading with `heading-md` typography (Tobias Light)
|
||||
- Optional description with `body-l` typography (Booton Light)
|
||||
- Proper spacing using `PageGrid` for container and alignment
|
||||
- Full dark mode support
|
||||
- Reuses the `CardStat` component for consistent styling
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx
|
||||
import { CardStats } from 'shared/patterns/CardStats';
|
||||
|
||||
<CardStats
|
||||
heading="Blockchain Trusted at Scale"
|
||||
description="Streamline development and build powerful RWA tokenization solutions with XRP Ledger's comprehensive developer toolset."
|
||||
cards={[
|
||||
{
|
||||
statistic: "12",
|
||||
superscript: "+",
|
||||
label: "Continuous uptime years",
|
||||
variant: "lilac",
|
||||
primaryButton: { label: "Learn More", href: "/docs" }
|
||||
},
|
||||
{
|
||||
statistic: "6M",
|
||||
superscript: "2",
|
||||
label: "Active wallets",
|
||||
variant: "light-gray",
|
||||
primaryButton: { label: "Explore", href: "/wallets" }
|
||||
},
|
||||
{
|
||||
statistic: "$1T",
|
||||
superscript: "+",
|
||||
label: "Value transferred",
|
||||
variant: "green",
|
||||
primaryButton: { label: "View Stats", href: "/stats" }
|
||||
},
|
||||
// ... more cards
|
||||
]}
|
||||
/>
|
||||
```
|
||||
|
||||
## Props
|
||||
|
||||
| Prop | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `heading` | `React.ReactNode` | Yes | Section heading text |
|
||||
| `description` | `React.ReactNode` | No | Optional section description text |
|
||||
| `cards` | `CardStatProps[]` | Yes | Array of CardStat configurations |
|
||||
| `className` | `string` | No | Additional CSS classes |
|
||||
|
||||
### CardStat Configuration
|
||||
|
||||
Each card in the `cards` array accepts the following props:
|
||||
|
||||
| Prop | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `statistic` | `string` | Yes | The main statistic to display (e.g., "6M", "$1T") |
|
||||
| `superscript` | `'+' \| '*' \| '1'-'9' \| '0'` | No | Superscript text for the statistic |
|
||||
| `label` | `string` | Yes | Descriptive label for the statistic |
|
||||
| `variant` | `'lilac' \| 'green' \| 'light-gray' \| 'dark-gray'` | No | Background color variant (default: 'lilac') |
|
||||
| `primaryButton` | `{ label: string, href?: string, onClick?: () => void }` | No | Primary CTA button |
|
||||
| `secondaryButton` | `{ label: string, href?: string, onClick?: () => void }` | No | Secondary CTA button |
|
||||
|
||||
## Color Variants
|
||||
|
||||
| Variant | Color | Hex | Use Case |
|
||||
|---------|-------|-----|----------|
|
||||
| `lilac` | Lilac 300 | #C0A7FF | User metrics, community stats |
|
||||
| `green` | Green 300 | #21E46B | Financial metrics, growth indicators |
|
||||
| `light-gray` | Gray 200 | #E6EAF0 | Technical stats, reliability metrics |
|
||||
| `dark-gray` | Gray 300 | #CAD4DF | Neutral metrics, secondary info |
|
||||
|
||||
## Responsive Behavior
|
||||
|
||||
Uses breakpoints from `styles/_breakpoints.scss`:
|
||||
|
||||
| Breakpoint | Width | Columns | Card Gap |
|
||||
|------------|-------|---------|----------|
|
||||
| xs (Mobile) | 0 - 575px | 1 | 8px |
|
||||
| md (Tablet) | 576px - 991px | 2 | 8px |
|
||||
| lg (Desktop) | 992px+ | 3 | 8px |
|
||||
|
||||
## Examples
|
||||
|
||||
### With Description
|
||||
|
||||
```tsx
|
||||
<CardStats
|
||||
heading="Blockchain Trusted at Scale"
|
||||
description="Streamline development and build powerful RWA tokenization solutions."
|
||||
cards={statsCards}
|
||||
/>
|
||||
```
|
||||
|
||||
### Without Description (Heading Only)
|
||||
|
||||
```tsx
|
||||
<CardStats
|
||||
heading="XRPL Network Statistics"
|
||||
cards={statsCards}
|
||||
/>
|
||||
```
|
||||
|
||||
### Mixed Card Variants
|
||||
|
||||
```tsx
|
||||
<CardStats
|
||||
heading="Why Build on XRPL?"
|
||||
cards={[
|
||||
{ statistic: "12", superscript: "+", label: "Uptime years", variant: "lilac" },
|
||||
{ statistic: "6M", label: "Active wallets", variant: "green" },
|
||||
{ statistic: "3-5s", label: "Transaction finality", variant: "light-gray" },
|
||||
]}
|
||||
/>
|
||||
```
|
||||
|
||||
## CSS Classes
|
||||
|
||||
| Class | Description |
|
||||
|-------|-------------|
|
||||
| `.bds-card-stats` | Base section container |
|
||||
| `.bds-card-stats__header` | Header wrapper for heading and description |
|
||||
| `.bds-card-stats__heading` | Section heading (uses `.h-md`) |
|
||||
| `.bds-card-stats__description` | Section description (uses `.body-l`) |
|
||||
| `.bds-card-stats__cards` | Cards grid container |
|
||||
| `.bds-card-stats__card-wrapper` | Individual card wrapper |
|
||||
|
||||
## Design References
|
||||
|
||||
- **Figma Design**: [Section Cards - Stats](https://www.figma.com/design/drnQQXnK9Q67MTPPKQsY9l/Section-Cards---Stats?node-id=32051-2839&m=dev)
|
||||
- **Showcase Page**: `/about/card-stats-showcase`
|
||||
- **Pattern Location**: `shared/patterns/CardStats/`
|
||||
- **Component Used**: `shared/components/CardStat/`
|
||||
|
||||
## Accessibility
|
||||
|
||||
- Uses semantic HTML with `<section>` and proper heading hierarchy
|
||||
- CardStat buttons include proper focus states
|
||||
- Color contrast meets WCAG AA requirements
|
||||
- Responsive layout ensures readability on all devices
|
||||
|
||||
## Version History
|
||||
|
||||
- Initial implementation: January 2026
|
||||
- Figma design alignment with 4 color variants
|
||||
- Responsive grid layout with PageGrid integration
|
||||
|
||||
176
shared/patterns/CardStats/CardStats.scss
Normal file
176
shared/patterns/CardStats/CardStats.scss
Normal file
@@ -0,0 +1,176 @@
|
||||
// BDS CardStats Pattern Styles
|
||||
// Brand Design System - Section with heading, description, and grid of CardStat components
|
||||
//
|
||||
// Naming Convention: BEM with 'bds' namespace
|
||||
// .bds-card-stats - Base section container
|
||||
// .bds-card-stats__header - Header wrapper for heading and description
|
||||
// .bds-card-stats__heading - Section heading (uses .h-md)
|
||||
// .bds-card-stats__description - Section description (uses .body-l)
|
||||
// .bds-card-stats__cards - Cards grid container
|
||||
// .bds-card-stats__card-wrapper - Individual card wrapper
|
||||
//
|
||||
// Design tokens from Figma:
|
||||
// Light Mode:
|
||||
// - Background: White (#FFFFFF)
|
||||
// - Heading: Neutral Black (#141414) → $black
|
||||
// - Description: Neutral Black (#141414) → $black
|
||||
//
|
||||
// Dark Mode:
|
||||
// - Background: transparent (inherits page background)
|
||||
// - Heading: Neutral White (#FFFFFF) → $white
|
||||
// - Description: Neutral White (#FFFFFF) → $white
|
||||
//
|
||||
// - Header content max-width: 808px (approximately 8 columns at desktop)
|
||||
// - Gap between heading and description: 16px
|
||||
// - Gap between cards: 8px (matches $bds-grid-gutter)
|
||||
|
||||
// =============================================================================
|
||||
// Design Tokens (from Figma)
|
||||
// =============================================================================
|
||||
|
||||
$bds-grid-gutter: 8px;
|
||||
|
||||
// Color tokens - Light Mode (from Figma: node 32051-2839)
|
||||
$bds-card-stats-bg-light: $white; // --neutral/white (#FFFFFF)
|
||||
$bds-card-stats-heading-light: $black; // --neutral/black (#141414)
|
||||
$bds-card-stats-description-light: $black; // --neutral/black (#141414)
|
||||
|
||||
// Color tokens - Dark Mode (from Figma: node 32051-2524)
|
||||
$bds-card-stats-bg-dark: transparent; // Inherits page background
|
||||
$bds-card-stats-heading-dark: $white; // --neutral/white (#FFFFFF)
|
||||
$bds-card-stats-description-dark: $white; // --neutral/white (#FFFFFF)
|
||||
|
||||
// Spacing - Header gap (between heading and description)
|
||||
$bds-card-stats-header-gap-sm: 8px; // Mobile: 8px
|
||||
$bds-card-stats-header-gap-md: 8px; // Tablet: 8px
|
||||
$bds-card-stats-header-gap-lg: 16px; // Desktop: 16px
|
||||
|
||||
// Spacing - Section gap (between header and cards)
|
||||
$bds-card-stats-section-gap-sm: 24px; // Mobile: 24px
|
||||
$bds-card-stats-section-gap-md: 32px; // Tablet: 32px
|
||||
$bds-card-stats-section-gap-lg: 40px; // Desktop: 40px
|
||||
|
||||
// Spacing - Section padding
|
||||
$bds-card-stats-padding-y-sm: 24px; // Mobile: 24px
|
||||
$bds-card-stats-padding-y-md: 32px; // Tablet: 32px
|
||||
$bds-card-stats-padding-y-lg: 40px; // Desktop: 40px
|
||||
|
||||
// =============================================================================
|
||||
// Base Section Styles
|
||||
// =============================================================================
|
||||
|
||||
.bds-card-stats {
|
||||
// Layout
|
||||
display: block;
|
||||
width: 100%;
|
||||
background-color: $bds-card-stats-bg-light;
|
||||
|
||||
// Vertical padding
|
||||
padding-top: $bds-card-stats-padding-y-sm;
|
||||
padding-bottom: $bds-card-stats-padding-y-sm;
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
padding-top: $bds-card-stats-padding-y-md;
|
||||
padding-bottom: $bds-card-stats-padding-y-md;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(lg) {
|
||||
padding-top: $bds-card-stats-padding-y-lg;
|
||||
padding-bottom: $bds-card-stats-padding-y-lg;
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Header Styles
|
||||
// =============================================================================
|
||||
|
||||
.bds-card-stats__header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $bds-card-stats-header-gap-sm;
|
||||
max-width: 808px;
|
||||
|
||||
// Responsive header gap
|
||||
@include media-breakpoint-up(md) {
|
||||
gap: $bds-card-stats-header-gap-md;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(lg) {
|
||||
gap: $bds-card-stats-header-gap-lg;
|
||||
}
|
||||
|
||||
// Margin below header (gap between header and cards)
|
||||
margin-bottom: $bds-card-stats-section-gap-sm;
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
margin-bottom: $bds-card-stats-section-gap-md;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(lg) {
|
||||
margin-bottom: $bds-card-stats-section-gap-lg;
|
||||
}
|
||||
}
|
||||
|
||||
.bds-card-stats__heading {
|
||||
color: $black;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.bds-card-stats__description {
|
||||
color: $black;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Cards Grid Styles
|
||||
// Breakpoints from _breakpoints.scss:
|
||||
// - xs: 0 (mobile - 1 column)
|
||||
// - sm/md: 576px (tablet - 2 columns)
|
||||
// - lg: 992px (desktop - 3 columns)
|
||||
// - xl: 1280px, xxl: 1512px
|
||||
// =============================================================================
|
||||
|
||||
.bds-card-stats__cards {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $bds-grid-gutter;
|
||||
width: 100%;
|
||||
|
||||
// Tablet and above: switch to flex-wrap row layout
|
||||
@include media-breakpoint-up(md) {
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.bds-card-stats__card-wrapper {
|
||||
// Mobile (base): 1 column - full width
|
||||
flex: 0 0 100%;
|
||||
min-width: 0;
|
||||
|
||||
// Tablet (md - 576px): 2 columns
|
||||
@include media-breakpoint-up(md) {
|
||||
flex: 0 0 calc(50% - #{$bds-grid-gutter / 2});
|
||||
}
|
||||
|
||||
// Desktop (lg - 992px): 3 columns
|
||||
@include media-breakpoint-up(lg) {
|
||||
flex: 0 0 calc(33.333% - #{$bds-grid-gutter * 2 / 3});
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Dark Mode Styles
|
||||
// =============================================================================
|
||||
|
||||
html.dark {
|
||||
.bds-card-stats {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.bds-card-stats__heading,
|
||||
.bds-card-stats__description {
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
111
shared/patterns/CardStats/CardStats.tsx
Normal file
111
shared/patterns/CardStats/CardStats.tsx
Normal file
@@ -0,0 +1,111 @@
|
||||
import React from 'react';
|
||||
import clsx from 'clsx';
|
||||
import { CardStat, CardStatProps } from '../../components/CardStat';
|
||||
import { PageGrid } from '../../components/PageGrid/page-grid';
|
||||
|
||||
/**
|
||||
* Configuration for a single stat card in the CardStats pattern
|
||||
*/
|
||||
export type CardStatsCardConfig = CardStatProps;
|
||||
|
||||
/**
|
||||
* Props for the CardStats pattern component
|
||||
*/
|
||||
export interface CardStatsProps extends React.ComponentPropsWithoutRef<'section'> {
|
||||
/** Section heading text */
|
||||
heading: React.ReactNode;
|
||||
/** Optional section description text */
|
||||
description?: React.ReactNode;
|
||||
/** Array of CardStat configurations */
|
||||
cards: readonly CardStatsCardConfig[];
|
||||
}
|
||||
|
||||
/**
|
||||
* CardStats Pattern Component
|
||||
*
|
||||
* A section pattern that displays a heading, optional description, and a responsive
|
||||
* grid of CardStat components. Designed for showcasing key statistics and metrics.
|
||||
*
|
||||
* Features:
|
||||
* - Responsive grid layout (2 columns mobile/tablet, 3 columns desktop)
|
||||
* - Heading with `heading-md` typography (Tobias Light)
|
||||
* - Optional description with `body-l` typography (Booton Light)
|
||||
* - Proper spacing using PageGrid for container and alignment
|
||||
* - Full dark mode support
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <CardStats
|
||||
* heading="Blockchain Trusted at Scale"
|
||||
* description="Streamline development and build powerful RWA tokenization solutions."
|
||||
* cards={[
|
||||
* {
|
||||
* statistic: "12",
|
||||
* superscript: "+",
|
||||
* label: "Continuous uptime years",
|
||||
* variant: "lilac",
|
||||
* primaryButton: { label: "Learn More", href: "/docs" }
|
||||
* },
|
||||
* {
|
||||
* statistic: "6M",
|
||||
* superscript: "2",
|
||||
* label: "Active wallets",
|
||||
* variant: "light-gray"
|
||||
* },
|
||||
* // ... more cards
|
||||
* ]}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export const CardStats = React.forwardRef<HTMLElement, CardStatsProps>(
|
||||
(props, ref) => {
|
||||
const { heading, description, cards, className, ...rest } = props;
|
||||
|
||||
// Early return for empty cards array
|
||||
if (cards.length === 0) {
|
||||
console.warn('CardStats: No cards provided');
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<section
|
||||
ref={ref}
|
||||
className={clsx('bds-card-stats', className)}
|
||||
{...rest}
|
||||
>
|
||||
<PageGrid>
|
||||
<PageGrid.Row>
|
||||
<PageGrid.Col span={{ base: 4, md: 8, lg: 12 }}>
|
||||
{/* Header section */}
|
||||
<div className="bds-card-stats__header">
|
||||
<h2 className="bds-card-stats__heading h-md">{heading}</h2>
|
||||
{description && (
|
||||
<p className="bds-card-stats__description body-l">
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Cards grid */}
|
||||
<div className="bds-card-stats__cards">
|
||||
{cards.map((cardConfig, index) => (
|
||||
<div
|
||||
key={`card-stat-${index}`}
|
||||
className="bds-card-stats__card-wrapper"
|
||||
>
|
||||
<CardStat {...cardConfig} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</PageGrid.Col>
|
||||
</PageGrid.Row>
|
||||
</PageGrid>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
CardStats.displayName = 'CardStats';
|
||||
|
||||
export default CardStats;
|
||||
|
||||
3
shared/patterns/CardStats/index.ts
Normal file
3
shared/patterns/CardStats/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export { CardStats, type CardStatsProps, type CardStatsCardConfig } from './CardStats';
|
||||
export { default } from './CardStats';
|
||||
|
||||
@@ -13313,6 +13313,11 @@ html.dark .bds-btn--tertiary:not(.bds-btn--black):disabled, html.dark .bds-btn--
|
||||
top: -0.4em;
|
||||
font-size: 0.7em;
|
||||
}
|
||||
.bds-card-stat__statistic sup.bds-card-stat__superscript--numeric {
|
||||
font-size: 0.5em;
|
||||
top: -0.75em;
|
||||
font-weight: 400;
|
||||
}
|
||||
.bds-card-stat__buttons {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@@ -20194,6 +20199,102 @@ html.light .bds-callout-media-banner--image-text-black .bds-callout-media-banner
|
||||
color: #141414 !important;
|
||||
}
|
||||
|
||||
.bds-card-stats {
|
||||
display: block;
|
||||
width: 100%;
|
||||
background-color: #FFFFFF;
|
||||
padding-top: 24px;
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
@media (min-width: 576px) {
|
||||
.bds-card-stats {
|
||||
padding-top: 32px;
|
||||
padding-bottom: 32px;
|
||||
}
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
.bds-card-stats {
|
||||
padding-top: 40px;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.bds-card-stats__header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
max-width: 808px;
|
||||
}
|
||||
@media (min-width: 576px) {
|
||||
.bds-card-stats__header {
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
.bds-card-stats__header {
|
||||
gap: 16px;
|
||||
}
|
||||
}
|
||||
.bds-card-stats__header {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
@media (min-width: 576px) {
|
||||
.bds-card-stats__header {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
.bds-card-stats__header {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.bds-card-stats__heading {
|
||||
color: #141414;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.bds-card-stats__description {
|
||||
color: #141414;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.bds-card-stats__cards {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
@media (min-width: 576px) {
|
||||
.bds-card-stats__cards {
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.bds-card-stats__card-wrapper {
|
||||
flex: 0 0 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
@media (min-width: 576px) {
|
||||
.bds-card-stats__card-wrapper {
|
||||
flex: 0 0 calc(50% - 4px);
|
||||
}
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
.bds-card-stats__card-wrapper {
|
||||
flex: 0 0 calc(33.333% - 5.3333333333px);
|
||||
}
|
||||
}
|
||||
|
||||
html.dark .bds-card-stats {
|
||||
background-color: transparent;
|
||||
}
|
||||
html.dark .bds-card-stats__heading,
|
||||
html.dark .bds-card-stats__description {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.bds-feature-two-column__button-group .bds-btn--tertiary {
|
||||
padding-top: 0px !important;
|
||||
padding-bottom: 0px !important;
|
||||
|
||||
@@ -101,6 +101,7 @@ $line-height-base: 1.5;
|
||||
@import "../shared/patterns/HeaderHeroSplitMedia/HeaderHeroSplitMedia.scss";
|
||||
@import "../shared/patterns/CardsFeatured/CardsFeatured.scss";
|
||||
@import "../shared/patterns/CalloutMediaBanner/CalloutMediaBanner.scss";
|
||||
@import "../shared/patterns/CardStats/CardStats.scss";
|
||||
@import "../shared/patterns/FeatureTwoColumn/FeatureTwoColumn.scss";
|
||||
@import "_code-tabs.scss";
|
||||
@import "_code-walkthrough.scss";
|
||||
|
||||
Reference in New Issue
Block a user