midnight-mcp 0.1.0 → 0.1.2

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,897 @@
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
+ };
897
+ //# sourceMappingURL=docs-content.js.map