# AGENTS

- Cashu TS is a TypeScript library for Cashu wallets and mint interactions.
- Public API surface is defined in `src/index.ts` and built for ESM.
- Docs and examples live in `docs-src/` and `examples/`.

## Quickstart (local dev)

```bash
npm ci
# optional for integration tests
npm run test:prepare
```

Node requirement: see `package.json` (currently `>=22.4.0`).
Local installs configure Husky hooks automatically.

## Repo map

- `src/` core library source
  - `auth/` OIDC auth helpers
  - `crypto/` cryptographic primitives
  - `logger/` library logger interface and ConsoleLogger
  - `mint/` mint client logic and request/response types
  - `model/` shared domain models, tokens, proofs, errors
  - `transport/` HTTP/WebSocket transport, request helpers
  - `utils/` various helpers (cbor, base64, bech32, Bytes etc)
  - `wallet/` wallet logic, WalletOps builders, counters, events
- `test/` unit + integration tests; `test/integration.test.ts` is a good live usage reference
- `examples/` runnable examples and usage patterns
- `docs-src/` contributor docs and usage recipes (rendered on docs site)
- `lib/` build output (generated)
- `etc/` API Extractor reports (generated/updated when public API changes)

## Entry points and API surface

- `src/index.ts` exports the public API.
- The build emits:
  - ESM runtime: `lib/**/*.js` (relative imports must include `.js`)
  - Types: `lib/types/index.d.ts` (rolled up)

## Generated artifacts (do not hand-edit)

- `lib/` build output.
- `etc/cashu-ts.api.md` API Extractor report (update via `npm run api:update`).
- `coverage/` test coverage output (generated by `npm test` / `npm run test-integration`).

## Common tasks

CI check: `npm run prtasks` (lint, format, api:update, tests).
Repo-wide lint checks: `npm run check-lint` and `npm run check-format`.
Integration tests: `npm run test-integration` (requires local mint, see below).
Consumer smoke tests: `npm run test:consumer`.
Other scripts: see `package.json`.

## Day-to-day commands

- `npm run dev` for TypeScript watch mode.
- `npm run compile` to build ESM output.
- `npm test` for unit/browser test projects.
- `npm run lint` / `npm run format` for local fixes.
- `npm run api:update` for compile + api-extractor report update

## Integration tests (local mint)

Integration tests expect a local mint at `http://localhost:3338`.
Use the Makefile targets (Docker required):

```bash
DEV=1 make cdk-stable-up
# or
DEV=1 make nutshell-stable-up

npm run test-integration

DEV=1 make cdk-stable-down
# or
DEV=1 make nutshell-stable-down
```

## Coding guidelines for PR submissions

- Avoid breaking API changes unless the change targets next major version.
- Commit messages follow Conventional Commits; template in `.gitmessage`.
- Test naming: files with `.node.` run only in Node; `.browser.` would run in browser.
- Keep changes scoped; one concern per PR.
- Prefer the smallest reasonable diff that fully fixes the bug.
- Match the existing local style and abstraction level before introducing new structure.
- Prefer clear, boring code over clever tricks.
- Be explicit about errors; fail fast with actionable messages.
- Make invalid states unrepresentable (model with types).
- Optimize for readability over micro-performance.
- Prefer early exits and flatter structures to avoid deep if/else nesting.
- Do not add one-off helpers, new type aliases, exported types, or wider public API signatures unless they are clearly justified.
- If a broader refactor seems better than a local fix, explain the tradeoff first.
- If it's not "Zen" (PEP 20) in spirit, then don't do it.

## Linting and TypeScript rules

- Lint config lives in `eslint.config.js` (flat config).
- `any` is not allowed (prefer explicit types, generics, or `unknown` with narrowing).
- Type-only imports/exports are required (`@typescript-eslint/consistent-type-imports`).
- No Node-only modules in library code (`import/no-nodejs-modules`).
- Empty functions are disallowed (`@typescript-eslint/no-empty-function`).
- Prefer short-form array types like `string[]` (`@typescript-eslint/array-type`).
- Avoid `else` after `return` for flatter control flow (`no-else-return`).

## Hooks and commit hygiene

Hooks are installed by Husky:

- `commit-msg` enforces Conventional Commits.
- `pre-commit` runs `lint-staged` on staged files.
- `pre-push` runs `npm run check-lint` and `npm run check-format`.

## If you are making changes (author flow)

1. Start with the public surface: check `src/index.ts` for exports and types.
2. Keep changes tight and scoped; follow patterns in `src/wallet/`, `src/mint/`, `src/model/`.
3. Public API changes: run `npm run api:update` and commit `/etc/cashu-ts.api.md`.
4. Update docs/usage examples if the API behavior changes (`docs-src/usage/*`).
5. Run `npm run prtasks`; run `npm run test-integration` if behavior depends on a mint.

## PR review flow (reviewer)

1. Confirm scope: one concern per PR; avoid unrelated edits.
2. Public API changes: check `src/index.ts` and the diff in `/etc/cashu-ts.api.md`.
3. Tests: ensure new behavior is covered; check for `.node.`/`.browser.` naming if relevant.
4. Docs: verify usage recipes/examples if API shape or behavior changed.
5. Build/runtime: ensure ESM expectations are met (relative `.js` in ESM builds).

## Amount model (v4 breaking change)

- `Proof.amount` is `bigint`, not `number`. This changed in v4.
- `AmountLike` (`number | bigint | string | Amount`) is the flexible input type for consumers.
- `Amount` (`src/model/Amount.ts`) is the normalization and arithmetic layer. Use `Amount.from(x)` to convert any `AmountLike`, `.toBigInt()` to extract the raw value.
- Mint response DTOs are normalized to `Amount` before reaching consumers — API response amount fields return `Amount` objects, not raw numbers.
- When constructing `Proof` objects, always normalize: `amount: Amount.from(x).toBigInt()`.
- Avoid `number` in canonical domain models and avoid `bigint | number` in stored/core types.

## Branching and releases

- `main` is the active development branch (v4).
- `v3-dev` is the maintenance branch for v3 backports.
- Releases are automated with release-please; do not cut releases manually.

## Common pitfalls (save time)

- Switching `main` ↔ `v3-dev`: run `npm ci` after checkout to refresh dependencies.
- Integration tests expect port `3338`; ensure no other service is bound.
- API Extractor only updates with `npm run api:update`; `api:check` is read-only.
