<!--
Sitemap:
- [Interop SDK Documentation](/index): Build multichain TypeScript apps with interoperable addresses, cross-chain quotes, transfer execution, and order tracking across providers.
- [Install Interop SDK](/installation): Install @wonderland/interop-addresses and @wonderland/interop-cross-chain, then choose the package that fits your multichain app.
- [Addresses Module](/addresses/): Parse, encode, and resolve chain-aware addresses that combine an account, chain, and optional ENS name into one unambiguous identifier.
- [Addresses: Getting Started](/addresses/getting-started): Parse an interoperable address and extract its components — go from a human-readable name like vitalik.eth@eip155:1 to address and chain ID.
- [Addresses: Concepts](/addresses/concepts): How EIP-7930, ERC-7828, and CAIP-350 combine address and chain into a single, unambiguous, validated identifier for multichain apps.
- [Parsing an Interoperable Name](/addresses/example): Walkthrough for wallet developers — extract the raw address and chain ID from an interop address so legacy contracts keep working.
- [Addresses: Advanced Usage](/addresses/advanced-usage): Advanced patterns for interoperable addresses — checksums, validation, error handling, and round-trip conversions between formats.
- [Addresses: API Reference](/addresses/api): Function signatures and types for the interop-addresses package — high-level helpers, name-layer methods, and binary-layer primitives.
- [Cross-Chain Module](/cross-chain/): One open source integration for cross-chain actions — compare quotes across providers, execute orders, and track completion.
- [Cross-Chain: Getting Started](/cross-chain/getting-started): Execute a cross-chain token transfer end-to-end — create a provider, fetch a quote, send the transaction, and track the order to completion.
- [Cross-Chain: Concepts](/cross-chain/concepts): The intent-based architecture behind the cross-chain package and how the SDK unifies heterogeneous bridge providers behind a common interface.
- [Supported Providers](/cross-chain/providers): Supported cross-chain providers (Across, Relay, OIF, Bungee, LiFi Intents) and how to configure each via createCrossChainProvider.
- [Across Provider](/cross-chain/across-provider): Configure and use the Across Protocol provider for cross-chain token transfers via the Across bridge infrastructure.
- [Relay Provider](/cross-chain/relay-provider): Configure and use the Relay Protocol provider for cross-chain transfers, including opt-in gasless execution via EIP-3009 signatures.
- [OIF Provider](/cross-chain/oif-provider): Direct integration with any OIF-compliant solver — submission modes, resource locks, and configuration for Open Intents Framework backends.
- [Bungee Provider](/cross-chain/bungee-provider): Cross-chain token transfers via Bungee — onchain transactions, gasless permit2 flow, and tier-based API access for sandbox or production.
- [LiFi Intents Provider](/cross-chain/lifi-intents-provider): Cross-chain transfers through the LI.FI intent solver marketplace, where competing solvers fulfill deposits at the best available rate.
- [Cross-Chain: Full Example](/cross-chain/example): End-to-end example of executing a cross-chain transfer — setup, quote, approval handling, transaction submission, and order tracking.
- [Cross-Chain: Frontend Integration](/cross-chain/frontend-integration): Wire the cross-chain SDK into a React/Next.js app with wagmi v2 — a useCrossChainSwap hook covering quotes, approvals, and submission.
- [Order Tracking](/cross-chain/order-tracking): Track cross-chain orders from initiation to completion via OIF OrderStatus events, with both onchain and offchain observation strategies.
- [Cross-Chain: Advanced Usage](/cross-chain/advanced-usage): Aggregator patterns for cross-chain transfers — multi-provider quote fetching, sorting strategies, timeouts, and built-in order tracking.
- [Cross-Chain: API Reference](/cross-chain/api): Function signatures and types for the interop-cross-chain package — providers, aggregator, approval service, and order tracking.
-->

# Addresses: Concepts

This page explains the standards behind interoperable addresses and how the package implements them.

## The problem

An Ethereum address like `0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045` doesn't say *which chain* the account is on. In a multichain world, this ambiguity leads to lost funds, broken UIs, and manual chain selection.

Interoperable addresses solve this by encoding the **chain alongside the address** in a single, standardized format — in two complementary ways.

## Human-readable: ERC-7828

[ERC-7828](https://eips.ethereum.org/EIPS/eip-7828) defines a readable name format designed for end-users, wallets, and UIs:

```
vitalik.eth@ethereum
0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045@eip155:10#1A2B3C4D
```

The format is: `{address}@{chain}`, with an optional `#{checksum}` suffix.

What makes it user-friendly:

* **ENS names** work directly — `vitalik.eth` instead of a raw hex address
* **Chain shortnames** like `ethereum`, `base`, or `optimism` resolve automatically via an onchain registry
* **Checksums** (4 bytes, calculated from the binary form) catch typos and detect tampering
* Fully-qualified CAIP-2 identifiers (`eip155:1`) also work when precision matters

This is what users see and what apps display.

## Onchain-optimized: EIP-7930

[EIP-7930](https://eips.ethereum.org/EIPS/eip-7930) defines a compact binary format optimized for smart contracts, where minimal byte size directly reduces gas costs:

```
0x00010000010114d8da6bf26964af9d7eed9e03e53415d37aa96045
```

The binary encodes a version byte, chain type, chain reference, and the address into a single byte sequence — no ambiguity, no resolution needed. This is the format smart contracts pass around and store onchain.

## How they relate

Both formats carry the same information. A human-readable ERC-7828 name resolves to the same structured address that EIP-7930 serializes into bytes:

```
vitalik.eth@eip155:1  ←→  { chainType: "eip155", chainReference: "1", address: "0xd8dA..." }  ←→  0x0001...
      (name)                              (structured address)                                    (binary)
```

A third standard, [CAIP-350](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-350.md), defines chain-type-specific rules for representing binary fields as text:

* **eip155**: Chain references as decimal strings, addresses as hex with EIP-55 checksumming
* **bip122**: Chain references as 32-char lowercase hex (genesis hash prefix), addresses as base58check or bech32/bech32m
* **solana**: Base58 encoding for both chain references and addresses

## Package API design

The package API reflects the two formats:

* **Functions that work with names** (`parseName`, `nameToBinary`, `getAddress`, `getChainId`) are **async** — they may need to resolve ENS names or chain shortnames over the network.
* **Functions that work with binary/structured addresses** (`encodeAddress`, `decodeAddress`, `formatName`, `binaryToName`) are **sync** — everything is already resolved.

<Mermaid
  chart={`graph TD
  A[InteroperableName]
  B[InteroperableAddress]
  C[Binary Address]

  A -->|"parseName (async)"| B
  A -->|"nameToBinary (async)"| C
  B -->|"encodeAddress (sync)"| C
  B -->|"formatName (sync)"| A
  C -->|"decodeAddress (sync)"| B
  C -->|"binaryToName (sync)"| A`}
/>

The structured `InteroperableAddress` in the middle is a discriminated union — it can hold either text strings or raw bytes:

```typescript
// Text variant — human-friendly strings
{ version: 1, chainType: "eip155", chainReference: "1", address: "0xd8dA..." }

// Binary variant — raw bytes
{ version: 1, chainType: Uint8Array, chainReference: Uint8Array, address: Uint8Array }
```

Use `isTextAddress()` or `isBinaryAddress()` type guards to narrow the union.

## Chain resolution

When a name uses a chain shortname (e.g., `@ethereum` instead of `@eip155:1`), the SDK resolves it using a two-tier strategy:

1. **Onchain**: Queries the `on.eth` ENS registry on Ethereum mainnet. The registry maps labels like `ethereum` to their ERC-7930 binary representation.
2. **Offchain fallback**: Uses the chainid.network registry to map shortnames to chain IDs.

Both are enabled by default. Fully-qualified CAIP-2 identifiers (e.g., `eip155:10`) skip resolution entirely.

You can customize resolution behavior per call:

```typescript
// Disable onchain, use offchain only (chainid.network uses "eth" shortname)
await parseName("0x...@eth", { onchainRegistry: false });

// Custom registry domain
await parseName("0x...@ethereum", { onchainRegistry: "custom.eth" });

// Custom RPC URL for onchain resolution
await parseName("0x...@ethereum", { rpcUrl: "https://my-rpc.example.com" });
```

## Checksums

Checksums protect against typos and address tampering. The checksum is the first 4 bytes of the keccak-256 hash of the address's ERC-7930 binary encoding — the chain type, chain reference, and address (everything except the version) — rendered as 8 uppercase hex characters and appended to the name after a `#`. Because the chain is part of the input, the same address on a different chain produces a different checksum:

```
0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045@eip155:1#4CA88C9C
```

The trailing `#4CA88C9C` is the checksum.

Per [ERC-7828](https://eips.ethereum.org/EIPS/eip-7828), a checksum **should not be appended when the address component is an ENS name** (e.g. `vitalik.eth@base`). ENS names resolve to addresses that can change over time, so a stored checksum may stop validating even when resolution is correct, and ENS already handles its own name normalization and validation.

When parsing, the SDK compares any checksum present in the input against the value it calculates and reports a mismatch via `result.meta.checksumMismatch`.

## References

* [EIP-7930: Interoperable Addresses](https://eips.ethereum.org/EIPS/eip-7930)
* [ERC-7828: Readable Interoperable Addresses using ENS](https://eips.ethereum.org/EIPS/eip-7828)
* [CAIP-350: Interoperable Addresses](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-350.md)
