midnight-mcp 0.1.1 → 0.1.3

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.
@@ -0,0 +1,1173 @@
1
+ /**
2
+ * Embedded documentation content for offline access
3
+ * Separated from docs.ts for better maintainability
4
+ */
5
+ export const EMBEDDED_DOCS = {
6
+ "midnight://docs/compact-reference": `# Compact Language Reference
7
+
8
+ Compact is a TypeScript-inspired language for writing privacy-preserving smart contracts on Midnight.
9
+
10
+ ## Basic Structure
11
+
12
+ \`\`\`compact
13
+ include "std";
14
+
15
+ ledger {
16
+ // Public state (on-chain, visible to everyone)
17
+ counter: Counter;
18
+
19
+ // Private state (off-chain, only owner can see)
20
+ @private
21
+ secretValue: Field;
22
+ }
23
+
24
+ // Circuit - generates ZK proof
25
+ export circuit increment(amount: Field): Void {
26
+ assert(amount > 0);
27
+ ledger.counter.increment(amount);
28
+ }
29
+
30
+ // Witness - off-chain computation
31
+ witness getSecret(): Field {
32
+ return ledger.secretValue;
33
+ }
34
+ \`\`\`
35
+
36
+ ## Data Types
37
+
38
+ ### Primitive Types
39
+ - \`Field\` - Finite field element (basic numeric type)
40
+ - \`Boolean\` - True or false
41
+ - \`Bytes<N>\` - Fixed-size byte array
42
+ - \`Uint<N>\` - Unsigned integer (N = 8, 16, 32, 64, 128, 256)
43
+
44
+ ### Collection Types
45
+ - \`Counter\` - Incrementable/decrementable counter
46
+ - \`Map<K, V>\` - Key-value mapping
47
+ - \`Set<T>\` - Collection of unique values
48
+ - \`Opaque<T>\` - Type-safe wrapper for arbitrary data
49
+
50
+ ## Circuits
51
+
52
+ Circuits are functions that generate zero-knowledge proofs:
53
+
54
+ \`\`\`compact
55
+ export circuit transfer(to: Address, amount: Field): Void {
56
+ // Assertions create ZK constraints
57
+ assert(amount > 0);
58
+ assert(ledger.balance.value() >= amount);
59
+
60
+ // State modifications
61
+ ledger.balance.decrement(amount);
62
+ }
63
+ \`\`\`
64
+
65
+ ### Key Points:
66
+ - \`export\` makes circuit callable from outside
67
+ - Must be deterministic (same inputs = same outputs)
68
+ - Cannot access external data directly (use witnesses)
69
+ - Assertions become ZK constraints
70
+
71
+ ## Witnesses
72
+
73
+ Witnesses provide off-chain data to circuits:
74
+
75
+ \`\`\`compact
76
+ witness getCurrentPrice(): Field {
77
+ // This runs off-chain
78
+ return fetchPrice();
79
+ }
80
+
81
+ export circuit swap(amount: Field): Void {
82
+ const price = getCurrentPrice();
83
+ // Use price in circuit logic
84
+ }
85
+ \`\`\`
86
+
87
+ ## Built-in Functions
88
+
89
+ ### Cryptographic
90
+ - \`hash(data)\` - Compute cryptographic hash
91
+ - \`commit(value)\` - Create hiding commitment
92
+ - \`disclose(private)\` - Reveal private data
93
+
94
+ ### State Operations
95
+ - \`Counter.increment(n)\` - Add to counter
96
+ - \`Counter.decrement(n)\` - Subtract from counter
97
+ - \`Counter.value()\` - Read current value
98
+ - \`Map.insert(k, v)\` - Add key-value
99
+ - \`Map.get(k)\` - Retrieve value
100
+ - \`Set.add(v)\` - Add to set
101
+ - \`Set.contains(v)\` - Check membership
102
+
103
+ ## Privacy Annotations
104
+
105
+ \`\`\`compact
106
+ ledger {
107
+ publicData: Field; // Visible on-chain
108
+ @private
109
+ privateData: Field; // Only owner sees
110
+ }
111
+ \`\`\`
112
+ `,
113
+ "midnight://docs/sdk-api": `# Midnight TypeScript SDK API
114
+
115
+ ## Installation
116
+
117
+ \`\`\`bash
118
+ npm install @midnight-ntwrk/midnight-js-contracts @midnight-ntwrk/midnight-js-types
119
+ \`\`\`
120
+
121
+ ## Core Packages
122
+
123
+ ### @midnight-ntwrk/midnight-js-contracts
124
+ Contract interaction layer for deploying and calling Midnight smart contracts.
125
+
126
+ \`\`\`typescript
127
+ import { Contract, DeployedContract } from '@midnight-ntwrk/midnight-js-contracts';
128
+
129
+ // Deploy a contract
130
+ const deployed = await Contract.deploy(
131
+ wallet,
132
+ contractArtifact,
133
+ initialState
134
+ );
135
+
136
+ // Call a circuit
137
+ const result = await deployed.call('increment', { amount: 1n });
138
+ \`\`\`
139
+
140
+ ### @midnight-ntwrk/midnight-js-types
141
+ Shared types and interfaces for the SDK.
142
+
143
+ \`\`\`typescript
144
+ import type {
145
+ Address,
146
+ Transaction,
147
+ Proof,
148
+ ContractState
149
+ } from '@midnight-ntwrk/midnight-js-types';
150
+ \`\`\`
151
+
152
+ ### @midnight-ntwrk/wallet-api
153
+ Wallet integration interface.
154
+
155
+ \`\`\`typescript
156
+ import { WalletAPI } from '@midnight-ntwrk/wallet-api';
157
+
158
+ const wallet = await WalletAPI.connect();
159
+ const address = await wallet.getAddress();
160
+ const balance = await wallet.getBalance();
161
+ \`\`\`
162
+
163
+ ## Common Patterns
164
+
165
+ ### Contract Deployment
166
+ \`\`\`typescript
167
+ import { Contract } from '@midnight-ntwrk/midnight-js-contracts';
168
+ import counterContract from './counter.json';
169
+
170
+ async function deployCounter() {
171
+ const deployed = await Contract.deploy(
172
+ wallet,
173
+ counterContract,
174
+ { counter: 0n }
175
+ );
176
+
177
+ console.log('Deployed at:', deployed.address);
178
+ return deployed;
179
+ }
180
+ \`\`\`
181
+
182
+ ### Calling Circuits
183
+ \`\`\`typescript
184
+ async function increment(contract: DeployedContract, amount: bigint) {
185
+ const tx = await contract.call('increment', { amount });
186
+ await tx.wait();
187
+
188
+ const newValue = await contract.query('counter');
189
+ return newValue;
190
+ }
191
+ \`\`\`
192
+
193
+ ### Querying State
194
+ \`\`\`typescript
195
+ async function getState(contract: DeployedContract) {
196
+ const publicState = await contract.query('publicField');
197
+ // Note: Private state requires witness functions
198
+ return publicState;
199
+ }
200
+ \`\`\`
201
+ `,
202
+ "midnight://docs/concepts/zero-knowledge": `# Zero-Knowledge Proofs in Midnight
203
+
204
+ ## What are Zero-Knowledge Proofs?
205
+
206
+ Zero-knowledge proofs (ZKPs) allow one party (the prover) to convince another party (the verifier) that a statement is true, without revealing any information beyond the validity of the statement.
207
+
208
+ ## How Midnight Uses ZKPs
209
+
210
+ In Midnight, every circuit execution generates a zero-knowledge proof:
211
+
212
+ 1. **User calls a circuit** with private inputs
213
+ 2. **Proof is generated** off-chain
214
+ 3. **Only the proof** (not the inputs) is submitted to the blockchain
215
+ 4. **Validators verify** the proof without knowing the inputs
216
+
217
+ ## Example
218
+
219
+ \`\`\`compact
220
+ export circuit proveAge(birthYear: Field): Boolean {
221
+ const currentYear = 2024;
222
+ const age = currentYear - birthYear;
223
+
224
+ // Proves user is over 18 without revealing exact age
225
+ assert(age >= 18);
226
+ return true;
227
+ }
228
+ \`\`\`
229
+
230
+ When this circuit runs:
231
+ - Input: \`birthYear = 1990\` (private)
232
+ - Output: \`true\` (public)
233
+ - Proof: "I know a birthYear that makes age >= 18" (public)
234
+
235
+ The verifier learns the user is over 18, but not their actual birth year.
236
+
237
+ ## Key Properties
238
+
239
+ 1. **Completeness**: Valid proofs always verify
240
+ 2. **Soundness**: Invalid proofs cannot be forged
241
+ 3. **Zero-knowledge**: Nothing beyond validity is revealed
242
+
243
+ ## Privacy Patterns
244
+
245
+ ### Selective Disclosure
246
+ \`\`\`compact
247
+ export circuit verifyCredential(
248
+ @private credential: Credential
249
+ ): Field {
250
+ // Prove credential is valid
251
+ assert(credential.isValid());
252
+
253
+ // Only reveal specific fields
254
+ return disclose(credential.issuer);
255
+ }
256
+ \`\`\`
257
+
258
+ ### Hidden Computation
259
+ \`\`\`compact
260
+ export circuit secretBid(
261
+ @private amount: Field,
262
+ commitment: Field
263
+ ): Void {
264
+ // Prove bid matches commitment without revealing amount
265
+ assert(commit(amount) == commitment);
266
+ }
267
+ \`\`\`
268
+ `,
269
+ "midnight://docs/concepts/shielded-state": `# Shielded vs Unshielded State
270
+
271
+ Midnight supports two types of state: shielded (private) and unshielded (public).
272
+
273
+ ## Unshielded State
274
+
275
+ Public state visible to everyone on the blockchain:
276
+
277
+ \`\`\`compact
278
+ ledger {
279
+ totalSupply: Counter; // Public counter
280
+ balances: Map<Address, Field>; // Public mapping
281
+ }
282
+ \`\`\`
283
+
284
+ **Use for:**
285
+ - Token total supply
286
+ - Public voting tallies
287
+ - Any data that should be transparent
288
+
289
+ ## Shielded State
290
+
291
+ Private state only visible to the owner:
292
+
293
+ \`\`\`compact
294
+ ledger {
295
+ @private
296
+ secretKey: Bytes<32>;
297
+
298
+ @private
299
+ privateBalance: Field;
300
+ }
301
+ \`\`\`
302
+
303
+ **Use for:**
304
+ - User credentials
305
+ - Private balances
306
+ - Sensitive personal data
307
+
308
+ ## Hybrid Approach
309
+
310
+ Most contracts use both:
311
+
312
+ \`\`\`compact
313
+ ledger {
314
+ // Public: anyone can see total messages
315
+ messageCount: Counter;
316
+
317
+ // Private: only owner sees message contents
318
+ @private
319
+ messages: Map<Field, Opaque<"string">>;
320
+ }
321
+
322
+ export circuit postMessage(content: Opaque<"string">): Void {
323
+ const id = ledger.messageCount.value();
324
+
325
+ // Public increment
326
+ ledger.messageCount.increment(1);
327
+
328
+ // Private storage
329
+ ledger.messages.insert(id, content);
330
+ }
331
+ \`\`\`
332
+
333
+ ## Transitioning Between States
334
+
335
+ ### Disclose: Private → Public
336
+ \`\`\`compact
337
+ export circuit revealBalance(): Field {
338
+ // Reveal private balance publicly
339
+ return disclose(ledger.privateBalance);
340
+ }
341
+ \`\`\`
342
+
343
+ ### Commit: Public → Hidden
344
+ \`\`\`compact
345
+ export circuit hideValue(value: Field): Field {
346
+ // Create commitment (hides value but proves existence)
347
+ return commit(value);
348
+ }
349
+ \`\`\`
350
+ `,
351
+ "midnight://docs/concepts/witnesses": `# Witness Functions
352
+
353
+ Witnesses provide off-chain data to circuits in Midnight.
354
+
355
+ ## Why Witnesses?
356
+
357
+ Circuits run in a ZK environment with limitations:
358
+ - Cannot make network requests
359
+ - Cannot access system time
360
+ - Cannot read external files
361
+ - Must be deterministic
362
+
363
+ Witnesses bridge this gap by running off-chain.
364
+
365
+ ## Basic Witness
366
+
367
+ \`\`\`compact
368
+ // Runs off-chain, provides data to circuits
369
+ witness getTimestamp(): Field {
370
+ return getCurrentUnixTime();
371
+ }
372
+
373
+ export circuit timedAction(): Void {
374
+ const timestamp = getTimestamp();
375
+ assert(timestamp > ledger.deadline);
376
+ // ... perform action
377
+ }
378
+ \`\`\`
379
+
380
+ ## Witness with Parameters
381
+
382
+ \`\`\`compact
383
+ witness fetchPrice(asset: Opaque<"string">): Field {
384
+ // Off-chain: call price oracle
385
+ return callPriceOracle(asset);
386
+ }
387
+
388
+ export circuit swap(asset: Opaque<"string">, amount: Field): Void {
389
+ const price = fetchPrice(asset);
390
+ const total = amount * price;
391
+ // ... execute swap
392
+ }
393
+ \`\`\`
394
+
395
+ ## Private Data Access
396
+
397
+ Witnesses can access private ledger state:
398
+
399
+ \`\`\`compact
400
+ ledger {
401
+ @private
402
+ secretNonce: Field;
403
+ }
404
+
405
+ witness getNextNonce(): Field {
406
+ const current = ledger.secretNonce;
407
+ return current + 1;
408
+ }
409
+
410
+ export circuit signedOperation(data: Field): Field {
411
+ const nonce = getNextNonce();
412
+ return hash(data, nonce);
413
+ }
414
+ \`\`\`
415
+
416
+ ## Best Practices
417
+
418
+ 1. **Keep witnesses simple** - Complex logic should be in circuits
419
+ 2. **Handle failures gracefully** - Witnesses can fail
420
+ 3. **Don't trust witness data blindly** - Validate in circuits
421
+ 4. **Cache when possible** - Reduce off-chain calls
422
+
423
+ ## Security Considerations
424
+
425
+ ⚠️ Witnesses are NOT proven in ZK:
426
+ - Circuit verifies witness output is used correctly
427
+ - But doesn't verify HOW witness computed the value
428
+ - Malicious witnesses can provide false data
429
+
430
+ Always add assertions to validate witness data:
431
+
432
+ \`\`\`compact
433
+ export circuit usePrice(asset: Opaque<"string">): Void {
434
+ const price = fetchPrice(asset);
435
+
436
+ // Validate witness data
437
+ assert(price > 0);
438
+ assert(price < MAX_REASONABLE_PRICE);
439
+
440
+ // ... use price
441
+ }
442
+ \`\`\`
443
+ `,
444
+ "midnight://docs/concepts/kachina": `# Kachina Protocol
445
+
446
+ Kachina is the cryptographic protocol underlying Midnight's privacy features.
447
+
448
+ ## Overview
449
+
450
+ Kachina enables:
451
+ - Private smart contracts with public verifiability
452
+ - Composable privacy across contracts
453
+ - Efficient on-chain verification
454
+
455
+ ## Architecture
456
+
457
+ \`\`\`
458
+ ┌─────────────────┐ ┌─────────────────┐
459
+ │ User Wallet │────▶│ Compact Code │
460
+ └─────────────────┘ └────────┬────────┘
461
+
462
+ ┌────────▼────────┐
463
+ │ ZK Circuit │
464
+ │ (Prover) │
465
+ └────────┬────────┘
466
+
467
+ ┌────────▼────────┐
468
+ │ Proof │
469
+ └────────┬────────┘
470
+
471
+ ┌────────▼────────┐
472
+ │ Midnight │
473
+ │ Validators │
474
+ └─────────────────┘
475
+ \`\`\`
476
+
477
+ ## Key Concepts
478
+
479
+ ### State Model
480
+ - **Public State**: Stored on-chain, visible to all
481
+ - **Private State**: Stored off-chain, encrypted
482
+ - **Commitments**: On-chain references to private state
483
+
484
+ ### Transaction Flow
485
+ 1. User prepares transaction locally
486
+ 2. Prover generates ZK proof
487
+ 3. Transaction + proof submitted to network
488
+ 4. Validators verify proof (not re-execute)
489
+ 5. State updates applied
490
+
491
+ ### Composability
492
+ Contracts can interact while preserving privacy:
493
+
494
+ \`\`\`compact
495
+ // Contract A
496
+ export circuit transferToken(to: Address, amount: Field): Void {
497
+ // Private transfer logic
498
+ }
499
+
500
+ // Contract B can call Contract A
501
+ export circuit atomicSwap(
502
+ tokenA: Address,
503
+ tokenB: Address,
504
+ amountA: Field,
505
+ amountB: Field
506
+ ): Void {
507
+ // Both transfers happen atomically
508
+ // Privacy preserved for both
509
+ }
510
+ \`\`\`
511
+
512
+ ## Benefits
513
+
514
+ 1. **Privacy by Default**: All computation is private unless explicitly disclosed
515
+ 2. **Scalability**: Verification is faster than re-execution
516
+ 3. **Flexibility**: Developers choose what to reveal
517
+ 4. **Interoperability**: Works with existing blockchain infrastructure
518
+ `,
519
+ "midnight://docs/openzeppelin": `# OpenZeppelin Contracts for Compact
520
+
521
+ > **Official Documentation**: https://docs.openzeppelin.com/contracts-compact
522
+ > **GitHub Repository**: https://github.com/OpenZeppelin/compact-contracts
523
+
524
+ OpenZeppelin Contracts for Compact is the **official and recommended** library for building secure smart contracts on Midnight. This library provides audited, battle-tested modules for common patterns.
525
+
526
+ ## Installation
527
+
528
+ \`\`\`bash
529
+ # Create project directory
530
+ mkdir my-project && cd my-project
531
+
532
+ # Initialize git and add as submodule
533
+ git init && git submodule add https://github.com/OpenZeppelin/compact-contracts.git
534
+
535
+ # Install dependencies
536
+ cd compact-contracts
537
+ nvm install && yarn && SKIP_ZK=true yarn compact
538
+ \`\`\`
539
+
540
+ ## Available Modules
541
+
542
+ ### Token
543
+ - **FungibleToken**: Standard token implementation with transfer, mint, burn
544
+ - Recommended for all token contracts on Midnight
545
+
546
+ ### Access Control
547
+ - **Ownable**: Single owner access control
548
+ - **AccessControl**: Role-based access control
549
+
550
+ ### Security
551
+ - **Pausable**: Emergency stop mechanism
552
+
553
+ ## Usage Example
554
+
555
+ \`\`\`compact
556
+ pragma language_version >= 0.16.0;
557
+
558
+ import CompactStandardLibrary;
559
+ import "./compact-contracts/node_modules/@openzeppelin-compact/contracts/src/access/Ownable" prefix Ownable_;
560
+ import "./compact-contracts/node_modules/@openzeppelin-compact/contracts/src/security/Pausable" prefix Pausable_;
561
+ import "./compact-contracts/node_modules/@openzeppelin-compact/contracts/src/token/FungibleToken" prefix FungibleToken_;
562
+
563
+ constructor(
564
+ _name: Opaque<"string">,
565
+ _symbol: Opaque<"string">,
566
+ _decimals: Uint<8>,
567
+ _recipient: Either<ZswapCoinPublicKey, ContractAddress>,
568
+ _amount: Uint<128>,
569
+ _initOwner: Either<ZswapCoinPublicKey, ContractAddress>,
570
+ ) {
571
+ Ownable_initialize(_initOwner);
572
+ FungibleToken_initialize(_name, _symbol, _decimals);
573
+ FungibleToken__mint(_recipient, _amount);
574
+ }
575
+
576
+ export circuit transfer(
577
+ to: Either<ZswapCoinPublicKey, ContractAddress>,
578
+ value: Uint<128>,
579
+ ): Boolean {
580
+ Pausable_assertNotPaused();
581
+ return FungibleToken_transfer(to, value);
582
+ }
583
+
584
+ export circuit pause(): [] {
585
+ Ownable_assertOnlyOwner();
586
+ Pausable__pause();
587
+ }
588
+
589
+ export circuit unpause(): [] {
590
+ Ownable_assertOnlyOwner();
591
+ Pausable__unpause();
592
+ }
593
+ \`\`\`
594
+
595
+ ## Compilation
596
+
597
+ \`\`\`bash
598
+ compact compile MyContract.compact artifacts/MyContract
599
+ \`\`\`
600
+
601
+ ## Why Use OpenZeppelin?
602
+
603
+ 1. **Security Audited**: Contracts are professionally audited
604
+ 2. **Battle-Tested**: Used in production across the ecosystem
605
+ 3. **Official Recommendation**: Midnight's recommended library for tokens
606
+ 4. **Modularity**: Use only what you need
607
+ 5. **Best Practices**: Follows Compact language best practices
608
+ `,
609
+ "midnight://docs/openzeppelin/token": `# OpenZeppelin FungibleToken
610
+
611
+ > **This is the official and recommended token standard for Midnight.**
612
+
613
+ The FungibleToken module provides a complete implementation for fungible tokens on Midnight.
614
+
615
+ ## Features
616
+
617
+ - ERC20-compatible interface
618
+ - Transfer with balance tracking
619
+ - Mint and burn operations
620
+ - Approval and transferFrom patterns
621
+ - Privacy-preserving by default
622
+
623
+ ## Basic Usage
624
+
625
+ \`\`\`compact
626
+ pragma language_version >= 0.16.0;
627
+
628
+ import "./compact-contracts/node_modules/@openzeppelin-compact/contracts/src/token/FungibleToken" prefix FungibleToken_;
629
+
630
+ constructor(
631
+ _name: Opaque<"string">,
632
+ _symbol: Opaque<"string">,
633
+ _decimals: Uint<8>,
634
+ _recipient: Either<ZswapCoinPublicKey, ContractAddress>,
635
+ _initialSupply: Uint<128>,
636
+ ) {
637
+ FungibleToken_initialize(_name, _symbol, _decimals);
638
+ FungibleToken__mint(_recipient, _initialSupply);
639
+ }
640
+
641
+ // Transfer tokens
642
+ export circuit transfer(
643
+ to: Either<ZswapCoinPublicKey, ContractAddress>,
644
+ value: Uint<128>,
645
+ ): Boolean {
646
+ return FungibleToken_transfer(to, value);
647
+ }
648
+
649
+ // Check balance (witness function for privacy)
650
+ witness balanceOf(
651
+ account: Either<ZswapCoinPublicKey, ContractAddress>
652
+ ): Uint<128> {
653
+ return FungibleToken_balanceOf(account);
654
+ }
655
+
656
+ // Get total supply
657
+ witness totalSupply(): Uint<128> {
658
+ return FungibleToken_totalSupply();
659
+ }
660
+ \`\`\`
661
+
662
+ ## Advanced: With Approval Pattern
663
+
664
+ \`\`\`compact
665
+ // Approve spender
666
+ export circuit approve(
667
+ spender: Either<ZswapCoinPublicKey, ContractAddress>,
668
+ value: Uint<128>,
669
+ ): Boolean {
670
+ return FungibleToken_approve(spender, value);
671
+ }
672
+
673
+ // Transfer from approved account
674
+ export circuit transferFrom(
675
+ from: Either<ZswapCoinPublicKey, ContractAddress>,
676
+ to: Either<ZswapCoinPublicKey, ContractAddress>,
677
+ value: Uint<128>,
678
+ ): Boolean {
679
+ return FungibleToken_transferFrom(from, to, value);
680
+ }
681
+ \`\`\`
682
+
683
+ ## Mint and Burn (Owner-Only)
684
+
685
+ \`\`\`compact
686
+ import "./compact-contracts/node_modules/@openzeppelin-compact/contracts/src/access/Ownable" prefix Ownable_;
687
+
688
+ export circuit mint(
689
+ to: Either<ZswapCoinPublicKey, ContractAddress>,
690
+ amount: Uint<128>,
691
+ ): [] {
692
+ Ownable_assertOnlyOwner();
693
+ FungibleToken__mint(to, amount);
694
+ }
695
+
696
+ export circuit burn(
697
+ from: Either<ZswapCoinPublicKey, ContractAddress>,
698
+ amount: Uint<128>,
699
+ ): [] {
700
+ Ownable_assertOnlyOwner();
701
+ FungibleToken__burn(from, amount);
702
+ }
703
+ \`\`\`
704
+ `,
705
+ "midnight://docs/openzeppelin/access": `# OpenZeppelin Access Control
706
+
707
+ Access control modules for managing permissions in your contracts.
708
+
709
+ ## Ownable
710
+
711
+ Simple single-owner access control.
712
+
713
+ \`\`\`compact
714
+ pragma language_version >= 0.16.0;
715
+
716
+ import "./compact-contracts/node_modules/@openzeppelin-compact/contracts/src/access/Ownable" prefix Ownable_;
717
+
718
+ constructor(
719
+ _owner: Either<ZswapCoinPublicKey, ContractAddress>,
720
+ ) {
721
+ Ownable_initialize(_owner);
722
+ }
723
+
724
+ // Only owner can call this
725
+ export circuit adminFunction(): [] {
726
+ Ownable_assertOnlyOwner();
727
+ // ... admin logic
728
+ }
729
+
730
+ // Transfer ownership
731
+ export circuit transferOwnership(
732
+ newOwner: Either<ZswapCoinPublicKey, ContractAddress>,
733
+ ): [] {
734
+ Ownable_assertOnlyOwner();
735
+ Ownable_transferOwnership(newOwner);
736
+ }
737
+
738
+ // Renounce ownership (irreversible!)
739
+ export circuit renounceOwnership(): [] {
740
+ Ownable_assertOnlyOwner();
741
+ Ownable_renounceOwnership();
742
+ }
743
+
744
+ // Check current owner
745
+ witness owner(): Either<ZswapCoinPublicKey, ContractAddress> {
746
+ return Ownable_owner();
747
+ }
748
+ \`\`\`
749
+
750
+ ## AccessControl (Role-Based)
751
+
752
+ For contracts needing multiple roles with different permissions.
753
+
754
+ \`\`\`compact
755
+ import "./compact-contracts/node_modules/@openzeppelin-compact/contracts/src/access/AccessControl" prefix AC_;
756
+
757
+ // Define role identifiers
758
+ const MINTER_ROLE: Bytes<32> = keccak256("MINTER_ROLE");
759
+ const PAUSER_ROLE: Bytes<32> = keccak256("PAUSER_ROLE");
760
+
761
+ constructor(_admin: Either<ZswapCoinPublicKey, ContractAddress>) {
762
+ AC_initialize(_admin);
763
+ AC__grantRole(MINTER_ROLE, _admin);
764
+ AC__grantRole(PAUSER_ROLE, _admin);
765
+ }
766
+
767
+ // Only minters can call
768
+ export circuit mint(to: Address, amount: Uint<128>): [] {
769
+ AC_assertOnlyRole(MINTER_ROLE);
770
+ // ... mint logic
771
+ }
772
+
773
+ // Only pausers can call
774
+ export circuit pause(): [] {
775
+ AC_assertOnlyRole(PAUSER_ROLE);
776
+ // ... pause logic
777
+ }
778
+
779
+ // Grant role (admin only)
780
+ export circuit grantRole(
781
+ role: Bytes<32>,
782
+ account: Either<ZswapCoinPublicKey, ContractAddress>,
783
+ ): [] {
784
+ AC_assertOnlyRole(AC_DEFAULT_ADMIN_ROLE());
785
+ AC__grantRole(role, account);
786
+ }
787
+ \`\`\`
788
+ `,
789
+ "midnight://docs/openzeppelin/security": `# OpenZeppelin Security Patterns
790
+
791
+ Security modules for protecting your contracts.
792
+
793
+ ## Pausable
794
+
795
+ Emergency stop mechanism for your contract.
796
+
797
+ \`\`\`compact
798
+ pragma language_version >= 0.16.0;
799
+
800
+ import "./compact-contracts/node_modules/@openzeppelin-compact/contracts/src/security/Pausable" prefix Pausable_;
801
+ import "./compact-contracts/node_modules/@openzeppelin-compact/contracts/src/access/Ownable" prefix Ownable_;
802
+
803
+ constructor(_owner: Either<ZswapCoinPublicKey, ContractAddress>) {
804
+ Ownable_initialize(_owner);
805
+ // Contract starts unpaused
806
+ }
807
+
808
+ // Protected function - won't work when paused
809
+ export circuit transfer(
810
+ to: Either<ZswapCoinPublicKey, ContractAddress>,
811
+ amount: Uint<128>,
812
+ ): Boolean {
813
+ Pausable_assertNotPaused();
814
+ // ... transfer logic
815
+ }
816
+
817
+ // Owner can pause
818
+ export circuit pause(): [] {
819
+ Ownable_assertOnlyOwner();
820
+ Pausable__pause();
821
+ }
822
+
823
+ // Owner can unpause
824
+ export circuit unpause(): [] {
825
+ Ownable_assertOnlyOwner();
826
+ Pausable__unpause();
827
+ }
828
+
829
+ // Check if paused
830
+ witness isPaused(): Boolean {
831
+ return Pausable_paused();
832
+ }
833
+ \`\`\`
834
+
835
+ ## Combined Example: Secure Token
836
+
837
+ \`\`\`compact
838
+ pragma language_version >= 0.16.0;
839
+
840
+ import CompactStandardLibrary;
841
+ import "./compact-contracts/node_modules/@openzeppelin-compact/contracts/src/access/Ownable" prefix Ownable_;
842
+ import "./compact-contracts/node_modules/@openzeppelin-compact/contracts/src/security/Pausable" prefix Pausable_;
843
+ import "./compact-contracts/node_modules/@openzeppelin-compact/contracts/src/token/FungibleToken" prefix FungibleToken_;
844
+
845
+ constructor(
846
+ _name: Opaque<"string">,
847
+ _symbol: Opaque<"string">,
848
+ _decimals: Uint<8>,
849
+ _initialSupply: Uint<128>,
850
+ _owner: Either<ZswapCoinPublicKey, ContractAddress>,
851
+ ) {
852
+ Ownable_initialize(_owner);
853
+ FungibleToken_initialize(_name, _symbol, _decimals);
854
+ FungibleToken__mint(_owner, _initialSupply);
855
+ }
856
+
857
+ // Pausable transfer
858
+ export circuit transfer(
859
+ to: Either<ZswapCoinPublicKey, ContractAddress>,
860
+ value: Uint<128>,
861
+ ): Boolean {
862
+ Pausable_assertNotPaused();
863
+ return FungibleToken_transfer(to, value);
864
+ }
865
+
866
+ // Owner-only mint
867
+ export circuit mint(
868
+ to: Either<ZswapCoinPublicKey, ContractAddress>,
869
+ amount: Uint<128>,
870
+ ): [] {
871
+ Ownable_assertOnlyOwner();
872
+ Pausable_assertNotPaused();
873
+ FungibleToken__mint(to, amount);
874
+ }
875
+
876
+ // Emergency pause
877
+ export circuit pause(): [] {
878
+ Ownable_assertOnlyOwner();
879
+ Pausable__pause();
880
+ }
881
+
882
+ export circuit unpause(): [] {
883
+ Ownable_assertOnlyOwner();
884
+ Pausable__unpause();
885
+ }
886
+ \`\`\`
887
+
888
+ ## Best Practices
889
+
890
+ 1. **Always use Pausable** for contracts handling value
891
+ 2. **Combine with Ownable** for admin-only pause control
892
+ 3. **Test pause scenarios** thoroughly
893
+ 4. **Document pause conditions** for users
894
+ 5. **Consider timelock** for unpause in high-value contracts
895
+ `,
896
+ "midnight://docs/tokenomics": `# Midnight Tokenomics and Incentives Whitepaper
897
+
898
+ ## Overview
899
+
900
+ Midnight introduces a novel dual-component tokenomics system with NIGHT (utility token) and DUST (transaction resource), designed for operational predictability, privacy, and cross-chain cooperation.
901
+
902
+ ## Core Pillars
903
+
904
+ 1. **Operational Predictability**: NIGHT generates DUST continuously, enabling transactions without direct token expenditure
905
+ 2. **Rational Privacy**: DUST is shielded - transactions don't leave metadata trails
906
+ 3. **Cooperative Tokenomics**: Multi-chain architecture enables cross-chain value creation
907
+ 4. **Fair Distribution**: Free, multi-phase token distribution (Glacier Drop)
908
+
909
+ ---
910
+
911
+ ## The NIGHT Token
912
+
913
+ NIGHT is Midnight's native utility token. One NIGHT = 1,000,000 STARs.
914
+
915
+ ### Key Properties
916
+
917
+ - **Unshielded**: NIGHT transactions are publicly visible on-chain
918
+ - **Transferable**: Can be freely transferred, listed on exchanges, bridged across networks
919
+ - **Total Supply**: 24 billion NIGHT tokens
920
+ - **Non-expendable**: Not consumed to execute transactions
921
+ - **Disinflationary**: Circulating supply expansion slows over time
922
+ - **Multi-chain Native**: Exists natively on both Cardano (as Native Asset) and Midnight
923
+
924
+ ### Stakeholders
925
+
926
+ - **NIGHT Token Holders**: Control future network governance
927
+ - **Midnight Block Producers (MBPs)**: Validate blocks, receive rewards
928
+ - **Midnight Foundation**: Long-term ecosystem development
929
+ - **On-chain Treasury**: Protocol-managed fund for ecosystem growth
930
+ - **Reserve**: Protocol-managed pool for block production rewards
931
+
932
+ ### Cross-Chain Token States
933
+
934
+ Tokens can be:
935
+ - **Protocol-locked**: Cannot move or generate DUST
936
+ - **Protocol-unlocked**: Full utility and transferability
937
+
938
+ Key invariant: A token unlocked on one chain is locked on the other, ensuring effective supply never exceeds 24 billion.
939
+
940
+ ### Cross-Chain Invariants
941
+
942
+ \`\`\`
943
+ C.R + C.L + C.U = M.R + M.L + M.U = S (24 billion)
944
+
945
+ Where:
946
+ - C = Cardano, M = Midnight
947
+ - R = Reserve, L = Locked, U = Unlocked
948
+ - S = Total Supply
949
+ \`\`\`
950
+
951
+ ---
952
+
953
+ ## The DUST Resource
954
+
955
+ DUST is the shielded, renewable resource for transaction fees.
956
+
957
+ ### Key Properties
958
+
959
+ - **Shielded**: Transactions don't expose wallet addresses or details
960
+ - **Consumable**: Burned when used (not recycled)
961
+ - **Renewable**: Continuously generated by NIGHT holdings
962
+ - **Decaying**: Balance decays when disassociated from generating NIGHT
963
+ - **Non-transferable**: Cannot be bought, sold, or transferred between addresses
964
+ - **MEV-resistant**: Shielding prevents attackers from identifying victims
965
+
966
+ ### DUST Mechanics
967
+
968
+ **Generation**:
969
+ 1. NIGHT holder designates a DUST recipient address
970
+ 2. DUST accumulates linearly over time up to a cap
971
+ 3. Cap is proportional to associated NIGHT balance
972
+
973
+ **DUST Cap**: Maximum DUST = f(associated NIGHT balance)
974
+
975
+ **Usage**:
976
+ - DUST is consumed/burned when used
977
+ - No DUST is collected by block producers
978
+ - Generation resumes after use if below cap
979
+
980
+ **Decay**:
981
+ - Severing NIGHT association causes linear decay
982
+ - Prevents double-spending through cap enforcement
983
+
984
+ ### DUST Beneficiaries
985
+
986
+ 1. **NIGHT Holders**: Generate and use their own DUST
987
+ 2. **DUST Recipients**: Receive DUST generation from NIGHT holders
988
+ 3. **DUST Sponsees**: Transactions paid by a DUST holder (enables tokenless UX)
989
+
990
+ ---
991
+
992
+ ## Transaction Fees
993
+
994
+ ### Components
995
+
996
+ \`\`\`
997
+ TxFee = CongestionRate × TxWeight + MinFee
998
+ \`\`\`
999
+
1000
+ - **Minimum Fee**: Fixed fee preventing DDoS attacks
1001
+ - **Congestion Rate**: Dynamic multiplier based on network demand
1002
+ - **Transaction Weight**: Based on computational resources (initially storage in KB)
1003
+
1004
+ ### Block Utilization Target: 50%
1005
+
1006
+ - Below 50%: Fees decrease to stimulate activity
1007
+ - Above 50%: Fees increase to manage congestion
1008
+ - Acts as automatic stabilizer for network efficiency
1009
+
1010
+ ---
1011
+
1012
+ ## Block Production & Rewards
1013
+
1014
+ ### At Launch
1015
+
1016
+ - Federated block production by trusted permissioned nodes
1017
+ - Initial producers don't receive rewards
1018
+ - Progressive decentralization planned
1019
+
1020
+ ### Moving to Permissionless
1021
+
1022
+ - Cardano SPOs can become Midnight Block Producers
1023
+ - Selection proportional to delegated ADA stake
1024
+ - Dual-network participation doesn't affect Cardano rewards
1025
+
1026
+ ### Block Reward Formula
1027
+
1028
+ **Base Distribution Rate (R)**:
1029
+ \`\`\`
1030
+ R = π(1 - B - T) / (B × γ)
1031
+
1032
+ Where:
1033
+ - π = Initial annual inflation rate (~3.14%)
1034
+ - B = Reserve allocation percentage
1035
+ - T = Treasury allocation percentage
1036
+ - γ = Blocks per year
1037
+ \`\`\`
1038
+
1039
+ **Base Reward**:
1040
+ \`\`\`
1041
+ Nb = Bo × R
1042
+
1043
+ Where Bo = Outstanding tokens in Reserve
1044
+ \`\`\`
1045
+
1046
+ ### Reward Split
1047
+
1048
+ Rewards divided between block producer and Treasury based on block utilization:
1049
+
1050
+ \`\`\`
1051
+ Actual Reward (Na) = Nb × [S + (1 - S) × U]
1052
+ Treasury Share (Nt) = Nb - Na
1053
+
1054
+ Where:
1055
+ - S = Subsidy rate (95% at launch)
1056
+ - U = Block utilization ratio
1057
+ \`\`\`
1058
+
1059
+ - **Full block**: Producer gets 100% of base reward
1060
+ - **Empty block**: Producer gets only the subsidy (95%)
1061
+ - **Partially full**: Linear interpolation between them
1062
+
1063
+ ---
1064
+
1065
+ ## Token Distribution
1066
+
1067
+ ### Design Principles
1068
+
1069
+ - **Broad**: No single party dominates
1070
+ - **Inclusive**: Open to participants beyond crypto
1071
+ - **Free**: Allocated at no cost
1072
+ - **Transparent**: Open-source audited smart contracts
1073
+
1074
+ ### Phase 1: Glacier Drop (60 days)
1075
+
1076
+ **Eligible Networks**:
1077
+ - Cardano (50% allocation)
1078
+ - Bitcoin (20% allocation)
1079
+ - Ethereum, Solana, XRPL, BNB Chain, Avalanche, Brave (remaining 30%, proportional)
1080
+
1081
+ **Eligibility**:
1082
+ - Minimum $100 USD equivalent in native tokens at snapshot
1083
+ - Address not on OFAC sanctions list
1084
+ - Random historical snapshot to prevent gaming
1085
+
1086
+ **Mechanics**:
1087
+ 1. Sign message proving address ownership
1088
+ 2. Provide unused Cardano address for redemption
1089
+ 3. Tokens initially frozen, thaw during redemption period
1090
+
1091
+ ### Phase 2: Scavenger Mine (30 days)
1092
+
1093
+ - Process unclaimed Glacier Drop tokens
1094
+ - Computational puzzles accessible to general public
1095
+ - Daily allocation over 30 one-day slots
1096
+
1097
+ **Apportionment of Unclaimed Tokens**:
1098
+ - ~35% → Midnight Foundation
1099
+ - ~30% → Reserve (block rewards)
1100
+ - ~10% → Midnight TGE (partnerships/liquidity)
1101
+ - ~5% → On-chain Treasury
1102
+ - Rest → Scavenger Mine participants + Lost-and-Found
1103
+
1104
+ ### Phase 3: Lost-and-Found (4 years)
1105
+
1106
+ - Second chance for eligible non-claimers from Glacier Drop
1107
+ - Fractional allocation of original entitlement
1108
+ - After 4 years, unclaimed tokens go to Treasury
1109
+
1110
+ ### Redemption Period (450 days)
1111
+
1112
+ **Thawing Schedule**:
1113
+ - Random start day (1-90 days after genesis)
1114
+ - 25% unlock at start, then every 90 days
1115
+ - Total: 4 unlocks over 360 days
1116
+
1117
+ ---
1118
+
1119
+ ## Cooperative Tokenomics
1120
+
1121
+ ### Capacity Marketplace
1122
+
1123
+ Enables non-NIGHT holders to access Midnight:
1124
+
1125
+ **Off-chain Models**:
1126
+ - DUST generation leasing
1127
+ - Broker-managed leasing
1128
+ - Babel Station (DUST filling station using ZSwap)
1129
+
1130
+ **On-chain Models** (future):
1131
+ - Ledger-native capacity leasing
1132
+ - On-chain capacity exchange
1133
+
1134
+ ### Multi-chain Features
1135
+
1136
+ **Cross-chain Observability**: Actions on one chain trigger agents on another
1137
+
1138
+ **Multichain Signatures**: Treasury can receive fees in other tokens
1139
+
1140
+ ---
1141
+
1142
+ ## Governance
1143
+
1144
+ ### At Launch: Federated
1145
+
1146
+ - Select committee with equal powers
1147
+ - Multisig mechanism for protocol updates
1148
+ - Handles: parameter updates, protocol upgrades, hard forks
1149
+
1150
+ ### Future: Decentralized On-chain
1151
+
1152
+ - Community-centric tools and processes
1153
+ - Proposal submission and voting
1154
+ - Treasury access for approved proposals
1155
+ - Automated protocol updates
1156
+
1157
+ ---
1158
+
1159
+ ## Glossary
1160
+
1161
+ - **NIGHT**: Midnight's native utility token
1162
+ - **STAR**: Smallest subunit of NIGHT (1 NIGHT = 1M STARs)
1163
+ - **DUST**: Shielded transaction resource
1164
+ - **MBP**: Midnight Block Producer
1165
+ - **Reserve**: Protocol-managed token pool for block rewards
1166
+ - **Treasury**: Protocol-managed fund for ecosystem growth
1167
+ - **Glacier Drop**: Initial free token distribution
1168
+ - **Scavenger Mine**: Computational task-based distribution
1169
+ - **ZSwap**: Atomic asset swap mechanism for privacy
1170
+ - **Babel Station**: Service enabling tokenless transactions
1171
+ `,
1172
+ };
1173
+ //# sourceMappingURL=docs-content.js.map