Skip to main content

Frequently Asked Questions

General Questions​

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

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:

  1. Transaction Created:

    • Transaction enters PENDING status
    • Link Core logs "Starting AML verification"
    • Transaction awaits external screening
  2. 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
  3. Screening Callback:

    • External system calls POST /transactions/complete-screening
    {
    "id": "transaction-id",
    "isApproved": true/false,
    "screeningData": { /* screening details */ }
    }
  4. Link Core Processes Result:

    • If approved: Transaction queued for processing
    • If rejected: Status changed to FROZEN for manual review
  5. 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​

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:

  1. Request validated
  2. Balance checked
  3. Transaction created (PENDING)
  4. Sent to screening
  5. If approved → Blockchain transaction initiated
  6. 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

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?​

  1. Check Transaction Status:

    • GET /transactions/:id
    • Review status and error details
  2. Common Failure Reasons:

    • Insufficient balance
    • Invalid blockchain address
    • Network errors
    • Screening rejection
  3. 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-screening when back online
    • Admins can manually approve/reject via freeze endpoints
  • 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?​

  1. Check existing JIRA tickets
  2. Gather information:
    • Steps to reproduce
    • Expected vs actual behavior
    • Relevant log output
    • Transaction IDs (if applicable)
  3. Create JIRA task or email helpdesk@ledgerlink.ai
# 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.