Skip to content

Commit 97e63a4

Browse files
authored
Merge pull request #5 from PolyhedraZK/fix/sdk-v2
Fix/sdk v2
2 parents 034057e + 7d7dbb9 commit 97e63a4

File tree

102 files changed

+6126
-3119
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+6126
-3119
lines changed

.prettierrc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"singleQuote": true,
3+
"jsxSingleQuote": false,
4+
"trailingComma": "es5",
5+
"printWidth": 200,
6+
"proseWrap": "never",
7+
"useTabs": false,
8+
"tabWidth": 2,
9+
"semi": true
10+
}

AGENTS.md

Lines changed: 14 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ The repository is a single-package layout. The root `package.json` is the only d
1313
- SDK source: `src/`
1414
- Build output: `dist/` (publish includes only `dist/` and `assets/`)
1515
- Demos: `demos/` (for showcase/debug only; not published with the SDK)
16-
- Asset build: `pnpm run build:assets` outputs to `assets/`
1716
- Browser demo: `pnpm run dev`
1817
- Node demo: `pnpm run demo:node -- <command>`
1918

@@ -25,6 +24,7 @@ src/ # SDK source (~60 files, ~8400 lines)
2524
index.browser.ts # Browser entry: + IndexedDbStore
2625
index.node.ts # Node entry: + FileStore
2726
types.ts # All type definitions (~850 lines)
27+
errors.ts # Error codes and SdkError
2828
core/ # SdkCore: event bus, init orchestration
2929
crypto/ # Poseidon2, BabyJubjub, key derivation, commitments
3030
wallet/ # WalletService: session, UTXO, balance, memo decrypt
@@ -38,6 +38,10 @@ src/ # SDK source (~60 files, ~8400 lines)
3838
memo/ # MemoKit: ECDH + NaCl secretbox encrypt/decrypt
3939
abi/ # Contract ABIs (Ocash.json compiled ABI, ERC20)
4040
runtime/ # WasmBridge: WASM loading, runtime detect, asset cache
41+
ledger/ # Chain/token/relayer configuration
42+
assets/ # Default assets metadata
43+
abi/ # Contract ABIs
44+
dummy/ # Test data helpers
4145
utils/ # Shared utilities (random, signal, url, bigint)
4246
tests/ # Vitest tests (~38 files)
4347
demos/browser/ # React + Vite + wagmi browser demo
@@ -55,8 +59,6 @@ pnpm run dev # Browser demo (Vite, port 5173)
5559
pnpm run dev:sdk # SDK watch mode (tsup --watch)
5660
pnpm run demo:node -- <cmd> # Run Node demo (requires build)
5761
pnpm run demo:node:tsx -- <cmd> # Run Node demo via tsx
58-
pnpm run build:assets # Build WASM/circuit assets
59-
pnpm run build:assets:local # Build assets including wasm_exec.js
6062
```
6163

6264
## Tech Stack
@@ -100,33 +102,6 @@ The ABI JSON is extracted from the Foundry compiled output (`Ocash.sol/Ocash.jso
100102
- `core.ready()` must be called before any proof/witness operations (loads WASM lazily)
101103
- StorageAdapter is an interface — default MemoryStore is non-persistent
102104

103-
## SDK Modules (Public API)
104-
105-
```
106-
sdk.core — ready(), reset(), on(), off()
107-
sdk.keys — deriveKeyPair(seed, nonce), userPkToAddress(), addressToUserPk()
108-
sdk.crypto — commitment(), nullifier(), createRecordOpening(), memo.createMemo()
109-
sdk.assets — getChains(), getTokens(), syncRelayerConfig()
110-
sdk.storage — getAdapter()
111-
sdk.wallet — open(), close(), getUtxos(), getBalance(), markSpent()
112-
sdk.sync — start(), stop(), syncOnce(), getStatus()
113-
sdk.merkle — getProofByCids(), buildInputSecretsFromUtxos()
114-
sdk.planner — estimate(), estimateMax(), plan()
115-
sdk.zkp — proveTransfer(), proveWithdraw()
116-
sdk.tx — buildTransferCalldata(), buildWithdrawCalldata()
117-
sdk.ops — prepareTransfer(), prepareWithdraw(), prepareDeposit(), submitRelayerRequest()
118-
```
119-
120-
## Cryptography
121-
122-
- Curve: BabyJubjub (twisted Edwards over BN254 scalar field) — pure JS
123-
- Hash: Poseidon2 (commitments, nullifiers, Merkle nodes) — pure JS
124-
- Encryption: ECDH + NaCl XSalsa20-Poly1305 (memo encryption) — tweetnacl
125-
- Key derivation: HKDF-SHA256 — @noble/hashes
126-
- Proofs: Groth16 zk-SNARK — Go WASM (fetched at runtime, not bundled)
127-
- commitment = Poseidon2(asset_id, amount, pk.x, pk.y, blinding_factor)
128-
- nullifier = Poseidon2(commitment, secret_key, merkle_index)
129-
130105
## Testing
131106

132107
- All tests in `tests/` directory, file pattern `{module}.test.ts`
@@ -188,7 +163,7 @@ const sdk = createSdk({
188163
await sdk.core.ready();
189164
await sdk.wallet.open({ seed: 'seed phrase or bytes' });
190165
await sdk.sync.syncOnce();
191-
const balance = await sdk.wallet.getBalance({ chainId: 11155111 });
166+
const balance = await sdk.wallet.getBalance({ chainId, assetId });
192167
```
193168

194169
### 2) Runtime Assets and `assetsOverride`
@@ -733,12 +708,7 @@ export interface MerkleApi {
733708
getProofByCids: (input: { chainId: number; cids: number[]; totalElements: bigint }) => Promise<RemoteMerkleProofResponse>;
734709
getProofByCid: (input: { chainId: number; cid: number; totalElements: bigint }) => Promise<RemoteMerkleProofResponse>;
735710
ingestEntryMemos?: (chainId: number, memos: Array<{ cid: number | null; commitment: Hex | string | bigint }>) => Promise<void> | void;
736-
buildAccMemberWitnesses: (input: {
737-
remote: RemoteMerkleProofResponse;
738-
utxos: Array<{ commitment: Hex; mkIndex: number }>;
739-
arrayHash: bigint;
740-
totalElements: bigint;
741-
}) => AccMemberWitness[];
711+
buildAccMemberWitnesses: (input: { remote: RemoteMerkleProofResponse; utxos: Array<{ commitment: Hex; mkIndex: number }>; arrayHash: bigint; totalElements: bigint }) => AccMemberWitness[];
742712
buildInputSecretsFromUtxos: (input: {
743713
remote: RemoteMerkleProofResponse;
744714
utxos: Array<{ commitment: Hex; memo?: Hex; mkIndex: number }>;
@@ -757,7 +727,7 @@ export interface WalletApi {
757727
open(session: WalletSessionInput): Promise<void>;
758728
close(): Promise<void>;
759729
getUtxos(query?: ListUtxosQuery): Promise<ListUtxosResult>;
760-
getBalance(query?: { chainId?: number; assetId?: string }): Promise<bigint>;
730+
getBalance(query: { chainId: number; assetId: string }): Promise<bigint>;
761731
markSpent(input: { chainId: number; nullifiers: Hex[] }): Promise<void>;
762732
}
763733
```
@@ -766,20 +736,9 @@ export interface WalletApi {
766736

767737
```ts
768738
export interface PlannerApi {
769-
estimate(input: {
770-
chainId: number;
771-
assetId: string;
772-
action: 'transfer' | 'withdraw';
773-
amount: bigint;
774-
payIncludesFee?: boolean;
775-
}): Promise<PlannerEstimateResult>;
739+
estimate(input: { chainId: number; assetId: string; action: 'transfer' | 'withdraw'; amount: bigint; payIncludesFee?: boolean }): Promise<PlannerEstimateResult>;
776740

777-
estimateMax(input: {
778-
chainId: number;
779-
assetId: string;
780-
action: 'transfer' | 'withdraw';
781-
payIncludesFee?: boolean;
782-
}): Promise<PlannerMaxEstimateResult>;
741+
estimateMax(input: { chainId: number; assetId: string; action: 'transfer' | 'withdraw'; payIncludesFee?: boolean }): Promise<PlannerMaxEstimateResult>;
783742

784743
plan(input: Record<string, unknown>): Promise<PlannerPlanResult>;
785744
}
@@ -809,16 +768,7 @@ export interface TxBuilderApi {
809768

810769
```ts
811770
export interface OpsApi {
812-
prepareTransfer(input: {
813-
chainId: number;
814-
assetId: string;
815-
amount: bigint;
816-
to: Hex;
817-
ownerKeyPair: UserKeyPair;
818-
publicClient: PublicClient;
819-
relayerUrl?: string;
820-
autoMerge?: boolean;
821-
}): Promise<
771+
prepareTransfer(input: { chainId: number; assetId: string; amount: bigint; to: Hex; ownerKeyPair: UserKeyPair; publicClient: PublicClient; relayerUrl?: string; autoMerge?: boolean }): Promise<
822772
| {
823773
kind: 'transfer';
824774
plan: TransferPlan;
@@ -858,14 +808,7 @@ export interface OpsApi {
858808
meta: { arrayHashIndex: number; merkleRootIndex: number; relayer: Address };
859809
}>;
860810

861-
prepareDeposit(input: {
862-
chainId: number;
863-
assetId: string;
864-
amount: bigint;
865-
ownerPublicKey: UserPublicKey;
866-
account: Address;
867-
publicClient: PublicClient;
868-
}): Promise<{
811+
prepareDeposit(input: { chainId: number; assetId: string; amount: bigint; ownerPublicKey: UserPublicKey; account: Address; publicClient: PublicClient }): Promise<{
869812
chainId: number;
870813
assetId: string;
871814
amount: bigint;
@@ -908,24 +851,9 @@ export interface OpsApi {
908851
operationId?: string;
909852
}>;
910853

911-
waitRelayerTxHash(input: {
912-
relayerUrl: string;
913-
relayerTxHash: Hex;
914-
timeoutMs?: number;
915-
intervalMs?: number;
916-
signal?: AbortSignal;
917-
operationId?: string;
918-
requestUrl?: string;
919-
}): Promise<Hex>;
854+
waitRelayerTxHash(input: { relayerUrl: string; relayerTxHash: Hex; timeoutMs?: number; intervalMs?: number; signal?: AbortSignal; operationId?: string; requestUrl?: string }): Promise<Hex>;
920855

921-
waitForTransactionReceipt(input: {
922-
publicClient: PublicClient;
923-
txHash: Hex;
924-
timeoutMs?: number;
925-
pollIntervalMs?: number;
926-
confirmations?: number;
927-
operationId?: string;
928-
}): Promise<TransactionReceipt>;
856+
waitForTransactionReceipt(input: { publicClient: PublicClient; txHash: Hex; timeoutMs?: number; pollIntervalMs?: number; confirmations?: number; operationId?: string }): Promise<TransactionReceipt>;
929857

930858
submitRelayerRequest<T = unknown>(input: {
931859
prepared: { plan: TransferPlan | WithdrawPlan; request: RelayerRequest; kind?: 'transfer' | 'merge' };

CLAUDE.md

Lines changed: 20 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,17 @@ The repository is a single-package layout. The root `package.json` is the only d
6262

6363
## Tech Stack
6464

65-
| Layer | Tech |
66-
|---|---|
67-
| Language | TypeScript 5.8 (strict), ES2020 target |
68-
| Build | tsup (ESM + CJS dual format, 3 entry points) |
69-
| Tests | vitest 2.1 (Node env, globals) |
70-
| Crypto | @noble/curves + @noble/hashes + @noble/ciphers + tweetnacl |
71-
| Chain | viem 2.x |
72-
| ZK Proofs | Go WASM circuits (Groth16) via ProofBridge |
73-
| Events | eventemitter3 |
74-
| Package | pnpm 9.15+ |
75-
| Node | 20.19.0+ |
65+
| Layer | Tech |
66+
| --------- | ---------------------------------------------------------- |
67+
| Language | TypeScript 5.8 (strict), ES2020 target |
68+
| Build | tsup (ESM + CJS dual format, 3 entry points) |
69+
| Tests | vitest 2.1 (Node env, globals) |
70+
| Crypto | @noble/curves + @noble/hashes + @noble/ciphers + tweetnacl |
71+
| Chain | viem 2.x |
72+
| ZK Proofs | Go WASM circuits (Groth16) via ProofBridge |
73+
| Events | eventemitter3 |
74+
| Package | pnpm 9.15+ |
75+
| Node | 20.19.0+ |
7676

7777
## Project Structure
7878

@@ -223,7 +223,7 @@ const sdk = createSdk({
223223
await sdk.core.ready();
224224
await sdk.wallet.open({ seed: 'seed phrase or bytes' });
225225
await sdk.sync.syncOnce();
226-
const balance = await sdk.wallet.getBalance({ chainId: 11155111 });
226+
const balance = await sdk.wallet.getBalance({ chainId, assetId });
227227
```
228228

229229
### 2) Runtime Assets and `assetsOverride`
@@ -768,12 +768,7 @@ export interface MerkleApi {
768768
getProofByCids: (input: { chainId: number; cids: number[]; totalElements: bigint }) => Promise<RemoteMerkleProofResponse>;
769769
getProofByCid: (input: { chainId: number; cid: number; totalElements: bigint }) => Promise<RemoteMerkleProofResponse>;
770770
ingestEntryMemos?: (chainId: number, memos: Array<{ cid: number | null; commitment: Hex | string | bigint }>) => Promise<void> | void;
771-
buildAccMemberWitnesses: (input: {
772-
remote: RemoteMerkleProofResponse;
773-
utxos: Array<{ commitment: Hex; mkIndex: number }>;
774-
arrayHash: bigint;
775-
totalElements: bigint;
776-
}) => AccMemberWitness[];
771+
buildAccMemberWitnesses: (input: { remote: RemoteMerkleProofResponse; utxos: Array<{ commitment: Hex; mkIndex: number }>; arrayHash: bigint; totalElements: bigint }) => AccMemberWitness[];
777772
buildInputSecretsFromUtxos: (input: {
778773
remote: RemoteMerkleProofResponse;
779774
utxos: Array<{ commitment: Hex; memo?: Hex; mkIndex: number }>;
@@ -792,7 +787,7 @@ export interface WalletApi {
792787
open(session: WalletSessionInput): Promise<void>;
793788
close(): Promise<void>;
794789
getUtxos(query?: ListUtxosQuery): Promise<ListUtxosResult>;
795-
getBalance(query?: { chainId?: number; assetId?: string }): Promise<bigint>;
790+
getBalance(query: { chainId: number; assetId: string }): Promise<bigint>;
796791
markSpent(input: { chainId: number; nullifiers: Hex[] }): Promise<void>;
797792
}
798793
```
@@ -801,20 +796,9 @@ export interface WalletApi {
801796

802797
```ts
803798
export interface PlannerApi {
804-
estimate(input: {
805-
chainId: number;
806-
assetId: string;
807-
action: 'transfer' | 'withdraw';
808-
amount: bigint;
809-
payIncludesFee?: boolean;
810-
}): Promise<PlannerEstimateResult>;
799+
estimate(input: { chainId: number; assetId: string; action: 'transfer' | 'withdraw'; amount: bigint; payIncludesFee?: boolean }): Promise<PlannerEstimateResult>;
811800

812-
estimateMax(input: {
813-
chainId: number;
814-
assetId: string;
815-
action: 'transfer' | 'withdraw';
816-
payIncludesFee?: boolean;
817-
}): Promise<PlannerMaxEstimateResult>;
801+
estimateMax(input: { chainId: number; assetId: string; action: 'transfer' | 'withdraw'; payIncludesFee?: boolean }): Promise<PlannerMaxEstimateResult>;
818802

819803
plan(input: Record<string, unknown>): Promise<PlannerPlanResult>;
820804
}
@@ -844,16 +828,7 @@ export interface TxBuilderApi {
844828

845829
```ts
846830
export interface OpsApi {
847-
prepareTransfer(input: {
848-
chainId: number;
849-
assetId: string;
850-
amount: bigint;
851-
to: Hex;
852-
ownerKeyPair: UserKeyPair;
853-
publicClient: PublicClient;
854-
relayerUrl?: string;
855-
autoMerge?: boolean;
856-
}): Promise<
831+
prepareTransfer(input: { chainId: number; assetId: string; amount: bigint; to: Hex; ownerKeyPair: UserKeyPair; publicClient: PublicClient; relayerUrl?: string; autoMerge?: boolean }): Promise<
857832
| {
858833
kind: 'transfer';
859834
plan: TransferPlan;
@@ -893,14 +868,7 @@ export interface OpsApi {
893868
meta: { arrayHashIndex: number; merkleRootIndex: number; relayer: Address };
894869
}>;
895870

896-
prepareDeposit(input: {
897-
chainId: number;
898-
assetId: string;
899-
amount: bigint;
900-
ownerPublicKey: UserPublicKey;
901-
account: Address;
902-
publicClient: PublicClient;
903-
}): Promise<{
871+
prepareDeposit(input: { chainId: number; assetId: string; amount: bigint; ownerPublicKey: UserPublicKey; account: Address; publicClient: PublicClient }): Promise<{
904872
chainId: number;
905873
assetId: string;
906874
amount: bigint;
@@ -943,24 +911,9 @@ export interface OpsApi {
943911
operationId?: string;
944912
}>;
945913

946-
waitRelayerTxHash(input: {
947-
relayerUrl: string;
948-
relayerTxHash: Hex;
949-
timeoutMs?: number;
950-
intervalMs?: number;
951-
signal?: AbortSignal;
952-
operationId?: string;
953-
requestUrl?: string;
954-
}): Promise<Hex>;
914+
waitRelayerTxHash(input: { relayerUrl: string; relayerTxHash: Hex; timeoutMs?: number; intervalMs?: number; signal?: AbortSignal; operationId?: string; requestUrl?: string }): Promise<Hex>;
955915

956-
waitForTransactionReceipt(input: {
957-
publicClient: PublicClient;
958-
txHash: Hex;
959-
timeoutMs?: number;
960-
pollIntervalMs?: number;
961-
confirmations?: number;
962-
operationId?: string;
963-
}): Promise<TransactionReceipt>;
916+
waitForTransactionReceipt(input: { publicClient: PublicClient; txHash: Hex; timeoutMs?: number; pollIntervalMs?: number; confirmations?: number; operationId?: string }): Promise<TransactionReceipt>;
964917

965918
submitRelayerRequest<T = unknown>(input: {
966919
prepared: { plan: TransferPlan | WithdrawPlan; request: RelayerRequest; kind?: 'transfer' | 'merge' };

0 commit comments

Comments
 (0)