# MVP Crypto Wallet Ledger Core (Tasks 17–21)

Use this reference when extending the FinanceManager crypto subsystem before any real coin/wallet file is mapped or imported.

## Safety boundary

- Use only synthetic fixtures until the crypto core, mapper, and dry-run flow are verified.
- Do not import or inspect real wallet/coin files during core implementation.
- Do not commit wallet addresses, exchange exports, portfolio CSVs, PDFs, DBs, runtime data, or credentials.
- Real crypto files are initial-snapshot/mapping inputs only after explicit user approval and a dry-run importer exists.

## Wallets

- Wallet name is unique.
- Wallet address is optional; tests/fixtures must not contain real addresses.
- Valid wallet types: `Hardware Wallet`, `Software Wallet`, `Exchange`, `Bank/Broker`, `DeFi`, `Sonstiges`.
- Wallet create/update/deactivate actions should be auditable.

## Crypto assets

- CoinGecko ID is strongly recommended but not hard-required.
- Missing CoinGecko ID creates a data-quality warning because valuation cannot be reliable.
- Symbol alone is not unique; symbol conflicts should create a warning/manual-selection requirement rather than silently merging assets.

## Initial holdings

- Initial crypto holdings are confirmed snapshots, not fabricated trade history.
- Calculate/control holdings by wallet + asset from initial snapshots plus crypto transactions; do not silently overwrite current holdings.
- Store legacy snapshot values for provenance/control only. Never use legacy values as current valuation.
- Track `verification_status`: `verified`, `stale`, `unverified`, `estimated`.
- Store/consider `last_verified_at`.

## Transfers

- Transfer requires source wallet, target wallet, same asset, and quantity > 0.
- Source and target wallet must differ.
- TxHash is optional.
- Coin fee is optional and reduces the source-wallet coin balance when paid in the transferred coin.
- Negative wallet balance should be blocked, or only allowed as an explicit confirmed correction with critical alert. MVP blocks and raises critical alert.
- Confirmed transfers create audit entries.

## Buy/sell with ledger coupling

- Crypto buy/sell with fiat/CHF impact must create or reference a general ledger transaction.
- Use `source_type='crypto'` and `source_id=<crypto_transaction_id>` to keep cash ledger consistency.
- Buy increases target wallet balance.
- Sell reduces source wallet balance.
- Foreign currency requires FX; if missing, set `fx_status='missing'` and `quality_status='incomplete'`, and create a critical data-quality alert.
- Do not automatically import real exchange data in this block.

## Fees

- Coin fee reduces coin balance.
- Fiat fee is represented in the general ledger as a fee transaction when the fee currency is clear.
- Store fee currency explicitly.
- Avoid double counting: if sell net amount already includes fee, do not create a second fee ledger row for the same economic fee.
- Unclear fee currency creates a data-quality warning rather than inventing treatment.
- Fee history must be traceable through crypto transaction, ledger transaction where applicable, and audit/log entries.

## Tests to preserve

At minimum cover:

- wallet create/read/update/deactivate and duplicate-name rejection
- asset with CoinGecko ID
- asset without CoinGecko ID warning
- symbol conflict warning/manual selection
- initial holdings per wallet and aggregate by asset
- legacy snapshot value not used as current valuation
- transfer, transfer with coin fee, same-wallet rejection, overdraft block/critical alert
- buy/sell create ledger links and update wallet balances
- coin fee reduces balance
- fiat fee creates general ledger fee when unambiguous
- confirmed crypto actions create audit entries
- missing FX marks ledger incomplete
