# 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<string>`.
  - `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).
