Frequently Asked Questions
General Questions
What is Link Core?
Link Core is the central orchestrator microservice for the LedgerLink platform. It manages the entire lifecycle of transactions, balance tracking, and digital asset management across the ecosystem.
Technology Stack:
- NestJS backend with TypeScript
- PostgreSQL database with TypeORM
- Bull queues for background job processing
- Blockchain integration for digital asset transactions
- RESTful API with Swagger documentation
Core Responsibilities:
- Transaction processing (deposits, withdrawals, transfers)
- AML/compliance screening integration
- Balance management and ledger operations
- Digital asset configuration
- Job processing and event handling
What types of transactions does Link Core handle?
Deposit Transactions:
- Detected via blockchain event monitoring
- Automatically screened for AML/compliance
- Can be frozen for manual review
- Balance updated upon approval
Withdrawal Transactions:
- Customer-initiated via API
- Screened before processing
- Can be frozen for manual review
- Blockchain transaction executed upon approval
Internal Transfers:
- Between customer accounts
- Real-time balance updates
- Audit trail maintained
How does transaction screening work?
Link Core uses a webhook/callback pattern for screening:
-
Transaction Created:
- Transaction enters PENDING status
- Link Core logs "Starting AML verification"
- Transaction awaits external screening
-
External Screening (outside LedgerLink):
- External AML/compliance system performs checks
- This could be a third-party service or manual compliance team
- External system has access to Link Core API
-
Screening Callback:
- External system calls
POST /transactions/complete-screening
{
"id": "transaction-id",
"isApproved": true/false,
"screeningData": { /* screening details */ }
} - External system calls
-
Link Core Processes Result:
- If approved: Transaction queued for processing
- If rejected: Status changed to FROZEN for manual review
-
Manual Review (for frozen transactions):
- Admin reviews transaction details and screening data
- Decision: Approve or Reject
- API endpoints:
/transactions/:id/approve-frozen-*or/transactions/:id/reject-frozen-*
What are transaction statuses?
- PENDING: Created, awaiting external screening callback
- FROZEN: Flagged by external screening, requires manual review
- APPROVED: Approved (automatically or after manual review), processing
- COMPLETED: Fully processed, balance updated
- REJECTED: Rejected by external screening or manual review
- FAILED: Processing error occurred
Note: There is no "SCREENING" status - transactions remain PENDING while awaiting the external screening webhook callback.
How are balances calculated?
Link Core uses double-entry bookkeeping:
- Available Balance: Funds available for withdrawal
- Frozen Balance: Funds held (pending transactions, frozen deposits)
- Total Balance: Available + Frozen
Balance Updates:
- Real-time updates on transaction completion
- Atomic operations ensure consistency
- Audit trail maintained for all changes
Technical Questions
How do I integrate with Link Core?
For Dashboard/Frontend:
// Access through Auth Server proxy
const response = await fetch('/api/link-core/v1/transactions', {
credentials: 'include' // Include session cookies
});
For Internal Services:
// Direct service-to-service calls (within secure network)
const response = await fetch('http://link-core:3000/transactions');
What authentication is required?
Production: All requests go through the Link Dashboard's Auth Server:
- User authentication handled by Dashboard
- Session validation by Auth Server
- Requests proxied to Link Core
Development: Direct access to service (no authentication required)
How do I request a withdrawal?
POST /transactions/withdrawal
{
"customerId": "customer-123",
"assetId": "btc-asset-id",
"amount": "0.5",
"destinationAddress": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh"
}
Flow:
- Request validated
- Balance checked
- Transaction created (PENDING)
- Sent to screening
- If approved → Blockchain transaction initiated
- If frozen → Manual review required
How do I handle frozen transactions?
Check Transaction Status:
GET /transactions/:id
Approve Frozen Deposit:
POST /transactions/:id/approve-frozen-deposit
Reject Frozen Deposit:
POST /transactions/:id/reject-frozen-deposit
{
"reason": "AML compliance violation"
}
Approve Frozen Withdrawal:
POST /transactions/:id/approve-frozen-withdrawal
Reject Frozen Withdrawal:
POST /transactions/:id/reject-frozen-withdrawal
{
"reason": "Suspicious activity detected"
}
How do I query customer balances?
Get All Balances:
GET /balances/customer/:customerId
Filter by Asset:
GET /balances/customer/:customerId?filter[assetCode]=BTC
Response includes:
- Asset details (code, name, ID)
- Available balance
- Frozen balance
- Total balance
What happens during background job processing?
Screening Complete Job:
- Processes approved transactions
- Updates balances
- Sends notifications
- Logs to Link Tracker
Omnibus Balance Monitor:
- Tracks omnibus wallet balances
- Alerts on low balance conditions
- Ensures liquidity for withdrawals
How does Link Core integrate with other services?
Link Quote:
- Fetches real-time asset prices
- Values transactions in USD/fiat
- Used for reporting and analytics
Link Tracker:
- Logs all transaction events
- Maintains audit trail
- Provides activity monitoring
Wallet Manager:
- Executes blockchain transactions
- Manages digital asset custody
- Processes withdrawals
Blockchain Listener:
- Monitors incoming deposits
- Detects blockchain events
- Triggers transaction creation
External AML/Compliance System:
- Independent system (outside LedgerLink)
- Performs AML/compliance checks
- Calls back to Link Core via webhook:
POST /transactions/complete-screening - Provides screening metadata and approval/rejection decisions
What are the rate limits?
Link Dashboard (Auth Server): Rate limiting is implemented at the Dashboard/Auth Server level to protect the entire platform.
Link Core Service: No rate limiting at the service level (relies on Dashboard protection).
Best Practices:
- Dashboard rate limiting protects against excessive requests
- Implement client-side caching where appropriate
- Use appropriate pagination for list endpoints
- Monitor your request patterns
Integration Questions
How do I monitor transaction status?
Polling Approach:
async function monitorTransaction(id: string): Promise<Transaction> {
while (true) {
const tx = await fetchTransaction(id);
if (['COMPLETED', 'REJECTED', 'FAILED'].includes(tx.status)) {
return tx;
}
await sleep(5000); // Wait 5 seconds
}
}
Event-Driven Approach:
- Subscribe to Link Tracker events
- Filter by transaction ID
- React to status changes in real-time
How do I handle transaction failures?
-
Check Transaction Status:
- GET /transactions/:id
- Review status and error details
-
Common Failure Reasons:
- Insufficient balance
- Invalid blockchain address
- Network errors
- Screening rejection
-
Recovery:
- For FAILED withdrawals: Balance automatically refunded
- For REJECTED transactions: Customer notified
- Retry logic for network errors
Can I cancel a transaction?
Pending/Screening Transactions: Not currently supported (transactions process quickly)
Frozen Transactions: Can be rejected via API:
- Deposits: POST
/transactions/:id/reject-frozen-deposit - Withdrawals: POST
/transactions/:id/reject-frozen-withdrawal
Approved/Completed Transactions: Cannot be cancelled (use reversal transaction if needed)
How do I create a new digital asset?
POST /assets
{
"code": "ETH",
"name": "Ethereum",
"decimals": 18,
"blockchain": "ethereum",
"contractAddress": "0x..."
}
Required for:
- Adding new blockchain support
- Supporting new tokens
- Custom digital asset definitions
What happens if the external screening system is unavailable?
- Transactions remain in PENDING status indefinitely
- No automatic retry (webhook pattern - external system must call back)
- Manual intervention options:
- External system can call
/transactions/complete-screeningwhen back online - Admins can manually approve/reject via freeze endpoints
- External system can call
- Monitor PENDING transactions for extended delays
Troubleshooting
Transaction stuck in PENDING status
Causes:
- External screening system hasn't called back yet
- External screening system unavailable
- Webhook endpoint not reachable from external system
- External system configuration issue
Solution:
- Check external screening system status
- Verify webhook endpoint is accessible
- Review Link Tracker logs for "Starting AML verification"
- Manually complete screening via webhook endpoint if needed
- Contact external screening system administrator
Balance mismatch
Causes:
- Concurrent transaction processing
- Database replication lag
- Failed transaction not rolled back
Solution:
- Check transaction history
- Review all transactions for customer/account
- Verify ledger entries
- Contact support if issue persists
Withdrawal not executing
Causes:
- Transaction frozen for review
- Insufficient omnibus balance
- Wallet Manager service down
- Invalid destination address
Solution:
- Check transaction status
- Verify omnibus balances
- Check Wallet Manager service health
- Validate destination address format
Support & Maintenance
What support is available?
- Documentation: Comprehensive guides and API reference
- Email Support: helpdesk@ledgerlink.ai
- JIRA: Report bugs and request features
- Development Team: Contact for technical assistance
How do I report a bug?
- Check existing JIRA tickets
- Gather information:
- Steps to reproduce
- Expected vs actual behavior
- Relevant log output
- Transaction IDs (if applicable)
- Create JIRA task or email helpdesk@ledgerlink.ai
How do I run Link Core locally?
# Install dependencies
npm install
# Start PostgreSQL
npm run docker
# Run migrations
npm run migration:run
# Start development server
npm run start:dev
Access Swagger docs at http://localhost:3000/api
Still have questions? Contact helpdesk@ledgerlink.ai or create an issue in the GitHub repository.