Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 120 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Contributing to Freighter Backend (V1)

TypeScript backend service powering the Freighter wallet. Provides indexing,
subscriptions, feature flags, notifications, token balances, and pricing data.

For the Stellar organization's general contribution guidelines, see the
[Stellar Contribution Guide](https://github.com/stellar/.github/blob/master/CONTRIBUTING.md).

## Prerequisites

| Tool | Version | Install |
| ------ | --------- | ------------------------------------------------------------ |
| Node.js | >= 25.3.0 | [nodejs.org](https://nodejs.org) or `nvm install 25` |
| Yarn | >= 1.22.5 | `npm install --global yarn` |
| Docker | Latest | [docker.com](https://docs.docker.com/get-docker/) (for Redis) |

## Getting Started

### Quick Setup with an LLM

If you use an LLM-powered coding assistant, you can automate the setup. The repo
includes a quick start guide ([`LLM-QUICK-START.md`](LLM-QUICK-START.md)) that
checks your environment, installs missing tools, configures `.env`, and verifies
the build.

Point your LLM assistant at `LLM-QUICK-START.md` and ask it to follow the steps.

If you don't use an LLM assistant, follow the manual setup below.

### Manual Setup

```bash
git clone https://github.com/stellar/freighter-backend.git
cd freighter-backend
cp .env-EXAMPLE .env # Then fill in values (see below)
yarn install
yarn start # Dev mode (uses in-memory store, no Redis needed)
```
Comment on lines +32 to +38

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docker compose up -d + cp .env-EXAMPLE .env is described as a working starting point, but the runtime env validation currently requires additional keys that are not present in .env-EXAMPLE (e.g. FREIGHTER_RPC_PUBNET_URL and FREIGHTER_TRUST_PROXY_RANGE in src/config.ts). As written, a fresh clone will error on startup unless the contributor adds those variables. Please document the missing required variables here (or update .env-EXAMPLE in the same PR) so the manual setup is actually runnable.

Copilot uses AI. Check for mistakes.

For production mode (requires Redis):

```bash
docker compose up -d # Starts Redis Stack on port 6379
yarn build:prod
node build/index.js
```

### Environment Variables

Copy `.env-EXAMPLE` to `.env`. For local development with `yarn start`, most
variables can be left as `not-set` — the app uses an in-memory store by default.

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implies most variables can remain not-set for yarn start, but at least FREIGHTER_TRUST_PROXY_RANGE must be empty or a valid proxy-addr range (a literal not-set will be treated as configured and can crash startup). It would help to list any exceptions explicitly so a straight copy of .env-EXAMPLE leads to a bootable dev setup.

Suggested change
variables can be left as `not-set` the app uses an in-memory store by default.
variables can remain `not-set` because the app uses an in-memory store by
default. **Exception:** `FREIGHTER_TRUST_PROXY_RANGE` must be left empty or set
to a valid proxy-addr range such as `127.0.0.1/32` for local dev; do not leave
it as the literal string `not-set`.

Copilot uses AI. Check for mistakes.

**Required for full functionality:**

| Variable | Purpose | How to obtain |
| ------------------- | ---------------------------------------------- | ----------------------------------- |
| `MODE` | `development` or `production` | Set to `development` for local dev |
| `HOSTNAME` | Server hostname | `localhost` |

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HOSTNAME is described as the server hostname, but in the current code it’s used as the Redis host (and passed into Redis-backed workers). Consider renaming the description to something like “Redis hostname”/“Redis host” to avoid contributors setting this incorrectly.

Suggested change
| `HOSTNAME` | Server hostname | `localhost` |
| `HOSTNAME` | Redis hostname | `localhost` |

Copilot uses AI. Check for mistakes.
| `REDIS_PORT` | Redis port | `6379` (Docker Compose default) |
| `REDIS_CONNECTION_NAME` | Redis connection name | Any string (e.g., `freighter-dev`) |

**Optional — features degrade gracefully:**

| Variable | Purpose | Notes |
| --------------------- | -------------------------- | ------------------------------------ |
| `AUTH_EMAIL` / `AUTH_PASS` | Mercury indexer auth | Only needed if `USE_MERCURY=true` |
| `SENTRY_KEY` | Error tracking | Leave as `not-set` for local dev |
| `BLOCKAID_KEY` | Transaction scanning | Leave as `not-set` for local dev |
| `COINBASE_API_KEY/SECRET` | Pricing data | Leave as `not-set` for local dev |

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

COINBASE_API_KEY/SECRET doesn’t match the actual env var names in .env-EXAMPLE / config (COINBASE_API_KEY and COINBASE_API_SECRET). Please update the docs to list the exact variable names so contributors can copy/paste them correctly.

Suggested change
| `COINBASE_API_KEY/SECRET` | Pricing data | Leave as `not-set` for local dev |
| `COINBASE_API_KEY` / `COINBASE_API_SECRET` | Pricing data | Leave as `not-set` for local dev |

Copilot uses AI. Check for mistakes.
| `FREIGHTER_HORIZON_URL` | Stellar Horizon endpoint | Defaults to public Horizon if unset |

## Key Commands

```bash
yarn start # Dev mode (in-memory store)
yarn build:prod # Production build (webpack)
yarn test # Jest unit tests
yarn test:ci # Jest CI mode
```

## Code Conventions

- **Formatting:** Prettier + ESLint (extends `@stellar/eslint-config`)
- **Pre-commit hooks:** `pretty-quick --staged` + `lint-staged` (ESLint fix)
- **Framework:** Fastify v5 with CORS, Helmet, rate-limiting
- **Logging:** Pino
- **Monitoring:** Prometheus metrics via `prom-client`

## Testing

```bash
yarn test # Run all tests
yarn test:ci # CI mode
```

Jest with `ts-jest` preset, Node test environment.

## Pull Requests

- Branch from `main`
- Commit messages: action verb in present tense
- All tests must pass
- Code must be formatted (pre-commit hooks handle this)

**CI runs on every PR:** build + test (`runTests.yaml`).

## Related Repositories

- [stellar/freighter-backend-v2](https://github.com/stellar/freighter-backend-v2)
(Go) — V2 backend for collectibles, RPC health, protocols
- [stellar/freighter](https://github.com/stellar/freighter) — Browser extension
- [stellar/freighter-mobile](https://github.com/stellar/freighter-mobile) — Mobile app

## Security

- **Never log** API keys, auth credentials, or user data
- **Rate limiting** is enforced via Fastify plugin — don't bypass
- **Report vulnerabilities** via the
[Stellar Security Policy](https://github.com/stellar/.github/blob/master/SECURITY.md)
— not public issues
97 changes: 97 additions & 0 deletions LLM-QUICK-START.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Freighter Backend V1 — LLM Quick Start

Evaluate the contributor's machine against all prerequisites for
freighter-backend (TypeScript/Fastify), install what's missing, and run the
initial setup.

## Step 1: Check all prerequisites

Run every check and collect results. Report all at once.

```bash
# Node.js >= 25.3.0
node --version 2>&1 || which node

# Yarn
yarn --version 2>&1 || which yarn

# Docker (needed for Redis in production mode)
docker --version 2>&1 || which docker

# Docker Compose
docker compose version 2>&1 || which docker-compose

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Docker Compose prerequisite check falls back to which docker-compose, which only prints a path (not a version) and doesn't verify Compose is usable. Consider falling back to docker-compose --version when docker compose version fails.

Suggested change
docker compose version 2>&1 || which docker-compose
docker compose version 2>&1 || docker-compose --version 2>&1

Copilot uses AI. Check for mistakes.
```

## Step 2: Present results

```
Freighter Backend V1 — Prerequisites Check
============================================
Node.js v25.x.x >= 25.3.0 required OK
Yarn 1.22.x >= 1.22.5 required OK
Docker 27.x.x any (for Redis) OK
Docker Compose 2.x.x any OK
```

## Step 3: Install missing tools

Present missing tools and ask the user to confirm before installing.

**Auto-installable (run after user confirms):**

- **nvm + Node.js 25**: `nvm install 25`
- **Yarn**: `npm install --global yarn`
- **Docker**: `brew install --cask docker` (macOS) or follow
[docs.docker.com](https://docs.docker.com/engine/install/) (Linux)

## Step 4: Configure environment

Check if `.env` exists. If not:

```bash
cp .env-EXAMPLE .env
```

For local development with `yarn start`, most values can stay as `not-set` — the
app uses an in-memory store. Set these for basic operation:

| Variable | Value for local dev |
| --------------------- | ------------------------- |
| `MODE` | `development` |
| `HOSTNAME` | `localhost` |
| `REDIS_PORT` | `6379` |
| `REDIS_CONNECTION_NAME` | `freighter-dev` |

Copilot AI Apr 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The setup flow implies cp .env-EXAMPLE .env is sufficient, but the app currently hard-requires additional env keys that are not present in .env-EXAMPLE (notably FREIGHTER_RPC_PUBNET_URL and FREIGHTER_TRUST_PROXY_RANGE via src/config.ts’s ENV_KEYS check). Following these instructions will fail with an invalid/missing env error unless those keys are added. Please either (a) update this guide to explicitly add/set those missing variables, or (b) update .env-EXAMPLE (ideally in this PR) so copy/paste setup works as documented.

Suggested change
For local development with `yarn start`, most values can stay as `not-set` — the
app uses an in-memory store. Set these for basic operation:
| Variable | Value for local dev |
| --------------------- | ------------------------- |
| `MODE` | `development` |
| `HOSTNAME` | `localhost` |
| `REDIS_PORT` | `6379` |
| `REDIS_CONNECTION_NAME` | `freighter-dev` |
Copying `.env-EXAMPLE` is only the starting point. Before the app will boot,
make sure all required environment variables are set in `.env`.
For local development with `yarn start`, most values can stay as `not-set` — the
app uses an in-memory store. Set these for basic operation:
| Variable | Value for local dev |
| ------------------------------ | ------------------------------------ |
| `MODE` | `development` |
| `HOSTNAME` | `localhost` |
| `REDIS_PORT` | `6379` |
| `REDIS_CONNECTION_NAME` | `freighter-dev` |
| `FREIGHTER_RPC_PUBNET_URL` | Your pubnet RPC URL |
| `FREIGHTER_TRUST_PROXY_RANGE` | `127.0.0.1/32` |

Copilot uses AI. Check for mistakes.

## Step 5: Run initial setup

```bash
yarn install
yarn start # Dev mode with in-memory store
```

For production mode (requires Redis):

```bash
docker compose up -d # Start Redis
yarn build:prod
node build/index.js
```

## Step 6: Verify

```bash
yarn test # Jest unit tests
```

## Step 7: Summary

```
Setup Complete
==============
Prerequisites: [list with versions]
Configured: .env from .env-EXAMPLE

Ready to run:
- yarn start (dev mode, in-memory store)
- docker compose up -d (start Redis for production mode)
```
Loading