Start implementing tutorial for updated timed escrow sample

This commit is contained in:
mDuo13
2025-09-17 18:19:53 -07:00
parent 242a6cc31b
commit 8c25a5ea33
3 changed files with 68 additions and 110 deletions

View File

@@ -1,92 +0,0 @@
import xrpl from 'xrpl'
/* Sleep function that can be used with await */
function sleep (delayInSeconds) {
const delayInMs = delayInSeconds * 1000
return new Promise((resolve) => setTimeout(resolve, delayInMs))
}
const client = new xrpl.Client('wss://s.altnet.rippletest.net:51233')
await client.connect()
console.log('Funding new wallet from faucet...')
const { wallet } = await client.fundWallet()
const dest_address = 'rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe' // Testnet faucet
const delay = 30
// Set the escrow finish time -----------------------------------------------
const finishAfter = new Date()
finishAfter.setSeconds(finishAfter.getSeconds() + delay)
console.log('This escrow will finish after:', finishAfter)
// Convert finishAfter to seconds since the Ripple Epoch:
const finishAfterRippleTime = xrpl.isoTimeToRippleTime(finishAfter.toISOString())
// Send EscrowCreate transaction --------------------------------------------
const escrowCreate = {
TransactionType: 'EscrowCreate',
Account: wallet.address,
Destination: dest_address,
Amount: '12345', // drops of XRP
FinishAfter: finishAfterRippleTime
}
xrpl.validate(escrowCreate)
console.log('Signing and submitting the transaction:',
JSON.stringify(escrowCreate, null, 2))
const response = await client.submitAndWait(escrowCreate, {
wallet,
autofill: true
})
console.log(JSON.stringify(response.result, null, 2))
const escrowSeq = response.result.tx_json.Sequence
console.log(`Escrow sequence is ${escrowSeq}.`)
// Wait for the escrow to be finishable -------------------------------------
console.log(`Waiting ${delay} seconds for the escrow to mature...`)
await sleep(delay)
// Check if escrow can be finished -------------------------------------------
let escrowReady = false
while (!escrowReady) {
// Check the close time of the latest validated ledger.
// Close times are rounded by about 10 seconds, so the exact time the escrow
// is ready to finish may vary by +/- 10 seconds.
const validatedLedger = await client.request({
command: 'ledger',
ledger_index: 'validated'
})
const ledgerCloseTime = validatedLedger.result.ledger.close_time
console.log('Latest validated ledger closed at',
xrpl.rippleTimeToISOTime(ledgerCloseTime))
if (ledgerCloseTime > finishAfterRippleTime) {
escrowReady = true
console.log('Escrow is ready to be finished.')
} else {
let timeDifference = finishAfterRippleTime - ledgerCloseTime
if (timeDifference === 0) { timeDifference = 1 }
console.log(`Waiting another ${timeDifference} second(s).`)
await sleep(timeDifference)
}
}
// Send EscrowFinish transaction --------------------------------------------
const escrowFinish = {
TransactionType: 'EscrowFinish',
Account: wallet.address,
Owner: wallet.address,
OfferSequence: escrowSeq
}
xrpl.validate(escrowFinish)
console.log('Signing and submitting the transaction:',
JSON.stringify(escrowFinish, null, 2))
const response2 = await client.submitAndWait(escrowFinish, {
wallet,
autofill: true
})
console.log(JSON.stringify(response2.result, null, 2))
if (response2.result.meta.TransactionResult === 'tesSUCCESS') {
console.log('Escrow finished successfully.')
}
client.disconnect()

View File

@@ -1,11 +1,5 @@
import xrpl from 'xrpl'
/* Sleep function that can be used with await */
function sleep (delayInSeconds) {
const delayInMs = delayInSeconds * 1000
return new Promise((resolve) => setTimeout(resolve, delayInMs))
}
/* Main function when called as a commandline script */
async function main () {
const client = new xrpl.Client('wss://s.altnet.rippletest.net:51233')
@@ -13,13 +7,17 @@ async function main () {
console.log('Funding new wallet from faucet...')
const { wallet } = await client.fundWallet()
// Define properties of the escrow
const dest_address = 'rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe' // Testnet faucet
const delay = 30
const delay = 30 // how long to escrow the funds, in seconds
const amount = '12345' // drops of XRP to send in the escrow
const { escrowSeq, finishAfterRippleTime } = await send_timed_escrow(
client,
wallet,
dest_address,
amount,
delay
)
@@ -30,12 +28,13 @@ async function main () {
client.disconnect()
}
/*
/* send_timed_escrow
* Create a time-based escrow.
* Parameters:
* client (xrpl.Client): network-connected client
* wallet (xrpl.Wallet): sender wallet
* dest_address (string): receiver address in base58
* amount (string): how many drops of XRP to send in escrow
* delay (int): number of seconds until the escrow is mature
* Returns: object with the following keys
* response (xrpl.TxResponse): transaction result from submitAndWait
@@ -43,7 +42,7 @@ async function main () {
* finishAfterRippleTime (int): the FinishAfter time of the created escrow,
* in seconds since the Ripple Epoch
*/
async function send_timed_escrow (client, wallet, dest_address, delay) {
async function send_timed_escrow (client, wallet, dest_address, amount, delay) {
// Set the escrow finish time -----------------------------------------------
const finishAfter = new Date()
finishAfter.setSeconds(finishAfter.getSeconds() + delay)
@@ -56,7 +55,7 @@ async function send_timed_escrow (client, wallet, dest_address, delay) {
TransactionType: 'EscrowCreate',
Account: wallet.address,
Destination: dest_address,
Amount: '12345', // drops of XRP
Amount: amount,
FinishAfter: finishAfterRippleTime
}
xrpl.validate(escrowCreate)
@@ -77,7 +76,7 @@ async function send_timed_escrow (client, wallet, dest_address, delay) {
}
}
/*
/* wait_for_escrow
* Check the ledger close time to see if an escrow can be finished.
* If it's not ready yet, wait a number of seconds equal to the difference
* from the latest ledger close time to the escrow's FinishAfter time.
@@ -113,7 +112,13 @@ async function wait_for_escrow (client, finishAfterRippleTime) {
}
}
/*
/* Sleep function that can be used with await */
function sleep (delayInSeconds) {
const delayInMs = delayInSeconds * 1000
return new Promise((resolve) => setTimeout(resolve, delayInMs))
}
/* finish_escrow
* Finish an escrow that your account owns.
* Parameters:
* client (xrpl.Client): network-connected client
@@ -143,4 +148,5 @@ async function finish_escrow (client, wallet, escrowSeq) {
}
}
// Call main function so it runs as a script
main()

View File

@@ -1,15 +1,59 @@
---
html: send-a-time-held-escrow.html
parent: use-escrows.html
seo:
description: Create an escrow whose only condition for release is that a specific time has passed.
description: Send an escrow whose only condition for release is that a specific time has passed.
labels:
- Escrow
- Smart Contracts
---
# Send a Time-Held Escrow
# Send a Timed Escrow
This tutorial demonstrates how to send an [escrow](../../../../concepts/payment-types/escrow.md) whose only condition for release is that a specific time has passed. You can use this to set aside money for yourself or others so that it absolutely cannot be used until the specified time.
This tutorial shows how to escrow XRP. If the [TokenEscrow amendment][] is enabled, you can also escrow tokens.
## Goals
By following this tutorial, you should learn how to:
- Convert a timestamp into the XRP Ledger's native format.
- Create and finish an escrow.
## Prerequisites
To complete this tutorial, you should:
- Have a basic understanding of the XRP Ledger
- Have an XRP Ledger client library, such as **xrpl.js**, installed.
## Source Code
You can find the complete source code for this tutorial's examples in the {% repo-link path="_code-samples/escrow/send-timed-escrow.js" %}code samples section of this website's repository{% /repo-link %}.
## Steps
### 1. Install dependencies
{% tabs %}
{% tab label="JavaScript" %}
From the code sample folder, use npm to install dependencies:
```sh
npm i
```
{% /tab %}
{% /tabs %}
### 2. Import dependencies and get accounts
After importing the XRPL client library, the tutorial code gets a new wallet from the testnet faucet and defines the properties of the escrow as hard-coded constants. You can use an existing wallet or modify the constants as desired.
{% tabs %}
{% tab label="JavaScript" %}
{% code-snippet file="/_code-samples/escrow/js/send-timed-escrow.js" language="js" before="/* send_timed_escrow" /%}
{% /tab %}
{% /tabs %}
The [EscrowCreate transaction][] type can create an escrow whose only condition for release is that a specific time has passed. To do this, use the `FinishAfter` field and omit the `Condition` field.
## 1. Calculate release time