# Cancel an Expired Escrow An escrow in the XRP Ledger is expired when its `CancelAfter` time is lower than the `close_time` of the latest validated ledger. Escrows without a `CancelAfter` time never expire. ## 1. Get the latest validated ledger Use the [ledger method](/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger) to look up the latest validated ledger and get the `close_time` value. Request: Websocket { "id": 4, "command": "ledger", "ledger_index": "validated" } Response: Websocket { "id": 1, "status": "success", "type": "response", "result": { "ledger": { # ... (trimmed) ... "close_time": 560302643, "close_time_human": "2017-Oct-02 23:37:23", "close_time_resolution": 10, # ... (trimmed) ... }, "ledger_hash": "668F0647A6F3CC277496245DBBE9BD2E3B8E70E7AA824E97EF3237FE7E1EE3F2", "ledger_index": 2906341, "validated": true } } ## 2. Look up the escrow Use the [account_objects method](/docs/references/http-websocket-apis/public-api-methods/account-methods/account_objects) and compare `CancelAfter` to `close_time`: Request: Websocket { "id": 2, "command": "account_objects", "account": "r3wN3v2vTUkr5qd6daqDc2xE4LSysdVjkT", "ledger_index": "validated", "type": "escrow" } Response: Websocket { "id": 2, "status": "success", "type": "response", "result": { "account": "r3wN3v2vTUkr5qd6daqDc2xE4LSysdVjkT", "account_objects": [ { "Account": "r3wN3v2vTUkr5qd6daqDc2xE4LSysdVjkT", "Amount": "10000", "CancelAfter": 559913895, "Destination": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", "FinishAfter": 559892324, "Flags": 0, "LedgerEntryType": "Escrow", "OwnerNode": "0000000000000000", "PreviousTxnID": "4756C22BBB7FC23D9081FDB180806939D6FEBC967BE0EC2DB95B166AF9C086E9", "PreviousTxnLgrSeq": 2764813, "index": "7243A9750FA4BE3E63F75F6DACFD79AD6B6C76947F6BDC46CD0F52DBEEF64C89" } ], "ledger_hash": "82F24FFA72AED16F467BBE79D387E92FDA39F29038B26E79464CDEDFB506E366", "ledger_index": 2764826, "validated": true } } ## 3. Submit EscrowCancel transaction ***Anyone*** can cancel an expired escrow in the XRP Ledger by sending an [EscrowCancel transaction](/docs/references/protocol/transactions/types/escrowcancel). Set the `Owner` field of the transaction to the `Account` of the `EscrowCreate` transaction that created this escrow. Set the `OfferSequence` field to the `Sequence` of the `EscrowCreate` transaction. If you don't know what `OfferSequence` to use, you can look up the transaction that created the Escrow: call the [tx method](/docs/references/http-websocket-apis/public-api-methods/transaction-methods/tx) with the value of the Escrow's `PreviousTxnID` field. In `tx` response, use the `Sequence` value of that transaction as the `OfferSequence` value of the EscrowCancel transaction. Caution Never submit a secret key to a server you do not control. Do not send a secret key unencrypted over the network. Websocket Request: { "id": 5, "command": "submit", "secret": "s████████████████████████████", "tx_json": { "Account": "rhgdnc82FwHFUKXp9ZcpgwXWRAxKf5Buqp", "TransactionType": "EscrowCancel", "Owner": "r3wN3v2vTUkr5qd6daqDc2xE4LSysdVjkT", "OfferSequence": 1 } } Response: { "id": 5, "status": "success", "type": "response", "result": { "engine_result": "tesSUCCESS", "engine_result_code": 0, "engine_result_message": "The transaction was applied. Only final in a validated ledger.", "tx_blob": "1200042280000000240000000320190000000168400000000000000A7321027FB1CF34395F18901CD294F77752EEE25277C6E87A224FC7388AA7EF872DB43D74473045022100AC45749FC4291F7811B2D8AC01CA04FEE38910CB7216FB0C5C0AEBC9C0A95F4302203F213C71C00136A0ADC670EFE350874BCB2E559AC02059CEEDFB846685948F2B81142866B7B47574C8A70D5E71FFB95FFDB18951427B82144E87970CD3EA984CF48B1AA6AB6C77DC4AB059FC", "tx_json": { "Account": "rhgdnc82FwHFUKXp9ZcpgwXWRAxKf5Buqp", "Fee": "10", "Flags": 2147483648, "OfferSequence": 1, "Owner": "r3wN3v2vTUkr5qd6daqDc2xE4LSysdVjkT", "Sequence": 3, "SigningPubKey": "027FB1CF34395F18901CD294F77752EEE25277C6E87A224FC7388AA7EF872DB43D", "TransactionType": "EscrowCancel", "TxnSignature": "3045022100AC45749FC4291F7811B2D8AC01CA04FEE38910CB7216FB0C5C0AEBC9C0A95F4302203F213C71C00136A0ADC670EFE350874BCB2E559AC02059CEEDFB846685948F2B", "hash": "65F36C5514153D94F0ADE5CE747061A5E70B73B56B4C66DA5040D99CAF252831" } } } Javascript const escrowCancelTransaction = { "Account": wallet.address, "TransactionType": "EscrowCancel", "Owner": wallet.address, "OfferSequence": sequenceNumber, // Sequence number }; xrpl.validate(escrowCancelTransaction); // Sign and submit the transaction -------------------------------------------- console.log('Signing and submitting the transaction: ', JSON.stringify(escrowCancelTransaction, null, "\t")); const response = await client.submitAndWait(escrowCancelTransaction, { wallet }); console.log(`Finished submitting! \n${JSON.stringify(response.result, null, "\t")}`); Python # Build escrow cancel transaction cancel_txn = EscrowCancel( account=sender_wallet.address, owner=sender_wallet.address, offer_sequence=escrow_sequence ) # Autofill, sign, then submit transaction and wait for result stxn_response = submit_and_wait(cancel_txn, client, sender_wallet) # Parse response and return result stxn_result = stxn_response.result # Parse result and print out the transaction result and transaction hash print(stxn_result["meta"]["TransactionResult"]) print(stxn_result["hash"]) Take note of the transaction's identifying `hash` value so you can check its final status when it is included in a validated ledger version. ## 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](/docs/references/http-websocket-apis/admin-api-methods/server-control-methods/ledger_accept) to manually close the ledger. ## 5. Confirm final result Use the [tx method](/docs/references/http-websocket-apis/public-api-methods/transaction-methods/tx) with the `EscrowCancel` transaction's identifying hash to check its final status. Look in the transaction metadata for a `DeletedNode` with `LedgerEntryType` of `Escrow`. Also look for a `ModifiedNode` of type `AccountRoot` for the sender of the escrowed payment. The `FinalFields` of the object should show the increase in XRP in the `Balance` field for the returned XRP. Request: Websocket { "id": 6, "command": "tx", "transaction": "65F36C5514153D94F0ADE5CE747061A5E70B73B56B4C66DA5040D99CAF252831" } Response: Websocket { "id": 6, "status": "success", "type": "response", "result": { "Account": "rhgdnc82FwHFUKXp9ZcpgwXWRAxKf5Buqp", "Fee": "10", "Flags": 2147483648, "OfferSequence": 1, "Owner": "r3wN3v2vTUkr5qd6daqDc2xE4LSysdVjkT", "Sequence": 3, "SigningPubKey": "027FB1CF34395F18901CD294F77752EEE25277C6E87A224FC7388AA7EF872DB43D", "TransactionType": "EscrowCancel", "TxnSignature": "3045022100AC45749FC4291F7811B2D8AC01CA04FEE38910CB7216FB0C5C0AEBC9C0A95F4302203F213C71C00136A0ADC670EFE350874BCB2E559AC02059CEEDFB846685948F2B", "date": 560302841, "hash": "65F36C5514153D94F0ADE5CE747061A5E70B73B56B4C66DA5040D99CAF252831", "inLedger": 2906406, "ledger_index": 2906406, "meta": { "AffectedNodes": [ { "ModifiedNode": { "LedgerEntryType": "AccountRoot", "LedgerIndex": "13F1A95D7AAB7108D5CE7EEAF504B2894B8C674E6D68499076441C4837282BF8", "PreviousTxnID": "4756C22BBB7FC23D9081FDB180806939D6FEBC967BE0EC2DB95B166AF9C086E9", "PreviousTxnLgrSeq": 2764813 } }, { "ModifiedNode": { "FinalFields": { "Account": "rhgdnc82FwHFUKXp9ZcpgwXWRAxKf5Buqp", "Balance": "9999999970", "Flags": 0, "OwnerCount": 0, "Sequence": 4 }, "LedgerEntryType": "AccountRoot", "LedgerIndex": "3430FA3A160FA8F9842FA4A8B5549ECDCB3783E585D0F9796A1736DEAE35F6FE", "PreviousFields": { "Balance": "9999999980", "Sequence": 3 }, "PreviousTxnID": "DA6F5CA8CE13A03B8BC58515E085F2FEF90B3C08230B5AEC8DE4FAF39F79010B", "PreviousTxnLgrSeq": 2906391 } }, { "DeletedNode": { "FinalFields": { "Account": "r3wN3v2vTUkr5qd6daqDc2xE4LSysdVjkT", "Amount": "10000", "CancelAfter": 559913895, "Destination": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", "FinishAfter": 559892324, "Flags": 0, "OwnerNode": "0000000000000000", "PreviousTxnID": "4756C22BBB7FC23D9081FDB180806939D6FEBC967BE0EC2DB95B166AF9C086E9", "PreviousTxnLgrSeq": 2764813 }, "LedgerEntryType": "Escrow", "LedgerIndex": "7243A9750FA4BE3E63F75F6DACFD79AD6B6C76947F6BDC46CD0F52DBEEF64C89" } }, { "ModifiedNode": { "FinalFields": { "Flags": 0, "Owner": "r3wN3v2vTUkr5qd6daqDc2xE4LSysdVjkT", "RootIndex": "DACDBEBD31D14EAC4207A45DB88734AD14D26D908507F41D2FC623BDD91C582F" }, "LedgerEntryType": "DirectoryNode", "LedgerIndex": "DACDBEBD31D14EAC4207A45DB88734AD14D26D908507F41D2FC623BDD91C582F" } }, { "ModifiedNode": { "FinalFields": { "Account": "r3wN3v2vTUkr5qd6daqDc2xE4LSysdVjkT", "Balance": "9999999990", "Flags": 0, "OwnerCount": 0, "Sequence": 2 }, "LedgerEntryType": "AccountRoot", "LedgerIndex": "F5F1834B80A8B5DA878270AB4DE4EA444281181349375F1D21E46D5F3F0ABAC8", "PreviousFields": { "Balance": "9999989990", "OwnerCount": 1 }, "PreviousTxnID": "4756C22BBB7FC23D9081FDB180806939D6FEBC967BE0EC2DB95B166AF9C086E9", "PreviousTxnLgrSeq": 2764813 } } ], "TransactionIndex": 2, "TransactionResult": "tesSUCCESS" }, "validated": true } } In the above example, `r3wN3v2vTUkr5qd6daqDc2xE4LSysdVjkT` is the sender of the escrow, and the increase in `Balance` from 99999**8**9990 drops to 99999**9**9990 drops represents the return of the escrowed 10,000 drops of XRP (0.01 XRP). ## See Also - **Concepts:** - [What is XRP?](/docs/introduction/what-is-xrp) - [Payment Types](/docs/concepts/payment-types) - [Escrow](/docs/concepts/payment-types/escrow) - **Tutorials:** - [Send XRP](/docs/tutorials/how-tos/send-xrp) - [Look Up Transaction Results](/docs/concepts/transactions/finality-of-results/look-up-transaction-results) - [Reliable Transaction Submission](/docs/concepts/transactions/reliable-transaction-submission) - **References:** - [EscrowCancel transaction](/docs/references/protocol/transactions/types/escrowcancel) - [EscrowCreate transaction](/docs/references/protocol/transactions/types/escrowcreate) - [EscrowFinish transaction](/docs/references/protocol/transactions/types/escrowfinish) - [account_objects method](/docs/references/http-websocket-apis/public-api-methods/account-methods/account_objects) - [tx method](/docs/references/http-websocket-apis/public-api-methods/transaction-methods/tx) - [Escrow ledger object](/docs/references/protocol/ledger-data/ledger-entry-types/escrow)