Skip to content

feat: add asset reconciliation endpoint#3494

Merged
TaprootFreak merged 15 commits intodevelopfrom
feature/asset-reconciliation-endpoint
Mar 27, 2026
Merged

feat: add asset reconciliation endpoint#3494
TaprootFreak merged 15 commits intodevelopfrom
feature/asset-reconciliation-endpoint

Conversation

@TaprootFreak
Copy link
Copy Markdown
Collaborator

Summary

  • New read-only admin endpoint GET /balance/reconciliation?assetId=X&from=DATE&to=DATE for auditing asset balances
  • Verifies the equation startBalance + inflows - outflows = endBalance for any asset over a given period
  • Supports three asset categories: Blockchain (LM orders, payout orders, crypto inputs, exchange withdrawals), Exchange (deposits, withdrawals, trades base/quote side, fees), Bank (credits/debits by IBAN)
  • Deduplicates LM deficit orders vs exchange withdrawals using correlation IDs
  • Balances extracted from FinancialDataLog snapshots; also adds reusable getFinancialLogAt() to LogRepository
  • Protected with RoleGuard(UserRole.DEBUG), excluded from Swagger docs

Test plan

  • Query GET /balance/reconciliation?assetId=113&from=2026-03-01&to=2026-03-21 (Bitcoin/BTC) — difference should be ~-0.00063 BTC
  • Query for an exchange asset (e.g. Binance/USDT, assetId=287)
  • Query for a bank asset (e.g. Yapeal/CHF, assetId=404)
  • Verify non-admin users get 403

🤖 Generated with Claude Code

Add read-only admin endpoint GET /balance/reconciliation that verifies
start + inflows - outflows = end for any asset over a given period.
Supports blockchain, exchange, and bank assets with LM deduplication.
…trades

- Bank flows: query by tx.accountIban instead of batch.iban (most bank_tx
  records link to the account IBAN directly, not via batch)
- Exchange trades: parse symbol field (e.g. "BTC/USDT") as fallback when
  currency/pair are null (Binance trade format)
- Filter out Lightning Network withdrawals (lnbc* addresses) from
  blockchain inflow calculation — these don't hit the on-chain wallet
- Track withdrawal/deposit fees as exchange outflows (not just trade fees)
  to capture network fees deducted by exchanges like Binance
Use only liquidityBalance.total for balance snapshots, falling back to 0
if missing. The previous liquidity.total fallback included paymentDeposit
balances which would produce inconsistent reconciliation results.
- Add @apitags('Balance') to ReconciliationController
- Add DfxLogger with warning on financial log parse failures
- Parameterize NOT LIKE pattern in QueryBuilder
@TaprootFreak TaprootFreak marked this pull request as ready for review March 21, 2026 23:30
Group flows by counter-account (exchange/customer), resolve LM order
correlationIds to blockchain txIds via ExchangeTx lookup, filter
zero-amount groups, and sub-group bank flows by transaction type.
Parse destinationSystem from LM action params when system is DfxDex,
so counter-account shows Binance/BTC instead of DfxDex/BTC.
…thdrawals

Resolves Binance/BTC showing itself as counter-account. Deposits and
withdrawals now correctly reference Bitcoin/BTC (the blockchain wallet).
USDT → Binance/USDT, WBTC → Binance/WBTC for proper account names.
Filter by uniqueName LIKE '%/BTC' to exclude DeFiChain/dBTC, and
order by ID to prefer Bitcoin/BTC over Lightning/BTC.
New endpoint GET /balance/reconciliation/overview runs reconciliation
for all assets, showing start/end balance, inflows, outflows, and
unexplained differences per account.
Prevents ETH withdrawals to Ethereum mainnet from being counted as
inflows for Arbitrum/ETH, Optimism/ETH, etc. Uses blockchain-specific
wallet addresses from environment variables to filter.
@github-actions
Copy link
Copy Markdown

❌ ESLint: 2 errors, 1 warnings

@TaprootFreak TaprootFreak merged commit 6ae2141 into develop Mar 27, 2026
8 checks passed
@TaprootFreak TaprootFreak deleted the feature/asset-reconciliation-endpoint branch March 27, 2026 15:00
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