Skip to content

Commit c061b4a

Browse files
niconiconiclaude
andcommitted
docs: add standard llms.txt and llms-full.txt for AI coding tools
Restructure llms.txt to follow llmstxt.org standard: concise index linking to doc pages, plus llms-full.txt with complete API context. Add prominent AI-Friendly Context section to both EN and ZH homepages. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 31101af commit c061b4a

File tree

4 files changed

+326
-42
lines changed

4 files changed

+326
-42
lines changed

docs/index.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,13 @@ features:
2323
- title: Modular Architecture
2424
details: Factory pattern with event-driven modules — core, wallet, sync, planner, ops, and more. Compose what you need.
2525
---
26+
27+
<div style="margin-top: 2rem; padding: 1.5rem; border-radius: 8px; background: var(--vp-c-bg-soft); text-align: center;">
28+
29+
### AI-Friendly Context
30+
31+
Building with AI coding tools? Feed them our SDK context for accurate code generation.
32+
33+
[`llms.txt`](/llms.txt) — Index &nbsp;&nbsp;|&nbsp;&nbsp; [`llms-full.txt`](/llms-full.txt) — Full API context
34+
35+
</div>

docs/public/llms-full.txt

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
# @ocash/sdk
2+
3+
> TypeScript ZKP SDK for privacy-preserving token operations via UTXO model and zk-SNARK proofs.
4+
5+
## Install
6+
7+
```bash
8+
pnpm add @ocash/sdk
9+
```
10+
11+
Three entry points:
12+
- `@ocash/sdk` — universal (MemoryStore)
13+
- `@ocash/sdk/browser` — browser (+ IndexedDbStore)
14+
- `@ocash/sdk/node` — Node.js (+ FileStore)
15+
16+
## Quick Start
17+
18+
```ts
19+
import { createSdk } from '@ocash/sdk';
20+
21+
const sdk = createSdk({
22+
chains: [{
23+
chainId: 11155111,
24+
entryUrl: 'https://entry.example.com',
25+
ocashContractAddress: '0x...',
26+
relayerUrl: 'https://relayer.example.com',
27+
merkleProofUrl: 'https://merkle.example.com',
28+
tokens: [],
29+
}],
30+
onEvent: (event) => console.log(event.type, event.payload),
31+
});
32+
33+
await sdk.core.ready(); // Load WASM & circuits
34+
await sdk.wallet.open({ seed: 'your-secret-seed' }); // Derive keys, init storage
35+
await sdk.sync.syncOnce(); // Sync memos, nullifiers, merkle
36+
const balance = await sdk.wallet.getBalance({ chainId: 11155111 });
37+
await sdk.wallet.close(); // Release keys, flush storage
38+
```
39+
40+
## SDK Modules
41+
42+
sdk.core — WASM & circuit initialization (ready, reset)
43+
sdk.keys — BabyJubjub key derivation (deriveKeyPair, userPkToAddress, addressToUserPk)
44+
sdk.crypto — Commitments, nullifiers, memo encryption (commitment, nullifier, createRecordOpening)
45+
sdk.assets — Chain/token/relayer configuration (getChains, getTokens, syncRelayerConfig)
46+
sdk.storage — Persistence adapter (upsertUtxos, listUtxos, markSpent, getSyncCursor)
47+
sdk.wallet — Session, UTXOs, balance (open, close, getUtxos, getBalance, markSpent)
48+
sdk.sync — Memo/nullifier/Merkle sync (start, stop, syncOnce, getStatus)
49+
sdk.merkle — Merkle proofs & membership witnesses (getProofByCids, buildInputSecretsFromUtxos)
50+
sdk.planner — Coin selection, fee estimation (estimate, estimateMax, plan)
51+
sdk.zkp — zk-SNARK proof generation (proveTransfer, proveWithdraw)
52+
sdk.tx — Relayer request builder (buildTransferCalldata, buildWithdrawCalldata)
53+
sdk.ops — End-to-end orchestration (prepareTransfer, prepareWithdraw, prepareDeposit, submitRelayerRequest)
54+
55+
## Configuration
56+
57+
```ts
58+
interface OCashSdkConfig {
59+
chains: ChainConfigInput[]; // Required: chain configurations
60+
assetsOverride?: AssetsOverride; // WASM/circuit file URLs (string or string[] for chunks)
61+
storage?: StorageAdapter; // Default: MemoryStore
62+
runtime?: 'auto' | 'browser' | 'node' | 'hybrid';
63+
cacheDir?: string; // Node/hybrid: local asset cache directory
64+
merkle?: { mode?: 'remote' | 'local' | 'hybrid'; treeDepth?: number };
65+
sync?: { pageSize?: number; pollMs?: number; requestTimeoutMs?: number; retry?: { attempts?: number; baseDelayMs?: number; maxDelayMs?: number } };
66+
onEvent?: (event: SdkEvent) => void; // Event callback
67+
}
68+
69+
interface ChainConfigInput {
70+
chainId: number;
71+
rpcUrl?: string; // JSON-RPC URL
72+
entryUrl?: string; // Entry Service (memo/nullifier sync)
73+
ocashContractAddress?: Address; // OCash contract
74+
relayerUrl?: string; // Relayer service
75+
merkleProofUrl?: string; // Merkle proof service
76+
tokens?: TokenMetadata[];
77+
}
78+
79+
interface TokenMetadata {
80+
id: string; symbol: string; decimals: number; wrappedErc20: Address;
81+
viewerPk: [string, string]; freezerPk: [string, string];
82+
depositFeeBps?: number; withdrawFeeBps?: number;
83+
transferMaxAmount?: bigint | string; withdrawMaxAmount?: bigint | string;
84+
}
85+
```
86+
87+
## Transfer
88+
89+
```ts
90+
const keyPair = sdk.keys.deriveKeyPair(seed, nonce);
91+
92+
// Estimate fees first
93+
const estimate = await sdk.planner.estimate({
94+
chainId: 11155111, assetId: 'token-id', action: 'transfer', amount: 500000n,
95+
});
96+
// estimate.feeSummary.mergeCount / relayerFeeTotal / protocolFeeTotal
97+
98+
// Max transferable
99+
const max = await sdk.planner.estimateMax({
100+
chainId: 11155111, assetId: 'token-id', action: 'transfer',
101+
});
102+
// max.maxSummary.outputAmount
103+
104+
// Prepare (plan → merkle proof → witness → zk-SNARK proof → relayer request)
105+
const prepared = await sdk.ops.prepareTransfer({
106+
chainId: 11155111, assetId: 'token-id', amount: 500000n,
107+
to: recipientViewingAddress, // Hex: BabyJubjub compressed address
108+
ownerKeyPair: keyPair,
109+
publicClient, // viem PublicClient
110+
});
111+
112+
// Submit to relayer
113+
const result = await sdk.ops.submitRelayerRequest({ prepared, publicClient });
114+
const txHash = await result.waitRelayerTxHash;
115+
const receipt = await result.transactionReceipt;
116+
```
117+
118+
If more than 3 UTXOs needed, prepareTransfer returns `{ kind: 'merge' }` with merge steps. The planner handles this automatically with `autoMerge: true` (default).
119+
120+
## Withdraw
121+
122+
```ts
123+
const prepared = await sdk.ops.prepareWithdraw({
124+
chainId: 11155111, assetId: 'token-id', amount: 500000n,
125+
recipient: '0x1234...abcd', // EVM address to receive tokens
126+
ownerKeyPair: keyPair, publicClient,
127+
gasDropValue: 10000000000000000n, // Optional: 0.01 ETH gas drop
128+
});
129+
const result = await sdk.ops.submitRelayerRequest({ prepared, publicClient });
130+
```
131+
132+
## Deposit
133+
134+
```ts
135+
const ownerPub = sdk.keys.getPublicKeyBySeed(seed, nonce);
136+
const prepared = await sdk.ops.prepareDeposit({
137+
chainId: 11155111, assetId: 'token-id', amount: 1000000n,
138+
ownerPublicKey: ownerPub,
139+
account: walletAddress, // Depositor's EOA
140+
publicClient,
141+
});
142+
143+
// ERC-20 approval if needed
144+
if (prepared.approveNeeded && prepared.approveRequest) {
145+
await walletClient.writeContract(prepared.approveRequest);
146+
}
147+
await walletClient.writeContract(prepared.depositRequest);
148+
149+
// Or use submitDeposit for auto-approve:
150+
const result = await sdk.ops.submitDeposit({
151+
prepared, walletClient, publicClient, autoApprove: true,
152+
});
153+
```
154+
155+
## Key Management
156+
157+
```ts
158+
// Derive key pair (seed must be >= 16 characters)
159+
const keyPair = sdk.keys.deriveKeyPair('my-secret-seed', 'optional-nonce');
160+
// keyPair.user_sk.address_sk: bigint (secret key)
161+
// keyPair.user_pk.user_address: [bigint, bigint] (BabyJubjub public key)
162+
163+
// Public key only (no secret key exposure)
164+
const pubKey = sdk.keys.getPublicKeyBySeed(seed, nonce);
165+
166+
// Compress to viewing address
167+
const address = sdk.keys.userPkToAddress(pubKey); // 0x... (32 bytes)
168+
169+
// Decompress back
170+
const pk = sdk.keys.addressToUserPk(address);
171+
```
172+
173+
## Sync
174+
175+
```ts
176+
// One-shot sync
177+
await sdk.sync.syncOnce({
178+
chainIds: [11155111],
179+
resources: ['memo', 'nullifier', 'merkle'],
180+
signal: abortController.signal,
181+
});
182+
183+
// Background polling
184+
await sdk.sync.start({ pollMs: 10_000 });
185+
sdk.sync.stop(); // Stops polling + aborts in-flight sync
186+
187+
// Check status
188+
const status = sdk.sync.getStatus();
189+
// { 11155111: { memo: { status: 'synced', downloaded: 1291 }, ... } }
190+
```
191+
192+
## Storage Adapters
193+
194+
```ts
195+
import { MemoryStore } from '@ocash/sdk';
196+
import { IndexedDbStore } from '@ocash/sdk/browser';
197+
import { FileStore } from '@ocash/sdk/node';
198+
199+
new MemoryStore({ maxOperations: 100 })
200+
new IndexedDbStore({ dbName: 'myapp', maxOperations: 200 })
201+
new FileStore({ baseDir: './data', maxOperations: 500 })
202+
```
203+
204+
Required interface methods:
205+
- upsertUtxos(utxos: UtxoRecord[]): Promise<void>
206+
- listUtxos(query?: ListUtxosQuery): Promise<{ total: number; rows: UtxoRecord[] }>
207+
- markSpent(input: { chainId: number; nullifiers: Hex[] }): Promise<number>
208+
- getSyncCursor(chainId: number): Promise<SyncCursor | undefined>
209+
- setSyncCursor(chainId: number, cursor: SyncCursor): Promise<void>
210+
211+
## Events
212+
213+
All events via `onEvent` callback. Union type `SdkEvent`:
214+
215+
- core:ready — { assetsVersion, durationMs }
216+
- core:progress — { stage: 'fetch'|'compile'|'init', loaded, total? }
217+
- sync:start — { chainId }
218+
- sync:progress — { chainId, resource: 'memo'|'nullifier'|'merkle', downloaded, total? }
219+
- sync:done — { chainId, cursor }
220+
- wallet:utxo:update — { chainId, added, spent, frozen }
221+
- zkp:start — { circuit: 'transfer'|'withdraw' }
222+
- zkp:done — { circuit, costMs }
223+
- error — { code: SdkErrorCode, message, detail?, cause? }
224+
225+
Error codes: CONFIG | ASSETS | STORAGE | SYNC | CRYPTO | MERKLE | WITNESS | PROOF | RELAYER
226+
227+
## Key Types
228+
229+
```ts
230+
type Hex = `0x${string}`;
231+
232+
interface UtxoRecord {
233+
chainId: number; assetId: string; amount: bigint;
234+
commitment: Hex; nullifier: Hex; mkIndex: number;
235+
isFrozen: boolean; isSpent: boolean; memo?: Hex; createdAt?: number;
236+
}
237+
238+
interface CommitmentData {
239+
asset_id: bigint; asset_amount: bigint;
240+
user_pk: { user_address: [bigint, bigint] };
241+
blinding_factor: bigint; is_frozen: boolean;
242+
}
243+
244+
interface SyncCursor { memo: number; nullifier: number; merkle: number; }
245+
246+
type OperationType = 'deposit' | 'transfer' | 'withdraw';
247+
type OperationStatus = 'pending' | 'submitted' | 'confirmed' | 'failed';
248+
249+
interface ProofResult { proof: string; publicInputs: string[]; }
250+
interface RelayerRequest { kind: 'relayer'; method: 'POST'; path: string; body: Record<string, unknown>; }
251+
```
252+
253+
## Cryptography
254+
255+
- Curve: BabyJubjub (twisted Edwards over BN254 scalar field)
256+
- Hash: Poseidon2 (commitments, nullifiers, Merkle nodes)
257+
- Encryption: ECDH + NaCl XSalsa20-Poly1305 (memo encryption)
258+
- Key derivation: HKDF-SHA256 (seed → spending key)
259+
- Proofs: Groth16 zk-SNARK (Go WASM, transfer & withdraw circuits)
260+
- commitment = Poseidon2(asset_id, amount, pk.x, pk.y, blinding_factor)
261+
- nullifier = Poseidon2(commitment, secret_key, merkle_index)
262+
263+
## Static Utilities
264+
265+
```ts
266+
import { MemoKit, CryptoToolkit, KeyManager, Utils } from '@ocash/sdk';
267+
268+
MemoKit.createMemo(recordOpening) // Encrypt record opening → Hex memo
269+
MemoKit.decodeMemoForOwner({ secretKey, memo }) // Decrypt memo → CommitmentData | null
270+
271+
CryptoToolkit.commitment(data) // Poseidon2 commitment
272+
CryptoToolkit.nullifier(secretKey, commitment) // Nullifier derivation
273+
CryptoToolkit.createRecordOpening({ assetId, amount, userPk })
274+
275+
Utils.calcDepositFee(amount, feeBps) // Protocol fee calculation
276+
Utils.randomBytes32Bigint() // Cryptographic random bigint
277+
```

docs/public/llms.txt

Lines changed: 29 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,31 @@
11
# @ocash/sdk
22

3-
> TypeScript ZKP SDK for privacy-preserving token operations via UTXO model and zk-SNARK proofs.
4-
5-
## Install
6-
7-
```bash
8-
pnpm add @ocash/sdk
9-
```
10-
11-
Three entry points:
12-
- `@ocash/sdk` — universal (MemoryStore)
13-
- `@ocash/sdk/browser` — browser (+ IndexedDbStore)
14-
- `@ocash/sdk/node` — Node.js (+ FileStore)
15-
16-
## Quick Start
17-
18-
```ts
19-
import { createSdk } from '@ocash/sdk';
20-
21-
const sdk = createSdk({
22-
chains: [{
23-
chainId: 11155111,
24-
entryUrl: 'https://entry.example.com',
25-
ocashContractAddress: '0x...',
26-
relayerUrl: 'https://relayer.example.com',
27-
merkleProofUrl: 'https://merkle.example.com',
28-
tokens: [],
29-
}],
30-
onEvent: (event) => console.log(event.type, event.payload),
31-
});
32-
33-
await sdk.core.ready();
34-
await sdk.wallet.open({ seed: 'your-secret-seed' });
35-
await sdk.sync.syncOnce();
36-
const balance = await sdk.wallet.getBalance({ chainId: 11155111 });
37-
await sdk.wallet.close();
38-
```
39-
40-
## Lifecycle
41-
42-
createSdk(config) → sdk.core.ready() → sdk.wallet.open({ seed }) → sdk.sync.start() → sdk.ops.* → sdk.wallet.close()
43-
44-
## Full API Reference: docs.o.cash
3+
> TypeScript ZKP SDK for privacy-preserving token operations — deposit, transfer, and withdraw via UTXO model and zk-SNARK proofs (Groth16, Go WASM). Headless, multi-environment (browser, Node.js, Electron/Tauri), modular factory pattern.
4+
5+
## Docs
6+
7+
- [Getting Started](https://docs.o.cash/guide/getting-started): Installation, quick start, lifecycle
8+
- [Configuration](https://docs.o.cash/guide/configuration): OCashSdkConfig, chains, assetsOverride, sync, runtime
9+
- [Architecture](https://docs.o.cash/guide/architecture): Module system, crypto stack, proof flow
10+
- [UTXO Model](https://docs.o.cash/guide/utxo-model): Commitments, nullifiers, Merkle tree, transactions
11+
- [Storage Adapters](https://docs.o.cash/guide/storage): MemoryStore, IndexedDbStore, FileStore, KV, Redis, SQLite
12+
- [Events & Errors](https://docs.o.cash/guide/events): SdkEvent union type, error codes
13+
- [Deposit](https://docs.o.cash/guide/deposit): Shield tokens into the privacy pool
14+
- [Transfer](https://docs.o.cash/guide/transfer): Private transfers with auto-merge
15+
- [Withdraw](https://docs.o.cash/guide/withdraw): Unshield tokens to EVM address
16+
17+
## API Reference
18+
19+
- [createSdk](https://docs.o.cash/api/sdk): Factory function, OCashSdk modules
20+
- [Core](https://docs.o.cash/api/core): ready(), reset()
21+
- [Wallet](https://docs.o.cash/api/wallet): open, close, getUtxos, getBalance, markSpent
22+
- [Keys & Crypto](https://docs.o.cash/api/crypto): deriveKeyPair, commitment, nullifier, MemoKit
23+
- [Sync](https://docs.o.cash/api/sync): start, stop, syncOnce, getStatus
24+
- [Planner](https://docs.o.cash/api/planner): estimate, estimateMax, plan
25+
- [Ops](https://docs.o.cash/api/ops): prepareTransfer, prepareWithdraw, prepareDeposit, submitRelayerRequest
26+
- [Storage](https://docs.o.cash/api/storage): StorageAdapter interface, built-in adapters
27+
- [Types](https://docs.o.cash/api/types): Hex, UtxoRecord, CommitmentData, SyncCursor, ProofResult
28+
29+
## Optional
30+
31+
- [Full LLM context](https://docs.o.cash/llms-full.txt): Complete API signatures, examples, and type definitions

docs/zh/index.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,13 @@ features:
2323
- title: 模块化架构
2424
details: 工厂模式配合事件驱动的模块体系 — core、wallet、sync、planner、ops 等。按需组合使用。
2525
---
26+
27+
<div style="margin-top: 2rem; padding: 1.5rem; border-radius: 8px; background: var(--vp-c-bg-soft); text-align: center;">
28+
29+
### AI 编程工具上下文
30+
31+
使用 AI 编程工具?将 SDK 上下文喂给它,获得准确的代码生成。
32+
33+
[`llms.txt`](/llms.txt) — 索引 &nbsp;&nbsp;|&nbsp;&nbsp; [`llms-full.txt`](/llms-full.txt) — 完整 API 上下文
34+
35+
</div>

0 commit comments

Comments
 (0)