Cancel an Expired Escrow

1. Confirm the expired escrow

An escrow in the XRP Ledger is expired when its CancelAfter time is lower than the close_time of a validated ledger version. (If the escrow does not have a CancelAfter time, it never expires.) You can look up the close time of the latest validated ledger with the ledger method:

Request:

{
  "id": 4,
  "command": "ledger",
  "ledger_index": "validated"
}

Response:

{
  "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
  }
}

You can look up the escrow and compare to the CancelAfter time using the account_objects method:

Request:

{
  "id": 2,
  "command": "account_objects",
  "account": "r3wN3v2vTUkr5qd6daqDc2xE4LSysdVjkT",
  "ledger": "validated",
  "type": "escrow"
}

Response:

{
  "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
  }
}

2. Submit EscrowCancel transaction

Anyone can cancel an expired escrow in the XRP Ledger by signing and submitting an EscrowCancel transaction. 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.

Caution: Never submit a secret key to a server you do not control. Do not send a secret key unencrypted over the network.

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"
    }
  }
}

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.

3. Wait for validation

On the live network or the Ripple Test Net, 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.

4. Confirm final result

Use the tx method 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:

{
  "id": 6,
  "command": "tx",
  "transaction": "65F36C5514153D94F0ADE5CE747061A5E70B73B56B4C66DA5040D99CAF252831"
}

Response:

{
  "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 9999989990 drops to 9999999990 drops represents the return of the escrowed 10,000 drops of XRP (0.01 XRP).

Tip: If you don't know what OfferSequence to use in the EscrowFinish transaction to execute an escrow, use the tx method to look up the transaction that created the escrow, using the identifying hash of the transaction in the Escrow's PreviousTxnID field. Use the Sequence value of that transaction as the OfferSequence value when finishing the escrow.