@b402ai/kohaku
v0.1.0
Published
b402 execution adapter for Kohaku-compatible wallets and apps.
Maintainers
Readme
@b402ai/kohaku
A b402 execution adapter for Kohaku-compatible wallets and apps.
The package implements a Kohaku-style plugin using
@kohaku-eth/plugins types and routes execution through the b402 SDK. Wallets
and apps get a small privacy surface for users:
- view shielded balances
- prepare shield and unshield operations
- execute shield and unshield through b402
- expose private swap, lend, and redeem actions as explicit extensions
The end-user value is simple: privacy actions can be initiated from a familiar wallet or app flow while b402 handles the execution path behind the adapter.
Who This Is For
Wallet teams can use this adapter to add a privacy plugin surface without building Railgun/b402 execution plumbing into the wallet itself.
App developers can use the same runtime to offer private actions such as swap, lend, and redeem without inventing a separate app-specific privacy API.
SDK evaluators can run the examples and smoke tests to inspect the integration boundary: Kohaku-compatible types at the edge, b402 execution underneath.
Why It Matters
Most privacy flows force users into a separate app. This adapter is structured for the wallet and app surface where users already make decisions:
- the wallet can show shielded balances next to an account
- the user can prepare an operation before execution
- app-level private DeFi actions can share the same runtime and account context
- transaction hashes stay redacted in examples by default
User Flow
A wallet can register the adapter as a Kohaku-compatible plugin:
- The user connects a wallet or account.
- The app reads
plugin.instanceId()andplugin.balance(). - The user prepares a shield or unshield action.
- The prepared operation executes through
b402.execute(...). - The app refreshes status and shows updated private balances.
Apps that want higher-level private actions can use the execution extensions:
execution.privateSwap(...)execution.privateLend(...)execution.privateRedeem(...)
These are intentionally separate from the minimal plugin surface so wallet integrators can start with balances and shield/unshield before enabling private DeFi actions.
Supported Surface
| Capability | Surface | Status |
| ------------------- | ------------------------------- | ------------------------------------------- |
| Shielded balance | plugin.balance() | Supported on Base through b402 status |
| Raw b402 status | plugin.rawStatus() | Supported |
| Shield | plugin.prepareShield() | Supported |
| Unshield | plugin.prepareUnshield() | Supported to the runtime smart wallet |
| Private swap | execution.privateSwap() | Supported, with env-gated live smoke test |
| Private lend | execution.privateLend() | SDK-backed extension, needs live smoke test |
| Private redeem | execution.privateRedeem() | SDK-backed extension, needs live smoke test |
| Private cross-chain | execution.privateCrossChain() | Experimental |
The default token registry and live tests are Base-oriented.
Install
npm install @b402ai/kohaku @b402ai/sdkFor local development beside the SDK repo:
cd ../b402-sdk
npm install
npm run build
cd ../b402-kohaku
npm install --omit=peer
npm run verifyBasic Usage
import { createB402KohakuRuntime } from '@b402ai/kohaku';
const runtime = await createB402KohakuRuntime({
b402: {
privateKey: process.env.B402_PRIVATE_KEY,
chainId: 8453,
rpcUrl: process.env.B402_RPC_URL,
facilitatorUrl: process.env.B402_FACILITATOR_URL,
backendApiUrl: process.env.B402_BACKEND_API_URL,
},
plugin: {
chainId: 8453,
},
});
const accountId = await runtime.plugin.instanceId();
const privateBalances = await runtime.plugin.balance();
const result = await runtime.execution.privateSwap({
from: 'USDC',
to: 'WETH',
amount: '0.01',
slippageBps: 75,
});How Execution Works
The adapter depends on a b402 client with:
status(): Promise<B402StatusResult>;
execute(params: B402ExecuteParams): Promise<B402ExecuteResult>;plugin.balance() calls status() and maps shieldedBalances into
Kohaku-style AssetAmount<ERC20AssetId> values.
Prepared shield and unshield operations are lazy. Calling prepareShield() or
prepareUnshield() returns an operation preview. Calling operation.execute()
dispatches the matching b402 action:
await client.execute({ action: 'shield', token: 'USDC', amount: '1' });
await client.execute({ action: 'unshield', token: 'USDC', amount: '1' });The extension layer uses the same dispatcher:
await client.execute({ action: 'privateSwap', from: 'USDC', to: 'WETH', amount: '0.01' });
await client.execute({ action: 'privateLend', amount: '1', vault: 'steakhouse' });
await client.execute({ action: 'privateRedeem', vault: 'steakhouse' });Examples
Run the live private swap smoke test only when you intentionally want to execute against a funded b402 environment:
B402_E2E_SWAP=1 npm run test:e2e:swapDevelopment Checks
npm run verify
npm audit --omit=dev --omit=peer
npm pack --dry-runnpm run verify runs TypeScript, ESLint, Prettier, unit tests, and the local
secret scan.
Security
- Never commit
.envfiles or private keys. - Transaction hashes from private runs should be treated as sensitive metadata.
- Public examples should prefer redacted output, reproducible commands, and test results over posting transaction links.
