Send and Cash Checks
This example shows how to:
- Send a check to transfer XRP or issued currency to another account.
- Get a list of checks you have sent or received.
- Cash a check received from another account.
- Cancel a check you have sent.
Checks offer another option for transferring funds between accounts. Checks have two particular advantages.
- You can use a check to send funds to another account without first creating a trust line - the trust line is created automatically when the receiver chooses to accept the funds.
- The receiver can choose to accept less than the full amount of the check. This allows you to authorize a maximum amount when the actual cost is not finalized.
Prerequisites
Clone or download the Modular Tutorial Samples{.github-code-download}.
Note: Without the Quickstart Samples, you will not be able to try the examples that follow.
Usage
To get test accounts:
- Open and launch
10check.html
. - Click Get Standby Account.
- Click Get Operational Account.
You can transfer XRP between your new accounts. Each account has its own fields and buttons.
Send a Check for XRP
To send a check for XRP from the Standby account to the Operational account:
- On the Standby (left) side of the form, enter the Amount of XRP to send, in drops.
- Copy and paste the Operational Account field to the Standby Destination field.
- Set the Currency to XRP.
- Click Send Check.
Send a Check for an Issued Currency
To send a check for an issued currency token from the Standby account to the Operational account:
- On the Standby side of the form, enter the Amount of currency to send.
- Copy and paste the Operational Account field to the Standby Destination field.
- Copy the Standby Account field and paste the value in the Issuer field.
- Enter the Currency code for your token.
- Click Send Check.
Get Checks
Click Get Checks to get a list of the current checks you have sent or received. To uniquely identify a check (for existence, when cashing a check), capture the index value for the check.
Cash Check
To cash a check you have received:
- Enter the Check ID (index value).
- Enter the Amount you want to collect, up to the full amount of the check.
- Enter the currency code. a. If you cashing a check for XRP, enter XRP in the Currency field. b. If you are cashing a check for an issued currency token:
- Enter the Issuer of the token.
- Enter the Currency code for the token.
- Click Cash Check.
Get Balances
Click Get Balances to get a list of obligations and assets for each account.
Cancel Check
To cancel a check you have previously sent to another account.
- Enter the Check ID (index value).
- Click Cancel Check.
Code Walkthrough
You can download the Quickstart Samples{.github-code-download} in the source repository for this website.
ripplex10-check.js
sendCheck()
Connect to the XRP ledger.
async function sendCheck() { let net = getNet() const client = new xrpl.Client(net) results = 'Connecting to ' + getNet() + '....' standbyResultField.value = results await client.connect() results += '\nConnected.' standbyResultField.value = results
Instantiate the account wallets.
const standby_wallet = xrpl.Wallet.fromSeed(standbySeedField.value) const operational_wallet = xrpl.Wallet.fromSeed(operationalSeedField.value)
Create the check_amount
variable, based on the standby amount field.
var check_amount = standbyAmountField.value
If the currency is anything but XRP, it's an issued currency. Update the check_amount
variable to include the currency
and issuer
fields.
if (standbyCurrencyField.value != "XRP") { check_amount = { "currency": standbyCurrencyField.value, "value": standbyAmountField.value, "issuer": standby_wallet.address } }
Define the CheckCreate
transaction.
const send_check_tx = { "TransactionType": "CheckCreate", "Account": standby_wallet.address, "SendMax": check_amount, "Destination": standbyDestinationField.value }
Prepare and sign the transaction.
const check_prepared = await client.autofill(send_check_tx) const check_signed = standby_wallet.sign(check_prepared) results += 'Sending ' + check_amount + ' ' + standbyCurrencyField + ' to ' + standbyDestinationField.value + '...' standbyResultField.value = results
Submit the transaction to the XRP Ledger and wait for the response.
const check_result = await client.submitAndWait(check_signed.tx_blob)
Report the results
if (check_result.result.meta.TransactionResult == "tesSUCCESS") { results += 'Transaction succeeded: https://testnet.xrpl.org/transactions/${check_signed.hash}' standbyResultField.value = JSON.stringify(check_result.result, null, 2) } else { results += 'Transaction failed: See JavaScript console for details.' standbyResultField.value = results throw 'Error sending transaction: ${check_result.result.meta.TransactionResult}' }
Update the XRP balance fields.
standbyBalanceField.value = (await client.getXrpBalance(standby_wallet.address)) operationalBalanceField.value = (await client.getXrpBalance(operational_wallet.address))
Disconnect from the XRP Ledger.
client.disconnect() } // end of sendCheck()
getChecks()
async function getChecks() {
Connect to the XRP Ledger.
let net = getNet() const client = new xrpl.Client(net) results = 'Connecting to ' + getNet() + '....' standbyResultField.value = results await client.connect() results += '\nConnected.' standbyResultField.value = results results= "\nGetting standby account checks...\n"
Define and send the account_objects
request, specifying check
objects.
const check_objects = await client.request({ "id": 5, "command": "account_objects", "account": standbyAccountField.value, "ledger_index": "validated", "type": "check" })
Report the results.
standbyResultField.value = JSON.stringify(check_objects.result, null, 2)
Disconnect from the XRP Ledger.
client.disconnect() } // End of getChecks()
cashCheck()
Connect to the XRP Ledger and instantiate the account wallets.
async function cashCheck() { let net = getNet() const client = new xrpl.Client(net) results = 'Connecting to ' + getNet() + '....' standbyResultField.value = results await client.connect() results += '\nConnected.' standbyResultField.value = results const standby_wallet = xrpl.Wallet.fromSeed(standbySeedField.value) const operational_wallet = xrpl.Wallet.fromSeed(operationalSeedField.value)
Set the check_amount
variable to the value in the Amount field.
var check_amount = standbyAmountField.value
If the Currency is anything other than XRP
, the check is for an issued currency. Redefine the variable to include the currency
and issuer
for the token.
if (standbyCurrencyField.value != "XRP") { check_amount = { "value": standbyAmountField.value, "currency": standbyCurrencyField.value, "issuer": standbyIssuerField.value } }
Define the CheckCash
transaction.
const cash_check_tx = { "TransactionType": "CheckCash", "Account": standby_wallet.address, "Amount": check_amount, "CheckID": standbyCheckID.value }
Prepare and sign the transaction.
const cash_prepared = await client.autofill(cash_check_tx) const cash_signed = standby_wallet.sign(cash_prepared) results += ' Receiving ' + standbyAmountField.value + ' ' + standbyCurrencyField.value + '.\n' standbyResultField.value = results
Submit the transaction and wait for the results.
const check_result = await client.submitAndWait(cash_signed.tx_blob)
Report the results.
if (check_result.result.meta.TransactionResult == "tesSUCCESS") { results += 'Transaction succeeded: https://testnet.xrpl.org/transactions/${cash_signed.hash}' standbyResultField.value = results } else { results += 'Transaction failed: See JavaScript console for details.' standbyResultField.value = results throw 'Error sending transaction: ${check_result.result.meta.TransactionResult}' }
Update the XRP balance fields.
standbyBalanceField.value = (await client.getXrpBalance(standby_wallet.address)) operationalBalanceField.value = (await client.getXrpBalance(operational_wallet.address))
Disconnect from the XRP Ledger.
client.disconnect() } // end of cashCheck()
cancelCheck
Connect to the XRP Ledger and instantiate the account wallets.
async function cancelCheck() { let net = getNet() const client = new xrpl.Client(net) results = 'Connecting to ' + getNet() + '....' standbyResultField.value = results await client.connect() results += '\nConnected.' standbyResultField.value = results const standby_wallet = xrpl.Wallet.fromSeed(standbySeedField.value) const operational_wallet = xrpl.Wallet.fromSeed(operationalSeedField.value)
Define the CheckCancel
transaction.
const cancel_check_tx = { "TransactionType": "CheckCancel", "Account": standby_wallet.address, "CheckID": standbyCheckID.value }
Prepare and sign the transaction object.
const cancel_prepared = await client.autofill(cancel_check_tx) const cancel_signed = standby_wallet.sign(cancel_prepared) results += ' Cancelling check.\n' standbyResultField.value = results
Submit the transaction and wait for the results.
const check_result = await client.submitAndWait(cancel_signed.tx_blob)
Report the results.
if (check_result.result.meta.TransactionResult == "tesSUCCESS") { results += 'Transaction succeeded: https://testnet.xrpl.org/transactions/${cash_signed.hash}' standbyResultField.value = results } else { results += 'Transaction failed: See JavaScript console for details.' standbyResultField.value = results throw 'Error sending transaction: ${check_result.result.meta.TransactionResult}' }
Update the XRP balance fields.
standbyBalanceField.value = (await client.getXrpBalance(standby_wallet.address)) operationalBalanceField.value = (await client.getXrpBalance(operational_wallet.address))
Disconnect from the XRP Ledger.
client.disconnect() } // end of cancelCheck()
Reciprocal functions for the Operational account.
// ******************************************************* // ************ Operational Send Check ******************* // ******************************************************* async function opSendCheck() { let net = getNet() const client = new xrpl.Client(net) results = 'Connecting to ' + getNet() + '....' operationalResultField.value = results await client.connect() results += '\nConnected.' operationalResultField.value = results const standby_wallet = xrpl.Wallet.fromSeed(standbySeedField.value) const operational_wallet = xrpl.Wallet.fromSeed(operationalSeedField.value) const issue_quantity = operationalAmountField.value var check_amount = operationalAmountField.value if (operationalCurrencyField.value != "XRP") { check_amount = { "currency": operationalCurrencyField.value, "value": operationalAmountField.value, "issuer": operational_wallet.address } } const send_check_tx = { "TransactionType": "CheckCreate", "Account": operational_wallet.address, "SendMax": check_amount, "Destination": operationalDestinationField.value } const check_prepared = await client.autofill(send_check_tx) const check_signed = operational_wallet.sign(check_prepared) results += '\nSending check to ' + operationalDestinationField.value + '...' operationalResultField.value = results const check_result = await client.submitAndWait(check_signed.tx_blob) if (check_result.result.meta.TransactionResult == "tesSUCCESS") { results += 'Transaction succeeded: https://testnet.xrpl.org/transactions/${check_signed.hash}' operationalResultField.value = JSON.stringify(check_result.result, null, 2) } else { results += 'Transaction failed: See JavaScript console for details.' operationalResultField.value = results throw 'Error sending transaction: ${check_result.result.meta.TransactionResult}' } standbyBalanceField.value = (await client.getXrpBalance(standby_wallet.address)) operationalBalanceField.value = (await client.getXrpBalance(operational_wallet.address)) client.disconnect() } // end of opSendCheck() // ******************************************************* // ************ Operational Get Checks ******************* // ******************************************************* async function opGetChecks() { let net = getNet() const client = new xrpl.Client(net) results = 'Connecting to ' + getNet() + '....' operationalResultField.value = results await client.connect() results += '\nConnected.' operationalResultField.value = results results= "\nGetting standby account checks...\n" const check_objects = await client.request({ "id": 5, "command": "account_objects", "account": operationalAccountField.value, "ledger_index": "validated", "type": "check" }) operationalResultField.value = JSON.stringify(check_objects.result, null, 2) client.disconnect() } // End of opGetChecks() // ******************************************************* // ************* Operational Cash Check ****************** // ******************************************************* async function opCashCheck() { let net = getNet() const client = new xrpl.Client(net) results = 'Connecting to ' + getNet() + '....' operationalResultField.value = results await client.connect() results += '\nConnected.' operationalResultField.value = results const standby_wallet = xrpl.Wallet.fromSeed(standbySeedField.value) const operational_wallet = xrpl.Wallet.fromSeed(operationalSeedField.value) var check_amount = operationalAmountField.value if (operationalCurrencyField.value != "XRP") { check_amount = { "value": operationalAmountField.value, "currency": operationalCurrencyField.value, "issuer": operationalIssuerField.value } } const cash_check_tx = { "TransactionType": "CheckCash", "Account": operational_wallet.address, "Amount": check_amount, "CheckID": operationalCheckIDField.value } const cash_prepared = await client.autofill(cash_check_tx) const cash_signed = operational_wallet.sign(cash_prepared) results += ' Receiving ' + operationalAmountField.value + ' ' + operationalCurrencyField.value + '.\n' operationalResultField.value = results const check_result = await client.submitAndWait(cash_signed.tx_blob) if (check_result.result.meta.TransactionResult == "tesSUCCESS") { results += 'Transaction succeeded: https://testnet.xrpl.org/transactions/${cash_signed.hash}' operationalResultField.value = results } else { results += 'Transaction failed: See JavaScript console for details.' operationalResultField.value = results throw 'Error sending transaction: ${check_result.result.meta.TransactionResult}' } standbyBalanceField.value = (await client.getXrpBalance(standby_wallet.address)) operationalBalanceField.value = (await client.getXrpBalance(operational_wallet.address)) client.disconnect() } // end of opCashCheck() // ******************************************************* // ************* Operational Cancel Check **************** // ******************************************************* async function opCancelCheck() { let net = getNet() const client = new xrpl.Client(net) results = 'Connecting to ' + getNet() + '....' operationalResultField.value = results await client.connect() results += '\nConnected.' operationalResultField.value = results const standby_wallet = xrpl.Wallet.fromSeed(standbySeedField.value) const operational_wallet = xrpl.Wallet.fromSeed(operationalSeedField.value) const cancel_check_tx = { "TransactionType": "CheckCancel", "Account": operational_wallet.address, "CheckID": operationalCheckIDField.value } const cancel_prepared = await client.autofill(cancel_check_tx) const cancel_signed = operational_wallet.sign(cancel_prepared) results += ' Cancelling check.\n' operationalResultField.value = results const check_result = await client.submitAndWait(cancel_signed.tx_blob) if (check_result.result.meta.TransactionResult == "tesSUCCESS") { results += 'Transaction succeeded: https://testnet.xrpl.org/transactions/${cash_signed.hash}' operationalResultField.value = results } else { results += 'Transaction failed: See JavaScript console for details.' operationalResultField.value = results throw 'Error sending transaction: ${check_result.result.meta.TransactionResult}' } standbyBalanceField.value = (await client.getXrpBalance(standby_wallet.address)) operationalBalanceField.value = (await client.getXrpBalance(operational_wallet.address)) client.disconnect() } // end of cancelCheck()
10.check.html
<html> <head> <title>Token Test Harness</title> <link href='https://fonts.googleapis.com/css?family=Work Sans' rel='stylesheet'> <style> body{font-family: "Work Sans", sans-serif;padding: 20px;background: #fafafa;} h1{font-weight: bold;} input, button {padding: 6px;margin-bottom: 8px;} button{font-weight: bold;font-family: "Work Sans", sans-serif;} td{vertical-align: middle;} </style> <script src='https://unpkg.com/[email protected]/build/xrpl-latest-min.js'></script> <script src='ripplex1-send-xrp.js'></script> <script src='ripplex2-send-currency.js'></script> <script src='ripplex10-check.js'></script> </head> <!-- ************************************************************** --> <!-- ********************** The Form ****************************** --> <!-- ************************************************************** --> <body> <h1>Token Test Harness</h1> <form id="theForm"> Choose your ledger instance: <input type="radio" id="tn" name="server" value="wss://s.altnet.rippletest.net:51233" checked> <label for="testnet">Testnet</label> <input type="radio" id="dn" name="server" value="wss://s.devnet.rippletest.net:51233"> <label for="devnet">Devnet</label> <br/><br/> <button type="button" onClick="getAccountsFromSeeds()">Get Accounts From Seeds</button> <br/> <textarea id="seeds" cols="40" rows= "2"></textarea> <br/><br/> <table> <tr valign="top"> <td> <table> <tr valign="top"> <td> <td> <button type="button" onClick="getAccount('standby')">Get New Standby Account</button> <table> <tr valign="top"> <td align="right"> Standby Account </td> <td> <input type="text" id="standbyAccountField" size="40"></input> <br> </td> </tr> <tr> <td align="right"> Public Key </td> <td> <input type="text" id="standbyPubKeyField" size="40"></input> <br> </td> </tr> <tr> <td align="right"> Private Key </td> <td> <input type="text" id="standbyPrivKeyField" size="40"></input> <br> </td> </tr> <tr> <td align="right"> Seed </td> <td> <input type="text" id="standbySeedField" size="40"></input> <br> </td> </tr> <tr> <td align="right"> XRP Balance </td> <td> <input type="text" id="standbyBalanceField" size="40"></input> <br> </td> </tr> <tr> <td align="right"> Amount </td> <td> <input type="text" id="standbyAmountField" size="40"></input> <br> </td> </tr> <tr> <td align="right"> Destination </td> <td> <input type="text" id="standbyDestinationField" size="40"></input> <br> </td> </tr> <tr> <td align="right"> Issuer </td> <td> <input type="text" id="standbyIssuerField" size="40"></input> <br> </td> </tr> <tr> <td align="right"> Check ID </td> <td> <input type="text" id="standbyCheckID" size="40"></input> <br> </td> </tr> <tr valign="top"> <td><button type="button" onClick="configureAccount('standby',document.querySelector('#standbyDefault').checked)">Configure Account</button></td> <td> <input type="checkbox" id="standbyDefault" checked="true"/> <label for="standbyDefault">Allow Rippling</label> </td> </tr> <tr> <td align="right"> Currency </td> <td> <input type="text" id="standbyCurrencyField" size="40" value="USD"></input> </td> </tr> </table> <p align="left"> <textarea id="standbyResultField" cols="80" rows="20" ></textarea> </p> </td> </td> <td> <table> <tr valign="top"> <td align="center" valign="top"> <button type="button" onClick="sendXRP()">Send XRP></button> <br/><br/> <button type="button" onClick="sendCheck()">Send Check</button> <br/> <button type="button" onClick="getChecks()">Get Checks</button> <br/> <button type="button" onClick="cashCheck()">Cash Check</button> <br/> <button type="button" onClick="cancelCheck()">Cancel Check</button> <br/> <button type="button" onClick="getBalances()">Get Balances</button> </td> </tr> </td> </tr> </table> </td> </tr> </table> </td> <td> <table> <tr> <td> <td> <table> <tr> <td align="center" valign="top"> <button type="button" onClick="oPsendXRP()">< Send XRP</button> <br/><br/> <button type="button" onClick="opSendCheck()">Send Check</button> <br/> <button type="button" onClick="opGetChecks()">Get Checks</button> <br/> <button type="button" onClick="opCashCheck()">Cash Check</button> <br/> <button type="button" onClick="opCancelCheck()">Cancel Check</button> <br/> <button type="button" onClick="getBalances()">Get Balances</button> </td> <td valign="top" align="right"> <button type="button" onClick="getAccount('operational')">Get New Operational Account</button> <table> <tr valign="top"> <td align="right"> Operational Account </td> <td> <input type="text" id="operationalAccountField" size="40"></input> <br> </td> </tr> <tr> <td align="right"> Public Key </td> <td> <input type="text" id="operationalPubKeyField" size="40"></input> <br> </td> </tr> <tr> <td align="right"> Private Key </td> <td> <input type="text" id="operationalPrivKeyField" size="40"></input> <br> </td> </tr> <tr> <td align="right"> Seed </td> <td> <input type="text" id="operationalSeedField" size="40"></input> <br> </td> </tr> <tr> <td align="right"> XRP Balance </td> <td> <input type="text" id="operationalBalanceField" size="40"></input> <br> </td> </tr> <tr> <td align="right"> Amount </td> <td> <input type="text" id="operationalAmountField" size="40"></input> <br> </td> </tr> <tr> <td align="right"> Destination </td> <td> <input type="text" id="operationalDestinationField" size="40"></input> <br> </td> </tr> <tr> <td align="right"> Issuer </td> <td> <input type="text" id="operationalIssuerField" size="40"></input> <br> </td> </tr> <tr> <td align="right"> Check ID </td> <td> <input type="text" id="operationalCheckIDField" size="40"></input> <br> </td> </tr> <tr> <td> </td> <td align="right"> <input type="checkbox" id="operationalDefault" checked="true"/> <label for="operationalDefault">Allow Rippling</label> <button type="button" onClick="configureAccount('operational',document.querySelector('#operationalDefault').checked)">Configure Account</button> </td> </tr> <tr> <td align="right"> Currency </td> <td> <input type="text" id="operationalCurrencyField" size="40" value="USD"></input> </td> </tr> </table> <p align="right"> <textarea id="operationalResultField" cols="80" rows="20" ></textarea> </p> </td> </td> </tr> </td> </tr> </table> </td> </tr> </table> </td> </tr> </table> </form> </body> </html>