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.
- package/dist/resources/code.js +24 -0
- package/dist/resources/content/code-content.js +261 -0
- package/dist/resources/content/docs-content.d.ts +10 -2
- package/dist/resources/content/docs-content.js +545 -825
- package/dist/resources/docs.js +23 -32
- package/dist/server.js +2 -2
- package/package.json +1 -1
package/dist/resources/code.js
CHANGED
|
@@ -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
|
|
3
|
-
*
|
|
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
|