<!--
Sitemap:
- [Welcome to Kakushi 隠し](/index): Kakushi is a private execution layer for institutions building on stablecoin rails.
- [What is Kakushi](/introduction/what-is-kakushi): Money is private.
- [Using Kakushi with AI](/introduction/using-kakushi-with-ai): Every page in these docs is available as plain markdown for use with language models.
- [Quickstart](/quickstart): This is the ten minute path.
- [Zones and the trust model](/concepts/zones-and-trust): A zone is a private blockchain only you can see inside, with a public chain's proofs underneath.
- [The portal](/concepts/the-portal): Money walks in as public USDC and becomes private the moment it crosses.
- [Accounts and custody](/concepts/accounts-and-custody): Your existing wallet address is already a Kakushi account. Nothing to deploy, nothing to enroll.
- [Bring your own address](/concepts/bring-your-own-address): A zone account is just an address, the one an auth key recovers to, with nothing deployed.
- [Virtual addresses](/concepts/virtual-addresses): Hand every customer their own address, the way a bank hands out virtual account numbers.
- [Private transfers](/concepts/private-transfers): Pay fifty thousand people and publish zero salaries.
- [Settlement and composability](/concepts/settlement-and-composability): Two institutions settle in real time without sharing a ledger or seeing each other's books.
- [Private deposits and withdrawals](/concepts/private-deposits-and-withdrawals): Soon, even the edges go dark.
- [Proofs and the verifier](/concepts/proofs-and-the-verifier): You cannot fake a balance, and you can prove you are solvent without showing a single customer.
- [Fees and gas](/concepts/fees-and-gas): Your users never hold ETH and never see gas. They pay in the dollars they are already sending.
- [Privacy and disclosure](/concepts/privacy-and-disclosure): The public sees nothing, you see everything, the regulator sees what the law entitles them to.
- [Zone policies](/concepts/zone-policies): Compliance is built into the zone. You configure your program; the substrate enforces it on every transfer.
- [Onboard a customer](/guides/onboard-a-customer): Two calls and a webhook, and your customer has a private on-chain account.
- [Accept deposits](/guides/accept-deposits): Anyone with funds on the host chain can pay into your zone, and it lands as a private balance for your user.
- [Make private transfers](/guides/private-transfers): One call moves money privately. One call pays a whole payroll.
- [Process withdrawals](/guides/withdrawals): Burn inside, release canonical USDC outside, in one call.
- [Settle between zones](/guides/settle-between-zones): Send money to another institution's zone like it is a withdrawal. It is interbank settlement.
- [Handle webhooks](/guides/webhooks): React to money moving. Do not poll for it.
- [Reconcile](/guides/reconcile): Two numbers that must always match. Assert it on a schedule.
- [Non-custodial integration](/guides/non-custodial-integration): The user signs on their device. You never hold the key, and you still cannot move their money.
- [Compliance and disclosure](/guides/compliance): You hold the whole record. Disclosure is an export, not a negotiation with the protocol.
- [SDK reference](/sdk-reference): The look-it-up layer.
- [Connect and EVM reference](/connect-and-evm-reference): The chain-level integration detail.
- [Run a zone](/run-a-zone): Most operators never run any infrastructure.
- [Protocol spec](/protocol-spec): The deep technical layer, for auditors and engineers integrating below the SDK.
- [Resources](/resources): See Key concepts for the working vocabulary, expanded throughout Core concepts.
-->

# SDK reference

The look-it-up layer. The SDK is the primary surface, and most integrations never touch Rust or the contracts directly.

**Conventions.**

* **Amounts** are decimal money-unit strings, for example `"100.00"`. Never wei, never floats.
* **Accounts** are referenced by address. The signing account's address is its identity; attach your own labels (a `customerId`, an invoice id) in `metadata`.
* **Mutations** take an `idempotencyKey`. Reusing a key returns the original result instead of acting twice.
* **Errors** are typed and carry a stable `code`. Pagination uses `cursor` and `limit`.

**Initialization.**

```ts
new Kakushi({ zoneId: string, environment: "sandbox" | "production", apiKey: string })
```

**accounts**

```ts
accounts.create({ account, metadata?, idempotencyKey? })   // returns { address, virtualAddress }; account signs the claim, created lazily on first deposit
accounts.get(address)
accounts.createVirtualAddress({ account, metadata? })      // returns { virtualAddress }
accounts.listVirtualAddresses(account)                     // all deposit addresses for the account
```

The virtual-address methods map to the zone RPC `zone_getDepositAddress` (allocate one) and `zone_getDepositAddresses` (list all).

**balances**

```ts
balances.get(account, { token })   // reads as the owner; reference by account or address
balances.list(account)
```

**deposits**

```ts
deposits.list({ account?, virtualAddress?, cursor?, limit? })
deposits.getAttribution(depositId)
```

**transfers**

```ts
transfers.create({ to, amount, token, account, idempotencyKey })   // source is account.address; `to` is a zone address
transfers.batch({ transfers: [{ to, amount, token }], account, idempotencyKey })   // one source account
transfers.get(transferId)
transfers.list({ account?, cursor?, limit? })
transfers.prepare({ from, to, amount, token })   // split signing: no signer present, so `from` is explicit; returns { unsignedTx }
transfers.submit(signedTx)                        // submits over the authenticated RPC
```

**withdrawals**

```ts
withdrawals.create({ to, amount, token, account, idempotencyKey })   // source is account.address; `to` is a host-chain address
withdrawals.get(withdrawalId)
withdrawals.estimateFee({ account, amount, token })
withdrawals.prepare({ from, to, amount, token })  // split signing: `from` is explicit
withdrawals.submit(signedTx)
```

**webhooks**

```ts
webhooks.configure({ url, events })
webhooks.verify(rawBody, signatureHeader)          // returns the typed event
```

**reconciliation**

```ts
reconciliation.getLockedBalance({ token })
reconciliation.getZoneSupply({ token })
```

**compliance**

```ts
compliance.exportAuditTrail({ account?, from, to })   // from / to are dates
```

**auth**

```ts
auth.createToken(account, { expiresIn? })   // signs a kzt auth token with the account you pass
```

<Callout variant="note">
  **Signers.** A signer is a viem `Account` or an ethers `Signer`, obtained with viem: `privateKeyToAccount` for a custodial key you hold in your own secret store, or the wallet's viem account (for example `toViemAccount`) for non-custodial signing. The SDK reads the address off it and signs through it, and holds no keys of its own. You supply the account where signing happens (the account you hold for custodial, the user's account for non-custodial), never at client init. Passkey and smart-account signing arrive in V2.
</Callout>
