> ## Documentation Index
> Fetch the complete documentation index at: https://docs.eco.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Chains and registries

> Read, from TypeScript, the registries a program's names resolve against, without reaching a chain.

The package carries the registries a program's names resolve against: 46 chains, each chain's tokens, and 133 protocols with their deployments. The exports on this page read those registries. None of them reads a chain or takes an RPC endpoint, and they cover preview chains as well as the chains that send. The data itself is listed in [Chains](https://docs.eco.com/sauce-sdk/reference/chains.md), [Tokens](https://docs.eco.com/sauce-sdk/reference/tokens.md) and [Protocols](https://docs.eco.com/sauce-sdk/reference/protocols.md).

A bare name in a program, such as `USDC` or `UniswapV3.Factory`, is SauceScript syntax that `routes.compileSauceProgram`, the `sauce` command, the MCP server and actions documents resolve for the chain they compile for, before the compiler runs; `routes.compileSauceRoute` adds neither the chain id nor the token functions, and the compiler alone knows none of these names ([Names](https://docs.eco.com/sauce/names.md), [Compiler or SDK](https://docs.eco.com/sauce/builtins.md#compiler-or-sdk)). The TypeScript spelling of the same registry entry hangs off a chain export: `Base.USDC`, `Base.UniswapV3.Factory`.

## Chain exports

One named export per canonical chain, each carrying the chain's record, its registry tokens and the protocol contract tree.

### Import

```ts theme={null}
import { Arc, Base, Ethereum, Optimism, Solana } from "@eco-incorp/sauce";
```

The export name is the chain's slug in PascalCase: `Base`, `Arbitrum`, `Bsc`, `Zksync`, `Solana`.

### Usage

```ts cr-chain-exports.mts theme={null}
import { Arc, Base, Ethereum, Optimism, Solana } from "@eco-incorp/sauce";

console.log(Base.chain);
console.log(Base.USDC);
console.log(Ethereum.WETH.address);
console.log(Arc.USDC.decimals);
console.log(Solana.USDC.mint);
console.log(Base.UniswapV3.Factory.address, Base.UniswapV3.Factory.available);
console.log(Optimism.PancakeswapV3.Factory.available);
```

```text theme={null}
{ id: 8453, slug: 'base', name: 'Base', kind: 'evm', aliases: [] }
{
  address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
  decimals: 6,
  symbol: 'USDC',
  chain: { id: 8453, slug: 'base', name: 'Base', kind: 'evm', aliases: [] }
}
0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
6
EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
0x33128a8fC17869897dcE68Ed026d694621f6FDfD true
false
```

### Type

```ts theme={null}
type Composed<N extends keyof ChainGlobals> = ChainGlobals[N] & ChainContracts;
type Tokens<S extends string> = {
    readonly [K in S]: RegistryToken;
};
export declare const Base: Composed<"Base"> & Tokens<"USDC" | "WETH" | "AAPLc" /* | … every Base symbol */>;
export declare const Solana: Composed<"Solana"> & SvmVenueAccessors & Tokens<"PYUSD" | "USDC" | "USDT" | "WSOL" /* | … */>;
```

### Properties

| Property | What it is |
| - | - |
| `.chain` | The chain's `CanonicalChain` record: `id`, `slug`, `name`, `kind` (`"evm"` or `"svm"`), `aliases`. |
| `.<Symbol>` | A registry token, a frozen `RegistryToken`: `address`, `decimals`, `symbol`, `chain`. On Solana, `address` is the mint's 32-byte key as hex, the value a program's symbol resolves to, and `mint` is its base58 address. |
| `.<Namespace>.<Contract>` | A protocol contract: `address` (`undefined` where the chain has no deployment), `available`, `chains`, `abi`, `methods`, and one method per ABI function. |
| `.<Venue>` | On `Solana` only: the registered venue adapters (`Solana.RaydiumCpSwap`), each with `programId`, `poolConfig`, `quoteSource` and `swap`. |

A chain export's tokens are exactly that chain's registry rows: `Base.USDT` is a type error and `undefined` at run time. Every chain export carries every protocol namespace, so use `.available` to ask whether the chain has a deployment.

### Contract calls

A contract's method builds a `ContractCall` synchronously, typed from the registry ABI.

```ts cr-contract-call.mts theme={null}
import { Base } from "@eco-incorp/sauce";

// Built offline: nothing is read until you pass a viem client to read(), simulate() or write().
const getPool = Base.UniswapV3.Factory.getPool(Base.USDC.address, Base.WETH.address, 500);

console.log(getPool.method.signature, getPool.method.returns);
console.log(getPool.toCall());

// QuoterV2's quotes are state-changing methods meant to be read: quote.read(client) runs an eth_call.
const quote = Base.UniswapV3.QuoterV2.quoteExactInputSingle({
  tokenIn: Base.USDC.address,
  tokenOut: Base.WETH.address,
  amountIn: 1_000_000_000n, // 1,000 USDC
  fee: 500,
  sqrtPriceLimitX96: 0n,
});
console.log(quote.method.signature, quote.method.stateMutability);
```

```text theme={null}
getPool(address,address,uint24) [ { path: [], protocol: 'uniswap-v3', contract: 'Pool' } ]
{
  target: '0x33128a8fC17869897dcE68Ed026d694621f6FDfD',
  data: '0x1698ee82000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda02913000000000000000000000000420000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000001f4',
  value: 0n
}
quoteExactInputSingle((address,address,uint256,uint24,uint160)) nonpayable
```

`UniswapV3.QuoterV2` is a name on every chain the registry records a Uniswap V3 factory on, Base among them.

| Member | What it does |
| - | - |
| `toCall(options?)` | Returns `{ target, data, value }`. |
| `encode(options?)` | Returns the calldata. |
| `toSauceScript(options?)` | Returns `{ imports, statement, source }`: the same call as a program. |
| `read(client)` | Runs the method as an `eth_call` through your viem client and decodes the outputs. Sends nothing. |
| `simulate(client, options)` | On a state-changing method: viem's `simulateContract` as `options.account`. |
| `write(client, options?)` | On a state-changing method: viem's `writeContract`; resolves to the transaction hash. |

`read`, `simulate` and `write` first check that the client is on the call's chain, and refuse a client on another chain. `method.returns` names the registry contract an address output is, where the registry knows it. Calling a method of a contract with no deployment on the chain throws, naming the chains that have one. An interface such as `Base.Erc4626.Vault` has methods only after `.at(address)`.

## chain

Resolves a chain chosen at run time to its record.

### Import

```ts theme={null}
import { chain } from "@eco-incorp/sauce";
```

### Usage

```ts cr-chain.mts theme={null}
import { chain, contracts, routes } from "@eco-incorp/sauce";

const picked = chain("eth"); // a slug, an alias, a name or a chain id
console.log(picked.chain);

// `chain(ref)` carries `.chain` only. For the same chain's names, pass that record on:
console.log(contracts.on(picked.chain).UniswapV3.Factory.address);
console.log(routes.registryTokens(picked.chain).USDC?.address);
```

```text theme={null}
{
  id: 1,
  slug: 'ethereum',
  name: 'Ethereum',
  kind: 'evm',
  aliases: [ 'mainnet', 'eth' ]
}
0x1F98431c8aD98523631AE4a59f267346ea31F984
0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
```

### Signature

```ts theme={null}
export declare function chain(ref: number | string | bigint | CanonicalChain): ChainGlobal;

export interface ChainGlobal {
    readonly chain: CanonicalChain;
}
```

### Parameters

* `ref`: a chain id (`8453`, `8453n`), a slug, name or alias (`"eth"`, `"BNB Chain"`), or a `CanonicalChain`. Strings match without regard to case and punctuation.

### Returns

`ChainGlobal`: an object with `.chain` alone. It is not the composed chain export, so it has no tokens or contract tree. Use `contracts.on(ref)` and `routes.registryTokens(chain)` for those.

### Throws

When `ref` names no chain, with the list of known slugs: `Unknown chain 'nope' (known slugs: ethereum, optimism, bsc, …)`.

## contracts.on

The protocol contract tree of a chain chosen at run time: the same tree a chain export carries.

### Import

```ts theme={null}
import { contracts } from "@eco-incorp/sauce";
```

### Usage

`contracts.on(picked.chain)` in the [`chain` example](#chain) above.

### Signature

```ts theme={null}
export declare function on(chainRef: ChainRef): ChainContracts;
```

### Parameters

* `chainRef`: a chain id, slug, alias or `CanonicalChain`.

### Returns

`ChainContracts`: every protocol and family namespace, each contract with `address`, `available` and its methods. `contracts.listContracts(slug)`, `contracts.contractsOnChain(chain)` and `contracts.describeContract(chain, protocol, contract)` query the same descriptors.

## Token

The host builder for one ERC-20 or SPL token operation: it returns the call or the program text, and sends nothing.

### Import

```ts theme={null}
import { Token } from "@eco-incorp/sauce";
```

### Usage

```ts cr-token.mts theme={null}
import { Base, Token } from "@eco-incorp/sauce";

const transfer = Token.transfer({
  token: Base.USDC.address,
  to: "0x1111111111111111111111111111111111111111",
  amount: 1_000_000n, // 1 USDC
});

console.log(transfer.toCall()); // { target, data, value }: the plain ERC-20 call
```

```text theme={null}
{
  target: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913',
  data: '0xa9059cbb000000000000000000000000111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000f4240',
  value: 0n
}
```

### Signature

```ts theme={null}
export declare const Token: TokenApi & TokenFactory;

export interface TokenApi {
    transfer(spec: TokenTransferSpec): TokenCall;
    approve(spec: TokenApproveSpec): TokenCall;
    balanceOf(spec: TokenBalanceSpec): TokenCall;
    program(specs: readonly TokenSpec[], opts: {
        target: TokenTarget;
    }): string;
    // … constants: TOKEN_PROGRAM, TOKEN_2022_PROGRAM, ERC20ABI, …
}

export interface TokenCall {
    readonly spec: TokenSpec;
    source(target: TokenTarget): string;
    statement(target: TokenTarget): string;
    expression(target: TokenTarget): string;
    toSauceScript(target: TokenTarget): TokenSauceScript;
    toCall(): { readonly target: `0x${string}`; readonly data: Hex; readonly value: bigint };
    accountRefs(): readonly string[];
}
```

### Parameters

* `spec.token`: on EVM, the ERC-20's address.
* `spec.to` (transfer) or `spec.spender` (approve): on EVM, the recipient or the spender.
* `spec.amount`: a `bigint`, a safe-integer `number`, or `"balance"` to read the live balance when the program runs.
* `spec.svm`, `spec.tokenProgram`: on Solana, the account references the operation uses and `"spl"` (the default) or `"token-2022"`.

### Returns

`TokenCall`. `toCall()` is the plain ERC-20 call, for a fixed amount on EVM. `source(target)` is a complete one-operation program whose writes follow OpenZeppelin `SafeERC20`; compile it like any other program. `Token.program(specs, { target })` puts several operations in one program.

### Throws

`toCall()` throws for an SVM spec; `statement()` throws for `balanceOf`; `expression()` throws for a write.

In a program, `Token(address)` is program syntax and not this builder: see [Names](https://docs.eco.com/sauce/names.md).

## The /chains subpath

The canonical chain records and the EVM chain metadata. The package root re-exports every one of these.

### Import

```ts theme={null}
import { CANONICAL_CHAINS, getChain, requireChain } from "@eco-incorp/sauce/chains";
```

### Usage

```ts cr-chains-subpath.mts theme={null}
import {
  CANONICAL_CHAINS,
  chainById,
  getChain,
  nativeErc20,
  nativeToErc20Amount,
  requireChain,
  resolveChain,
} from "@eco-incorp/sauce/chains";

console.log(CANONICAL_CHAINS.length); // every chain a program can name
console.log(requireChain("mainnet")); // slug, name or alias, matched loosely
console.log(resolveChain("nowhere")); // undefined where requireChain throws
console.log(chainById(1399811149)?.slug);
console.log(getChain(5042)?.nativeCurrency); // EVM metadata: native coin, explorer
console.log(nativeErc20(5042)); // Arc's native coin is also an ERC-20
console.log(nativeToErc20Amount(5042, 1_500_000_000_000_000_000n)); // 1.5 USDC, 18 to 6 decimals
```

```text theme={null}
45
{
  id: 1,
  slug: 'ethereum',
  name: 'Ethereum',
  kind: 'evm',
  aliases: [ 'mainnet', 'eth' ]
}
undefined
solana
{
  name: 'USDC',
  symbol: 'USDC',
  decimals: 18,
  erc20: {
    address: '0x3600000000000000000000000000000000000000',
    decimals: 6
  }
}
{ address: '0x3600000000000000000000000000000000000000', decimals: 6 }
1500000n
```

### Signature

```ts theme={null}
export declare const CANONICAL_CHAINS: readonly [/* 45 records */];
export type ChainRef = number | bigint | string | CanonicalChain;
export declare function resolveChain(ref: ChainRef): CanonicalChain | undefined;
export declare function requireChain(ref: ChainRef): CanonicalChain;
export declare function chainById(id: number): CanonicalChain | undefined;
export declare function chainBySlug(slug: string): CanonicalChain | undefined;
export declare function chainByAlias(nameOrAlias: string): CanonicalChain | undefined;
export declare function isEvm(ref: ChainRef): boolean;
export declare function isSvm(ref: ChainRef): boolean;
export declare function evmChains(): CanonicalChain[];
export declare function svmChains(): CanonicalChain[];
export declare function canonicalChainSlugs(): ChainSlug[];

export declare const chains: Record<number, Chain>;
export declare function getChain(chainId: number): Chain | undefined;
export declare function getAllChainIds(): number[];
export declare function nativeCoinSymbol(chain: CanonicalChain): string | undefined;
export declare function nativeErc20(chainId: number): NativeErc20 | undefined;
export declare function nativeToErc20Amount(chainId: number, wei: bigint): bigint;
```

### Returns

* A `CanonicalChain` is identity only: `id`, `slug`, `name`, `kind`, `aliases`. Solana's id is `1399811149`.
* A `Chain` from `getChain` is EVM metadata: `nativeCurrency`, `blockExplorerUrls`, `testnet`, and `minBaseFeePerGas` where the chain enforces a floor (20 gwei on Arc and Arc Testnet). It carries no RPC URL. `chains` covers 37 of the 43 EVM chains; `getChain` returns `undefined` for the rest.
* `nativeErc20(chainId)` is the ERC-20 that is the chain's native coin, or `undefined` where the native coin is separate from every token. On Arc it is USDC: one balance, 18 decimals natively and 6 through the ERC-20.
* `nativeToErc20Amount(chainId, wei)` converts a native amount to the ERC-20's units, rounding down as `balanceOf` reads it.

### Throws

`requireChain` throws for an unknown chain, naming the known slugs. `nativeToErc20Amount` throws on a chain whose native coin is not an ERC-20.

## routes.TOKEN\_REGISTRY

The EVM token table, keyed by chain id: every token symbol a program on that chain can name, tokenized stocks included.

### Import

```ts theme={null}
import { routes } from "@eco-incorp/sauce";
```

### Usage

```ts cr-tokens.mts theme={null}
import { requireChain, routes } from "@eco-incorp/sauce";

const base = requireChain("base");

// The EVM table, keyed by chain id: one row per token, tokenized stocks included.
const rows = routes.TOKEN_REGISTRY[base.id] ?? [];
console.log(rows.length, rows.filter((row) => row.stock === undefined).map((row) => row.symbol));
console.log(rows.find((row) => row.symbol === "SPCXc"));

// The same tokens as a program resolves them.
console.log(routes.knownTokenSymbols(base).length);
console.log(routes.registryTokenAddress(base, "USDC")); // a bigint, or undefined
console.log(routes.registryTokens(base).WETH);

// Solana's mints, per cluster, each with the token program that owns it.
const pyusd = routes.SVM_TOKEN_REGISTRY["mainnet-beta"].find((row) => row.symbol === "PYUSD");
console.log(pyusd);
console.log(routes.SVM_TOKEN_REGISTRY.devnet.map((row) => row.symbol));

// Stock issuers, and how an issuer's ticker becomes a symbol.
console.log(Object.keys(routes.STOCK_ISSUERS));
console.log(routes.stockSymbol("BRK.Bx"));
```

```text theme={null}
69 [ 'USDC', 'WETH' ]
{
  symbol: 'SPCXc',
  address: '0xb2000000000000000000007b9fcbd005511aCBd5',
  decimals: 8,
  source: 'https://api.coinbase.com/v1/tokenized-stocks',
  stock: {
    issuer: 'coinbase',
    name: 'Space Exploration Technologies Corp.',
    ticker: 'SPCX'
  }
}
69
749071750893463290574776461331093852760741783827n
{
  address: '0x4200000000000000000000000000000000000006',
  decimals: 18,
  symbol: 'WETH',
  chain: { id: 8453, slug: 'base', name: 'Base', kind: 'evm', aliases: [] }
}
{
  symbol: 'PYUSD',
  mint: '2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo',
  tokenProgram: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',
  decimals: 6,
  source: 'probe:solana@2026-10-01',
  address: '0x1792483b6c8a2a87b7471d814f9591f9395c840a9ce3d9f4d5ba7d3a4b8a749e'
}
[ 'USDC', 'WSOL' ]
[ 'backed', 'ondo', 'coinbase', 'mtpelerin', 'backpack', 'prestocks' ]
BRK_Bx
```

### Type

```ts theme={null}
export declare const TOKEN_REGISTRY: Readonly<Record<number, readonly TokenRegistryRow[]>>;

export interface TokenRegistryRow {
    readonly symbol: string;
    readonly onchainSymbol?: string;
    readonly address: `0x${string}`;
    readonly decimals: number;
    readonly source: string;
    readonly stock?: StockToken;
}
```

A row's `address` is EIP-55 checksummed, and `source` records where the row was verified: an in-repository pin, a `probe:<chain>@<date>` read, or a stock issuer's published list. `decimals` is metadata: the compiler applies no decimal scaling, so amounts in a program are integers in the token's smallest unit. A chain with no row has no token symbols.

## routes.SVM\_TOKEN\_REGISTRY

Solana's registered mints, per cluster. A program compiled for `solana` resolves its symbols against `mainnet-beta`.

### Type

```ts theme={null}
export type SvmTokenCluster = "mainnet-beta" | "devnet" | "testnet";
export declare const SVM_TOKEN_REGISTRY: Readonly<Record<SvmTokenCluster, readonly SvmTokenRow[]>>;

export interface SvmTokenRow {
    readonly symbol: string;
    readonly mint: string;
    readonly tokenProgram: SolanaAddress;
    readonly address: `0x${string}`;
    readonly stock?: StockToken;
    readonly decimals: number;
    readonly source: string;
}
```

`tokenProgram` is the program that owns the mint: SPL Token (`TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`) for USDC and USDT, Token-2022 (`TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb`) for PYUSD and every tokenized stock. `address` is the mint's 32-byte key as hex, the value a program compares an account's mint against. The example under `routes.TOKEN_REGISTRY` above reads it.

## Token lookups

Per-chain views of both tables, as a compiled program resolves them.

### Usage

The example under `routes.TOKEN_REGISTRY` above calls each one.

### Signature

```ts theme={null}
export declare function registryTokens(chain: CanonicalChain): Readonly<Record<string, RegistryToken>>;
export declare function knownTokenSymbols(chain: CanonicalChain): readonly string[];
export declare function registryTokenAddress(chain: CanonicalChain, symbol: string): bigint | undefined;
export declare function svmTokenRows(chain: CanonicalChain): readonly SvmTokenRow[];
```

### Parameters

* `chain`: a `CanonicalChain`, from `requireChain(ref)` or a chain export's `.chain`.
* `symbol`: a registry symbol, matched exactly.

### Returns

* `registryTokens`: every registry token on the chain by symbol, the same frozen objects a chain export carries (`routes.registryTokens(base).USDC === Base.USDC`). Empty for a chain with no rows.
* `knownTokenSymbols`: every symbol on the chain, sorted.
* `registryTokenAddress`: the value the symbol resolves to in a program, as a `bigint`: the token's address on an EVM chain, the mint's 32-byte key on Solana. `undefined` when the chain does not register the symbol.
* `svmTokenRows`: the mints a program compiled for the chain resolves; empty off Solana.

To give a token a symbol for one compile, pass `tokens: { SYMBOL: address }` in `routes.compileSauceProgram`'s options; it merges per symbol with the registry ([Compiling](https://docs.eco.com/sauce-sdk/typescript/compiling.md)).

## Tokenized stocks

Ethereum, Base and Solana register tokenized stocks as ordinary rows with a `stock` field. Each list is copied from its issuer's own published list.

### Signature

```ts theme={null}
export type StockIssuer = "backed" | "ondo" | "coinbase" | "mtpelerin" | "backpack" | "prestocks";
export declare const STOCK_ISSUERS: Readonly<Record<StockIssuer, {
    readonly name: string;
    readonly source: string;
    readonly transferFee?: true;
}>>;
export declare function stockSymbol(symbol: string): string;

export interface StockToken {
    readonly issuer: StockIssuer;
    readonly name: string;
    readonly ticker: string;
}
```

### Returns

* `STOCK_ISSUERS`: each issuer's name, the list its rows come from, and `transferFee` where its Solana mints charge a Token-2022 transfer fee.
* `stockSymbol(symbol)`: the registry symbol for an issuer's ticker, with `.` written as `_` (`BRK.Bx` is `BRK_Bx`), so that every symbol is an identifier a program can write.

Stock symbols are not all uppercase (`TSLAx`, `SPCXc`, `bTSLA`); the registry keeps each chain's symbols unique without regard to case. [Tokenized stocks](https://docs.eco.com/sauce-sdk/reference/tokens.md#tokenized-stocks) lists what differs about each issuer's tokens.

## Protocol registry

The protocol catalogue: each protocol's metadata and per-chain deployments.

### Import

```ts theme={null}
import { getProtocol, getProtocolsByChain, listProtocols } from "@eco-incorp/sauce";
```

### Usage

```ts cr-protocols.mts theme={null}
import {
  getProtocol,
  getProtocolsByCategory,
  getProtocolsByChain,
  listProtocolSlugs,
  listProtocols,
} from "@eco-incorp/sauce";
import * as uniswapV3 from "@eco-incorp/sauce/protocols/uniswap-v3";

console.log(listProtocols().length, listProtocolSlugs().slice(0, 4));
console.log(getProtocolsByCategory("lending").map((p) => p.slug).slice(0, 5));
console.log(getProtocolsByChain(8453).length); // catalogued on Base

const info = getProtocol("uniswap-v3");
console.log(info?.name, info?.category, info?.chains.length);

// One protocol's module: its metadata, deployments by role, ABIs and SauceScript templates.
console.log(Object.keys(uniswapV3));
console.log(uniswapV3.deployments.find((d) => d.chainId === 8453)?.addresses);
```

```text theme={null}
133 [ 'uniswap-v2', 'uniswap-v3', 'uniswap-v4', 'sushiswap-v2' ]
[ 'aave-v2', 'aave-v3', 'aave-v4', 'compound-v2', 'compound-v3' ]
45
Uniswap V3 dex 10
[
  'UniswapV3FactoryABI',
  'UniswapV3NonfungiblePositionManagerABI',
  'UniswapV3PoolABI',
  'UniswapV3QuoterV2ABI',
  'UniswapV3SwapRouter02ABI',
  'UniswapV3SwapRouterABI',
  'addLiquidity',
  'deployments',
  'protocolInfo',
  'removeLiquidity',
  'swap'
]
{
  factory: '0x33128a8fC17869897dcE68Ed026d694621f6FDfD',
  swapRouter02: '0x2626664c2603336E57B271c5C0b26F421741e481',
  quoterV2: '0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a',
  nonfungiblePositionManager: '0x03a520b32C04BF3bEEf7BEb72E919cf822Ed34f1'
}
```

### Signature

```ts theme={null}
export declare const protocols: Record<string, ProtocolInfo>;
export declare function getProtocol(slug: string): ProtocolInfo | undefined;
export declare function listProtocols(): ProtocolInfo[];
export declare function getProtocolsByCategory(category: ProtocolCategory): ProtocolInfo[];
export declare function getProtocolsByChain(chainId: number): ProtocolInfo[];
export declare function listProtocolSlugs(): string[];
```

### Returns

A `ProtocolInfo` carries `name`, `slug`, `description`, `website`, `category` and `chains`, one `{ chainId, chainName, addresses }` per chain, its addresses keyed by role (`factory`, `quoterV2`). `ProtocolCategory` is one of `dex`, `lending`, `bridge`, `yield`, `derivatives`, `staking`, `oracle`, `cdp`, `aggregator`, `liquid-staking`, `restaking` and the other values in its type.

An address in the catalogue is recorded, not proof of live code: read the chain before you rely on it. Whether a program can call a contract by name is a separate question that `.available` on a chain export, or `routes.sourceGlobals`, answers.

## /protocols/\*

One module per protocol slug.

### Import

```ts theme={null}
import * as uniswapV3 from "@eco-incorp/sauce/protocols/uniswap-v3";
```

### Exports

| Export | What it is |
| - | - |
| `protocolInfo` | The protocol's `ProtocolInfo`. |
| `deployments` | One `{ chainId, chainName, addresses }` per chain, addresses keyed by role. |
| `…ABI` | Each contract ABI the registry declares, `as const` (`UniswapV3FactoryABI`). |
| Templates | SauceScript program source by name (`swap`, `addLiquidity`), as strings. |

The usage is in the [protocol registry example](#protocol-registry). Every registry ABI declares the deployed contract's own types, so the selectors it computes are the ones the deployment dispatches. [Protocols](https://docs.eco.com/sauce-sdk/reference/protocols.md) lists each protocol's contracts on every chain.

## routes.sourceGlobals

Every name a program compiled for a chain may use without declaring it: what `sauce globals --chain <chain>` prints.

### Import

```ts theme={null}
import { routes } from "@eco-incorp/sauce";
```

### Usage

```ts cr-source-globals.mts theme={null}
import { routes } from "@eco-incorp/sauce";

const names = routes.sourceGlobals("base");

console.log(names.chain);
console.log(names.tokens.length, names.protocols.length, names.interfaces.length, names.chains.length);
console.log(names.modules.map((module) => `${module.specifier}: ${module.functions.length} functions`));

const uniswap = names.protocols.find((namespace) => namespace.namespace === "Uniswap");
console.log(uniswap?.kind, uniswap?.contracts.map((c) => `${c.name} (${c.protocol})`));

const solana = routes.sourceGlobals("solana");
console.log(solana.venues.map((venue) => venue.namespace));
```

```text theme={null}
{ key: 'Base', slug: 'base', id: 8453, kind: 'evm' }
69 51 39 45
[ '@sauce/token: 9 functions' ]
family [
  'NonfungiblePositionManager (uniswap-v3)',
  'PoolManager (uniswap-v4)',
  'PositionManager (uniswap-v4)',
  'QuoterV2 (uniswap-v3)',
  'Router (uniswap-v2)',
  'StateView (uniswap-v4)',
  'SwapRouter02 (uniswap-v3)',
  'UniversalRouter (uniswap-v4)'
]
[
  'Raydium.CLMM',
  'Pancakeswap.CLMM',
  'Byreal.CLMM',
  'Stabble.CLMM',
  'Orca.Whirlpool',
  'Cropper.Whirlpool',
  'Defituna.Fusion',
  'Crema.CLMM',
  'Phoenix.Market',
  'Meteora.DLMM'
]
```

### Signature

```ts theme={null}
export declare function sourceGlobals(chain: ChainRef): SourceGlobals;

export interface SourceGlobals {
    readonly chain: SourceChainName;
    readonly tokens: readonly SourceToken[];
    readonly protocols: readonly SourceNamespace[];
    readonly venues: readonly SourceVenue[];
    readonly accounts: readonly SvmAccountExpression[];
    readonly interfaces: readonly SourceInterface[];
    readonly chains: readonly SourceChainName[];
    readonly defines: Readonly<Record<string, bigint | boolean | number>>;
    readonly modules: readonly SourceModule[];
}
```

### Parameters

* `chain`: a chain id, slug, alias or `CanonicalChain`.

### Returns

| Field | What it lists |
| - | - |
| `tokens` | Each token symbol with its address and decimals; on Solana also the mint and its token program. Tokenized stocks are included. |
| `protocols` | Each namespace a program can write on the chain (`UniswapV3`, or a family alias such as `Uniswap`), with each contract's address, protocol and methods. Only namespaces with a contract on the chain appear. |
| `interfaces` | The ABIs a program binds to an address of its own (`Erc4626.Vault`); EVM only. |
| `chains` | The chain names a program qualifies a contract by (`Arbitrum.UniswapV3.Factory`). |
| `venues` | On Solana, each venue namespace a program swaps at (`Orca.Whirlpool`); empty on an EVM chain. |
| `accounts` | On Solana, the account expressions a program writes where it uses them; empty on an EVM chain. |
| `defines` | The scalars every program on the chain reads, such as `chainId`. |
| `modules` | The zero-import modules (`@sauce/token`) and the functions each exports for the chain's target. |

A name listed here is one the compile accepts on that chain, resolved to the value the program gets. `sauce globals --chain base --json` prints the same object, except that its `tokens` leave out the tokenized stocks, which the text output counts ([`sauce globals`](https://docs.eco.com/sauce-sdk/cli/globals)).

## installRouteGlobals

Importing the package defines nothing on `globalThis`. `installRouteGlobals()` is the opt-in for a host that wants the chain exports, `chain` and `Token` as run-time globals.

### Import

```ts theme={null}
import { installRouteGlobals, uninstallRouteGlobals } from "@eco-incorp/sauce";
```

### Usage

```ts cr-globals.mts theme={null}
const before = new Set(Object.getOwnPropertyNames(globalThis));
const { Base, installRouteGlobals, uninstallRouteGlobals } = await import("@eco-incorp/sauce");
console.log(Object.getOwnPropertyNames(globalThis).filter((name) => !before.has(name))); // []

const report = installRouteGlobals(); // onto globalThis; never overwrites a name already there
console.log(report.installed.length, report.installed.slice(0, 3), report.skipped);
console.log((globalThis as Record<string, unknown>).Base === Base);

uninstallRouteGlobals();
console.log("Base" in globalThis);
```

```text theme={null}
[]
47 [ 'Ethereum', 'Optimism', 'Bsc' ] []
true
false
```

### Signature

```ts theme={null}
export declare function installRouteGlobals(opts?: InstallRouteGlobalsOptions): RouteGlobalsReport;
export declare function uninstallRouteGlobals(target?: object): void;
export declare const routeGlobals: RouteGlobalsReport;

export interface InstallRouteGlobalsOptions {
    readonly target?: object;
    readonly includeChain?: boolean;
    readonly includeToken?: boolean;
}
export interface RouteGlobalsReport {
    readonly installed: readonly string[];
    readonly skipped: readonly string[];
}
```

### Parameters

* `opts.target`: the object to define the names on. Default `globalThis`.
* `opts.includeChain`: also define `chain`. Default `true`.
* `opts.includeToken`: also define `Token`. Default `true`.
* `target` (`uninstallRouteGlobals`): the object to remove them from. Default `globalThis`.

### Returns

`RouteGlobalsReport`: the names this call defined, and the names it skipped because the target already had them. A name already present, inherited or getter-only included, is never overwritten. Each installed property is non-enumerable, and its value is the same object the named export holds. `routeGlobals` is a live view of the last install, empty until one happens. `uninstallRouteGlobals()` removes every name the module installed.

`installRouteGlobals()` installs values only. The TypeScript declarations for bare names in a program (`USDC`, `Uniswap`) are type-only and come with the package's root types; no run-time `USDC` object exists.

## Next steps

* [Chains](https://docs.eco.com/sauce-sdk/reference/chains.md), [Tokens](https://docs.eco.com/sauce-sdk/reference/tokens.md) and [Protocols](https://docs.eco.com/sauce-sdk/reference/protocols.md): the registries' contents.
* [Names](https://docs.eco.com/sauce/names.md): how a program uses token symbols, namespaces and `Token(address)`.
* [`sauce globals`](https://docs.eco.com/sauce-sdk/cli/globals): the same names from the command line.
* [Compiling](https://docs.eco.com/sauce-sdk/typescript/compiling.md): `routes.compileSauceProgram` and its `tokens` option.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.