Contributing
Currencyinfo is open source under the GPL-3.0 License and maintained by the ADAMANT developer community. Contributions are welcome from anyone.
The authoritative contributor guide is CONTRIBUTING.md in the repository. This page is the orientation version.
What changes protect
Changes must preserve, in this order:
- Calculation accuracy — rate precision, pair direction, inverse triangulation
- Merging reliability — deterministic behaviour under provider outages and disagreement
- Security — no credential ever reaches a log, an error payload, or a commit
- Contributor clarity — modular NestJS structure, typed code, tests that describe behaviour
Everything in the repository is written in English: code, comments, documentation, commits, issues, and pull requests.
Development setup
git clone https://github.com/Adamant-im/currencyinfo.git
cd currencyinfo
git switch dev
pnpm install --ignore-scripts
pnpm run deps:setup
cp config.default.jsonc config.jsonc--ignore-scripts is not optional. It blocks lifecycle scripts across the whole dependency tree; deps:setup then rebuilds @swc/core alone, which is the one package that genuinely needs a native build step.
The allow-list lives in pnpm-workspace.yaml, where allowBuilds records an explicit true or false for every dependency that ships an install script. pnpm 12 fails the install while any of them is undecided, so a new one has to be reviewed and answered rather than silently inherited.
A local MongoDB for development:
docker compose up -dThen run the service with file watching, which prefers config.test.jsonc and falls back to config.default.jsonc:
pnpm run start:devValidation
Run all four before opening a pull request, and report the results in the description:
pnpm run build
pnpm test
pnpm run lint
pnpm run format:checkpnpm test needs Node.js 24.9 or newer, which is stricter than the 22.12 the service itself runs on. NestJS 12 publishes ES modules only, and Jest can load them from a CommonJS test only where vm.SourceTextModule.prototype.hasAsyncGraph exists — hence the --experimental-vm-modules flag the test scripts already pass. The compiled application is unaffected: it reaches the same packages through Node's own require(esm), available since 22.12.
For documentation changes, also:
pnpm run docs:builddocs:build fails on a dead internal link, which is the check that keeps this site honest.
Pull requests must include tests for new features and bug fixes. Tests live beside the code they cover as *.spec.ts.
Working on the documentation
The site lives in docs/ and is a VitePress project.
pnpm run docs:dev # local server with hot reload
pnpm run docs:build # production build, fails on dead internal links
pnpm run docs:preview # serve the built output| Path | Contents |
|---|---|
docs/.vitepress/config.mts | Site config, navigation, sidebar, search |
docs/index.md | Home page |
docs/guide/ | Narrative documentation |
docs/reference/ | API, configuration, and per-source reference |
docs/project/ | Contributor and project pages |
docs/public/ | Static assets and the Pages CNAME |
Rules that apply to every page:
- documentation follows the code. If they disagree, the code is right and the page is a bug
- an option documented here must exist in
src/global/config/schema.tsand inconfig.default.jsonc - credentials in examples must be unmistakably synthetic. Never paste a real webhook URL, key, or passphrase
- adding a page means adding it to the sidebar in
docs/.vitepress/config.mts - follow the Markdown conventions in
AGENTS.md: a blank line around every list, a language tag on every fenced block, and no trailing period on a single-sentence list item
Every page carries an "Edit this page on GitHub" link that opens the right file.
Branches and pull requests
- base your work on
devand targetdev.masterrepresents stable releases - name branches by type:
feat/short-description,fix/…,docs/…,chore/… - use Conventional Commits style for the PR title:
Type: Short summary, for exampleFeat: Add support for new fiat provider - issue-style prefixes such as
[Docs]are for issues, not for PR titles - link the issue with a closing keyword:
Closes #123 - follow the PR template:
Description,Related issue,Breaking changes,How to test,Notes for reviewers,Checklist
Keep pull requests focused. Unrelated refactoring and formatting churn make review harder and are usually asked to be split out.
Adding a rate source
A new connector is the most common substantial contribution. What it takes:
- a class in
src/rates/sources/api/extendingBaseApi, orCoinIdFetcherwhen the provider needs coin discovery - registration in
src/rates/sources/sources-manager.ts - a schema entry in
src/global/config/schema.ts, including any cross-field rule the source needs - a documented block in
config.default.jsonc, with the terms and the quota spelled out - a
*.spec.tscovering the success path, a malformed response, and the failure mode - a page under
docs/reference/sources/, plus rows in the source index tables
Design rules the existing connectors follow:
- emit
<COIN>/USDpairs. USD is the pivot; the merger triangulates everything else - never throw for a condition the operator cannot fix this cycle. Disable the source and alert once, as Binance does for a geo-block
- verify provider identifiers. IDs get reassigned and symbols collide; both have caused real incidents
- document the quota and derive the safe
refreshIntervalfrom it - state the redistribution terms explicitly if keyless access does not include them
Dependencies
- install with
pnpm install --ignore-scripts, never with--ignore-scripts=false - review package names, maintainers, release dates, and lifecycle scripts before adding or updating anything
- keep
pnpm-lock.yamlcommitted and synchronized - answer
allowBuildsinpnpm-workspace.yamlfor any dependency that arrives with an install script, and deny it unless the build is genuinely required - revisit
overridesinpnpm-workspace.yamlon every dependency update, and drop an override once the tree resolves to the patched version without it
Reporting issues
Search existing issues first, then open one with a prefix such as [Bug], [Feat], [Enhancement], [Docs], [Test], or [Chore].
Include the version from /status, how it is deployed, the relevant log lines, and your configuration with every credential redacted.
Security issues go privately to devs@adamant.im instead — see security.
Financial contribution
Cryptocurrency donations are welcome at ADAMANT Donate.
