<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: M Zidan Fatonie</title>
    <description>The latest articles on Forem by M Zidan Fatonie (@mzf11125).</description>
    <link>https://forem.com/mzf11125</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1904352%2F7076e94e-1eeb-4b83-93ee-7b806408e687.jpg</url>
      <title>Forem: M Zidan Fatonie</title>
      <link>https://forem.com/mzf11125</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mzf11125"/>
    <language>en</language>
    <item>
      <title>Vibe Code Your First Midnight dApp with AI Agent Skills</title>
      <dc:creator>M Zidan Fatonie</dc:creator>
      <pubDate>Wed, 29 Apr 2026 16:24:48 +0000</pubDate>
      <link>https://forem.com/midnight-aliit/vibe-code-your-first-midnight-dapp-with-ai-agent-skills-2ocn</link>
      <guid>https://forem.com/midnight-aliit/vibe-code-your-first-midnight-dapp-with-ai-agent-skills-2ocn</guid>
      <description>&lt;p&gt;Your AI coding assistant doesn't know Compact. It knows TypeScript, Solidity, Rust, but Midnight's ZK smart contract language didn't exist when most models were trained. Ask it to write a Compact contract and you'll get plausible-looking code that won't compile.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;midnight_agent_skills&lt;/code&gt; is a set of 4 agent skills that fix this. Install them once, and your AI assistant has accurate knowledge of Compact syntax, the Midnight SDK, network config, and the gotchas that trip up real builders.&lt;/p&gt;

&lt;p&gt;This is a walkthrough of using those skills to build your first Midnight dApp.&lt;/p&gt;




&lt;h2&gt;
  
  
  What are agent skills?
&lt;/h2&gt;

&lt;p&gt;Agent skills are structured knowledge files that AI coding assistants load at context time. Instead of relying on training data, the assistant reads the skill files directly, so it gets accurate, current information rather than hallucinated guesses.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;midnight_agent_skills&lt;/code&gt; package has 4 skills:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;midnight-concepts&lt;/strong&gt;: ZK architecture, DUST/NIGHT tokenomics, Kachina protocol&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;midnight-compact&lt;/strong&gt;: Compact language, circuits, ledger operations, best practices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;midnight-api&lt;/strong&gt;: SDK integration, wallet connection, contract deployment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;midnight-network&lt;/strong&gt;: Node setup, Docker, indexer, proof server&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 1: Install the skills
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx skills add https://github.com/mzf11125/midnight_agent_skills
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or pick individual skills:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx skills add https://github.com/mzf11125/midnight_agent_skills &lt;span class="nt"&gt;--skill&lt;/span&gt; midnight-compact
npx skills add https://github.com/mzf11125/midnight_agent_skills &lt;span class="nt"&gt;--skill&lt;/span&gt; midnight-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: Start the proof server
&lt;/h2&gt;

&lt;p&gt;Midnight generates ZK proofs client-side, your data stays on your machine. You need a local proof server running before you can deploy anything.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 6300:6300 midnightnetwork/proof-server &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'midnight-proof-server --network preprod'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check it's up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:6300
&lt;span class="c"&gt;# We're alive 🎉!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: Scaffold your project
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-midnight-app my-first-dapp
&lt;span class="nb"&gt;cd &lt;/span&gt;my-first-dapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Write your contract
&lt;/h2&gt;

&lt;p&gt;Open your AI assistant and ask it to write a Midnight contract. With the skills loaded, it knows the correct syntax.&lt;/p&gt;

&lt;p&gt;Here's a simple owner-gated counter, only the deployer can increment it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma language_version &amp;gt;= 0.20;
import CompactStandardLibrary;

export ledger counter: Counter;
export ledger owner: Bytes&amp;lt;32&amp;gt;;

witness local_secret_key(): Bytes&amp;lt;32&amp;gt;;

export circuit initialize(): [] {
  const pk = publicKey(local_secret_key()).bytes;
  owner.write(disclose(pk));
}

export circuit increment(): [] {
  const caller = publicKey(local_secret_key()).bytes;
  assert(disclose(caller) == owner.read(), "Not authorized");
  counter.increment(1);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Things the skills teach your AI that it wouldn't otherwise know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;export circuit&lt;/code&gt; not &lt;code&gt;function&lt;/code&gt;, circuits declare constraints, they don't execute&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;disclose()&lt;/code&gt; is required when moving witness data to the public ledger, the compiler rejects code without it&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Counter&lt;/code&gt; uses &lt;code&gt;.increment()&lt;/code&gt; and &lt;code&gt;.read()&lt;/code&gt;, not &lt;code&gt;.value()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;No recursion, no unbounded loops, circuits must compile to a fixed-size constraint system&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 5: Compile
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;compact build src/counter.compact src/managed/counter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Success looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fetching public parameters for k=10 [====================] 192.38 KiB
  circuit "increment" (k=10, rows=29)
Overall progress [====================] 1/1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 6: Deploy
&lt;/h2&gt;

&lt;p&gt;With the &lt;code&gt;midnight-api&lt;/code&gt; skill loaded, your AI generates the correct facade 4.x pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;WalletFacade&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@midnight-ntwrk/wallet-sdk-facade&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CounterContract&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./managed/counter/contract/index.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// facade 4.x, the old WalletFacade.init() hangs silently on standalone nodes&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wallet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WalletFacade&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shielded&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;unshielded&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dust&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CounterContract&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deployed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deploy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;privateCounter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Deployed at:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;deployed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deployTxData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contractAddress&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The skills include the SDK compatibility matrix. Your AI knows that &lt;code&gt;wallet-sdk-facade@2.x&lt;/code&gt; uses &lt;code&gt;WalletFacade.init()&lt;/code&gt; which hangs silently on standalone nodes, and that &lt;code&gt;4.x&lt;/code&gt; switched to &lt;code&gt;new WalletFacade(...) + .start()&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 7: Run a pre-flight check
&lt;/h2&gt;

&lt;p&gt;Before you spend hours debugging, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx midnight-doctor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It reads your &lt;code&gt;package.json&lt;/code&gt;, running Docker containers, and config files, then cross-references them against a known compatibility matrix. The &lt;code&gt;midnight-api&lt;/code&gt; skill documents the most common silent failures:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Root cause&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;waitForSyncedState()&lt;/code&gt; hangs forever&lt;/td&gt;
&lt;td&gt;facade 2.x + standalone node mismatch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transactions silently fail&lt;/td&gt;
&lt;td&gt;Duplicate &lt;code&gt;@midnight-ntwrk/ledger-v7&lt;/code&gt; in node_modules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Indexer crash-loops&lt;/td&gt;
&lt;td&gt;Missing &lt;code&gt;subscription:&lt;/code&gt; block in &lt;code&gt;indexer.yml&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  What the skills know that your AI doesn't
&lt;/h2&gt;

&lt;p&gt;The skills pull from the official Midnight docs plus 19 community articles from the Midnight Aliit Fellowship, builders documenting real production failures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mental model shifts:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Circuits declare constraints, they don't execute. &lt;code&gt;assert&lt;/code&gt; is a constraint declaration, not a runtime guard, if the condition is false, the proof can't be generated.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;disclose()&lt;/code&gt; is a compile-time annotation, not encryption. The compiler tracks witness data through arithmetic and rejects undeclared disclosures.&lt;/li&gt;
&lt;li&gt;Block limits are hard limits, not gas costs. &lt;code&gt;BlockLimitExceeded&lt;/code&gt; means your transaction can't execute at all.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;On-chain design patterns:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flat maps over struct maps, reading a struct pulls every field into the circuit&lt;/li&gt;
&lt;li&gt;Off-chain computation + Merkle root, the chain verifies, it doesn't compute&lt;/li&gt;
&lt;li&gt;Minimal on-chain state, only what the chain needs to enforce&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Common syntax gotchas:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;counter.read()&lt;/code&gt; not &lt;code&gt;counter.value()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Enum access uses &lt;code&gt;.&lt;/code&gt; not &lt;code&gt;::&lt;/code&gt;, &lt;code&gt;GameState.playing&lt;/code&gt; not &lt;code&gt;GameState::playing&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Witness functions have no body, declaration only&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;return&lt;/code&gt; inside &lt;code&gt;for&lt;/code&gt; loops is not allowed, use &lt;code&gt;fold&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Install and start building
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx skills add https://github.com/mzf11125/midnight_agent_skills
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The skills are open source. If you hit a pattern that's missing, PRs are open.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/mzf11125/midnight_agent_skills" rel="noopener noreferrer"&gt;https://github.com/mzf11125/midnight_agent_skills&lt;/a&gt;&lt;/p&gt;

</description>
      <category>midnight</category>
      <category>compact</category>
      <category>web3</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
