<?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>DEV Community: Michael Steuer</title>
    <description>The latest articles on DEV Community by Michael Steuer (@mssteuer).</description>
    <link>https://dev.to/mssteuer</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%2F951390%2F285d6b74-37ba-4a7d-b737-4ce5b19172a4.jpeg</url>
      <title>DEV Community: Michael Steuer</title>
      <link>https://dev.to/mssteuer</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mssteuer"/>
    <language>en</language>
    <item>
      <title>I Gave Claude the Ability to Trade on a DEX. Here's How It Works</title>
      <dc:creator>Michael Steuer</dc:creator>
      <pubDate>Tue, 24 Mar 2026 22:10:41 +0000</pubDate>
      <link>https://dev.to/casperblockchain/i-gave-claude-the-ability-to-trade-on-a-dex-heres-how-it-works-3m2j</link>
      <guid>https://dev.to/casperblockchain/i-gave-claude-the-ability-to-trade-on-a-dex-heres-how-it-works-3m2j</guid>
      <description>&lt;p&gt;Here's a simple question: &lt;em&gt;Can an AI agent trade on a DEX without ever touching a private key?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Not read-only. Not "here's a price feed." Actually build a swap, sign it, submit it — end to end. And the answer, until now, was no.&lt;/p&gt;

&lt;p&gt;Every DeFi MCP server I looked at fell into one of two camps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Read-only&lt;/strong&gt; — your agent can look at prices, maybe get a quote, but can't actually do anything&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custodial&lt;/strong&gt; — hand over your keys and trust the server not to drain your wallet&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Neither is acceptable. Read-only is a toy. Custodial is a liability. So we built a third option.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Hard Problem: It's Not the DEX. It's the Keys.
&lt;/h2&gt;

&lt;p&gt;The hard problem of agentic DeFi isn't connecting to a DEX. Any wrapper can do that. The hard problem is: &lt;strong&gt;who holds the keys?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;CSPR.trade MCP does neither read-only nor custody. The agent builds the transaction remotely, your machine signs it locally, and &lt;strong&gt;keys never move&lt;/strong&gt;. That's not a feature. That's the architecture.&lt;/p&gt;

&lt;p&gt;Here's the flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────┐      ┌───────────────────┐      ┌──────────────┐
│  AI Agent    │─────▶│  CSPR.trade MCP   │─────▶│  Casper DEX  │
│  (Claude,    │      │  Server           │      │  (on-chain)  │
│   Cursor,    │      │                   │      │              │
│   custom)    │◀─────│  Returns UNSIGNED │      │              │
└──────┬───────┘      │  transaction JSON │      └──────────────┘
       │              └───────────────────┘
       │
       ▼
┌───────────────┐
│  LOCAL SIGNER │  ← Keys live here. Nowhere else.
│  (your        │
│   machine)    │
└──────┬────────┘
       │
       ▼
  Submit signed tx → on-chain execution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The MCP server never sees your private key. It can't. It builds an unsigned deploy, hands it back to the agent, and the agent signs locally before submitting. Zero custody. Zero trust assumptions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It: Two Servers, Zero Custody
&lt;/h2&gt;

&lt;p&gt;Add this to Claude Desktop, Cursor, or any MCP client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cspr-trade"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mcp.cspr.trade/mcp"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cspr-signer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"@make-software/cspr-trade-mcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"--signer"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"CSPR_TRADE_KEY_PATH"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~/.casper/secret_key.pem"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two servers, one architecture: the &lt;strong&gt;remote server&lt;/strong&gt; handles market data and builds unsigned transactions. The &lt;strong&gt;local signer&lt;/strong&gt; signs them with your key. Keys never leave your machine — and the remote server doesn't even have the signing tools. It &lt;em&gt;can't&lt;/em&gt; touch your keys, by design.&lt;/p&gt;

&lt;p&gt;No API key. No auth. No accounts. Just add the config and your agent can trade on &lt;a href="https://cspr.trade" rel="noopener noreferrer"&gt;CSPR.trade&lt;/a&gt;, the leading DEX on Casper Network.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Just want to explore?&lt;/strong&gt; The remote server works standalone — skip &lt;code&gt;cspr-signer&lt;/code&gt; and your agent gets full market data, quotes, and can build unsigned transactions. Add the signer when you're ready to execute.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What Your Agent Can Actually Do
&lt;/h2&gt;

&lt;p&gt;14 tools, three categories:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See everything (no wallet needed):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;get_tokens&lt;/code&gt; — all tokens with live prices&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_pairs&lt;/code&gt; — trading pairs with liquidity depth&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_pair_details&lt;/code&gt; — deep stats on any pair&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_quote&lt;/code&gt; — "How much WETH do I get for 10,000 CSPR?"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_currencies&lt;/code&gt; — supported currencies&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_swap_history&lt;/code&gt; — any account's trade history&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_liquidity_positions&lt;/code&gt; — LP positions and value&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_impermanent_loss&lt;/code&gt; — calculate IL for any position&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Build transactions (returns unsigned JSON):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;build_swap&lt;/code&gt; — construct a swap deploy&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;build_approve_token&lt;/code&gt; — token approval for the router&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;build_add_liquidity&lt;/code&gt; — add to a liquidity pool&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;build_remove_liquidity&lt;/code&gt; — withdraw from a pool&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Sign locally:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sign_deploy&lt;/code&gt; — sign with a local key (signer mode only)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Submit (back to remote server):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;submit_transaction&lt;/code&gt; — broadcast the signed deploy to the Casper network&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key insight: your agent can freely explore market data and build transactions on the remote server. When it needs to sign, it crosses to the local signer — then the signed transaction goes &lt;em&gt;back&lt;/em&gt; to the remote server for submission. Keys never leave your machine.&lt;/p&gt;




&lt;h2&gt;
  
  
  Walkthrough: Swapping 1000 CSPR for WETH
&lt;/h2&gt;

&lt;p&gt;Here's what actually happens when you tell Claude "Swap 1000 CSPR for WETH":&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — Agent gets a quote&lt;/strong&gt; &lt;em&gt;(remote server)&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;get_quote(tokenIn:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CSPR"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;tokenOut:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"WETH"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;amountIn:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1000"&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;←&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;amountOut:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.285"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;priceImpact:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.02%"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;route:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2 — Agent builds the swap&lt;/strong&gt; &lt;em&gt;(remote server)&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;build_swap(&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;publicKey:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"02036d..."&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;tokenIn:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CSPR"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;tokenOut:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"WETH"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;amountIn:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1000"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;slippage:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;←&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;deploy:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;unsigned&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;transaction&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JSON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3 — Local signing&lt;/strong&gt; &lt;em&gt;(local signer — your machine)&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;sign_deploy(deploy_json:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;key_source:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pem_file"&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;←&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;signedDeploy:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4 — Submit&lt;/strong&gt; &lt;em&gt;(remote server)&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;submit_transaction(signed_deploy_json:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;←&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;deployHash:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a1b2c3..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;status:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"submitted"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the boundary: Steps 1-2 hit the remote server, Step 3 runs on the local signer, and Step 4 goes back to the remote server to submit. The signed transaction crosses back — but the private key never does. Your agent routes each tool call to the right server automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  Self-Hosting and Testnet
&lt;/h2&gt;

&lt;p&gt;Want to run everything locally, or develop against testnet? Run the full server on your machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cspr-trade"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"@make-software/cspr-trade-mcp"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"CSPR_TRADE_NETWORK"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"testnet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"CSPR_TRADE_KEY_PATH"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~/.casper/secret_key.pem"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In stdio mode, the full server includes all tools — market data, transaction building, signing, and submission — in a single process. Your keys stay local because the server &lt;em&gt;is&lt;/em&gt; local.&lt;/p&gt;

&lt;p&gt;The SDK is also available separately for custom integrations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @make-software/cspr-trade-mcp-sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Why This Matters Beyond Casper
&lt;/h2&gt;

&lt;p&gt;Every blockchain is going to face this problem. As AI agents get more capable, they'll need to interact with DeFi — and the custody question doesn't go away just because the agent is smarter.&lt;/p&gt;

&lt;p&gt;The pattern we're using here — &lt;strong&gt;build remote, sign local&lt;/strong&gt; — isn't Casper-specific. It's a design pattern for any chain where you want agents to transact without surrendering keys. We just shipped it first.&lt;/p&gt;




&lt;h2&gt;
  
  
  Context: Casper v2.2.0
&lt;/h2&gt;

&lt;p&gt;This ships the same week Casper Network upgraded to v2.2.0 on mainnet. The v2.2.0 release marks a notable protocol upgrade, and CSPR.trade MCP is the first DeFi MCP server built for it. If you want to see what building on Casper looks like right now — this is it.&lt;/p&gt;




&lt;h2&gt;
  
  
  OpenClaw Skill
&lt;/h2&gt;

&lt;p&gt;Using &lt;a href="https://openclaw.ai" rel="noopener noreferrer"&gt;OpenClaw&lt;/a&gt;? Install the skill from &lt;a href="https://clawhub.com" rel="noopener noreferrer"&gt;ClawHub&lt;/a&gt; and your agent gets the full workflow guide — intent classification, signing flows, safety checks — baked in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx clawhub@latest &lt;span class="nb"&gt;install &lt;/span&gt;cspr-trade-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The skill teaches your agent &lt;em&gt;how&lt;/em&gt; to use the 14 tools: when to get a quote before building a swap, when to warn about price impact, how to handle local signing vs external wallets. It's the difference between "here are 14 tools, good luck" and "here's how a DeFi agent should behave."&lt;/p&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public endpoint:&lt;/strong&gt; &lt;a href="https://mcp.cspr.trade/mcp" rel="noopener noreferrer"&gt;mcp.cspr.trade/mcp&lt;/a&gt; — add it and go&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/make-software/cspr-trade-mcp" rel="noopener noreferrer"&gt;make-software/cspr-trade-mcp&lt;/a&gt; — MIT, PRs welcome&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/@make-software/cspr-trade-mcp" rel="noopener noreferrer"&gt;@make-software/cspr-trade-mcp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ClawHub skill:&lt;/strong&gt; &lt;a href="https://clawhub.com/skills/cspr-trade-mcp" rel="noopener noreferrer"&gt;&lt;code&gt;cspr-trade-mcp&lt;/code&gt;&lt;/a&gt; — install with &lt;code&gt;npx clawhub install cspr-trade-mcp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent SKILL.md:&lt;/strong&gt; &lt;a href="https://mcp.cspr.trade/SKILL.md" rel="noopener noreferrer"&gt;mcp.cspr.trade/SKILL.md&lt;/a&gt; — structured instructions for AI agents&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSPR.trade:&lt;/strong&gt; &lt;a href="https://cspr.trade" rel="noopener noreferrer"&gt;cspr.trade&lt;/a&gt; — the DEX itself&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Questions? Drop a comment or &lt;a href="https://github.com/make-software/cspr-trade-mcp/issues" rel="noopener noreferrer"&gt;open an issue&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;— Built by &lt;a href="https://make.services" rel="noopener noreferrer"&gt;MAKE&lt;/a&gt;, the team behind Casper's core developer tools.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>blockchain</category>
      <category>web3</category>
    </item>
    <item>
      <title>Why We Built Edicts</title>
      <dc:creator>Michael Steuer</dc:creator>
      <pubDate>Sun, 22 Mar 2026 23:46:19 +0000</pubDate>
      <link>https://dev.to/mssteuer/why-we-built-edicts-kef</link>
      <guid>https://dev.to/mssteuer/why-we-built-edicts-kef</guid>
      <description>&lt;p&gt;A lot of agent failures do not come from reasoning. They come from certainty.&lt;/p&gt;

&lt;p&gt;An agent will happily draft a convincing answer, a polished status update, or a perfectly formatted post while being wrong about the one fact that actually matters. The launch date is off by a week. The product has a feature it does not have. The company policy is described backwards. The partner name that should stay private ends up in public copy because the model found a familiar pattern in its training data and filled in the blank with confidence.&lt;/p&gt;

&lt;p&gt;One example was painfully small: an agent prepared public copy that referenced the wrong version number. The current version was known. The team had already agreed on it. It existed in Slack, docs, release notes, and someone’s head. But “known somewhere” is not the same as “available cheaply, reliably, every time the model speaks.”&lt;/p&gt;

&lt;p&gt;That distinction is where Edicts came from.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem was not memory in the broad sense
&lt;/h2&gt;

&lt;p&gt;There are already good tools for memory.&lt;/p&gt;

&lt;p&gt;If you want long-horizon conversational recall, there are products built around that. If you want graph-shaped knowledge with deeper semantic retrieval, there are products built around that too. If you want a full RAG pipeline over manuals, tickets, PDFs, and scattered internal docs, plenty of tooling already exists.&lt;/p&gt;

&lt;p&gt;But we kept running into a narrower problem.&lt;/p&gt;

&lt;p&gt;Agents often need a tiny set of high-value facts that should always win:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the current release number&lt;/li&gt;
&lt;li&gt;the public launch date&lt;/li&gt;
&lt;li&gt;a hard compliance constraint&lt;/li&gt;
&lt;li&gt;a negative assertion like “this product does &lt;strong&gt;not&lt;/strong&gt; support gas sponsorship”&lt;/li&gt;
&lt;li&gt;a temporary operational constraint like “writes are disabled during the migration window”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are not documents. They are not embeddings-worthy paragraphs. They are not knowledge graphs. They are not “memory” in the warm, human, conversational sense.&lt;/p&gt;

&lt;p&gt;They are ground truth.&lt;/p&gt;

&lt;p&gt;And ground truth should be cheap.&lt;/p&gt;

&lt;h2&gt;
  
  
  The existing options were either too heavy or too sloppy
&lt;/h2&gt;

&lt;p&gt;We kept seeing four unsatisfying patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. System prompt stuffing
&lt;/h3&gt;

&lt;p&gt;The fastest solution is to keep appending more context to the system prompt until the prompt looks like a family garage after twenty years: technically still functional, impossible to search, and full of things nobody wants to carry every single time.&lt;/p&gt;

&lt;p&gt;Important facts get buried. Token cost drifts upward. Temporary facts linger forever. Contradictory updates accumulate. The model receives a wall of prose instead of a disciplined set of assertions.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. RAG for tiny facts
&lt;/h3&gt;

&lt;p&gt;RAG is powerful when you genuinely need retrieval across large corpora. But if your real need is “always remind the model that feature X does not exist,” wiring a retrieval pipeline around that is like installing airport security to protect a sandwich.&lt;/p&gt;

&lt;p&gt;It solves a bigger class of problems than the one you have, and you pay for that ambition in complexity.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Conversational memory systems
&lt;/h3&gt;

&lt;p&gt;Conversational memory systems are designed for a different kind of job: recall from interactions, preferences, patterns, personal details, and accumulated conversational context. Useful job. Wrong tool for non-negotiable product facts.&lt;/p&gt;

&lt;p&gt;We did not want a system inferring which launch timing statement mattered most. We wanted a place to write the launch timing statement down and make it authoritative.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Knowledge graphs for everything
&lt;/h3&gt;

&lt;p&gt;Knowledge-graph-heavy approaches become interesting when your domain genuinely needs relationships, entities, traversals, and deeper structured reasoning. But a surprising amount of agent reality is flatter than that.&lt;/p&gt;

&lt;p&gt;Most production-critical facts are just assertions with a few pieces of metadata:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;category&lt;/li&gt;
&lt;li&gt;confidence&lt;/li&gt;
&lt;li&gt;source&lt;/li&gt;
&lt;li&gt;expiration&lt;/li&gt;
&lt;li&gt;optional supersession key&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is it. A lot of the time, that is enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  The insight was embarrassingly simple
&lt;/h2&gt;

&lt;p&gt;We did not need a grand theory of memory.&lt;/p&gt;

&lt;p&gt;We needed a tiny layer for flat, verified assertions that could be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;stored on disk&lt;/li&gt;
&lt;li&gt;rendered cheaply into prompts&lt;/li&gt;
&lt;li&gt;updated safely&lt;/li&gt;
&lt;li&gt;expired automatically&lt;/li&gt;
&lt;li&gt;small enough to keep around all the time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That became Edicts.&lt;/p&gt;

&lt;p&gt;An edict is just a statement plus metadata. Not a transcript. Not a vector. Not a graph node. A statement.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Product v2.0 launches April 15, NOT before.”&lt;/li&gt;
&lt;li&gt;“Do not name unannounced design partners publicly.”&lt;/li&gt;
&lt;li&gt;“Enterprise plan does NOT include white-label support.”&lt;/li&gt;
&lt;li&gt;“User-profile writes are disabled during the migration window.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each one can carry a category, tags, confidence, provenance, and a TTL. That is enough structure to make the facts operational without turning them into a tiny enterprise software project.&lt;/p&gt;

&lt;h2&gt;
  
  
  We optimized for token cost on purpose
&lt;/h2&gt;

&lt;p&gt;A big part of the design came from refusing to treat every fact like a document retrieval problem.&lt;/p&gt;

&lt;p&gt;If an edict averages around a dozen useful tokens of actual semantic payload, you can afford to inject several of them into every prompt. That matters. Reliability often comes from repetition. The model should not have to go hunting for the facts that would make a public answer safe.&lt;/p&gt;

&lt;p&gt;The goal is not to build the most sophisticated memory substrate in the world. The goal is to make the right facts cheap enough to always be present.&lt;/p&gt;

&lt;p&gt;That changes behavior. Teams stop hoarding facts in docs nobody injects. They stop relying on the agent to “remember from last time.” They stop pretending that a compliance rule mentioned three tools ago will still be salient when the agent writes the public-facing answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Edicts sits in the memory hierarchy
&lt;/h2&gt;

&lt;p&gt;We think of agent memory as a hierarchy, not a winner-take-all battle.&lt;/p&gt;

&lt;p&gt;At the bottom, you have immediate working context: the current turn, the current task, the current prompt.&lt;/p&gt;

&lt;p&gt;Above that, you have Edicts: compact, verified, operational truths that should travel with the agent because they are cheap and important.&lt;/p&gt;

&lt;p&gt;Above that, you may have richer recall systems: transcripts, summaries, vector stores, graphs, document retrieval, long-term conversational memory.&lt;/p&gt;

&lt;p&gt;Those systems are not enemies of Edicts. They solve different problems.&lt;/p&gt;

&lt;p&gt;Edicts is the layer you use when the question is not “what might be relevant?” but “what must stay true?”&lt;/p&gt;

&lt;h2&gt;
  
  
  Production taught us a few lessons quickly
&lt;/h2&gt;

&lt;p&gt;The first lesson was that &lt;strong&gt;negative assertions are gold&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;People naturally document what exists. Agents hallucinate most dangerously around what does not exist. If your product does not support a feature, say that explicitly. If a name should never be used publicly, say that explicitly. If an inferred capability is false, write the counter-fact down.&lt;/p&gt;

&lt;p&gt;The second lesson was &lt;strong&gt;TTL hygiene&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Temporary truths become permanent lies if you never expire them. Migration windows end. freezes end. launch embargoes end. “For the next 48 hours” is not a category; it is a lifecycle. Edicts bakes that lifecycle into the model. Ephemeral and event-based facts are not a social contract. They actually expire.&lt;/p&gt;

&lt;p&gt;The third lesson was &lt;strong&gt;key-based supersession&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Facts that change over time should not pile up like geological layers in a prompt. If the current release is now &lt;code&gt;v2.4.2&lt;/code&gt;, that should supersede &lt;code&gt;v2.4.1&lt;/code&gt;, not sit next to it and ask the model to infer chronology from vibes. Stable keys give you clean replacement and a history trail without prompt clutter.&lt;/p&gt;

&lt;p&gt;The fourth lesson was that &lt;strong&gt;simple storage wins&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;YAML and JSON are boring. That is the compliment. You can read them, diff them, commit them, inspect them in production, and repair them without an archaeology team. We did not want ground truth trapped in a black box.&lt;/p&gt;

&lt;h2&gt;
  
  
  We also wanted framework agnosticism to be real, not marketing copy
&lt;/h2&gt;

&lt;p&gt;A lot of “framework-agnostic” products are framework-agnostic in a very theoretical sense: technically possible, but not the default experience.&lt;/p&gt;

&lt;p&gt;We wanted Edicts to be genuinely usable anywhere.&lt;/p&gt;

&lt;p&gt;If your stack can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;load a file,&lt;/li&gt;
&lt;li&gt;prepend text to a system prompt, and&lt;/li&gt;
&lt;li&gt;optionally expose function calls,&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;then you can integrate Edicts.&lt;/p&gt;

&lt;p&gt;That is why the core stays small and boring. OpenClaw has a first-party integration because it is useful, but the store itself does not depend on OpenClaw or any orchestration framework. &lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started with OpenClaw
&lt;/h2&gt;

&lt;p&gt;If you are running &lt;a href="https://openclaw.ai" rel="noopener noreferrer"&gt;OpenClaw&lt;/a&gt;, Edicts has a first-party plugin that handles everything: injection, tool registration, and file bootstrapping.&lt;/p&gt;

&lt;p&gt;Install and restart:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openclaw plugins &lt;span class="nb"&gt;install &lt;/span&gt;openclaw-plugin-edicts
openclaw gateway restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is it. On first load, the plugin creates an &lt;code&gt;edicts.yaml&lt;/code&gt; file in your workspace. Every agent session — main chat, cron jobs, sub-agents, every channel — gets the edicts prepended to its system prompt automatically. No per-session wiring.&lt;/p&gt;

&lt;p&gt;Your agents also get tools (&lt;code&gt;edicts_add&lt;/code&gt;, &lt;code&gt;edicts_list&lt;/code&gt;, &lt;code&gt;edicts_update&lt;/code&gt;, &lt;code&gt;edicts_remove&lt;/code&gt;, &lt;code&gt;edicts_search&lt;/code&gt;, &lt;code&gt;edicts_stats&lt;/code&gt;, &lt;code&gt;edicts_review&lt;/code&gt;) so they can manage edicts conversationally. Say "remember that v2.2.0 launches March 23" and the agent writes it to the store.&lt;/p&gt;

&lt;p&gt;You can also edit &lt;code&gt;edicts.yaml&lt;/code&gt; by hand. It is a plain YAML file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="na"&gt;edicts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;e_001&lt;/span&gt;
    &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Product&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;v2.2.0&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;launches&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;March&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;23,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;2026."&lt;/span&gt;
    &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;product&lt;/span&gt;
    &lt;span class="na"&gt;ttl&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;event&lt;/span&gt;
    &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;product-launch-date&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are not on OpenClaw, install the standalone library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;edicts
edicts init        &lt;span class="c"&gt;# creates starter edicts.yaml&lt;/span&gt;
edicts add &lt;span class="s2"&gt;"Feature X does NOT support gas sponsorship"&lt;/span&gt; &lt;span class="nt"&gt;--category&lt;/span&gt; product
edicts list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The core library has zero framework dependencies. Any agent system that can prepend text to a system prompt can use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Edicts is not
&lt;/h2&gt;

&lt;p&gt;Edicts is not an attempt to replace RAG.&lt;/p&gt;

&lt;p&gt;It is not a general-purpose knowledge graph.&lt;/p&gt;

&lt;p&gt;It is not a substitute for long-term conversational memory.&lt;/p&gt;

&lt;p&gt;It is not trying to solve every memory problem an agent could ever have.&lt;/p&gt;

&lt;p&gt;We wanted a tool that knows exactly which problem it is solving: compact ground truth for agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why we think this matters
&lt;/h2&gt;

&lt;p&gt;As agent systems become more common, a lot of reliability work will come down to memory discipline rather than model cleverness.&lt;/p&gt;

&lt;p&gt;Most public-facing or operational mistakes are not the result of deep reasoning failure. They are the result of missing or stale facts. A model that can reason beautifully on top of bad premises is still a liability.&lt;/p&gt;

&lt;p&gt;Edicts is our attempt to make that layer boring, explicit, and cheap.&lt;/p&gt;

&lt;p&gt;Not glamorous. Just useful.&lt;/p&gt;

&lt;p&gt;If you need a small set of verified truths to follow your agents around without dragging a wagon of context behind them, that is exactly what we built.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docs: &lt;a href="https://edicts.ai" rel="noopener noreferrer"&gt;https://edicts.ai&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/edicts-ai/edicts" rel="noopener noreferrer"&gt;https://github.com/edicts-ai/edicts&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;License: MIT&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>agents</category>
      <category>agentskills</category>
      <category>openclaw</category>
      <category>memory</category>
    </item>
    <item>
      <title>Opening the Playbook: Why We're Open-Sourcing Casper's Core DeFi Infrastructure</title>
      <dc:creator>Michael Steuer</dc:creator>
      <pubDate>Thu, 19 Mar 2026 18:30:15 +0000</pubDate>
      <link>https://dev.to/casperblockchain/opening-the-playbook-why-were-open-sourcing-caspers-core-defi-infrastructure-3d9o</link>
      <guid>https://dev.to/casperblockchain/opening-the-playbook-why-were-open-sourcing-caspers-core-defi-infrastructure-3d9o</guid>
      <description>&lt;p&gt;&lt;em&gt;Four production systems, security-audited by Halborn, open-sourced in one week. A naming service, a decentralized exchange, liquid staking, and EIP-712 typed signatures. All live on mainnet. All yours now.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Earlier this week, I &lt;a href="https://github.com/casper-ecosystem/casper-eip-712" rel="noopener noreferrer"&gt;open-sourced casper-eip-712&lt;/a&gt;, a Rust crate that brings Ethereum's typed signing standard to Casper. I wrote about why we did it, what it unlocks, and how it started with a security auditor telling us we had a gap.&lt;/p&gt;

&lt;p&gt;That was &lt;a href="https://dev.to/casperblockchain/why-we-brought-ethereums-most-important-signing-standard-to-casper-38k2"&gt;yesterday&lt;/a&gt;. We weren't done.&lt;/p&gt;

&lt;p&gt;Today I'm announcing that we've open-sourced three additional contract repositories that power core DeFi infrastructure on Casper Network:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/make-software/cspr-name-contracts" rel="noopener noreferrer"&gt;cspr-name-contracts&lt;/a&gt;&lt;/strong&gt;: the smart contracts behind &lt;a href="https://cspr.name" rel="noopener noreferrer"&gt;CSPR.name&lt;/a&gt;, Casper's decentralized naming service&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/odradev/casper-trade" rel="noopener noreferrer"&gt;casper-trade&lt;/a&gt;&lt;/strong&gt;: the DEX contracts powering &lt;a href="https://cspr.trade" rel="noopener noreferrer"&gt;CSPR.trade&lt;/a&gt;, a Uniswap V2-style automated market maker&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/casper-ecosystem/liquid-staking-contracts" rel="noopener noreferrer"&gt;liquid-staking-contracts&lt;/a&gt;&lt;/strong&gt;: the liquid staking protocol behind &lt;a href="https://casper.wiselending.com" rel="noopener noreferrer"&gt;casper.wiselending.com&lt;/a&gt;, enabling staked CSPR to remain liquid as sCSPR&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These aren't proofs of concept. They're not hackathon projects gathering dust. Each of these repositories powers a live product with real users on Casper mainnet right now. And critically, each has been independently security-audited by &lt;a href="https://halborn.com" rel="noopener noreferrer"&gt;Halborn&lt;/a&gt;, one of the leading blockchain security firms in the industry:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.halborn.com/audits/casper-association/make-csprname-7b1108" rel="noopener noreferrer"&gt;CSPR.name audit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.halborn.com/audits/casper-association/odradevcasper--trade-af1b5a" rel="noopener noreferrer"&gt;CSPR.trade audit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.halborn.com/audits/casper-association/odra---liquid-staking-231379" rel="noopener noreferrer"&gt;Liquid staking audit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Production-deployed, battle-tested, and security-audited. That's the bar we're setting for what "open source" means on Casper.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Open-Source, Why Now
&lt;/h2&gt;

&lt;p&gt;Let me be direct about the motivation. Casper Network is an open-source Layer 1 blockchain with decentralized community governance. The protocol is open. The node software is open. The SDK is open. But until now, the production-grade application contracts, the ones that actually demonstrate how to build real things on Casper, weren't.&lt;/p&gt;

&lt;p&gt;That's a gap. And it's the kind of gap that makes life harder for builders.&lt;/p&gt;

&lt;p&gt;If you wanted to build a naming service on Casper, you'd start from scratch. If you wanted to build a DEX, you'd reverse-engineer how AMMs work on EVM chains and figure out how to translate that to Casper's architecture. If you wanted to implement liquid staking, you'd be pioneering patterns that someone had already solved, just behind closed doors.&lt;/p&gt;

&lt;p&gt;We're opening those doors.&lt;/p&gt;

&lt;p&gt;The timing matters, too. Casper's v2.2.0 mainnet upgrade launches on March 23rd. Validators are already staging, with 83% of stake staged and climbing. The protocol is evolving. Upgradeable smart contracts, improved developer ergonomics, a maturing DeFi stack. But none of that matters if builders don't have the reference material, the production-tested patterns, and the working code to build on.&lt;/p&gt;

&lt;p&gt;Open-sourcing these repositories isn't an act of charity. It's infrastructure investment. It's saying: "Here's how we solved naming, liquidity, staking, and typed signatures on Casper. Take it. Learn from it. Build on it. Make it better."&lt;/p&gt;

&lt;h2&gt;
  
  
  Three Teams, One Commons
&lt;/h2&gt;

&lt;p&gt;One thing worth highlighting: these four repositories come from three different organizations.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/make-software" rel="noopener noreferrer"&gt;make-software&lt;/a&gt;&lt;/strong&gt; (MAKE) hosts the CSPR.name contracts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/odradev" rel="noopener noreferrer"&gt;odradev&lt;/a&gt;&lt;/strong&gt; (Odra) built the CSPR.trade DEX&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/casper-ecosystem" rel="noopener noreferrer"&gt;casper-ecosystem&lt;/a&gt;&lt;/strong&gt; hosts the liquid staking contracts and casper-eip-712&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is how we operate. The Casper Association doesn't build everything in-house. It functions as an ecosystem orchestrator, ensuring that different teams across the ecosystem contribute to, collaborate on, and benefit from shared infrastructure. MAKE, Odra, WiseLending: each team brings deep expertise in their domain. The Association's job is to make sure that expertise compounds instead of staying siloed.&lt;/p&gt;

&lt;p&gt;Open-sourcing these repositories is a concrete expression of that philosophy. Three teams, four repos, one ecosystem commons.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Framework That Runs the Stack
&lt;/h2&gt;

&lt;p&gt;Three of the four repositories are built entirely with &lt;a href="https://odra.dev" rel="noopener noreferrer"&gt;Odra&lt;/a&gt;, the Rust-native smart contract framework for Casper. The fourth, casper-eip-712, is a vanilla Rust crate by design (it needs to work in any environment, including &lt;code&gt;no_std&lt;/code&gt;). But we built its &lt;a href="https://github.com/casper-ecosystem/casper-eip-712/tree/master/examples/permit-token" rel="noopener noreferrer"&gt;demo project&lt;/a&gt;, a full CEP-18 token with gasless permit/approve, in Odra specifically to demonstrate how the vanilla crate integrates with the framework.&lt;/p&gt;

&lt;p&gt;If you're not familiar with Odra: think of it as what OpenZeppelin provides for the EVM ecosystem, but more comprehensive and designed from the ground up for Casper's architecture. Odra handles the contract lifecycle, testing infrastructure, deployment tooling, and factory patterns, so you can focus on your application logic rather than blockchain plumbing.&lt;/p&gt;

&lt;p&gt;The fact that three production DeFi systems were built with Odra, and the fourth integrates seamlessly, is itself a strong signal. A naming protocol, a full Uniswap V2 port, and a liquid staking system with protocol-level integration, all built, tested, audited, deployed, and running in production using the same framework.&lt;/p&gt;

&lt;p&gt;For developers considering Casper, these repos serve as a real-world Odra curriculum:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;cspr-name-contracts&lt;/strong&gt; demonstrates domain registration, resolution, and the tradable NFT-like ownership model&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;casper-trade&lt;/strong&gt; shows how to port a battle-tested EVM design (Uniswap V2) to Casper, including Odra's factory pattern for runtime contract deployment, which is a genuinely different approach from EVM's &lt;code&gt;create2&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;liquid-staking-contracts&lt;/strong&gt; illustrates protocol-level integration, the sCSPR liquid token pattern, and Gherkin-style BDD tests&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;casper-eip-712&lt;/strong&gt; demonstrates how standalone Rust crates integrate with Odra contracts in production&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Under the Hood
&lt;/h2&gt;

&lt;h3&gt;
  
  
  CSPR.name: Decentralized Naming for Casper
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/make-software/cspr-name-contracts" rel="noopener noreferrer"&gt;make-software/cspr-name-contracts&lt;/a&gt; | &lt;a href="https://www.halborn.com/audits/casper-association/make-csprname-7b1108" rel="noopener noreferrer"&gt;Halborn audit&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Live product:&lt;/strong&gt; &lt;a href="https://cspr.name" rel="noopener noreferrer"&gt;CSPR.name&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;14c8b2f09ad2ef34c23bff91d52e6f48cbd714ea1fa8b3e71d26547ebfd1229c&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That's a Casper account hash. Try sending tokens to it from memory. Now try sending tokens to &lt;code&gt;michael.cspr&lt;/code&gt;. That's the problem CSPR.name solves.&lt;/p&gt;

&lt;p&gt;CSPR.name is Casper's official naming service. It replaces cryptographic account hashes with human-readable &lt;code&gt;.cspr&lt;/code&gt; names, making the entire ecosystem more navigable. Register a name, and it becomes your on-chain identity, recognized across &lt;a href="https://cspr.live" rel="noopener noreferrer"&gt;CSPR.live&lt;/a&gt;, Casper Wallet, dApps, and the broader ecosystem.&lt;/p&gt;

&lt;p&gt;But CSPR.name goes beyond simple name-to-address resolution. As of the latest release, names are &lt;a href="https://www.casper.network/news/cspr-names-are-now-tradable-on-cspr-market" rel="noopener noreferrer"&gt;fully tradable on CSPR.market&lt;/a&gt;. You can buy, sell, and make purchase offers for names. Your .cspr name isn't just a convenience. It's a digital asset.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What developers can learn from this repo:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name registration and resolution contract architecture using Odra&lt;/li&gt;
&lt;li&gt;Tradable naming rights: turning registered names into transferable assets&lt;/li&gt;
&lt;li&gt;Integration with marketplace contracts&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;cargo odra build&lt;/code&gt; and &lt;code&gt;cargo odra test&lt;/code&gt; for the full development lifecycle
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone and run tests locally&lt;/span&gt;
git clone https://github.com/make-software/cspr-name-contracts
&lt;span class="nb"&gt;cd &lt;/span&gt;cspr-name-contracts
&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
cargo odra &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CSPR.trade: Native Decentralized Exchange
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/odradev/casper-trade" rel="noopener noreferrer"&gt;odradev/casper-trade&lt;/a&gt; | &lt;a href="https://www.halborn.com/audits/casper-association/odradevcasper--trade-af1b5a" rel="noopener noreferrer"&gt;Halborn audit&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Live product:&lt;/strong&gt; &lt;a href="https://cspr.trade" rel="noopener noreferrer"&gt;CSPR.trade&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CSPR.trade is Casper's native DEX, a Uniswap V2-style automated market maker built specifically for Casper's architecture. It provides token swaps, liquidity pools, and yield farming. With deterministic finality and non-custodial execution, every swap, pool rebalance, and fee distribution is verifiable on-chain.&lt;/p&gt;

&lt;p&gt;What makes this repo particularly interesting for developers is how faithfully it ports the Uniswap V2 architecture while handling the fundamental differences between EVM and Casper:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The factory pattern:&lt;/strong&gt; On Ethereum, Uniswap's factory deploys Pair contracts using &lt;code&gt;create2&lt;/code&gt; with the Pair bytecode stored in the Factory. Casper doesn't have &lt;code&gt;create2&lt;/code&gt;. Instead, Odra provides a &lt;code&gt;factory=on&lt;/code&gt; directive that auto-generates a PairFactory contract. The PairFactory's sole purpose is managing deployments and upgrades of Pair contracts. Factory calls &lt;code&gt;factory()&lt;/code&gt; on PairFactory, which deploys a new Pair and returns its address.&lt;/p&gt;

&lt;p&gt;This is one of those architectural differences that would take a team weeks to figure out from scratch. Now it's documented, tested, audited, and open.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test parity:&lt;/strong&gt; The tests are based directly on the original Uniswap V2 test suites (&lt;code&gt;UniswapV2Router01.spec.ts&lt;/code&gt;, &lt;code&gt;UniswapV2Router02.spec.ts&lt;/code&gt;, &lt;code&gt;UniswapV2Factory.spec.ts&lt;/code&gt;, and &lt;code&gt;UniswapV2Pair.spec.ts&lt;/code&gt;). This isn't a loose reimplementation; it's a faithful port with behavioral verification against the original.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contract architecture:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Pair&lt;/code&gt;: The AMM pair contract (deployed by PairFactory, not directly). Corresponds to UniswapV2Pair.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PairFactory&lt;/code&gt;: Auto-generated by Odra. Responsible for deploying and upgrading Pair contracts.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Router&lt;/code&gt;: Corresponds to UniswapV2Router. Entry point for swaps and liquidity operations.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Factory&lt;/code&gt;: Pair management. Corresponds to UniswapV2Factory.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;WrappedNativeToken&lt;/code&gt;: From Odra modules, wraps native CSPR for use in AMM pools.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone, install, and test&lt;/span&gt;
git clone https://github.com/odradev/casper-trade
&lt;span class="nb"&gt;cd &lt;/span&gt;casper-trade
cargo &lt;span class="nb"&gt;install &lt;/span&gt;cargo-odra
just &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Liquid Staking: The StakedCSPR Protocol
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/casper-ecosystem/liquid-staking-contracts" rel="noopener noreferrer"&gt;casper-ecosystem/liquid-staking-contracts&lt;/a&gt; | &lt;a href="https://www.halborn.com/audits/casper-association/odra---liquid-staking-231379" rel="noopener noreferrer"&gt;Halborn audit&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Live product:&lt;/strong&gt; &lt;a href="https://casper.wiselending.com" rel="noopener noreferrer"&gt;casper.wiselending.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's the staking dilemma every Proof-of-Stake network faces: users who stake their tokens to secure the network get their capital locked up. They earn rewards, but they lose liquidity. They can't use those tokens in DeFi. They can't respond to market conditions without waiting through unbonding periods. So they face a choice: security or liquidity.&lt;/p&gt;

&lt;p&gt;Liquid staking removes that choice.&lt;/p&gt;

&lt;p&gt;When you stake CSPR through the liquid staking protocol, you receive sCSPR, a liquid token that represents your staked position. Your original CSPR stays staked and continues earning network rewards. Meanwhile, sCSPR is freely transferable. You can use it in &lt;a href="https://cspr.trade" rel="noopener noreferrer"&gt;CSPR.trade&lt;/a&gt; pools. You can use it as collateral. Your capital works in two places at once.&lt;/p&gt;

&lt;p&gt;On Casper, this &lt;a href="https://www.casper.network/news/liquid-staking" rel="noopener noreferrer"&gt;isn't a third-party bolt-on&lt;/a&gt;. It's built with protocol-level awareness, in collaboration with &lt;a href="https://wiselending.com" rel="noopener noreferrer"&gt;WiseLending&lt;/a&gt;. No custodians, no synthetic wrappers, no workarounds that bypass the base layer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What makes this repo especially valuable for developers:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The StakedCSPR token contract implementation, a real-world example of a liquid representation token&lt;/li&gt;
&lt;li&gt;Gherkin-style BDD test specifications in the &lt;code&gt;tests/features&lt;/code&gt; folder, showing how to write readable, verifiable test suites for complex DeFi logic&lt;/li&gt;
&lt;li&gt;Full CLI tooling for deployment and interaction&lt;/li&gt;
&lt;li&gt;Protocol-level staking integration patterns
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone and test&lt;/span&gt;
git clone https://github.com/casper-ecosystem/liquid-staking-contracts
&lt;span class="nb"&gt;cd &lt;/span&gt;liquid-staking-contracts
just &lt;span class="nb"&gt;test&lt;/span&gt;

&lt;span class="c"&gt;# Deploy to testnet (configure .env first)&lt;/span&gt;
just build-contracts
just cli deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What This Means for Builders
&lt;/h2&gt;

&lt;p&gt;Let me be concrete about what you can do with these repositories today:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you want to build a naming service on another domain&lt;/strong&gt;, fork cspr-name-contracts. The architecture handles registration, resolution, renewal, and marketplace integration. Adapt the domain logic to your use case.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you want to build a DEX or AMM on Casper&lt;/strong&gt;, casper-trade gives you a production-tested, Halborn-audited Uniswap V2 implementation. Add new pool types, modify fee structures, build a frontend. The hard contract work is done.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you want to incorporate liquid staking functionality in your dApp&lt;/strong&gt;, liquid-staking-contracts shows you the pattern. Whether you're building a lending protocol, a yield optimizer, or anything that benefits from compounding staking rewards alongside your application's native functionality, the sCSPR token design, the staking/unstaking flow, and the reward distribution logic are all there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you need typed signatures for any cross-chain, gasless, or multi-party signing use case&lt;/strong&gt;, casper-eip-712 handles encoding, hashing, domain separation, and verification. Drop it in as a crate dependency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you're learning Odra&lt;/strong&gt;, these repos are your graduate-level coursework. Registration systems, AMMs, staking protocols, cryptographic primitives. Each demonstrates different Odra patterns in production context, with Halborn audits that serve as implicit code quality benchmarks.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Broader Picture
&lt;/h2&gt;

&lt;p&gt;When I wrote about &lt;a href="https://medium.com/@mssteuer/turns-out-we-werent-exaggerating-who-could-ve-predicated-that-ffa4b794ab65" rel="noopener noreferrer"&gt;building CSPR.guru&lt;/a&gt; a few months ago, I made the case that Casper's developer experience, powered by Odra, CSPR.click, CSPR.cloud, and the rest of MAKE's toolchain, is genuinely best-in-class. I built a full prediction market, solo, in my spare evenings, using only Casper ecosystem tools.&lt;/p&gt;

&lt;p&gt;But I also know that "best-in-class tools" means nothing if builders can't see what production-grade code looks like on your platform. Documentation gets you started. Tutorials teach you patterns. But nothing replaces reading real code that runs in production, serving real users, handling real money, and surviving a Halborn audit.&lt;/p&gt;

&lt;p&gt;That's what these repositories provide. Not examples. Not templates. Production systems with the security receipts to prove it.&lt;/p&gt;

&lt;p&gt;Four repos. Three teams. Three Halborn audits. One ecosystem.&lt;/p&gt;

&lt;p&gt;As we approach the v2.2.0 mainnet upgrade on March 23rd, with 83% of stake already staged, we're not just upgrading the protocol. We're opening the entire application layer. The code that powers Casper's DeFi infrastructure is now the same code you can fork, study, extend, and deploy.&lt;/p&gt;

&lt;p&gt;Build something.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Repositories:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/casper-ecosystem/casper-eip-712" rel="noopener noreferrer"&gt;casper-eip-712&lt;/a&gt;: EIP-712 typed signatures for Casper&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/make-software/cspr-name-contracts" rel="noopener noreferrer"&gt;cspr-name-contracts&lt;/a&gt;: CSPR.name decentralized naming protocol&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/odradev/casper-trade" rel="noopener noreferrer"&gt;casper-trade&lt;/a&gt;: Uniswap V2-style DEX for Casper&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/casper-ecosystem/liquid-staking-contracts" rel="noopener noreferrer"&gt;liquid-staking-contracts&lt;/a&gt;: Liquid staking with StakedCSPR&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Security audits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.halborn.com/audits/casper-association/make-csprname-7b1108" rel="noopener noreferrer"&gt;CSPR.name (Halborn)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.halborn.com/audits/casper-association/odradevcasper--trade-af1b5a" rel="noopener noreferrer"&gt;CSPR.trade (Halborn)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.halborn.com/audits/casper-association/odra---liquid-staking-231379" rel="noopener noreferrer"&gt;Liquid staking (Halborn)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Live products:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://cspr.name" rel="noopener noreferrer"&gt;CSPR.name&lt;/a&gt; | &lt;a href="https://cspr.trade" rel="noopener noreferrer"&gt;CSPR.trade&lt;/a&gt; | &lt;a href="https://casper.wiselending.com" rel="noopener noreferrer"&gt;Liquid Staking&lt;/a&gt; | &lt;a href="https://csprbridge.com" rel="noopener noreferrer"&gt;CSPRbridge&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Learn more:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://odra.dev/docs" rel="noopener noreferrer"&gt;Odra Framework Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.casper.network" rel="noopener noreferrer"&gt;Casper Developer Portal&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>blockchain</category>
      <category>opensource</category>
      <category>web3</category>
    </item>
    <item>
      <title>Why We Brought Ethereum's Most Important Signing Standard to Casper</title>
      <dc:creator>Michael Steuer</dc:creator>
      <pubDate>Tue, 17 Mar 2026 19:20:41 +0000</pubDate>
      <link>https://dev.to/casperblockchain/why-we-brought-ethereums-most-important-signing-standard-to-casper-38k2</link>
      <guid>https://dev.to/casperblockchain/why-we-brought-ethereums-most-important-signing-standard-to-casper-38k2</guid>
      <description>&lt;p&gt;Every blockchain that wants to play in the big leagues (cross-chain bridges, gasless transactions, AI agents moving money on your behalf) needs EIP-712. It's the standard that makes typed, domain-separated signatures possible. Ethereum figured this out years ago. Uniswap uses it. Aave uses it. OpenSea uses it. It's the plumbing behind every "approve without paying gas" interaction you've ever done on an EVM chain.&lt;/p&gt;

&lt;p&gt;Casper has it now.&lt;/p&gt;

&lt;p&gt;This isn't something we planned on a roadmap six months ago. It started the way the best infrastructure usually starts: with a security auditor telling us we had a gap. During the Halborn security audit of &lt;a href="https://csprbridge.com" rel="noopener noreferrer"&gt;CSPRbridge.com&lt;/a&gt;, our cross-chain bridge connecting Casper to EVM networks, the auditors flagged that our attestation verification was using ad-hoc signature encoding. Custom &lt;code&gt;encodePacked&lt;/code&gt;-style hashing, hand-rolled for each message type. It worked, but it was brittle, non-standard, and the kind of thing that keeps security engineers up at night.&lt;/p&gt;

&lt;p&gt;We could have patched the finding and moved on. That's what most teams do: fix the specific issue, close the ticket, ship the update. Instead, we asked ourselves: "If this is a gap in the bridge, isn't it a gap in the entire ecosystem?" The answer was yes. So we built infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Roll-Your-Own Signatures Fail
&lt;/h2&gt;

&lt;p&gt;Here's a scenario that plays out more often than anyone in crypto likes to admit. A team builds a bridge, or a cross-chain messaging protocol, or a multi-chain dApp. They need signatures: attestations that something happened on Chain A, verified on Chain B. So they roll their own encoding. They pick a hash function, concatenate some fields, maybe add a prefix. Ship it.&lt;/p&gt;

&lt;p&gt;Then someone replays a signature from testnet on mainnet. Or submits an attestation meant for the ERC-20 locker contract against the NFT bridge. Or finds that the "domain" is just the contract name hard-coded as a string, with nothing tying the signature to a specific deployment.&lt;/p&gt;

&lt;p&gt;This is what domain separation solves, and it's what the ad-hoc approach almost always gets wrong. When every project invents its own encoding, you get inconsistency, incompatibility between systems, and attack surfaces that are invisible until someone exploits them.&lt;/p&gt;

&lt;p&gt;Security auditors don't tell you what's nice to have. They tell you what will get you exploited.&lt;/p&gt;

&lt;p&gt;That Halborn audit was the catalyst. The bridge's attestation verification was using raw &lt;code&gt;keccak256&lt;/code&gt; with &lt;code&gt;encodePacked&lt;/code&gt;-style concatenation: four different hash functions, each assembling bytes manually for different message types. Functional? Yes. Standardized? No. Upgradeable without breaking every deployed relayer? Absolutely not.&lt;/p&gt;

&lt;p&gt;We decided that if we were going to fix the bridge, we'd fix it for the whole ecosystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  What EIP-712 Is and Why Ethereum Got It Right
&lt;/h2&gt;

&lt;p&gt;If you've been building on Ethereum, you've already used EIP-712, even if you didn't know it by name. Every time you've signed a "permit" in MetaMask and seen a nicely formatted breakdown of what you're approving (the token, the spender, the amount), that's EIP-712 at work.&lt;/p&gt;

&lt;p&gt;Before EIP-712, signing on Ethereum meant signing opaque byte blobs. Your wallet would show you a hex string and essentially ask: "Do you trust this?" The answer should always have been "no," but people clicked "sign" anyway. EIP-712 changed this by introducing typed structured data hashing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Human-readable in wallets.&lt;/strong&gt; Instead of a hex blob, users see the actual fields they're signing: token name, amount, recipient, deadline. The wallet can display this because the data has a schema.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Domain-separated.&lt;/strong&gt; Every signature is bound to a specific domain: a contract address, a chain ID, a protocol version. A signature for Uniswap on Ethereum mainnet cannot be replayed against a copycat contract on Arbitrum. The domain is baked into the hash.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Machine-verifiable.&lt;/strong&gt; Smart contracts can reconstruct the exact hash from the typed data, recover the signer, and verify the authorization on-chain. No ambiguity, no parsing, no custom deserialization logic.&lt;/p&gt;

&lt;p&gt;This combination is why EIP-712 became the backbone of gasless approvals (ERC-2612), meta-transactions, and most of modern DeFi's authorization infrastructure. Uniswap's Permit2 uses it to let users approve token spending with a signature instead of a transaction. Aave uses it for credit delegation. OpenSea used it for gasless NFT listings. The pattern is always the same: user signs structured data off-chain, contract verifies on-chain, and the domain separator ensures that signature can't be replayed anywhere it wasn't intended.&lt;/p&gt;

&lt;p&gt;It's not just a convenience. It's a security primitive. And it's the kind of standard that separates blockchains that are ready for real-world financial applications from those that aren't.&lt;/p&gt;

&lt;p&gt;If you're building on Casper, you're about to start using it too.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4afdhb3yk6qfu4i642fu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4afdhb3yk6qfu4i642fu.jpg" alt="Architecture diagram — EIP-712 signing flow: User signs typed data off-chain (zero cost) → Relayer submits to Casper contract → Contract verifies signature, recovers signer, executes action" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How We Brought EIP-712 to Casper
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/casper-ecosystem/casper-eip-712" rel="noopener noreferrer"&gt;&lt;code&gt;casper-eip-712&lt;/code&gt;&lt;/a&gt; is a &lt;code&gt;no_std&lt;/code&gt;-compatible Rust crate that brings the full EIP-712 toolkit to Casper. It gives you domain construction, typed struct hashing, encoding helpers, and optional secp256k1 signer recovery. Everything you need to implement the same signature patterns that power the EVM ecosystem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building a Domain
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;DomainBuilder&lt;/code&gt; supports both standard EVM fields and Casper-native extensions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;casper_eip_712&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// EVM-compatible domain, interoperable with ethers.js and MetaMask&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;DomainBuilder&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"MyToken"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.chain_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.verifying_contract&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;0x11&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="nf"&gt;.build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Casper-native domain: uses chain_name and contract_package_hash&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;DomainBuilder&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Bridge"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.custom_field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"chain_name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;DomainFieldValue&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"casper-test"&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
    &lt;span class="nf"&gt;.custom_field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"contract_package_hash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;DomainFieldValue&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Bytes32&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;0x99&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
    &lt;span class="nf"&gt;.build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7rrhuw0b3gvbe8ecs8q6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7rrhuw0b3gvbe8ecs8q6.jpg" alt="Domain separator comparison" width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That dual-domain support is intentional. If you're building a bridge that verifies Ethereum-origin signatures, use the EVM-compatible domain. If you're building a Casper-native dApp and want domain fields that make sense for Casper (like &lt;code&gt;chain_name&lt;/code&gt; and &lt;code&gt;contract_package_hash&lt;/code&gt; instead of integer chain IDs and 20-byte addresses), use the custom fields. Same hashing algorithm, same security properties, native semantics for each chain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Defining Custom Typed Structs
&lt;/h3&gt;

&lt;p&gt;Any struct can be EIP-712 hashable by implementing the &lt;code&gt;Eip712Struct&lt;/code&gt; trait:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Attestation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;claim_hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Eip712Struct&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Attestation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;type_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"Attestation(address subject,bytes32 claim_hash)"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;type_hash&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;keccak256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;type_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.as_bytes&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;encode_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_capacity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="nf"&gt;.extend_from_slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nf"&gt;encode_address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.subject&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="nf"&gt;.extend_from_slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nf"&gt;encode_bytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.claim_hash&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;out&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then hashing is one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;digest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;hash_typed_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;attestation&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The crate ships with prebuilt &lt;code&gt;Permit&lt;/code&gt;, &lt;code&gt;Approval&lt;/code&gt;, and &lt;code&gt;Transfer&lt;/code&gt; structs for common patterns, so you don't have to implement these yourself for standard use cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Design Decisions
&lt;/h3&gt;

&lt;p&gt;A few things worth noting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;no_std&lt;/code&gt; + &lt;code&gt;alloc&lt;/code&gt;&lt;/strong&gt;: The crate is designed for WASM-based contract targets. It works inside Casper smart contracts without pulling in &lt;code&gt;std&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optional &lt;code&gt;verify&lt;/code&gt; feature&lt;/strong&gt;: Enable &lt;code&gt;verify&lt;/code&gt; in your &lt;code&gt;Cargo.toml&lt;/code&gt; to get secp256k1 signer recovery via &lt;code&gt;k256&lt;/code&gt;. Leave it off if you only need hashing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Framework-agnostic&lt;/strong&gt;: We built &lt;code&gt;casper-eip-712&lt;/code&gt; as a standalone Rust crate, not as a module for any specific framework. This was intentional: any Casper contract can use it, regardless of tooling. But since most contracts on Casper today are developed using &lt;a href="https://odra.dev" rel="noopener noreferrer"&gt;Odra&lt;/a&gt;, the rapid-development smart contracting framework, we made sure it integrates seamlessly. Add it to your &lt;code&gt;Cargo.toml&lt;/code&gt;, import the prelude, and you're signing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Real-World Usage: The Bridge
&lt;/h2&gt;

&lt;p&gt;Remember that Halborn audit? Here's the payoff.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://csprbridge.com" rel="noopener noreferrer"&gt;CSPRbridge.com&lt;/a&gt; cross-chain bridge connects Casper to EVM networks. Its core security mechanism is multi-relayer attestation: when tokens move between chains, a threshold of relayers must sign an attestation confirming the transaction. The Casper-side contract then verifies these signatures before minting or releasing tokens.&lt;/p&gt;

&lt;p&gt;Before &lt;code&gt;casper-eip-712&lt;/code&gt;, this verification used hand-rolled encoding: four separate hash functions in &lt;code&gt;crypto.rs&lt;/code&gt;, each manually assembling bytes with &lt;code&gt;keccak256&lt;/code&gt; and &lt;code&gt;encodePacked&lt;/code&gt;-style concatenation. Each one was correct for its specific message type, but each was also bespoke. No shared schema. No domain binding per deployment. No way for a wallet or monitoring tool to introspect what was being signed.&lt;/p&gt;

&lt;p&gt;The audit identified the gap: signatures weren't bound to a specific contract deployment. An attestation for one bridge instance could theoretically be replayed against another. It also flagged the lack of a standardized encoding scheme, which made the system harder to audit, harder to extend, and harder to reason about.&lt;/p&gt;

&lt;p&gt;We didn't just patch the finding. We built infrastructure so that every project on Casper gets this right by default. The bridge is migrating its attestation verification to &lt;code&gt;casper-eip-712&lt;/code&gt;, binding every signature to a specific chain, contract, and protocol version. What used to be four custom hash functions becomes one standard pattern. And critically, any new message type the bridge needs to support (new token standards, new cross-chain operations) follows the same trait implementation. Add your struct, implement &lt;code&gt;Eip712Struct&lt;/code&gt;, and the hashing, encoding, and verification are handled.&lt;/p&gt;

&lt;p&gt;This is what I mean when I say we built infrastructure, not a patch. The next team that builds a bridge, an oracle, or any system that needs cross-chain attestations on Casper doesn't have to solve this problem again.&lt;/p&gt;

&lt;h2&gt;
  
  
  The TypeScript Companion
&lt;/h2&gt;

&lt;p&gt;Smart contracts verify signatures. But someone has to create them first, and that someone is usually a frontend developer writing TypeScript.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/@casper-ecosystem/casper-eip-712" rel="noopener noreferrer"&gt;&lt;code&gt;@casper-ecosystem/casper-eip-712&lt;/code&gt;&lt;/a&gt; is the TypeScript mirror of the Rust crate. It provides the same domain construction, type hashing, and encoding functions, plus signer recovery for client-side verification:&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;hashTypedData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;recoverTypedDataSigner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;PermitTypes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;EIP712Domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PermitMessage&lt;/span&gt;&lt;span class="p"&gt;,&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="s2"&gt;@casper-ecosystem/casper-eip-712&lt;/span&gt;&lt;span class="dl"&gt;"&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;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EIP712Domain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PermitToken&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;chainId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1314614895&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;verifyingContract&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;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;permit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PermitMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;spender&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;spenderAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;padStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;nonce&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;deadline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xffffffff&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;padStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Sign with ethers.js, standard Ethereum tooling&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;signature&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;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;signTypedData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PermitTypes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;permitPayload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Verify locally before submitting to chain&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;digest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;hashTypedData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PermitTypes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Permit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;permit&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;recovered&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;recoverTypedDataSigner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PermitTypes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Permit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;permit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sigBytes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Frontend devs don't need to touch Rust. The TypeScript package produces the exact same hashes and digests as the Rust crate, verified by shared test vectors generated from a single source of truth. Sign in the browser, verify on Casper.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo: The Permit/Approve Pattern in Action
&lt;/h2&gt;

&lt;p&gt;Talk is cheap. Let me show you.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/casper-ecosystem/casper-eip-712/tree/master/examples/permit-token" rel="noopener noreferrer"&gt;&lt;code&gt;examples/permit-token&lt;/code&gt;&lt;/a&gt; directory contains a complete working CEP-18 token with gasless permit/approve, the same pattern that powers Uniswap's token approvals, now running on Casper.&lt;/p&gt;

&lt;p&gt;Here's what happens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A user signs a Permit off-chain&lt;/strong&gt; using standard Ethereum tooling (ethers.js &lt;code&gt;signTypedData&lt;/code&gt;). Zero cost. No transaction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A relayer submits the signature&lt;/strong&gt; to the Casper contract, paying the deploy cost on the user's behalf.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The contract verifies the EIP-712 signature&lt;/strong&gt;, recovers the signer's Ethereum address, checks the nonce and deadline, and writes the token allowance. All without the token owner ever submitting a transaction.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The demo is a CEP-18 token built with &lt;a href="https://odra.dev" rel="noopener noreferrer"&gt;Odra&lt;/a&gt;. The EIP-712 permit pattern drops in as a regular crate dependency. No special adapters, no glue code. Odra handles the smart contract scaffolding; &lt;code&gt;casper-eip-712&lt;/code&gt; handles the cryptographic verification.&lt;/p&gt;

&lt;p&gt;Run the Rust tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;examples/permit-token
cargo odra &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the TypeScript demo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;js &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run build &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;span class="nb"&gt;cd &lt;/span&gt;examples/permit-token/demo
npm &lt;span class="nb"&gt;install
&lt;/span&gt;npx tsx demo.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can run this demo without a Casper node. Right now. Go.&lt;/p&gt;

&lt;p&gt;The TypeScript demo generates a keypair, signs a permit using ethers.js, verifies it client-side with our TypeScript package, and shows you exactly what the on-chain contract call would look like: the 65-byte signature, the reconstructed digest, and the recovered signer address. The Rust integration tests do the full round-trip inside an Odra test environment: deploy the contract, sign a permit, submit it, verify the allowance was set, and confirm that invalid signatures, expired deadlines, and replayed nonces are rejected.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Unlocks for Casper
&lt;/h2&gt;

&lt;p&gt;I didn't write a Rust crate because I was bored on a Saturday night. (Well, partially. But mostly for what it enables.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Gasless Transactions and Relayer Services
&lt;/h3&gt;

&lt;p&gt;The number one UX barrier in crypto is "buy gas first." A new user wants to use your dApp. They don't own CSPR. Under the current model, they bounce. With EIP-712 permits and a relayer service, that user signs an authorization off-chain (free) and the relayer submits it on their behalf, paying the deploy cost. The user interacts with Casper without ever acquiring CSPR upfront. This is how you onboard the next million users. By not asking them to figure out gas fees before they can do anything useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agentic Commerce via x402
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://www.x402.org/" rel="noopener noreferrer"&gt;x402 protocol&lt;/a&gt; is enabling AI agents to pay for API access and services using HTTP 402 payment flows with stablecoins. Think about that for a second. Autonomous agents, making purchasing decisions, signing payment authorizations. EIP-712 is the natural signing layer for this: structured, domain-separated, human-auditable authorizations that smart contracts can verify. As x402 comes to Casper, &lt;code&gt;casper-eip-712&lt;/code&gt; provides the cryptographic foundation for agents to sign verifiable, scoped authorizations. Not opaque byte blobs. Typed, structured data with clear semantics that a compliance system, a monitoring tool, or a human can read and understand.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cross-Chain Interoperability
&lt;/h3&gt;

&lt;p&gt;In a multi-chain world, domain separation isn't a nice-to-have. It's a security requirement. A signature for your mainnet bridge deployment must not be valid against your testnet deployment. An attestation for the ERC-20 locker must not work against the NFT bridge. &lt;code&gt;casper-eip-712&lt;/code&gt;'s &lt;code&gt;DomainBuilder&lt;/code&gt; supports hybrid environments natively: EVM-standard fields for Ethereum-origin signatures, Casper-native fields for Casper-native protocols, and the flexibility to mix custom fields for whatever your architecture needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Batch Authorization
&lt;/h3&gt;

&lt;p&gt;A relayer collects signed permits from multiple users and submits them in a single deploy. Users get instant, gasless interactions. The relayer amortizes deploy costs. Smart contracts verify each signature independently. This pattern is already standard on Ethereum (Uniswap's Permit2, for example). Now it works on Casper.&lt;/p&gt;

&lt;h3&gt;
  
  
  Non-Crypto-Native Onboarding
&lt;/h3&gt;

&lt;p&gt;Let's be blunt: the current onboarding flow for most blockchain applications is terrible. I &lt;a href="https://dev.to/csprsuite/enabling-web3-adoption-with-cspr-click-8c551875985a"&gt;wrote about this extensively&lt;/a&gt;: the "connect your wallet" gauntlet, the gas token requirement, the 24-word seed phrase anxiety. EIP-712 is a key piece of the puzzle for fixing this. Combined with a relayer architecture, you can build Casper dApps where the user never sees a wallet popup, never buys gas, and never knows they're interacting with a blockchain. They sign a message, a message they can actually read and understand, and the relayer handles the rest. That's the user experience that gets us from 420 million crypto users to a billion.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Big Picture
&lt;/h3&gt;

&lt;p&gt;This isn't just a library. It's a building block that positions Casper to compete for the next wave of adoption, the wave where users don't know they're using a blockchain, and AI agents transact on their behalf. Gasless UX, agentic commerce, cross-chain interop, batch transactions: these are the patterns that the most successful chains will support natively. &lt;code&gt;casper-eip-712&lt;/code&gt; gives Casper that foundation.&lt;/p&gt;

&lt;p&gt;When I look at where crypto is headed (account abstraction, intent-based architectures, agent-driven commerce), every one of those paths runs through structured, domain-separated signing. We're not building for where blockchain is today. We're building for where it's going.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build With Us
&lt;/h2&gt;

&lt;p&gt;The crate is open source, published, and ready to use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/casper-ecosystem/casper-eip-712" rel="noopener noreferrer"&gt;casper-ecosystem/casper-eip-712&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rust Crate:&lt;/strong&gt; &lt;a href="https://crates.io/crates/casper-eip-712" rel="noopener noreferrer"&gt;crates.io/crates/casper-eip-712&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NPM Package:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/@casper-ecosystem/casper-eip-712" rel="noopener noreferrer"&gt;@casper-ecosystem/casper-eip-712&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rust Docs:&lt;/strong&gt; &lt;a href="https://docs.rs/casper-eip-712/1.0.0/casper_eip_712/" rel="noopener noreferrer"&gt;docs.rs/casper-eip-712&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Working Demo:&lt;/strong&gt; &lt;a href="https://github.com/casper-ecosystem/casper-eip-712/tree/master/examples/permit-token" rel="noopener noreferrer"&gt;examples/permit-token&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're building on Casper, use it. If you're building on Ethereum and wondering what else is out there, try it. The signatures are the same.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
      <category>ethereum</category>
      <category>rust</category>
    </item>
  </channel>
</rss>
