midnight-mcp 0.1.3 → 0.1.5

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.
@@ -49,6 +49,30 @@ export const codeResources = [
49
49
  description: "Starter template for private voting contracts",
50
50
  mimeType: "text/x-compact",
51
51
  },
52
+ {
53
+ uri: "midnight://code/examples/nullifier",
54
+ name: "Nullifier Pattern",
55
+ description: "How to create and use nullifiers to prevent double-spending and replay attacks",
56
+ mimeType: "text/x-compact",
57
+ },
58
+ {
59
+ uri: "midnight://code/examples/hash",
60
+ name: "Hash Functions",
61
+ description: "Using hash functions for commitments, nullifiers, and data integrity",
62
+ mimeType: "text/x-compact",
63
+ },
64
+ {
65
+ uri: "midnight://code/examples/simple-counter",
66
+ name: "Simple Counter",
67
+ description: "Minimal counter contract for beginners learning Compact",
68
+ mimeType: "text/x-compact",
69
+ },
70
+ {
71
+ uri: "midnight://code/templates/basic",
72
+ name: "Basic Contract Template",
73
+ description: "Starting template with initialization, access control, and state management",
74
+ mimeType: "text/x-compact",
75
+ },
52
76
  ];
53
77
  /**
54
78
  * Get code content by URI
@@ -536,6 +536,267 @@ export circuit addVoter(voter: Opaque<"address">): Void {
536
536
  // Add access control in real implementation
537
537
  ledger.eligibleVoters.add(voter);
538
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
+ }
539
800
  `,
540
801
  };
541
802
  //# sourceMappingURL=code-content.js.map
@@ -1,6 +1,14 @@
1
1
  /**
2
- * Embedded documentation content for offline access
3
- * Separated from docs.ts for better maintainability
2
+ * Embedded documentation content
3
+ *
4
+ * DESIGN PRINCIPLE: This file contains ONLY curated/unique content that:
5
+ * 1. Doesn't exist in official docs (wallet-integration guide we created)
6
+ * 2. Is a synthesized summary (tokenomics whitepaper)
7
+ * 3. Is a quick reference card (compact-reference, sdk-api)
8
+ * 4. Is from external sources (OpenZeppelin Compact contracts)
9
+ *
10
+ * For official Midnight docs (glossary, Zswap, Kachina concepts),
11
+ * use the search_docs tool which queries the Vector DB.
4
12
  */
5
13
  export declare const EMBEDDED_DOCS: Record<string, string>;
6
14
  //# sourceMappingURL=docs-content.d.ts.map