Skip to content

Conversation

@JSTONE1111
Copy link
Owner

// index.js — XRPL Dev Boilerplate (Express API)
// Usage: configure .env, then npm start

require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');
const xrpl = require('xrpl');

const app = express();
app.use(bodyParser.json());

const PORT = process.env.PORT || 3000;
const NETWORK = process.env.XRPL_NETWORK === 'mainnet'
? 'wss://s1.ripple.com' // Mainnet public node (be careful with real XRP)
: 'wss://s.altnet.rippletest.net:51233'; // Testnet

// Shared client instance (connect once)
const client = new xrpl.Client(NETWORK);

// connect at startup
(async () => {
try {
await client.connect();
console.log(Connected to XRPL network: ${NETWORK});
} catch (err) {
console.error('Failed to connect to XRPL:', err);
process.exit(1);
}
})();

/**

  • Helpers
    */
    function xrpToDrops(xrpAmount) {
    // xrpl.js provides this util, but keep a small helper for safety
    return xrpl.xrpToDrops(String(xrpAmount));
    }

/**

  • Routes
    */

// Generate a fresh wallet (Testnet/mainnet compatible - funding required on testnet)
app.get('/wallet/new', async (req, res) => {
try {
const wallet = xrpl.Wallet.generate();
// wallet: { seed, classicAddress, publicKey, privateKey }
res.json({
ok: true,
wallet: {
seed: wallet.seed,
address: wallet.classicAddress,
publicKey: wallet.publicKey
},
warning: 'Keep your seed private. This endpoint returns the seed for dev only.'
});
} catch (err) {
res.status(500).json({ ok: false, error: err.toString() });
}
});

// Import from seed
app.post('/wallet/import', async (req, res) => {
try {
const { seed } = req.body;
if (!seed) return res.status(400).json({ ok: false, error: 'seed required' });
const wallet = xrpl.Wallet.fromSeed(seed);
res.json({
ok: true,
wallet: {
address: wallet.classicAddress,
publicKey: wallet.publicKey
}
});
} catch (err) {
res.status(500).json({ ok: false, error: err.toString() });
}
});

// Get account balance
app.get('/balance/:address', async (req, res) => {
const address = req.params.address;
try {
const response = await client.request({
command: 'account_info',
account: address,
ledger_index: 'validated'
});
const balanceDrops = response.result.account_data.Balance;
const balanceXrp = xrpl.dropsToXrp(balanceDrops);
res.json({ ok: true, address, balance: balanceXrp, raw: response.result.account_data });
} catch (err) {
// If account doesn't exist yet on ledger (unfunded) you'll get an error
res.status(400).json({ ok: false, error: err.message || err.toString() });
}
});

// Send XRP (dangerous on mainnet — dev use only)
// POST body: { seed: "<s...>", destination: "r...", amount: "1.5" }
app.post('/send', async (req, res) => {
try {
const { seed, destination, amount } = req.body;
if (!seed || !destination || !amount) {
return res.status(400).json({ ok: false, error: 'seed, destination, and amount are required' });
}

const wallet = xrpl.Wallet.fromSeed(seed);
const prepared = await client.autofill({
  TransactionType: 'Payment',
  Account: wallet.classicAddress,
  Amount: xrpToDrops(amount),
  Destination: destination
});

const signed = wallet.sign(prepared);
const tx = await client.submitAndWait(signed.tx_blob);

res.json({
  ok: true,
  result: tx.result,
  tx_hash: tx.result.tx_json && tx.result.tx_json.hash
});

} catch (err) {
res.status(500).json({ ok: false, error: err.message || err.toString() });
}
});

// Get transaction details by hash
app.get('/tx/:hash', async (req, res) => {
const hash = req.params.hash;
try {
const response = await client.request({
command: 'tx',
transaction: hash
});
res.json({ ok: true, tx: response.result });
} catch (err) {
res.status(400).json({ ok: false, error: err.message || err.toString() });
}
});

// Simple health check
app.get('/health', (req, res) => res.json({ ok: true, network: NETWORK }));

// Shutdown handler to close client
process.on('SIGINT', async () => {
console.log('Shutting down — disconnecting XRPL client');
try { await client.disconnect(); } catch (e) {}
process.exit(0);
});

app.listen(PORT, () => {
console.log(XRPL dev API listening on http://localhost:${PORT});
});

Updated the build dependencies step in the Windows workflow.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants