CLI Tool Example
A minimal Node.js CLI that creates a signing request, prints the signing URL, and waits for the user to sign — useful for scripts, CI pipelines, and dev tooling.
Install dependencies
npm install @xrplrequest/sdk
npm install -D typescript @types/node tsxFull example
#!/usr/bin/env tsx
// xrpl-sign.ts — usage: tsx xrpl-sign.ts <destination> [amount_in_xrp]
import { XRPLRequest } from "@xrplrequest/sdk";
async function main() {
const apiKey = process.env.XRPL_REQUEST_API_KEY;
if (!apiKey) {
console.error("Error: XRPL_REQUEST_API_KEY environment variable is not set.");
process.exit(1);
}
const destination = process.argv[2];
const amountXrp = parseFloat(process.argv[3] ?? "1");
if (!destination || !destination.startsWith("r")) {
console.error("Usage: tsx xrpl-sign.ts <destination_address> [amount_in_xrp]");
console.error("Example: tsx xrpl-sign.ts rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh 10");
process.exit(1);
}
const client = new XRPLRequest({ apiKey });
console.log(`\nCreating signing request: ${amountXrp} XRP → ${destination}`);
const payload = await client.payloads.create({
type: "signAndSubmit",
transaction: {
TransactionType: "Payment",
Destination: destination,
Amount: String(Math.round(amountXrp * 1_000_000)), // drops
},
options: { expiresIn: 300 },
});
console.log(`\n Signing URL: ${payload.signingUrl}`);
console.log(` Expires: ${new Date(payload.expiresAt).toLocaleTimeString()}`);
console.log(` UUID: ${payload.uuid}`);
console.log("\nWaiting for signature (5 min timeout)...");
let lastStatus = "";
const result = await client.payloads.poll(payload.uuid, {
timeout: 300_000,
interval: 2_000,
onUpdate: (p) => {
if (p.status !== lastStatus) {
process.stdout.write(` Status: ${p.status}\r`);
lastStatus = p.status;
}
},
});
console.log(""); // newline after \r updates
if (result.status === "signed") {
console.log(`\n✅ Signed by ${result.signerAddress}`);
if (result.txHash) {
console.log(` Tx hash: ${result.txHash}`);
console.log(` Explorer: https://livenet.xrpl.org/transactions/${result.txHash}`);
}
} else if (result.status === "rejected") {
console.log("\n❌ Rejected by user.");
process.exit(1);
} else {
console.log("\n⏱ Request expired without a signature.");
process.exit(1);
}
}
main().catch((err) => {
console.error("\nUnexpected error:", err.message);
process.exit(1);
});Usage
# Set your API key
export XRPL_REQUEST_API_KEY=xrplr_live_...
# Send 5 XRP to an address
tsx xrpl-sign.ts rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh 5Output:
Creating signing request: 5 XRP → rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh
Signing URL: https://xrplre.quest/sign/550e8400-e29b-41d4-a716-446655440000
Expires: 2:37:00 PM
UUID: 550e8400-e29b-41d4-a716-446655440000
Waiting for signature (5 min timeout)...
Status: pending
✅ Signed by rGWrZyax5eXbi5gs49MRZKmm...
Tx hash: A1B2C3D4E5F6...
Explorer: https://livenet.xrpl.org/transactions/A1B2C3D4...Make it globally executable
Add a shebang and chmod:
# tsconfig.json must have "module": "ESNext"
chmod +x xrpl-sign.ts
# Run directly (requires tsx installed globally: npm i -g tsx)
./xrpl-sign.ts rHb9... 1Or compile to plain JS for distribution:
# Compile with tsup
npx tsup xrpl-sign.ts --format esm
# Run
node dist/xrpl-sign.js rHb9... 1Extend: wallet-connect mode
Change the payload type to just connect a wallet (no transaction):
const payload = await client.payloads.create({
type: "connect",
options: { expiresIn: 120 },
});
// After polling...
if (result.status === "signed") {
console.log(`Wallet connected: ${result.signerAddress}`);
}Extend: sign arbitrary transactions
Pass raw JSON for any XRPL transaction type:
const payload = await client.payloads.create({
type: "sign", // sign only — don't submit
transaction: {
TransactionType: "NFTokenMint",
NFTokenTaxon: 0,
Flags: 8, // tfTransferable
URI: Buffer.from("https://example.com/metadata.json").toString("hex").toUpperCase(),
},
});The SDK’s poll() method handles retry logic and backoff for you. Set interval (ms between polls, min 1000ms on Pro / 3000ms on Free) and timeout (total wait time in ms).