import { Client, Payment } from '../../dist/npm' /** * 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 { 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( await client.getXrpBalance(wallet1.classicAddress), await client.getXrpBalance(wallet2.classicAddress), ) // 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, } 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( await client.getXrpBalance(wallet1.classicAddress), await client.getXrpBalance(wallet2.classicAddress), ) await client.disconnect() }