Merge pull request #1711 from pdp2121/migrate-snippets

migrate code snippets from xrpl-js and xrpl-py
This commit is contained in:
jonathanlei
2023-02-07 13:42:50 -08:00
committed by GitHub
20 changed files with 906 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
# Create and Claim a Payment Channel
Create, claim and verify a Payment Channel.
For more context, see [PayChannel](https://xrpl.org/paychannel.html).

View File

@@ -0,0 +1,83 @@
/*
* Create, claim and verify a Payment Channel.
* Reference: https://xrpl.org/paychannel.html
*/
import {
AccountObjectsRequest,
Client,
PaymentChannelCreate,
PaymentChannelClaim,
hashes,
} from 'xrpl'
const client = new Client('wss://s.altnet.rippletest.net:51233')
void claimPayChannel()
// The snippet walks us through creating and claiming a Payment Channel.
async function claimPayChannel(): Promise<void> {
await client.connect()
// creating wallets as prerequisite
const { wallet: wallet1 } = await client.fundWallet()
const { wallet: wallet2 } = await client.fundWallet()
console.log('Balances of wallets before Payment Channel is claimed:')
console.log(`Balance of ${wallet1.address} is ${await client.getXrpBalance(wallet1.address)} XRP`)
console.log(`Balance of ${wallet2.address} is ${await client.getXrpBalance(wallet2.address)} XRP`)
// create a Payment Channel and submit and wait for tx to be validated
const paymentChannelCreate: PaymentChannelCreate = {
TransactionType: 'PaymentChannelCreate',
Account: wallet1.classicAddress,
Amount: '100',
Destination: wallet2.classicAddress,
SettleDelay: 86400,
PublicKey: wallet1.publicKey,
}
console.log("Submitting a PaymentChannelCreate transaction...")
const paymentChannelResponse = await client.submitAndWait(
paymentChannelCreate,
{ wallet: wallet1 },
)
console.log("PaymentChannelCreate transaction response:")
console.log(paymentChannelResponse)
// check that the object was actually created
const accountObjectsRequest: AccountObjectsRequest = {
command: 'account_objects',
account: wallet1.classicAddress,
}
const accountObjects = (await client.request(accountObjectsRequest)).result
.account_objects
console.log("Account Objects:", accountObjects)
// destination claims the Payment Channel and we see the balances to verify.
const paymentChannelClaim: PaymentChannelClaim = {
Account: wallet2.classicAddress,
TransactionType: 'PaymentChannelClaim',
Channel: hashes.hashPaymentChannel(
wallet1.classicAddress,
wallet2.classicAddress,
paymentChannelResponse.result.Sequence ?? 0,
),
Amount: '100',
}
console.log("Submitting a PaymentChannelClaim transaction...")
const channelClaimResponse = await client.submit(paymentChannelClaim, {
wallet: wallet1,
})
console.log("PaymentChannelClaim transaction response:")
console.log(channelClaimResponse)
console.log('Balances of wallets after Payment Channel is claimed:')
console.log(`Balance of ${wallet1.address} is ${await client.getXrpBalance(wallet1.address)} XRP`)
console.log(`Balance of ${wallet2.address} is ${await client.getXrpBalance(wallet2.address)} XRP`)
await client.disconnect()
}

View File

@@ -0,0 +1,5 @@
# Get a Transaction on the Ledger
Retrieve and display a transaction on the ledger.
For more context, see [tx Method](https://xrpl.org/tx.html).

View File

@@ -0,0 +1,44 @@
/*
* Retrieve and display a transaction on the ledger.
* Reference: https://xrpl.org/tx.html
*/
import { Client, LedgerResponse, TxResponse } from 'xrpl'
const client = new Client('wss://s.altnet.rippletest.net:51233')
async function getTransaction(): Promise<void> {
await client.connect()
const ledger: LedgerResponse = await client.request({
command: 'ledger',
transactions: true,
ledger_index: 'validated',
})
console.log("Latest validated ledger:", ledger)
const transactions = ledger.result.ledger.transactions
if (transactions) {
const tx: TxResponse = await client.request({
command: 'tx',
transaction: transactions[0],
})
console.log("First transaction in the ledger:")
console.log(tx)
// The meta field would be a string(hex) when the `binary` parameter is `true` for the `tx` request.
if (tx.result.meta == null) {
throw new Error('meta not included in the response')
}
/*
* delivered_amount is the amount actually received by the destination account.
* Use this field to determine how much was delivered, regardless of whether the transaction is a partial payment.
* https://xrpl.org/transaction-metadata.html#delivered_amount
*/
if (typeof tx.result.meta !== 'string') {
console.log('delivered_amount:', tx.result.meta.delivered_amount)
}
}
await client.disconnect()
}
void getTransaction()

View File

@@ -0,0 +1,30 @@
"""Example of how we can see a transaction that was validated on the ledger"""
from xrpl.clients import JsonRpcClient
from xrpl.models.requests import Ledger, Tx
# References
# - https://xrpl.org/look-up-transaction-results.html
# - https://xrpl.org/parallel-networks.html#parallel-networks
# - https://xrpl.org/tx.html
# Create a client to connect to the main network
client = JsonRpcClient("https://xrplcluster.com/")
# Create a Ledger request and have the client call it
ledger_request = Ledger(ledger_index="validated", transactions=True)
ledger_response = client.request(ledger_request)
print(ledger_response)
# Extract out transactions from the ledger response
transactions = ledger_response.result["ledger"]["transactions"]
# If there are transactions, we can display the first one
# If there are none (visualized at https://testnet.xrpl.org/), try re running the script
if transactions:
# Create a Transaction request and have the client call it
tx_request = Tx(transaction=transactions[0])
tx_response = client.request(tx_request)
print("First transaction in the ledger:")
print(tx_response)
else:
print("No transactions were found on the ledger!")

View File

@@ -0,0 +1,5 @@
# Multisign a transaction.
Create and submit a SignerListSet and multisign a transaction.
For more context, see [Multi-signing](https://xrpl.org/multi-signing.html).

View File

@@ -0,0 +1,82 @@
/*
* Create and submit a SignerListSet and multisign a transaction.
* Reference: https://xrpl.org/multi-signing.html
*/
import {
multisign,
Client,
AccountSet,
convertStringToHex,
SignerListSet,
} from 'xrpl'
const client = new Client('wss://s.altnet.rippletest.net:51233')
async function multisigning(): Promise<void> {
await client.connect()
/*
* This wallet creation is for demonstration purposes.
* In practice, users generally will not have all keys in one spot,
* hence, users need to implement a way to get signatures.
*/
const { wallet: wallet1 } = await client.fundWallet()
const { wallet: wallet2 } = await client.fundWallet()
const { wallet: walletMaster } = await client.fundWallet()
const signerListSet: SignerListSet = {
TransactionType: 'SignerListSet',
Account: walletMaster.classicAddress,
SignerEntries: [
{
SignerEntry: {
Account: wallet1.classicAddress,
SignerWeight: 1,
},
},
{
SignerEntry: {
Account: wallet2.classicAddress,
SignerWeight: 1,
},
},
],
SignerQuorum: 2,
}
const signerListResponse = await client.submit(signerListSet, {
wallet: walletMaster,
})
console.log('SignerListSet constructed successfully:')
console.log(signerListResponse)
const accountSet: AccountSet = {
TransactionType: 'AccountSet',
Account: walletMaster.classicAddress,
Domain: convertStringToHex('example.com'),
}
const accountSetTx = await client.autofill(accountSet, 2)
console.log('AccountSet transaction is ready to be multisigned:')
console.log(accountSetTx)
const { tx_blob: tx_blob1 } = wallet1.sign(accountSetTx, true)
const { tx_blob: tx_blob2 } = wallet2.sign(accountSetTx, true)
const multisignedTx = multisign([tx_blob1, tx_blob2])
const submitResponse = await client.submit(multisignedTx)
if (submitResponse.result.engine_result === 'tesSUCCESS') {
console.log('The multisigned transaction was accepted by the ledger:')
console.log(submitResponse)
if (submitResponse.result.tx_json.Signers) {
console.log(
`The transaction had ${submitResponse.result.tx_json.Signers.length} signatures`,
)
}
} else {
console.log(
"The multisigned transaction was rejected by rippled. Here's the response from rippled:",
)
console.log(submitResponse)
}
await client.disconnect()
}
void multisigning()

View File

@@ -0,0 +1,79 @@
"""
Example of how we can multisign a transaction.
This will only work with version 2.0.0-beta.0 or later.
Reference: https://xrpl.org/multi-signing.html
"""
from xrpl.clients import JsonRpcClient
from xrpl.models.requests import SubmitMultisigned
from xrpl.models.transactions import AccountSet, SignerEntry, SignerListSet
from xrpl.transaction import (
autofill,
autofill_and_sign,
multisign,
send_reliable_submission,
sign,
)
from xrpl.utils import str_to_hex
from xrpl.wallet import generate_faucet_wallet
client = JsonRpcClient("https://s.altnet.rippletest.net:51234")
# Create a wallets to use for multisigning
# Prints debug info as it creates the wallet
master_wallet = generate_faucet_wallet(client, debug=True)
signer_wallet_1 = generate_faucet_wallet(client, debug=True)
signer_wallet_2 = generate_faucet_wallet(client, debug=True)
signer_entries = [
SignerEntry(account=signer_wallet_1.classic_address, signer_weight=1),
SignerEntry(account=signer_wallet_2.classic_address, signer_weight=1),
]
signer_list_set_tx = SignerListSet(
account=master_wallet.classic_address,
signer_quorum=2,
signer_entries=signer_entries,
)
signed_signer_list_set_tx = autofill_and_sign(signer_list_set_tx, master_wallet, client)
print("Constructed SignerListSet and submitting it to the ledger...")
signed_list_set_tx_response = send_reliable_submission(
signed_signer_list_set_tx, client
)
print("SignerListSet submitted, here's the response:")
print(signed_list_set_tx_response)
# Now that we've set up multisigning, let's try using it to submit an AccountSet
# transaction.
account_set_tx = AccountSet(
account=master_wallet.classic_address, domain=str_to_hex("example.com")
)
autofilled_account_set_tx = autofill(account_set_tx, client, len(signer_entries))
print("AccountSet transaction is ready to be multisigned")
print(autofilled_account_set_tx)
# Since we created both signer keys, we can sign locally, but if you are building an app
# That allows multisigning, you would need to request signatures from the key holders.
tx_1 = sign(autofilled_account_set_tx, signer_wallet_1, multisign=True)
tx_2 = sign(autofilled_account_set_tx, signer_wallet_2, multisign=True)
multisigned_tx = multisign(autofilled_account_set_tx, [tx_1, tx_2])
print("Successfully multisigned the transaction")
print(multisigned_tx)
multisigned_tx_response = client.request(SubmitMultisigned(tx_json=multisigned_tx))
if multisigned_tx_response.result["engine_result"] == "tesSUCCESS":
print("The multisigned transaction was accepted by the ledger:")
print(multisigned_tx_response)
if multisigned_tx_response.result["tx_json"]["Signers"]:
print(
"The transaction had "
f"{len(multisigned_tx_response.result['tx_json']['Signers'])} signatures"
)
else:
print(
"The multisigned transaction was rejected by rippled."
"Here's the response from rippled:"
)
print(multisigned_tx_response)

View File

@@ -0,0 +1,12 @@
# Send Partial Payments
Send partial payments with money amount less than the amount specified on 2 conditions:
- Sender has less money than the aamount specified in the payment Tx.
- Sender has the tfPartialPayment flag activated.
Other ways to specify flags are by using Hex code and decimal code.
eg. For partial payment(tfPartialPayment)
decimal ->131072, hex -> 0x00020000
For more context, see [Partial Payments](https://xrpl.org/partial-payments.html)

View File

@@ -0,0 +1,97 @@
import { Client, Payment, PaymentFlags, TrustSet } from 'xrpl'
const client = new Client('wss://s.altnet.rippletest.net:51233')
// This snippet walks us through partial payment.
// Reference: https://xrpl.org/partial-payments.html
async function partialPayment(): Promise<void> {
await client.connect()
// creating wallets as prerequisite
const { wallet: wallet1 } = await client.fundWallet()
const { wallet: wallet2 } = await client.fundWallet()
// create a trustline to issue an IOU `FOO` and set limit on it.
const trust_set_tx: TrustSet = {
TransactionType: 'TrustSet',
Account: wallet2.classicAddress,
LimitAmount: {
currency: 'FOO',
issuer: wallet1.classicAddress,
// Value for the new IOU - 10000000000 - is arbitarily chosen.
value: '10000000000',
},
}
console.log("Submitting a TrustSet transaction...")
const trust_set_res = await client.submitAndWait(trust_set_tx, {
wallet: wallet2,
})
console.log("TrustSet transaction response:")
console.log(trust_set_res)
console.log('Balances after trustline is created')
console.log(`Balance of ${wallet1.classicAddress} is ${await client.getBalances(wallet1.classicAddress)}`)
console.log(`Balance of ${wallet2.classicAddress} is ${await client.getBalances(wallet2.classicAddress)}`)
// Initially, the issuer(wallet1) sends an amount to the other account(wallet2)
const issue_quantity = '3840'
const payment: Payment = {
TransactionType: 'Payment',
Account: wallet1.classicAddress,
Amount: {
currency: 'FOO',
value: issue_quantity,
issuer: wallet1.classicAddress,
},
Destination: wallet2.classicAddress,
}
// submit payment
const initialPayment = await client.submitAndWait(payment, {
wallet: wallet1,
})
console.log("Initial payment response:", initialPayment)
console.log('Balances after issuer(wallet1) sends IOU("FOO") to wallet2')
console.log(`Balance of ${wallet1.classicAddress} is ${await client.getBalances(wallet1.classicAddress)}`)
console.log(`Balance of ${wallet2.classicAddress} is ${await client.getBalances(wallet2.classicAddress)}`)
/*
* Send money less than the amount specified on 2 conditions:
* 1. Sender has less money than the aamount specified in the payment Tx.
* 2. Sender has the tfPartialPayment flag activated.
*
* Other ways to specify flags are by using Hex code and decimal code.
* eg. For partial payment(tfPartialPayment)
* decimal ->131072, hex -> 0x00020000
*/
const partialPaymentTx: Payment = {
TransactionType: 'Payment',
Account: wallet2.classicAddress,
Amount: {
currency: 'FOO',
value: '4000',
issuer: wallet1.classicAddress,
},
Destination: wallet1.classicAddress,
Flags: PaymentFlags.tfPartialPayment,
}
// submit payment
console.log("Submitting a Partial Payment transaction...")
const submitResponse = await client.submitAndWait(partialPaymentTx, {
wallet: wallet2,
})
console.log("Partial Payment response: ", submitResponse)
console.log(
"Balances after Partial Payment, when wallet2 tried to send 4000 FOO's",
)
console.log(`Balance of ${wallet1.classicAddress} is ${await client.getBalances(wallet1.classicAddress)}`)
console.log(`Balance of ${wallet2.classicAddress} is ${await client.getBalances(wallet2.classicAddress)}`)
await client.disconnect()
}
void partialPayment()

View File

@@ -0,0 +1,102 @@
"""Example of how to handle partial payments"""
from xrpl.clients import JsonRpcClient
from xrpl.models.amounts import IssuedCurrencyAmount
from xrpl.models.requests import AccountLines
from xrpl.models.transactions import Payment, PaymentFlag, TrustSet
from xrpl.transaction import autofill_and_sign, send_reliable_submission
from xrpl.wallet import generate_faucet_wallet
# References
# - https://xrpl.org/partial-payments.html#partial-payments
# - https://xrpl.org/payment.html#payment-flags
# - https://xrpl.org/trustset.html#trustset
# - https://xrpl.org/account_lines.html#account_lines
# Create a client to connect to the test network
client = JsonRpcClient("https://s.altnet.rippletest.net:51234")
# Creating two wallets to send money between
wallet1 = generate_faucet_wallet(client, debug=True)
wallet2 = generate_faucet_wallet(client, debug=True)
# Create a TrustSet to issue an IOU `FOO` and set limit on it
trust_set_tx = TrustSet(
account=wallet2.classic_address,
limit_amount=IssuedCurrencyAmount(
currency="FOO",
value="10000000000",
issuer=wallet1.classic_address,
),
)
# Sign and autofill, then send transaction to the ledger
signed_trust_set_tx = autofill_and_sign(trust_set_tx, wallet2, client)
send_reliable_submission(signed_trust_set_tx, client)
# Both balances should be zero since nothing has been sent yet
print("Balances after trustline is claimed:")
print("Balance of ${wallet1.classic_address} is:")
print((client.request(AccountLines(account=wallet1.classic_address))).result["lines"])
print("Balance of ${wallet2.classic_address} is:")
print((client.request(AccountLines(account=wallet2.classic_address))).result["lines"])
# Create a Payment to send 3840 FOO from wallet1 (issuer) to destination (wallet2)
issue_quantity = "3840"
payment_tx = Payment(
account=wallet1.classic_address,
amount=IssuedCurrencyAmount(
currency="FOO",
value=issue_quantity,
issuer=wallet1.classic_address,
),
destination=wallet2.classic_address,
)
# Sign and autofill, then send transaction to the ledger
signed_payment_tx = autofill_and_sign(payment_tx, wallet1, client)
payment_response = send_reliable_submission(signed_payment_tx, client)
print("Initial Payment response: ", payment_response)
# Issuer (wallet1) should have -3840 FOO and destination (wallet2) should have 3840 FOO
print("Balances after wallet1 sends 3840 FOO to wallet2:")
print("Balance of ${wallet1.classic_address} is:")
print((client.request(AccountLines(account=wallet1.classic_address))).result["lines"])
print("Balance of ${wallet2.classic_address} is:")
print((client.request(AccountLines(account=wallet2.classic_address))).result["lines"])
# Send money less than the amount specified on 2 conditions:
# 1. Sender has less money than the amount specified in the payment Tx.
# 2. Sender has the tfPartialPayment flag activated.
# Other ways to specify flags are by using Hex code and decimal code.
# eg. For partial payment(tfPartialPayment)
# decimal ->131072, hex -> 0x00020000
# Create Payment to send 4000 (of 3840) FOO from wallet2 to wallet1
partial_payment_tx = Payment(
account=wallet2.classic_address,
amount=IssuedCurrencyAmount(
currency="FOO",
value="4000",
issuer=wallet1.classic_address,
),
destination=wallet1.classic_address,
flags=[PaymentFlag.TF_PARTIAL_PAYMENT],
send_max=IssuedCurrencyAmount(
currency="FOO",
value="1000000",
issuer=wallet1.classic_address,
),
)
# Sign and autofill, then send transaction to the ledger
signed_partial_payment_tx = autofill_and_sign(partial_payment_tx, wallet2, client)
partial_payment_response = send_reliable_submission(signed_partial_payment_tx, client)
print("Partial Payment response: ", partial_payment_response)
# Tried sending 4000 of 3840 FOO -> wallet1 and wallet2 should have 0 FOO
print("Balances after Partial Payment, when wallet2 tried to send 4000 FOOs")
print("Balance of ${wallet1.classic_address} is:")
print((client.request(AccountLines(account=wallet1.classic_address))).result["lines"])
print("Balance of ${wallet2.classic_address} is:")
print((client.request(AccountLines(account=wallet2.classic_address))).result["lines"])

View File

@@ -0,0 +1,5 @@
# Use Paths
Extract paths from RipplePathFind and send a payment using paths.
For more context, see [Paths](https://xrpl.org/paths.html).

View File

@@ -0,0 +1,53 @@
/*
* Extract best paths from RipplePathFind to trade with and send a payment using paths.
* Reference: https://xrpl.org/paths.html
*/
import { Client, Payment, RipplePathFindResponse } from 'xrpl'
const client = new Client('wss://s.altnet.rippletest.net:51233')
async function createTxWithPaths(): Promise<void> {
await client.connect()
const { wallet } = await client.fundWallet()
const destination_account = 'rKT4JX4cCof6LcDYRz8o3rGRu7qxzZ2Zwj'
const destination_amount = {
value: '0.001',
currency: 'USD',
issuer: 'rVnYNK9yuxBz4uP8zC8LEFokM2nqH3poc',
}
const request = {
command: 'ripple_path_find',
source_account: wallet.classicAddress,
source_currencies: [
{
currency: 'XRP',
},
],
destination_account,
destination_amount,
}
const resp: RipplePathFindResponse = await client.request(request)
console.log("Ripple Path Find response: ", resp)
const paths = resp.result.alternatives[0].paths_computed
console.log("Computed paths: ", paths)
const tx: Payment = {
TransactionType: 'Payment',
Account: wallet.classicAddress,
Amount: destination_amount,
Destination: destination_account,
Paths: paths,
}
await client.autofill(tx)
const signed = wallet.sign(tx)
console.log('signed:', signed)
await client.disconnect()
}
void createTxWithPaths()

View File

@@ -0,0 +1,50 @@
"""Example of how to find the best path to trade with"""
from xrpl.clients import JsonRpcClient
from xrpl.models.amounts import IssuedCurrencyAmount
from xrpl.models.currencies.xrp import XRP
from xrpl.models.requests import RipplePathFind
from xrpl.models.transactions import Payment
from xrpl.transaction import autofill_and_sign
from xrpl.wallet import generate_faucet_wallet
# References
# - https://xrpl.org/paths.html#paths
# - https://xrpl.org/ripple_path_find.html#ripple_path_find
# Create a client to connect to the test network
client = JsonRpcClient("https://s.altnet.rippletest.net:51234")
# Creating wallet to send money from
wallet = generate_faucet_wallet(client, debug=True)
# Create account and amount variables for later transaction
destination_account = "rKT4JX4cCof6LcDYRz8o3rGRu7qxzZ2Zwj"
destination_amount = IssuedCurrencyAmount(
value="0.001",
currency="USD",
issuer="rVnYNK9yuxBz4uP8zC8LEFokM2nqH3poc",
)
# Create a RipplePathFind request and have the client call it
path_request = RipplePathFind(
source_account=wallet.classic_address,
source_currencies=[XRP()],
destination_account=destination_account,
destination_amount=destination_amount,
)
path_response = client.request(path_request)
print(path_response)
# Extract out paths from the RipplePathFind response
paths = path_response.result["alternatives"][0]["paths_computed"]
print(paths)
# # Create a Payment to send money from wallet to destination_account using path
payment_tx = Payment(
account=wallet.classic_address,
amount=destination_amount,
destination=destination_account,
paths=paths,
)
print("signed: ", autofill_and_sign(payment_tx, wallet, client))

View File

@@ -0,0 +1,9 @@
# Implement Reliable Transaction Submission
Send a transaction and see its validation response. For the implementation in this example, we have made the following decisions:
- We allow the autofill function as a part of submitAndWait to fill up the account sequence, LastLedgerSequence and Fee. Payments are defined upfront, and idempotency is not needed. If the script is run a second time, duplicate payments will result.
- We will rely on the submitAndWait function to get us the transaction submission result after the wait time.
- Transactions will not be automatically retried. Transactions are limited to XRP-to-XRP payments and cannot "succeed" in an unexpected way.
For more context, see [Reliable Transaction Submission](https://xrpl.org/reliable-transaction-submission.html)

View File

@@ -0,0 +1,81 @@
import { Client, Payment } from 'xrpl';
/**
* When implementing Reliable Transaction Submission, there are many potential solutions, each with different trade-offs.
* The main decision points are:
* 1) Transaction preparation:
* - The autofill function as a part of the submitAndWait should be able to correctly populate
* values for the fields Sequence, LastLedgerSequence and Fee.
* 2) Transaction status retrieval. Options include:
* - Poll for transaction status:
* - On a regular interval (e.g. Every 3-5 seconds), or
* - When a new validated ledger is detected
* + (To accommodate an edge case in transaction retrieval,
* check the sending account's Sequence number to confirm that it has the expected value;
* alternatively, wait until a few additional ledgers have been validated before deciding that a
* transaction has definitively not been included in a validated ledger)
* - Listen for transaction status: scan all validated transactions to see if our transactions are among them
* 3) What do we do when a transaction fails? It is possible to implement retry logic, but caution is advised.
* Note that there are a few ways for a transaction to fail:
* A) `tec`: The transaction was included in a ledger but only claimed the transaction fee
* B) `tesSUCCESS` but unexpected result: The transaction was successful but did not have the expected result.
* This generally does not occur for XRP-to-XRP payments
* C) The transaction was not, and never will be, included in a validated ledger [3C].
*
* References:
* - https://xrpl.org/reliable-transaction-submission.html
* - https://xrpl.org/send-xrp.html
* - https://xrpl.org/look-up-transaction-results.html
* - https://xrpl.org/monitor-incoming-payments-with-websocket.html.
*
* For the implementation in this example, we have made the following decisions:
* 1) We allow the autofill function as a part of submitAndWait to fill up the account sequence,
* LastLedgerSequence and Fee. Payments are defined upfront, and idempotency is not needed.
* If the script is run a second time, duplicate payments will result.
* 2) We will rely on the xrpl.js submitAndWait function to get us the transaction submission result after the wait time.
* 3) Transactions will not be automatically retried. Transactions are limited to XRP-to-XRP payments
* and cannot "succeed" in an unexpected way.
*/
const client = new Client("wss://s.altnet.rippletest.net:51233");
void sendReliableTx();
async function sendReliableTx(): Promise<void> {
await client.connect();
// creating wallets as prerequisite
const { wallet: wallet1 } = await client.fundWallet();
const { wallet: wallet2 } = await client.fundWallet();
console.log("Balances of wallets before Payment tx");
console.log(`Balance of ${wallet1.classicAddress} is ${await client.getXrpBalance(wallet1.classicAddress)}XRP`);
console.log(`Balance of ${wallet2.classicAddress} is ${await client.getXrpBalance(wallet2.classicAddress)}XRP`);
// create a Payment tx and submit and wait for tx to be validated
const payment: Payment = {
TransactionType: "Payment",
Account: wallet1.classicAddress,
Amount: "1000",
Destination: wallet2.classicAddress,
};
console.log("Submitting a Payment transaction...")
const paymentResponse = await client.submitAndWait(payment, {
wallet: wallet1,
});
console.log("\nTransaction was submitted.\n");
const txResponse = await client.request({
command: "tx",
transaction: paymentResponse.result.hash,
});
// With the following reponse we are able to see that the tx was indeed validated.
console.log("Validated:", txResponse.result.validated);
console.log("Balances of wallets after Payment tx:");
console.log(`Balance of ${wallet1.classicAddress} is ${await client.getXrpBalance(wallet1.classicAddress)}XRP`);
console.log(`Balance of ${wallet2.classicAddress} is ${await client.getXrpBalance(wallet2.classicAddress)}XRP`);
await client.disconnect();
}

View File

@@ -0,0 +1,49 @@
"""Example of how to send a transaction and see its validation response"""
from xrpl.account import get_balance
from xrpl.clients import JsonRpcClient
from xrpl.models.requests import Tx
from xrpl.models.transactions import Payment
from xrpl.transaction import autofill_and_sign, send_reliable_submission
from xrpl.wallet import generate_faucet_wallet
# References:
# - https://xrpl.org/reliable-transaction-submission.html
# - https://xrpl.org/send-xrp.html
# - https://xrpl.org/look-up-transaction-results.html
# Create a client to connect to the test network
client = JsonRpcClient("https://s.altnet.rippletest.net:51234")
# Creating two wallets to send money between
wallet1 = generate_faucet_wallet(client, debug=True)
wallet2 = generate_faucet_wallet(client, debug=True)
# Both balances should be zero since nothing has been sent yet
print("Balances of wallets before Payment tx")
print(get_balance(wallet1.classic_address, client))
print(get_balance(wallet2.classic_address, client))
# Create a Payment transaction
payment_tx = Payment(
account=wallet1.classic_address,
amount="1000",
destination=wallet2.classic_address,
)
# Sign and autofill the transaction (prepares it to be ready to submit)
signed_payment_tx = autofill_and_sign(payment_tx, wallet1, client)
# Submits transaction and waits for response (validated or rejected)
payment_response = send_reliable_submission(signed_payment_tx, client)
print("Transaction was submitted")
# Create a Transaction request to see transaction
tx_response = client.request(Tx(transaction=payment_response.result["hash"]))
# Check validated field on the transaction
print("Validated:", tx_response.result["validated"])
# Check balances after 1000 was sent from wallet1 to wallet2
print("Balances of wallets after Payment tx:")
print(get_balance(wallet1.classic_address, client))
print(get_balance(wallet2.classic_address, client))

View File

@@ -0,0 +1,5 @@
# Use `SetRegularKey`
Use `SetRegularKey` to assign a key pair to a wallet and make a payment signed using the regular key wallet.
For more context, see [SetRegularKey](https://xrpl.org/setregularkey.html).

View File

@@ -0,0 +1,56 @@
/*
* Use `SetRegularKey` to assign a key pair to a wallet and make a payment signed using the regular key wallet.
* Reference: https://xrpl.org/setregularkey.html
*/
import { Client, Payment, SetRegularKey } from 'xrpl'
const client = new Client('wss://s.altnet.rippletest.net:51233')
async function setRegularKey(): Promise<void> {
await client.connect()
const { wallet: wallet1 } = await client.fundWallet()
const { wallet: wallet2 } = await client.fundWallet()
const { wallet: regularKeyWallet } = await client.fundWallet()
console.log('Balances before payment')
console.log(`Balance of ${wallet1.classicAddress} is ${await client.getXrpBalance(wallet1.classicAddress)}XRP`)
console.log(`Balance of ${wallet2.classicAddress} is ${await client.getXrpBalance(wallet2.classicAddress)}XRP`)
// assigns key-pair(regularKeyWallet) to wallet1 using `SetRegularKey`.
const tx: SetRegularKey = {
TransactionType: 'SetRegularKey',
Account: wallet1.classicAddress,
RegularKey: regularKeyWallet.classicAddress,
}
console.log('Submitting a SetRegularKey transaction...')
const response = await client.submitAndWait(tx, {
wallet: wallet1,
})
console.log('Response for successful SetRegularKey tx')
console.log(response)
/*
* when wallet1 sends payment to wallet2 and
* signs using the regular key wallet, the transaction goes through.
*/
const payment: Payment = {
TransactionType: 'Payment',
Account: wallet1.classicAddress,
Destination: wallet2.classicAddress,
Amount: '1000',
}
const submitTx = await client.submit(payment, {
wallet: regularKeyWallet,
})
console.log('Response for tx signed using Regular Key:')
console.log(submitTx)
console.log('Balances after payment:')
console.log(`Balance of ${wallet1.classicAddress} is ${await client.getXrpBalance(wallet1.classicAddress)}XRP`)
console.log(`Balance of ${wallet2.classicAddress} is ${await client.getXrpBalance(wallet2.classicAddress)}XRP`)
await client.disconnect()
}
void setRegularKey()

View File

@@ -0,0 +1,54 @@
"""Example of how we can setting a regular key"""
from xrpl.account import get_balance
from xrpl.clients import JsonRpcClient
from xrpl.models.transactions import Payment, SetRegularKey
from xrpl.transaction import autofill_and_sign, send_reliable_submission
from xrpl.wallet import generate_faucet_wallet
# References
# - https://xrpl.org/assign-a-regular-key-pair.html#assign-a-regular-key-pair
# - https://xrpl.org/setregularkey.html#setregularkey
# - https://xrpl.org/change-or-remove-a-regular-key-pair.html
# Create a client to connect to the test network
client = JsonRpcClient("https://s.altnet.rippletest.net:51234")
# Creating two wallets to send money between
wallet1 = generate_faucet_wallet(client, debug=True)
wallet2 = generate_faucet_wallet(client, debug=True)
regular_key_wallet = generate_faucet_wallet(client, debug=True)
# Both balances should be zero since nothing has been sent yet
print("Balances before payment:")
print(get_balance(wallet1.classic_address, client))
print(get_balance(wallet2.classic_address, client))
# Assign key pair (regular_key_wallet) to wallet1 using SetRegularKey transaction
tx = SetRegularKey(
account=wallet1.classic_address, regular_key=regular_key_wallet.classic_address
)
signed_tx = autofill_and_sign(tx, wallet1, client)
set_regular_key_response = send_reliable_submission(signed_tx, client)
print("Response for successful SetRegularKey tx:")
print(set_regular_key_response)
# Since regular_key_wallet is linked to wallet1,
# walet1 can send payment to wallet2 and have regular_key_wallet sign it
payment = Payment(
account=wallet1.classic_address,
destination=wallet2.classic_address,
amount="1000",
)
signed_payment = autofill_and_sign(payment, regular_key_wallet, client)
payment_response = send_reliable_submission(signed_payment, client)
print("Response for tx signed using Regular Key:")
print(payment_response)
# Balance after sending 1000 from wallet1 to wallet2
print("Balances after payment:")
print(get_balance(wallet1.classic_address, client))
print(get_balance(wallet2.classic_address, client))