xrpl.js 2.0: updates for lib fixes, etc.

This commit is contained in:
mDuo13
2021-09-24 17:04:36 -07:00
parent 9fc9d58c82
commit 8ef2c87a21
9 changed files with 103 additions and 104 deletions

View File

@@ -239,12 +239,12 @@ function get_address(event) {
} }
/** /**
* Get the secret key from the Generate step (snippet), or display an error in * Get the Wallet from the Generate step (snippet), or display an error in
* the relevant interactive block if it fails—usually because the user hasn't * the relevant interactive block if it fails—usually because the user hasn't
* cliked the "Get Credentials" button yet. * cliked the "Get Credentials" button yet.
* @return {String, undefined} The secret key, if available, or undefined if not * @return {Wallet, undefined} The Wallet instance, if available, or undefined if not
*/ */
function get_secret(event) { function get_wallet(event) {
const secret = $("#use-secret").text() const secret = $("#use-secret").text()
if (!secret) { if (!secret) {
const block = $(event.target).closest(".interactive-block") const block = $(event.target).closest(".interactive-block")
@@ -256,7 +256,7 @@ function get_secret(event) {
if (!block.length) {return} if (!block.length) {return}
show_error(block, tl("Can't use the example secret here. Check that the previous steps were completed successfully.")) show_error(block, tl("Can't use the example secret here. Check that the previous steps were completed successfully."))
} }
return secret return xrpl.Wallet.fromSeed(secret)
} }
/** /**
@@ -301,7 +301,7 @@ function setup_connect_step() {
console.error("Interactive Tutorial: WS URL not found. Did you set use_network?") console.error("Interactive Tutorial: WS URL not found. Did you set use_network?")
return return
} }
api = new ripple.RippleAPI({server: ws_url}) api = new xrpl.Client(ws_url)
api.on('connected', async function() { api.on('connected', async function() {
$("#connection-status").text(tl("Connected")) $("#connection-status").text(tl("Connected"))
$("#connect-button").prop("disabled", true) $("#connect-button").prop("disabled", true)
@@ -309,6 +309,9 @@ function setup_connect_step() {
$(".connection-required").prop("disabled", false) $(".connection-required").prop("disabled", false)
$(".connection-required").prop("title", "") $(".connection-required").prop("title", "")
// Subscribe to ledger close events
api.request({command: "subscribe", streams: ["ledger"]})
complete_step("Connect") complete_step("Connect")
}) })
api.on('disconnected', (code) => { api.on('disconnected', (code) => {
@@ -333,7 +336,7 @@ function setup_connect_step() {
* step's "tx-validation-status" field doesn't have a final result set. * step's "tx-validation-status" field doesn't have a final result set.
* These listeners do very little (just updating the latest validated ledger * These listeners do very little (just updating the latest validated ledger
* index) until you activate one with activate_wait_step(step_name). * index) until you activate one with activate_wait_step(step_name).
* Requires ripple-lib to be loaded and instantiated as "api" first. * Requires xrpl.js to be loaded and instantiated as "api" first.
*/ */
function setup_wait_steps() { function setup_wait_steps() {
const wait_steps = $(".wait-step") const wait_steps = $(".wait-step")
@@ -342,9 +345,9 @@ function setup_wait_steps() {
const wait_step = $(el) const wait_step = $(el)
const explorer_url = wait_step.data("explorerurl") const explorer_url = wait_step.data("explorerurl")
const status_box = wait_step.find(".tx-validation-status") const status_box = wait_step.find(".tx-validation-status")
api.on('ledger', async (ledger) => { api.on('ledgerClosed', async (ledger) => {
// Update the latest validated ledger index in this step's table // Update the latest validated ledger index in this step's table
wait_step.find(".validated-ledger-version").text(ledger.ledgerVersion) wait_step.find(".validated-ledger-version").text(ledger.ledger_index)
if (!status_box.data("status_pending")) { if (!status_box.data("status_pending")) {
// Before submission or after a final result. // Before submission or after a final result.
// Either way, nothing more to do here. // Either way, nothing more to do here.
@@ -354,17 +357,18 @@ function setup_wait_steps() {
const transaction = wait_step.find(".waiting-for-tx").text().trim() const transaction = wait_step.find(".waiting-for-tx").text().trim()
const min_ledger = parseInt(wait_step.find(".earliest-ledger-version").text()) const min_ledger = parseInt(wait_step.find(".earliest-ledger-version").text())
const max_ledger = parseInt(wait_step.find(".lastledgersequence").text()) const max_ledger = parseInt(wait_step.find(".lastledgersequence").text())
let tx_result let tx_response
try { try {
tx_result = await api.request("tx", { tx_response = await api.request({
command: "tx",
transaction, transaction,
min_ledger, min_ledger,
max_ledger max_ledger
}) })
if (tx_result.validated) { if (tx_response.result.validated) {
status_box.html( status_box.html(
`<th>${tl("Final Result:")}</th><td>${tx_result.meta.TransactionResult} `<th>${tl("Final Result:")}</th><td>${tx_response.result.meta.TransactionResult}
(<a href="${explorer_url}/transactions/${transaction}" (<a href="${explorer_url}/transactions/${transaction}"
target="_blank">${tl("Validated")}</a>)</td>`) target="_blank">${tl("Validated")}</a>)</td>`)
@@ -402,22 +406,22 @@ function setup_wait_steps() {
* @param {String} step_name The exact name of the "Wait" step to activate, as * @param {String} step_name The exact name of the "Wait" step to activate, as
* defined in the start_step(step_name) function in * defined in the start_step(step_name) function in
* the MD file. * the MD file.
* @param {Object} prelim_result The (resolved) return value of submitting a * @param {Object} prelim The (resolved) return value of submitting a
* transaction blob via api.request("submit", {opts}) * transaction blob via api.request({command: "submit", opts})
*/ */
async function activate_wait_step(step_name, prelim_result) { async function activate_wait_step(step_name, prelim) {
const step_id = slugify(step_name) const step_id = slugify(step_name)
const wait_step = $(`#interactive-${step_id} .wait-step`) const wait_step = $(`#interactive-${step_id} .wait-step`)
const status_box = wait_step.find(".tx-validation-status") const status_box = wait_step.find(".tx-validation-status")
const tx_id = prelim_result.tx_json.hash const tx_id = prelim.result.tx_json.hash
const lls = prelim_result.tx_json.LastLedgerSequence || tl("(None)") const lls = prelim.result.tx_json.LastLedgerSequence || tl("(None)")
if (wait_step.find(".waiting-for-tx").text() == tx_id) { if (wait_step.find(".waiting-for-tx").text() == tx_id) {
// Re-submitting the same transaction? Don't update min_ledger. // Re-submitting the same transaction? Don't update min_ledger.
} else { } else {
wait_step.find(".waiting-for-tx").text(tx_id) wait_step.find(".waiting-for-tx").text(tx_id)
wait_step.find(".earliest-ledger-version").text( wait_step.find(".earliest-ledger-version").text(
prelim_result.validated_ledger_index prelim.result.validated_ledger_index
) )
} }
wait_step.find(".lastledgersequence").text(lls) wait_step.find(".lastledgersequence").text(lls)
@@ -493,36 +497,35 @@ function add_memo(event, tx_json) {
* @param {Event} event The (click) event that this is helping to handle. * @param {Event} event The (click) event that this is helping to handle.
* @param {Object} tx_json JSON object of transaction instructions to finish * @param {Object} tx_json JSON object of transaction instructions to finish
* preparing and send. * preparing and send.
* @param {String} secret (Optional) The base58 seed to use to sign the * @param {Wallet} wallet (Optional) The xrpl.js Wallet instance to use to sign the
* transaction. If omitted, look up the #use-secret field * transaction. If omitted, look up the #use-secret field
* which was probably added by a "Get Credentials" step. * which was probably added by a "Get Credentials" step.
*/ */
async function generic_full_send(event, tx_json, secret) { async function generic_full_send(event, tx_json, wallet) {
const block = $(event.target).closest(".interactive-block") const block = $(event.target).closest(".interactive-block")
const blob_selector = $(event.target).data("txBlobFrom") const blob_selector = $(event.target).data("txBlobFrom")
const wait_step_name = $(event.target).data("waitStepName") const wait_step_name = $(event.target).data("waitStepName")
block.find(".output-area").html("") block.find(".output-area").html("")
if (secret === undefined) { if (wallet === undefined) {
secret = get_secret(event) wallet = get_wallet(event)
} }
if (!secret) {return} if (!wallet) {return}
add_memo(event, tx_json) add_memo(event, tx_json)
block.find(".loader").show() block.find(".loader").show()
const prepared = await api.prepareTransaction(tx_json, { const prepared = await api.autofill(tx_json)
maxLedgerVersionOffset: 20
})
block.find(".output-area").append( block.find(".output-area").append(
`<p>${tl("Prepared transaction:")}</p> `<p>${tl("Prepared transaction:")}</p>
<pre><code>${pretty_print(prepared.txJSON)}</code></pre>`) <pre><code>${pretty_print(prepared)}</code></pre>`)
const signed = api.sign(prepared.txJSON, secret) const signed = wallet.signTransaction(prepared)
block.find(".output-area").append( block.find(".output-area").append(
`<p>${tl("Transaction hash:")} <code id="tx_id">${signed.id}</code></p>`) `<p>${tl("Transaction hash:")} <code id="tx_id">${xrpl.computeSignedTransactionHash(signed)}</code></p>`)
// TODO: update computeSignedTransactionHash if that changes
await do_submit(block, {"tx_blob": signed.signedTransaction}, wait_step_name) await do_submit(block, {"tx_blob": signed}, wait_step_name)
} }
/** /**
@@ -559,8 +562,8 @@ async function submit_handler(event) {
async function do_submit(block, submit_opts, wait_step_name) { async function do_submit(block, submit_opts, wait_step_name) {
block.find(".loader").show() block.find(".loader").show()
try { try {
// Future feature: support passing in options like fail_hard here. submit_opts["command"] = "submit"
const prelim_result = await api.request("submit", submit_opts) const prelim_result = await api.request(submit_opts)
block.find(".output-area").append( block.find(".output-area").append(
`<p>${tl("Preliminary result:")}</p> `<p>${tl("Preliminary result:")}</p>
<pre><code>${pretty_print(prelim_result)}</code></pre>`) <pre><code>${pretty_print(prelim_result)}</code></pre>`)

View File

@@ -1,5 +1,3 @@
const xrpl = ripple; // TODO: remove when webpack build is updated
jQuery(function ($) { jQuery(function ($) {
const FULL_HISTORY_SERVER = "wss://s2.ripple.com" const FULL_HISTORY_SERVER = "wss://s2.ripple.com"
const reTxId = /^[0-9A-Fa-f]{64}$/ const reTxId = /^[0-9A-Fa-f]{64}$/

View File

@@ -1,12 +1,13 @@
// Submit-and-verify XRPL transaction using ripple-lib (v1.x) // Submit-and-verify XRPL transaction using xrpl.js (v2.0)
// Demonstrates how to submit a transaction and wait for validation. // Demonstrates how to submit a transaction and wait for validation.
// This is not true "robust" transaction submission because it does not protect // This is not true "robust" transaction submission because it does not protect
// against power outages or other sudden interruptions. // against power outages or other sudden interruptions.
// Look up a transaction's result. // Look up a transaction's result.
// Arguments: // Arguments:
// @param api object RippleAPI instance connected to the network where you // @param api object Client instance connected to the network where you
// submitted the transaction. // submitted the transaction. MUST ALREADY BE SUBSCRIBED TO THE
// `ledger` event stream.
// @param tx_id string The identifying hash of the transaction. // @param tx_id string The identifying hash of the transaction.
// @param max_ledger int optional The highest ledger index where the // @param max_ledger int optional The highest ledger index where the
// transaction can be validated. // transaction can be validated.
@@ -145,6 +146,9 @@ function lookup_tx_final(api, tx_id, max_ledger, min_ledger) {
// something else went wrong when trying to look up the results. The // something else went wrong when trying to look up the results. The
// warning written to the console can tell you more about what happened. // warning written to the console can tell you more about what happened.
async function submit_and_verify(api, tx_blob) { async function submit_and_verify(api, tx_blob) {
// Make sure we subscribe to the ledger stream. This is idempotent so we don't
// have to worry about oversubscribing.
api.request({"command": "subscribe", "streams": ["ledger"]})
const prelim = await api.request({"command": "submit", "tx_blob": tx_blob}) const prelim = await api.request({"command": "submit", "tx_blob": tx_blob})
console.log("Preliminary result code:", prelim.result.engine_result) console.log("Preliminary result code:", prelim.result.engine_result)
const min_ledger = prelim.result.validated_ledger_index const min_ledger = prelim.result.validated_ledger_index

View File

@@ -1,5 +1,3 @@
const xrpl = ripple; // TODO: remove when webpack build is updated
async function wait_for_seq(network_url, address) { async function wait_for_seq(network_url, address) {
const api = new xrpl.Client(network_url) const api = new xrpl.Client(network_url)
await api.connect() await api.connect()

View File

@@ -32,17 +32,20 @@ $(document).ready(() => {
block.find(".output-area").html("") block.find(".output-area").html("")
block.find(".loader").show() block.find(".loader").show()
let account_info = await api.request("account_info", { let account_info = await api.request({
"command": "account_info",
"account": address, "account": address,
"ledger_index": "validated" "ledger_index": "validated"
}) })
console.log(account_info) console.log(account_info)
const flags = api.parseAccountFlags(account_info.account_data.Flags) // TODO: what's the replacement for parseAccountFlags?
//const flags = api.parseAccountFlags(account_info.account_data.Flags)
block.find(".loader").hide() block.find(".loader").hide()
block.find(".output-area").append( block.find(".output-area").append(
`<pre><code>${pretty_print(flags)}</code></pre>`) `<pre><code>${pretty_print(flags)}</code></pre>`)
if (flags.requireDestinationTag) { //if (flags.requireDestinationTag) {
if (account_info.result.account_data.Flags | 0x00020000) { // TODO: change this back if there's a better way
block.find(".output-area").append(`<p><i class="fa fa-check-circle"></i> block.find(".output-area").append(`<p><i class="fa fa-check-circle"></i>
Require Destination Tag is enabled.</p>`) Require Destination Tag is enabled.</p>`)
} else { } else {
@@ -63,24 +66,30 @@ $(document).ready(() => {
let secret = block.data("testSendSecret") let secret = block.data("testSendSecret")
if (!address || !secret) { if (!address || !secret) {
console.debug("First-time setup for test sender...") console.debug("First-time setup for test sender...")
const faucet_url = $("#generate-creds-button").data("fauceturl") // Old way:
const data = await call_faucet(faucet_url) // const faucet_url = $("#generate-creds-button").data("fauceturl")
address = data.account.classicAddress // const data = await call_faucet(faucet_url)
block.data("testSendAddress", address) // address = data.account.classicAddress
secret = data.account.secret // block.data("testSendAddress", address)
block.data("testSendSecret", secret) // secret = data.account.secret
// block.data("testSendSecret", secret)
// New way: get a wallet
let test_sender_wallet = await api.generateFaucetWallet()
block.data("testSendAddress", test_sender_wallet.classicAddress)
block.data("testSendSecret", test_sender_wallet.seed)
// First time: Wait for our test sender to be fully funded, so we don't // First time: Wait for our test sender to be fully funded, so we don't
// get the wrong starting sequence number. // get the wrong starting sequence number.
while (true) { while (true) {
try { try {
await api.request("account_info", {account: address, ledger_index: "validated"}) await api.request({command: "account_info", account: address, ledger_index: "validated"})
break break
} catch(e) { } catch(e) {
await new Promise(resolve => setTimeout(resolve, 1000)) await new Promise(resolve => setTimeout(resolve, 1000))
} }
} }
} }
return {address, secret} return test_sender_wallet
} }
// Actual handler for the two buttons in the Send Test Payments block. // Actual handler for the two buttons in the Send Test Payments block.
@@ -95,7 +104,7 @@ $(document).ready(() => {
const test_sender = await get_test_sender(block) const test_sender = await get_test_sender(block)
const tx_json = { const tx_json = {
"TransactionType": "Payment", "TransactionType": "Payment",
"Account": test_sender.address, "Account": test_sender.classicAddress,
"Amount": "3152021", "Amount": "3152021",
"Destination": address "Destination": address
} }
@@ -104,39 +113,21 @@ $(document).ready(() => {
tx_json["DestinationTag"] = parseInt(dt) tx_json["DestinationTag"] = parseInt(dt)
} }
const prepared = await api.prepareTransaction(tx_json) const prepared = await api.autofill(tx_json)
const signed = api.sign(prepared.txJSON, test_sender.secret) const tx_blob = test_sender.signTransaction(prepared)
console.debug("Submitting test payment", prepared.txJSON) console.debug("Submitting test payment", prepared)
const prelim_result = await api.request("submit", const prelim = await api.request({"command": "submit", tx_blob})
{"tx_blob": signed.signedTransaction}) const tx_hash = xrpl.computeSignedTransactionHash(tx_blob)
block.find(".loader").hide() block.find(".loader").hide()
block.find(".output-area").append(`<p>${tx_json.TransactionType} block.find(".output-area").append(`<p>${tx_json.TransactionType}
${prepared.instructions.sequence} ${(dt?"WITH":"WITHOUT")} Dest. Tag: ${prepared.Sequence} ${(dt?"WITH":"WITHOUT")} Dest. Tag:
<a href="https://testnet.xrpl.org/transactions/${signed.id}" <a href="https://testnet.xrpl.org/transactions/${tx_hash}"
target="_blank">${prelim_result.engine_result}</a></p>`) target="_blank">${prelim.result.engine_result}</a></p>`)
} catch(err) { } catch(err) {
block.find(".loader").hide() block.find(".loader").hide()
show_error(block, `An error occurred when sending the test payment: ${err}`) show_error(block, `An error occurred when sending the test payment: ${err}`)
} }
// SCRAPPED ALT CODE: using the Faucet as a test sender.
// // We can use the Faucet to send a payment to our existing address with a
// // destination tag, but only if we roll it into an X-address.
// const faucet_url = $("#generate-creds-button").data("fauceturl")
// const XCodec = require('xrpl-tagged-address-codec')
// const dt = $(event.target).data("dt")
// let dest_x_address
// if (dt) {
// dest_x_address = XCodec.Encode({ account: address, tag: dt, test: true })
// } else {
// dest_x_address = XCodec.Encode({ account: address, test: true })
// }
// call_faucet(faucet_url, dest_x_address)
//
// // TODO: monitor our target address and report when we receive the tx from
// // the faucet. (including ✅ or ❌ as appropriate)
}) })
}) })

View File

@@ -13,23 +13,23 @@ $("#prepare-button").click( async function(event) {
const sender = get_address(event) const sender = get_address(event)
if (!sender) {return} if (!sender) {return}
const prepared = await api.prepareTransaction({ const vli = await api.getLedgerIndex()
const prepared = await api.autofill({
"TransactionType": "Payment", "TransactionType": "Payment",
"Account": sender, "Account": sender,
"Amount": api.xrpToDrops(send_amount), // Same as "Amount": "22000000" "Amount": xrpl.xrpToDrops(send_amount), // Same as "Amount": "22000000"
"Destination": "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe" "Destination": "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe",
}, { "LastLedgerSequence": vli+75 // gives ~5min, rather than the default ~1min
// Expire this transaction if it doesn't execute within ~5 minutes:
"maxLedgerVersionOffset": 75
}) })
block.find(".output-area").append( block.find(".output-area").append(
`<div><strong>Prepared transaction instructions:</strong> `<div><strong>Prepared transaction instructions:</strong>
<pre><code id='prepared-tx-json'>${pretty_print(prepared.txJSON)}</code></pre> <pre><code id='prepared-tx-json'>${pretty_print(prepared)}</code></pre>
</div> </div>
<div><strong>Transaction cost:</strong> ${prepared.instructions.fee} XRP</div> <div><strong>Transaction cost:</strong> ${xrpl.dropsToXrp(prepared.Fee)} XRP</div>
<div><strong>Transaction expires after ledger:</strong> <div><strong>Transaction expires after ledger:</strong>
${prepared.instructions.maxLedgerVersion}</div>`) ${prepared.LastLedgerSequence}</div>`)
complete_step("Prepare") complete_step("Prepare")
}) })
@@ -40,18 +40,19 @@ $("#sign-button").click( function(event) {
const block = $(event.target).closest(".interactive-block") const block = $(event.target).closest(".interactive-block")
block.find(".output-area").html("") block.find(".output-area").html("")
const preparedTxJSON = $("#prepared-tx-json").text() const preparedTxJSON = JSON.parse($("#prepared-tx-json").text())
const secret = get_secret(event) const wallet = get_wallet(event)
if (!secret) {return} if (!wallet) {return}
signResponse = api.sign(preparedTxJSON, secret) signed = wallet.signTransaction(preparedTxJSON)
hash = xrpl.computeSignedTransactionHash(signed) // TODO: update if computeSignedTransactionHash changes
block.find(".output-area").html( block.find(".output-area").html(
`<div><strong>Signed Transaction blob:</strong> `<div><strong>Signed Transaction blob:</strong>
<code id='signed-tx-blob' style='overflow-wrap: anywhere; word-wrap: anywhere' <code id='signed-tx-blob' style='overflow-wrap: anywhere; word-wrap: anywhere'
>${signResponse.signedTransaction}</code></div> >${signed}</code></div>
<div><strong>Identifying hash:</strong> <span id='signed-tx-hash' <div><strong>Identifying hash:</strong> <span id='signed-tx-hash'
>${signResponse.id}</span></div>` >${hash}</span></div>`
) )
complete_step("Sign") complete_step("Sign")
@@ -77,16 +78,19 @@ $("#get-tx-button").click( async function(event) {
$("#interactive-wait .lastledgersequence").text(), 10) $("#interactive-wait .lastledgersequence").text(), 10)
try { try {
const tx = await api.getTransaction(txID, { const tx = await api.request({
minLedgerVersion: earliestLedgerVersion, command: "tx",
maxLedgerVersion: lastLedgerSequence transaction: txID,
min_ledger: earliestLedgerVersion,
max_ledger: lastLedgerSequence
}) })
block.find(".output-area").html( block.find(".output-area").html(
"<div><strong>Transaction result:</strong> " + "<div><strong>Transaction result:</strong> " +
tx.outcome.result + "</div>" + tx.result + "</div>" +
"<div><strong>Balance changes:</strong> <pre><code>" + // TODO: restore some "balance changes" functionality based on what xrpl.js 2.0 offers.
pretty_print(tx.outcome.balanceChanges) + //"<div><strong>Balance changes:</strong> <pre><code>" +
//pretty_print(tx.outcome.balanceChanges) +
"</pre></code></div>" "</pre></code></div>"
) )

View File

@@ -1,5 +1,3 @@
const xrpl = ripple; // TODO: remove when webpack build is updated
const set_up_tx_sender = async function() { const set_up_tx_sender = async function() {
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Notification helpers // Notification helpers
@@ -76,6 +74,7 @@ const set_up_tx_sender = async function() {
try { try {
sending_wallet = await api.generateFaucetWallet() sending_wallet = await api.generateFaucetWallet()
} catch(error) { } catch(error) {
console.error(error)
errorNotif("There was an error with the XRP Ledger Testnet Faucet. Reload this page to try again.") errorNotif("There was an error with the XRP Ledger Testnet Faucet. Reload this page to try again.")
return return
} }
@@ -135,14 +134,14 @@ const set_up_tx_sender = async function() {
// Determine first and last ledger the tx could be validated in *BEFORE* // Determine first and last ledger the tx could be validated in *BEFORE*
// signing it. // signing it.
min_ledger = (await api.request({"command": "ledger", "ledger_index": "validated"})).result.ledger.ledger_index, // TODO: change to a simpler way when xrpl.js supports it min_ledger = await api.getLedgerIndex()
max_ledger = prepared.LastLedgerSequence max_ledger = prepared.LastLedgerSequence
let signed let signed
try { try {
// Sign, submit // Sign, submit
signed = use_wallet.sign(prepared) signed = use_wallet.signTransaction(prepared)
await api.request({"command": "submit", "tx_blob": signed}) await api.request({"command": "submit", "tx_blob": signed})
} catch (error) { } catch (error) {
console.log(error) console.log(error)

File diff suppressed because one or more lines are too long

View File

@@ -69,7 +69,7 @@ In ripple-lib 1.x all methods and properties were on instances of the `RippleAPI
| `isConnected()` | `Client.isConnected()` | | `isConnected()` | `Client.isConnected()` |
| `getServerInfo()` | `Client.request({command: "server_info"})` | Request/response match the [server_info method][] exactly. | | `getServerInfo()` | `Client.request({command: "server_info"})` | Request/response match the [server_info method][] exactly. |
| `getFee()` | `Client.getFee()` ***TODO: confirm*** | | `getFee()` | `Client.getFee()` ***TODO: confirm*** |
| `getLedgerVersion()` | `(await api.request({"command": "ledger", "ledger_index": "validated"})).result.ledger.ledger_index` | ***TODO: follow up if an easier way gets re-added*** | `getLedgerVersion()` | `Client.getLedgerIndex()` | |
| `getTransaction(hash)` | `Client.request({command: "tx", transaction: hash})` | Request/response match the [tx method][] exactly. | | `getTransaction(hash)` | `Client.request({command: "tx", transaction: hash})` | Request/response match the [tx method][] exactly. |
| `getTransactions(address, options)` | `Client.request({command: "account_tx", ..})` | Request/response match the [account_tx method][] exactly. | | `getTransactions(address, options)` | `Client.request({command: "account_tx", ..})` | Request/response match the [account_tx method][] exactly. |
| `getTrustlines(address, options)` | `Client.request({command: "account_lines", ..})` | Request/response match the [account_lines method][] exactly. | | `getTrustlines(address, options)` | `Client.request({command: "account_lines", ..})` | Request/response match the [account_lines method][] exactly. |
@@ -77,6 +77,8 @@ In ripple-lib 1.x all methods and properties were on instances of the `RippleAPI
| `isValidAddress(address)` | ***TBD maybe in utils?*** | Separate from isValidXAddress / isValidClassicAddress | | `isValidAddress(address)` | ***TBD maybe in utils?*** | Separate from isValidXAddress / isValidClassicAddress |
| `iso8601ToRippleTime(timestamp)` | `ISOTimeToRippleTime(timestamp)` | Now a static method at the `xrpl` module level. | | `iso8601ToRippleTime(timestamp)` | `ISOTimeToRippleTime(timestamp)` | Now a static method at the `xrpl` module level. |
Instead of `maxLedgerVersionOffset` when preparing a transaction, use `getLedgerIndex()`, add the offset to it, and provide that as `LastLedgerSequence`. ***TODO details***
<!--{# common link defs #}--> <!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %} {% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %} {% include '_snippets/tx-type-links.md' %}