Merge branch 'master' of https://github.com/JakeatRipple/xrpl-dev-portal into feat-learningportal-banner

# Conflicts:
#	assets/css/devportal2022-v9.css
This commit is contained in:
Jake
2022-10-18 08:20:14 -07:00
40 changed files with 1125 additions and 17 deletions

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 479 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

View File

@@ -0,0 +1,94 @@
from xrpl.clients import JsonRpcClient
from xrpl.models import AccountObjects
from xrpl.utils import drops_to_xrp, hex_to_str, ripple_time_to_datetime
client = JsonRpcClient("https://s.altnet.rippletest.net:51234") # Connect to the testnetwork
# Query the ledger for all xrp checks an account has created or received
wallet_addr_to_query = "rPKcw5cXUtREMgsQZqSLkxJTfpwMGg7WcP"
checks_dict = {}
sent_checks = []
received_checks = []
# Build request
req = AccountObjects(account=wallet_addr, ledger_index="validated", type="check")
# Make request and return result
response = client.request(req)
result = response.result
# Parse result
if "account_objects" in result:
account_checks = result["account_objects"]
for check in account_checks:
if isinstance(check["SendMax"], str):
check_data = {}
check_data["sender"] = check["Account"]
check_data["receiver"] = check["Destination"]
if "Expiration" in check:
check_data["expiry_date"] = str(ripple_time_to_datetime(check["Expiration"]))
check_data["amount"] = str(drops_to_xrp(check["SendMax"]))
check_data["check_id"] = check["index"]
if check_data["sender"] == wallet_addr:
sent.append(check_data)
elif check_data["sender"] != wallet_addr:
receive.append(check_data)
# Sort checks
checks_dict["sent"] = sent
checks_dict["receive"] = receive
print(checks_dict)
############################# Query for token checks #############################
# Query the ledger for all token checks an account has created or received
wallet_addr_to_query = "rPKcw5cXUtREMgsQZqSLkxJTfpwMGg7WcP"
checks_dict = {}
sent_dict = []
received_dict = []
# Build request
req = AccountObjects(account=wallet_addr, ledger_index="validated", type="check")
# Make request and return result
response = client.request(req)
result = response.result
# Parse result
if "account_objects" in result:
account_checks = result["account_objects"]
for check in account_checks:
if isinstance(check["SendMax"], dict):
check_data = {}
check_data["sender"] = check["Account"]
check_data["receiver"] = check["Destination"]
if "Expiration" in check:
check_data["expiry_date"] = str(ripple_time_to_datetime(check["Expiration"]))
check_data["token"] = hex_to_str(check["SendMax"]["currency"])
check_data["issuer"] = check["SendMax"]["issuer"]
check_data["amount"] = check["SendMax"]["value"]
check_data["check_id"] = check["index"]
if check_data["sender"] == wallet_addr:
sent.append(check_data)
elif check_data["sender"] != wallet_addr:
receive.append(check_data)
# Sort checks
checks_dict["sent"] = sent
checks_dict["receive"] = receive
print(checks_dict)

View File

@@ -0,0 +1,32 @@
from xrpl.wallet import Wallet, generate_faucet_wallet
from xrpl.clients import JsonRpcClient
from xrpl.models import CheckCancel
from xrpl.transaction import (safe_sign_and_autofill_transaction,
send_reliable_submission)
client = JsonRpcClient("https://s.altnet.rippletest.net:51234") # Connect to the testnetwork
"""Cancel a check"""
# Sender is the check creator or recipient
# If the Check has expired, any address can cancel it
# Check id
check_id = "F944CB379DEE18EFDA7A58A4F81AF1A98C46E54A8B9F2D268F1E26610BC0EB03"
# Create wallet object
sender_wallet = generate_faucet_wallet(client=client)
# Build check cancel transaction
check_txn = CheckCancel(account=sender_wallet.classic_address, check_id=check_id)
# Sign and submit transaction
stxn = safe_sign_and_autofill_transaction(check_txn, sender_wallet, client)
stxn_response = send_reliable_submission(stxn, client)
# Parse response for result
stxn_result = stxn_response.result
# Print result and transaction hash
print(stxn_result["meta"]["TransactionResult"])
print(stxn_result["hash"])

View File

@@ -0,0 +1,74 @@
from xrpl.clients import JsonRpcClient
from xrpl.models import CheckCash, IssuedCurrencyAmount
from xrpl.transaction import (safe_sign_and_autofill_transaction,
send_reliable_submission)
from xrpl.utils import str_to_hex, xrp_to_drops
from xrpl.wallet import generate_faucet_wallet
# Connect to a network
client = JsonRpcClient("https://s.altnet.rippletest.net:51234")
# Cash an xrp check
# Check id
check_id = "F944CB379DEE18EFDA7A58A4F81AF1A98C46E54A8B9F2D268F1E26610BC0EB03"
# Amount to cash
amount = 10.00
# Generate wallet
sender_wallet = generate_faucet_wallet(client=client)
# Build check cash transaction
check_txn = CheckCash(account=sender_wallet.classic_address, check_id=check_id, amount=xrp_to_drops(amount))
# Sign transaction
stxn = safe_sign_and_autofill_transaction(check_txn, sender_wallet, client)
# Submit transaction and wait for result
stxn_response = send_reliable_submission(stxn, client)
# Parse response for result
stxn_result = stxn_response.result
# Print result and transaction hash
print(stxn_result["meta"]["TransactionResult"])
print(stxn_result["hash"])
#################### cash token check #############################
# Cash token check
# Token name
token = "USD"
# Amount of token to deliver
amount = 10.00
# Token issuer address
issuer = generate_faucet_wallet(client=client).classic_address
# Create sender wallet object
sender_wallet = generate_faucet_wallet(client=client)
# Build check cash transaction
check_txn = CheckCash(account=sender_wallet.classic_address, check_id=check_id, amount=IssuedCurrencyAmount(
currency=str_to_hex(token),
issuer=issuer,
value=amount))
# Sign transaction
stxn = safe_sign_and_autofill_transaction(check_txn, sender_wallet, client)
# Submit transaction and wait for result
stxn_response = send_reliable_submission(stxn, client)
# Parse response for result
stxn_result = stxn_response.result
# Print result and transaction hash
print(stxn_result["meta"]["TransactionResult"])
print(stxn_result["hash"])

View File

@@ -0,0 +1,78 @@
from datetime import datetime, timedelta
from xrpl.clients import JsonRpcClient
from xrpl.models import CheckCreate, IssuedCurrencyAmount
from xrpl.transaction import (safe_sign_and_autofill_transaction,
send_reliable_submission)
from xrpl.utils import datetime_to_ripple_time, str_to_hex, xrp_to_drops
from xrpl.wallet import generate_faucet_wallet
client = JsonRpcClient("https://s.altnet.rippletest.net:51234") # Connect to the testnetwork
"""Create a token check"""
check_receiver_addr = "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe" # Example: send back to Testnet Faucet
token_name = "USD"
amount_to_deliver = 10.00
token_issuer = "r9CEVt4Cmcjt68ME6GKyhf2DyEGo2rG8AW"
# Set check to expire after 5 days
expiry_date = datetime_to_ripple_time(datetime.now() + timedelta(days=5))
# Generate wallet
sender_wallet = generate_faucet_wallet(client=client)
# Build check create transaction
check_txn = CheckCreate(account=sender_wallet.classic_address, destination=receiver_addr,
send_max=IssuedCurrencyAmount(
currency=str_to_hex(token),
issuer=issuer,
value=amount),
expiration=expiry_date)
# Sign, submit transaction and wait for result
stxn = safe_sign_and_autofill_transaction(check_txn, sender_wallet, client)
stxn_response = send_reliable_submission(stxn, client)
# Parse response for result
stxn_result = stxn_response.result
# Print result and transaction hash
print(stxn_result["meta"]["TransactionResult"])
print(stxn_result["hash"])
############### CREATE XRP CHECK ################################
"""Create xrp check"""
check_receiver_addr = "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe" # Example: send back to Testnet Faucet
amount_to_deliver = 10.00
# Set check to expire after 5 days
expiry_date = datetime_to_ripple_time(datetime.now() + timedelta(days=5))
# Generate wallet
sender_wallet = generate_faucet_wallet(client=client)
# Build check create transaction
check_txn = CheckCreate(account=sender_wallet.classic_address,
destination=receiver_addr,
send_max=xrp_to_drops(amount),
expiration=expiry_date)
# Sign, submit transaction and wait for result
stxn = safe_sign_and_autofill_transaction(check_txn, sender_wallet, client)
stxn_response = send_reliable_submission(stxn, client)
# Parse response for result
stxn_result = stxn_response.result
# Print result and transaction hash
print(stxn_result["meta"]["TransactionResult"])
print(stxn_result["hash"])

View File

@@ -0,0 +1,24 @@
# JavaScript key derivation examples
Generates key from a given input in Ed25519 and Secp256k1 format. On first run, you
have to install the necessary node.js dedpendencies:
npm install
## Command-line usage:
### Base58 formatted seed:
npm start "snJj9fYixUfpNCBn9LzLdLv5QqUKZ"
### Hex formatted seed:
npm start "BB664A14F510A366404BC4352A2230A5"
### Password like seed:
npm start "sEdSKaCy2JT7JaM7v95H9SxkhP9wS2r"
### Random seed
npm start

View File

@@ -0,0 +1,198 @@
'use strict';
// Organize imports
const assert = require("assert")
const brorand = require("brorand")
const BN = require("bn.js")
const elliptic = require("elliptic");
const Ed25519 = elliptic.eddsa('ed25519');
const Secp256k1 = elliptic.ec('secp256k1');
const hashjs = require("hash.js");
const Sha512 = require("ripple-keypairs/dist/Sha512")
const { codec, encodeAccountPublic, encodeNodePublic } = require("ripple-address-codec");
const XRPL_SEED_PREFIX = 0x21
const isHex = function(value) {
const regex = new RegExp(/^[0-9a-f]+$/, 'i')
return regex.test(value)
}
const bytesToHex = function(bytes) {
return Array.from(bytes, (byteValue) => {
const hex = byteValue.toString(16).toUpperCase();
return hex.length > 1 ? hex : `0${hex}`;
}).join('');
}
const hexToBytes = function(hex) {
assert.ok(hex.length % 2 === 0);
return hex.length === 0 ? [] : new BN(hex, 16).toArray(null, hex.length / 2);
}
const encodeUTF8 = function (string) {
return encodeURIComponent(string)
}
const sha512half = function (value) {
return hashjs.sha512().update(value).digest().slice(0, 32);
}
class Seed {
constructor(seedValue = '', checkRFC1751 = false) {
this.bytes = this._initSeed(seedValue)
this.ED25519Keypair = this._deriveED25519Keypair(this.bytes)
this.Secp256K1Keypair = this._deriveSecp256K1Keypair(this.bytes)
}
_initSeed(seedValue) {
// No input given - default to random seed
if (!seedValue || seedValue === '') {
const randomBuffer = brorand(16)
return [...randomBuffer]
}
// From base58 formatted seed
try {
const base58decoded = codec.decodeChecked(seedValue)
if (base58decoded[0] === XRPL_SEED_PREFIX && base58decoded.length === 17) {
return [...base58decoded.slice(1)];
}
} catch (exception) {
// Continue probing the seed for different format
}
// From hex formatted seed
if (isHex(seedValue)) {
const decoded = hexToBytes(seedValue);
if(decoded.length === 16) {
return decoded
} else {
// Raise Error
throw new Error("incorrect decoded seed length")
}
}
// From password seed
const encoded = encodeUTF8(seedValue)
return hashjs.sha512().update(encoded).digest().slice(0, 16);
}
_deriveED25519Keypair() {
const prefix = 'ED';
const rawPrivateKey = sha512half(this.bytes);
const privateKey = prefix + bytesToHex(rawPrivateKey);
const publicKey = prefix + bytesToHex(Ed25519.keyFromSecret(rawPrivateKey).pubBytes());
return { privateKey, publicKey };
}
_deriveSecp256K1Keypair(entropy, options) {
const prefix = '00';
const privateKey = prefix + this._deriveSecp256K1PrivateKey(entropy, options).toString(16, 64).toUpperCase()
const publicKey = bytesToHex(Secp256k1.keyFromPrivate(privateKey.slice(2))
.getPublic()
.encodeCompressed());
return { privateKey, publicKey };
}
_deriveSecp256K1PrivateKey(seed, opts = {}) {
const root = opts.validator;
const order = Secp256k1.curve.n;
// This private generator represents the `root` private key, and is what's
// used by validators for signing when a keypair is generated from a seed.
const privateGen = this._deriveScalar(seed);
if (root) {
// As returned by validation_create for a given seed
return privateGen;
}
const publicGen = Secp256k1.g.mul(privateGen);
// A seed can generate many keypairs as a function of the seed and a uint32.
// Almost everyone just uses the first account, `0`.
const accountIndex = opts.accountIndex || 0;
return this._deriveScalar(publicGen.encodeCompressed(), accountIndex)
.add(privateGen)
.mod(order);
}
_deriveScalar(bytes, discrim) {
const order = Secp256k1.curve.n;
for (let i = 0; i <= 0xffffffff; i++) {
// We hash the bytes to find a 256 bit number, looping until we are sure it
// is less than the order of the curve.
const hasher = new Sha512.default().add(bytes);
// If the optional discriminator index was passed in, update the hash.
if (discrim !== undefined) {
hasher.addU32(discrim);
}
hasher.addU32(i);
const key = hasher.first256BN();
/* istanbul ignore else */
/* istanbul ignore else */
if (key.cmpn(0) > 0 && key.cmp(order) < 0) {
return key;
}
}
// This error is practically impossible to reach.
// The order of the curve describes the (finite) amount of points on the curve
// https://github.com/indutny/elliptic/blob/master/lib/elliptic/curves.js#L182
// How often will an (essentially) random number generated by Sha512 be larger than that?
// There's 2^32 chances (the for loop) to get a number smaller than the order,
// and it's rare that you'll even get past the first loop iteration.
// Note that in TypeScript we actually need the throw, otherwise the function signature would be BN | undefined
//
/* istanbul ignore next */
throw new Error('impossible unicorn ;)');
}
getBase58ED25519Account() {
const buffer = Buffer.from(this.ED25519Keypair.publicKey, "hex")
return encodeAccountPublic([...buffer])
}
getBase58ESecp256k1Account(validator = false) {
const buffer = Buffer.from(this.Secp256K1Keypair.publicKey, "hex")
if (validator) {
return encodeNodePublic([...buffer])
} else {
return encodeAccountPublic([...buffer])
}
}
toString() {
const base58Seed = codec.encodeChecked([XRPL_SEED_PREFIX].concat(this.bytes))
const hexSeed = Buffer.from(this.bytes).toString('hex').toUpperCase()
const base58ED25519Account = this.getBase58ED25519Account();
const base58Secp256k1Account = this.getBase58ESecp256k1Account();
const base58Secp256k1AccountValidator = this.getBase58ESecp256k1Account(true);
const out = `
Seed (base58): ${base58Seed}
Seed (hex): ${hexSeed}
Ed25519 Secret Key (hex): ${this.ED25519Keypair.privateKey}
Ed25519 Public Key (hex): ${this.ED25519Keypair.publicKey}
Ed25519 Public Key (base58 - Account): ${base58ED25519Account}
secp256k1 Secret Key (hex): ${this.Secp256K1Keypair.privateKey}
secp256k1 Public Key (hex): ${this.Secp256K1Keypair.publicKey}
secp256k1 Public Key (base58 - Account): ${base58Secp256k1Account}
secp256k1 Public Key (base58 - Validator): ${base58Secp256k1AccountValidator}
`
return out
}
}
if (process.argv[2] !== undefined) {
console.log(process.argv[2]);
const seed = new Seed(process.argv[2]);
console.log(seed.toString())
} else {
const seed = new Seed();
console.log(seed.toString())
}

View File

@@ -0,0 +1,12 @@
{
"name": "key-derivation-examples",
"version": "0.1.0",
"license": "MIT",
"dependencies": {
"xrpl": "^2.0.0"
},
"main": "index.js",
"scripts": {
"start": "node index.js"
}
}

View File

@@ -19,7 +19,7 @@ The following is a comprehensive list of all known [amendments](amendments.html)
| [fixRemoveNFTokenAutoTrustLine][] | v1.9.4 | [Open for Voting: TBD](https://xrpl.org/blog/2022/rippled-1.9.4.html "BADGE_80d0e0") | | [fixRemoveNFTokenAutoTrustLine][] | v1.9.4 | [Open for Voting: TBD](https://xrpl.org/blog/2022/rippled-1.9.4.html "BADGE_80d0e0") |
| [fixNFTokenNegOffer][] | v1.9.2 | [Open for Voting: TBD](https://xrpl.org/blog/2022/rippled-1.9.2.html "BADGE_80d0e0") | | [fixNFTokenNegOffer][] | v1.9.2 | [Open for Voting: TBD](https://xrpl.org/blog/2022/rippled-1.9.2.html "BADGE_80d0e0") |
| [NonFungibleTokensV1_1][] | v1.9.2 | [Open for Voting: TBD](https://xrpl.org/blog/2022/rippled-1.9.2.html "BADGE_80d0e0") | | [NonFungibleTokensV1_1][] | v1.9.2 | [Open for Voting: TBD](https://xrpl.org/blog/2022/rippled-1.9.2.html "BADGE_80d0e0") |
| [ExpandedSignerList][] | v1.9.1 | [Open for Voting: TBD](https://xrpl.org/blog/2022/rippled-1.9.1.html "BADGE_80d0e0") | | [ExpandedSignerList][] | v1.9.1 | [Enabled: 2022-10-13](https://livenet.xrpl.org/transactions/802E2446547BB86397217E32A78CB9857F21B048B91C81BCC6EF837BE9C72C87 "BADGE_GREEN") |
| [fixNFTokenDirV1][] | v1.9.1 | [Open for Voting: TBD](https://xrpl.org/blog/2022/rippled-1.9.1.html "BADGE_80d0e0") | | [fixNFTokenDirV1][] | v1.9.1 | [Open for Voting: TBD](https://xrpl.org/blog/2022/rippled-1.9.1.html "BADGE_80d0e0") |
| [NonFungibleTokensV1][] | v1.9.0 | [Open for Voting: TBD](https://xrpl.org/blog/2022/rippled-1.9.0.html "BADGE_80d0e0") | | [NonFungibleTokensV1][] | v1.9.0 | [Open for Voting: TBD](https://xrpl.org/blog/2022/rippled-1.9.0.html "BADGE_80d0e0") |
| [CheckCashMakesTrustLine][] | v1.8.0 | [Open for Voting: TBD](https://xrpl.org/blog/2021/rippled-1.8.1.html "BADGE_80d0e0") | | [CheckCashMakesTrustLine][] | v1.8.0 | [Open for Voting: TBD](https://xrpl.org/blog/2021/rippled-1.8.1.html "BADGE_80d0e0") |
@@ -234,7 +234,7 @@ Provides "suspended payments" for XRP for escrow within the XRP Ledger, includin
| Amendment | ExpandedSignerList | | Amendment | ExpandedSignerList |
|:----------|:-----------| |:----------|:-----------|
| Amendment ID | B2A4DB846F0891BF2C76AB2F2ACC8F5B4EC64437135C6E56F3F859DE5FFD5856 | | Amendment ID | B2A4DB846F0891BF2C76AB2F2ACC8F5B4EC64437135C6E56F3F859DE5FFD5856 |
| Status | Open for Voting | | Status | Enabled |
| Default Vote (Latest stable release) | No | | Default Vote (Latest stable release) | No |
| Pre-amendment functionality retired? | No | | Pre-amendment functionality retired? | No |

View File

@@ -0,0 +1,42 @@
---
html: intro-to-evm-sidechain.html
parent: xrpl-interoperability.html
blurb: Introduction to the EVM compatible XRP Ledger Sidechain
labels:
- Interoperability
status: not_enabled
---
# Introduction to EVM Compatible XRP Ledger Sidechain
The Etherium Virtual Machine (EVM) compatible XRP Ledger sidechain is a secure and fast public blockchain that brings all kinds of web3 applications to the XRP Ledger community.
- Explorer: [https://evm-sidechain.xrpl.org](https://evm-sidechain.xrpl.org/)
- Public RPC: [https://rpc.evm-sidechain.xrpl.org](https://evm-sidechain.xrpl.org/)
The EVM Sidechain is a powerful latest generation blockchain with the following features:
- Supports up to 1000 transactions per second, thus handling large loads and throughput.
- Has a low transaction confirmation time, on average, as a block is produced every 5 seconds.
- Once a block is added to the chain and confirmed, it is considered final (1 block finalization time).
- Provides full Ethereum Virtual Machine (EVM) compatibility, enabling you to connect your wallet and interact or deploy smart contracts written in Solidity.
## Consensus
The EVM Sidechain runs on a proof-of-stake (PoS) consensus algorithm. Staking is when you pledge your coins to be used for verifying transactions. The proof-of-stake model allows you to stake cryptocurrency (also referred to as "coins") and create your own validator nodes. Your coins are locked up while you stake them, but you can unstake them if you want to trade your coins.
In a proof-of-stake blockchain, mining power depends on the amount of coins a validator is staking. Participants who stake more coins are more likely to be chosen to add new blocks.
If you are interested in staking cryptocurrency and running your own validator, see [Join EVM Sidechain Devnet](join-evm-sidechain-devnet.html) for more information.
The underlying technology for the XRP Ledger EVM Sidechain consensus is [Tendermint](https://tendermint.com/), a Byzantine-Fault Tolerant engine for building blockchains.
The blockchain uses the `cosmos-sdk` library on top of Tendermint to create and customize the blockchain using its built-in modules. The EVM sidechain uses the [Ethermint](https://github.com/evmos/ethermint) `cosmos-sdk` module, which provides EVM compatibility
## Interoperability Using the EVM Sidechain
The EVM sidechain is directly connected to XRP Ledger through the XRP Ledger bridge ([https://bridge.devnet.xrpl.](https://bridge.devnet.xrpl.org/). Through this bridge component, you can move your XRP to the EVM Sidechain and use its features.
## See Also
[Get Started with EVM Sidechain](get-started-evm-sidechain.html)

View File

@@ -0,0 +1,13 @@
---
html: xrpl-interoperability.html
parent: concepts.html
blurb: Learn about capabilities that bring programmability and ability to interact with other chains to the XRP Ledger.
template: pagetype-category.html.jinja
labels:
- Interoperability
status: not_enabled
---
# Interoperability
The XRP Ledger is known for its transaction throughput, speed, and low fees. With the addition of programmabilty and interoperability, developers can access features such as smart contracts and can build apps with cross-chain interoperability.

View File

@@ -38,9 +38,9 @@ The transaction cost is not paid to any party: the XRP is irrevocably destroyed.
## Load Cost and Open Ledger Cost ## Load Cost and Open Ledger Cost
When the [FeeEscalation amendment][] is enabled, there are two thresholds for the transaction cost: There are two thresholds for the transaction cost:
* If the transaction cost does not meet a `rippled` server's [load-based transaction cost threshold](#local-load-cost), the server ignores the transaction completely. (This logic is essentially unchanged with or without the amendment.) * If the transaction cost does not meet a `rippled` server's [load-based transaction cost threshold](#local-load-cost), the server ignores the transaction completely.
* If the transaction cost does not meet a `rippled` server's [open ledger cost threshold](#open-ledger-cost), the server queues the transaction for a later ledger. * If the transaction cost does not meet a `rippled` server's [open ledger cost threshold](#open-ledger-cost), the server queues the transaction for a later ledger.
This divides transactions into roughly three categories: This divides transactions into roughly three categories:
@@ -90,7 +90,7 @@ _Fee levels_ represent the proportional difference between the minimum cost and
The `rippled` APIs have two ways to query the local load-based transaction cost: the `server_info` command (intended for humans) and the `server_state` command (intended for machines). The `rippled` APIs have two ways to query the local load-based transaction cost: the `server_info` command (intended for humans) and the `server_state` command (intended for machines).
If the [FeeEscalation amendment][] is enabled, you can use the [fee method][] to check the open ledger cost. You can use the [fee method][] to check the open ledger cost.
### server_info ### server_info
@@ -151,7 +151,7 @@ This feature is designed to allow you to recover an account if the regular key i
The [`lsfPasswordSpent` flag](accountroot.html) starts out disabled. It gets enabled when you send a SetRegularKey transaction signed by the master key pair. It gets disabled again when the account receives a [Payment](payment.html) of XRP. The [`lsfPasswordSpent` flag](accountroot.html) starts out disabled. It gets enabled when you send a SetRegularKey transaction signed by the master key pair. It gets disabled again when the account receives a [Payment](payment.html) of XRP.
When the [FeeEscalation amendment][] is enabled, `rippled` prioritizes key reset transactions above other transactions even though the nominal transaction cost of a key reset transaction is zero. `rippled` prioritizes key reset transactions above other transactions even though the nominal transaction cost of a key reset transaction is zero.
## Changing the Transaction Cost ## Changing the Transaction Cost

View File

@@ -37,6 +37,6 @@ For a practical example, see the [Batch Mint NFTokens](batch-minting.html) tutor
* NFToken objects are minted ahead of time * NFToken objects are minted ahead of time
* Market activity for the initial sale of the NFToken object is captured on the ledger * Market activity for the initial sale of the NFToken object is captured on the ledger
Downside ### Downside
You need to retain the appropriate XRP reserve for all of the NFToken objects you mint. As a rule of thumb, this is roughly 1/12th XRP per NFToken object at the current reserve rate. In the event that you do not have sufficient XRP in reserve, your mint transactions fail until you add sufficient XRP to your account. You need to retain the appropriate XRP reserve for all of the NFToken objects you mint. As a rule of thumb, this is roughly 1/12th XRP per NFToken object at the current reserve rate. In the event that you do not have sufficient XRP in reserve, your mint transactions fail until you add sufficient XRP to your account.

View File

@@ -4,11 +4,11 @@ The software that powers the XRP Ledger is open-source, so anyone can download,
| XRP Ledger Source Code | | | XRP Ledger Source Code | |
|:-----------------------|:----------------------------------------------------| |:-----------------------|:----------------------------------------------------|
| Repository | <https://github.com/ripple/rippled/> | | Repository | <https://github.com/XRPLF/rippled> |
| License | [Multiple; ISC (permissive)](https://github.com/ripple/rippled/blob/develop/LICENSE.md) | | License | [Multiple; ISC (permissive)](https://github.com/ripple/rippled/blob/develop/LICENSE.md) |
| Programming Language | C++ | | Programming Language | C++ |
If you're not sure where to start, Dev Null Productions provides a detailed and thorough [**Source Code Guide**](https://xrpintel.com/source) that describes the structure and functions of the `rippled` XRP Ledger server implementation. If you're not sure where to start, Dev Null Productions provides a detailed and thorough [**Source Code Guide**](https://xrpintel.com/source) that describes the structure and functions of the core XRP Ledger server (`rippled`) implementation.
## Standards Drafts ## Standards Drafts

View File

@@ -112,12 +112,12 @@ status: not_enabled
### 送金手数料 ### 送金手数料
送金手数料には、トークンの二次販売時に発行者が請求する手数料を1/10,000単位で指定します。このフィールドの有効な値は0から50,000までです。1の値は1bpsまたは0.01%に相当し、0%から50%の間の転送レートを許容します。 送金手数料には、トークンの二次販売時に発行者が請求する手数料を1/100,000単位で指定します。このフィールドの有効な値は0から50,000までです。1の値は1bpsまたは0.01%に相当し、0%から50%の間の転送レートを許容します。
### 例 ### 例
この値では、転送手数料は314bps3.14に設定されます。 この値では、転送手数料は31.4bps0.314に設定されます。
![送金手数料](img/nftokenb.png "送金手数料") ![送金手数料](img/nftokenb.png "送金手数料")

View File

@@ -68,12 +68,12 @@ The example sets three flags: `lsfBurnable` (`0x0001`), `lsfOnlyXRP` (`0x0002`),
### TransferFee ### TransferFee
The `TransferFee` value specifies the percentage fee, in units of 1/10,000, charged by the issuer for secondary sales of the token. Valid values for this field are between 0 and 50,000, inclusive. A value of 1 is equivalent to 1bps or 0.00001%, allowing transfer rates between 0% and 50%. The `TransferFee` value specifies the percentage fee, in units of 1/100,000, charged by the issuer for secondary sales of the token. Valid values for this field are between 0 and 50,000, inclusive. A value of 1 is equivalent to 0.001% or 1/10 of a basis point (bps), allowing transfer rates between 0% and 50%.
### Example ### Example
This value sets the transfer fee to 314, or .00314%. This value sets the transfer fee to 314, or 0.314%.
![Transfer Fee](img/nftokenb.png "Transfer Fee") ![Transfer Fee](img/nftokenb.png "Transfer Fee")

View File

@@ -0,0 +1,47 @@
---
html: connect-metamask-to-xrpl-evm-sidechain.html
parent: get-started-evm-sidechain.html
blurb: Learn how to connect MetaMask wallet to the EVM Sidechain for the XRP Ledger.
labels:
- Development, Interoperability
status: not_enabled
---
# Connect MetaMask to XRP Ledger Sidechain
MetaMask is an extension for accessing Harmony-enabled distributed applications (_dapps_) from your browser. The extension injects the XRP Ledger EVM sidechain Web3 API into every website's Javascript context, so that Web3 applications can read from the blockchain.
This tutorial walks through the process of installing MetaMask, configuring it on the XRP Ledger EVM sidechain network, and importing an existing account using a previously generated private key.
## 1. Installing MetaMask
Install the MetaMask extension on your browser from **[https://metamask.io/download/](https://metamask.io/download/)**. The extension supports most desktop browsers.
## 2. Create an Account on MetaMask
To create a new account on MetaMask:
1. Click the MetaMask icon.
![Create an account on MetaMask](img/evm-sidechain-create-metamask-account.png "Create an account on MetaMask")
2. Choose **Create Account**.
3. Enter the Account Name.
4. Click **Create**.
### 3. Adding XRP Ledger EVM Sidechain to MetaMask
To add XRP Ledger EVM Sidechain to MetaMask:
1. Open the MetaMask extension.
2. Use the drop-down menu to choose **Add Network**.
![Add the EVM Sidechain network to MetaMask](img/evm-sidechain-add-metamask-network.png "Add the EVM Sidechain network to MetaMask")
3. Enter the XRP Ledger Devnet endpoint information.
* **Network Name**: XRP Ledger EVM Sidechain
* **New RPC URL**: http://rpc.evm-sidechain.xrpl.org
* **Chain ID**: 1440001
* **Currency Symbol**: XRP
* **Block Explorer**: https://evm-sidechain.xrpl.org

View File

@@ -0,0 +1,107 @@
---
html: evm-sidechain-run-a-validator-node.html
parent: evm-sidechains.html
blurb: Learn how to run a validator node on the EVM Sidechain Devnet.
labels:
- Development, Interoperability
status: not_enabled
---
# Run a Validator Node on an EVM Sidechain
## Create Your Validator
Use your node consensus public key (`exrpvalconspub...`) to create a new validator by staking XRP tokens. You can find your validator pubkey by running:
```bash
exrpd tendermint show-validator
```
To create your validator on Devnet, use the following command:
```bash
exrpd tx staking create-validator \
--amount=1000000000000000000000axrp \
--pubkey=$(exrpd tendermint show-validator) \
--moniker="<your_custom_moniker>" \
--chain-id=<chain_id> \
--commission-rate="0.05" \
--commission-max-rate="0.10" \
--commission-max-change-rate="0.01" \
--min-self-delegation="1000000" \
--gas="auto" \
--gas-prices="0.025aphoton" \
--from=<key_name>
```
**Note** When specifying commission parameters, the `commission-max-change-rate` is used to measure % *point* change over the `commission-rate`. For example, 1% to 2% is a 100% rate increase, but only 1 percentage point.
**Note** `Min-self-delegation` is a strictly positive integer that represents the minimum amount of self-delegated voting power your validator must always have. A `min-self-delegation` of `1000000` means your validator will never have a self-delegation lower than `1 axrp`.
You can confirm that you are in the validator set by using a third-party explorer.
## Edit Validator Description
You can edit your validator's public description. This info is to identify your validator, and is relied on by delegators when they decide to stake XRP tokens to a particular validator. Make sure to provide input for every flag below. If a flag is not included in the command, the field defaults to empty (`--moniker` defaults to the machine name), if the field has never been set, or remains the same, if it has been set in the past.
The <key_name> specifies which validator you are editing. If you choose to not include certain flags, remember that the --from flag must be included to identify the validator to update.
The `--identity` can be used as to verify identity with systems like Keybase or UPort. When using with Keybase `--identity` must be populated with a 16-digit string that is generated with a [keybase.io](https://keybase.io/) account. It is a cryptographically secure method of verifying your identity across multiple online networks. The Keybase API allows us to retrieve your Keybase avatar. This is how you can add a logo to your validator profile.
```bash
exrpd tx staking edit-validator
--moniker="<your_custom_moniker>" \
--website="https://xrpl.org" \
--identity=6A0D65E29A4CBC8E \
--details="<your_validator_description>" \
--chain-id=<chain_id> \
--gas="auto" \
--gas-prices="0.025axrp" \
--from=<key_name> \
--commission-rate="0.10"
```
Note that the `commission-rate` value must adhere to the following invariants:
* Must be between 0 and the validator's `commission-max-rate`
* Must not exceed the validator's `commission-max-change-rate` which is the maximum % point change rate **per day**. In other words, a validator can only change its commission once per day and within `commission-max-change-rate` bounds.
## View Validator Description
View the validator's information with this command:
```bash
exrpd query staking validator <account>
```
## Track Validator Signing Information
To track a validator's signatures from past transactions use the `signing-info` command.
```bash
exrpd query slashing signing-info <validator-pubkey> --chain-id=<chain_id>
```
## Unjail Validator
When a validator is "jailed" for downtime, you must submit an `Unjail` transaction from the operator account in order to restore block proposer awards (depending on the zone fee distribution).
```bash
exrpd tx slashing unjail --from=<key_name> --chain-id=<chain_id>
```
## Confirm Your Validator is Running
Your validator is active if the following command returns anything:
```bash
exrpd query tendermint-validator-set | grep "$(exrpd tendermint show-address)"
```
You should now see your validator in one of the Exrp explorers. You are looking for the `bech32` encoded `address` in the `~/.exprd/config/priv_validator.json` file.
**Note** To be in the validator set, you must have more total voting power than the 100th validator.
## Halting Your Validator
When attempting to perform routine maintenance or planning for an upcoming coordinated upgrade, it can be useful to have your validator systematically and gracefully halt. Set the `halt-height` to the height at which you want your node to shut down, or pass the `--halt-height` flag to `exrpd`. The node shuts down with a 0 exit code at that given height after committing the block.

View File

@@ -0,0 +1,65 @@
---
html: evm-sidechain-validator-security.html
parent: join-evm-sidechain-devnet.html
blurb: Learn how to join the XRP Ledger EVM Sidechain Devnet.
labels:
- Development, Interoperability
status: not_enabled
---
# EVM Sidechain Validator Security
Each validator candidate is encouraged to run its operations independently, as diverse setups increase the resilience of the network. Validator candidates should commence their setup phase now, in order to be on time for launch.
## Horcrux
Horcrux is a [multi-party-computation (MPC)](https://en.wikipedia.org/wiki/Secure_multi-party_computation) signing service for Tendermint nodes.
- Composed of a cluster of signer nodes in place of the [remote signer](https://docs.tendermint.com/master/nodes/remote-signer.html), thereby enabling High Availability (HA) for block signing through fault tolerance.
- Secures your validator private key by splitting it across multiple private signer nodes using threshold Ed25519 signatures.
- Adds security and availability without sacrificing block sign performance.
For information on how to upgrade your validator infrastructure with Horcrux, refer to the [documentation](https://github.com/strangelove-ventures/horcrux/blob/main/docs/migrating.md).
## Tendermint KMS
Tendermint KMS is a signature service with support for Hardware Security Modules (HSMs), such as YubiHSM2 and Ledger Nano. It is intended to be run alongside XRP Ledger EVM Sidechain validators, ideally on separate physical hosts, providing defense-in-depth for online validator signing keys, double signing protection, and a central signing service that can be used when operating multiple validators in several zones.
## Hardware Security Modules (HSM)
You must ensure that an attacker cannot steal a validator's key. Otherwise, the entire stake delegated to the compromised validator at risk. Hardware security modules (HSM) help mitigate this risk.
HSMs must support `ed25519` signatures for Evmos. The [YubiHSM 2](https://www.yubico.com/products/hardware-security-module/) supports `ed25519` and can be used with this YubiKey [library](https://github.com/iqlusioninc/yubihsm.rs).
**IMPORTANT**: The YubiHSM can protect a private key but **cannot ensure** in a secure setting that it will not sign the same block twice.
## Sentry Nodes (DDOS Protection)
Validators are responsible for ensuring that the network can sustain denial of service attacks.
One recommended way to mitigate these risks is for validators to carefully structure their network topology in a sentry node architecture.
Validator nodes should only connect to full-nodes they trust; either they operate these nodes themselves, or the nodes are run by other validator administrators they know personally. A validator node typically runs in a data center. Most data centers provide direct links to the networks of major cloud providers. The validator can use those links to connect to sentry nodes in the cloud. This shifts the burden of denial-of-service from the validator's node directly to its sentry nodes, and might require new sentry nodes be spun up or activated to mitigate attacks on existing ones.
Sentry nodes can be quickly spun up or change their IP addresses. Because the links to the sentry nodes are in private IP space, an internet-based attacked cannot disturb them directly. This ensures that the validator's block proposals and votes always make it to the rest of the network.
To setup your sentry node architecture:
1. Edit your validator node's `config.toml` file:
```sql
#Comma separated list of nodes to keep persistent connections to
#Do not add private peers to this list if you don't want them advertised
persistent_peers =[list of sentry nodes]
# Set true to enable the peer-exchange reactor
pex = false
```
2. Edit your sentry node's `config.toml` file:
```sql
#Comma separated list of peer IDs to keep private (will not be gossiped to other peers)
#Example ID: 3e16af0cead27979e1fc3dac57d03df3c7a77acc@3.87.179.235:26656
private_peer_ids = "node_ids_of_private_peers"
```

View File

@@ -0,0 +1,116 @@
---
html: get-started-evm-sidechain.html
parent: evm-sidechains.html
blurb: Get started with the EVM compatible sidechain for the XRP Ledger.
labels:
- Development, Interoperability
status: not_enabled
---
# Get Started with the EVM Sidechain
This getting started tutorial walks you through the steps to set up your account and transfer funds using the EVM sidechain bridge.
## 1. Create an Account Using an EVM Compatible Wallet
In order to interact with the network, you need to create an account in the EVM sidechain. To create and manage this account you can use any EVM compatible wallet such as MetaMask.
For instructions on how to install and create an account using MetaMask, then send and receive tokens, see [Connect MetaMask to XRP Ledger EVM Sidechain](connect-metamask-to-xrpl-evm-sidechain.html).
## 2. Move XRP Ledger Devnet Tokens to the EVM Sidechain
Before you can start interacting with the EVM blockchain, you need to transfer some tokens from the XRP Ledger Devnet to the EVM sidechain.
To obtain tokens in the XRP Ledger Devnet, go to the [XRP Faucets](xrp-testnet-faucet.html) page and click *Generate Devnet credentials* to generate a new Devnet account with some test XRP in it.
![Generate XRP Ledger Devnet credentials](img/evm-sidechain-xrpl-devnet-faucet.png "Generate XRP Ledger Devnet credentials")
Note the address and secret associated with your Devnet address. You need this information to set up your preferred XRP Ledger wallet.
## 3. Transfer Funds Using the EVM Sidechain Bridge
Once you have your accounts set up and test fund allocated, you can use the EVM Sidechain bridge to move the test XRP tokens to the EVM Sidechain.
The EVM Sidechain bridge is a tool that allows you to transfer funds between chains in a fast and secure way.
To start using the bridge, go to [https://bridge.devnet.xrpl.org](https://bridge.devnet.xrpl.org/)
### 1. Connect Both Wallets
**Connect Xumm Wallet**
Use your Xumm wallet to interact with the XRP Ledger Devnet chain.
Ensure that you have created an account on the public XRP Ledger Devnet as described in Step 1.
To connect a Xumm wallet to the bridge, go to the [EVM Sidechain bridge](https://bridge.devnet.xrpl.org) and click “Connect with Xumm Wallet”.
![Connect XUMM Wallet](img/evm-sidechain-connect-xumm-wallet.png "Connect XUMM wallet")
**Note:** Ensure that you are connected to XRP Ledger Devnet and that the application that you are connecting with is the correct one.
Follow the instructions on screen to scan the QR code using the Xumm app. The Xumm wallet app displays a confirmation page.
![Connect to XRP Ledger Devnet](img/evm-sidechain-bridge-sign-in.jpg "Connect to XRP Ledger Devnet")
**Connect MetaMask Wallet**
Use your MetaMask wallet to interact with the XRP Ledger EVM Sidechain.
Ensure that you have created a MetaMask account and connected to the public XRP Ledger Devnet as described in [Connect MetaMask to XRP Ledger EVM Sidechain](connect-metamask-to-xrpl-evm-sidechain.html).
To connect a MetaMask wallet to the bridge, go to the [EVM Sidechain bridge](https://bridge.devnet.xrpl.org) and click “Connect with Metamask Wallet”.
![Connect MetaMask Wallet](img/evm-sidechain-connect-metamask.png "Connect MetaMask wallet")
### 2. Initiate the Transfer of Funds
Now that both Xumm and MetaMask wallets are connected to the bridge, you can select the direction of the bridge, the amount to send, and the destination address.
- **Direction of the bridge**: This is the direction of transfer; it can be either EVM sidechain → XRP Ledger Devnet or XRP Ledger Devnet → EVM sidechain. Use the “Switch Network” button to switch the direction of transfer.
- **Amount to send**: This is the amount that you want to transfer to the other side. Note that there is a fee to use the bridge.
- Network fees: The fees required by the network for your transactions.
- Commission: The bridge applies a commission for every transaction completed. This is to prevent spam and distributed denial of service attacks (DDOS).
- **Destination address**: The address on the destination chain where you want to receive funds.
![Initiate the transaction](img/evm-sidechain-initiate-transfer.png "Initiate the transaction")
Enter the details for your transaction and click **Transfer**. Review the details of the transaction carefully before accepting the transaction in the corresponding wallet.
![Approve the transaction](img/evm-sidechain-approve-transaction.png "Approve the transaction")
Depending on the direction of the transfer, you need to approve the transaction in the Xumm Wallet or in the Metamask.
**XRP Ledger Devnet → EVM sidechain**
For this direction you must approve the transaction in your Xumm Wallet. Before doing so, please check that the details are correct:
- Destination address has to be: `radjmEZTb4zsyNUJGV4gcVPXrFTJAuskKa`
- Memo has to be the same address that you entered in the destination field
![Review the transaction](img/evm-sidechain-review-transaction.jpg)
**EVM sidechain → XRP Ledger Devnet**
If this is the case, then you must approve the transaction in your Metamask. Before doing so, please check the details are correct:
- Destination address has to be: `0x8cDE56336E289c028C8f7CF5c20283fF02272182`
![Review the transaction in MetaMask](img/evm-sidechain-metamask-confirmation.png "Review the transaction in MetaMask")
Once you approve the transaction either in Xumm wallet or in Metamask, a loading screen displays. This process can take up to a few minutes.
![Transaction in progress](img/evm-sidechain-transfer-in-progress.png "Transaction in progress")
### 3. Receive the Funds
Following a few minutes of transaction processing time, you are redirected to the **Transaction Confirmation** screen where you can verify the details of the bridge transaction.
- **Origin transaction hash**: Hash of the transaction in the origin chain.
- **Destination transaction hash**: Hash of the transaction in the destination chain.
- **From address**: Origin address of the transfer.
- **To address**: Destination address of the transfer.
- **Receive**: The amount received in the destination address.
![Transaction confirmation](img/evm-sidechain-transaction-confirmation.png "Transaction confirmation")
Your test XRP tokens have been successfully transferred and are now available in the other chain.

View File

@@ -0,0 +1,119 @@
---
html: join-evm-sidechain-devnet.html
parent: evm-sidechains.html
blurb: Learn how to join the XRP Ledger EVM Sidechain Devnet.
labels:
- Development, Interoperability
status: not_enabled
---
# Join the XRP Ledger EVM Sidechain Devnet
This tutorial walks you through the steps to join the existing **XRP Ledger EVM Sidechain Devnet**.
For ease of use, create an alias, `exprd`, to run all commands inside your Docker container.
## Pre-requisites
Before proceeding to initialize the node, ensure that the following pre-requisites are installed and running:
* Docker 19+
* Create an alias to run all commands in this tutorial inside a Docker container:
```bash
alias exrpd="docker run -it --rm -v ~/.exrpd:/root/.exrpd peersyst/xrp-evm-client:latest exrpd"
```
## Initialize Node
The first task is to initialize the node, which creates the necessary validator and node configuration files.
1. Initialize the chain parameters using the following command:
```bash
exrpd config chain-id exrp_1440001-1
```
2. Create or add a key to your node. For this tutorial, we use the `test` keyring:
```bash
exrpd keys add <key_name> --keyring-backend test
```
Note the `key_name` you enter as you need to reference it in subsequent steps.
**Note** For more information on a more secure setup for your validator, refer to [cosmos-sdk keys and keyrings](https://docs.cosmos.network/v0.46/run-node/keyring.html) and [validator security](evm-sidechain-validator-security.html).
3. Initialize the node using the following command:
```bash
exrpd init <your_custom_moniker> --chain-id exrp_1440001-1
```
Monikers can contain only ASCII characters. Using Unicode characters renders your node unreachable.
All these commands create your `~/.exrpd` (i.e `$HOME`) directory with subfolders `config/` and `data/`. In the `config` directory, the most important files for configuration are `app.toml` and `config.toml`.
## Genesis & Seeds
1. Copy the Genesis File.
Download the `genesis.json` file from here and copy it to the `config` directory: `~/.exrpd/config/genesis.json`. This is a genesis file with the chain-id and genesis accounts balances.
```bash
wget [https://raw.githubusercontent.com/Peersyst/xrp-evm-archive/main/devnet/genesis.json](https://raw.githubusercontent.com/Peersyst/xrp-evm-archive/main/devnet/genesis.json) ~/.exrpd/config/
```
Verify the genesis configuration file:
```bash
exrpd validate-genesis
```
2. Add Persistent Peer Nodes
Set the [`persistent_peer`](https://docs.tendermint.com/master/tendermint-core/using-tendermint.html#persistent-peer)s field in `~/.exrpd/config/config.toml` to specify peers with which your node maintains persistent connections. You can retrieve them from the list of available peers on the archive repo ([https://raw.githubusercontent.com/Peersyst/xrp-evm-archive/main/devnet/peers.txt](https://raw.githubusercontent.com/Peersyst/xrp-evm-archive/main/devnet/peers.txt)).
To get a list of entries from the `peers.txt` file in the `PEERS` variable, run the following command:
```bash
PEERS=`curl -sL https://raw.githubusercontent.com/Peersyst/xrp-evm-archive/main/devnet/peers.txt | sort -R | head -n 10 | awk '{print $1}' | paste -s -d, -`
```
Use `sed` to include them in the configuration. You can also add them manually:
```bash
sed -i.bak -e "s/^persistent_peers *=.*/persistent_peers = \"$PEERS\"/" ~/.exrpd/config/config.toml
```
## Run a Devnet Validator Node
Run the Devnet validator node using following command:
```bash
exrpd tx staking create-validator \
--amount=1000000000000axrp \
--pubkey=$(exrpd tendermint show-validator) \
--moniker="<your_custom_moniker>" \
--chain-id=<chain_id> \
--commission-rate="0.05" \
--commission-max-rate="0.20" \
--commission-max-change-rate="0.01" \
--min-self-delegation="1000000" \
--gas="auto" \
--gas-prices="0.025axrp" \
--from=<key_name>
```
**Note** For more information on running a validator note, see [Run a validator](evm-sidechain-run-a-validator-node.html)
## Start the Node
Start the node.
```bash
exrpd start
```
Once enough voting power (+2/3) from the genesis validators is up-and-running, the node starts producing blocks.

View File

@@ -1060,6 +1060,22 @@ pages:
- en - en
- ja - ja
- md: concepts/interoperability/xrpl-interoperability.md
targets:
- en
- md: concepts/interoperability/intro-to-evm-sidechain.md
targets:
- en
- name: Hooks
html: https://xrpl-hooks.readme.io/
parent: xrpl-interoperability.html
blurb: Smart contract proposal for the XRP Ledger.
targets:
- en
# Redirect old "the-rippled-server.html" # Redirect old "the-rippled-server.html"
- name: The rippled Server - name: The rippled Server
html: the-rippled-server.html html: the-rippled-server.html
@@ -2071,6 +2087,34 @@ pages:
- en - en
- ja - ja
- name: Interoperability - EVM Sidechain
html: evm-sidechains.html
parent: tutorials.html
blurb: Learn how to interact with the EVM Sidechain Devnet.
template: pagetype-category.html.jinja
targets:
- en
- ja
- md: tutorials/interoperability/get-started-evm-sidechain.md
targets:
- en
- md: tutorials/interoperability/connect-metamask-to-xrpl-evm-sidechain.md
targets:
- en
- md: tutorials/interoperability/join-evm-sidechain-devnet.md
targets:
- en
- md: tutorials/interoperability/evm-sidechain-validator-security.md
targets:
- en
- md: tutorials/interoperability/evm-sidechain-run-a-validator-node.md
targets:
- en
# References ------------------------------------------------------------------- # References -------------------------------------------------------------------

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

View File

@@ -994,6 +994,14 @@
} }
} }
#xrpl-blog {
padding-bottom: 5rem;
@include media-breakpoint-up(md) {
padding-top: 104px;
padding-bottom: 104px;
}
}
#xrpl-events { #xrpl-events {
padding-bottom: 5rem; padding-bottom: 5rem;
@include media-breakpoint-up(md) { @include media-breakpoint-up(md) {

View File

@@ -677,6 +677,10 @@ pre code {
#run-a-network-node .text-cards a { #run-a-network-node .text-cards a {
color: $black; color: $black;
} }
#xrpl-blog .blog-graphic {
content: url(../img/community/lightmode/community-blog@2x.png);
}
#xrpl-events .text-light { #xrpl-events .text-light {
color: $black !important; color: $black !important;

View File

@@ -132,15 +132,15 @@
<div class="col"> <div class="col">
<div class="mb-4 pb-3 mb-lg-3 pb-lg-5"> <div class="mb-4 pb-3 mb-lg-3 pb-lg-5">
<h6 class="eyebrow mb-2">{% trans %}Awarded in a single grant{% endtrans %}</h6> <h6 class="eyebrow mb-2">{% trans %}Awarded in a single grant{% endtrans %}</h6>
<img src="./assets/img/community/community-grants-1.svg" class="w-100"> <img src="./assets/img/community/community-grants-1.svg">
</div> </div>
<div class="mb-4 pb-3 mb-lg-3 pb-lg-5"> <div class="mb-4 pb-3 mb-lg-3 pb-lg-5">
<h6 class="eyebrow mb-2">{% trans %}Distributed to grant recipients{% endtrans %}</h6> <h6 class="eyebrow mb-2">{% trans %}Distributed to grant recipients{% endtrans %}</h6>
<img src="./assets/img/community/community-grants-2.svg" class="w-100"> <img src="./assets/img/community/community-grants-2.svg">
</div> </div>
<div class="mb-4 pb-3 mb-lg-3 pb-lg-5"> <div class="mb-4 pb-3 mb-lg-3 pb-lg-5">
<h6 class="eyebrow mb-2">{% trans %}Open-source projects funded {% endtrans %}</h6> <h6 class="eyebrow mb-2">{% trans %}Open-source projects funded {% endtrans %}</h6>
<img src="./assets/img/community/community-grants-3.svg" class="w-100"> <img src="./assets/img/community/community-grants-3.svg">
</div> </div>
<div class="d-lg-none d-block mt-4 pt-3"> <div class="d-lg-none d-block mt-4 pt-3">
@@ -151,6 +151,33 @@
</div> </div>
</section> </section>
<!-- Blog -->
<section class="container-new" id="xrpl-blog">
<div class="card-grid card-grid-2xN align-items-lg-center">
<div class="col pr-2 d-lg-block d-none">
<img src="./assets/img/community/community-blog@2x.png" class="w-100 blog-graphic">
</div>
<div class="col">
<div class="d-flex flex-column-reverse mb-lg-2 pl-0">
<h2 class="h4 h2-sm">{% trans %}Showcase your XRPL project, application or product{% endtrans %}</h2>
<h6 class="eyebrow mb-3">{% trans %}XRPL Community Spotlight{% endtrans %}</h6>
</div>
<p class="mb-3 py-4">{% trans %}Get featured on the Developer Reflections blog or Use Cases page, and explore XRPL community highlights.{% endtrans %}</p>
<div class="d-lg-none d-block">
<img src="./assets/img/community/community-blog@2x.png" class="w-100 blog-graphic">
</div>
<div class="text-lg-left text-center">
<a class="btn btn-primary btn-arrow mb-4 mb-md-0" data-tf-popup="ssHZA7Ly" data-tf-iframe-props="title=Developer Reflections" data-tf-medium="snippet">{% trans %}Submit Your Projects{% endtrans %}</a>
<a class="ml-lg-4 video-external-link" target="_blank" href="https://xrpl.org/blog/">{% trans %}Read the Blog{% endtrans %}</a>
</div>
</div>
</div>
</section>
<!-- Events --> <!-- Events -->
<section class="container-new" id="xrpl-events"> <section class="container-new" id="xrpl-events">
@@ -279,6 +306,10 @@
{% block endbody %} {% block endbody %}
<!-- TypeFrom for blog -->
<script src="//embed.typeform.com/next/embed.js"></script>
<script type="text/javascript" src="{{currentpage.prefix}}assets/js/bodymovin.min.js"></script> <script type="text/javascript" src="{{currentpage.prefix}}assets/js/bodymovin.min.js"></script>
<!-- Light version for network node looks ok for both light/dark.--> <!-- Light version for network node looks ok for both light/dark.-->