@veilo/sdk-core 0.1.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +439 -0
- package/package.json +42 -0
- package/src/client.ts +352 -0
- package/src/config.ts +13 -0
- package/src/index.ts +6 -0
- package/src/merkle.ts +178 -0
- package/src/note.ts +193 -0
- package/src/poseidon.ts +62 -0
- package/src/proof.ts +170 -0
- package/test/script.js +0 -0
- package/test-tsconfig.json +19 -0
- package/tests/note.test.ts +50 -0
- package/tests/sdk.integration.test.ts +210 -0
- package/tsconfig.json +18 -0
package/README.md
ADDED
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
# @zkprivacysol/sdk-core
|
|
2
|
+
|
|
3
|
+
Tiny TypeScript SDK for the `privacy-pool` Anchor program.
|
|
4
|
+
|
|
5
|
+
This package wraps the on-chain program with a small set of ergonomic helpers for:
|
|
6
|
+
|
|
7
|
+
- Deriving PDAs (`config`, `vault`, `note_tree`, `nullifiers`)
|
|
8
|
+
- Initializing the pool with fixed SOL denominations
|
|
9
|
+
- Depositing using a note commitment + **off-chain Merkle root**
|
|
10
|
+
- Withdrawing via an authorized relayer (with fee + TVL accounting)
|
|
11
|
+
- Building simple Merkle roots off-chain (for demo / testing)
|
|
12
|
+
- Handling note commitments (`createRandomNote`, `commitNote`, etc.)
|
|
13
|
+
|
|
14
|
+
> **Status:** internal/dev SDK. No production guarantees.
|
|
15
|
+
> ZK verification is expected to happen **off-chain in a relayer service**.
|
|
16
|
+
> On-chain, `proof: Vec<u8>` is treated as opaque bytes (hook for a future verifier).
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 1. Install
|
|
21
|
+
|
|
22
|
+
From the monorepo root (or inside the package folder):
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
cd packages/sdk-core
|
|
26
|
+
npm install
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
If you publish it somewhere later:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install @zkprivacysol/sdk-core
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 2. Prerequisites
|
|
38
|
+
|
|
39
|
+
You need:
|
|
40
|
+
|
|
41
|
+
- A running Solana validator (localnet recommended):
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
solana-test-validator
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
- The `privacy-pool` program built and deployed to that validator.
|
|
48
|
+
- The `privacy-pool` Anchor IDL available (the SDK tests load it from):
|
|
49
|
+
|
|
50
|
+
```text
|
|
51
|
+
../../privacy-pool/target/idl/privacy_pool.json
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
- A funded keypair on that validator:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
solana config set --url http://127.0.0.1:8899
|
|
58
|
+
solana-keygen new --outfile ~/.config/solana/id.json
|
|
59
|
+
solana airdrop 10
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Environment variables for tests:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
export ANCHOR_PROVIDER_URL=http://127.0.0.1:8899
|
|
66
|
+
export ANCHOR_WALLET=$HOME/.config/solana/id.json
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 3. Build & Test
|
|
72
|
+
|
|
73
|
+
From `packages/sdk-core`:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Typecheck & build to dist/
|
|
77
|
+
npm run build
|
|
78
|
+
|
|
79
|
+
# Run unit + integration tests
|
|
80
|
+
npm test
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
What the tests do:
|
|
84
|
+
|
|
85
|
+
- **Unit tests (`note.test.ts`)**
|
|
86
|
+
- `createRandomNote` / `encodeNoteToBytes` / `commitNote` / `createNoteWithCommitment`
|
|
87
|
+
- Ensures 32-byte commitments, deterministic encoding, etc.
|
|
88
|
+
|
|
89
|
+
- **Integration test (`sdk.integration.test.ts`)**
|
|
90
|
+
- Loads the `privacy-pool` IDL from `privacy-pool/target/idl/privacy_pool.json`
|
|
91
|
+
- Constructs an Anchor `Program` with a provider from `ANCHOR_PROVIDER_URL` / `ANCHOR_WALLET`
|
|
92
|
+
- Runs end-to-end flow:
|
|
93
|
+
1. `initializePool` (configures denoms + fee)
|
|
94
|
+
2. `createNoteAndDeposit` (creates note, commits it, calls on-chain `depositFixed` and updates the Merkle root)
|
|
95
|
+
3. `addRelayer`
|
|
96
|
+
4. `withdrawViaRelayer` (using a Merkle root that actually contains the note + a demo nullifier, empty proof)
|
|
97
|
+
5. Asserts vault TVL decreased, recipient gained funds, relayer received fee.
|
|
98
|
+
|
|
99
|
+
The integration test uses an **empty proof** for now; in a real deployment your **relayer** would generate and verify a Groth16/Plonk proof off-chain, then pass the proof bytes into `withdraw`.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## 4. SDK Surface
|
|
104
|
+
|
|
105
|
+
### 4.1 PDA helpers
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import { getPoolPdas } from "@zkprivacysol/sdk-core";
|
|
109
|
+
import { PublicKey } from "@solana/web3.js";
|
|
110
|
+
|
|
111
|
+
const programId = new PublicKey("YourProgram1111111111111111111111111111111111");
|
|
112
|
+
const { config, vault, noteTree, nullifiers } = getPoolPdas(programId);
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
These must match the on-chain seeds (v3 layout):
|
|
116
|
+
|
|
117
|
+
- `["privacy_config_v3"]`
|
|
118
|
+
- `["privacy_vault_v3"]`
|
|
119
|
+
- `["privacy_note_tree_v3"]`
|
|
120
|
+
- `["privacy_nullifiers_v3"]`
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
### 4.2 Pool init / configuration
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
import * as anchor from "@coral-xyz/anchor";
|
|
128
|
+
import { initializePool } from "@zkprivacysol/sdk-core";
|
|
129
|
+
import { sol } from "@zkprivacysol/sdk-core/config";
|
|
130
|
+
import type { Program, Idl } from "@coral-xyz/anchor";
|
|
131
|
+
|
|
132
|
+
async function initPool(program: Program<Idl>, adminWallet: anchor.Wallet) {
|
|
133
|
+
await initializePool({
|
|
134
|
+
program,
|
|
135
|
+
admin: adminWallet,
|
|
136
|
+
denomsLamports: [sol(1), sol(5)], // 1 SOL & 5 SOL
|
|
137
|
+
feeBps: 50, // 0.5% fee
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
This calls the on-chain `initialize` instruction and sets:
|
|
143
|
+
|
|
144
|
+
- fixed denominations (in lamports)
|
|
145
|
+
- vault + note tree + nullifier set PDAs
|
|
146
|
+
- fee in basis points
|
|
147
|
+
- initial TVL = 0
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
### 4.3 Notes & commitments
|
|
152
|
+
|
|
153
|
+
`src/note.ts` is a small “note” helper module. It **does not** implement real zk-friendly Poseidon hashing yet; it’s just using SHA-256 to get 32-byte commitments that the on-chain program treats as opaque.
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
import {
|
|
157
|
+
createRandomNote,
|
|
158
|
+
encodeNoteToBytes,
|
|
159
|
+
commitNote,
|
|
160
|
+
createNoteWithCommitment,
|
|
161
|
+
} from "@zkprivacysol/sdk-core/note";
|
|
162
|
+
import { Keypair } from "@solana/web3.js";
|
|
163
|
+
|
|
164
|
+
const owner = Keypair.generate().publicKey;
|
|
165
|
+
|
|
166
|
+
// 1. Create a note
|
|
167
|
+
const note = createRandomNote({
|
|
168
|
+
value: 1_000_000n, // lamports
|
|
169
|
+
owner,
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// 2. Encode deterministically
|
|
173
|
+
const bytes = encodeNoteToBytes(note);
|
|
174
|
+
|
|
175
|
+
// 3. Hash to a 32-byte commitment (placeholder)
|
|
176
|
+
const commitment = commitNote(note);
|
|
177
|
+
|
|
178
|
+
// 4. Convenience combo
|
|
179
|
+
const full = createNoteWithCommitment({
|
|
180
|
+
value: 1_000_000n,
|
|
181
|
+
owner,
|
|
182
|
+
});
|
|
183
|
+
// full.commitment is 32 bytes
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Encoding layout:
|
|
187
|
+
|
|
188
|
+
```text
|
|
189
|
+
value (u64 LE, 8 bytes)
|
|
190
|
+
|| owner pubkey (32 bytes)
|
|
191
|
+
|| rho (32 bytes random)
|
|
192
|
+
|| r (32 bytes random)
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Hash:
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
commitment = sha256(encodedBytes);
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Later, a real implementation should swap this out for the exact hash function used inside the zk circuit (Poseidon/Rescue/etc.). The on-chain program just sees `[u8; 32]`.
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
### 4.4 Merkle helpers (demo-only)
|
|
206
|
+
|
|
207
|
+
`src/merkle.ts` provides **very basic** Merkle helpers so callers can build roots off-chain. This is meant for demos/tests, not production.
|
|
208
|
+
|
|
209
|
+
Key functions:
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
import {
|
|
213
|
+
merkleLeafFromCommitment,
|
|
214
|
+
merkleHashPair,
|
|
215
|
+
merkleRootFromLeaves,
|
|
216
|
+
MerkleTree,
|
|
217
|
+
} from "@zkprivacysol/sdk-core/merkle";
|
|
218
|
+
|
|
219
|
+
// Stateless helpers
|
|
220
|
+
const leaf = merkleLeafFromCommitment(commitment);
|
|
221
|
+
const parent = merkleHashPair(left, right);
|
|
222
|
+
const root = merkleRootFromLeaves([leaf1, leaf2, leaf3]);
|
|
223
|
+
|
|
224
|
+
// Simple incremental tree (toy)
|
|
225
|
+
const tree = new MerkleTree();
|
|
226
|
+
const { index, root: newRoot } = tree.insert(commitment);
|
|
227
|
+
const path = tree.getPath(index); // Merkle path for proofs
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Notes:
|
|
231
|
+
|
|
232
|
+
- Uses SHA-256 under the hood, returning `Uint8Array` of length 32.
|
|
233
|
+
- Pads with a “zero node” derived from hashing the all-zero leaf repeatedly up the tree.
|
|
234
|
+
- This is intentionally “toy” to keep the SDK usable while the real circuit/Merkle design is still in flux.
|
|
235
|
+
- On-chain, the program only stores the **latest Merkle root** in the `NoteTree` account (v3 layout exposes a `currentRoot` field).
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
### 4.5 Deposits
|
|
240
|
+
|
|
241
|
+
Low-level helper (you supply both commitment + Merkle root):
|
|
242
|
+
|
|
243
|
+
```ts
|
|
244
|
+
import * as anchor from "@coral-xyz/anchor";
|
|
245
|
+
import { depositFixedSol } from "@zkprivacysol/sdk-core";
|
|
246
|
+
|
|
247
|
+
const provider = anchor.getProvider() as anchor.AnchorProvider;
|
|
248
|
+
const wallet = provider.wallet as anchor.Wallet;
|
|
249
|
+
|
|
250
|
+
await depositFixedSol({
|
|
251
|
+
program,
|
|
252
|
+
depositor: wallet,
|
|
253
|
+
denomIndex: 0, // index into cfg.denoms
|
|
254
|
+
commitment, // 32-byte note commitment
|
|
255
|
+
newRoot, // 32-byte Merkle root (caller computed off-chain)
|
|
256
|
+
});
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
High-level helper (with note creation, but you still feed a root):
|
|
260
|
+
|
|
261
|
+
```ts
|
|
262
|
+
import * as anchor from "@coral-xyz/anchor";
|
|
263
|
+
import { createNoteAndDeposit } from "@zkprivacysol/sdk-core";
|
|
264
|
+
import { sol } from "@zkprivacysol/sdk-core/config";
|
|
265
|
+
|
|
266
|
+
const provider = anchor.getProvider() as anchor.AnchorProvider;
|
|
267
|
+
const wallet = provider.wallet as anchor.Wallet;
|
|
268
|
+
|
|
269
|
+
const dummyRoot = new Uint8Array(32).fill(7); // replace with real Merkle root
|
|
270
|
+
|
|
271
|
+
const note = await createNoteAndDeposit({
|
|
272
|
+
program,
|
|
273
|
+
depositor: wallet,
|
|
274
|
+
denomIndex: 0,
|
|
275
|
+
valueLamports: sol(1),
|
|
276
|
+
newRoot: dummyRoot,
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
// note.commitment can later be used in your off-chain tree
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
There’s also a higher-level helper that integrates directly with an in-memory `MerkleTree`:
|
|
283
|
+
|
|
284
|
+
```ts
|
|
285
|
+
import { createNoteDepositWithMerkle } from "@zkprivacysol/sdk-core";
|
|
286
|
+
import { MerkleTree } from "@zkprivacysol/sdk-core/merkle";
|
|
287
|
+
|
|
288
|
+
const tree = new MerkleTree();
|
|
289
|
+
|
|
290
|
+
const { note, leafIndex, root, merklePath } =
|
|
291
|
+
await createNoteDepositWithMerkle({
|
|
292
|
+
program,
|
|
293
|
+
depositor: wallet,
|
|
294
|
+
denomIndex: 0,
|
|
295
|
+
valueLamports: sol(1),
|
|
296
|
+
tree,
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
// `root` is what got written to the on-chain NoteTree
|
|
300
|
+
// `merklePath` can be used as witness for the zk circuit
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
On-chain, the `depositFixed` instruction:
|
|
304
|
+
|
|
305
|
+
- moves SOL from `depositor` to the vault PDA,
|
|
306
|
+
- updates TVL,
|
|
307
|
+
- writes `new_root` into the on-chain note tree’s current root field.
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
### 4.6 Relayers & Withdrawals
|
|
312
|
+
|
|
313
|
+
Add a relayer (admin-only):
|
|
314
|
+
|
|
315
|
+
```ts
|
|
316
|
+
import * as anchor from "@coral-xyz/anchor";
|
|
317
|
+
import { addRelayer } from "@zkprivacysol/sdk-core";
|
|
318
|
+
import { Keypair } from "@solana/web3.js";
|
|
319
|
+
|
|
320
|
+
const provider = anchor.getProvider() as anchor.AnchorProvider;
|
|
321
|
+
const wallet = provider.wallet as anchor.Wallet;
|
|
322
|
+
|
|
323
|
+
const relayer = Keypair.generate();
|
|
324
|
+
|
|
325
|
+
await addRelayer({
|
|
326
|
+
program,
|
|
327
|
+
admin: wallet,
|
|
328
|
+
newRelayer: relayer.publicKey,
|
|
329
|
+
});
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Withdraw via relayer (SDK-level helper):
|
|
333
|
+
|
|
334
|
+
```ts
|
|
335
|
+
import { withdrawViaRelayer } from "@zkprivacysol/sdk-core";
|
|
336
|
+
import { Keypair } from "@solana/web3.js";
|
|
337
|
+
|
|
338
|
+
const relayer = Keypair.generate();
|
|
339
|
+
const recipient = Keypair.generate();
|
|
340
|
+
|
|
341
|
+
const root = /* 32-byte Merkle root containing the note */;
|
|
342
|
+
const nullifier = new Uint8Array(32).fill(3); // demo only
|
|
343
|
+
|
|
344
|
+
// In the real world, `proof` will be zk-proof bytes coming from your prover.
|
|
345
|
+
const proofBytes = new Uint8Array([]); // currently ignored by on-chain program
|
|
346
|
+
|
|
347
|
+
await withdrawViaRelayer({
|
|
348
|
+
program,
|
|
349
|
+
relayer,
|
|
350
|
+
recipient: recipient.publicKey,
|
|
351
|
+
denomIndex: 0,
|
|
352
|
+
root,
|
|
353
|
+
nullifier,
|
|
354
|
+
proof: proofBytes,
|
|
355
|
+
});
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
There is also a higher-level helper (`withdrawViaRelayerWithProof`) that takes:
|
|
359
|
+
|
|
360
|
+
- `noteData` (serialized note),
|
|
361
|
+
- `merklePath`,
|
|
362
|
+
- `feeBps`,
|
|
363
|
+
- a `builder: ProofBuilder` callback
|
|
364
|
+
|
|
365
|
+
and lets you plug in your own proof generator. In practice, your **relayer service** will own that logic.
|
|
366
|
+
|
|
367
|
+
**Production pattern:**
|
|
368
|
+
|
|
369
|
+
- A **backend relayer service** (see `packages/relayer` or similar) owns:
|
|
370
|
+
- the proving key / circuits,
|
|
371
|
+
- a mirror view of the Merkle tree and nullifier set,
|
|
372
|
+
- a funded relayer keypair.
|
|
373
|
+
- The front-end sends a withdraw request to that service:
|
|
374
|
+
- `root`, `nullifier`, `denomIndex`, `recipient`, plus any private witness data.
|
|
375
|
+
- The relayer:
|
|
376
|
+
1. Builds & verifies the zk proof off-chain.
|
|
377
|
+
2. Packs it into bytes (e.g. via a `packProofToBytes` helper).
|
|
378
|
+
3. Calls the on-chain `withdraw` via Anchor, using the same program/PDAs as the SDK.
|
|
379
|
+
|
|
380
|
+
From the SDK’s perspective, `proof: Uint8Array` is **already-built**; this package doesn’t know how you generated it.
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## 5. Environment & Localnet
|
|
385
|
+
|
|
386
|
+
To run the integration tests successfully, you should:
|
|
387
|
+
|
|
388
|
+
1. Start local validator:
|
|
389
|
+
|
|
390
|
+
```bash
|
|
391
|
+
solana-test-validator
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
2. Build & deploy the `privacy-pool` Anchor program in `packages/privacy-pool`:
|
|
395
|
+
|
|
396
|
+
```bash
|
|
397
|
+
cd packages/privacy-pool
|
|
398
|
+
anchor build
|
|
399
|
+
anchor deploy
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
3. Ensure your CLI and wallet match the validator:
|
|
403
|
+
|
|
404
|
+
```bash
|
|
405
|
+
solana config set --url http://127.0.0.1:8899
|
|
406
|
+
solana-keygen new --outfile ~/.config/solana/id.json
|
|
407
|
+
solana airdrop 10
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
4. Export env vars (or inject via `npm test` script):
|
|
411
|
+
|
|
412
|
+
```bash
|
|
413
|
+
export ANCHOR_PROVIDER_URL=http://127.0.0.1:8899
|
|
414
|
+
export ANCHOR_WALLET=$HOME/.config/solana/id.json
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
5. Then from `packages/sdk-core`:
|
|
418
|
+
|
|
419
|
+
```bash
|
|
420
|
+
npm run build
|
|
421
|
+
npm test
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
## 6. Limitations & TODOs
|
|
427
|
+
|
|
428
|
+
- **Merkle tree is minimal.**
|
|
429
|
+
- Toy implementation, primarily for demos/tests.
|
|
430
|
+
- No persisted tree; you’re expected to maintain state in your own service.
|
|
431
|
+
- **On-chain NoteTree only stores the latest root.**
|
|
432
|
+
- Historical roots/nullifiers must be mirrored off-chain.
|
|
433
|
+
- **Proofs are relayer-only.**
|
|
434
|
+
- SDK does **not** generate Groth16/Plonk proofs.
|
|
435
|
+
- On-chain program currently only sees `Vec<u8>` and does not verify it yet.
|
|
436
|
+
- **API is still evolving.**
|
|
437
|
+
- Types, exports, and function signatures may change as the circuit + relayer design solidifies.
|
|
438
|
+
|
|
439
|
+
This SDK is meant as a thin, hackable layer around the Anchor program while the core privacy design (circuit, proof system, Merkle layout, relayer flow) is being explored.
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@veilo/sdk-core",
|
|
3
|
+
"version": "0.1.17",
|
|
4
|
+
"description": "Tiny TypeScript SDK for the `privacy-pool` Anchor program.",
|
|
5
|
+
"homepage": "https://github.com/ZKSOLDev/core-sdk#readme",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/ZKSOLDev/core-sdk/issues"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/ZKSOLDev/core-sdk.git"
|
|
12
|
+
},
|
|
13
|
+
"license": "ISC",
|
|
14
|
+
"author": "",
|
|
15
|
+
"type": "commonjs",
|
|
16
|
+
"main": "dist/index.js",
|
|
17
|
+
"types": "dist/index.d.ts",
|
|
18
|
+
"directories": {
|
|
19
|
+
"test": "tests"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "rm -rf dist/ && tsc -p tsconfig.json",
|
|
23
|
+
"test": "ANCHOR_PROVIDER_URL=http://127.0.0.1:8899 ANCHOR_WALLET=$HOME/.config/solana/id.json rm -rf dist/ && tsc -p test-tsconfig.json && mocha -t 1000000 \"dist/tests/**/*.js\""
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@coral-xyz/anchor": "^0.30.0",
|
|
27
|
+
"@noble/hashes": "^1.8.0",
|
|
28
|
+
"@solana/spl-token": "^0.4.6",
|
|
29
|
+
"@solana/web3.js": "^1.95.0",
|
|
30
|
+
"circomlibjs": "^0.1.7",
|
|
31
|
+
"mocha": "^11.7.5",
|
|
32
|
+
"tweetnacl": "^1.0.3"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/circomlibjs": "^0.1.6",
|
|
36
|
+
"@types/mocha": "^10.0.10",
|
|
37
|
+
"@types/node": "^24.10.1",
|
|
38
|
+
"chai": "^6.2.1",
|
|
39
|
+
"ts-node": "^10.9.2",
|
|
40
|
+
"typescript": "^5.9.3"
|
|
41
|
+
}
|
|
42
|
+
}
|