@claritydao/midnight-agora-sdk 0.1.0

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.
Files changed (60) hide show
  1. package/.prettierrc +1 -0
  2. package/LICENSE +0 -0
  3. package/README.md +1134 -0
  4. package/dist/browser-providers.d.ts +21 -0
  5. package/dist/browser-providers.d.ts.map +1 -0
  6. package/dist/browser-providers.js +147 -0
  7. package/dist/browser-providers.js.map +1 -0
  8. package/dist/common-types.d.ts +29 -0
  9. package/dist/common-types.d.ts.map +1 -0
  10. package/dist/common-types.js +2 -0
  11. package/dist/common-types.js.map +1 -0
  12. package/dist/errors.d.ts +67 -0
  13. package/dist/errors.d.ts.map +1 -0
  14. package/dist/errors.js +108 -0
  15. package/dist/errors.js.map +1 -0
  16. package/dist/governor-api.d.ts +348 -0
  17. package/dist/governor-api.d.ts.map +1 -0
  18. package/dist/governor-api.js +716 -0
  19. package/dist/governor-api.js.map +1 -0
  20. package/dist/index.d.ts +11 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +14 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/manager.d.ts +87 -0
  25. package/dist/manager.d.ts.map +1 -0
  26. package/dist/manager.js +93 -0
  27. package/dist/manager.js.map +1 -0
  28. package/dist/types.d.ts +307 -0
  29. package/dist/types.d.ts.map +1 -0
  30. package/dist/types.js +77 -0
  31. package/dist/types.js.map +1 -0
  32. package/dist/utils/index.d.ts +34 -0
  33. package/dist/utils/index.d.ts.map +1 -0
  34. package/dist/utils/index.js +57 -0
  35. package/dist/utils/index.js.map +1 -0
  36. package/dist/validators.d.ts +52 -0
  37. package/dist/validators.d.ts.map +1 -0
  38. package/dist/validators.js +160 -0
  39. package/dist/validators.js.map +1 -0
  40. package/eslint.config.mjs +48 -0
  41. package/package.json +39 -0
  42. package/src/browser-providers.ts +274 -0
  43. package/src/common-types.ts +51 -0
  44. package/src/errors.ts +124 -0
  45. package/src/governor-api.ts +948 -0
  46. package/src/index.ts +51 -0
  47. package/src/manager.ts +203 -0
  48. package/src/types.ts +403 -0
  49. package/src/utils/index.ts +60 -0
  50. package/src/validators.ts +245 -0
  51. package/test/README.md +409 -0
  52. package/test/errors.test.ts +179 -0
  53. package/test/integration/governor-api.test.ts +370 -0
  54. package/test/mocks/providers.ts +130 -0
  55. package/test/types.test.ts +112 -0
  56. package/test/utils.test.ts +111 -0
  57. package/test/validators.test.ts +368 -0
  58. package/test/wasm-init.test.ts +132 -0
  59. package/tsconfig.json +18 -0
  60. package/vitest.config.ts +9 -0
@@ -0,0 +1,245 @@
1
+ /**
2
+ * Validation utilities for the Agora DAO Governor SDK.
3
+ *
4
+ * @module validators
5
+ */
6
+
7
+ import { InvalidParameterError, InvalidConfigurationError } from "./errors";
8
+ import type {
9
+ GovernanceConfig,
10
+ GovernorConfig,
11
+ DeploymentConfig,
12
+ TokenConfig
13
+ } from "./types";
14
+ import { VoteChoice } from "./types";
15
+
16
+ // Constants for validation limits
17
+ const MAX_TITLE_LENGTH = 256;
18
+ const MAX_DESCRIPTION_LENGTH = 10000;
19
+ const MAX_TOKEN_NAME_LENGTH = 64;
20
+ const MAX_TOKEN_SYMBOL_LENGTH = 16;
21
+ const MAX_TOKEN_DECIMALS = 18n;
22
+ const MIN_VOTING_PERIOD = 60n;
23
+
24
+ /**
25
+ * Validates that a value is a non-empty string.
26
+ */
27
+ export function validateNonEmptyString(
28
+ value: string,
29
+ parameterName: string
30
+ ): void {
31
+ if (typeof value !== "string") {
32
+ throw new InvalidParameterError(parameterName, "must be a string");
33
+ }
34
+ if (value.trim().length === 0) {
35
+ throw new InvalidParameterError(parameterName, "cannot be empty");
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Validates that a string does not exceed a maximum length.
41
+ */
42
+ export function validateMaxLength(
43
+ value: string,
44
+ maxLength: number,
45
+ parameterName: string
46
+ ): void {
47
+ if (value.length > maxLength) {
48
+ throw new InvalidParameterError(
49
+ parameterName,
50
+ `cannot exceed ${maxLength} characters (got ${value.length})`
51
+ );
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Validates that a value is a valid Uint8Array address (32 bytes).
57
+ */
58
+ export function validateAddress(
59
+ address: Uint8Array,
60
+ parameterName: string
61
+ ): void {
62
+ if (!(address instanceof Uint8Array)) {
63
+ throw new InvalidParameterError(parameterName, "must be a Uint8Array");
64
+ }
65
+ if (address.length !== 32) {
66
+ throw new InvalidParameterError(
67
+ parameterName,
68
+ `must be exactly 32 bytes (got ${address.length})`
69
+ );
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Validates that a bigint is positive.
75
+ */
76
+ export function validatePositiveBigInt(
77
+ value: bigint,
78
+ parameterName: string
79
+ ): void {
80
+ if (typeof value !== "bigint") {
81
+ throw new InvalidParameterError(parameterName, "must be a bigint");
82
+ }
83
+ if (value <= 0n) {
84
+ throw new InvalidParameterError(parameterName, "must be greater than 0");
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Validates that a bigint is non-negative.
90
+ */
91
+ export function validateNonNegativeBigInt(
92
+ value: bigint,
93
+ parameterName: string
94
+ ): void {
95
+ if (typeof value !== "bigint") {
96
+ throw new InvalidParameterError(parameterName, "must be a bigint");
97
+ }
98
+ if (value < 0n) {
99
+ throw new InvalidParameterError(parameterName, "cannot be negative");
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Validates a vote choice value.
105
+ */
106
+ export function validateVoteChoice(choice: VoteChoice): void {
107
+ if (
108
+ ![VoteChoice.For, VoteChoice.Against, VoteChoice.Abstain].includes(choice)
109
+ ) {
110
+ throw new InvalidParameterError(
111
+ "choice",
112
+ "must be VoteChoice.For, VoteChoice.Against, or VoteChoice.Abstain"
113
+ );
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Validates proposal parameters.
119
+ */
120
+ export function validateProposal(
121
+ title: string,
122
+ description: string,
123
+ creator: Uint8Array
124
+ ): void {
125
+ validateNonEmptyString(title, "title");
126
+ validateMaxLength(title, MAX_TITLE_LENGTH, "title");
127
+
128
+ validateNonEmptyString(description, "description");
129
+ validateMaxLength(description, MAX_DESCRIPTION_LENGTH, "description");
130
+
131
+ validateAddress(creator, "creator");
132
+ }
133
+
134
+ /**
135
+ * Validates governance configuration.
136
+ */
137
+ export function validateGovernanceConfig(config: GovernanceConfig): void {
138
+ validatePositiveBigInt(config.votingPeriod, "votingPeriod");
139
+ validatePositiveBigInt(config.quorumThreshold, "quorumThreshold");
140
+ validatePositiveBigInt(config.proposalThreshold, "proposalThreshold");
141
+ validatePositiveBigInt(config.proposalLifetime, "proposalLifetime");
142
+ validateNonNegativeBigInt(config.executionDelay, "executionDelay");
143
+ validateNonNegativeBigInt(config.gracePeriod, "gracePeriod");
144
+ validatePositiveBigInt(config.minStakeAmount, "minStakeAmount");
145
+ validateNonNegativeBigInt(config.stakingPeriod, "stakingPeriod");
146
+
147
+ // Logical validations
148
+ if (config.votingPeriod < MIN_VOTING_PERIOD) {
149
+ throw new InvalidConfigurationError(
150
+ `votingPeriod must be at least ${MIN_VOTING_PERIOD} seconds`
151
+ );
152
+ }
153
+
154
+ if (config.proposalThreshold > config.quorumThreshold) {
155
+ throw new InvalidConfigurationError(
156
+ "proposalThreshold cannot exceed quorumThreshold"
157
+ );
158
+ }
159
+ }
160
+
161
+ /**
162
+ * Validates governor configuration.
163
+ */
164
+ export function validateGovernorConfig(config: GovernorConfig): void {
165
+ validateGovernanceConfig(config.governance);
166
+
167
+ validateNonNegativeBigInt(config.executionDelay, "executionDelay");
168
+ validateNonNegativeBigInt(config.gracePeriod, "gracePeriod");
169
+ validatePositiveBigInt(config.maxActiveProposals, "maxActiveProposals");
170
+ validatePositiveBigInt(config.proposalLifetime, "proposalLifetime");
171
+
172
+ if (typeof config.emergencyVetoEnabled !== "boolean") {
173
+ throw new InvalidParameterError(
174
+ "emergencyVetoEnabled",
175
+ "must be a boolean"
176
+ );
177
+ }
178
+
179
+ if (config.emergencyVetoEnabled) {
180
+ validatePositiveBigInt(
181
+ config.emergencyVetoThreshold,
182
+ "emergencyVetoThreshold"
183
+ );
184
+ }
185
+
186
+ // Check consistency
187
+ if (config.executionDelay !== config.governance.executionDelay) {
188
+ throw new InvalidConfigurationError(
189
+ "executionDelay must match governance.executionDelay"
190
+ );
191
+ }
192
+
193
+ if (config.gracePeriod !== config.governance.gracePeriod) {
194
+ throw new InvalidConfigurationError(
195
+ "gracePeriod must match governance.gracePeriod"
196
+ );
197
+ }
198
+
199
+ if (config.proposalLifetime !== config.governance.proposalLifetime) {
200
+ throw new InvalidConfigurationError(
201
+ "proposalLifetime must match governance.proposalLifetime"
202
+ );
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Validates token configuration.
208
+ */
209
+ export function validateTokenConfig(config: TokenConfig): void {
210
+ validateNonEmptyString(config.name, "token.name");
211
+ validateMaxLength(config.name, MAX_TOKEN_NAME_LENGTH, "token.name");
212
+
213
+ validateNonEmptyString(config.symbol, "token.symbol");
214
+ validateMaxLength(config.symbol, MAX_TOKEN_SYMBOL_LENGTH, "token.symbol");
215
+
216
+ validatePositiveBigInt(config.decimals, "token.decimals");
217
+
218
+ if (config.decimals > MAX_TOKEN_DECIMALS) {
219
+ throw new InvalidConfigurationError(
220
+ `token.decimals cannot exceed ${MAX_TOKEN_DECIMALS}`
221
+ );
222
+ }
223
+ }
224
+
225
+ /**
226
+ * Validates complete deployment configuration.
227
+ */
228
+ export function validateDeploymentConfig(config: DeploymentConfig): void {
229
+ validateGovernorConfig(config.governor);
230
+ validateTokenConfig(config.token);
231
+ validateAddress(config.adminKey, "adminKey");
232
+
233
+ // Security check: warn about predictable admin keys
234
+ const allZeros = config.adminKey.every((byte) => byte === 0);
235
+ const allOnes = config.adminKey.every((byte) => byte === 1);
236
+ const sequential =
237
+ config.adminKey[0] === 1 &&
238
+ config.adminKey.slice(1).every((byte) => byte === 0);
239
+
240
+ if (allZeros || allOnes || sequential) {
241
+ console.warn(
242
+ "WARNING: adminKey appears to be predictable. Use cryptographically secure random bytes in production."
243
+ );
244
+ }
245
+ }
package/test/README.md ADDED
@@ -0,0 +1,409 @@
1
+ # SDK Test Suite
2
+
3
+ Comprehensive test suite for the Agora DAO Midnight SDK.
4
+
5
+ ## Overview
6
+
7
+ The test suite validates the SDK's functionality across multiple layers:
8
+ - Type definitions and enums
9
+ - Input validators
10
+ - Error classes
11
+ - Utility functions
12
+ - WASM initialization
13
+ - Integration tests with mocked providers
14
+
15
+ ## Test Structure
16
+
17
+ ```
18
+ test/
19
+ ├── types.test.ts # Type system tests (8 tests)
20
+ ├── validators.test.ts # Input validation tests (31 tests)
21
+ ├── errors.test.ts # Error class tests (14 tests)
22
+ ├── utils.test.ts # Utility function tests (14 tests)
23
+ ├── wasm-init.test.ts # WASM loading tests (5 tests)
24
+ ├── integration/
25
+ │ └── governor-api.test.ts # Integration tests (31 tests)
26
+ └── mocks/
27
+ └── providers.ts # Mock provider factories
28
+ ```
29
+
30
+ ## Running Tests
31
+
32
+ ### Run All Tests
33
+ ```bash
34
+ pnpm test
35
+ ```
36
+
37
+ ### Watch Mode
38
+ ```bash
39
+ pnpm test --watch
40
+ ```
41
+
42
+ ### Run Specific Test File
43
+ ```bash
44
+ pnpm test types.test.ts
45
+ pnpm test integration/governor-api.test.ts
46
+ ```
47
+
48
+ ### Coverage
49
+ ```bash
50
+ pnpm test --coverage
51
+ ```
52
+
53
+ ## Test Categories
54
+
55
+ ### 1. Type System Tests (`types.test.ts`)
56
+
57
+ Tests the core type definitions and enums:
58
+
59
+ - **VoteChoice Enum**: Validates For, Against, Abstain values
60
+ - **ProposalStatus Enum**: Validates all 8 proposal states
61
+ - **ConfigPresets**: Tests production() and testing() configurations
62
+ - **Type Exports**: Ensures all types are properly exported
63
+
64
+ **Key Tests:**
65
+ - VoteChoice enum values (0, 1, 2)
66
+ - ProposalStatus enum completeness
67
+ - ConfigPresets have correct values
68
+ - Production config has higher thresholds than testing
69
+
70
+ ### 2. Validator Tests (`validators.test.ts`)
71
+
72
+ Tests input validation for all public SDK methods:
73
+
74
+ **Coverage:**
75
+ - `validateDeploymentConfig()`: Token config, governance config, admin key
76
+ - `validateProposal()`: Title, description, creator validation
77
+ - `validateVoteChoice()`: Enum validation
78
+ - `validateStakeAmount()`: BigInt validation
79
+ - `validateAddress()`: Uint8Array length validation
80
+ - `validateProposalId()`: BigInt validation
81
+
82
+ **Edge Cases:**
83
+ - Empty strings
84
+ - Maximum length limits
85
+ - Invalid enum values
86
+ - Incorrect array lengths
87
+ - Negative values
88
+
89
+ ### 3. Error Class Tests (`errors.test.ts`)
90
+
91
+ Tests custom error classes:
92
+
93
+ **Error Types:**
94
+ - `GovernorSDKError`: Base error
95
+ - `WalletNotConnectedError`: Wallet state errors
96
+ - `InsufficientStakeError`: Stake validation errors
97
+ - `InvalidParameterError`: Input validation errors
98
+ - `ContractNotFoundError`: Contract lookup errors
99
+ - `ProposalNotFoundError`: Proposal lookup errors
100
+ - `TransactionError`: Transaction submission errors
101
+ - `DeploymentError`: Contract deployment errors
102
+ - `InvalidConfigurationError`: Configuration errors
103
+ - `NetworkNotConfiguredError`: Network setup errors
104
+
105
+ **Validation:**
106
+ - Correct error names
107
+ - Proper message formatting
108
+ - Error inheritance
109
+ - Parameter validation in constructors
110
+
111
+ ### 4. Utility Function Tests (`utils.test.ts`)
112
+
113
+ Tests utility functions:
114
+
115
+ **Functions Tested:**
116
+ - `randomBytes()`: Cryptographically secure random generation
117
+ - `bytesToHex()`: Binary to hex string conversion
118
+ - `hexToBytes()`: Hex string to binary conversion
119
+ - `addressToBytes()`: Midnight address parsing
120
+
121
+ **Key Tests:**
122
+ - Random bytes are non-zero and different each call
123
+ - Hex conversion is reversible
124
+ - Address parsing handles prefixes
125
+ - Edge cases (empty arrays, 0x prefix)
126
+
127
+ ### 5. WASM Initialization Tests (`wasm-init.test.ts`)
128
+
129
+ Tests WASM module loading behavior:
130
+
131
+ **Critical Tests:**
132
+ - SDK imports without triggering immediate WASM load
133
+ - WASM modules load only when needed
134
+ - No `ocrt.maxField is not a function` errors
135
+ - Proper lazy loading behavior
136
+
137
+ **Why This Matters:**
138
+ The SDK uses WASM modules from `@midnight-ntwrk/compact-runtime`. These tests ensure:
139
+ - No top-level WASM execution during import
140
+ - Vite can bundle the SDK correctly
141
+ - Browser compatibility is maintained
142
+
143
+ ### 6. Integration Tests (`integration/governor-api.test.ts`)
144
+
145
+ Tests SDK logic with mocked providers (no real blockchain):
146
+
147
+ **Test Categories:**
148
+
149
+ #### Provider Interaction (8 tests)
150
+ - Public data provider queries contract state
151
+ - Wallet provider submits transactions
152
+ - Transaction failure handling
153
+ - Proof provider generates ZK proofs
154
+ - Block height queries
155
+ - Private state save/retrieve
156
+ - Network queries
157
+ - Transaction balancing
158
+
159
+ #### Configuration Validation
160
+ - Valid deployment config accepted
161
+ - Invalid deployment config rejected
162
+ - Admin key length validation
163
+
164
+ #### Vote Choice Validation
165
+ - Valid vote choices (For, Against, Abstain)
166
+ - Invalid vote choices rejected
167
+
168
+ #### Proposal Validation
169
+ - Valid proposals accepted
170
+ - Empty titles rejected
171
+ - Title length limits enforced
172
+ - Empty descriptions rejected
173
+
174
+ #### Transaction Flow
175
+ - Transaction balancing
176
+ - Transaction submission
177
+ - Error handling
178
+
179
+ #### Private State Management
180
+ - State retrieval
181
+ - State saving
182
+ - State persistence
183
+
184
+ #### Block Height Queries
185
+ - Current block height queries
186
+
187
+ #### Error Handling Scenarios
188
+ - Wallet connection errors
189
+ - Indexer query errors
190
+ - Proof generation errors
191
+
192
+ #### Wallet State
193
+ - Wallet state retrieval
194
+ - Address, coinPublicKey, encryptionPublicKey
195
+
196
+ #### Configuration Presets
197
+ - Testing configuration values
198
+ - Production configuration values
199
+ - Production has higher thresholds than testing
200
+
201
+ ## Mock Providers
202
+
203
+ The test suite uses mock providers to simulate blockchain interactions:
204
+
205
+ ### `createMockProviders()`
206
+
207
+ Creates a complete mock provider set with default successful responses:
208
+
209
+ ```typescript
210
+ const mockProviders = createMockProviders();
211
+ // All operations succeed
212
+ ```
213
+
214
+ ### `createFailingMockProviders()`
215
+
216
+ Creates providers that simulate transaction failures:
217
+
218
+ ```typescript
219
+ const failingProviders = createFailingMockProviders();
220
+ // submitTransaction() throws error
221
+ ```
222
+
223
+ ### `createInsufficientStakeMockProviders()`
224
+
225
+ Creates providers with insufficient stake scenarios:
226
+
227
+ ```typescript
228
+ const insufficientStakeProviders = createInsufficientStakeMockProviders();
229
+ // User has stake < minStakeAmount
230
+ ```
231
+
232
+ ### Custom Overrides
233
+
234
+ Override specific provider behavior:
235
+
236
+ ```typescript
237
+ const customProviders = createMockProviders({
238
+ publicDataProvider: {
239
+ queryContractState: vi.fn().mockResolvedValue(customState),
240
+ },
241
+ });
242
+ ```
243
+
244
+ ## Test Execution Strategy
245
+
246
+ ### Unit Tests
247
+ Fast, isolated tests for individual functions:
248
+ - Type definitions
249
+ - Validators
250
+ - Error classes
251
+ - Utility functions
252
+
253
+ ### Integration Tests
254
+ Tests SDK logic with mocked providers:
255
+ - No real blockchain connection
256
+ - No proof generation
257
+ - Fast execution (< 100ms)
258
+ - Suitable for CI/CD
259
+
260
+ ### E2E Tests (Not Included)
261
+ For complete end-to-end testing:
262
+ - Use real testnet
263
+ - Real Lace wallet
264
+ - Real proof generation
265
+ - Slow execution (minutes)
266
+ - Manual testing recommended
267
+
268
+ ## Common Issues
269
+
270
+ ### Issue: "Cannot find module '@agora-dao-midnight/sdk'"
271
+
272
+ **Solution:** Build the SDK first:
273
+ ```bash
274
+ cd /path/to/sdk
275
+ pnpm run build
276
+ ```
277
+
278
+ ### Issue: "ocrt.maxField is not a function"
279
+
280
+ **Solution:** This should not happen in tests. If it does:
281
+ 1. Check that WASM modules are properly mocked
282
+ 2. Verify `wasm-init.test.ts` is passing
283
+ 3. Ensure no eager WASM loading in imports
284
+
285
+ ### Issue: Tests timing out
286
+
287
+ **Solution:**
288
+ - Check if using real providers instead of mocks
289
+ - Increase Vitest timeout in test file
290
+ - Verify no network calls in unit tests
291
+
292
+ ## Test Coverage Goals
293
+
294
+ Current coverage: **103 tests passing**
295
+
296
+ Target coverage:
297
+ - Types: 100%
298
+ - Validators: 100%
299
+ - Errors: 100%
300
+ - Utils: 100%
301
+ - WASM Init: 100%
302
+ - Integration: 80%+ (critical paths)
303
+
304
+ ## Writing New Tests
305
+
306
+ ### Unit Test Template
307
+
308
+ ```typescript
309
+ import { describe, it, expect } from 'vitest';
310
+ import { functionToTest } from '../src/module';
311
+
312
+ describe('Module Name', () => {
313
+ describe('functionToTest', () => {
314
+ it('should handle valid input', () => {
315
+ const result = functionToTest(validInput);
316
+ expect(result).toBe(expectedValue);
317
+ });
318
+
319
+ it('should throw on invalid input', () => {
320
+ expect(() => functionToTest(invalidInput)).toThrow();
321
+ });
322
+ });
323
+ });
324
+ ```
325
+
326
+ ### Integration Test Template
327
+
328
+ ```typescript
329
+ import { describe, it, expect, beforeEach } from 'vitest';
330
+ import { createMockProviders } from '../mocks/providers';
331
+ import { GovernorAPI } from '../../src/governor-api';
332
+
333
+ describe('GovernorAPI Feature', () => {
334
+ let mockProviders: GovernorProviders;
335
+
336
+ beforeEach(() => {
337
+ mockProviders = createMockProviders();
338
+ });
339
+
340
+ it('should perform operation', async () => {
341
+ const result = await governorAPI.operation(params);
342
+ expect(result).toBeDefined();
343
+ });
344
+ });
345
+ ```
346
+
347
+ ## Best Practices
348
+
349
+ 1. **Use Mocks for Integration Tests**: Never hit real blockchain in tests
350
+ 2. **Test Edge Cases**: Empty strings, max lengths, invalid types
351
+ 3. **Test Error Paths**: Ensure errors are thrown correctly
352
+ 4. **Keep Tests Fast**: Unit tests < 5ms, integration tests < 100ms
353
+ 5. **Clear Test Names**: Describe what the test validates
354
+ 6. **Arrange-Act-Assert**: Structure tests clearly
355
+ 7. **Don't Test Implementation Details**: Test behavior, not internals
356
+
357
+ ## CI/CD Integration
358
+
359
+ The test suite is designed to run in continuous integration:
360
+
361
+ ```yaml
362
+ # GitHub Actions example
363
+ - name: Run tests
364
+ run: pnpm test
365
+
366
+ - name: Check coverage
367
+ run: pnpm test --coverage
368
+ ```
369
+
370
+ All tests should pass before merging to main.
371
+
372
+ ## Future Test Additions
373
+
374
+ Planned test coverage:
375
+
376
+ 1. **Contract Interaction Tests**: Test actual contract method calls with mocked blockchain
377
+ 2. **State Management Tests**: Comprehensive private state tests
378
+ 3. **Transaction Building Tests**: Test transaction construction
379
+ 4. **ZK Witness Tests**: Test witness preparation
380
+ 5. **Performance Tests**: Benchmark critical operations
381
+
382
+ ## Troubleshooting
383
+
384
+ ### Tests Fail After SDK Changes
385
+
386
+ 1. Rebuild the SDK: `pnpm run build`
387
+ 2. Clear test cache: `rm -rf node_modules/.vite`
388
+ 3. Reinstall: `pnpm install`
389
+ 4. Run tests: `pnpm test`
390
+
391
+ ### Mock Provider Issues
392
+
393
+ If mock providers aren't working:
394
+ 1. Check `test/mocks/providers.ts`
395
+ 2. Verify Vitest mock functions are used: `vi.fn()`
396
+ 3. Ensure proper async/await in tests
397
+
398
+ ### Type Errors in Tests
399
+
400
+ 1. Rebuild SDK types: `pnpm run build`
401
+ 2. Check test imports match SDK exports
402
+ 3. Verify TypeScript version compatibility
403
+
404
+ ## Contact
405
+
406
+ For test-related issues:
407
+ - Check test output for specific error messages
408
+ - Review this README for common solutions
409
+ - Check main SDK README for build instructions