mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2026-04-29 15:37:48 +00:00
135 lines
4.4 KiB
JavaScript
135 lines
4.4 KiB
JavaScript
// IMPORTANT: This example pays off an existing loan and then deletes it.
|
|
|
|
import fs from 'fs'
|
|
import { execSync } from 'child_process'
|
|
import xrpl from 'xrpl'
|
|
|
|
// Connect to the network ----------------------
|
|
const client = new xrpl.Client('wss://s.devnet.rippletest.net:51233')
|
|
await client.connect()
|
|
|
|
// This step checks for the necessary setup data to run the lending protocol tutorials.
|
|
// If missing, lendingSetup.js will generate the data.
|
|
if (!fs.existsSync('lendingSetup.json')) {
|
|
console.log(`\n=== Lending tutorial data doesn't exist. Running setup script... ===\n`)
|
|
execSync('node lendingSetup.js', { stdio: 'inherit' })
|
|
}
|
|
|
|
// Load preconfigured accounts and LoanID.
|
|
const setupData = JSON.parse(fs.readFileSync('lendingSetup.json', 'utf8'))
|
|
|
|
// You can replace these values with your own
|
|
const borrower = xrpl.Wallet.fromSeed(setupData.borrower.seed)
|
|
const loanID = setupData.loanID2
|
|
const mptID = setupData.mptID
|
|
|
|
console.log(`\nBorrower address: ${borrower.address}`)
|
|
console.log(`LoanID: ${loanID}`)
|
|
console.log(`MPT ID: ${mptID}`)
|
|
|
|
// Check initial loan status ----------------------
|
|
console.log(`\n=== Loan Status ===\n`)
|
|
const loanStatus = await client.request({
|
|
command: 'ledger_entry',
|
|
index: loanID,
|
|
ledger_index: 'validated'
|
|
})
|
|
|
|
const totalValueOutstanding = loanStatus.result.node.TotalValueOutstanding
|
|
const loanServiceFee = loanStatus.result.node.LoanServiceFee
|
|
const totalPayment = (BigInt(totalValueOutstanding) + BigInt(loanServiceFee)).toString()
|
|
|
|
console.log(`Amount Owed: ${totalValueOutstanding} TSTUSD`)
|
|
console.log(`Loan Service Fee: ${loanServiceFee} TSTUSD`)
|
|
console.log(`Total Payment Due (including fees): ${totalPayment} TSTUSD`)
|
|
|
|
// Prepare LoanPay transaction ----------------------
|
|
console.log(`\n=== Preparing LoanPay transaction ===\n`)
|
|
|
|
const loanPayTx = {
|
|
TransactionType: 'LoanPay',
|
|
Account: borrower.address,
|
|
LoanID: loanID,
|
|
Amount: {
|
|
mpt_issuance_id: mptID,
|
|
value: totalPayment
|
|
}
|
|
}
|
|
|
|
// Validate the transaction structure before submitting
|
|
xrpl.validate(loanPayTx)
|
|
console.log(JSON.stringify(loanPayTx, null, 2))
|
|
|
|
// Sign, submit, and wait for payment validation ----------------------
|
|
console.log(`\n=== Submitting LoanPay transaction ===\n`)
|
|
const payResponse = await client.submitAndWait(loanPayTx, {
|
|
wallet: borrower,
|
|
autofill: true
|
|
})
|
|
|
|
if (payResponse.result.meta.TransactionResult !== 'tesSUCCESS') {
|
|
const resultCode = payResponse.result.meta.TransactionResult
|
|
console.error('Error: Unable to pay loan:', resultCode)
|
|
await client.disconnect()
|
|
process.exit(1)
|
|
}
|
|
console.log('Loan paid successfully!')
|
|
|
|
// Extract updated loan info from transaction results ----------------------
|
|
console.log(`\n=== Loan Status After Payment ===\n`)
|
|
const loanNode = payResponse.result.meta.AffectedNodes.find(node =>
|
|
node.ModifiedNode?.LedgerEntryType === 'Loan'
|
|
)
|
|
|
|
const finalBalance = loanNode.ModifiedNode.FinalFields.TotalValueOutstanding
|
|
? `${loanNode.ModifiedNode.FinalFields.TotalValueOutstanding} TSTUSD`
|
|
: 'Loan fully paid off!'
|
|
console.log(`Outstanding Loan Balance: ${finalBalance}`)
|
|
|
|
// Prepare LoanDelete transaction ----------------------
|
|
// Either the loan broker or borrower can submit this transaction.
|
|
console.log(`\n=== Preparing LoanDelete transaction ===\n`)
|
|
const loanDeleteTx = {
|
|
TransactionType: 'LoanDelete',
|
|
Account: borrower.address,
|
|
LoanID: loanID
|
|
}
|
|
|
|
// Validate the transaction structure before submitting
|
|
xrpl.validate(loanDeleteTx)
|
|
console.log(JSON.stringify(loanDeleteTx, null, 2))
|
|
|
|
// Sign, submit, and wait for deletion validation ----------------------
|
|
console.log(`\n=== Submitting LoanDelete transaction ===\n`)
|
|
const deleteResponse = await client.submitAndWait(loanDeleteTx, {
|
|
wallet: borrower,
|
|
autofill: true
|
|
})
|
|
|
|
if (deleteResponse.result.meta.TransactionResult !== 'tesSUCCESS') {
|
|
const resultCode = deleteResponse.result.meta.TransactionResult
|
|
console.error('Error: Unable to delete loan:', resultCode)
|
|
await client.disconnect()
|
|
process.exit(1)
|
|
}
|
|
console.log('Loan deleted successfully!')
|
|
|
|
// Verify loan deletion ----------------------
|
|
console.log(`\n=== Verifying Loan Deletion ===\n`)
|
|
try {
|
|
await client.request({
|
|
command: 'ledger_entry',
|
|
index: loanID,
|
|
ledger_index: 'validated'
|
|
})
|
|
console.log('Warning: Loan still exists in the ledger.')
|
|
} catch (error) {
|
|
if (error.data.error === 'entryNotFound') {
|
|
console.log('Loan has been successfully removed from the XRP Ledger!')
|
|
} else {
|
|
console.error('Error checking loan status:', error)
|
|
}
|
|
}
|
|
|
|
await client.disconnect()
|