# Core SDK

`@tonado/core` is the shared TypeScript SDK that powers the CLI, the relayer, and any third-party integration. It exposes the protocol's primitives: note generation, commitments, Merkle proofs, Groth16 proving, deployment registry, and high-level deposit/withdraw flows.

Workspace-internal for now. Structured so it can be published to npm as `@tonado/core` (or as `tonado-ts`, the EVM-equivalent npm name) by flipping `"private": true` to `false` in `package.json`.

## Layout

| File              | Purpose                                                                                    |
| ----------------- | ------------------------------------------------------------------------------------------ |
| `constants.ts`    | `MERKLE_TREE_HEIGHT`, `ROOT_HISTORY_SIZE`, `FIELD_SIZE_BLS12_381`, `ZERO_VALUE`, op codes. |
| `types.ts`        | All TS types: `Deposit`, `ParsedNote`, `WithdrawalArgs`, etc.                              |
| `deployments.ts`  | Registry of deployed pool addresses per network.                                           |
| `poseidon.ts`     | Poseidon over BLS12-381 (must agree with `poseidon.tolk` and the circuit).                 |
| `commitment.ts`   | `createDeposit`: generates `(nullifier, secret)` → derives commitment + nullifier hash.    |
| `notes.ts`        | Note string parsing/building, invoice URLs.                                                |
| `merkleTree.ts`   | Off-chain mirror of the on-chain commitment tree.                                          |
| `proof.ts`        | snarkjs Groth16-BLS12-381 prove / verify.                                                  |
| `tonClient.ts`    | TonClient factory + address ↔ field-element helpers.                                       |
| `jettons.ts`      | TEP-74 helpers for jetton pool deposits.                                                   |
| `indexer.ts`      | Toncenter-backed scanner that decodes pool log out-messages.                               |
| `pool.ts`         | Typed `TonadoPool` wrapper (mirrors Acton wrapper API).                                    |
| `depositFlow.ts`  | High-level `depositNative` / `depositJetton`.                                              |
| `withdrawFlow.ts` | High-level `buildWithdrawArgs` (load tree + prove + assemble).                             |
| `walletLoader.ts` | Mnemonic → wallet (v4R2 / v5R1).                                                           |

## Artifacts

Circuit artifacts live in [`packages/core/artifacts/`](https://github.com/tonadocash/monorepo/tree/main/packages/core/artifacts):

* `withdraw.wasm` (\~500KB)
* `withdraw_final.zkey` (\~50MB after ceremony)
* `verification_key.json`

Produced by `pnpm circuits:compile` in `apps/contracts/`.

## Top-level exports

```ts
import {
  parseNote,
  buildNote,
  generateNote,
  createDeposit,
  buildMerkleTree,
  merkleProofForLeaf,
  generateProof,
  verifyProof,
  TonadoPool,
  buildWithdrawArgs,
  depositNative,
  depositJetton,
  makeTonClient,
  deployments,
  getPool,
} from "@tonado/core";
```

## Typical usage

### Generating and saving a note

```ts
import { generateNote, createDeposit } from "@tonado/core";

const note = generateNote({ asset: "ton", amount: "1", network: "testnet" });
// note.string  → "tonado-ton-1-testnet-0x..."
// note.deposit → { nullifier, secret, commitment, nullifierHash }

// Persist note.string somewhere safe.
```

### Submitting a deposit

```ts
import { depositNative, makeTonClient } from "@tonado/core";

const client = makeTonClient({
  network: "testnet",
  apiKey: process.env.TONCENTER_API_KEY!,
});

const result = await depositNative({
  client,
  mnemonic: process.env.DEPOSITOR_MNEMONIC!,
  amount: "1",
  network: "testnet",
});

// result.note  → the note string to save
// result.seqno → wallet seqno of the deposit tx
```

### Querying a pool

```ts
import { Address } from "@ton/core";
import { makeTonClient, getPool, TonadoPool } from "@tonado/core";

const client = makeTonClient({ network: "testnet", apiKey: process.env.TONCENTER_API_KEY! });
const pool = getPool("testnet", "ton", "1")!;
const handle = TonadoPool.at(Address.parse(pool.address));
const provider = client.provider(handle.address);

const root      = await handle.getCurrentRoot(provider);
const nextIndex = await handle.getNextIndex(provider);
const denom     = await handle.getDenomination(provider);

console.log({ root: root.toString(16), nextIndex, denom });
```

### Checking if a specific note has been withdrawn

```ts
import { parseNote, TonadoPool, getPool } from "@tonado/core";

const note = await parseNote("tonado-ton-1-testnet-0x...");
const pool = getPool("testnet", "ton", "1")!;
const handle = TonadoPool.at(Address.parse(pool.address));

const spent = await handle.getIsSpent(provider, note.deposit.nullifierHash);
console.log("Spent?", spent);
```

### Scanning pool events

For event-by-event decoding of pool transactions:

```ts
import { scanPoolTransactions } from "@tonado/core";

const result = await scanPoolTransactions(client, {
  pool: Address.parse(pool.address),
  maxTransactions: 100,
});

for (const event of result.events) {
  console.log("Deposit", event.commitment, event.leafIndex, event.timestamp);
}
```

For continuous indexing, prefer the relayer's `indexerWorker`. It persists to Postgres and handles cursor management.

### Building a withdrawal client-side

This is what `tonado withdraw relay` does internally:

```ts
import { parseNote, buildWithdrawArgs } from "@tonado/core";

const note = await parseNote("tonado-ton-1-testnet-0x...");

const args = await buildWithdrawArgs({
  note,
  recipient: "EQRecipient...",
  relayer: "EQRelayer...",
  fee: 50_000_000n,         // 0.05 TON
  refund: 0n,
  client,
});

// args.proof          → the Groth16 proof
// args.publicSignals  → the 6 public inputs
// Send args to a relayer's POST /withdraw, OR submit directly via TonadoPool.sendWithdraw(...)
```

## Things that must agree across the system

| Surface                        | Source of truth                                                                                                                         |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| Poseidon round constants & MDS | The compiled circom WASM.                                                                                                               |
| Off-chain prover Poseidon      | `packages/core/src/poseidon.ts`, uses the circom WASM under the hood.                                                                   |
| Address-to-field encoding      | `addressToFieldElement` in `packages/core/src/tonClient.ts`. The on-chain pool reverses this when constructing the public-signals cell. |
| Note format                    | `notes.ts`, read/write. The deployer script and the relayer both depend on this exact format.                                           |
| Proof cell serialisation       | `pool.ts :: serialiseGroth16Proof`, must match the bit layout the auto-generated `verifier.tolk` expects.                               |

If any of these drift between the prover and the verifier, proofs will silently mis-verify. CI runs parity checks on every PR. Don't override or skip them.


---

# 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.tonadocash.com/for-developers/sdk-core.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.
