midnight-mcp 0.1.41 → 0.2.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.
- package/README.md +32 -1
- package/dist/bin.d.ts +1 -0
- package/dist/bin.js +60 -0
- package/dist/chunk-HOWO4K5A.js +2197 -0
- package/dist/chunk-S7G4OHA4.js +8306 -0
- package/dist/db-YDGUWI5K.js +7 -0
- package/dist/index.d.ts +205 -3
- package/dist/index.js +28 -16
- package/package.json +16 -6
- package/dist/config/compact-version.d.ts +0 -183
- package/dist/config/compact-version.js +0 -423
- package/dist/db/index.d.ts +0 -3
- package/dist/db/index.js +0 -2
- package/dist/db/vectorStore.d.ts +0 -69
- package/dist/db/vectorStore.js +0 -196
- package/dist/pipeline/embeddings.d.ts +0 -25
- package/dist/pipeline/embeddings.js +0 -103
- package/dist/pipeline/github.d.ts +0 -84
- package/dist/pipeline/github.js +0 -399
- package/dist/pipeline/index.d.ts +0 -11
- package/dist/pipeline/index.js +0 -6
- package/dist/pipeline/indexer.d.ts +0 -41
- package/dist/pipeline/indexer.js +0 -254
- package/dist/pipeline/parser.d.ts +0 -46
- package/dist/pipeline/parser.js +0 -436
- package/dist/pipeline/releases.d.ts +0 -112
- package/dist/pipeline/releases.js +0 -298
- package/dist/pipeline/repository.d.ts +0 -372
- package/dist/pipeline/repository.js +0 -520
- package/dist/prompts/index.d.ts +0 -3
- package/dist/prompts/index.js +0 -2
- package/dist/prompts/templates.d.ts +0 -26
- package/dist/prompts/templates.js +0 -443
- package/dist/resources/code.d.ts +0 -15
- package/dist/resources/code.js +0 -122
- package/dist/resources/content/code-content.d.ts +0 -6
- package/dist/resources/content/code-content.js +0 -802
- package/dist/resources/content/docs-content.d.ts +0 -14
- package/dist/resources/content/docs-content.js +0 -1202
- package/dist/resources/content/index.d.ts +0 -6
- package/dist/resources/content/index.js +0 -6
- package/dist/resources/docs.d.ts +0 -15
- package/dist/resources/docs.js +0 -98
- package/dist/resources/index.d.ts +0 -6
- package/dist/resources/index.js +0 -13
- package/dist/resources/schemas.d.ts +0 -16
- package/dist/resources/schemas.js +0 -407
- package/dist/scripts/index-repos.d.ts +0 -12
- package/dist/scripts/index-repos.js +0 -53
- package/dist/server.d.ts +0 -43
- package/dist/server.js +0 -696
- package/dist/services/index.d.ts +0 -6
- package/dist/services/index.js +0 -6
- package/dist/services/sampling.d.ts +0 -62
- package/dist/services/sampling.js +0 -277
- package/dist/tools/analyze.d.ts +0 -106
- package/dist/tools/analyze.js +0 -431
- package/dist/tools/generation.d.ts +0 -9
- package/dist/tools/generation.js +0 -285
- package/dist/tools/health.d.ts +0 -120
- package/dist/tools/health.js +0 -365
- package/dist/tools/index.d.ts +0 -14
- package/dist/tools/index.js +0 -22
- package/dist/tools/meta.d.ts +0 -61
- package/dist/tools/meta.js +0 -282
- package/dist/tools/repository/constants.d.ts +0 -19
- package/dist/tools/repository/constants.js +0 -324
- package/dist/tools/repository/handlers.d.ts +0 -373
- package/dist/tools/repository/handlers.js +0 -724
- package/dist/tools/repository/index.d.ts +0 -9
- package/dist/tools/repository/index.js +0 -13
- package/dist/tools/repository/schemas.d.ts +0 -153
- package/dist/tools/repository/schemas.js +0 -106
- package/dist/tools/repository/tools.d.ts +0 -7
- package/dist/tools/repository/tools.js +0 -484
- package/dist/tools/repository/validation.d.ts +0 -106
- package/dist/tools/repository/validation.js +0 -820
- package/dist/tools/repository.d.ts +0 -6
- package/dist/tools/repository.js +0 -7
- package/dist/tools/search.d.ts +0 -76
- package/dist/tools/search.js +0 -423
- package/dist/types/index.d.ts +0 -2
- package/dist/types/index.js +0 -2
- package/dist/types/mcp.d.ts +0 -187
- package/dist/types/mcp.js +0 -6
- package/dist/utils/cache.d.ts +0 -77
- package/dist/utils/cache.js +0 -172
- package/dist/utils/config.d.ts +0 -70
- package/dist/utils/config.js +0 -294
- package/dist/utils/errors.d.ts +0 -111
- package/dist/utils/errors.js +0 -165
- package/dist/utils/health.d.ts +0 -29
- package/dist/utils/health.js +0 -132
- package/dist/utils/hosted-api.d.ts +0 -67
- package/dist/utils/hosted-api.js +0 -119
- package/dist/utils/index.d.ts +0 -16
- package/dist/utils/index.js +0 -15
- package/dist/utils/logger.d.ts +0 -48
- package/dist/utils/logger.js +0 -124
- package/dist/utils/rate-limit.d.ts +0 -61
- package/dist/utils/rate-limit.js +0 -148
- package/dist/utils/validation.d.ts +0 -52
- package/dist/utils/validation.js +0 -255
|
@@ -1,1202 +0,0 @@
|
|
|
1
|
-
/**
|
|
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.
|
|
12
|
-
*/
|
|
13
|
-
export const EMBEDDED_DOCS = {
|
|
14
|
-
"midnight://docs/compact-reference": `# Compact Language Syntax Reference (v0.16 - v0.18)
|
|
15
|
-
|
|
16
|
-
> **CRITICAL**: This reference is derived from **actual compiling contracts** in the Midnight ecosystem.
|
|
17
|
-
> Always verify syntax against this reference before generating contracts.
|
|
18
|
-
|
|
19
|
-
## Quick Start Template
|
|
20
|
-
|
|
21
|
-
Use this as a starting point - it compiles successfully:
|
|
22
|
-
|
|
23
|
-
\`\`\`compact
|
|
24
|
-
pragma language_version >= 0.16 && <= 0.18;
|
|
25
|
-
|
|
26
|
-
import CompactStandardLibrary;
|
|
27
|
-
|
|
28
|
-
// Ledger state (individual declarations, NOT a block)
|
|
29
|
-
export ledger counter: Counter;
|
|
30
|
-
export ledger owner: Bytes<32>;
|
|
31
|
-
|
|
32
|
-
// Witness for private/off-chain data
|
|
33
|
-
witness local_secret_key(): Bytes<32>;
|
|
34
|
-
|
|
35
|
-
// Circuit (returns [] not Void)
|
|
36
|
-
export circuit increment(): [] {
|
|
37
|
-
counter.increment(1);
|
|
38
|
-
}
|
|
39
|
-
\`\`\`
|
|
40
|
-
|
|
41
|
-
---
|
|
42
|
-
|
|
43
|
-
## 1. Pragma (Version Declaration)
|
|
44
|
-
|
|
45
|
-
**CORRECT** - use bounded range without patch version:
|
|
46
|
-
\`\`\`compact
|
|
47
|
-
pragma language_version >= 0.16 && <= 0.18;
|
|
48
|
-
\`\`\`
|
|
49
|
-
|
|
50
|
-
**WRONG** - these will cause parse errors:
|
|
51
|
-
\`\`\`compact
|
|
52
|
-
pragma language_version >= 0.14.0; // ❌ patch version not needed
|
|
53
|
-
pragma language_version >= 0.16.0 < 0.19.0; // ❌ wrong operator format
|
|
54
|
-
\`\`\`
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
## 2. Imports
|
|
59
|
-
|
|
60
|
-
Always import the standard library:
|
|
61
|
-
\`\`\`compact
|
|
62
|
-
import CompactStandardLibrary;
|
|
63
|
-
\`\`\`
|
|
64
|
-
|
|
65
|
-
For multi-file contracts, use \`include\`:
|
|
66
|
-
\`\`\`compact
|
|
67
|
-
include "types";
|
|
68
|
-
include "ledger";
|
|
69
|
-
include "circuits";
|
|
70
|
-
\`\`\`
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
## 3. Ledger Declarations
|
|
75
|
-
|
|
76
|
-
**CORRECT** - individual declarations with \`export ledger\`:
|
|
77
|
-
\`\`\`compact
|
|
78
|
-
export ledger counter: Counter;
|
|
79
|
-
export ledger owner: Bytes<32>;
|
|
80
|
-
export ledger balances: Map<Bytes<32>, Uint<64>>;
|
|
81
|
-
|
|
82
|
-
// Private state (off-chain only)
|
|
83
|
-
ledger secretValue: Field; // no export = private
|
|
84
|
-
\`\`\`
|
|
85
|
-
|
|
86
|
-
**WRONG** - block syntax is deprecated:
|
|
87
|
-
\`\`\`compact
|
|
88
|
-
// ❌ This causes parse error: found "{" looking for an identifier
|
|
89
|
-
ledger {
|
|
90
|
-
counter: Counter;
|
|
91
|
-
owner: Bytes<32>;
|
|
92
|
-
}
|
|
93
|
-
\`\`\`
|
|
94
|
-
|
|
95
|
-
### Ledger Modifiers
|
|
96
|
-
|
|
97
|
-
\`\`\`compact
|
|
98
|
-
export ledger publicData: Field; // Public, readable by anyone
|
|
99
|
-
export sealed ledger immutableData: Field; // Set once in constructor, cannot change
|
|
100
|
-
ledger privateData: Field; // Private, not exported
|
|
101
|
-
\`\`\`
|
|
102
|
-
|
|
103
|
-
---
|
|
104
|
-
|
|
105
|
-
## 4. Data Types
|
|
106
|
-
|
|
107
|
-
### Primitive Types
|
|
108
|
-
| Type | Description | Example |
|
|
109
|
-
|------|-------------|---------|
|
|
110
|
-
| \`Field\` | Finite field element (basic numeric) | \`amount: Field\` |
|
|
111
|
-
| \`Boolean\` | True or false | \`isActive: Boolean\` |
|
|
112
|
-
| \`Bytes<N>\` | Fixed-size byte array | \`hash: Bytes<32>\` |
|
|
113
|
-
| \`Uint<N>\` | Unsigned integer (N = 8, 16, 32, 64, 128, 256) | \`balance: Uint<64>\` |
|
|
114
|
-
| \`Uint<MIN..MAX>\` | Bounded unsigned integer | \`score: Uint<0..100>\` |
|
|
115
|
-
|
|
116
|
-
### Collection Types
|
|
117
|
-
| Type | Description | Example |
|
|
118
|
-
|------|-------------|---------|
|
|
119
|
-
| \`Counter\` | Incrementable/decrementable | \`count: Counter\` |
|
|
120
|
-
| \`Map<K, V>\` | Key-value mapping | \`Map<Bytes<32>, Uint<64>>\` |
|
|
121
|
-
| \`Set<T>\` | Unique value collection | \`Set<Bytes<32>>\` |
|
|
122
|
-
| \`Vector<N, T>\` | Fixed-size array | \`Vector<3, Field>\` |
|
|
123
|
-
| \`List<T>\` | Dynamic list | \`List<Bytes<32>>\` |
|
|
124
|
-
| \`Maybe<T>\` | Optional value | \`Maybe<Bytes<32>>\` |
|
|
125
|
-
| \`Either<L, R>\` | Union type | \`Either<Field, Bytes<32>>\` |
|
|
126
|
-
| \`Opaque<"type">\` | External type from TypeScript | \`Opaque<"string">\` |
|
|
127
|
-
|
|
128
|
-
### Custom Types
|
|
129
|
-
|
|
130
|
-
**Enums** - must use \`export\` to access from TypeScript:
|
|
131
|
-
\`\`\`compact
|
|
132
|
-
export enum GameState { waiting, playing, finished }
|
|
133
|
-
export enum Choice { rock, paper, scissors }
|
|
134
|
-
\`\`\`
|
|
135
|
-
|
|
136
|
-
**Enum Access Syntax** - use DOT notation (not Rust-style ::):
|
|
137
|
-
\`\`\`compact
|
|
138
|
-
// CORRECT - dot notation
|
|
139
|
-
if (choice == Choice.rock) { ... }
|
|
140
|
-
game_state = GameState.waiting;
|
|
141
|
-
|
|
142
|
-
// WRONG - Rust-style double colon
|
|
143
|
-
if (choice == Choice::rock) { ... } // ❌ Parse error: found ":" looking for ")"
|
|
144
|
-
\`\`\`
|
|
145
|
-
|
|
146
|
-
**Structs**:
|
|
147
|
-
\`\`\`compact
|
|
148
|
-
export struct PlayerConfig {
|
|
149
|
-
name: Opaque<"string">,
|
|
150
|
-
score: Uint<32>,
|
|
151
|
-
isActive: Boolean,
|
|
152
|
-
}
|
|
153
|
-
\`\`\`
|
|
154
|
-
|
|
155
|
-
---
|
|
156
|
-
|
|
157
|
-
## 5. Circuits
|
|
158
|
-
|
|
159
|
-
Circuits are on-chain functions that generate ZK proofs.
|
|
160
|
-
|
|
161
|
-
**CRITICAL**: Return type is \`[]\` (empty tuple), NOT \`Void\`:
|
|
162
|
-
|
|
163
|
-
\`\`\`compact
|
|
164
|
-
// CORRECT - returns []
|
|
165
|
-
export circuit increment(): [] {
|
|
166
|
-
counter.increment(1);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// CORRECT - with parameters
|
|
170
|
-
export circuit transfer(to: Bytes<32>, amount: Uint<64>): [] {
|
|
171
|
-
assert(amount > 0, "Amount must be positive");
|
|
172
|
-
// ... logic
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// CORRECT - with return value
|
|
176
|
-
export circuit getBalance(addr: Bytes<32>): Uint<64> {
|
|
177
|
-
return balances.lookup(addr);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// WRONG - Void does not exist
|
|
181
|
-
export circuit broken(): Void { // ❌ Parse error
|
|
182
|
-
counter.increment(1);
|
|
183
|
-
}
|
|
184
|
-
\`\`\`
|
|
185
|
-
|
|
186
|
-
### Circuit Modifiers
|
|
187
|
-
|
|
188
|
-
\`\`\`compact
|
|
189
|
-
export circuit publicFn(): [] // Callable externally
|
|
190
|
-
circuit internalFn(): [] // Internal only, not exported
|
|
191
|
-
export pure circuit hash(x: Field): Bytes<32> // No state access
|
|
192
|
-
\`\`\`
|
|
193
|
-
|
|
194
|
-
---
|
|
195
|
-
|
|
196
|
-
## 6. Witnesses
|
|
197
|
-
|
|
198
|
-
Witnesses provide off-chain/private data to circuits. They run locally, not on-chain.
|
|
199
|
-
|
|
200
|
-
**CRITICAL**: Witnesses are declarations only - NO implementation body in Compact!
|
|
201
|
-
The implementation goes in your TypeScript prover.
|
|
202
|
-
|
|
203
|
-
\`\`\`compact
|
|
204
|
-
// ✅ CORRECT - declaration only, semicolon at end
|
|
205
|
-
witness local_secret_key(): Bytes<32>;
|
|
206
|
-
witness get_merkle_path(leaf: Bytes<32>): MerkleTreePath<10, Bytes<32>>;
|
|
207
|
-
witness store_locally(data: Field): [];
|
|
208
|
-
witness find_user(id: Bytes<32>): Maybe<UserData>;
|
|
209
|
-
|
|
210
|
-
// ❌ WRONG - witnesses cannot have bodies
|
|
211
|
-
witness get_caller(): Bytes<32> {
|
|
212
|
-
return public_key(local_secret_key()); // ERROR!
|
|
213
|
-
}
|
|
214
|
-
\`\`\`
|
|
215
|
-
|
|
216
|
-
---
|
|
217
|
-
|
|
218
|
-
## 7. Constructor
|
|
219
|
-
|
|
220
|
-
Optional - initializes sealed ledger fields at deploy time:
|
|
221
|
-
|
|
222
|
-
\`\`\`compact
|
|
223
|
-
export sealed ledger owner: Bytes<32>;
|
|
224
|
-
export sealed ledger nonce: Bytes<32>;
|
|
225
|
-
|
|
226
|
-
constructor(initNonce: Bytes<32>) {
|
|
227
|
-
owner = disclose(public_key(local_secret_key()));
|
|
228
|
-
nonce = disclose(initNonce);
|
|
229
|
-
}
|
|
230
|
-
\`\`\`
|
|
231
|
-
|
|
232
|
-
---
|
|
233
|
-
|
|
234
|
-
## 7.5 Pure Circuits (Helper Functions)
|
|
235
|
-
|
|
236
|
-
Use \`pure circuit\` for helper functions that don't modify ledger state:
|
|
237
|
-
|
|
238
|
-
\`\`\`compact
|
|
239
|
-
// ✅ CORRECT - use "pure circuit"
|
|
240
|
-
pure circuit determine_winner(p1: Choice, p2: Choice): Result {
|
|
241
|
-
if (p1 == p2) {
|
|
242
|
-
return Result.draw;
|
|
243
|
-
}
|
|
244
|
-
// ... logic
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// ❌ WRONG - "function" keyword doesn't exist
|
|
248
|
-
pure function determine_winner(p1: Choice, p2: Choice): Result {
|
|
249
|
-
// ERROR: unbound identifier "function"
|
|
250
|
-
}
|
|
251
|
-
\`\`\`
|
|
252
|
-
|
|
253
|
-
---
|
|
254
|
-
|
|
255
|
-
## 8. Common Patterns
|
|
256
|
-
|
|
257
|
-
### Authentication Pattern
|
|
258
|
-
\`\`\`compact
|
|
259
|
-
witness local_secret_key(): Bytes<32>;
|
|
260
|
-
|
|
261
|
-
// IMPORTANT: public_key() is NOT a builtin - use this pattern
|
|
262
|
-
circuit get_public_key(sk: Bytes<32>): Bytes<32> {
|
|
263
|
-
return persistentHash<Vector<2, Bytes<32>>>([pad(32, "myapp:pk:"), sk]);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
export circuit authenticated_action(): [] {
|
|
267
|
-
const sk = local_secret_key();
|
|
268
|
-
const caller = get_public_key(sk);
|
|
269
|
-
assert(disclose(caller == owner), "Not authorized");
|
|
270
|
-
// ... action
|
|
271
|
-
}
|
|
272
|
-
\`\`\`
|
|
273
|
-
|
|
274
|
-
### Commit-Reveal Pattern (COMPLETE, VALIDATED)
|
|
275
|
-
\`\`\`compact
|
|
276
|
-
pragma language_version >= 0.16 && <= 0.18;
|
|
277
|
-
|
|
278
|
-
import CompactStandardLibrary;
|
|
279
|
-
|
|
280
|
-
// Ledger state
|
|
281
|
-
export ledger commitment: Bytes<32>;
|
|
282
|
-
export ledger revealed_value: Field;
|
|
283
|
-
export ledger is_revealed: Boolean;
|
|
284
|
-
|
|
285
|
-
// Witnesses for off-chain storage
|
|
286
|
-
witness local_secret_key(): Bytes<32>;
|
|
287
|
-
witness store_secret_value(v: Field): [];
|
|
288
|
-
witness get_secret_value(): Field;
|
|
289
|
-
|
|
290
|
-
// Helper: compute commitment hash
|
|
291
|
-
circuit compute_commitment(value: Field, salt: Bytes<32>): Bytes<32> {
|
|
292
|
-
// Convert Field to Bytes for hashing
|
|
293
|
-
const value_bytes = value as Bytes<32>;
|
|
294
|
-
return persistentHash<Vector<2, Bytes<32>>>([value_bytes, salt]);
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Commit phase: store hash on-chain, value off-chain
|
|
298
|
-
export circuit commit(value: Field): [] {
|
|
299
|
-
const salt = local_secret_key();
|
|
300
|
-
store_secret_value(value);
|
|
301
|
-
commitment = disclose(compute_commitment(value, salt));
|
|
302
|
-
is_revealed = false;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// Reveal phase: verify stored value matches commitment
|
|
306
|
-
export circuit reveal(): Field {
|
|
307
|
-
const salt = local_secret_key();
|
|
308
|
-
const value = get_secret_value();
|
|
309
|
-
const expected = compute_commitment(value, salt);
|
|
310
|
-
assert(disclose(expected == commitment), "Value doesn't match commitment");
|
|
311
|
-
assert(disclose(!is_revealed), "Already revealed");
|
|
312
|
-
|
|
313
|
-
revealed_value = disclose(value);
|
|
314
|
-
is_revealed = true;
|
|
315
|
-
return disclose(value);
|
|
316
|
-
}
|
|
317
|
-
\`\`\`
|
|
318
|
-
|
|
319
|
-
### Disclosure in Conditionals
|
|
320
|
-
When branching on witness values, wrap comparisons in \`disclose()\`:
|
|
321
|
-
|
|
322
|
-
\`\`\`compact
|
|
323
|
-
// CORRECT
|
|
324
|
-
export circuit check(guess: Field): Boolean {
|
|
325
|
-
const secret = get_secret(); // witness
|
|
326
|
-
if (disclose(guess == secret)) {
|
|
327
|
-
return true;
|
|
328
|
-
}
|
|
329
|
-
return false;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
// WRONG - will not compile
|
|
333
|
-
export circuit check_broken(guess: Field): Boolean {
|
|
334
|
-
const secret = get_secret();
|
|
335
|
-
if (guess == secret) { // ❌ implicit disclosure error
|
|
336
|
-
return true;
|
|
337
|
-
}
|
|
338
|
-
return false;
|
|
339
|
-
}
|
|
340
|
-
\`\`\`
|
|
341
|
-
|
|
342
|
-
---
|
|
343
|
-
|
|
344
|
-
## 9. Common Operations
|
|
345
|
-
|
|
346
|
-
### Counter Operations
|
|
347
|
-
\`\`\`compact
|
|
348
|
-
// These work in circuits:
|
|
349
|
-
counter.increment(1);
|
|
350
|
-
counter.decrement(1);
|
|
351
|
-
counter.resetToDefault();
|
|
352
|
-
|
|
353
|
-
// ⚠️ DOES NOT WORK IN CIRCUITS:
|
|
354
|
-
// const val = counter.value(); // ERROR: operation undefined
|
|
355
|
-
// Instead, read counter value in TypeScript SDK: ledgerState.counter
|
|
356
|
-
\`\`\`
|
|
357
|
-
|
|
358
|
-
### Map Operations
|
|
359
|
-
\`\`\`compact
|
|
360
|
-
// These work in circuits:
|
|
361
|
-
balances.insert(address, 100);
|
|
362
|
-
balances.remove(address);
|
|
363
|
-
|
|
364
|
-
// ⚠️ DOES NOT WORK IN CIRCUITS:
|
|
365
|
-
// const balance = balances.lookup(address); // ERROR
|
|
366
|
-
// const exists = balances.member(address); // ERROR
|
|
367
|
-
// Instead, use witnesses to read values:
|
|
368
|
-
witness get_balance(addr: Bytes<32>): Uint<64>;
|
|
369
|
-
\`\`\`
|
|
370
|
-
|
|
371
|
-
### Set Operations
|
|
372
|
-
\`\`\`compact
|
|
373
|
-
// These work in circuits:
|
|
374
|
-
members.insert(address);
|
|
375
|
-
members.remove(address);
|
|
376
|
-
|
|
377
|
-
// ⚠️ DOES NOT WORK IN CIRCUITS:
|
|
378
|
-
// const isMember = members.member(address); // ERROR
|
|
379
|
-
// Use witness instead:
|
|
380
|
-
witness is_member(addr: Bytes<32>): Boolean;
|
|
381
|
-
\`\`\`
|
|
382
|
-
|
|
383
|
-
### Maybe Operations
|
|
384
|
-
\`\`\`compact
|
|
385
|
-
const opt: Maybe<Field> = some<Field>(42);
|
|
386
|
-
const empty: Maybe<Field> = none<Field>();
|
|
387
|
-
|
|
388
|
-
if (opt.is_some) {
|
|
389
|
-
const val = opt.value;
|
|
390
|
-
}
|
|
391
|
-
\`\`\`
|
|
392
|
-
|
|
393
|
-
### Type Casting
|
|
394
|
-
\`\`\`compact
|
|
395
|
-
const bytes: Bytes<32> = myField as Bytes<32>; // Field to Bytes
|
|
396
|
-
const num: Uint<64> = myField as Uint<64>; // Field to Uint (bounds not checked!)
|
|
397
|
-
const field: Field = myUint as Field; // Uint to Field (safe)
|
|
398
|
-
\`\`\`
|
|
399
|
-
|
|
400
|
-
### Hashing
|
|
401
|
-
\`\`\`compact
|
|
402
|
-
// Persistent hash (same input = same output across calls)
|
|
403
|
-
const hash = persistentHash<Vector<2, Bytes<32>>>([data1, data2]);
|
|
404
|
-
|
|
405
|
-
// Persistent commit (hiding commitment)
|
|
406
|
-
const commit = persistentCommit<Field>(value);
|
|
407
|
-
\`\`\`
|
|
408
|
-
|
|
409
|
-
---
|
|
410
|
-
|
|
411
|
-
## 10. Assertions
|
|
412
|
-
|
|
413
|
-
\`\`\`compact
|
|
414
|
-
assert(condition, "Error message");
|
|
415
|
-
assert(amount > 0, "Amount must be positive");
|
|
416
|
-
assert(disclose(caller == owner), "Not authorized");
|
|
417
|
-
\`\`\`
|
|
418
|
-
|
|
419
|
-
---
|
|
420
|
-
|
|
421
|
-
## 11. Common Mistakes to Avoid
|
|
422
|
-
|
|
423
|
-
| Mistake | Correct |
|
|
424
|
-
|---------|---------|
|
|
425
|
-
| \`ledger { field: Type; }\` | \`export ledger field: Type;\` |
|
|
426
|
-
| \`circuit fn(): Void\` | \`circuit fn(): []\` |
|
|
427
|
-
| \`pragma >= 0.16.0\` | \`pragma >= 0.16 && <= 0.18\` |
|
|
428
|
-
| \`enum State { ... }\` | \`export enum State { ... }\` |
|
|
429
|
-
| \`if (witness_val == x)\` | \`if (disclose(witness_val == x))\` |
|
|
430
|
-
| \`Cell<Field>\` | \`Field\` (Cell is deprecated) |
|
|
431
|
-
| \`myValue.read()\` / \`.write()\` | Direct assignment: \`myValue = x\` |
|
|
432
|
-
|
|
433
|
-
---
|
|
434
|
-
|
|
435
|
-
## 12. Exports for TypeScript
|
|
436
|
-
|
|
437
|
-
To use types/values in TypeScript, they must be exported:
|
|
438
|
-
|
|
439
|
-
\`\`\`compact
|
|
440
|
-
// These are accessible from TypeScript
|
|
441
|
-
export enum GameState { waiting, playing }
|
|
442
|
-
export struct Config { value: Field }
|
|
443
|
-
export ledger counter: Counter;
|
|
444
|
-
export circuit play(): []
|
|
445
|
-
|
|
446
|
-
// Standard library re-exports (if needed in TS)
|
|
447
|
-
export { Maybe, Either, CoinInfo };
|
|
448
|
-
\`\`\`
|
|
449
|
-
|
|
450
|
-
---
|
|
451
|
-
|
|
452
|
-
## Reference Contracts
|
|
453
|
-
|
|
454
|
-
These contracts compile successfully and demonstrate correct patterns:
|
|
455
|
-
|
|
456
|
-
1. **Counter** (beginner): \`midnightntwrk/example-counter\`
|
|
457
|
-
2. **Bulletin Board** (intermediate): \`midnightntwrk/example-bboard\`
|
|
458
|
-
3. **Naval Battle Game** (advanced): \`ErickRomeroDev/naval-battle-game_v2\`
|
|
459
|
-
4. **Sea Battle** (advanced): \`bricktowers/midnight-seabattle\`
|
|
460
|
-
|
|
461
|
-
When in doubt, reference these repos for working syntax.
|
|
462
|
-
`,
|
|
463
|
-
"midnight://docs/sdk-api": `# Midnight TypeScript SDK Quick Reference
|
|
464
|
-
|
|
465
|
-
## Installation
|
|
466
|
-
|
|
467
|
-
\`\`\`bash
|
|
468
|
-
npm install @midnight-ntwrk/midnight-js-contracts
|
|
469
|
-
\`\`\`
|
|
470
|
-
|
|
471
|
-
## Core Types
|
|
472
|
-
|
|
473
|
-
### Contract Deployment
|
|
474
|
-
|
|
475
|
-
\`\`\`typescript
|
|
476
|
-
import { deployContract, ContractDeployment } from '@midnight-ntwrk/midnight-js-contracts';
|
|
477
|
-
|
|
478
|
-
const deployment: ContractDeployment = await deployContract({
|
|
479
|
-
contract: compiledContract,
|
|
480
|
-
privateState: initialPrivateState,
|
|
481
|
-
args: constructorArgs,
|
|
482
|
-
});
|
|
483
|
-
|
|
484
|
-
const { contractAddress, initialState } = deployment;
|
|
485
|
-
\`\`\`
|
|
486
|
-
|
|
487
|
-
### Contract Interaction
|
|
488
|
-
|
|
489
|
-
\`\`\`typescript
|
|
490
|
-
import { callContract } from '@midnight-ntwrk/midnight-js-contracts';
|
|
491
|
-
|
|
492
|
-
// Call a circuit
|
|
493
|
-
const result = await callContract({
|
|
494
|
-
contractAddress,
|
|
495
|
-
circuitName: 'increment',
|
|
496
|
-
args: [amount],
|
|
497
|
-
privateState: currentPrivateState,
|
|
498
|
-
});
|
|
499
|
-
|
|
500
|
-
// Result contains new state and return value
|
|
501
|
-
const { newPrivateState, returnValue, proof } = result;
|
|
502
|
-
\`\`\`
|
|
503
|
-
|
|
504
|
-
### Providers
|
|
505
|
-
|
|
506
|
-
\`\`\`typescript
|
|
507
|
-
import {
|
|
508
|
-
MidnightProvider,
|
|
509
|
-
createMidnightProvider
|
|
510
|
-
} from '@midnight-ntwrk/midnight-js-contracts';
|
|
511
|
-
|
|
512
|
-
const provider = await createMidnightProvider({
|
|
513
|
-
indexer: 'https://indexer.testnet.midnight.network',
|
|
514
|
-
node: 'https://node.testnet.midnight.network',
|
|
515
|
-
proofServer: 'https://prover.testnet.midnight.network',
|
|
516
|
-
});
|
|
517
|
-
\`\`\`
|
|
518
|
-
|
|
519
|
-
## State Management
|
|
520
|
-
|
|
521
|
-
\`\`\`typescript
|
|
522
|
-
interface ContractState<T> {
|
|
523
|
-
publicState: PublicState;
|
|
524
|
-
privateState: T;
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
// Subscribe to state changes
|
|
528
|
-
provider.subscribeToContract(contractAddress, (state) => {
|
|
529
|
-
console.log('New state:', state);
|
|
530
|
-
});
|
|
531
|
-
\`\`\`
|
|
532
|
-
|
|
533
|
-
## Transaction Building
|
|
534
|
-
|
|
535
|
-
\`\`\`typescript
|
|
536
|
-
import { buildTransaction } from '@midnight-ntwrk/midnight-js-contracts';
|
|
537
|
-
|
|
538
|
-
const tx = await buildTransaction({
|
|
539
|
-
contractAddress,
|
|
540
|
-
circuitName: 'transfer',
|
|
541
|
-
args: [recipient, amount],
|
|
542
|
-
privateState,
|
|
543
|
-
});
|
|
544
|
-
|
|
545
|
-
// Sign and submit
|
|
546
|
-
const signedTx = await wallet.signTransaction(tx);
|
|
547
|
-
const txHash = await provider.submitTransaction(signedTx);
|
|
548
|
-
\`\`\`
|
|
549
|
-
|
|
550
|
-
## Error Handling
|
|
551
|
-
|
|
552
|
-
\`\`\`typescript
|
|
553
|
-
import { MidnightError, ContractError } from '@midnight-ntwrk/midnight-js-contracts';
|
|
554
|
-
|
|
555
|
-
try {
|
|
556
|
-
await callContract({ ... });
|
|
557
|
-
} catch (error) {
|
|
558
|
-
if (error instanceof ContractError) {
|
|
559
|
-
console.error('Contract assertion failed:', error.message);
|
|
560
|
-
} else if (error instanceof MidnightError) {
|
|
561
|
-
console.error('Network error:', error.code);
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
\`\`\`
|
|
565
|
-
`,
|
|
566
|
-
"midnight://docs/openzeppelin": `# OpenZeppelin Contracts for Compact
|
|
567
|
-
|
|
568
|
-
> **Official Documentation**: https://docs.openzeppelin.com/contracts-compact
|
|
569
|
-
> **GitHub Repository**: https://github.com/OpenZeppelin/compact-contracts
|
|
570
|
-
|
|
571
|
-
The official OpenZeppelin library for Midnight smart contracts provides battle-tested, audited implementations of common patterns.
|
|
572
|
-
|
|
573
|
-
## Installation
|
|
574
|
-
|
|
575
|
-
\`\`\`bash
|
|
576
|
-
npm install @openzeppelin/compact-contracts
|
|
577
|
-
\`\`\`
|
|
578
|
-
|
|
579
|
-
## Available Modules
|
|
580
|
-
|
|
581
|
-
### Token Standards
|
|
582
|
-
- **FungibleToken** - Privacy-preserving token with shielded balances
|
|
583
|
-
- **NFT** - Non-fungible tokens with optional privacy
|
|
584
|
-
|
|
585
|
-
### Access Control
|
|
586
|
-
- **Ownable** - Single-owner access pattern
|
|
587
|
-
- **Roles** - Role-based access control
|
|
588
|
-
- **AccessControl** - Flexible permission system
|
|
589
|
-
|
|
590
|
-
### Security
|
|
591
|
-
- **Pausable** - Emergency stop mechanism
|
|
592
|
-
- **ReentrancyGuard** - Prevent reentrancy attacks
|
|
593
|
-
|
|
594
|
-
## Usage Example
|
|
595
|
-
|
|
596
|
-
\`\`\`compact
|
|
597
|
-
include "std";
|
|
598
|
-
include "@openzeppelin/compact-contracts/token/FungibleToken.compact";
|
|
599
|
-
include "@openzeppelin/compact-contracts/access/Ownable.compact";
|
|
600
|
-
|
|
601
|
-
ledger {
|
|
602
|
-
// Inherit from OpenZeppelin contracts
|
|
603
|
-
...FungibleToken.ledger;
|
|
604
|
-
...Ownable.ledger;
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
export circuit mint(to: Address, amount: Field): Void {
|
|
608
|
-
Ownable.assertOnlyOwner();
|
|
609
|
-
FungibleToken.mint(to, amount);
|
|
610
|
-
}
|
|
611
|
-
\`\`\`
|
|
612
|
-
|
|
613
|
-
## Best Practices
|
|
614
|
-
|
|
615
|
-
1. **Always use audited contracts** - Don't reinvent token standards
|
|
616
|
-
2. **Combine patterns** - Ownable + FungibleToken + Pausable
|
|
617
|
-
3. **Check for updates** - Security patches are released regularly
|
|
618
|
-
4. **Read the docs** - Each module has specific usage patterns
|
|
619
|
-
`,
|
|
620
|
-
"midnight://docs/openzeppelin/token": `# OpenZeppelin FungibleToken
|
|
621
|
-
|
|
622
|
-
The recommended standard for privacy-preserving tokens on Midnight.
|
|
623
|
-
|
|
624
|
-
## Features
|
|
625
|
-
|
|
626
|
-
- Shielded balances (private by default)
|
|
627
|
-
- Optional public balance disclosure
|
|
628
|
-
- Transfer with ZK proofs
|
|
629
|
-
- Mint/burn capabilities
|
|
630
|
-
|
|
631
|
-
## Basic Usage
|
|
632
|
-
|
|
633
|
-
\`\`\`compact
|
|
634
|
-
include "std";
|
|
635
|
-
include "@openzeppelin/compact-contracts/token/FungibleToken.compact";
|
|
636
|
-
|
|
637
|
-
ledger {
|
|
638
|
-
...FungibleToken.ledger;
|
|
639
|
-
name: Opaque<"string">;
|
|
640
|
-
symbol: Opaque<"string">;
|
|
641
|
-
decimals: Uint<8>;
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
export circuit initialize(
|
|
645
|
-
name: Opaque<"string">,
|
|
646
|
-
symbol: Opaque<"string">,
|
|
647
|
-
decimals: Uint<8>,
|
|
648
|
-
initialSupply: Field,
|
|
649
|
-
owner: Address
|
|
650
|
-
): Void {
|
|
651
|
-
ledger.name = name;
|
|
652
|
-
ledger.symbol = symbol;
|
|
653
|
-
ledger.decimals = decimals;
|
|
654
|
-
FungibleToken.mint(owner, initialSupply);
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
// Shielded transfer
|
|
658
|
-
export circuit transfer(to: Address, amount: Field): Void {
|
|
659
|
-
FungibleToken.transfer(to, amount);
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
// Check balance (private)
|
|
663
|
-
witness myBalance(): Field {
|
|
664
|
-
return FungibleToken.balanceOf(context.caller);
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
// Reveal balance publicly (optional)
|
|
668
|
-
export circuit revealBalance(): Field {
|
|
669
|
-
return disclose(myBalance());
|
|
670
|
-
}
|
|
671
|
-
\`\`\`
|
|
672
|
-
|
|
673
|
-
## Minting and Burning
|
|
674
|
-
|
|
675
|
-
\`\`\`compact
|
|
676
|
-
include "@openzeppelin/compact-contracts/access/Ownable.compact";
|
|
677
|
-
|
|
678
|
-
ledger {
|
|
679
|
-
...FungibleToken.ledger;
|
|
680
|
-
...Ownable.ledger;
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
export circuit mint(to: Address, amount: Field): Void {
|
|
684
|
-
Ownable.assertOnlyOwner();
|
|
685
|
-
FungibleToken.mint(to, amount);
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
export circuit burn(amount: Field): Void {
|
|
689
|
-
FungibleToken.burn(context.caller, amount);
|
|
690
|
-
}
|
|
691
|
-
\`\`\`
|
|
692
|
-
|
|
693
|
-
## Privacy Model
|
|
694
|
-
|
|
695
|
-
| Operation | Privacy |
|
|
696
|
-
|-----------|---------|
|
|
697
|
-
| Balance | Shielded (private) |
|
|
698
|
-
| Transfer amount | Shielded |
|
|
699
|
-
| Sender | Shielded |
|
|
700
|
-
| Recipient | Shielded |
|
|
701
|
-
| Transaction occurred | Public (proof exists) |
|
|
702
|
-
|
|
703
|
-
## Important Notes
|
|
704
|
-
|
|
705
|
-
1. **No approval mechanism** - Unlike ERC20, transfers are direct
|
|
706
|
-
2. **Balances are commitments** - Not stored as plain values
|
|
707
|
-
3. **Privacy by default** - Explicit disclosure required to reveal
|
|
708
|
-
`,
|
|
709
|
-
"midnight://docs/openzeppelin/access": `# OpenZeppelin Access Control
|
|
710
|
-
|
|
711
|
-
Patterns for controlling who can call contract functions.
|
|
712
|
-
|
|
713
|
-
## Ownable
|
|
714
|
-
|
|
715
|
-
Simple single-owner access control.
|
|
716
|
-
|
|
717
|
-
\`\`\`compact
|
|
718
|
-
include "@openzeppelin/compact-contracts/access/Ownable.compact";
|
|
719
|
-
|
|
720
|
-
ledger {
|
|
721
|
-
...Ownable.ledger;
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
export circuit initialize(owner: Address): Void {
|
|
725
|
-
Ownable.initialize(owner);
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
export circuit adminFunction(): Void {
|
|
729
|
-
Ownable.assertOnlyOwner();
|
|
730
|
-
// Only owner can execute this
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
export circuit transferOwnership(newOwner: Address): Void {
|
|
734
|
-
Ownable.assertOnlyOwner();
|
|
735
|
-
Ownable.transferOwnership(newOwner);
|
|
736
|
-
}
|
|
737
|
-
\`\`\`
|
|
738
|
-
|
|
739
|
-
## Role-Based Access Control
|
|
740
|
-
|
|
741
|
-
For more complex permission systems.
|
|
742
|
-
|
|
743
|
-
\`\`\`compact
|
|
744
|
-
include "@openzeppelin/compact-contracts/access/AccessControl.compact";
|
|
745
|
-
|
|
746
|
-
ledger {
|
|
747
|
-
...AccessControl.ledger;
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
const ADMIN_ROLE: Bytes<32> = keccak256("ADMIN_ROLE");
|
|
751
|
-
const MINTER_ROLE: Bytes<32> = keccak256("MINTER_ROLE");
|
|
752
|
-
|
|
753
|
-
export circuit initialize(admin: Address): Void {
|
|
754
|
-
AccessControl.grantRole(ADMIN_ROLE, admin);
|
|
755
|
-
AccessControl.setRoleAdmin(MINTER_ROLE, ADMIN_ROLE);
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
export circuit mint(to: Address, amount: Field): Void {
|
|
759
|
-
AccessControl.assertHasRole(MINTER_ROLE);
|
|
760
|
-
// Mint tokens
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
export circuit grantMinterRole(account: Address): Void {
|
|
764
|
-
AccessControl.assertHasRole(ADMIN_ROLE);
|
|
765
|
-
AccessControl.grantRole(MINTER_ROLE, account);
|
|
766
|
-
}
|
|
767
|
-
\`\`\`
|
|
768
|
-
|
|
769
|
-
## Combining Patterns
|
|
770
|
-
|
|
771
|
-
\`\`\`compact
|
|
772
|
-
include "@openzeppelin/compact-contracts/access/Ownable.compact";
|
|
773
|
-
include "@openzeppelin/compact-contracts/security/Pausable.compact";
|
|
774
|
-
|
|
775
|
-
ledger {
|
|
776
|
-
...Ownable.ledger;
|
|
777
|
-
...Pausable.ledger;
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
export circuit criticalFunction(): Void {
|
|
781
|
-
Ownable.assertOnlyOwner();
|
|
782
|
-
Pausable.assertNotPaused();
|
|
783
|
-
// Execute critical logic
|
|
784
|
-
}
|
|
785
|
-
|
|
786
|
-
export circuit pause(): Void {
|
|
787
|
-
Ownable.assertOnlyOwner();
|
|
788
|
-
Pausable.pause();
|
|
789
|
-
}
|
|
790
|
-
\`\`\`
|
|
791
|
-
`,
|
|
792
|
-
"midnight://docs/openzeppelin/security": `# OpenZeppelin Security Patterns
|
|
793
|
-
|
|
794
|
-
Security utilities for Compact contracts.
|
|
795
|
-
|
|
796
|
-
## Pausable
|
|
797
|
-
|
|
798
|
-
Emergency stop mechanism for contracts.
|
|
799
|
-
|
|
800
|
-
\`\`\`compact
|
|
801
|
-
include "@openzeppelin/compact-contracts/security/Pausable.compact";
|
|
802
|
-
include "@openzeppelin/compact-contracts/access/Ownable.compact";
|
|
803
|
-
|
|
804
|
-
ledger {
|
|
805
|
-
...Pausable.ledger;
|
|
806
|
-
...Ownable.ledger;
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
export circuit transfer(to: Address, amount: Field): Void {
|
|
810
|
-
Pausable.assertNotPaused();
|
|
811
|
-
// Transfer logic
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
export circuit pause(): Void {
|
|
815
|
-
Ownable.assertOnlyOwner();
|
|
816
|
-
Pausable.pause();
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
export circuit unpause(): Void {
|
|
820
|
-
Ownable.assertOnlyOwner();
|
|
821
|
-
Pausable.unpause();
|
|
822
|
-
}
|
|
823
|
-
\`\`\`
|
|
824
|
-
|
|
825
|
-
## When to Use Pausable
|
|
826
|
-
|
|
827
|
-
- Token contracts handling real value
|
|
828
|
-
- DeFi protocols with liquidity
|
|
829
|
-
- Contracts with upgrade mechanisms
|
|
830
|
-
- Any contract where bugs could cause fund loss
|
|
831
|
-
|
|
832
|
-
## Implementation Details
|
|
833
|
-
|
|
834
|
-
\`\`\`compact
|
|
835
|
-
// Pausable module internals (simplified)
|
|
836
|
-
ledger {
|
|
837
|
-
paused: Boolean;
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
circuit Pausable_assertNotPaused(): Void {
|
|
841
|
-
assert(!ledger.paused, "Contract is paused");
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
circuit Pausable_pause(): Void {
|
|
845
|
-
ledger.paused = true;
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
circuit Pausable_unpause(): Void {
|
|
849
|
-
ledger.paused = false;
|
|
850
|
-
}
|
|
851
|
-
\`\`\`
|
|
852
|
-
|
|
853
|
-
## Best Practices
|
|
854
|
-
|
|
855
|
-
1. **Always use Pausable** for contracts handling value
|
|
856
|
-
2. **Combine with Ownable** for admin-only pause control
|
|
857
|
-
3. **Test pause scenarios** thoroughly
|
|
858
|
-
4. **Document pause conditions** for users
|
|
859
|
-
5. **Consider timelock** for unpause in high-value contracts
|
|
860
|
-
`,
|
|
861
|
-
"midnight://docs/tokenomics": `# Midnight Tokenomics Summary
|
|
862
|
-
|
|
863
|
-
A curated summary of the Midnight Tokenomics Whitepaper (June 2025).
|
|
864
|
-
|
|
865
|
-
## Dual-Token Model
|
|
866
|
-
|
|
867
|
-
Midnight uses two components: **NIGHT** (token) and **DUST** (resource).
|
|
868
|
-
|
|
869
|
-
### NIGHT Token
|
|
870
|
-
- **Supply**: 24 billion (fixed)
|
|
871
|
-
- **Subunit**: 1 NIGHT = 1,000,000 STARs
|
|
872
|
-
- **Visibility**: Unshielded (public)
|
|
873
|
-
- **Function**: Generates DUST, governance, block rewards
|
|
874
|
-
- **Multi-chain**: Native on both Cardano and Midnight
|
|
875
|
-
|
|
876
|
-
### DUST Resource
|
|
877
|
-
- **Type**: Shielded, non-transferable
|
|
878
|
-
- **Function**: Pay transaction fees
|
|
879
|
-
- **Generation**: Continuously from NIGHT holdings
|
|
880
|
-
- **Decay**: When disassociated from NIGHT
|
|
881
|
-
- **Privacy**: Transactions don't leak metadata
|
|
882
|
-
|
|
883
|
-
## Key Insight: NIGHT Generates DUST
|
|
884
|
-
|
|
885
|
-
\`\`\`
|
|
886
|
-
Hold NIGHT → Generates DUST → Pay for transactions
|
|
887
|
-
(continuous) (consumed on use)
|
|
888
|
-
\`\`\`
|
|
889
|
-
|
|
890
|
-
This means: **Hold NIGHT, transact "for free"** (no recurring token spend)
|
|
891
|
-
|
|
892
|
-
## Block Rewards
|
|
893
|
-
|
|
894
|
-
**Formula**:
|
|
895
|
-
\`\`\`
|
|
896
|
-
Actual Reward = Base Reward × [S + (1-S) × U]
|
|
897
|
-
|
|
898
|
-
Where:
|
|
899
|
-
- S = Subsidy rate (95% at launch)
|
|
900
|
-
- U = Block utilization (target: 50%)
|
|
901
|
-
\`\`\`
|
|
902
|
-
|
|
903
|
-
- Full blocks: Producer gets 100% of base reward
|
|
904
|
-
- Empty blocks: Producer gets only subsidy (95%)
|
|
905
|
-
- Remainder goes to Treasury
|
|
906
|
-
|
|
907
|
-
## Token Distribution
|
|
908
|
-
|
|
909
|
-
### Phase 1: Glacier Drop (60 days)
|
|
910
|
-
- Free allocation to crypto holders
|
|
911
|
-
- 50% to Cardano, 20% to Bitcoin, 30% to others
|
|
912
|
-
- Minimum $100 USD equivalent required
|
|
913
|
-
|
|
914
|
-
### Phase 2: Scavenger Mine (30 days)
|
|
915
|
-
- Computational puzzles (accessible to public)
|
|
916
|
-
- Claims unclaimed Glacier Drop tokens
|
|
917
|
-
- Seeds network constituents
|
|
918
|
-
|
|
919
|
-
### Phase 3: Lost-and-Found (4 years)
|
|
920
|
-
- Second chance for Glacier Drop eligible
|
|
921
|
-
- Fractional allocation
|
|
922
|
-
|
|
923
|
-
## Key Differentiators
|
|
924
|
-
|
|
925
|
-
1. **No token spend for transactions** - DUST is renewable
|
|
926
|
-
2. **MEV resistant** - Shielded transactions
|
|
927
|
-
3. **Cross-chain native** - Same token on Cardano + Midnight
|
|
928
|
-
4. **Fair distribution** - Free, multi-phase, broad eligibility
|
|
929
|
-
`,
|
|
930
|
-
"midnight://docs/wallet-integration": `# Midnight Wallet Integration Guide
|
|
931
|
-
|
|
932
|
-
A guide for integrating Midnight Lace wallet into your DApp.
|
|
933
|
-
|
|
934
|
-
## Browser Detection
|
|
935
|
-
|
|
936
|
-
\`\`\`typescript
|
|
937
|
-
declare global {
|
|
938
|
-
interface Window {
|
|
939
|
-
midnight?: {
|
|
940
|
-
mnLace?: MidnightProvider;
|
|
941
|
-
};
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
|
|
945
|
-
function isWalletAvailable(): boolean {
|
|
946
|
-
return typeof window !== 'undefined'
|
|
947
|
-
&& window.midnight?.mnLace !== undefined;
|
|
948
|
-
}
|
|
949
|
-
\`\`\`
|
|
950
|
-
|
|
951
|
-
## DApp Connector API
|
|
952
|
-
|
|
953
|
-
\`\`\`typescript
|
|
954
|
-
interface DAppConnectorAPI {
|
|
955
|
-
enable(): Promise<MidnightAPI>;
|
|
956
|
-
isEnabled(): Promise<boolean>;
|
|
957
|
-
apiVersion(): string;
|
|
958
|
-
name(): string;
|
|
959
|
-
icon(): string;
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
async function connectWallet(): Promise<MidnightAPI> {
|
|
963
|
-
if (!window.midnight?.mnLace) {
|
|
964
|
-
throw new Error('Midnight Lace wallet not found');
|
|
965
|
-
}
|
|
966
|
-
return await window.midnight.mnLace.enable();
|
|
967
|
-
}
|
|
968
|
-
\`\`\`
|
|
969
|
-
|
|
970
|
-
## MidnightAPI Interface
|
|
971
|
-
|
|
972
|
-
\`\`\`typescript
|
|
973
|
-
interface MidnightAPI {
|
|
974
|
-
getUsedAddresses(): Promise<string[]>;
|
|
975
|
-
getBalance(): Promise<Balance>;
|
|
976
|
-
signTx(tx: Transaction): Promise<SignedTransaction>;
|
|
977
|
-
submitTx(signedTx: SignedTransaction): Promise<TxHash>;
|
|
978
|
-
signData(address: string, payload: string): Promise<Signature>;
|
|
979
|
-
}
|
|
980
|
-
\`\`\`
|
|
981
|
-
|
|
982
|
-
## React Hook
|
|
983
|
-
|
|
984
|
-
\`\`\`typescript
|
|
985
|
-
export function useWallet() {
|
|
986
|
-
const [state, setState] = useState({
|
|
987
|
-
isConnected: false,
|
|
988
|
-
address: null as string | null,
|
|
989
|
-
isLoading: false,
|
|
990
|
-
error: null as string | null,
|
|
991
|
-
});
|
|
992
|
-
|
|
993
|
-
const connect = useCallback(async () => {
|
|
994
|
-
setState(prev => ({ ...prev, isLoading: true, error: null }));
|
|
995
|
-
try {
|
|
996
|
-
if (!window.midnight?.mnLace) {
|
|
997
|
-
throw new Error('Please install Midnight Lace wallet');
|
|
998
|
-
}
|
|
999
|
-
const api = await window.midnight.mnLace.enable();
|
|
1000
|
-
const addresses = await api.getUsedAddresses();
|
|
1001
|
-
setState({
|
|
1002
|
-
isConnected: true,
|
|
1003
|
-
address: addresses[0] || null,
|
|
1004
|
-
isLoading: false,
|
|
1005
|
-
error: null,
|
|
1006
|
-
});
|
|
1007
|
-
return api;
|
|
1008
|
-
} catch (error) {
|
|
1009
|
-
setState(prev => ({
|
|
1010
|
-
...prev,
|
|
1011
|
-
isLoading: false,
|
|
1012
|
-
error: error instanceof Error ? error.message : 'Failed',
|
|
1013
|
-
}));
|
|
1014
|
-
throw error;
|
|
1015
|
-
}
|
|
1016
|
-
}, []);
|
|
1017
|
-
|
|
1018
|
-
return { ...state, connect };
|
|
1019
|
-
}
|
|
1020
|
-
\`\`\`
|
|
1021
|
-
|
|
1022
|
-
## Connection Flow
|
|
1023
|
-
|
|
1024
|
-
\`\`\`
|
|
1025
|
-
1. User clicks "Connect Wallet"
|
|
1026
|
-
2. DApp calls window.midnight.mnLace.enable()
|
|
1027
|
-
3. Wallet popup asks user to approve
|
|
1028
|
-
4. User approves → DApp receives MidnightAPI
|
|
1029
|
-
5. DApp can now interact with wallet
|
|
1030
|
-
\`\`\`
|
|
1031
|
-
|
|
1032
|
-
## Best Practices
|
|
1033
|
-
|
|
1034
|
-
1. Always check wallet availability first
|
|
1035
|
-
2. Handle user rejection gracefully
|
|
1036
|
-
3. Store connection state in context
|
|
1037
|
-
4. Provide clear loading/error feedback
|
|
1038
|
-
5. Test with Midnight Lace extension
|
|
1039
|
-
`,
|
|
1040
|
-
// Common Errors Reference - VERIFIED from official Midnight documentation
|
|
1041
|
-
"midnight://docs/common-errors": `# Common Midnight Errors & Solutions
|
|
1042
|
-
|
|
1043
|
-
Verified error messages from official Midnight documentation.
|
|
1044
|
-
|
|
1045
|
-
## Version Mismatch Errors
|
|
1046
|
-
|
|
1047
|
-
**Source:** [Fix version mismatch errors guide](https://docs.midnight.network/how-to/fix-version-mismatches)
|
|
1048
|
-
|
|
1049
|
-
Version mismatches occur when Midnight components are out of sync:
|
|
1050
|
-
- Compact compiler
|
|
1051
|
-
- Runtime libraries (@midnight-ntwrk/compact-runtime, @midnight-ntwrk/ledger)
|
|
1052
|
-
- Proof server
|
|
1053
|
-
- Indexer
|
|
1054
|
-
|
|
1055
|
-
### "Version mismatch" / CompactError
|
|
1056
|
-
\`\`\`javascript
|
|
1057
|
-
// The runtime checks version compatibility on startup
|
|
1058
|
-
throw new __compactRuntime.CompactError(\`Version mismatch...\`);
|
|
1059
|
-
\`\`\`
|
|
1060
|
-
|
|
1061
|
-
**Fix:** Check versions and update all components together:
|
|
1062
|
-
\`\`\`bash
|
|
1063
|
-
# Check your versions
|
|
1064
|
-
compact --version
|
|
1065
|
-
npm list @midnight-ntwrk/compact-runtime
|
|
1066
|
-
npm list @midnight-ntwrk/ledger
|
|
1067
|
-
|
|
1068
|
-
# Consult the compatibility matrix
|
|
1069
|
-
# https://docs.midnight.network/relnotes/support-matrix
|
|
1070
|
-
\`\`\`
|
|
1071
|
-
|
|
1072
|
-
## Compact Compiler Errors
|
|
1073
|
-
|
|
1074
|
-
### "invalid context for a ledger ADT type"
|
|
1075
|
-
**Source:** Compact 0.15/0.23 release notes
|
|
1076
|
-
|
|
1077
|
-
Ledger ADT types (Counter, Map, etc.) cannot be used as Compact types in casts.
|
|
1078
|
-
|
|
1079
|
-
\`\`\`compact
|
|
1080
|
-
// ❌ Wrong - casting to ledger ADT type
|
|
1081
|
-
const x = value as Counter; // Error!
|
|
1082
|
-
|
|
1083
|
-
// ✅ Correct - use the ledger field directly
|
|
1084
|
-
ledger.counter.increment(1);
|
|
1085
|
-
\`\`\`
|
|
1086
|
-
|
|
1087
|
-
### "static type error" - argument count/type mismatch
|
|
1088
|
-
**Source:** Compact runtime type checks
|
|
1089
|
-
|
|
1090
|
-
\`\`\`javascript
|
|
1091
|
-
// Runtime validates argument counts
|
|
1092
|
-
if (args_1.length !== 2)
|
|
1093
|
-
throw new __compactRuntime.CompactError(
|
|
1094
|
-
\`post: expected 2 arguments, received \${args_1.length}\`
|
|
1095
|
-
);
|
|
1096
|
-
\`\`\`
|
|
1097
|
-
|
|
1098
|
-
**Fix:** Ensure TypeScript calls match circuit signatures exactly.
|
|
1099
|
-
|
|
1100
|
-
### assert() failures
|
|
1101
|
-
**Source:** [Compact language reference](https://docs.midnight.network/develop/reference/compact/lang-ref)
|
|
1102
|
-
|
|
1103
|
-
\`\`\`compact
|
|
1104
|
-
// Assert syntax (Compact 0.16+)
|
|
1105
|
-
assert(condition, "error message");
|
|
1106
|
-
|
|
1107
|
-
// Example from bboard tutorial
|
|
1108
|
-
assert(ledger.state == State.VACANT, "Attempted to post to an occupied board");
|
|
1109
|
-
\`\`\`
|
|
1110
|
-
|
|
1111
|
-
**Note:** If assertion fails, the transaction fails without reaching the chain.
|
|
1112
|
-
|
|
1113
|
-
## TypeScript SDK Errors
|
|
1114
|
-
|
|
1115
|
-
### ContractTypeError
|
|
1116
|
-
**Source:** @midnight-ntwrk/midnight-js-contracts
|
|
1117
|
-
|
|
1118
|
-
Thrown when there's a contract type mismatch between the given contract type
|
|
1119
|
-
and the initial state deployed at a contract address.
|
|
1120
|
-
|
|
1121
|
-
\`\`\`typescript
|
|
1122
|
-
// Typically thrown by findDeployedContract()
|
|
1123
|
-
try {
|
|
1124
|
-
const contract = await findDeployedContract(provider, address, MyContract);
|
|
1125
|
-
} catch (e) {
|
|
1126
|
-
if (e instanceof ContractTypeError) {
|
|
1127
|
-
// The contract at this address is a different type
|
|
1128
|
-
console.error('Contract type mismatch:', e.circuitIds);
|
|
1129
|
-
}
|
|
1130
|
-
}
|
|
1131
|
-
\`\`\`
|
|
1132
|
-
|
|
1133
|
-
### type_error() - Runtime type errors
|
|
1134
|
-
**Source:** @midnight-ntwrk/compact-runtime
|
|
1135
|
-
|
|
1136
|
-
Internal function for type errors with parameters: who, what, where, type, value.
|
|
1137
|
-
|
|
1138
|
-
## DApp Connector Errors
|
|
1139
|
-
|
|
1140
|
-
**Source:** @midnight-ntwrk/dapp-connector-api ErrorCodes
|
|
1141
|
-
|
|
1142
|
-
\`\`\`typescript
|
|
1143
|
-
import { ErrorCodes } from '@midnight-ntwrk/dapp-connector-api';
|
|
1144
|
-
|
|
1145
|
-
// ErrorCodes.Rejected - User rejected the request
|
|
1146
|
-
// ErrorCodes.InvalidRequest - Malformed transaction or request
|
|
1147
|
-
// ErrorCodes.InternalError - DApp connector couldn't process request
|
|
1148
|
-
|
|
1149
|
-
try {
|
|
1150
|
-
const api = await window.midnight.mnLace.enable();
|
|
1151
|
-
} catch (error) {
|
|
1152
|
-
if (error.code === ErrorCodes.Rejected) {
|
|
1153
|
-
console.log('User rejected wallet connection');
|
|
1154
|
-
}
|
|
1155
|
-
}
|
|
1156
|
-
\`\`\`
|
|
1157
|
-
|
|
1158
|
-
## Node.js Environment Errors
|
|
1159
|
-
|
|
1160
|
-
### ERR_UNSUPPORTED_DIR_IMPORT
|
|
1161
|
-
**Source:** [BBoard tutorial troubleshooting](https://docs.midnight.network/develop/tutorial/3-creating/bboard-dapp)
|
|
1162
|
-
|
|
1163
|
-
Occurs due to environment caching after modifying shell config or changing Node versions.
|
|
1164
|
-
|
|
1165
|
-
**Fix:**
|
|
1166
|
-
\`\`\`bash
|
|
1167
|
-
# 1. Open a NEW terminal window (don't just source ~/.zshrc)
|
|
1168
|
-
# 2. Verify Node version
|
|
1169
|
-
nvm use 18
|
|
1170
|
-
|
|
1171
|
-
# 3. Clear cached modules
|
|
1172
|
-
rm -rf node_modules/.cache
|
|
1173
|
-
\`\`\`
|
|
1174
|
-
|
|
1175
|
-
## Transaction Errors
|
|
1176
|
-
|
|
1177
|
-
### INSUFFICIENT_FUNDS / Not enough tDUST
|
|
1178
|
-
**Source:** Midnight documentation examples
|
|
1179
|
-
|
|
1180
|
-
\`\`\`typescript
|
|
1181
|
-
try {
|
|
1182
|
-
const result = await sdk.sendTransaction(options);
|
|
1183
|
-
} catch (error) {
|
|
1184
|
-
if (error.code === 'INSUFFICIENT_FUNDS') {
|
|
1185
|
-
console.error('Not enough tDUST in wallet');
|
|
1186
|
-
// Direct user to testnet faucet
|
|
1187
|
-
}
|
|
1188
|
-
}
|
|
1189
|
-
\`\`\`
|
|
1190
|
-
|
|
1191
|
-
## Debugging Resources
|
|
1192
|
-
|
|
1193
|
-
1. **Compatibility Matrix:** [/relnotes/support-matrix](https://docs.midnight.network/relnotes/support-matrix)
|
|
1194
|
-
2. **Discord:** #developer-support channel
|
|
1195
|
-
3. **Recompile after updates:**
|
|
1196
|
-
\`\`\`bash
|
|
1197
|
-
rm -rf contract/*.cjs contract/*.prover contract/*.verifier
|
|
1198
|
-
compact compile src/contract.compact contract/
|
|
1199
|
-
\`\`\`
|
|
1200
|
-
`,
|
|
1201
|
-
};
|
|
1202
|
-
//# sourceMappingURL=docs-content.js.map
|