mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2025-11-28 23:55:49 +00:00
Re-level non-docs content to top of repo and rename content→docs
This commit is contained in:
10
_code-samples/use-tickets/js/demo.html
Normal file
10
_code-samples/use-tickets/js/demo.html
Normal file
@@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Code Sample - Use Tickets</title>
|
||||
<script src="https://unpkg.com/xrpl@2.0.0/build/xrpl-latest-min.js"></script>
|
||||
<script type="application/javascript" src="use-tickets.js"></script>
|
||||
</head>
|
||||
<body>Open your browser's console (F12) to see the logs.</body>
|
||||
</html>
|
||||
5
_code-samples/use-tickets/js/package.json
Normal file
5
_code-samples/use-tickets/js/package.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"xrpl": "^2.11.0"
|
||||
}
|
||||
}
|
||||
129
_code-samples/use-tickets/js/use-tickets-multisig.js
Normal file
129
_code-samples/use-tickets/js/use-tickets-multisig.js
Normal file
@@ -0,0 +1,129 @@
|
||||
if (typeof module !== "undefined") {
|
||||
// Use var here because const/let are block-scoped to the if statement.
|
||||
var xrpl = require('xrpl')
|
||||
}
|
||||
// List which Tickets are outstanding against one’s own account and use Tickets to collect signatures for multisign transactions
|
||||
// https://xrpl.org/use-tickets.html
|
||||
// https://xrpl.org/signerlistset.html#signerlistset
|
||||
// https://xrpl.org/multi-signing.html#multi-signing
|
||||
|
||||
async function main() {
|
||||
// Connect to a testnet node
|
||||
console.log("Connecting to Testnet...")
|
||||
const client = new xrpl.Client('wss://s.altnet.rippletest.net:51233')
|
||||
await client.connect()
|
||||
|
||||
// Get account credentials from the Testnet Faucet
|
||||
console.log("Requesting account credentials from the Testnet faucet, this may take awhile...")
|
||||
const { wallet: main_wallet } = await client.fundWallet()
|
||||
|
||||
// Signer keys don't need to be funded on the ledger, it only needs to be cryptographically valid
|
||||
// Thus, we could generate keys and set them as signers without the need to fund their accounts
|
||||
// But we'll still fund them for testing purposes...
|
||||
const { wallet: wallet_1 } = await client.fundWallet()
|
||||
const { wallet: wallet_2 } = await client.fundWallet()
|
||||
const { wallet: wallet_3 } = await client.fundWallet()
|
||||
|
||||
console.log(" Main Account: ", main_wallet.address)
|
||||
console.log(" Seed: ", main_wallet.seed)
|
||||
|
||||
console.log("\n Signer 1: ", wallet_1.address)
|
||||
console.log(" Signer 2: ", wallet_2.address)
|
||||
console.log(" Signer 3: ", wallet_3.address)
|
||||
|
||||
// Send SignerListSet transaction
|
||||
// Since each signer is given a signer weight of 1 and there are 3 signers, the maximum quorom would be 3
|
||||
// SignerQuorom is a target number for the signer weights
|
||||
// A multisig from this list is valid only if the sum weights of the signatures provided is greater than or equal to the SignerQuorom
|
||||
const signerLiSetSignerList_tx = {
|
||||
TransactionType: "SignerListSet",
|
||||
Account: main_wallet.classicAddress,
|
||||
SignerEntries: [
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: wallet_1.classicAddress,
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: wallet_2.classicAddress,
|
||||
SignerWeight: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
SignerEntry: {
|
||||
Account: wallet_3.classicAddress,
|
||||
SignerWeight: 1,
|
||||
},
|
||||
}
|
||||
],
|
||||
SignerQuorum: 2,
|
||||
}
|
||||
|
||||
const signerLiSetSignerList_tx_prepared = await client.autofill(signerLiSetSignerList_tx)
|
||||
const SetSignerList_tx_signed = main_wallet.sign(signerLiSetSignerList_tx_prepared)
|
||||
console.log(`\n SignerListSet Tx hash: ${SetSignerList_tx_signed.hash}`)
|
||||
|
||||
const setsignerlist_submit = await client.submitAndWait(SetSignerList_tx_signed.tx_blob)
|
||||
console.log(`\t Submit result: ${setsignerlist_submit.result.meta.TransactionResult}`)
|
||||
|
||||
const CreateTicket_tx = await client.autofill({
|
||||
TransactionType: "TicketCreate",
|
||||
Account: main_wallet.address,
|
||||
TicketCount: 3
|
||||
})
|
||||
|
||||
const CreateTicket_tx_signed = main_wallet.sign(CreateTicket_tx)
|
||||
console.log("\n CreateTicket Tx hash:", CreateTicket_tx_signed.hash)
|
||||
|
||||
const ticket_submit = await client.submitAndWait(CreateTicket_tx_signed.tx_blob)
|
||||
console.log(" Submit result:", ticket_submit.result.meta.TransactionResult)
|
||||
|
||||
const ticket_response = await client.request({
|
||||
command: "account_objects",
|
||||
account: main_wallet.address,
|
||||
ledger_index: "validated",
|
||||
type: "ticket"
|
||||
})
|
||||
|
||||
console.log(`\n- Tickets issued by ${main_wallet.address}:\n`)
|
||||
for (let i = 0; i < ticket_response.result.account_objects.length; i++) {
|
||||
console.log(`Ticket ${i+1}: ${ticket_response.result.account_objects[i].TicketSequence}`)
|
||||
}
|
||||
|
||||
// We'll use this ticket on our tx
|
||||
const ticket_1 = ticket_response.result.account_objects[0].TicketSequence
|
||||
|
||||
console.log(`\n Ticket sequence ${ticket_1} will be used for our multi-sig transaction`)
|
||||
|
||||
const Payment_tx = {
|
||||
"TransactionType": "AccountSet",
|
||||
"Account": main_wallet.address,
|
||||
"TicketSequence": ticket_1,
|
||||
"LastLedgerSequence": null,
|
||||
"Sequence": 0
|
||||
}
|
||||
|
||||
const Payment_tx_prepared = await client.autofill(Payment_tx, signersCount=3)
|
||||
|
||||
// Each signer will sign the prepared tx (AccountSet_tx) and their signatures will be combines into 1 multi-sig transaction
|
||||
const { tx_blob: Payment_tx_signed_1 } = wallet_1.sign(Payment_tx_prepared, multisign=true)
|
||||
const { tx_blob: Payment_tx_signed_2 } = wallet_2.sign(Payment_tx_prepared, multisign=true)
|
||||
const { tx_blob: Payment_tx_signed_3 } = wallet_3.sign(Payment_tx_prepared, multisign=true)
|
||||
|
||||
console.log("\n All signers have signed the transaction with their corresponding keys")
|
||||
|
||||
// Combine 3 of the signers' signatures to form a multi-sig transaction
|
||||
const multisignedTx = xrpl.multisign([Payment_tx_signed_1, Payment_tx_signed_2, Payment_tx_signed_3])
|
||||
|
||||
const multisig_submit = await client.submitAndWait(multisignedTx)
|
||||
console.log("\n Multi-sig Submit result:", multisig_submit.result.meta.TransactionResult)
|
||||
console.log("\n Multi-sig Tx Binary:", multisignedTx)
|
||||
|
||||
client.disconnect()
|
||||
|
||||
// End main()
|
||||
}
|
||||
|
||||
main()
|
||||
76
_code-samples/use-tickets/js/use-tickets.js
Normal file
76
_code-samples/use-tickets/js/use-tickets.js
Normal file
@@ -0,0 +1,76 @@
|
||||
// Dependencies for Node.js.
|
||||
// In browsers, use a <script> tag instead.
|
||||
if (typeof module !== "undefined") {
|
||||
// Use var here because const/let are block-scoped to the if statement.
|
||||
var xrpl = require('xrpl')
|
||||
}
|
||||
|
||||
// Example credentials
|
||||
const wallet = xrpl.Wallet.fromSeed("sn3nxiW7v8KXzPzAqzyHXbSSKNuN9")
|
||||
|
||||
// Connect to Devnet (since that's where tickets are available)
|
||||
async function main() {
|
||||
const client = new xrpl.Client("wss://s.devnet.rippletest.net:51233")
|
||||
await client.connect()
|
||||
|
||||
// Get credentials from the Testnet Faucet -----------------------------------
|
||||
console.log("Getting a wallet from the faucet...")
|
||||
const {wallet, balance} = await client.fundWallet()
|
||||
|
||||
// Check Sequence Number -----------------------------------------------------
|
||||
const account_info = await client.request({
|
||||
"command": "account_info",
|
||||
"account": wallet.address
|
||||
})
|
||||
let current_sequence = account_info.result.account_data.Sequence
|
||||
|
||||
// Prepare and Sign TicketCreate ---------------------------------------------
|
||||
const prepared = await client.autofill({
|
||||
"TransactionType": "TicketCreate",
|
||||
"Account": wallet.address,
|
||||
"TicketCount": 10,
|
||||
"Sequence": current_sequence
|
||||
})
|
||||
const signed = wallet.sign(prepared)
|
||||
console.log(`Prepared TicketCreate transaction ${signed.hash}`)
|
||||
|
||||
// Submit TicketCreate -------------------------------------------------------
|
||||
const tx = await client.submitAndWait(signed.tx_blob)
|
||||
console.log(tx)
|
||||
|
||||
// Wait for Validation -------------------------------------------------------
|
||||
// submitAndWait() handles this automatically, but it can take 4-7s.
|
||||
|
||||
// Check Available Tickets ---------------------------------------------------
|
||||
let response = await client.request({
|
||||
"command": "account_objects",
|
||||
"account": wallet.address,
|
||||
"type": "ticket"
|
||||
})
|
||||
console.log("Available Tickets:", response.result.account_objects)
|
||||
|
||||
// Choose an arbitrary Ticket to use
|
||||
use_ticket = response.result.account_objects[0].TicketSequence
|
||||
|
||||
// Prepare and Sign Ticketed Transaction -------------------------------------
|
||||
const prepared_t = await client.autofill({
|
||||
"TransactionType": "AccountSet",
|
||||
"Account": wallet.address,
|
||||
"TicketSequence": use_ticket,
|
||||
"LastLedgerSequence": null, // Never expire this transaction.
|
||||
"Sequence": 0
|
||||
})
|
||||
const signed_t = wallet.sign(prepared_t)
|
||||
console.log(`Prepared ticketed transaction ${signed_t.hash}`)
|
||||
|
||||
// Submit Ticketed Transaction -----------------------------------------------
|
||||
const tx_t = await client.submitAndWait(signed_t.tx_blob)
|
||||
console.log(tx_t)
|
||||
|
||||
// Wait for Validation (again) -----------------------------------------------
|
||||
|
||||
// Disconnect when done (If you omit this, Node.js won't end the process)
|
||||
await client.disconnect()
|
||||
}
|
||||
|
||||
main()
|
||||
Reference in New Issue
Block a user