This guide explains how to integrate transaction creation with existing loan operations.
The transaction history feature is ready to use. To start tracking transactions, you need to call insertTransaction() when loan operations occur.
When a user requests a loan, create a transaction record:
import { insertTransaction } from "./db/store";
// In your loan request endpoint
app.post("/api/loan/request", async (req, res) => {
const { borrower, collateral_id, amount } = req.body;
// ... existing loan request logic ...
// Create transaction record
const transaction = insertTransaction({
borrower,
type: "loan",
status: "pending", // Will be "completed" after blockchain confirmation
amount,
collateralId: String(collateral_id),
});
// Return XDR for signing
res.json({ xdr: xdrTx, transactionId: transaction.id });
});When a user repays a loan:
// In your loan repay endpoint
app.post("/api/loan/repay", async (req, res) => {
const { borrower, loan_id, amount } = req.body;
// ... existing repay logic ...
// Create transaction record
const transaction = insertTransaction({
borrower,
type: "repayment",
status: "pending",
amount,
loanId: String(loan_id),
});
res.json({ xdr: xdrTx, transactionId: transaction.id });
});When a loan is liquidated:
// In your liquidation endpoint
app.post("/api/loan/liquidate", async (req, res) => {
const { liquidator, loan_id, repay_amount } = req.body;
// ... existing liquidation logic ...
// Create transaction record
const transaction = insertTransaction({
borrower: liquidator,
type: "liquidation",
status: "pending",
amount: repay_amount,
loanId: String(loan_id),
});
res.json({ xdr: xdrTx, transactionId: transaction.id });
});After blockchain confirmation, update the transaction status:
import { updateTransaction } from "./db/store";
// After transaction is confirmed on blockchain
updateTransaction(transactionId, {
status: "completed",
});
// If transaction fails
updateTransaction(transactionId, {
status: "failed",
});The TransactionHistory component automatically fetches and displays all transactions. No additional frontend integration needed.
After creating a transaction, you can show the ID to the user:
// Frontend
const response = await fetch("/api/loan/request", {
method: "POST",
body: JSON.stringify({ borrower, collateral_id, amount }),
});
const { xdr, transactionId } = await response.json();
console.log("Transaction ID:", transactionId); // Show to user if desiredWhen moving to a real database, create this migration:
-- Migration: Create transactions table
CREATE TABLE transactions (
id TEXT PRIMARY KEY,
borrower TEXT NOT NULL,
type TEXT NOT NULL CHECK (type IN ('loan', 'repayment', 'liquidation')),
status TEXT NOT NULL CHECK (status IN ('pending', 'completed', 'failed')),
amount INTEGER NOT NULL,
loan_id TEXT,
collateral_id TEXT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- Indexes for common queries
CREATE INDEX idx_transactions_borrower ON transactions(borrower);
CREATE INDEX idx_transactions_type ON transactions(type);
CREATE INDEX idx_transactions_status ON transactions(status);
CREATE INDEX idx_transactions_created_at ON transactions(created_at);
CREATE INDEX idx_transactions_borrower_created ON transactions(borrower, created_at DESC);curl "http://localhost:3001/api/transactions?borrower=GXXXXXX&page=1&pageSize=20"curl "http://localhost:3001/api/transactions?type=repayment&startDate=2026-04-01&endDate=2026-04-30"curl "http://localhost:3001/api/transactions/tx_1234567890_abc123"import { insertTransaction, updateTransaction } from "./db/store";
// Create a test loan transaction
const tx1 = insertTransaction({
borrower: "GXXXXXX...",
type: "loan",
status: "completed",
amount: 1000,
collateralId: "123",
});
// Create a test repayment
const tx2 = insertTransaction({
borrower: "GXXXXXX...",
type: "repayment",
status: "completed",
amount: 500,
loanId: "456",
});
// Update status
updateTransaction(tx1.id, { status: "completed" });- Always create transaction records - Even if blockchain confirmation is pending
- Use consistent borrower addresses - Ensures filtering works correctly
- Set correct transaction types - Use "loan", "repayment", or "liquidation"
- Update status after confirmation - Mark as "completed" or "failed" after blockchain confirmation
- Include optional IDs - Provide loanId and collateralId when available for better tracking
- Check that transactions are being created:
GET /api/transactions - Verify borrower address matches the logged-in user
- Check browser console for API errors
- Verify API is running on correct port
- Ensure date format is ISO (YYYY-MM-DD)
- Check that transaction type is one of: "loan", "repayment", "liquidation"
- Check that status is one of: "pending", "completed", "failed"
- Verify transactions exist for current filters
- Check that page size is not set to 0
- Ensure no JavaScript errors in browser console
- Add transaction creation to existing loan endpoints
- Implement blockchain confirmation webhook to update transaction status
- Test with real loan operations
- Monitor transaction history in dashboard
- Consider adding analytics based on transaction data