midnight-mcp 0.1.41 → 0.2.1

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 (100) hide show
  1. package/README.md +32 -1
  2. package/dist/bin.d.ts +1 -0
  3. package/dist/bin.js +10764 -0
  4. package/dist/index.d.ts +205 -3
  5. package/dist/index.js +10722 -15
  6. package/package.json +16 -6
  7. package/dist/config/compact-version.d.ts +0 -183
  8. package/dist/config/compact-version.js +0 -423
  9. package/dist/db/index.d.ts +0 -3
  10. package/dist/db/index.js +0 -2
  11. package/dist/db/vectorStore.d.ts +0 -69
  12. package/dist/db/vectorStore.js +0 -196
  13. package/dist/pipeline/embeddings.d.ts +0 -25
  14. package/dist/pipeline/embeddings.js +0 -103
  15. package/dist/pipeline/github.d.ts +0 -84
  16. package/dist/pipeline/github.js +0 -399
  17. package/dist/pipeline/index.d.ts +0 -11
  18. package/dist/pipeline/index.js +0 -6
  19. package/dist/pipeline/indexer.d.ts +0 -41
  20. package/dist/pipeline/indexer.js +0 -254
  21. package/dist/pipeline/parser.d.ts +0 -46
  22. package/dist/pipeline/parser.js +0 -436
  23. package/dist/pipeline/releases.d.ts +0 -112
  24. package/dist/pipeline/releases.js +0 -298
  25. package/dist/pipeline/repository.d.ts +0 -372
  26. package/dist/pipeline/repository.js +0 -520
  27. package/dist/prompts/index.d.ts +0 -3
  28. package/dist/prompts/index.js +0 -2
  29. package/dist/prompts/templates.d.ts +0 -26
  30. package/dist/prompts/templates.js +0 -443
  31. package/dist/resources/code.d.ts +0 -15
  32. package/dist/resources/code.js +0 -122
  33. package/dist/resources/content/code-content.d.ts +0 -6
  34. package/dist/resources/content/code-content.js +0 -802
  35. package/dist/resources/content/docs-content.d.ts +0 -14
  36. package/dist/resources/content/docs-content.js +0 -1202
  37. package/dist/resources/content/index.d.ts +0 -6
  38. package/dist/resources/content/index.js +0 -6
  39. package/dist/resources/docs.d.ts +0 -15
  40. package/dist/resources/docs.js +0 -98
  41. package/dist/resources/index.d.ts +0 -6
  42. package/dist/resources/index.js +0 -13
  43. package/dist/resources/schemas.d.ts +0 -16
  44. package/dist/resources/schemas.js +0 -407
  45. package/dist/scripts/index-repos.d.ts +0 -12
  46. package/dist/scripts/index-repos.js +0 -53
  47. package/dist/server.d.ts +0 -43
  48. package/dist/server.js +0 -696
  49. package/dist/services/index.d.ts +0 -6
  50. package/dist/services/index.js +0 -6
  51. package/dist/services/sampling.d.ts +0 -62
  52. package/dist/services/sampling.js +0 -277
  53. package/dist/tools/analyze.d.ts +0 -106
  54. package/dist/tools/analyze.js +0 -431
  55. package/dist/tools/generation.d.ts +0 -9
  56. package/dist/tools/generation.js +0 -285
  57. package/dist/tools/health.d.ts +0 -120
  58. package/dist/tools/health.js +0 -365
  59. package/dist/tools/index.d.ts +0 -14
  60. package/dist/tools/index.js +0 -22
  61. package/dist/tools/meta.d.ts +0 -61
  62. package/dist/tools/meta.js +0 -282
  63. package/dist/tools/repository/constants.d.ts +0 -19
  64. package/dist/tools/repository/constants.js +0 -324
  65. package/dist/tools/repository/handlers.d.ts +0 -373
  66. package/dist/tools/repository/handlers.js +0 -724
  67. package/dist/tools/repository/index.d.ts +0 -9
  68. package/dist/tools/repository/index.js +0 -13
  69. package/dist/tools/repository/schemas.d.ts +0 -153
  70. package/dist/tools/repository/schemas.js +0 -106
  71. package/dist/tools/repository/tools.d.ts +0 -7
  72. package/dist/tools/repository/tools.js +0 -484
  73. package/dist/tools/repository/validation.d.ts +0 -106
  74. package/dist/tools/repository/validation.js +0 -820
  75. package/dist/tools/repository.d.ts +0 -6
  76. package/dist/tools/repository.js +0 -7
  77. package/dist/tools/search.d.ts +0 -76
  78. package/dist/tools/search.js +0 -423
  79. package/dist/types/index.d.ts +0 -2
  80. package/dist/types/index.js +0 -2
  81. package/dist/types/mcp.d.ts +0 -187
  82. package/dist/types/mcp.js +0 -6
  83. package/dist/utils/cache.d.ts +0 -77
  84. package/dist/utils/cache.js +0 -172
  85. package/dist/utils/config.d.ts +0 -70
  86. package/dist/utils/config.js +0 -294
  87. package/dist/utils/errors.d.ts +0 -111
  88. package/dist/utils/errors.js +0 -165
  89. package/dist/utils/health.d.ts +0 -29
  90. package/dist/utils/health.js +0 -132
  91. package/dist/utils/hosted-api.d.ts +0 -67
  92. package/dist/utils/hosted-api.js +0 -119
  93. package/dist/utils/index.d.ts +0 -16
  94. package/dist/utils/index.js +0 -15
  95. package/dist/utils/logger.d.ts +0 -48
  96. package/dist/utils/logger.js +0 -124
  97. package/dist/utils/rate-limit.d.ts +0 -61
  98. package/dist/utils/rate-limit.js +0 -148
  99. package/dist/utils/validation.d.ts +0 -52
  100. package/dist/utils/validation.js +0 -255
@@ -1,802 +0,0 @@
1
- /**
2
- * Embedded code examples and templates
3
- * Separated from code.ts for better maintainability
4
- */
5
- export const EMBEDDED_CODE = {
6
- "midnight://code/examples/counter": `// Counter Example Contract
7
- // A simple contract demonstrating basic Compact concepts
8
-
9
- include "std";
10
-
11
- ledger {
12
- // Public counter - visible to everyone
13
- counter: Counter;
14
-
15
- // Track last modifier (public)
16
- lastModifier: Opaque<"address">;
17
- }
18
-
19
- // Increment the counter
20
- export circuit increment(amount: Field): Field {
21
- // Validate input
22
- assert(amount > 0, "Amount must be positive");
23
- assert(amount <= 100, "Amount too large");
24
-
25
- // Update counter
26
- ledger.counter.increment(amount);
27
-
28
- // Return new value
29
- return ledger.counter.value();
30
- }
31
-
32
- // Decrement the counter
33
- export circuit decrement(amount: Field): Field {
34
- // Validate input
35
- assert(amount > 0, "Amount must be positive");
36
- assert(ledger.counter.value() >= amount, "Counter would go negative");
37
-
38
- // Update counter
39
- ledger.counter.decrement(amount);
40
-
41
- // Return new value
42
- return ledger.counter.value();
43
- }
44
-
45
- // Read current value (view function)
46
- export circuit getValue(): Field {
47
- return ledger.counter.value();
48
- }
49
- `,
50
- "midnight://code/examples/bboard": `// Bulletin Board Example Contract
51
- // Demonstrates private messaging with selective disclosure
52
-
53
- include "std";
54
-
55
- ledger {
56
- // Public: message count and IDs
57
- messageCount: Counter;
58
- messageIds: Set<Field>;
59
-
60
- // Private: actual message contents
61
- @private
62
- messages: Map<Field, Opaque<"string">>;
63
-
64
- // Private: message authors
65
- @private
66
- authors: Map<Field, Opaque<"address">>;
67
- }
68
-
69
- // Post a new message (content is private)
70
- export circuit postMessage(content: Opaque<"string">, author: Opaque<"address">): Field {
71
- // Generate unique message ID
72
- const messageId = ledger.messageCount.value();
73
-
74
- // Store message privately
75
- ledger.messages.insert(messageId, content);
76
- ledger.authors.insert(messageId, author);
77
-
78
- // Update public counters
79
- ledger.messageCount.increment(1);
80
- ledger.messageIds.add(messageId);
81
-
82
- return messageId;
83
- }
84
-
85
- // Witness to fetch message content
86
- witness getMessageContent(id: Field): Opaque<"string"> {
87
- return ledger.messages.get(id);
88
- }
89
-
90
- // Reveal a message publicly (owner's choice)
91
- export circuit revealMessage(id: Field): Opaque<"string"> {
92
- assert(ledger.messageIds.contains(id), "Message not found");
93
-
94
- const content = getMessageContent(id);
95
- return disclose(content);
96
- }
97
-
98
- // Get total message count
99
- export circuit getMessageCount(): Field {
100
- return ledger.messageCount.value();
101
- }
102
- `,
103
- "midnight://code/patterns/state-management": `// State Management Pattern
104
- // Best practices for managing public and private state
105
-
106
- include "std";
107
-
108
- ledger {
109
- // PUBLIC STATE
110
- // - Use for data that should be transparent
111
- // - Visible in blockchain explorers
112
- // - Can be queried by anyone
113
-
114
- totalSupply: Counter;
115
- publicConfig: Field;
116
-
117
- // PRIVATE STATE
118
- // - Use for sensitive user data
119
- // - Only owner can read
120
- // - Requires witnesses to access in circuits
121
-
122
- @private
123
- userSecrets: Map<Opaque<"address">, Bytes<32>>;
124
-
125
- @private
126
- privateBalances: Map<Opaque<"address">, Field>;
127
- }
128
-
129
- // Reading public state is straightforward
130
- export circuit getTotalSupply(): Field {
131
- return ledger.totalSupply.value();
132
- }
133
-
134
- // Reading private state requires a witness
135
- witness getUserSecret(user: Opaque<"address">): Bytes<32> {
136
- return ledger.userSecrets.get(user);
137
- }
138
-
139
- // Using private state in a circuit
140
- export circuit proveSecretKnowledge(
141
- user: Opaque<"address">,
142
- secretHash: Bytes<32>
143
- ): Boolean {
144
- const secret = getUserSecret(user);
145
-
146
- // Prove knowledge without revealing secret
147
- assert(hash(secret) == secretHash);
148
- return true;
149
- }
150
-
151
- // Selective disclosure pattern
152
- export circuit revealBalance(user: Opaque<"address">): Field {
153
- const balance = getPrivateBalance(user);
154
- // Explicitly reveal - user's choice
155
- return disclose(balance);
156
- }
157
-
158
- witness getPrivateBalance(user: Opaque<"address">): Field {
159
- return ledger.privateBalances.get(user);
160
- }
161
- `,
162
- "midnight://code/patterns/access-control": `// Access Control Pattern
163
- // Implementing permissions and authorization
164
-
165
- include "std";
166
-
167
- ledger {
168
- // Role definitions
169
- owner: Opaque<"address">;
170
- admins: Set<Opaque<"address">>;
171
-
172
- // Access-controlled state
173
- sensitiveData: Field;
174
-
175
- @private
176
- adminKeys: Map<Opaque<"address">, Bytes<32>>;
177
- }
178
-
179
- // Witness to get caller identity
180
- witness getCaller(): Opaque<"address"> {
181
- return getCurrentCaller();
182
- }
183
-
184
- // Only owner can call
185
- export circuit onlyOwnerAction(newValue: Field): Void {
186
- const caller = getCaller();
187
- assert(caller == ledger.owner, "Not owner");
188
-
189
- ledger.sensitiveData = newValue;
190
- }
191
-
192
- // Only admins can call
193
- export circuit onlyAdminAction(data: Field): Void {
194
- const caller = getCaller();
195
- assert(ledger.admins.contains(caller), "Not admin");
196
-
197
- // Admin action here
198
- }
199
-
200
- // Multi-sig pattern (require multiple approvals)
201
- witness getApprovalCount(action: Bytes<32>): Field {
202
- return countApprovals(action);
203
- }
204
-
205
- export circuit requireMultisig(action: Bytes<32>, threshold: Field): Boolean {
206
- const approvals = getApprovalCount(action);
207
- assert(approvals >= threshold, "Insufficient approvals");
208
- return true;
209
- }
210
-
211
- // Time-locked action
212
- witness getCurrentTime(): Field {
213
- return getBlockTimestamp();
214
- }
215
-
216
- export circuit timeLockedAction(unlockTime: Field): Void {
217
- const currentTime = getCurrentTime();
218
- assert(currentTime >= unlockTime, "Action is timelocked");
219
-
220
- // Perform action
221
- }
222
- `,
223
- "midnight://code/patterns/privacy-preserving": `// Privacy-Preserving Patterns
224
- // Techniques for maintaining privacy in smart contracts
225
-
226
- include "std";
227
-
228
- ledger {
229
- // Commitment-based private balance
230
- balanceCommitments: Map<Opaque<"address">, Field>;
231
-
232
- // Nullifier set (prevents double-spending)
233
- nullifiers: Set<Field>;
234
-
235
- @private
236
- secretBalances: Map<Opaque<"address">, Field>;
237
-
238
- @private
239
- secretNonces: Map<Opaque<"address">, Field>;
240
- }
241
-
242
- // PATTERN 1: Commitment Scheme
243
- // Store commitments instead of values
244
-
245
- export circuit deposit(
246
- user: Opaque<"address">,
247
- amount: Field,
248
- nonce: Field
249
- ): Field {
250
- // Create commitment: hash(amount, nonce, user)
251
- const commitment = hash(amount, nonce, user);
252
-
253
- // Store commitment (hides amount)
254
- ledger.balanceCommitments.insert(user, commitment);
255
-
256
- return commitment;
257
- }
258
-
259
- export circuit proveBalance(
260
- user: Opaque<"address">,
261
- amount: Field,
262
- nonce: Field,
263
- minBalance: Field
264
- ): Boolean {
265
- // Verify commitment
266
- const expectedCommitment = hash(amount, nonce, user);
267
- assert(ledger.balanceCommitments.get(user) == expectedCommitment);
268
-
269
- // Prove property without revealing value
270
- assert(amount >= minBalance);
271
- return true;
272
- }
273
-
274
- // PATTERN 2: Nullifiers (Prevent Double-Spending)
275
-
276
- witness generateNullifier(secret: Bytes<32>, action: Field): Field {
277
- return hash(secret, action);
278
- }
279
-
280
- export circuit spendOnce(
281
- secret: Bytes<32>,
282
- action: Field
283
- ): Void {
284
- const nullifier = generateNullifier(secret, action);
285
-
286
- // Check nullifier hasn't been used
287
- assert(!ledger.nullifiers.contains(nullifier), "Already spent");
288
-
289
- // Mark as used
290
- ledger.nullifiers.add(nullifier);
291
-
292
- // Perform action
293
- }
294
-
295
- // PATTERN 3: Range Proofs
296
-
297
- export circuit proveInRange(
298
- @private value: Field,
299
- min: Field,
300
- max: Field
301
- ): Boolean {
302
- // Prove value is in range without revealing it
303
- assert(value >= min);
304
- assert(value <= max);
305
- return true;
306
- }
307
-
308
- // PATTERN 4: Private Set Membership
309
-
310
- export circuit proveMembership(
311
- @private element: Field,
312
- setRoot: Field,
313
- @private proof: Array<Field>
314
- ): Boolean {
315
- // Prove element is in set without revealing which element
316
- const computedRoot = computeMerkleRoot(element, proof);
317
- assert(computedRoot == setRoot);
318
- return true;
319
- }
320
-
321
- witness computeMerkleRoot(element: Field, proof: Array<Field>): Field {
322
- // Compute Merkle root from element and proof
323
- return merkleCompute(element, proof);
324
- }
325
- `,
326
- "midnight://code/templates/token": `// Privacy-Preserving Token Template
327
- // Starter template for token contracts with privacy features
328
-
329
- include "std";
330
-
331
- ledger {
332
- // Public token metadata
333
- name: Opaque<"string">;
334
- symbol: Opaque<"string">;
335
- decimals: Field;
336
- totalSupply: Counter;
337
-
338
- // Private balances
339
- @private
340
- balances: Map<Opaque<"address">, Field>;
341
-
342
- // Private allowances
343
- @private
344
- allowances: Map<Opaque<"address">, Map<Opaque<"address">, Field>>;
345
- }
346
-
347
- // Witnesses for private state access
348
- witness getBalance(account: Opaque<"address">): Field {
349
- return ledger.balances.get(account) ?? 0;
350
- }
351
-
352
- witness getAllowance(owner: Opaque<"address">, spender: Opaque<"address">): Field {
353
- return ledger.allowances.get(owner)?.get(spender) ?? 0;
354
- }
355
-
356
- witness getCaller(): Opaque<"address"> {
357
- return getCurrentCaller();
358
- }
359
-
360
- // Transfer tokens privately
361
- export circuit transfer(
362
- to: Opaque<"address">,
363
- amount: Field
364
- ): Boolean {
365
- const from = getCaller();
366
- const fromBalance = getBalance(from);
367
-
368
- // Validate
369
- assert(amount > 0, "Invalid amount");
370
- assert(fromBalance >= amount, "Insufficient balance");
371
-
372
- // Update balances privately
373
- ledger.balances.insert(from, fromBalance - amount);
374
- ledger.balances.insert(to, getBalance(to) + amount);
375
-
376
- return true;
377
- }
378
-
379
- // Approve spender
380
- export circuit approve(
381
- spender: Opaque<"address">,
382
- amount: Field
383
- ): Boolean {
384
- const owner = getCaller();
385
-
386
- // Get or create allowance map for owner
387
- // Note: Simplified - actual implementation needs nested map handling
388
- ledger.allowances.get(owner).insert(spender, amount);
389
-
390
- return true;
391
- }
392
-
393
- // Transfer from approved account
394
- export circuit transferFrom(
395
- from: Opaque<"address">,
396
- to: Opaque<"address">,
397
- amount: Field
398
- ): Boolean {
399
- const spender = getCaller();
400
- const allowance = getAllowance(from, spender);
401
- const fromBalance = getBalance(from);
402
-
403
- // Validate
404
- assert(amount > 0, "Invalid amount");
405
- assert(allowance >= amount, "Insufficient allowance");
406
- assert(fromBalance >= amount, "Insufficient balance");
407
-
408
- // Update state
409
- ledger.balances.insert(from, fromBalance - amount);
410
- ledger.balances.insert(to, getBalance(to) + amount);
411
- ledger.allowances.get(from).insert(spender, allowance - amount);
412
-
413
- return true;
414
- }
415
-
416
- // Reveal balance (user's choice)
417
- export circuit revealMyBalance(): Field {
418
- const caller = getCaller();
419
- const balance = getBalance(caller);
420
- return disclose(balance);
421
- }
422
- `,
423
- "midnight://code/templates/voting": `// Private Voting Template
424
- // Starter template for privacy-preserving voting contracts
425
-
426
- include "std";
427
-
428
- ledger {
429
- // Public: proposal metadata
430
- proposalCount: Counter;
431
- proposals: Map<Field, Opaque<"string">>;
432
- votingDeadlines: Map<Field, Field>;
433
-
434
- // Public: vote tallies (revealed after voting ends)
435
- finalTallies: Map<Field, Map<Field, Field>>; // proposalId -> optionId -> count
436
-
437
- // Private: individual votes
438
- @private
439
- votes: Map<Field, Map<Opaque<"address">, Field>>; // proposalId -> voter -> option
440
-
441
- // Nullifiers to prevent double voting
442
- voteNullifiers: Set<Field>;
443
-
444
- // Eligible voters
445
- eligibleVoters: Set<Opaque<"address">>;
446
- }
447
-
448
- // Witnesses
449
- witness getCaller(): Opaque<"address"> {
450
- return getCurrentCaller();
451
- }
452
-
453
- witness getCurrentTime(): Field {
454
- return getBlockTimestamp();
455
- }
456
-
457
- witness getVote(proposalId: Field, voter: Opaque<"address">): Field {
458
- return ledger.votes.get(proposalId)?.get(voter) ?? 0;
459
- }
460
-
461
- witness computeNullifier(voter: Opaque<"address">, proposalId: Field): Field {
462
- return hash(voter, proposalId);
463
- }
464
-
465
- // Create a new proposal
466
- export circuit createProposal(
467
- description: Opaque<"string">,
468
- deadline: Field,
469
- options: Field
470
- ): Field {
471
- const proposalId = ledger.proposalCount.value();
472
-
473
- // Store proposal
474
- ledger.proposals.insert(proposalId, description);
475
- ledger.votingDeadlines.insert(proposalId, deadline);
476
-
477
- // Initialize tally for each option
478
- // (Simplified - actual implementation needs loop)
479
-
480
- ledger.proposalCount.increment(1);
481
- return proposalId;
482
- }
483
-
484
- // Cast a private vote
485
- export circuit vote(
486
- proposalId: Field,
487
- option: Field
488
- ): Boolean {
489
- const voter = getCaller();
490
- const currentTime = getCurrentTime();
491
-
492
- // Check eligibility
493
- assert(ledger.eligibleVoters.contains(voter), "Not eligible to vote");
494
-
495
- // Check deadline
496
- const deadline = ledger.votingDeadlines.get(proposalId);
497
- assert(currentTime < deadline, "Voting ended");
498
-
499
- // Check for double voting using nullifier
500
- const nullifier = computeNullifier(voter, proposalId);
501
- assert(!ledger.voteNullifiers.contains(nullifier), "Already voted");
502
-
503
- // Record vote privately
504
- ledger.votes.get(proposalId).insert(voter, option);
505
-
506
- // Add nullifier to prevent double voting
507
- ledger.voteNullifiers.add(nullifier);
508
-
509
- return true;
510
- }
511
-
512
- // Reveal individual vote (voter's choice)
513
- export circuit revealMyVote(proposalId: Field): Field {
514
- const voter = getCaller();
515
- const myVote = getVote(proposalId, voter);
516
- return disclose(myVote);
517
- }
518
-
519
- // Tally votes (after deadline)
520
- // Note: This is simplified - real implementation would need
521
- // a mechanism to privately aggregate votes
522
- export circuit tallyVotes(proposalId: Field): Boolean {
523
- const currentTime = getCurrentTime();
524
- const deadline = ledger.votingDeadlines.get(proposalId);
525
-
526
- assert(currentTime >= deadline, "Voting still active");
527
-
528
- // In a real implementation, votes would be aggregated
529
- // using homomorphic encryption or MPC
530
-
531
- return true;
532
- }
533
-
534
- // Add eligible voter (admin only)
535
- export circuit addVoter(voter: Opaque<"address">): Void {
536
- // Add access control in real implementation
537
- ledger.eligibleVoters.add(voter);
538
- }
539
- `,
540
- "midnight://code/examples/nullifier": `// Nullifier Pattern Example
541
- // Demonstrates how to create and use nullifiers to prevent double-spending/actions
542
-
543
- include "std";
544
-
545
- ledger {
546
- // Set of used nullifiers - prevents replay attacks
547
- usedNullifiers: Set<Bytes<32>>;
548
-
549
- // Track claimed rewards
550
- claimedRewards: Counter;
551
- }
552
-
553
- // Hash function for creating nullifiers
554
- // Combines secret + public data to create unique identifier
555
- witness computeNullifier(secret: Field, commitment: Field): Bytes<32> {
556
- // Hash the secret with the commitment
557
- // The nullifier reveals nothing about the secret
558
- // but is unique per secret+commitment pair
559
- return hash(secret, commitment);
560
- }
561
-
562
- // Alternative: nullifier from address and action ID
563
- witness computeActionNullifier(
564
- userSecret: Field,
565
- actionId: Field
566
- ): Bytes<32> {
567
- // Create nullifier: hash(secret || actionId)
568
- return hash(userSecret, actionId);
569
- }
570
-
571
- // Claim a reward (can only claim once per user)
572
- export circuit claimReward(
573
- secret: Field,
574
- commitment: Field,
575
- rewardAmount: Field
576
- ): Boolean {
577
- // Compute the nullifier
578
- const nullifier = computeNullifier(secret, commitment);
579
-
580
- // Check nullifier hasn't been used (prevents double-claim)
581
- assert(
582
- !ledger.usedNullifiers.contains(nullifier),
583
- "Reward already claimed"
584
- );
585
-
586
- // Mark nullifier as used
587
- ledger.usedNullifiers.add(nullifier);
588
-
589
- // Process reward
590
- ledger.claimedRewards.increment(rewardAmount);
591
-
592
- return true;
593
- }
594
-
595
- // Vote with nullifier (prevents double-voting)
596
- export circuit voteWithNullifier(
597
- voterSecret: Field,
598
- proposalId: Field,
599
- vote: Field
600
- ): Boolean {
601
- // Create unique nullifier for this voter + proposal
602
- const nullifier = computeActionNullifier(voterSecret, proposalId);
603
-
604
- // Ensure hasn't voted on this proposal
605
- assert(
606
- !ledger.usedNullifiers.contains(nullifier),
607
- "Already voted on this proposal"
608
- );
609
-
610
- // Record nullifier
611
- ledger.usedNullifiers.add(nullifier);
612
-
613
- // Process vote...
614
- return true;
615
- }
616
- `,
617
- "midnight://code/examples/hash": `// Hash Functions in Compact
618
- // Examples of using hash functions for various purposes
619
-
620
- include "std";
621
-
622
- ledger {
623
- commitments: Set<Bytes<32>>;
624
- hashedData: Map<Field, Bytes<32>>;
625
- }
626
-
627
- // Basic hash function usage
628
- witness simpleHash(data: Field): Bytes<32> {
629
- // Hash a single field element
630
- return hash(data);
631
- }
632
-
633
- // Hash multiple values together
634
- witness hashMultiple(a: Field, b: Field, c: Field): Bytes<32> {
635
- // Concatenate and hash
636
- return hash(a, b, c);
637
- }
638
-
639
- // Create a commitment (hash of value + randomness)
640
- witness createCommitment(value: Field, randomness: Field): Bytes<32> {
641
- // Pedersen-style commitment: H(value || randomness)
642
- return hash(value, randomness);
643
- }
644
-
645
- // Hash bytes data
646
- witness hashBytes(data: Bytes<64>): Bytes<32> {
647
- return hash(data);
648
- }
649
-
650
- // Create nullifier from secret
651
- witness createNullifier(secret: Field, publicInput: Field): Bytes<32> {
652
- // Nullifier = H(secret || publicInput)
653
- // Reveals nothing about secret, but is deterministic
654
- return hash(secret, publicInput);
655
- }
656
-
657
- // Verify a commitment matches
658
- export circuit verifyCommitment(
659
- value: Field,
660
- randomness: Field,
661
- expectedCommitment: Bytes<32>
662
- ): Boolean {
663
- const computed = createCommitment(value, randomness);
664
- assert(computed == expectedCommitment, "Commitment mismatch");
665
- return true;
666
- }
667
-
668
- // Store a hashed value
669
- export circuit storeHashed(id: Field, data: Field): Bytes<32> {
670
- const hashed = simpleHash(data);
671
- ledger.hashedData.insert(id, hashed);
672
- return hashed;
673
- }
674
-
675
- // Commit-reveal pattern
676
- export circuit commit(commitment: Bytes<32>): Boolean {
677
- assert(!ledger.commitments.contains(commitment), "Already committed");
678
- ledger.commitments.add(commitment);
679
- return true;
680
- }
681
-
682
- export circuit reveal(value: Field, randomness: Field): Field {
683
- const commitment = createCommitment(value, randomness);
684
- assert(ledger.commitments.contains(commitment), "No matching commitment");
685
- return disclose(value);
686
- }
687
- `,
688
- "midnight://code/examples/simple-counter": `// Simple Counter Contract
689
- // Minimal example for learning Compact basics
690
-
691
- include "std";
692
-
693
- // Ledger state - stored on chain
694
- ledger {
695
- counter: Counter;
696
- }
697
-
698
- // Increment the counter by 1
699
- export circuit increment(): Field {
700
- ledger.counter.increment(1);
701
- return ledger.counter.value();
702
- }
703
-
704
- // Decrement the counter by 1
705
- export circuit decrement(): Field {
706
- assert(ledger.counter.value() > 0, "Cannot go below zero");
707
- ledger.counter.decrement(1);
708
- return ledger.counter.value();
709
- }
710
-
711
- // Get current value
712
- export circuit get(): Field {
713
- return ledger.counter.value();
714
- }
715
-
716
- // Reset to zero (add access control in real apps)
717
- export circuit reset(): Void {
718
- const current = ledger.counter.value();
719
- ledger.counter.decrement(current);
720
- }
721
- `,
722
- "midnight://code/templates/basic": `// Basic Compact Contract Template
723
- // Starting point for new contracts
724
-
725
- include "std";
726
-
727
- // ============================================
728
- // LEDGER STATE
729
- // ============================================
730
-
731
- ledger {
732
- // Public state (visible on-chain)
733
- initialized: Boolean;
734
- owner: Opaque<"address">;
735
-
736
- // Private state (only owner can see)
737
- @private
738
- secretData: Field;
739
- }
740
-
741
- // ============================================
742
- // INITIALIZATION
743
- // ============================================
744
-
745
- export circuit initialize(ownerAddress: Opaque<"address">): Boolean {
746
- assert(!ledger.initialized, "Already initialized");
747
-
748
- ledger.owner = ownerAddress;
749
- ledger.initialized = true;
750
-
751
- return true;
752
- }
753
-
754
- // ============================================
755
- // ACCESS CONTROL
756
- // ============================================
757
-
758
- witness getCaller(): Opaque<"address"> {
759
- // Returns the transaction sender
760
- return context.caller;
761
- }
762
-
763
- witness isOwner(): Boolean {
764
- return getCaller() == ledger.owner;
765
- }
766
-
767
- // ============================================
768
- // PUBLIC FUNCTIONS
769
- // ============================================
770
-
771
- export circuit publicFunction(input: Field): Field {
772
- assert(ledger.initialized, "Not initialized");
773
-
774
- // Your logic here
775
- return input * 2;
776
- }
777
-
778
- // ============================================
779
- // OWNER-ONLY FUNCTIONS
780
- // ============================================
781
-
782
- export circuit setSecret(newSecret: Field): Void {
783
- assert(isOwner(), "Only owner can set secret");
784
- ledger.secretData = newSecret;
785
- }
786
-
787
- // ============================================
788
- // PRIVATE DATA ACCESS
789
- // ============================================
790
-
791
- witness getSecret(): Field {
792
- assert(isOwner(), "Only owner can view");
793
- return ledger.secretData;
794
- }
795
-
796
- export circuit revealSecret(): Field {
797
- assert(isOwner(), "Only owner can reveal");
798
- return disclose(getSecret());
799
- }
800
- `,
801
- };
802
- //# sourceMappingURL=code-content.js.map