This repository is a monorepo consisting of the following packages:
@wonderland/interop-addresses: A utility library for interoperable addresses based on ERC-7930.@wonderland/interop-cross-chain: A library for cross-chain interoperability
interop-sdk/
├── apps/ # Application packages
│ ├── addresses-landing-page/ # Interoperable Addresses landing page
│ ├── docs/ # Documentation website
│ └── sdk/ # SDK application
├── packages/ # Shared packages
│ ├── addresses/ # Address-related utilities (ERC-7930/ERC-7828)
│ ├── cross-chain/ # Cross-chain interoperability
├── examples/ # Example implementations
│ └── ui/ # UI examples
├── .github/ # GitHub configuration
├── .husky/ # Git hooks
└── ...config files
- Node.js 20.x
- pnpm 9.7.1 or later
-
Install dependencies
pnpm install
-
Build all packages
pnpm build
-
Format code
pnpm format
-
Run tests
pnpm test -
Run E2E tests (UI examples)
pnpm --filter @examples/ui test:e2e
The addresses package provides utilities for handling interoperable blockchain addresses across different networks.
Address Formats:
- Human-readable (Interoperable Name):
0x...@eip155:1#ABCD1234- Use for display, configuration, and user-facing interfaces - Binary hex:
0x0001000000010114...- Use for on-chain operations, ERC-7683 intents, and smart contract interactions
Both formats are interchangeable - convert between them as needed for your use case.
import { encodeAddress, InteropAddressProvider } from "@wonderland/interop-addresses";
// Convert between human-readable (interoperable name) and binary addresses
const interoperableName = "alice.eth@eip155:1#ABCD1234";
const binaryAddress = await InteropAddressProvider.nameToBinary(interoperableName);
// Returns: "0x0001000000010114d8da6bf26964af9d7eed9e03e53415d37aa96045"
const backToName = InteropAddressProvider.binaryToName(binaryAddress);
// Returns: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045@eip155:1#ABCD1234"
// Get the underlying address for a chain
const address = await InteropAddressProvider.getAddress(interoperableName);
// Returns: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
// Validate addresses
const isValid = await InteropAddressProvider.isValidInteropAddress(interoperableName);
// Create binary addresses programmatically (without parsing a name string)
const binaryHex = encodeAddress(
{
version: 1,
chainType: "eip155",
chainReference: "11155111", // Sepolia
address: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
},
{ format: "hex" },
);The cross-chain package provides a standardized interface for cross-chain operations.
import { createCrossChainProvider } from "@wonderland/interop-cross-chain";
// Create a provider - Across works with no config (defaults to mainnet)
// Mainnet: https://app.across.to/api
// Testnet: https://testnet.across.to/api
const provider = createCrossChainProvider("across");
// Or with custom configuration for testnet
const testnetProvider = createCrossChainProvider("across", { isTestnet: true });
// Get quotes using OIF format (addresses must be EIP-7930 binary format: 0x0001...)
// Use nameToBinary() from @wonderland/interop-addresses to convert human-readable addresses
const quotes = await provider.getQuotes({
user: "0x0001000aa36a7114...", // binary format address
intent: {
intentType: "oif-swap",
inputs: [
{
user: "0x0001000aa36a7114...",
asset: "0x0001000aa36a7114...",
amount: "1000000000000000000",
},
],
outputs: [{ receiver: "0x0001000149d4114...", asset: "0x0001000149d4114..." }],
swapType: "exact-input",
},
supportedTypes: ["across"], // required by OIF request shape; ignored by Across
});
// OIF provider requires configuration
const oifProvider = createCrossChainProvider("oif", {
solverId: "my-solver",
url: "https://oif-api.example.com",
});This project uses changesets for version management.
When you make changes to any package:
- Make changes to one or more packages
- Create changeset:
pnpm changeset- Select which packages changed
- Choose change type (patch/minor/major)
- Write a description of the change
- Commit only the changeset file (
.changeset/random-name.md) - Open PR and merge to dev
Important: Do NOT run pnpm version-packages during development. Changesets accumulate in .changeset/ directory.
When ready to publish a new version:
- Apply all accumulated changesets:
pnpm version-packages- Reads all pending changesets
- Calculates new versions
- Updates package.json files
- Generates/updates CHANGELOGs
- Deletes applied changesets
- Commit version bumps and CHANGELOGs
- Push to GitHub
- Publish via GitHub Actions (manual workflow dispatch in Actions tab)
See .changeset/README.md for more details.
This project is maintained by Wonderland — a team of top Web3 researchers, developers, and operators who believe that the future needs to be open-source, permissionless, and decentralized. We welcome outside contributions.
- Large changes — please open an issue first to discuss your proposal before investing time in a PR.
- Small changes (bug fixes, typos, minor improvements) — PRs are welcome directly.
- Fork the repo and create your branch from
dev. - Make your changes and ensure
pnpm build,pnpm lint, andpnpm testpass. - If your change modifies a publishable package (
packages/addresses,packages/cross-chain, orapps/sdk), create a changeset:Select the affected packages, choose the appropriate bump level (patch / minor / major), and write a short description. Commit the generatedpnpm changeset
.changeset/*.mdfile with your PR. - If your change adds or modifies public API surface, update the relevant documentation:
- Package README (
packages/*/README.md) - Docs site (
apps/docs/docs/) - Inline JSDoc on exported functions and types
- Package README (
- Run
/review-interop-sdk(see below) to catch common issues before requesting human review. - Open your PR against
devand fill in the template.
We follow the Conventional Commits specification.
This repo includes a shared review skill at .claude/skills/review-interop-sdk/. Invoke it from any compatible AI agent to get a project-aware review of your changes:
/review-interop-sdk
It checks the current branch diff (or a specific PR) against the project's TypeScript rules, changeset policy, documentation requirements, and test coverage expectations.
This project is licensed under the MIT License. See the LICENSE file for details.