Cash a Check for an Exact Amount
Added by the Checks amendment.
As long as the Check is in the ledger and not expired, the specified recipient can cash it to receive any exact amount up to the amount specified in the Check by sending a CheckCash transaction with an Amount
field. You would cash a Check this way if you want to receive a specific amount, for example to pay off an invoice or bill exactly.
The specified recipient can also cash the check for a flexible amount.
Prerequisites
The prerequisites for cashing a check are the same whether you are cashing it for an exact amount or a flexible amount.
- You need the ID of a Check object currently in the ledger.
- For example, the ID of one Check in these examples is
838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334
, although you must use a different ID to go through these steps yourself.
- For example, the ID of one Check in these examples is
- The address and secret key of the Check's stated recipient. The address must match the
Destination
address in the Check object. - If the Check is for a token, you (the recipient) must have a trust line to the issuer. Your limit on that trust line must be high enough to hold your previous balance plus the amount you would receive.
- A secure way to sign transactions.
- A client library that can connect to the XRP Ledger, or any HTTP or WebSocket client.
1. Prepare the CheckCash transaction
Figure out the values of the CheckCash transaction fields. To cash a check for an exact amount, the following fields are the bare minimum; everything else is either optional or can be auto-filled when signing:
Field | Value | Description |
---|---|---|
TransactionType |
String | The value CheckCash indicates this is a CheckCash transaction. |
Account |
String (Address) | The address of the sender who is cashing the Check. (In other words, your address.) |
CheckID |
String | The ID of the Check object in the ledger to cash. You can get this information by looking up the metadata of the CheckCreate transaction using the tx method or by looking for Checks using the account_objects method. |
Amount |
String or Object (Amount) | The amount to redeem from the Check. For XRP, this must be a string specifying drops of XRP. For tokens, this is an object with currency , issuer , and value fields. The currency and issuer fields must match the corresponding fields in the Check object, and the value must be less than or equal to the amount in the Check object. (For currencies with transfer fees, you must cash the Check for less than its SendMax so the transfer fee can be paid by the SendMax .) If you cannot receive this much, cashing the Check fails, leaving the Check in the ledger so you can try again. For more information on specifying currency amounts, see Specifying Currency Amounts. |
Example CheckCash Preparation for an exact amount
The following examples show how to prepare a transaction to cash a Check for a fixed amount.
{
"Account": "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
"TransactionType": "CheckCash",
"Amount": "100000000",
"CheckID": "838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334",
"Fee": "12"
}
'use strict'
const RippleAPI = require('ripple-lib').RippleAPI
// This example connects to a public Test Net server
const api = new RippleAPI({server: 'wss://s.altnet.rippletest.net:51233'})
api.connect().then(() => {
console.log('Connected')
const sender = 'rGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis'
const options = {
// Allow up to 60 ledger versions (~5 min) instead of the default 3 versions
// before this transaction fails permanently.
"maxLedgerVersionOffset": 60
}
return api.prepareCheckCash(sender, {
"checkID": "84C61BE9B39B2C4A2267F67504404F1EC76678806C1B901EA781D1E3B4CE0CD9",
"amount": {
"currency": "XRP",
"value": "95" // Cash for exactly 95 XRP
}
}, options)
}).then(prepared => {
console.log("txJSON:", prepared.txJSON);
// Disconnect and return
}).then(() => {
api.disconnect().then(() => {
console.log('Disconnected')
process.exit()
})
}).catch(console.error)
// Example output:
//
// Connected
// txJSON: {"Account":"rGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis",
// "TransactionType":"CheckCash",
// "CheckID":"84C61BE9B39B2C4A2267F67504404F1EC76678806C1B901EA781D1E3B4CE0CD9",
// "Amount":"95000000",
// "Flags":2147483648,
// "LastLedgerSequence":8006841,
// "Fee":"12",
// "Sequence":5}
// Disconnected
2. Sign the CheckCash transaction
The most secure way to sign a transaction is to sign locally with a client library. Alternatively, if you run your own rippled
node you can sign the transaction using the sign method, but this must be done through a trusted and encrypted connection, or through a local (same-machine) connection.
In all cases, note the signed transaction's identifying hash for later.
Example Request
rippled sign s████████████████████████████ '{
"Account": "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
"TransactionType": "CheckCash",
"Amount": "100000000",
"CheckID": "838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334",
"Fee": "12"
}'
Example Response
Loading: "/etc/opt/ripple/rippled.cfg"
2018-Jan-24 01:17:54 HTTPClient:NFO Connecting to 127.0.0.1:5005
{
"result" : {
"status" : "success",
"tx_blob" : "120011228000000024000000015018838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334614000000005F5E10068400000000000000C732102F135B14C552968B0ABE8493CC4C5795A7484D73F6BFD01379F73456F725F66ED74473045022100C64278AC90B841CD3EA9889A4847CAB3AC9927057A34130810FAA7FAC0C6E3290220347260A4C0A6DC9B699DA12510795B2B3414E1FA222AF743226345FBAAEF937C811449FF0C73CA6AF9733DA805F76CA2C37776B7C46B",
"tx_json" : {
"Account" : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
"Amount" : "100000000",
"CheckID" : "838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334",
"Fee" : "12",
"Flags" : 2147483648,
"Sequence" : 1,
"SigningPubKey" : "02F135B14C552968B0ABE8493CC4C5795A7484D73F6BFD01379F73456F725F66ED",
"TransactionType" : "CheckCash",
"TxnSignature" : "3045022100C64278AC90B841CD3EA9889A4847CAB3AC9927057A34130810FAA7FAC0C6E3290220347260A4C0A6DC9B699DA12510795B2B3414E1FA222AF743226345FBAAEF937C",
"hash" : "0521707D510858BC8AF69D2227E1D1ADA7DB7C5B4B74115BCD0D91B62AFA8EDC"
}
}
}
3. Submit the signed CheckCash transaction
Take the signed transaction blob from the previous step and submit it to a rippled
server. You can do this safely even if you do not run the rippled
server. The response contains a provisional result, which should be tesSUCCESS
, but this result is usually not final. A provisional response of terQUEUED
is also OK, since queued transactions are generally included in the next open ledger version (usually about 10 seconds after submission).
Tip: If the preliminary result is tefMAX_LEDGER
, the transaction has failed permanently because its LastLedgerSequence
parameter is lower than the current ledger. This happens when you take longer than the expected number of ledger versions between preparing and submitting the transaction. If this occurs, start over from step 1 with a higher LastLedgerSequence
value.
Example Request
rippled submit 120011228000000024000000015018838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334614000000005F5E10068400000000000000C732102F135B14C552968B0ABE8493CC4C5795A7484D73F6BFD01379F73456F725F66ED74473045022100C64278AC90B841CD3EA9889A4847CAB3AC9927057A34130810FAA7FAC0C6E3290220347260A4C0A6DC9B699DA12510795B2B3414E1FA222AF743226345FBAAEF937C811449FF0C73CA6AF9733DA805F76CA2C37776B7C46B
Example Response
Loading: "/etc/opt/ripple/rippled.cfg"
2018-Jan-24 01:17:54 HTTPClient:NFO Connecting to 127.0.0.1:5005
{
"result" : {
"engine_result" : "tesSUCCESS",
"engine_result_code" : 0,
"engine_result_message" : "The transaction was applied. Only final in a validated ledger.",
"status" : "success",
"tx_blob" : "120011228000000024000000015018838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334614000000005F5E10068400000000000000C732102F135B14C552968B0ABE8493CC4C5795A7484D73F6BFD01379F73456F725F66ED74473045022100C64278AC90B841CD3EA9889A4847CAB3AC9927057A34130810FAA7FAC0C6E3290220347260A4C0A6DC9B699DA12510795B2B3414E1FA222AF743226345FBAAEF937C811449FF0C73CA6AF9733DA805F76CA2C37776B7C46B",
"tx_json" : {
"Account" : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
"Amount" : "100000000",
"CheckID" : "838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334",
"Fee" : "12",
"Flags" : 2147483648,
"Sequence" : 1,
"SigningPubKey" : "02F135B14C552968B0ABE8493CC4C5795A7484D73F6BFD01379F73456F725F66ED",
"TransactionType" : "CheckCash",
"TxnSignature" : "3045022100C64278AC90B841CD3EA9889A4847CAB3AC9927057A34130810FAA7FAC0C6E3290220347260A4C0A6DC9B699DA12510795B2B3414E1FA222AF743226345FBAAEF937C",
"hash" : "0521707D510858BC8AF69D2227E1D1ADA7DB7C5B4B74115BCD0D91B62AFA8EDC"
}
}
}
4. Wait for validation
On a live network (including Mainnet, Testnet, or Devnet), you can wait 4-7 seconds for the ledger to close automatically.
If you're running rippled
in stand-alone mode, use the ledger_accept method to manually close the ledger.
5. Confirm final result
Use the tx method with the CheckCash transaction's identifying hash to check its status. Look for a "TransactionResult": "tesSUCCESS"
field in the transaction's metadata, indicating that the transaction succeeded, and the field "validated": true
in the result, indicating that this result is final.
If the check was cashed for an exact Amount
and succeeded, you can assume that the recipient was credited for exactly that amount (with possible rounding for very large or very small amounts of tokens).
If cashing the Check failed, the Check remains in the ledger so you can try cashing again later. You may want to cash the Check for a flexible amount instead.
Example Request
rippled tx 0521707D510858BC8AF69D2227E1D1ADA7DB7C5B4B74115BCD0D91B62AFA8EDC
Example Response
Loading: "/etc/opt/ripple/rippled.cfg"
2018-Jan-24 01:18:39 HTTPClient:NFO Connecting to 127.0.0.1:5005
{
"result" : {
"Account" : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
"Amount" : "100000000",
"CheckID" : "838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334",
"Fee" : "12",
"Flags" : 2147483648,
"Sequence" : 1,
"SigningPubKey" : "02F135B14C552968B0ABE8493CC4C5795A7484D73F6BFD01379F73456F725F66ED",
"TransactionType" : "CheckCash",
"TxnSignature" : "3045022100C64278AC90B841CD3EA9889A4847CAB3AC9927057A34130810FAA7FAC0C6E3290220347260A4C0A6DC9B699DA12510795B2B3414E1FA222AF743226345FBAAEF937C",
"date" : 570071920,
"hash" : "0521707D510858BC8AF69D2227E1D1ADA7DB7C5B4B74115BCD0D91B62AFA8EDC",
"inLedger" : 9,
"ledger_index" : 9,
"meta" : {
"AffectedNodes" : [
{
"ModifiedNode" : {
"FinalFields" : {
"Flags" : 0,
"Owner" : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
"RootIndex" : "032D861D151E38E86F46805ED1896D1A50144F65459717B6D12470A9E6E3B66E"
},
"LedgerEntryType" : "DirectoryNode",
"LedgerIndex" : "032D861D151E38E86F46805ED1896D1A50144F65459717B6D12470A9E6E3B66E"
}
},
{
"ModifiedNode" : {
"FinalFields" : {
"Account" : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
"Balance" : "1000099999988",
"Flags" : 0,
"OwnerCount" : 0,
"Sequence" : 2
},
"LedgerEntryType" : "AccountRoot",
"LedgerIndex" : "38E1EF3284A45B090D549EFFB014ACF68927FE0884CDAF01CE3629DF90542D66",
"PreviousFields" : {
"Balance" : "1000000000000",
"Sequence" : 1
},
"PreviousTxnID" : "3E14D859F6B4BE923323EFC94571606455921E65173147A89BC6EDDA4374B294",
"PreviousTxnLgrSeq" : 5
}
},
{
"DeletedNode" : {
"FinalFields" : {
"Account" : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
"Destination" : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
"DestinationNode" : "0000000000000000",
"DestinationTag" : 1,
"Expiration" : 570113521,
"Flags" : 0,
"InvoiceID" : "6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B",
"OwnerNode" : "0000000000000000",
"PreviousTxnID" : "0FD9F719CDE29E6F6DF752B93EB9AC6FBB493BF989F2CB63B8C0E73A8DCDF61A",
"PreviousTxnLgrSeq" : 8,
"SendMax" : "100000000",
"Sequence" : 4
},
"LedgerEntryType" : "Check",
"LedgerIndex" : "838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334"
}
},
{
"ModifiedNode" : {
"FinalFields" : {
"Flags" : 0,
"Owner" : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
"RootIndex" : "AD136EC2A266027D8F202C97D294BBE32F6FC2AD5501D9853F785FE77AB94C94"
},
"LedgerEntryType" : "DirectoryNode",
"LedgerIndex" : "AD136EC2A266027D8F202C97D294BBE32F6FC2AD5501D9853F785FE77AB94C94"
}
},
{
"ModifiedNode" : {
"FinalFields" : {
"Account" : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
"Balance" : "4999899999952",
"Flags" : 0,
"OwnerCount" : 1,
"Sequence" : 5
},
"LedgerEntryType" : "AccountRoot",
"LedgerIndex" : "D3A1DBAA28717975A9119EC4CBC891BA9A66236C484F03C9911F463AD3B66DE0",
"PreviousFields" : {
"Balance" : "4999999999952",
"OwnerCount" : 2
},
"PreviousTxnID" : "0FD9F719CDE29E6F6DF752B93EB9AC6FBB493BF989F2CB63B8C0E73A8DCDF61A",
"PreviousTxnLgrSeq" : 8
}
}
],
"TransactionIndex" : 0,
"TransactionResult" : "tesSUCCESS"
},
"status" : "success",
"validated" : true
}
}