# SAL Extension and Migration **Purpose:** State & Accounting Ledger (SAL) extension: positions (asset x chain), fees, reconciliation snapshots. ## Schema - **sal_positions:** `(account_id, asset, chain_id)` → balance. Inventory per account per asset per chain. - **sal_fees:** `reference_id`, `chain_id`, `tx_hash`, `fee_type`, `amount`, `currency_code`. Gas and protocol fees. - **sal_reconciliation_snapshots:** `account_id`, `asset`, `chain_id`, `sal_balance`, `on_chain_balance`, `discrepancy`, `status`. On-chain vs SAL comparison. ## Migration Run the SAL migration after existing ledger migrations: ```bash export DATABASE_URL="postgresql://user:password@host:port/database" psql $DATABASE_URL -f db/migrations/006_sal_positions_fees.sql ``` Or run in order with other migrations (see [db/migrations/README.md](../../db/migrations/README.md)). ## Usage - **SalReconciliationService** ([src/core/ledger/sal-reconciliation.service.ts](../../src/core/ledger/sal-reconciliation.service.ts)): - `upsertPosition({ accountId, asset, chainId, balance })` — upsert position. - `recordFee({ referenceId, chainId, txHash?, feeType, amount, currencyCode? })` — record a fee. - `getPosition(accountId, asset, chainId)` — get balance. - `reconcile(input, fetcher?)` — compare SAL to on-chain; optional `OnChainBalanceFetcher(chainId, address, asset) => Promise`. - `listPositions(accountId, chainId?)`, `listFees(referenceId)`. Reconciliation can be driven by EII (Event Ingestion + Indexing) once on-chain balance fetcher is wired (e.g. from multi-chain-execution chain adapters).