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

# Cross-chain API

> UAB methods for relaying and scanning cross-chain stealth announcements.

Cross-chain flows use the Universal Announcement Bus (Wormhole). UAB must be configured for the client's `chainId` (bundled on Sepolia) or passed via `contracts`.

## Build relay

### `buildAnnounceWithRelayRequest(send, opts?)`

Ethereum: build `{ to, data, value }` for `announceWithRelay`. `value` is the Wormhole message fee.

```ts theme={"dark"}
const send = client.prepareStealthSend(metaAddressHex);
const req = await client.buildAnnounceWithRelayRequest(send, {
  consistencyLevel: undefined,
});
await walletClient.sendTransaction({
  to: req.to,
  data: req.data,
  value: req.value,
});
```

***

### `buildAnnounceWithRelay(chain, send, opts?)`

Discriminated builder for Ethereum or Solana.

```ts theme={"dark"}
// Ethereum
const evm = await client.buildAnnounceWithRelay("ethereum", send);
// { chain: "ethereum", to, data, value, chainId }

// Solana
const sol = await client.buildAnnounceWithRelay("solana", send, {
  batchId: 1,
  wormholeFee: undefined,  // auto-fetched
});
// { chain: "solana", instructions, signers }
```

**Solana note:** `signers` includes the Wormhole message keypair, which must co-sign with `solanaWallet`.

***

## Fetch and scan

### `fetchCrossChainAnnouncements(opts?)`

Read inbound UAB announcements as indexer-shaped rows.

```ts theme={"dark"}
const rows = await client.fetchCrossChainAnnouncements({
  fromBlock: 5_000_000n,
  toBlock: "latest",
});
```

***

### `scanCrossChain(opts?)`

Fetch + WASM filter to owned outputs from UAB only.

```ts theme={"dark"}
const owned = await client.scanCrossChain();
```

***

## Bundled in send / unified scan

`sendStealthPayment({ relay: true })` calls the relay path internally.

`scan({ includeCrossChain: true })` merges UAB outputs with `source: "uab"` (default when UAB is deployed and Ethereum is scanned).

```ts theme={"dark"}
const inbox = await client.scan({
  chains: ["ethereum"],
  includeCrossChain: true,
});
```

***

## Low-level UAB exports

Re-exported from `@opaquecash/uab` via `@opaquecash/opaque`:

```ts theme={"dark"}
import {
  fetchVaa,
  getUabDeployment,
  requireUabDeployment,
  CONSISTENCY_FINALIZED,
  CONSISTENCY_SAFE,
  WORMHOLESCAN_TESTNET,
} from "@opaquecash/opaque";
```

Payload codec from `@opaquecash/stealth-core`:

```ts theme={"dark"}
import {
  encodeUabPayload,
  decodeUabPayload,
  UAB_PAYLOAD_LENGTH,
} from "@opaquecash/opaque";
```

***

## Relayer

VAAs must be delivered to `UABReceiver` on the destination chain. Use [`opaquecash/relayer`](https://github.com/opaquecash/relayer) for off-chain delivery.

See [Cross-chain announcements](/concepts/cross-chain).

***

## Starknet

Starknet is a native scan chain (not a UAB/Wormhole path). Enable it with the
`starknet` client option, then include it in `scan`:

```ts theme={"dark"}
const client = await OpaqueClient.create({ /* … */, starknet: {} });

const inbox = await client.scan({ chains: ["ethereum", "solana", "starknet"] });
```

### `buildStarknetStealthSend({ recipient, amount, token? })`

Returns the counterfactual stealth account and the unsigned `transfer` +
`announce` calls to broadcast in one multicall from a Starknet wallet.

### `buildStarknetSweep({ output, destination, amount, token? })`

Returns the reconstructed signer key, the `deploy_account` parameters, and the
transfer-out call for the recipient to broadcast (Eth signer).

Full flow and caveats: [Starknet](/concepts/starknet).
