---
epic: 3
story: 3.1
title: "Fiat Currency Provider"
status: draft
---

## Epic 3 — Currency & Cryptocurrency
**Goal:** Real-time and historical currency conversion with 180+ fiat and 50+ crypto.

### Story 3.1: Fiat Currency Provider

As a CalcPad user,
I want live exchange rates for 180+ fiat currencies that are cached locally for offline use,
So that currency conversions are accurate and available even without internet.

**Acceptance Criteria:**

**Given** the engine is initialized with network access
**When** currency rates are requested for the first time
**Then** it fetches live rates from the configured provider (Open Exchange Rates or exchangerate.host)
**And** the rates cover at least 180 fiat currencies

**Given** rates have been fetched successfully
**When** the rates are stored
**Then** they are cached locally on disk with a timestamp
**And** the cache includes the provider name and base currency

**Given** cached rates exist and are less than the configured staleness threshold (e.g., 1 hour)
**When** currency conversion is requested
**Then** the cached rates are used without a network call

**Given** the device is offline
**When** a currency conversion is requested
**Then** the engine uses the most recent cached rates
**And** the result metadata indicates "offline -- rates from [timestamp]"

**Given** a successful rate fetch
**When** the result is displayed to the user
**Then** metadata includes "rates updated [relative time, e.g., '5 minutes ago']"

**Given** the rate provider API is unreachable and no cache exists
**When** a currency conversion is requested
**Then** the engine returns a `CalcResult::Error` indicating rates are unavailable
**And** non-currency calculations on the sheet are unaffected
