@zethub/bridge

Introduction

A signer agnostic SDK for native USDC transfers over Circle CCTP V2 across EVM chains and Stellar.

@zethub/bridge moves native USDC across chains using Circle CCTP V2. It burns USDC on the source chain, waits for Circle to attest the message, and mints on the destination chain. It works across EVM chains and Stellar, in both directions.

The SDK never touches keys. Every on chain write returns an unsigned RawTransaction for you to sign and broadcast with the wallet library you already use. That includes viem, ethers, wagmi, Freighter, Lobstr, Stellar Wallets Kit, or anything else.

Start here

Design

  • Bring your own signer. Every write returns a typed RawEvmTransaction or RawSorobanTransaction. You sign it however you already sign transactions.
  • Discover, do not configure. sdk.chainDetailsMap() returns every supported network with its supported tokens. You pick a TokenWithChainDetails and pass it back.
  • Small config surface. RPC overrides, environment, and optionally transfer persistence. No signers, no service overrides, no advanced escape hatch.
  • Extensible. Adding a new chain family is one interface, IChainConnector. The bridge router does not care.

The flow in ten lines

import { ZetHubBridge, NetworkId, AssetSymbol } from "@zethub/bridge";

const sdk = new ZetHubBridge();
const chains = await sdk.chainDetailsMap();
const from = chains[NetworkId.BASE].tokens[0];
const to = chains[NetworkId.STELLAR].tokens[0];

// 1. Build the burn tx
const burnTx = await sdk.bridge.rawTxBuilder.send({
  sourceToken: from,
  destinationToken: to,
  amount: "1.0",
  fromAccountAddress: myEvmAddress,
  toAccountAddress: myStellarAddress,
});

// 2. You sign and broadcast it however you like
const burnHash = await mySignAndBroadcast(burnTx);

// 3. Wait for Circle to attest
const att = await sdk.attestation.waitFor(NetworkId.BASE, burnHash);

// 4. Build the mint tx on the destination
const mintTx = await sdk.bridge.rawTxBuilder.receive({
  destinationToken: to,
  toAccountAddress: myStellarAddress,
  message: att.message,
  attestation: att.attestation,
});

// 5. Sign and broadcast the mint
await mySignAndBroadcast(mintTx);

That is the whole SDK. See Quick start for a full runnable example, or Bridging for a per route walkthrough.

On this page