Skip to content

Latest commit

 

History

History
186 lines (143 loc) · 6.91 KB

File metadata and controls

186 lines (143 loc) · 6.91 KB

CLI Reference

fetcher is the binary that drives the whole system. It fetches live exchange rates from external APIs, computes cross rates for every supported currency, and writes a tree of static JSON files ready to be deployed to a CDN.


How the data flows

            ┌─────────────────────┐
            │   data/currencies   │  master list of supported currencies
            │   data/crypto_ids   │  maps code → CoinGecko ID
            └────────┬────────────┘
                     │
          ┌──────────▼──────────┐
          │   sources/fiat.rs   │  GET fiat API        → EUR-based fiat rates
          │   sources/crypto.rs │  GET CoinGecko       → EUR-based crypto rates
          │   sources/metals.rs │  GET metalpriceapi   → EUR-based metal rates (optional)
          └──────────┬──────────┘
                     │ merge
          ┌──────────▼──────────┐
          │    normalize.rs     │  computes cross rates for every currency pair
          └──────────┬──────────┘
                     │ write
          ┌──────────▼──────────┐
          │     generate.rs     │  writes dist/v1/ file tree
          └─────────────────────┘

Every rate in the system is first normalized to EUR as the base. To convert between any two currencies A → B, the formula is:

rate(A → B) = eur_rate[B] / eur_rate[A]

This applies to every supported type — fiat, crypto, and precious metals. For example, rate(XAU → BRL) = eur_rate[BRL] / eur_rate[XAU].

This lets us derive all ~40,000 currency pairs from a single EUR-based map.


Building

cargo build --release

The binary will be at ./target/release/fetcher.


Usage

fetcher [OPTIONS]

Options:
  --output <DIR>                   Output directory              [default: dist]
  --date <YYYY-MM-DD|YYYY-MM-DDTHH:MM>  Override snapshot datetime  [default: current UTC clock]
  --dry-run                        Fetch data but skip writing files
  -h, --help                       Print help

Examples

Normal daily run

cargo run --release

Fetches live rates and writes everything to dist/v1/.

Dry run — test your API keys without writing files

cargo run -- --dry-run

Useful for verifying your environment variables are correct before deploying.

Custom output directory

cargo run --release -- --output /tmp/my-output

Backfill a specific date

cargo run --release -- --date 2026-01-15

Stamps each output file with "date": "2026-01-15". No timestamp field is included — output is identical to the old format. Useful for backfills.

Sub-daily snapshot (date + timestamp)

cargo run --release -- --date 2026-03-07T14:30

Stamps output with both "date": "2026-03-07" and "timestamp": "2026-03-07T14:30:00Z". This is the format used by sub-daily.yml in GitHub Actions.

No --date flag (default)

cargo run --release

Uses the current UTC clock. Produces both date and timestamp fields automatically.

Enable debug logging

RUST_LOG=debug cargo run -- --dry-run

Output file tree

After a successful run, dist/ will look like this:

dist/
└── v1/
    ├── currencies.json          # full list: { "usd": "US Dollar", ... }
    ├── currencies.min.json      # same, minified
    ├── countries.json           # country data (copied from data/ if present)
    └── currencies/
        ├── eur.json             # { "date": "...", "timestamp": "...", "eur": { "usd": 1.08, ... } }
        ├── eur.min.json
        ├── usd.json
        ├── usd.min.json
        └── ...                  # one pair per supported currency

The entire dist/ directory is what gets deployed to Cloudflare Pages.


Environment variables

The CLI reads these at startup. Set them in your shell for local runs or as GitHub secrets for CI (see SETUP.md).

Variable Required Default Description
FIAT_API_URL No https://open.er-api.com/v6/latest/EUR EUR-based fiat endpoint. Supports {key} placeholder (e.g. https://v6.exchangerate-api.com/v6/{key}/latest/EUR). Must use EUR as base.
FIAT_API_KEY No (none) Substituted into {key} in FIAT_API_URL, or sent as Bearer header if no placeholder is present
CRYPTO_API_URL No https://api.coingecko.com/api/v3/simple/price CoinGecko-compatible price endpoint
CRYPTO_API_KEY No (none) x-cg-demo-api-key header value
METALS_API_URL No https://api.metalpriceapi.com/v1/latest?base=EUR&currencies=XAU,XAG,XPT,XPD Precious metals endpoint (metalpriceapi.com-compatible)
METALS_API_KEY No (none) X-API-KEY header value. If not set, metals are silently skipped

Local run with API keys

Copy .env.example to .env, fill in your keys, then:

source .env && cargo run --release

Adding a new currency

  1. Open data/currencies.json and add the entry:
    "xyz": "My New Currency"
  2. Depending on the type:
    • Cryptocurrency — also open data/crypto_ids.json and map its CoinGecko ID:
      "xyz": "my-new-currency-coingecko-id"
      You can find the CoinGecko ID at https://www.coingecko.com — it is the slug in the coin's URL, e.g. coingecko.com/en/coins/bitcoinbitcoin.
    • Precious metal — ensure METALS_API_KEY is set and the metal's ISO code (e.g. XAU) is included in the currencies query parameter of METALS_API_URL. The default URL already includes XAU, XAG, XPT, and XPD.
    • Fiat currency — no extra config needed; the fiat API returns it automatically.
  3. Rebuild and run. The new currency will appear in the output automatically.

Removing a currency

Delete its entry from data/currencies.json (and data/crypto_ids.json if applicable). It will be excluded from the next run.