# Quickstart

### 1. Create a React + Typescript Project

Let's create a simple vite project with React and Typescript:

```bash
npm create vite@latest sdk-test -- --template react-ts
```

### 2. Install Dependencies

Install `shielder-sdk` and additional dependencies:

```bash
npm install @cardinal-cryptography/shielder-sdk@0.3.0-rc.3
npm install @cardinal-cryptography/shielder-sdk-crypto@0.3.0-rc.1
npm install @cardinal-cryptography/shielder-sdk-crypto-wasm-light@0.3.0-rc.2
npm install viem @types/node @vitejs/plugin-react
```

### 3. Configure Vite

Add following code to `vite.config.ts` :

{% code title="vite.config.ts" %}

```typescript
import * as path from "path";
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

// https://vite.dev/config/
export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./src"),
    },
  },
  optimizeDeps: {
    exclude: ["@cardinal-cryptography/shielder-sdk-crypto-wasm-light"],
  },
});

```

{% endcode %}

### 4. Set Up WASM Cryptography Client

Create a file `src/shielderWasm.ts` , where we'll set up the wasm engine loading.

Note, that in quickstart guide we use a light wasm client, which is simple to set up, but currently is in alpha stage. Refer to [Cryptography Client](/integration-guides/cryptography-client.md) for production-ready setup details.

PCR values can be found at [Github Releases](https://github.com/Cardinal-Cryptography/blanksquare-monorepo/releases), for example [pcr-92cd84c.json](https://github.com/Cardinal-Cryptography/blanksquare-monorepo/releases/tag/prover-server-v0.2.0)

{% code title="src/shielderWasm.ts" %}

```typescript
import { initWasmWorker } from "@cardinal-cryptography/shielder-sdk-crypto-wasm-light";

// values from releases page
const pcrs = new Map<string, string>(
  Object.entries({
    "0": "94b74422daddb8f503fcd69df064c7cde5d053001b9cd153c75ec34484283496a37e89c7287a00f467759a6863362b60",
    "1": "927e084e583f5c2d60a39e2b9cd9728bfb390aa9f83dee4b6ac768509850ba273ea8b019ccfbf3180eb18a2dd0c4a678",
    "2": "07c20c057d5c10cb732b273b7fa26a2b67e333344ccda49be939a6b7c5bed5e46f0b0703386dd2d0f6104a13a4894cb2",
  })
);

// WASM crypto client
export const wasmCryptoClientRead = (async () => {
  return initWasmWorker("https://prover-server.test.blanksquare.dev", pcrs);
})();

```

{% endcode %}

### 5. Initialize the Shielder SDK Client

Create `src/shielder.ts:`

{% code title="src/shielder.ts:" %}

```typescript
import {
  createShielderClient,
  type ShielderOperation,
} from "@cardinal-cryptography/shielder-sdk";
import { createPublicClient, http } from "viem";
import { baseSepolia } from "viem/chains";
import { wasmCryptoClientRead } from "./shielderWasm";

const chain = baseSepolia;

const shielderContractAddress =
  "0x2098a5f59DAB63F1a2aB7C0715DA437D1efB012B" as `0x${string}`;

const relayerUrl = "https://base-testnet-shielder-relayer-v3.test.blanksquare.dev";

export const publicClient = createPublicClient({
  chain,
  transport: http(),
});

// Simple in-memory key-value storage
const shielderStorage: Map<string, string> = new Map();

// 66-character (0x prefix + 64 hex symbols) of account private key
const shieldedAccountPrivateKey = "0x..." as `0x${string}`;

export async function initializeShielderClient() {
  return createShielderClient({
    shielderSeedPrivateKey,
    chainId: BigInt(chain.id),
    // Note: cast publicClient to 'any' for compatibility
    publicClient: publicClient as any,
    contractAddress: shielderContractAddress,
    relayerUrl,
    storage: {
      getItem: async (key: string) => {
        return shielderStorage.get(key) || null;
      },
      setItem: async (key: string, value: string) => {
        shielderStorage.set(key, value);
      },
    },
    cryptoClient: await wasmCryptoClientRead,
    callbacks: {
      onAccountNotOnChain: async (
        error: unknown,
        stage: string,
        operation: ShielderOperation
      ) => {
        console.error("Account not on chain:", error, stage, operation);
      },
      onSdkOutdated: async (
        error: unknown,
        stage: string,
        operation: ShielderOperation
      ) => {
        console.error("SDK outdated:", error, stage, operation);
      },
    },
  });
}
```

{% endcode %}

### 6. Verify the Setup

In your main file (e.g. `src/main.tsx` or `src/App.tsx`):

```typescript
import { initializeShielderClient } from "./shielder";
import { nativeToken } from "@cardinal-cryptography/shielder-sdk";

(async () => {
  // Initialize the SDK client
  const shielder = await initializeShielderClient();
  // Sync the account state from chain
  await shielder.syncShielder();
  
  // Get the native token representation
  const token = nativeToken();
  
  // Query your current account state (balance, nonce.)
  const accountState = await shielder.accountState(token);

  // Log the result to console (should be null at this point)
  console.log("Account:", accountState);
})();
```

At this point, your app is connected to the Shielder network, has synced the private account, and can query its state.\\

Next steps:

* To shield tokens (i.e. deposit), see: [Shielding Tokens](/integration-guides/shielding-tokens.md)
* To withdraw tokens back to a public address, see: [Withdrawing Tokens](/integration-guides/withdrawing-tokens.md)

Both operations require working with token approvals, gas fees, and relayer coordination. For a comprehensive understanding of all fee structures and costs involved, see [Understanding Fees](/integration-guides/fees.md).

We recommend you handle those through user-facing components in your app UI.

Explore the guides to implement full privacy flow.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.blanksquare.io/integration-guides/quickstart.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
