midnight-mcp 0.1.34 → 0.1.35

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.
@@ -65,4 +65,107 @@ export declare function getVersionInfo(): string;
65
65
  * Check if a version is within supported range
66
66
  */
67
67
  export declare function isVersionSupported(version: string): boolean;
68
+ /**
69
+ * Built-in functions vs patterns you must implement yourself
70
+ * CRITICAL: These are the actual stdlib functions available in Compact
71
+ */
72
+ export declare const BUILTIN_FUNCTIONS: {
73
+ /** Actually built into the language/stdlib */
74
+ stdlib: {
75
+ name: string;
76
+ signature: string;
77
+ description: string;
78
+ }[];
79
+ /** NOT built-in - you must implement these patterns yourself */
80
+ notBuiltIn: {
81
+ name: string;
82
+ wrongUsage: string;
83
+ correctPattern: string;
84
+ description: string;
85
+ }[];
86
+ };
87
+ /**
88
+ * Type compatibility rules - what types can be compared/operated together
89
+ */
90
+ export declare const TYPE_COMPATIBILITY: {
91
+ comparisons: ({
92
+ types: string;
93
+ works: boolean;
94
+ note: string;
95
+ fix?: undefined;
96
+ } | {
97
+ types: string;
98
+ works: boolean;
99
+ fix: string;
100
+ note?: undefined;
101
+ })[];
102
+ arithmetic: ({
103
+ types: string;
104
+ works: boolean;
105
+ note: string;
106
+ fix?: undefined;
107
+ } | {
108
+ types: string;
109
+ works: boolean;
110
+ fix: string;
111
+ note?: undefined;
112
+ })[];
113
+ assignments: {
114
+ types: string;
115
+ works: boolean;
116
+ fix: string;
117
+ }[];
118
+ tips: string[];
119
+ };
120
+ /**
121
+ * Ledger type limitations - what works in circuits vs TypeScript
122
+ */
123
+ export declare const LEDGER_TYPE_LIMITS: {
124
+ Counter: {
125
+ circuitOperations: {
126
+ method: string;
127
+ works: boolean;
128
+ note: string;
129
+ }[];
130
+ typescriptAccess: string;
131
+ reason: string;
132
+ };
133
+ Map: {
134
+ circuitOperations: {
135
+ method: string;
136
+ works: boolean;
137
+ note: string;
138
+ }[];
139
+ typescriptAccess: string;
140
+ reason: string;
141
+ pattern: string;
142
+ };
143
+ Set: {
144
+ circuitOperations: {
145
+ method: string;
146
+ works: boolean;
147
+ note: string;
148
+ }[];
149
+ typescriptAccess: string;
150
+ reason: string;
151
+ };
152
+ MerkleTree: {
153
+ circuitOperations: {
154
+ method: string;
155
+ works: boolean;
156
+ note: string;
157
+ }[];
158
+ typescriptAccess: string;
159
+ pattern: string;
160
+ };
161
+ };
162
+ /**
163
+ * Common compilation errors with their fixes
164
+ * Maps actual compiler error messages to solutions
165
+ */
166
+ export declare const COMMON_ERRORS: {
167
+ error: string;
168
+ cause: string;
169
+ fix: string;
170
+ }[];
68
171
  //# sourceMappingURL=compact-version.d.ts.map
@@ -92,4 +92,264 @@ export function isVersionSupported(version) {
92
92
  const maxNum = maxMajor * 100 + maxMinor;
93
93
  return versionNum >= minNum && versionNum <= maxNum;
94
94
  }
95
+ /**
96
+ * Built-in functions vs patterns you must implement yourself
97
+ * CRITICAL: These are the actual stdlib functions available in Compact
98
+ */
99
+ export const BUILTIN_FUNCTIONS = {
100
+ /** Actually built into the language/stdlib */
101
+ stdlib: [
102
+ {
103
+ name: "persistentHash",
104
+ signature: "persistentHash<T>(value: T): Bytes<32>",
105
+ description: "Poseidon hash that produces consistent results across calls",
106
+ },
107
+ {
108
+ name: "persistentCommit",
109
+ signature: "persistentCommit<T>(value: T): Bytes<32>",
110
+ description: "Creates a hiding commitment to a value",
111
+ },
112
+ {
113
+ name: "pad",
114
+ signature: "pad(length: number, value: string): Bytes<N>",
115
+ description: "Pads a string to fixed-length bytes",
116
+ },
117
+ {
118
+ name: "disclose",
119
+ signature: "disclose(value: T): T",
120
+ description: "Explicitly reveals a witness value (required in conditionals)",
121
+ },
122
+ {
123
+ name: "assert",
124
+ signature: "assert(condition: Boolean, message?: string): []",
125
+ description: "Fails circuit if condition is false",
126
+ },
127
+ {
128
+ name: "default",
129
+ signature: "default<T>(): T",
130
+ description: "Returns default value for a type (0 for numbers, empty for collections)",
131
+ },
132
+ ],
133
+ /** NOT built-in - you must implement these patterns yourself */
134
+ notBuiltIn: [
135
+ {
136
+ name: "public_key",
137
+ wrongUsage: "public_key(sk) // ERROR: unbound identifier",
138
+ correctPattern: `// Derive public key using persistentHash
139
+ const pk = persistentHash<Vector<2, Bytes<32>>>([
140
+ pad(32, "midnight:pk:"),
141
+ sk
142
+ ]);`,
143
+ description: "Public key derivation is NOT a builtin - use persistentHash pattern",
144
+ },
145
+ {
146
+ name: "verify_signature",
147
+ wrongUsage: "verify_signature(msg, sig, pk) // Does not exist",
148
+ correctPattern: `// Signature verification must be done via witnesses
149
+ // The prover verifies off-chain, then provides the boolean result
150
+ witness signature_valid(): Boolean;`,
151
+ description: "Signature verification is done off-chain in the prover",
152
+ },
153
+ {
154
+ name: "random",
155
+ wrongUsage: "random() // Does not exist in ZK circuits",
156
+ correctPattern: `// Randomness must come from witnesses (prover-provided)
157
+ witness get_random_value(): Field;`,
158
+ description: "ZK circuits are deterministic - randomness must come from witnesses",
159
+ },
160
+ ],
161
+ };
162
+ /**
163
+ * Type compatibility rules - what types can be compared/operated together
164
+ */
165
+ export const TYPE_COMPATIBILITY = {
166
+ comparisons: [
167
+ { types: "Field == Field", works: true, note: "Direct comparison" },
168
+ {
169
+ types: "Field == Uint<N>",
170
+ works: false,
171
+ fix: "Cast with `value as Field`",
172
+ },
173
+ {
174
+ types: "Field >= 0",
175
+ works: false,
176
+ fix: "Use bounded Uint<0..N> parameter instead",
177
+ },
178
+ { types: "Uint<N> == Uint<N>", works: true, note: "Same-width comparison" },
179
+ {
180
+ types: "Uint<0..2> == Uint<0..2>",
181
+ works: true,
182
+ note: "Bounded integers",
183
+ },
184
+ { types: "Bytes<32> == Bytes<32>", works: true, note: "Direct comparison" },
185
+ { types: "Boolean == Boolean", works: true, note: "Direct comparison" },
186
+ ],
187
+ arithmetic: [
188
+ { types: "Field + Field", works: true, note: "Field arithmetic" },
189
+ { types: "Field + Uint<N>", works: false, fix: "Cast Uint to Field first" },
190
+ {
191
+ types: "Uint<N> + Uint<N>",
192
+ works: true,
193
+ note: "Must fit in result width",
194
+ },
195
+ ],
196
+ assignments: [
197
+ {
198
+ types: "Field = Uint<N>",
199
+ works: false,
200
+ fix: "Cast with `value as Field`",
201
+ },
202
+ {
203
+ types: "Uint<N> = Field",
204
+ works: false,
205
+ fix: "Use bounded param or explicit cast",
206
+ },
207
+ ],
208
+ tips: [
209
+ "Use Uint<0..N> for circuit parameters that need range validation",
210
+ "Field is unbounded - use for hashes, commitments, general computation",
211
+ "Uint<N> is bounded - use when you need range checks",
212
+ "Casting with `as Field` is safe but loses range information",
213
+ ],
214
+ };
215
+ /**
216
+ * Ledger type limitations - what works in circuits vs TypeScript
217
+ */
218
+ export const LEDGER_TYPE_LIMITS = {
219
+ Counter: {
220
+ circuitOperations: [
221
+ { method: ".increment(n)", works: true, note: "Adds n to counter" },
222
+ {
223
+ method: ".decrement(n)",
224
+ works: true,
225
+ note: "Subtracts n from counter",
226
+ },
227
+ { method: ".resetToDefault()", works: true, note: "Resets to 0" },
228
+ { method: ".value()", works: false, note: "NOT available in circuits" },
229
+ ],
230
+ typescriptAccess: "Access counter value via `ledgerState.counter` in TypeScript SDK",
231
+ reason: "ZK circuits cannot read current ledger state - only modify it",
232
+ },
233
+ Map: {
234
+ circuitOperations: [
235
+ {
236
+ method: ".insert(key, value)",
237
+ works: true,
238
+ note: "Adds/updates entry",
239
+ },
240
+ { method: ".remove(key)", works: true, note: "Removes entry" },
241
+ {
242
+ method: ".lookup(key)",
243
+ works: false,
244
+ note: "NOT available in circuits",
245
+ },
246
+ {
247
+ method: ".member(key)",
248
+ works: false,
249
+ note: "NOT available in circuits",
250
+ },
251
+ ],
252
+ typescriptAccess: "Query map via `contractState.data.get(key)` in TypeScript SDK",
253
+ reason: "ZK circuits prove transitions, not current state. Use witnesses for reads.",
254
+ pattern: `// To read a map value in a circuit, use a witness:
255
+ witness get_stored_value(key: Bytes<32>): Field;
256
+
257
+ export circuit update_if_exists(key: Bytes<32>, new_value: Field): [] {
258
+ const current = get_stored_value(key); // Prover fetches from ledger
259
+ // ... use current value
260
+ data.insert(key, new_value); // Update is allowed
261
+ }`,
262
+ },
263
+ Set: {
264
+ circuitOperations: [
265
+ { method: ".insert(value)", works: true, note: "Adds to set" },
266
+ { method: ".remove(value)", works: true, note: "Removes from set" },
267
+ {
268
+ method: ".member(value)",
269
+ works: false,
270
+ note: "NOT available in circuits",
271
+ },
272
+ ],
273
+ typescriptAccess: "Check membership via `contractState.set.has(value)` in TypeScript SDK",
274
+ reason: "Same as Map - use witnesses for membership checks",
275
+ },
276
+ MerkleTree: {
277
+ circuitOperations: [
278
+ { method: ".insert(leaf)", works: true, note: "Adds leaf to tree" },
279
+ { method: ".root()", works: false, note: "NOT available in circuits" },
280
+ ],
281
+ typescriptAccess: "Get root via `contractState.tree.root` in TypeScript SDK",
282
+ pattern: `// To verify a merkle proof in circuit:
283
+ witness get_merkle_root(): Bytes<32>;
284
+ witness get_merkle_proof(leaf: Bytes<32>): Vector<32, Bytes<32>>;
285
+
286
+ // Verify proof using persistentHash to compute expected root`,
287
+ },
288
+ };
289
+ /**
290
+ * Common compilation errors with their fixes
291
+ * Maps actual compiler error messages to solutions
292
+ */
293
+ export const COMMON_ERRORS = [
294
+ {
295
+ error: 'unbound identifier "public_key"',
296
+ cause: "Trying to use public_key() as if it's a builtin function",
297
+ fix: `Use persistentHash pattern instead:
298
+ const pk = persistentHash<Vector<2, Bytes<32>>>([pad(32, "midnight:pk:"), sk]);`,
299
+ },
300
+ {
301
+ error: "incompatible combination of types Field and Uint",
302
+ cause: "Comparing or operating on Field with Uint without casting",
303
+ fix: `Cast Uint to Field: (myUint as Field)
304
+ Or use bounded Uint<0..N> for parameters that need constraints`,
305
+ },
306
+ {
307
+ error: 'operation "value" undefined for ledger field type Counter',
308
+ cause: "Trying to read Counter.value() inside a circuit",
309
+ fix: `Counter values cannot be read in circuits. Options:
310
+ 1. Use a witness: witness get_counter_value(): Uint<64>;
311
+ 2. Read from TypeScript SDK: ledgerState.counter
312
+ 3. Track the value in a separate Field ledger variable`,
313
+ },
314
+ {
315
+ error: "implicit disclosure of witness value",
316
+ cause: "Using witness value in conditional without disclose()",
317
+ fix: `Wrap witness comparisons in disclose():
318
+ if (disclose(witness_value == expected)) { ... }`,
319
+ },
320
+ {
321
+ error: 'parse error: found "{" looking for an identifier',
322
+ cause: "Using old ledger { } block syntax",
323
+ fix: `Use individual exports instead:
324
+ export ledger field1: Type1;
325
+ export ledger field2: Type2;`,
326
+ },
327
+ {
328
+ error: 'parse error: found "{" looking for ";"',
329
+ cause: "Using Void as return type (doesn't exist)",
330
+ fix: `Use empty tuple [] for no return value:
331
+ export circuit myCircuit(): [] { ... }`,
332
+ },
333
+ {
334
+ error: 'unbound identifier "Cell"',
335
+ cause: "Using deprecated Cell<T> wrapper (removed in 0.15)",
336
+ fix: `Remove Cell wrapper, just use the type directly:
337
+ export ledger myField: Field; // Not Cell<Field>`,
338
+ },
339
+ {
340
+ error: "member access requires struct type",
341
+ cause: "Trying to use .member() or .lookup() on Map/Set in circuit",
342
+ fix: `Map/Set queries are not available in circuits.
343
+ Use a witness to fetch the value from the prover:
344
+ witness lookup_value(key: Bytes<32>): Field;`,
345
+ },
346
+ {
347
+ error: "cannot prove assertion",
348
+ cause: "Assert condition cannot be proven true",
349
+ fix: `Check your logic. Common causes:
350
+ 1. Witness returns unexpected value
351
+ 2. Range check fails (use bounded Uint)
352
+ 3. Logic error in circuit`,
353
+ },
354
+ ];
95
355
  //# sourceMappingURL=compact-version.js.map
@@ -225,6 +225,7 @@ constructor(initNonce: Bytes<32>) {
225
225
  \`\`\`compact
226
226
  witness local_secret_key(): Bytes<32>;
227
227
 
228
+ // IMPORTANT: public_key() is NOT a builtin - use this pattern
228
229
  circuit get_public_key(sk: Bytes<32>): Bytes<32> {
229
230
  return persistentHash<Vector<2, Bytes<32>>>([pad(32, "myapp:pk:"), sk]);
230
231
  }
@@ -237,32 +238,47 @@ export circuit authenticated_action(): [] {
237
238
  }
238
239
  \`\`\`
239
240
 
240
- ### Commit-Reveal Pattern
241
+ ### Commit-Reveal Pattern (COMPLETE, VALIDATED)
241
242
  \`\`\`compact
243
+ pragma language_version >= 0.16 && <= 0.18;
244
+
245
+ import CompactStandardLibrary;
246
+
247
+ // Ledger state
242
248
  export ledger commitment: Bytes<32>;
243
- export ledger revealed: Boolean;
249
+ export ledger revealed_value: Field;
250
+ export ledger is_revealed: Boolean;
244
251
 
245
- witness get_stored_value(): Field;
246
- witness store_value(v: Field): [];
252
+ // Witnesses for off-chain storage
253
+ witness local_secret_key(): Bytes<32>;
254
+ witness store_secret_value(v: Field): [];
255
+ witness get_secret_value(): Field;
256
+
257
+ // Helper: compute commitment hash
258
+ circuit compute_commitment(value: Field, salt: Bytes<32>): Bytes<32> {
259
+ // Convert Field to Bytes for hashing
260
+ const value_bytes = value as Bytes<32>;
261
+ return persistentHash<Vector<2, Bytes<32>>>([value_bytes, salt]);
262
+ }
247
263
 
264
+ // Commit phase: store hash on-chain, value off-chain
248
265
  export circuit commit(value: Field): [] {
249
- const sk = local_secret_key();
250
- store_value(value);
251
- commitment = disclose(persistentHash<Vector<2, Bytes<32>>>([
252
- value as Bytes<32>,
253
- sk
254
- ]));
266
+ const salt = local_secret_key();
267
+ store_secret_value(value);
268
+ commitment = disclose(compute_commitment(value, salt));
269
+ is_revealed = false;
255
270
  }
256
271
 
272
+ // Reveal phase: verify stored value matches commitment
257
273
  export circuit reveal(): Field {
258
- const sk = local_secret_key();
259
- const value = get_stored_value();
260
- const expected = persistentHash<Vector<2, Bytes<32>>>([
261
- value as Bytes<32>,
262
- sk
263
- ]);
264
- assert(disclose(expected == commitment), "Mismatch");
265
- revealed = true;
274
+ const salt = local_secret_key();
275
+ const value = get_secret_value();
276
+ const expected = compute_commitment(value, salt);
277
+ assert(disclose(expected == commitment), "Value doesn't match commitment");
278
+ assert(disclose(!is_revealed), "Already revealed");
279
+
280
+ revealed_value = disclose(value);
281
+ is_revealed = true;
266
282
  return disclose(value);
267
283
  }
268
284
  \`\`\`
@@ -296,22 +312,39 @@ export circuit check_broken(guess: Field): Boolean {
296
312
 
297
313
  ### Counter Operations
298
314
  \`\`\`compact
315
+ // These work in circuits:
299
316
  counter.increment(1);
300
317
  counter.decrement(1);
301
- const val = counter.value(); // Note: returns as Field
318
+ counter.resetToDefault();
319
+
320
+ // ⚠️ DOES NOT WORK IN CIRCUITS:
321
+ // const val = counter.value(); // ERROR: operation undefined
322
+ // Instead, read counter value in TypeScript SDK: ledgerState.counter
302
323
  \`\`\`
303
324
 
304
325
  ### Map Operations
305
326
  \`\`\`compact
327
+ // These work in circuits:
306
328
  balances.insert(address, 100);
307
- const balance = balances.lookup(address);
308
- const exists = balances.member(address);
329
+ balances.remove(address);
330
+
331
+ // ⚠️ DOES NOT WORK IN CIRCUITS:
332
+ // const balance = balances.lookup(address); // ERROR
333
+ // const exists = balances.member(address); // ERROR
334
+ // Instead, use witnesses to read values:
335
+ witness get_balance(addr: Bytes<32>): Uint<64>;
309
336
  \`\`\`
310
337
 
311
338
  ### Set Operations
312
339
  \`\`\`compact
340
+ // These work in circuits:
313
341
  members.insert(address);
314
- const isMember = members.member(address);
342
+ members.remove(address);
343
+
344
+ // ⚠️ DOES NOT WORK IN CIRCUITS:
345
+ // const isMember = members.member(address); // ERROR
346
+ // Use witness instead:
347
+ witness is_member(addr: Bytes<32>): Boolean;
315
348
  \`\`\`
316
349
 
317
350
  ### Maybe Operations
@@ -326,9 +359,9 @@ if (opt.is_some) {
326
359
 
327
360
  ### Type Casting
328
361
  \`\`\`compact
329
- const f: Field = counter.value(); // Counter to Field
330
- const bytes: Bytes<32> = f as Bytes<32>; // Field to Bytes
331
- const num: Uint<64> = f as Uint<64>; // Field to Uint
362
+ const bytes: Bytes<32> = myField as Bytes<32>; // Field to Bytes
363
+ const num: Uint<64> = myField as Uint<64>; // Field to Uint (bounds not checked!)
364
+ const field: Field = myUint as Field; // Uint to Field (safe)
332
365
  \`\`\`
333
366
 
334
367
  ### Hashing
@@ -336,8 +369,8 @@ const num: Uint<64> = f as Uint<64>; // Field to Uint
336
369
  // Persistent hash (same input = same output across calls)
337
370
  const hash = persistentHash<Vector<2, Bytes<32>>>([data1, data2]);
338
371
 
339
- // Transient hash (includes randomness)
340
- const commit = transientCommit<Field>(value, randomness);
372
+ // Persistent commit (hiding commitment)
373
+ const commit = persistentCommit<Field>(value);
341
374
  \`\`\`
342
375
 
343
376
  ---
@@ -159,6 +159,93 @@ export declare function compareSyntax(input: CompareSyntaxInput): Promise<{
159
159
  */
160
160
  export declare function getLatestSyntax(input: GetLatestSyntaxInput): Promise<{
161
161
  quickStartTemplate: string;
162
+ builtinFunctions: {
163
+ stdlib: {
164
+ name: string;
165
+ signature: string;
166
+ description: string;
167
+ }[];
168
+ notBuiltIn: {
169
+ name: string;
170
+ wrongUsage: string;
171
+ correctPattern: string;
172
+ description: string;
173
+ }[];
174
+ };
175
+ typeCompatibility: {
176
+ comparisons: ({
177
+ types: string;
178
+ works: boolean;
179
+ note: string;
180
+ fix?: undefined;
181
+ } | {
182
+ types: string;
183
+ works: boolean;
184
+ fix: string;
185
+ note?: undefined;
186
+ })[];
187
+ arithmetic: ({
188
+ types: string;
189
+ works: boolean;
190
+ note: string;
191
+ fix?: undefined;
192
+ } | {
193
+ types: string;
194
+ works: boolean;
195
+ fix: string;
196
+ note?: undefined;
197
+ })[];
198
+ assignments: {
199
+ types: string;
200
+ works: boolean;
201
+ fix: string;
202
+ }[];
203
+ tips: string[];
204
+ };
205
+ ledgerTypeLimits: {
206
+ Counter: {
207
+ circuitOperations: {
208
+ method: string;
209
+ works: boolean;
210
+ note: string;
211
+ }[];
212
+ typescriptAccess: string;
213
+ reason: string;
214
+ };
215
+ Map: {
216
+ circuitOperations: {
217
+ method: string;
218
+ works: boolean;
219
+ note: string;
220
+ }[];
221
+ typescriptAccess: string;
222
+ reason: string;
223
+ pattern: string;
224
+ };
225
+ Set: {
226
+ circuitOperations: {
227
+ method: string;
228
+ works: boolean;
229
+ note: string;
230
+ }[];
231
+ typescriptAccess: string;
232
+ reason: string;
233
+ };
234
+ MerkleTree: {
235
+ circuitOperations: {
236
+ method: string;
237
+ works: boolean;
238
+ note: string;
239
+ }[];
240
+ typescriptAccess: string;
241
+ pattern: string;
242
+ };
243
+ };
244
+ commonErrors: {
245
+ error: string;
246
+ cause: string;
247
+ fix: string;
248
+ }[];
162
249
  commonMistakes: {
163
250
  wrong: string;
164
251
  correct: string;
@@ -8,7 +8,7 @@ import { logger, DEFAULT_REPOSITORIES, SelfCorrectionHints, } from "../../utils/
8
8
  import { sendProgressNotification } from "../../server.js";
9
9
  import { REPO_ALIASES, EXAMPLES } from "./constants.js";
10
10
  import { EMBEDDED_DOCS } from "../../resources/content/docs-content.js";
11
- import { COMPACT_VERSION, RECOMMENDED_PRAGMA, REFERENCE_CONTRACTS, } from "../../config/compact-version.js";
11
+ import { COMPACT_VERSION, RECOMMENDED_PRAGMA, REFERENCE_CONTRACTS, BUILTIN_FUNCTIONS, TYPE_COMPATIBILITY, LEDGER_TYPE_LIMITS, COMMON_ERRORS, } from "../../config/compact-version.js";
12
12
  // Re-export validation handlers from validation.ts
13
13
  export { extractContractStructure } from "./validation.js";
14
14
  /**
@@ -356,6 +356,14 @@ witness local_secret_key(): Bytes<32>;
356
356
  export circuit increment(): [] {
357
357
  counter.increment(1);
358
358
  }`,
359
+ // Built-in functions vs patterns (CRITICAL knowledge)
360
+ builtinFunctions: BUILTIN_FUNCTIONS,
361
+ // Type compatibility rules
362
+ typeCompatibility: TYPE_COMPATIBILITY,
363
+ // Ledger type limitations in circuits
364
+ ledgerTypeLimits: LEDGER_TYPE_LIMITS,
365
+ // Common compilation errors with fixes
366
+ commonErrors: COMMON_ERRORS,
359
367
  // Common mistakes that cause compilation failures
360
368
  commonMistakes: [
361
369
  {
@@ -388,6 +396,21 @@ export circuit increment(): [] {
388
396
  correct: "Field",
389
397
  error: "unbound identifier Cell (deprecated)",
390
398
  },
399
+ {
400
+ wrong: "public_key(sk)",
401
+ correct: 'persistentHash<Vector<2, Bytes<32>>>([pad(32, "midnight:pk:"), sk])',
402
+ error: 'unbound identifier "public_key"',
403
+ },
404
+ {
405
+ wrong: "counter.value()",
406
+ correct: "// Read via witness or TypeScript SDK",
407
+ error: 'operation "value" undefined for Counter',
408
+ },
409
+ {
410
+ wrong: "data.lookup(key)",
411
+ correct: "// Use witness: witness get_value(key): Type;",
412
+ error: "member access requires struct type",
413
+ },
391
414
  ],
392
415
  syntaxReference: compactReference,
393
416
  sections: [
@@ -396,6 +419,9 @@ export circuit increment(): [] {
396
419
  "Imports",
397
420
  "Ledger Declarations",
398
421
  "Data Types",
422
+ "Built-in Functions",
423
+ "Type Compatibility",
424
+ "Ledger Type Limits",
399
425
  "Circuits",
400
426
  "Witnesses",
401
427
  "Constructor",
@@ -403,6 +429,7 @@ export circuit increment(): [] {
403
429
  "Common Operations",
404
430
  "Assertions",
405
431
  "Common Mistakes to Avoid",
432
+ "Common Errors & Fixes",
406
433
  "Exports for TypeScript",
407
434
  "Reference Contracts",
408
435
  ],
@@ -411,7 +438,13 @@ export circuit increment(): [] {
411
438
  repo: rc.repo,
412
439
  description: rc.description,
413
440
  })),
414
- note: `CRITICAL: Use quickStartTemplate as your base. Check commonMistakes before submitting code. This reference is for Compact ${COMPACT_VERSION.min}-${COMPACT_VERSION.max} (last updated: ${COMPACT_VERSION.lastUpdated}).`,
441
+ note: `CRITICAL: Use quickStartTemplate as your base. Check commonMistakes and commonErrors before submitting code.
442
+ KEY GOTCHAS:
443
+ 1. public_key() is NOT a builtin - use persistentHash pattern
444
+ 2. Counter.value() NOT available in circuits - use witnesses
445
+ 3. Map.lookup()/Set.member() NOT available in circuits - use witnesses
446
+ 4. Field vs Uint comparison requires casting
447
+ This reference is for Compact ${COMPACT_VERSION.min}-${COMPACT_VERSION.max} (last updated: ${COMPACT_VERSION.lastUpdated}).`,
415
448
  };
416
449
  }
417
450
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "midnight-mcp",
3
- "version": "0.1.34",
3
+ "version": "0.1.35",
4
4
  "description": "Model Context Protocol Server for Midnight Blockchain Development",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",