--- 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