Skip to content

Repository files navigation

sure-eb-ingest

A sidecar that feeds a self-hosted Sure instance with bank transactions from Enable Banking (PSD2 access to Nordea SE).

Generic bank feeds land in Sure with a useless generic name while the actual merchant hides in the transaction details. This sidecar fetches the raw bank data itself and extracts a proper human-readable name (KORTKÖP 260718 ICA SUPERMARKET ARSTAICA SUPERMARKET ARSTA) before ingesting into Sure, preserving the full original details in the transaction notes.

             (4x/day max, PSD2)                    (idempotent)
Nordea SE ──► Enable Banking API ──► fetch ──► raw JSON dumps ──► ingest ──► Sure API
                                               $STATE_DIR/raw    name extraction

fetch pulls transactions (and balances) for every authorized account and writes them unmodified to disk — the only step that talks to the bank (PSD2 background access allows ~4 fetches/day). ingest maps each dump (name extraction, merchant, expense/income) and POSTs it to Sure; external_id (derived from the immutable entry_reference + account identification_hash) makes re-ingestion idempotent.

Quick start

  1. Register an application in the Enable Banking Control Panel (environment PRODUCTION, or SANDBOX to try it out), whitelist your redirect URL, and save the private key as secrets/enablebanking.pem.

  2. In Sure, create a read_write API key (Settings → API Keys).

  3. cp .env.example .env and fill in EB_APP_ID, EB_REDIRECT_URL and SURE_API_KEY.

  4. Authorize with the bank (interactive BankID, repeat every ~180 days):

    sure-eb-ingest auth
    sure-eb-ingest fetch -strategy longest   # right after auth: grab the full history window

    If the redirect can't reach the machine, copy the URL you landed on and run sure-eb-ingest auth -code '<full redirect URL>'.

  5. Map bank accounts to Sure accounts: sure-eb-ingest map prints both sides plus a ready SURE_ACCOUNT_MAP template for .env.

  6. Run:

    sure-eb-ingest run   # sidecar loop: fetch + ingest every FETCH_INTERVAL (default 6h)

sure-eb-ingest help lists all commands (auth, accounts, fetch, preview, ingest, run, aspsps, sure-accounts, map, app, version). Every setting is documented in .env.example and config.example.yaml; the environment wins over the file, so secrets can stay in the deployment env.

Merchants and loans

Ingest registers the extracted counterparty as a Sure merchant and attaches it — only where the payment type actually has one (card purchases, giro billers, Swish business; person-to-person Swish, own transfers and fees get none). Trailing store numbers are stripped so PRESSBYRAN 5121 and 5240 group as one merchant. Disable with SURE_MERCHANTS=false; upgrade pre-merchant history once with ingest -backfill-merchants.

SURE_LOAN_MAP=<merchant>=<sure-loan-uuid> mirrors expenses to that merchant into the loan account, and Sure's transfer matching links them as loan payments. The full payment reduces the balance (PSD2 has no interest/principal breakdown), so this only suits interest-free debts.

For interest-bearing loans, use amortizations in the config file instead: it posts one idempotent fixed principal entry per month from start onward, so history backfills itself. The entries are inflows on the loan, which Sure counts as income — pair each schedule with a Sure rule (Settings → Rules): name = <schedule name>Exclude from budgeting and reports, effective at or before start. Don't use the account-level "exclude from reports" toggle — it also removes the loan from net worth.

Deployment

See docker-compose.example.yml; build with make docker, run the interactive auth via docker compose run --rm --service-ports eb-ingest auth. Session state and raw dumps live under /data — keep that volume persistent. When consent expires, fetches fail with EXPIRED_SESSION/REVOKED_SESSION: re-run auth, then fetch -strategy longest (the bank only exposes >90 days of history right after fresh authentication).

Development

Everything runs inside the devcontainer (.devcontainer/):

make up      # create/start the devcontainer (needs @devcontainers/cli)
make check   # formatting + linters + race tests + build
make build   # bin/sure-eb-ingest

About

Enable Banking → Sure ingestion sidecar

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages