mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2026-04-29 15:37:48 +00:00
162 lines
5.4 KiB
JavaScript
162 lines
5.4 KiB
JavaScript
import xrpl from "xrpl"
|
|
import { execSync } from "child_process"
|
|
import fs from "fs"
|
|
|
|
// Auto-run setup if needed
|
|
if (!fs.existsSync("vaultSetup.json")) {
|
|
console.log(`\n=== Vault setup data doesn't exist. Running setup script... ===\n`)
|
|
execSync("node vaultSetup.js", { stdio: "inherit" })
|
|
}
|
|
|
|
// Load setup data
|
|
const setupData = JSON.parse(fs.readFileSync("vaultSetup.json", "utf8"))
|
|
|
|
// Connect to the network
|
|
const client = new xrpl.Client("wss://s.devnet.rippletest.net:51233")
|
|
await client.connect()
|
|
|
|
// You can replace these values with your own
|
|
const depositor = xrpl.Wallet.fromSeed(setupData.depositor.seed)
|
|
const vaultID = setupData.vaultID
|
|
const assetMPTIssuanceId = setupData.mptIssuanceId
|
|
const shareMPTIssuanceId = setupData.vaultShareMPTIssuanceId
|
|
|
|
console.log(`Depositor address: ${depositor.address}`)
|
|
console.log(`Vault ID: ${vaultID}`)
|
|
console.log(`Asset MPT issuance ID: ${assetMPTIssuanceId}`)
|
|
console.log(`Vault share MPT issuance ID: ${shareMPTIssuanceId}`)
|
|
|
|
const withdrawAmount = "1"
|
|
|
|
// Get initial vault state ----------------------
|
|
console.log("\n=== Getting initial vault state... ===")
|
|
const initialVaultInfo = await client.request({
|
|
command: "vault_info",
|
|
vault_id: vaultID,
|
|
ledger_index: "validated"
|
|
})
|
|
|
|
console.log(`Initial vault state:`)
|
|
console.log(` Assets Total: ${initialVaultInfo.result.vault.AssetsTotal}`)
|
|
console.log(` Assets Available: ${initialVaultInfo.result.vault.AssetsAvailable}`)
|
|
|
|
// Check depositor's share balance ----------------------
|
|
console.log("\n=== Checking depositor's share balance... ===")
|
|
try {
|
|
const shareBalanceResult = await client.request({
|
|
command: "ledger_entry",
|
|
mptoken: {
|
|
mpt_issuance_id: shareMPTIssuanceId,
|
|
account: depositor.address
|
|
},
|
|
ledger_index: "validated"
|
|
})
|
|
|
|
const shareBalance = shareBalanceResult.result.node?.MPTAmount
|
|
console.log(`Shares held: ${shareBalance}`)
|
|
} catch (error) {
|
|
if (error.data?.error === 'entryNotFound') {
|
|
console.error(`Error: The depositor doesn't hold any vault shares with ID: ${shareMPTIssuanceId}.`)
|
|
} else {
|
|
console.error(`Error checking MPT: ${error}`)
|
|
}
|
|
await client.disconnect()
|
|
process.exit(1)
|
|
}
|
|
|
|
// Prepare VaultWithdraw transaction ----------------------
|
|
console.log(`\n=== Preparing VaultWithdraw transaction ===`)
|
|
const vaultWithdrawTx = {
|
|
TransactionType: "VaultWithdraw",
|
|
Account: depositor.address,
|
|
VaultID: vaultID,
|
|
Amount: {
|
|
mpt_issuance_id: assetMPTIssuanceId,
|
|
value: withdrawAmount
|
|
},
|
|
// Optional: Add Destination field to send assets to a different account
|
|
// Destination: "rGg4tHPRGJfewwJkd8immCFx9uSo2GgcoY"
|
|
}
|
|
|
|
// Validate the transaction structure before submitting
|
|
xrpl.validate(vaultWithdrawTx)
|
|
console.log(JSON.stringify(vaultWithdrawTx, null, 2))
|
|
|
|
// Submit VaultWithdraw transaction ----------------------
|
|
console.log("\n=== Submitting VaultWithdraw transaction... ===")
|
|
const withdrawResult = await client.submitAndWait(vaultWithdrawTx, {
|
|
wallet: depositor,
|
|
autofill: true,
|
|
})
|
|
if (withdrawResult.result.meta.TransactionResult !== "tesSUCCESS") {
|
|
const result_code = withdrawResult.result.meta.TransactionResult
|
|
console.error("Error: Unable to withdraw from vault:", result_code)
|
|
await client.disconnect()
|
|
process.exit(1)
|
|
}
|
|
console.log("Withdrawal successful!")
|
|
|
|
// Extract vault state from transaction metadata ----------------------
|
|
console.log("\n=== Vault state after withdrawal ===")
|
|
const affectedNodes = withdrawResult.result.meta.AffectedNodes
|
|
const vaultNode = affectedNodes.find(
|
|
(node) => {
|
|
const modifiedNode = node.ModifiedNode || node.DeletedNode
|
|
return (
|
|
modifiedNode &&
|
|
modifiedNode.LedgerEntryType === "Vault" &&
|
|
modifiedNode.LedgerIndex === vaultID
|
|
)
|
|
}
|
|
)
|
|
if (vaultNode) {
|
|
if (vaultNode.DeletedNode) {
|
|
console.log(` Vault empty (all assets withdrawn)`)
|
|
} else {
|
|
const vaultFields = vaultNode.ModifiedNode.FinalFields
|
|
console.log(` Assets Total: ${vaultFields.AssetsTotal}`)
|
|
console.log(` Assets Available: ${vaultFields.AssetsAvailable}`)
|
|
}
|
|
}
|
|
|
|
// Get the depositor's share balance ----------------------
|
|
console.log("\n=== Depositor's share balance ==")
|
|
const depositorShareNode = affectedNodes.find((node) => {
|
|
const modifiedNode = node.ModifiedNode || node.DeletedNode
|
|
return (
|
|
modifiedNode &&
|
|
modifiedNode.LedgerEntryType === "MPToken" &&
|
|
modifiedNode.FinalFields?.Account === depositor.address &&
|
|
modifiedNode.FinalFields?.MPTokenIssuanceID === shareMPTIssuanceId
|
|
)
|
|
})
|
|
if (depositorShareNode) {
|
|
if (depositorShareNode.DeletedNode) {
|
|
console.log(`No more shares held (redeemed all shares)`)
|
|
} else {
|
|
const shareFields = depositorShareNode.ModifiedNode.FinalFields
|
|
console.log(`Shares held: ${shareFields.MPTAmount}`)
|
|
}
|
|
}
|
|
|
|
// Get the depositor's asset balance ----------------------
|
|
console.log("\n=== Depositor's asset balance ==")
|
|
const depositorAssetNode = affectedNodes.find((node) => {
|
|
const assetNode = node.ModifiedNode || node.CreatedNode
|
|
const fields = assetNode?.FinalFields || assetNode?.NewFields
|
|
return (
|
|
assetNode &&
|
|
assetNode.LedgerEntryType === "MPToken" &&
|
|
fields?.Account === depositor.address &&
|
|
fields?.MPTokenIssuanceID === assetMPTIssuanceId
|
|
)
|
|
})
|
|
if (depositorAssetNode) {
|
|
const assetNode = depositorAssetNode.ModifiedNode || depositorAssetNode.CreatedNode
|
|
const assetFields = assetNode.FinalFields || assetNode.NewFields
|
|
console.log(`Balance: ${assetFields.MPTAmount}`)
|
|
}
|
|
|
|
await client.disconnect()
|
|
|