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

# Quickstart

This is the ten minute path. One linear flow, no theory, running against the sandbox. By the end you will have created an account, funded it on testnet, made a private transfer, and withdrawn.

:::steps

### Get your credentials

You need three things from your Kakushi operator account: a `zoneId`, an `environment`, and an `apiKey`. The apiKey proves you are an operator on the zone and authorizes account setup and operator-tier reads. It is not a signing key: moving funds is always signed by the account you supply.

### Install the SDK

```bash
npm install @kakushi/sdk
```

### Initialize the client

```ts
import { Kakushi } from "@kakushi/sdk";

const kakushi = new Kakushi({
  zoneId: "zone_sandbox_123",
  environment: "sandbox",
  apiKey: process.env.KAKUSHI_API_KEY!,
});
```

There is no signer at init, and the SDK never holds keys. You pass an account to sign with wherever signing happens: the account you hold for custodial accounts, or the user's own account for non-custodial. It is a standard viem or ethers account. See [Accounts and custody](/concepts/accounts-and-custody).

### Create an account

You hold the account's key in your own secret store (in production). For the sandbox, generate one and wrap it as a viem account to pass in; the SDK signs the token that claims the account.

```ts
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";

// sandbox throwaway; in production, load the key from your own secret store
const alicePrivateKey = generatePrivateKey();
const aliceAccount = privateKeyToAccount(alicePrivateKey);

// the account is its address; tag it with your own labels in metadata
const { address, virtualAddress } = await kakushi.accounts.create({
  account: aliceAccount,
  metadata: { customerId: "user_001" },
});
```

### Get a deposit address and fund it

Creating the account already returned a first deposit address. Allocate a fresh one per payer or invoice whenever you want attribution:

```ts
import { privateKeyToAccount } from "viem/accounts";

// the account that owns the deposit address (its key from your secret store)
const aliceAccount = privateKeyToAccount(alicePrivateKey);

const { virtualAddress } = await kakushi.accounts.createVirtualAddress({
  account: aliceAccount,
  metadata: { reference: "first_deposit" },
});
```

Send testnet USDC to that address from the [faucet](/connect-and-evm-reference). When the deposit is detected and credited, you will receive a `deposit.credited` webhook, and the balance will appear in the zone.

### Make a private transfer

```ts
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";

// create user_002 so it can receive
const bobPrivateKey = generatePrivateKey();
const bobAccount = privateKeyToAccount(bobPrivateKey);
const { address: bobAddress } = await kakushi.accounts.create({
  account: bobAccount,
  metadata: { customerId: "user_002" },
});

// user_001's account signs the transfer (its key from your secret store)
const aliceAccount = privateKeyToAccount(alicePrivateKey);

await kakushi.transfers.create({
  to: bobAddress,        // a zone address
  amount: "25.00",
  token: "USDC",
  account: aliceAccount, // source is aliceAccount.address
  idempotencyKey: "transfer_001",
});
```

This transfer happens entirely inside the zone. It is instant, it costs nothing on the host chain, and it leaves no public trace.

### Withdraw

```ts
import { privateKeyToAccount } from "viem/accounts";

// user_002's account signs its own withdrawal (its key from your secret store)
const bobAccount = privateKeyToAccount(bobPrivateKey);

await kakushi.withdrawals.create({
  to: "0xRecipientOnBase",
  amount: "25.00",
  token: "USDC",
  account: bobAccount, // source is bobAccount.address
  idempotencyKey: "withdrawal_001",
});
```

The representation is burned in the zone and the canonical USDC is released from the portal to the host-chain address. That release is the only part of this entire sequence the public can see.

:::

That is the full lifecycle. Everything else in these docs is depth on each step.
