> ## 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.

# Installation

> Install @opaquecash/opaque, configure WASM, and choose the right signers per operation.

## Install

```bash theme={"dark"}
npm install @opaquecash/opaque
```

Peer dependencies you typically also need:

| Package                   | When                                                                            |
| ------------------------- | ------------------------------------------------------------------------------- |
| `viem`                    | Ethereum reads/writes, wallet clients                                           |
| `@solana/web3.js`         | Solana reads/writes (re-exported transitively)                                  |
| `starknet`                | Starknet reads/writes; wallet broadcast via `EthSigner` (starknet.js v10+)      |
| `@opaquecash/react`       | React apps: provider + hooks over the client ([React hooks](/sdk/react))        |
| `@opaquecash/deployments` | Raw generated addresses/ABIs/program ids ([Deployments](/protocol/deployments)) |

## WASM module

Scanning, sweeping, trait discovery, key reconstruction, and Groth16 witness generation run in a Rust→WASM module ([`opaque-scanner`](https://crates.io/crates/opaque-scanner)). Pass the JS glue URL as `wasmModuleSpecifier`:

```ts theme={"dark"}
await OpaqueClient.create({
  // ...
  wasmModuleSpecifier: "/pkg/cryptography.js",
});
```

### Self-hosting (recommended for production)

Build from the scanner crate:

```bash theme={"dark"}
wasm-pack build --target web --out-dir pkg --out-name cryptography
```

Serve `pkg/cryptography.js` and `pkg/cryptography_bg.wasm` from your app's `public/` directory. The glue file loads the `.wasm` sibling automatically.

<Warning>
  Do not hotlink `https://www.opaque.cash/pkg/cryptography.js` in production. Self-host the artifact so deploys are not blocked by CORS or third-party availability.
</Warning>

### PSR admin without WASM

Schema and attestation management uses pure-JS DKSAP. You can omit `wasmModuleSpecifier` for issuer backends:

```ts theme={"dark"}
const issuer = await OpaqueClient.create({
  chainId: 11155111,
  rpcUrl,
  walletSignature,
  ethereumAddress,
  ethereumWalletClient,  // backend issuer
  // no wasmModuleSpecifier
});

await issuer.createSchema("ethereum", { /* … */ });
```

Calling `scan`, `sweep`, or `generateReputationProof` without WASM throws a clear error.

## Signer matrix

| Operation                                                 | Ethereum                                     | Solana                                         | Starknet                               |
| --------------------------------------------------------- | -------------------------------------------- | ---------------------------------------------- | -------------------------------------- |
| Reads (`getMySchemas`, `scan`, balances)                  | `rpcUrl`                                     | `solana: { connection \| rpcUrl \| cluster }`  | `starknet: {}`                         |
| Writes (`registerMetaAddress`, `sendStealthPayment`, PSR) | `ethereumProvider` or `ethereumWalletClient` | `solanaWallet: { publicKey, signTransaction }` | `build*` methods → app wallet          |
| Scan / sweep / prove                                      | `wasmModuleSpecifier`                        | `wasmModuleSpecifier` + `solana` config        | `wasmModuleSpecifier` + `starknet: {}` |

<Note>
  **Starknet writes don't go through the generic facade.** `sendStealthPayment` and `registerMetaAddress` accept only `ethereum` and `solana`. On Starknet, `buildStarknetStealthSend`, `buildStarknetSweep`, and SNIP-12 on-behalf registration (via [`@opaquecash/stealth-chain-starknet`](/concepts/starknet)) return **unsigned** calls your app's Starknet wallet broadcasts — sweeps go out through a starknet.js `EthSigner` (v10+) and the stealth account self-funds its deploy fee. PSR schema/attestation **issuance** stays on Ethereum and Solana; Starknet does proof **verification and gating** only. Addresses come from `getStarknetDeployment("sepolia")` (packages [`@opaquecash/stealth-chain-starknet`](/concepts/starknet) and [`@opaquecash/psr-chain-starknet`](/concepts/starknet)). Starknet is at **testnet-preview** maturity — see the [Starknet flow](/concepts/starknet).
</Note>

## Backend issuer (Ethereum)

```ts theme={"dark"}
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { sepolia } from "viem/chains";

const account = privateKeyToAccount(process.env.ISSUER_PRIVATE_KEY as `0x${string}`);
const walletClient = createWalletClient({ account, chain: sepolia, transport: http(rpcUrl) });

const client = await OpaqueClient.create({
  chainId: sepolia.id,
  rpcUrl,
  walletSignature: testEntropySignature,
  ethereumAddress: account.address,
  ethereumWalletClient: walletClient,
});
```

## Backend issuer (Solana)

```ts theme={"dark"}
import { Keypair, Transaction } from "@solana/web3.js";

const keypair = Keypair.fromSecretKey(/* … */);

const client = await OpaqueClient.create({
  chainId: 11155111,  // EVM chainId required by config; unused on Solana-only path
  rpcUrl: "https://ethereum-sepolia.publicnode.com",
  walletSignature,
  ethereumAddress: "0x0000000000000000000000000000000000000001",
  solana: { rpcUrl: solanaRpc, cluster: "devnet" },
  solanaWallet: {
    publicKey: keypair.publicKey,
    signTransaction: async (tx: Transaction) => {
      tx.partialSign(keypair);
      return tx;
    },
  },
});
```

## Monorepo / workspace

Link the local package during development:

```json theme={"dark"}
{
  "dependencies": {
    "@opaquecash/opaque": "workspace:*"
  }
}
```

Build the SDK first: `cd sdk && npm install && npm run build`.

## Runnable examples

[`sdk/examples/`](https://github.com/opaquecash/sdk/tree/main/examples) ships one
runnable script per flow:

| Example           | Flow                                                                 |
| ----------------- | -------------------------------------------------------------------- |
| `from-wallet.ts`  | Build a client from a unified signer (offline)                       |
| `scan.ts`         | Unified cross-chain inbox scan + balances (read-only)                |
| `send.ts`         | Stealth send with optional delayed announcement (spends testnet ETH) |
| `psr-prove.ts`    | Generate and verify a Groth16 reputation proof (offline)             |
| `uab-readonly.ts` | Build a cross-chain announce request + read UAB inbox (read-only)    |

```bash theme={"dark"}
cd sdk && npm run build
npx tsx examples/from-wallet.ts
```
