Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
9 changes: 9 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ module.exports = {
parserOptions: {
ecmaVersion: 12,
},
overrides: [
{
files: ["scripts/**/*.mjs"],
rules: {
"node/no-unsupported-features/es-builtins": ["error", { version: ">=16.0.0" }],
"node/no-unsupported-features/node-builtins": ["error", { version: ">=16.0.0" }],
},
},
],
rules: {
"node/no-unsupported-features/es-syntax": ["error", { ignores: ["modules"] }],
"@typescript-eslint/no-var-requires": 0,
Expand Down
36 changes: 36 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: CI

on:
pull_request:
push:
branches: [master]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v3
with:
node-version: "22.18.0"

- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Lint
run: yarn lint

- name: Build
run: yarn build

- name: Verify legacy equivalence
run: yarn verify:legacy-equivalence

- name: Verify generated files are up to date
run: |
if ! git diff --exit-code src/; then
echo "::error::Generated files are out of date. Run 'yarn build' and commit the result."
git diff src/
exit 1
fi
5 changes: 4 additions & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ jobs:
- name: Build
run: yarn build

- name: Verify legacy equivalence
run: yarn verify:legacy-equivalence

- name: Update npm
run: npm install -g npm@latest

Expand Down Expand Up @@ -74,4 +77,4 @@ jobs:

- name: Publish tagged version
if: steps.release.outputs.tag != ''
run: npm publish --tag ${{ steps.release.outputs.tag }}
run: npm publish --tag ${{ steps.release.outputs.tag }}
1 change: 0 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"printWidth": 120,
"bracketSpacing": true,
"explicitTypes": "preserve",
"tabWidth": 2,
"overrides": [
{
Expand Down
126 changes: 90 additions & 36 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,78 +1,132 @@
# AGENTS.md - constants

This repository contains `@across-protocol/constants` — a shared library exporting network, token, and address definitions used across the Across Protocol ecosystem.
This repository contains `@across-protocol/json-constants` — a shared library exporting network, token, and address definitions used across the Across Protocol ecosystem.

## How to use docs in this repo

1. This file (`AGENTS.md`) for navigation and conventions.
2. `src/index.ts` re-exports everything from `networks.ts` and `tokens.ts`.
2. `data/constants.v1.json` is the canonical source of truth.
3. `schema/constants.v1.schema.json` defines the canonical JSON contract.
4. `src/index.ts` re-exports the backward-compatible legacy TypeScript surface.
5. `src/canonical.ts` exposes the canonical TypeScript wrapper.

## Documentation maintenance

Update this `AGENTS.md` when new source files are added or the build/publish process changes.
Update this `AGENTS.md` when the source-of-truth files, generation flow, or publish process changes.

## Quick index

- Entry point: `src/index.ts`
- Network/chain definitions: `src/networks.ts`
- Token mappings and metadata: `src/tokens.ts`
- Build output: `dist/` (cjs, esm, types)
- Canonical source data: `data/constants.v1.json`
- Canonical schema: `schema/constants.v1.schema.json`
- Legacy package entry point: `src/index.ts`
- Canonical TS wrapper: `src/canonical.ts`
- Generated canonical TS types: `src/generated/canonical-types.ts`
- Generated canonical TS runtime module: `src/generated/constants.v1.ts`
- Generated legacy networks: `src/networks.ts`
- Generated legacy tokens: `src/tokens.ts`
- Validation script: `scripts/validate-canonical.mjs`
- Canonical runtime generator: `scripts/generate-canonical-module.mjs`
- Legacy generator: `scripts/generate-legacy.mjs`
- Upstream equivalence check: `scripts/verify-legacy-equivalence.mjs`
- Build output: `dist/`
- CI workflow: `.github/workflows/ci.yml`
- Publish workflow: `.github/workflows/publish.yml`

## Source files

| File | Purpose | Key exports |
| ----------------- | ------------------ | ---------------------------------------------------------------------------------------------- |
| `src/index.ts` | Barrel re-export | Re-exports `networks` and `tokens` |
| `src/networks.ts` | Chain ID constants | Testnet and mainnet chain IDs, chain metadata (~620 lines) |
| `src/tokens.ts` | Token definitions | `TOKEN_SYMBOLS_MAP` with name, symbol, decimals, per-chain addresses, coingeckoId (~730 lines) |
| File | Purpose | Key exports / outputs |
| --------------------------------------- | -------------------------------------------- | --------------------------------------------------------- |
| `data/constants.v1.json` | Canonical source of truth | Chains, networks, tokens, token equivalence mappings |
| `schema/constants.v1.schema.json` | Canonical JSON Schema | Structural contract for canonical data |
| `src/index.ts` | Barrel re-export | Re-exports legacy `networks` and `tokens` |
| `src/canonical.ts` | Canonical TypeScript wrapper | `CONSTANTS_V1` and canonical TS type exports |
| `src/generated/canonical-types.ts` | Generated canonical TS types | Schema-derived canonical interfaces and unions |
| `src/generated/constants.v1.ts` | Generated canonical TS runtime module | Runtime value backing `src/canonical.ts` |
| `src/networks.ts` | Generated legacy chain/network definitions | Legacy chain IDs, enum, network maps |
| `src/tokens.ts` | Generated legacy token definitions | Legacy token metadata map and token equivalence remapping |
| `scripts/validate-canonical.mjs` | Canonical validation | AJV schema validation plus semantic invariants |
| `scripts/generate-canonical-module.mjs` | Canonical JSON -> TS runtime generator | Regenerates `src/generated/constants.v1.ts` |
| `scripts/generate-legacy.mjs` | Canonical -> legacy TS generator | Regenerates `src/networks.ts` and `src/tokens.ts` |
| `scripts/verify-legacy-equivalence.mjs` | Local vs upstream legacy compatibility check | Verifies built root exports match pinned upstream package |

## Directory tree

```text
constants/
json-constants/
├── data/
│ └── constants.v1.json
├── schema/
│ └── constants.v1.schema.json
├── src/
│ ├── index.ts # Barrel export
│ ├── networks.ts # Chain/network definitions
│ └── tokens.ts # Token metadata and addresses
├── dist/ # Build output (generated)
│ ├── cjs/ # CommonJS build
│ ├── esm/ # ES Modules build
│ └── types/ # TypeScript declarations
├── package.json # @across-protocol/constants, Yarn
├── tsconfig.json # TypeScript config (strict, ES5 target)
├── .eslintrc.cjs # ESLint config
├── .prettierrc # Prettier (120 printWidth)
└── .github/workflows/publish.yml # NPM publish on GitHub release
│ ├── canonical.ts
│ ├── generated/
│ │ ├── constants.v1.ts
│ │ └── canonical-types.ts
│ ├── index.ts
│ ├── networks.ts
│ └── tokens.ts
├── scripts/
│ ├── generate-canonical-module.mjs
│ ├── generate-legacy.mjs
│ ├── validate-canonical.mjs
│ └── verify-legacy-equivalence.mjs
├── dist/
│ ├── cjs/
│ ├── esm/
│ └── types/
├── package.json
├── tsconfig.json
├── .eslintrc.cjs
├── .prettierrc
└── .github/workflows/
├── ci.yml
└── publish.yml
```

## Build and test

```bash
# Build (CJS + ESM + types)
# Build generated sources and package outputs
yarn build

# Lint
yarn lint

# Auto-fix
yarn lint-fix
# Compare built legacy exports to the pinned upstream package
yarn verify:legacy-equivalence
```

There are no tests — this is a pure data library.
There are no application tests. The important verification gate is `verify:legacy-equivalence`, which ensures the generated legacy API matches the published upstream legacy package.

## Adding new tokens or networks
## Updating constants

1. **New network**: Add chain ID constant to `src/networks.ts`.
2. **New token**: Add entry to `TOKEN_SYMBOLS_MAP` in `src/tokens.ts` with name, symbol, decimals, per-chain addresses, and coingeckoId.
3. Run `yarn lint-fix` and `yarn build` to verify.
For normal constant additions or value changes, edit only `data/constants.v1.json`.

Update `schema/constants.v1.schema.json` only when the shape changes, for example a new field, a type change, or a new enum value.

Recommended flow:

1. Edit `data/constants.v1.json`.
2. If the shape changed, update `schema/constants.v1.schema.json`.
3. Run `yarn build`.
4. Run `yarn verify:legacy-equivalence`.

Legacy compatibility note:

- `TESTNET_CHAIN_IDs` must continue to include both `testnet` and `testnet_sepolia` chains, matching the historical TypeScript API.

Do not edit `src/generated/canonical-types.ts`, `src/generated/constants.v1.ts`, `src/networks.ts`, or `src/tokens.ts` by hand.

## Publish process

- Published to npm via GitHub Actions on GitHub release.
- Workflow validates semver, builds, and publishes with OIDC trusted publishing.
- Pre-release versions supported for beta/canary tags.
- `yarn build` validates canonical data, regenerates canonical and legacy TypeScript sources, and builds package outputs.
- Canonical JSON and schema are published as package artifacts.
- The root package API remains the legacy TypeScript surface for backward compatibility.
- The `./canonical` export exposes the canonical TypeScript wrapper.

## Consumers

This package is consumed by: relayer, indexer, frontend, and toolkit.
- Existing TypeScript consumers should continue using the root package exports.
- TypeScript consumers that want the language-agnostic shape can use `@across-protocol/json-constants/canonical`.
- Non-TypeScript consumers should consume `data/constants.v1.json` against `schema/constants.v1.schema.json`.
88 changes: 66 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,103 @@
# Across Constants

[![npm](https://img.shields.io/npm/v/@across-protocol/constants)](https://www.npmjs.com/package/@across-protocol/constants)
[![npm](https://img.shields.io/npm/v/@across-protocol/json-constants)](https://www.npmjs.com/package/@across-protocol/json-constants)

Shared library exporting network, token, and address definitions used across the Across Protocol ecosystem.

This package now has two public surfaces:

- The root package, `@across-protocol/json-constants`, which preserves the existing TypeScript legacy API.
- A canonical language-agnostic contract consisting of:
- `data/constants.v1.json`
- `schema/constants.v1.schema.json`
- `@across-protocol/json-constants/canonical`

## Installation

```bash
# npm
npm install @across-protocol/constants
npm install @across-protocol/json-constants

# yarn
yarn add @across-protocol/constants
yarn add @across-protocol/json-constants
```

## Usage

```typescript
import { TOKEN_SYMBOLS_MAP } from "@across-protocol/constants";
Legacy TypeScript surface:

```ts
import { TOKEN_SYMBOLS_MAP } from "@across-protocol/json-constants"

const usdc = TOKEN_SYMBOLS_MAP.USDC
console.log(usdc.decimals)
console.log(usdc.addresses[1])
```

Canonical TypeScript surface:

// Access token metadata
const usdc = TOKEN_SYMBOLS_MAP.USDC;
console.log(usdc.decimals); // 6
console.log(usdc.addresses[1]); // Ethereum mainnet address
```ts
import { CONSTANTS_V1 } from "@across-protocol/json-constants/canonical"

const mainnet = CONSTANTS_V1.networks.find((network) => network.chainId === 1)
console.log(mainnet?.name)
```

## What's Exported
## Package Layout

| Surface | Description |
| ------------------------------------------- | -------------------------------------------------- |
| `@across-protocol/json-constants` | Backward-compatible legacy TypeScript exports |
| `@across-protocol/json-constants/canonical` | Canonical TypeScript wrapper around canonical JSON |
| `data/constants.v1.json` | Canonical source of truth |
| `schema/constants.v1.schema.json` | Canonical JSON Schema |

| Module | Description |
|--------|-------------|
| `networks` | Chain ID constants for testnets and mainnets, chain metadata |
| `tokens` | `TOKEN_SYMBOLS_MAP` — token name, symbol, decimals, per-chain addresses, coingeckoId |
The canonical JSON is the source of truth. The legacy root TypeScript exports are generated from it during `yarn build`.

## Development

```bash
# Build (CJS + ESM + TypeScript declarations)
# Build generated sources and package outputs
yarn build

# Lint
yarn lint

# Auto-fix lint issues
yarn lint-fix
# Check canonical data against the published upstream legacy package
yarn verify:legacy-equivalence
```

## Adding Tokens or Networks
## Updating Constants

Most updates only require editing `data/constants.v1.json`.

Edit `schema/constants.v1.schema.json` only when the shape changes, for example:

- adding a new field
- changing a field type
- adding a new enum value
- making a required field optional, or the reverse

Typical update flow:

1. Edit `data/constants.v1.json`.
2. If the data shape changed, update `schema/constants.v1.schema.json`.
3. Run `yarn build`.
4. Run `yarn verify:legacy-equivalence`.

Do not edit generated files in `src/generated/`, `src/networks.ts`, or `src/tokens.ts` by hand.

## Validation And Generation

1. **New network**: Add chain ID constant to `src/networks.ts`.
2. **New token**: Add entry to `TOKEN_SYMBOLS_MAP` in `src/tokens.ts`.
3. Run `yarn lint-fix && yarn build` to verify.
- Canonical JSON is validated with `ajv`.
- Canonical TypeScript types are generated from JSON Schema with `json-schema-to-typescript`.
- The canonical TypeScript runtime module is generated from `data/constants.v1.json`.
- Legacy TypeScript exports are generated from canonical JSON by `scripts/generate-legacy.mjs`.
- `TESTNET_CHAIN_IDs` intentionally preserves the legacy behavior of including both `testnet` and `testnet_sepolia` chains.

## Publishing

Published to npm automatically via GitHub Actions on [GitHub release](https://github.com/across-protocol/constants/releases). Supports pre-release versions for beta/canary tags.
Published to npm automatically via GitHub Actions on [GitHub release](https://github.com/across-protocol/json-constants/releases). Pre-release versions are supported for beta/canary tags.

## License

Expand Down
Loading
Loading