<?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: Wallet Guy</title>
    <description>The latest articles on DEV Community by Wallet Guy (@walletguy).</description>
    <link>https://dev.to/walletguy</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3839576%2Fca8024e8-c8ac-4f6a-845c-e8ad44732a67.jpeg</url>
      <title>DEV Community: Wallet Guy</title>
      <link>https://dev.to/walletguy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/walletguy"/>
    <language>en</language>
    <item>
      <title>RATE_LIMIT Policy: Prevent Your DeFi Bot from Getting Rekt by MEV</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Sun, 11 Oct 2026 18:01:29 +0000</pubDate>
      <link>https://dev.to/walletguy/ratelimit-policy-prevent-your-defi-bot-from-getting-rekt-by-mev-35c7</link>
      <guid>https://dev.to/walletguy/ratelimit-policy-prevent-your-defi-bot-from-getting-rekt-by-mev-35c7</guid>
      <description>&lt;h1&gt;
  
  
  RATE_LIMIT Policy: Prevent Your DeFi Bot from Getting Rekt by MEV
&lt;/h1&gt;

&lt;p&gt;Your DeFi bot is firing transactions faster than you can monitor them — and without rate limiting baked into your wallet infrastructure, you're not just vulnerable to MEV, you're handing over free money to every searcher watching the mempool. Whether you're running an arb loop, a liquidation bot, or a multi-protocol yield strategy, uncontrolled transaction velocity is one of the fastest ways to blow up a wallet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Transaction Rate Control Is a First-Class Problem
&lt;/h2&gt;

&lt;p&gt;Here's a scenario most bot builders have lived through: your arb strategy detects a pricing discrepancy between two DEX pools. Your bot fires. Then fires again. Then fires a third time because the first confirmation hasn't landed yet and your loop hasn't exited. You've just broadcast three competing transactions from the same wallet, front-run yourself, and paid gas on all three — two of which reverted.&lt;/p&gt;

&lt;p&gt;MEV bots didn't steal that trade. You handed it to them.&lt;/p&gt;

&lt;p&gt;Rate limiting at the infrastructure level — not just in your application code — is the difference between a bot that survives market volatility and one that drains itself dry during a busy block. Application-level rate limiting is fragile: a restart, a race condition, a missed exception handler, and your throttle is gone. You need the wallet itself to enforce limits, independent of whatever application logic is running above it.&lt;/p&gt;

&lt;p&gt;This is where WAIaaS's &lt;code&gt;RATE_LIMIT&lt;/code&gt; policy comes in.&lt;/p&gt;

&lt;h2&gt;
  
  
  What RATE_LIMIT Actually Does
&lt;/h2&gt;

&lt;p&gt;WAIaaS has a policy engine with 21 policy types and 4 security tiers: &lt;code&gt;INSTANT&lt;/code&gt;, &lt;code&gt;NOTIFY&lt;/code&gt;, &lt;code&gt;DELAY&lt;/code&gt;, and &lt;code&gt;APPROVAL&lt;/code&gt;. The &lt;code&gt;RATE_LIMIT&lt;/code&gt; policy caps how many transactions your wallet can submit within a given period — and it enforces this at the daemon level, before execution, inside the 7-stage transaction pipeline.&lt;/p&gt;

&lt;p&gt;That means no matter what your bot code does — whether it crashes and restarts in a loop, has a logic bug that triggers duplicate sends, or gets compromised and starts spamming — the wallet will hard-stop once the rate limit is hit.&lt;/p&gt;

&lt;p&gt;The policy configuration is simple:&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="nl"&gt;"maxTransactions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"period"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hourly"&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;You set the max number of transactions allowed per period, and any submission beyond that gets rejected with a structured error before it ever touches the chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up RATE_LIMIT for Your Trading Bot
&lt;/h2&gt;

&lt;p&gt;First, you need a wallet. Here's the full flow from zero to rate-limited bot wallet using the REST API:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create the wallet:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/wallets &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"name": "trading-wallet", "chain": "solana", "environment": "mainnet"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Create a session for your bot:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/sessions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"walletId": "&amp;lt;wallet-uuid&amp;gt;"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Apply the RATE_LIMIT policy:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "RATE_LIMIT",
    "rules": {
      "maxTransactions": 10,
      "period": "hourly"
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ten transactions per hour is a conservative starting point. For a high-frequency arb bot you might push that higher. For a yield rebalancer that only needs to act a few times a day, you'd set it lower. The point is that it's explicit, enforced at the wallet level, and observable.&lt;/p&gt;

&lt;p&gt;When your bot hits the limit, it gets a structured error response — not a chain revert, not a silent failure:&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;"error"&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;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POLICY_DENIED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Transaction denied by RATE_LIMIT policy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POLICY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"retryable"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&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;Your bot can catch this, log it, and back off — rather than spiraling into a retry loop that chews through gas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layering RATE_LIMIT With SPENDING_LIMIT for Compound Protection
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;RATE_LIMIT&lt;/code&gt; controls frequency. &lt;code&gt;SPENDING_LIMIT&lt;/code&gt; controls size. Used together, they give you two independent axes of risk control — and WAIaaS's policy engine applies both simultaneously.&lt;/p&gt;

&lt;p&gt;Here's a &lt;code&gt;SPENDING_LIMIT&lt;/code&gt; policy configured for a trading bot wallet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 100,
      "notify_max_usd": 500,
      "delay_max_usd": 2000,
      "delay_seconds": 900,
      "daily_limit_usd": 5000
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this configuration, the 4-tier logic works like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Under $100 → &lt;code&gt;INSTANT&lt;/code&gt;: executes immediately, no notification&lt;/li&gt;
&lt;li&gt;$100–$500 → &lt;code&gt;NOTIFY&lt;/code&gt;: executes immediately, but you get an alert&lt;/li&gt;
&lt;li&gt;$500–$2000 → &lt;code&gt;DELAY&lt;/code&gt;: queued for 15 minutes, cancellable&lt;/li&gt;
&lt;li&gt;Over $2000 → &lt;code&gt;APPROVAL&lt;/code&gt;: requires human sign-off via WalletConnect or push notification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a trading bot, this means your routine small swaps execute at full speed, while anything anomalously large trips the delay or approval gate. If a bug in your bot logic generates a massive unexpected trade, it doesn't execute immediately — you have a window to intervene.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gas Conditional Execution: Don't Trade When It's Expensive
&lt;/h2&gt;

&lt;p&gt;Beyond rate limiting, WAIaaS has gas conditional execution built into its transaction pipeline. Transactions execute only when gas price meets your configured threshold.&lt;/p&gt;

&lt;p&gt;For Solana bots on Jupiter this is less of a concern, but for EVM bots — especially anything interacting with Aave, Pendle, or Hyperliquid on Ethereum-based chains — gas timing can make or break a strategy. An arb that's profitable at 20 gwei becomes a loss at 80 gwei.&lt;/p&gt;

&lt;p&gt;Gas-conditional execution gives your bot a structural filter: it only fires when execution cost is within your acceptable range.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multi-Protocol Access: One Wallet, 15 DeFi Integrations
&lt;/h2&gt;

&lt;p&gt;The other reason to run your trading infrastructure through WAIaaS is the breadth of DeFi protocol access. WAIaaS integrates 15 DeFi protocol providers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Jupiter&lt;/strong&gt; (Solana DEX aggregation)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drift&lt;/strong&gt; (Solana perpetuals)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hyperliquid&lt;/strong&gt; (perpetual futures, spot trading, sub-accounts)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aave V3&lt;/strong&gt; (lending/borrowing)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kamino&lt;/strong&gt; (Solana lending)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LI.FI + Across&lt;/strong&gt; (cross-chain bridging)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lido + Jito&lt;/strong&gt; (liquid staking)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;0x + D'CENT swap&lt;/strong&gt; (EVM DEX aggregation)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pendle&lt;/strong&gt; (yield trading)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Polymarket&lt;/strong&gt; (prediction markets)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;XRP Ledger DEX&lt;/strong&gt; (XRPL native DEX)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ERC-8004&lt;/strong&gt; (onchain agent reputation)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A multi-leg strategy — say, borrow on Aave, swap on 0x, bridge via LI.FI, then stake the output on Lido — runs through a single wallet, a single session token, and a single policy set. You're not managing credentials and rate limits across five different integrations.&lt;/p&gt;

&lt;p&gt;Here's what a Jupiter swap looks like through the API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/actions/jupiter-swap/swap &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_&amp;lt;token&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "inputMint": "So11111111111111111111111111111111111111112",
    "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "amount": "1000000000"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a SOL → USDC swap. The wallet handles signing, the policy engine checks it against your &lt;code&gt;RATE_LIMIT&lt;/code&gt; and &lt;code&gt;SPENDING_LIMIT&lt;/code&gt; rules, and the transaction goes out — or gets blocked, depending on your configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dry-Run Before You Execute
&lt;/h2&gt;

&lt;p&gt;Before your bot goes live, or before you commit to a trade in a new market condition, simulate it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/transactions/send &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_&amp;lt;token&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "type": "TRANSFER",
    "to": "recipient-address",
    "amount": "0.1",
    "dryRun": true
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;dryRun&lt;/code&gt; flag runs the transaction through the full 7-stage pipeline — including policy evaluation — without hitting the chain. You can verify that your bot's intended transaction would pass your rate limit, spending limit, token whitelist, and contract whitelist before committing real funds.&lt;/p&gt;

&lt;p&gt;This is especially useful during strategy development: wire up your bot logic, run it in dry-run mode under load, and see exactly which transactions would have been blocked and why.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start: Bot Wallet With Rate Limiting in 5 Steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install the CLI and start the daemon&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&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; &lt;span class="nt"&gt;-g&lt;/span&gt; @waiaas/cli
waiaas init
waiaas start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a dedicated trading wallet&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/wallets &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"name": "trading-wallet", "chain": "solana", "environment": "mainnet"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a session token for your bot&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/sessions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"walletId": "&amp;lt;wallet-uuid&amp;gt;"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Apply RATE_LIMIT and SPENDING_LIMIT policies&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Rate limit: 10 transactions per hour&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "RATE_LIMIT",
    "rules": {"maxTransactions": 10, "period": "hourly"}
  }'&lt;/span&gt;

&lt;span class="c"&gt;# Spending limit: tiered security by transaction size&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 100,
      "notify_max_usd": 500,
      "delay_max_usd": 2000,
      "delay_seconds": 900,
      "daily_limit_usd": 5000
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Run your first dry-run trade to verify policies are working&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/transactions/send &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_&amp;lt;token&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"type": "TRANSFER", "to": "recipient-address", "amount": "0.1", "dryRun": true}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Infrastructure Layer Your Bot Actually Needs
&lt;/h2&gt;

&lt;p&gt;The pattern here isn't complicated, but it's easy to skip when you're moving fast: enforce your risk rules at the infrastructure level, not in application code. Application code restarts, has bugs, and gets updated. A wallet-level policy enforced inside a 7-stage transaction pipeline before execution is a harder guarantee.&lt;/p&gt;

&lt;p&gt;WAIaaS gives you 21 policy types to work with — rate limits, spending tiers, token whitelists, contract whitelists, network restrictions, venue whitelists, and more. For a trading bot, you'd typically combine &lt;code&gt;RATE_LIMIT&lt;/code&gt; + &lt;code&gt;SPENDING_LIMIT&lt;/code&gt; + &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt; + &lt;code&gt;CONTRACT_WHITELIST&lt;/code&gt; to get a wallet that can only do exactly what your strategy requires, at the frequency and size your risk parameters allow.&lt;/p&gt;

&lt;p&gt;The policy engine enforces default-deny: if &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt; or &lt;code&gt;CONTRACT_WHITELIST&lt;/code&gt; isn't configured, those transaction types are blocked. Your bot can't accidentally interact with a contract you didn't explicitly whitelist.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The full policy engine documentation, including all 21 policy types and their configuration schemas, is available via the interactive API reference at &lt;code&gt;http://127.0.0.1:3100/reference&lt;/code&gt; once your daemon is running. For connecting your bot to Claude or other LLM-based agent frameworks, the 45 MCP tools in &lt;code&gt;@waiaas/mcp&lt;/code&gt; cover the full trading surface — from balance queries to DeFi position management.&lt;/p&gt;

&lt;p&gt;Check out the codebase and open issues on GitHub, and find the full documentation on the official site:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/waiaas/WAIaaS" rel="noopener noreferrer"&gt;https://github.com/waiaas/WAIaaS&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Official site:&lt;/strong&gt; &lt;a href="https://waiaas.ai" rel="noopener noreferrer"&gt;https://waiaas.ai&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>defi</category>
      <category>security</category>
      <category>trading</category>
      <category>policy</category>
    </item>
    <item>
      <title>CLI Session Hardening: TTL, Renewals, and Emergency Disconnection for Self-Hosted Wallets</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Sun, 11 Oct 2026 13:05:18 +0000</pubDate>
      <link>https://dev.to/walletguy/cli-session-hardening-ttl-renewals-and-emergency-disconnection-for-self-hosted-wallets-17ml</link>
      <guid>https://dev.to/walletguy/cli-session-hardening-ttl-renewals-and-emergency-disconnection-for-self-hosted-wallets-17ml</guid>
      <description>&lt;h1&gt;
  
  
  CLI Session Hardening: TTL, Renewals, and Emergency Disconnection for Self-Hosted Wallets
&lt;/h1&gt;

&lt;p&gt;Would you trust a third party with your AI agent's private keys? If you're running autonomous agents that move real money, the answer shapes everything about how you architect your setup. Self-hosted wallet infrastructure gives you something no hosted service can: the ability to define, inspect, and enforce exactly how long an AI agent's access lasts — and to kill that access instantly when something goes wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Session Hygiene Matters When Agents Hold Value
&lt;/h2&gt;

&lt;p&gt;There's a meaningful difference between an AI agent that &lt;em&gt;can&lt;/em&gt; access a wallet and one that &lt;em&gt;should&lt;/em&gt; — and that difference is time.&lt;/p&gt;

&lt;p&gt;Hosted wallet services abstract this away, which is convenient until it isn't. If an agent session token is long-lived and you don't control the server, a compromised token is someone else's problem to revoke. When you self-host, the session lifecycle is entirely yours. You decide when a token expires, whether it can be renewed, and how hard the ceiling is. And when you need to pull the plug — because the agent behaved unexpectedly, or you just want to sleep soundly — you can do it from your own terminal, against your own server, with no support ticket required.&lt;/p&gt;

&lt;p&gt;WAIaaS (Wallet-as-a-Service for AI agents) is an open-source, self-hosted daemon built around this philosophy. Your keys live on your server. Your policies run on your server. Your session rules are enforced on your server.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three Auth Layers You're Actually Working With
&lt;/h2&gt;

&lt;p&gt;Before diving into session hardening specifically, it helps to understand the three authentication roles in WAIaaS, because they serve different principals with different levels of trust.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;masterAuth&lt;/strong&gt; is the system administrator credential, used with &lt;code&gt;X-Master-Password&lt;/code&gt;. It can create wallets, manage sessions, and set policies. This is the credential you use at setup time and keep locked away.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;sessionAuth&lt;/strong&gt; is what your AI agent carries around — a JWT token prefixed &lt;code&gt;wai_sess_&lt;/code&gt;. This is the credential that actually moves money. It's scoped to a single wallet and constrained by whatever policies and TTL you configure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ownerAuth&lt;/strong&gt; is for the human fund owner — the person who approves high-value transactions or issues a kill switch. It uses cryptographic signatures (Ed25519 or secp256k1) rather than a shared password.&lt;/p&gt;

&lt;p&gt;The session layer is where most of your day-to-day hardening happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a Session with Explicit Lifetime
&lt;/h2&gt;

&lt;p&gt;Creating a session is a single API call with masterAuth:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/sessions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"walletId": "&amp;lt;wallet-uuid&amp;gt;"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WAIaaS supports per-session TTL, &lt;code&gt;maxRenewals&lt;/code&gt;, and &lt;code&gt;absoluteLifetime&lt;/code&gt; configuration. This means you can create a session that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Expires after a short window (TTL)&lt;/li&gt;
&lt;li&gt;Can be renewed by the agent up to N times (&lt;code&gt;maxRenewals&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Has a hard ceiling it can never cross (&lt;code&gt;absoluteLifetime&lt;/code&gt;), regardless of renewals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The practical effect: an agent can keep itself alive during a long trading run by renewing its own session, but it cannot extend that access indefinitely. When &lt;code&gt;absoluteLifetime&lt;/code&gt; hits, the session is dead and the agent must come back to a human (or an automated provisioning system) for a new one.&lt;/p&gt;

&lt;p&gt;This is the crypto equivalent of issuing a contractor a keycard that works for 8 hours, auto-renews if they badge in before expiry, but physically deactivates at midnight no matter what.&lt;/p&gt;

&lt;h2&gt;
  
  
  The CLI Owns Your Session Workflow
&lt;/h2&gt;

&lt;p&gt;WAIaaS ships a CLI with 20 commands. The session-relevant ones are what you'll reach for most:&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; &lt;span class="nt"&gt;-g&lt;/span&gt; @waiaas/cli
waiaas init          &lt;span class="c"&gt;# Initialize config directory&lt;/span&gt;
waiaas start         &lt;span class="c"&gt;# Start the daemon&lt;/span&gt;
waiaas quickset      &lt;span class="c"&gt;# Create wallets + sessions in one step&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For day-to-day operations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;waiaas session prompt    &lt;span class="c"&gt;# Interactive session management&lt;/span&gt;
waiaas status            &lt;span class="c"&gt;# Check daemon status&lt;/span&gt;
waiaas owner status      &lt;span class="c"&gt;# Check owner connection state&lt;/span&gt;
waiaas owner disconnect  &lt;span class="c"&gt;# Disconnect the owner approval channel&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;waiaas quickset&lt;/code&gt; command is worth calling out specifically. If you want wallets created and MCP session tokens generated in a single step — without manually stitching together API calls — &lt;code&gt;quickset&lt;/code&gt; handles that. For self-hosters who want to go from "fresh Docker volume" to "agent has a working token" in under two minutes, this is the path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Emergency Disconnection: The Kill Switch
&lt;/h2&gt;

&lt;p&gt;Here's the scenario: your agent starts behaving oddly — maybe it's submitting transactions you didn't expect, or your logs show something you don't understand. You want to stop it &lt;em&gt;now&lt;/em&gt;, not after you've found the right API endpoint in documentation at 2am.&lt;/p&gt;

&lt;p&gt;WAIaaS's security architecture includes three layers. The first is session auth — time-limited tokens that constrain normal operation. The second is time delay plus approval — transactions above your configured threshold get queued and require human sign-off before execution. The third is monitoring and kill switch.&lt;/p&gt;

&lt;p&gt;The kill switch is operated via ownerAuth. If you have WalletConnect connected (via &lt;code&gt;waiaas owner connect&lt;/code&gt;), you can approve or reject pending transactions from your phone. More relevantly here: you can disconnect and revoke access through the owner channel entirely.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;waiaas owner disconnect   &lt;span class="c"&gt;# Disconnect owner approval channel&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For pending transactions that already hit the APPROVAL tier, the ownerAuth endpoint lets you reject them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/transactions/&amp;lt;tx-id&amp;gt;/approve &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Owner-Signature: &amp;lt;ed25519-or-secp256k1-signature&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Owner-Message: &amp;lt;signed-message&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rejection works the same way — the ownerAuth endpoint handles both approval and denial of queued transactions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Policy as a Second Line of Defense
&lt;/h2&gt;

&lt;p&gt;Session TTL handles &lt;em&gt;when&lt;/em&gt; access expires. Policies handle &lt;em&gt;what&lt;/em&gt; the agent can do while access is active. These two systems work together.&lt;/p&gt;

&lt;p&gt;The policy engine has 21 policy types and 4 security tiers: INSTANT, NOTIFY, DELAY, and APPROVAL. The default is deny — if you haven't explicitly allowed a token or contract, the transaction is blocked.&lt;/p&gt;

&lt;p&gt;A minimal spending policy looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 100,
      "notify_max_usd": 500,
      "delay_max_usd": 2000,
      "delay_seconds": 900,
      "daily_limit_usd": 5000
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this configuration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Under $100: executes immediately&lt;/li&gt;
&lt;li&gt;$100–$500: executes and sends a notification&lt;/li&gt;
&lt;li&gt;$500–$2,000: queued for 15 minutes, cancellable during that window&lt;/li&gt;
&lt;li&gt;Over $2,000: requires explicit owner approval&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Combined with a short session TTL and &lt;code&gt;maxRenewals&lt;/code&gt;, this means even a fully autonomous agent is operating inside a box with hard walls on both time and value. If the agent misbehaves, the DELAY tier gives you a window to cancel before anything executes. The APPROVAL tier means certain actions simply cannot happen without a human.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dry-Run Before You Commit
&lt;/h2&gt;

&lt;p&gt;One underrated tool for self-hosters: the dry-run API. Before your agent goes live, you can simulate any transaction to see how the policy engine would respond — without broadcasting anything to a blockchain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/transactions/send &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_&amp;lt;token&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "type": "TRANSFER",
    "to": "recipient-address",
    "amount": "0.1",
    "dryRun": true
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is how you validate your policy configuration before exposing a session token to an agent. Run a dry-run at $50, $150, $600, $2,100 — confirm each hits the tier you intended. If a &lt;code&gt;POLICY_DENIED&lt;/code&gt; comes back when you expected &lt;code&gt;INSTANT&lt;/code&gt;, you know your &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt; policy isn't configured yet.&lt;/p&gt;

&lt;p&gt;The error format is machine-readable, so agents can inspect why a transaction was rejected:&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;"error"&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;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POLICY_DENIED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Transaction denied by SPENDING_LIMIT policy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POLICY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"retryable"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&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;h2&gt;
  
  
  Getting a Self-Hosted Instance Running
&lt;/h2&gt;

&lt;p&gt;If you want to try this on your own hardware, the Docker path is the fastest:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Clone and start&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/waiaas/WAIaaS.git
&lt;span class="nb"&gt;cd &lt;/span&gt;WAIaaS
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The daemon binds to &lt;code&gt;127.0.0.1:3100&lt;/code&gt; by default — it's not publicly accessible unless you explicitly expose it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Auto-provision for a passwordless first start&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; waiaas &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 127.0.0.1:3100:3100 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; waiaas-data:/data &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;WAIAAS_AUTO_PROVISION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  ghcr.io/waiaas/waiaas:latest

docker &lt;span class="nb"&gt;exec &lt;/span&gt;waiaas &lt;span class="nb"&gt;cat&lt;/span&gt; /data/recovery.key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Install the CLI and initialize&lt;/strong&gt;&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; &lt;span class="nt"&gt;-g&lt;/span&gt; @waiaas/cli
waiaas init
waiaas quickset &lt;span class="nt"&gt;--mode&lt;/span&gt; mainnet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4: Harden your master password when ready&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;waiaas set-master    &lt;span class="c"&gt;# Replace auto-provisioned password with your own&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, delete &lt;code&gt;recovery.key&lt;/code&gt; from your data volume. It's only needed for the initial bootstrap.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Configure a spending policy and set a session TTL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use the policy API call from earlier in this post. Then create a session for your agent with the scoped TTL you want. The agent gets a &lt;code&gt;wai_sess_&lt;/code&gt; token; your policies enforce the rest.&lt;/p&gt;

&lt;h2&gt;
  
  
  For Production: Secrets Overlay
&lt;/h2&gt;

&lt;p&gt;If you're running this on a server rather than a local machine, use the Docker secrets overlay for your master password:&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;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; secrets
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"your-secure-password"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; secrets/master_password.txt
&lt;span class="nb"&gt;chmod &lt;/span&gt;600 secrets/master_password.txt

docker compose &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.yml &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.secrets.yml up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps your master password out of environment variables and out of your compose file's commit history.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Self-Hosted Mindset
&lt;/h2&gt;

&lt;p&gt;Running your own wallet infrastructure for AI agents is closer to "actually practical" than it used to be. The operational surface is a single Docker container, a CLI, and a handful of API calls. The tradeoff you're making — accepting operational responsibility — is the same one you make when you run your own email server, your own VPN, or your own Nextcloud instance.&lt;/p&gt;

&lt;p&gt;What you get in exchange is meaningful: no third-party custody, no API rate limits from hosted services, no dependency on another company's uptime, and complete auditability of every session token ever issued. When an agent's session expires, it's because you said it should. When a transaction gets blocked, it's because your policy said so. When the kill switch fires, it fires on your server.&lt;/p&gt;

&lt;p&gt;That's not a philosophical position — it's an architecture decision with concrete security properties.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The WAIaaS documentation covers the full policy type reference, MCP integration for connecting agents to Claude and other LLM frameworks, and the TypeScript and Python SDKs for building agents that interact with the REST API directly.&lt;/p&gt;

&lt;p&gt;Start at the GitHub repository — &lt;a href="https://github.com/waiaas/WAIaaS" rel="noopener noreferrer"&gt;https://github.com/waiaas/WAIaaS&lt;/a&gt; — where you'll find the Docker Compose files, the CLI source, and the full monorepo. The project site at &lt;a href="https://waiaas.ai" rel="noopener noreferrer"&gt;https://waiaas.ai&lt;/a&gt; has additional guides for specific deployment patterns and agent integrations.&lt;/p&gt;

</description>
      <category>security</category>
      <category>selfhosted</category>
      <category>opensource</category>
      <category>api</category>
    </item>
    <item>
      <title>The Micropayment Revolution: How AI Agents Will Transform Digital Commerce with x402</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Sat, 10 Oct 2026 17:48:41 +0000</pubDate>
      <link>https://dev.to/walletguy/the-micropayment-revolution-how-ai-agents-will-transform-digital-commerce-with-x402-4inf</link>
      <guid>https://dev.to/walletguy/the-micropayment-revolution-how-ai-agents-will-transform-digital-commerce-with-x402-4inf</guid>
      <description>&lt;h1&gt;
  
  
  The Micropayment Revolution: How AI Agents Will Transform Digital Commerce with x402
&lt;/h1&gt;

&lt;p&gt;AI agents will need to pay for compute, data, and API calls — and the infrastructure to make that happen exists today, not in some theoretical future. The x402 HTTP payment protocol, combined with autonomous wallet infrastructure, means machines can already transact on their own behalf. If you're building AI systems or thinking seriously about the agent economy, this is the layer you need to understand.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;Everyone is excited about AI agents that can browse the web, write code, and make decisions. Far fewer people are asking the obvious follow-up question: how do agents &lt;em&gt;pay&lt;/em&gt; for things?&lt;/p&gt;

&lt;p&gt;Right now, the answer is embarrassing. An agent that needs to call a paid API either uses a hardcoded key controlled by a human, hits a free tier until it runs out, or stops working entirely. There's no mechanism for an autonomous agent to walk up to a paywall, evaluate whether the data is worth the cost, and pay for it — the way a human would with a credit card.&lt;/p&gt;

&lt;p&gt;This matters because the economics of the agent economy break down without it. If every agent action that costs money requires a human to approve a payment, you haven't built an autonomous agent. You've built a very sophisticated assistant that keeps interrupting you to ask for your wallet.&lt;/p&gt;

&lt;p&gt;The missing layer is autonomous payment infrastructure: wallets that agents can operate independently, within rules set by humans, without requiring human approval for every transaction.&lt;/p&gt;

&lt;h2&gt;
  
  
  What x402 Actually Is
&lt;/h2&gt;

&lt;p&gt;The x402 protocol is elegantly simple. When an HTTP server requires payment for a resource, it responds with a &lt;code&gt;402 Payment Required&lt;/code&gt; status code, along with the payment details in the response headers. A client that understands x402 can then make the payment and retry the request automatically.&lt;/p&gt;

&lt;p&gt;For AI agents, this is transformative. An agent making API calls doesn't need to know in advance which endpoints cost money or how much. It encounters a 402 response, evaluates the payment terms, pays if authorized, and continues — all without human involvement.&lt;/p&gt;

&lt;p&gt;WAIaaS implements x402 support directly, so agents using the SDK can make HTTP requests that automatically handle payment when they hit a 402 response:&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;WAIaaSClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@waiaas/sdk&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WAIaaSClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://127.0.0.1:3100&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;sessionToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WAIAAS_SESSION_TOKEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// This fetch call automatically handles 402 Payment Required responses&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;x402Fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/premium-data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That single method call is doing something that would otherwise require significant custom infrastructure: detecting payment requirements, constructing the payment, submitting it on-chain, and retrying the original request. The agent doesn't need to know any of that is happening. It just gets its data.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Wallet Problem for Autonomous Agents
&lt;/h2&gt;

&lt;p&gt;For x402 payments to work autonomously, agents need wallets they can actually use — not wallets controlled by humans that agents have to ask permission to spend from, and not custodied accounts managed by a centralized service.&lt;/p&gt;

&lt;p&gt;The requirements for an agent wallet are different from a human wallet:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Programmable spending rules.&lt;/strong&gt; An agent shouldn't be able to spend unlimited amounts. The humans deploying the agent need to define exactly what it's allowed to spend, on what, with what limits. These rules need to be enforced at the infrastructure level, not by hoping the agent follows instructions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Session-based authorization.&lt;/strong&gt; Agents operate in sessions. A session token scopes what the agent can do, for how long, with what permissions. When a session expires or is revoked, the agent loses access — immediately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Audit trails.&lt;/strong&gt; Every payment an agent makes needs to be logged, attributable, and reviewable. Not for regulation (though that matters too) — for debugging. When your agent spends money unexpectedly, you need to know exactly what it paid for and why.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Human escalation paths.&lt;/strong&gt; Some transactions should require human approval. Large payments, unusual patterns, high-risk actions — these should surface to a human who can approve or reject, without blocking the agent entirely.&lt;/p&gt;

&lt;p&gt;WAIaaS is built around exactly these requirements. It's a self-hosted, open-source Wallet-as-a-Service specifically designed for AI agents, and the policy engine is where the real thinking has happened.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Policy Engine: Rules That Actually Enforce
&lt;/h2&gt;

&lt;p&gt;The WAIaaS policy engine has 21 policy types and 4 security tiers (INSTANT, NOTIFY, DELAY, and APPROVAL). The tiers determine what happens when a transaction is submitted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;INSTANT&lt;/strong&gt; — execute immediately, no notification&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NOTIFY&lt;/strong&gt; — execute immediately, but notify the owner&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DELAY&lt;/strong&gt; — queue the transaction and execute after a time delay (cancellable)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;APPROVAL&lt;/strong&gt; — hold until a human explicitly approves&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For x402 payments specifically, there's a dedicated policy type: &lt;code&gt;X402_ALLOWED_DOMAINS&lt;/code&gt;. This lets you whitelist exactly which domains an agent is allowed to pay automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'X-Master-Password: &amp;lt;password&amp;gt;'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "X402_ALLOWED_DOMAINS",
    "rules": {
      "domains": ["api.example.com", "*.openai.com"]
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An agent trying to make an x402 payment to a domain not on this list will have the transaction blocked. The policy is enforced at the infrastructure level — the agent doesn't get to override it.&lt;/p&gt;

&lt;p&gt;Combine this with a spending limit policy and you have real guardrails:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'X-Master-Password: &amp;lt;password&amp;gt;'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 10,
      "notify_max_usd": 100,
      "delay_max_usd": 1000,
      "delay_seconds": 300,
      "daily_limit_usd": 500,
      "monthly_limit_usd": 5000
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An agent that tries to make a payment under $10 executes instantly. A payment between $10 and $100 executes but you get notified. A payment between $100 and $1,000 queues for 5 minutes (giving you time to cancel). Anything over $1,000 requires your explicit approval.&lt;/p&gt;

&lt;p&gt;The default-deny design matters here: transactions are blocked unless explicitly allowed by policy. An agent with no configured &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt; or &lt;code&gt;CONTRACT_WHITELIST&lt;/code&gt; can't move funds. You have to opt in to permissions, not opt out of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three-Layer Security Model
&lt;/h2&gt;

&lt;p&gt;The authentication model in WAIaaS reflects the different roles in the agent economy:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;masterAuth&lt;/strong&gt; is for system administrators — the humans who set up wallets, create sessions, and configure policies. This uses Argon2id password hashing and controls the critical administrative operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;sessionAuth&lt;/strong&gt; is for AI agents. A session token (JWT HS256) scopes what the agent can do. When you create a session for an agent, you're handing it a credential that lets it operate within the boundaries you've defined. The agent uses this token for balance queries, transactions, DeFi actions, and x402 payments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ownerAuth&lt;/strong&gt; is for fund owners — the humans who hold the actual assets. This uses cryptographic signatures (Ed25519 or secp256k1) and is what's required to approve transactions that hit the APPROVAL tier, or to exercise the kill switch if something goes wrong.&lt;/p&gt;

&lt;p&gt;Creating a wallet and issuing a session to an agent looks like this:&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="c"&gt;# Create the wallet (masterAuth)&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/wallets &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"name": "trading-wallet", "chain": "solana", "environment": "mainnet"}'&lt;/span&gt;

&lt;span class="c"&gt;# Create a session for the agent (masterAuth)&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/sessions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"walletId": "&amp;lt;wallet-uuid&amp;gt;"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent then uses the session token for everything it does. It never sees the master password. It can't create other sessions or modify policies. It operates within the box you've defined.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dry-Run: The Sanity Check Before Spending
&lt;/h2&gt;

&lt;p&gt;One capability worth highlighting for agent payments is dry-run simulation. Before executing a transaction, an agent (or the system building on WAIaaS) can simulate it to check what would happen without committing to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/transactions/send &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_&amp;lt;token&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "type": "TRANSFER",
    "to": "recipient-address",
    "amount": "0.1",
    "dryRun": true
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For an agent making autonomous payments, this is valuable. Before committing to an x402 payment, you can check whether it would be blocked by policy, whether the balance is sufficient, and what the expected outcome would be. This is the kind of infrastructure that makes autonomous payment systems trustworthy rather than terrifying.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting It Running in Five Minutes
&lt;/h2&gt;

&lt;p&gt;The fastest path from zero to a running agent wallet:&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; &lt;span class="nt"&gt;-g&lt;/span&gt; @waiaas/cli
waiaas init          &lt;span class="c"&gt;# Create data directory + config&lt;/span&gt;
waiaas start         &lt;span class="c"&gt;# Start the daemon&lt;/span&gt;
waiaas quickset      &lt;span class="c"&gt;# Create wallets + sessions in one step&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or with Docker if you prefer containers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/waiaas/WAIaaS.git
&lt;span class="nb"&gt;cd &lt;/span&gt;WAIaaS
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For production, Docker Secrets support is built in:&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;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; secrets
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"your-secure-password"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; secrets/master_password.txt
&lt;span class="nb"&gt;chmod &lt;/span&gt;600 secrets/master_password.txt
docker compose &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.yml &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.secrets.yml up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once running, the interactive API reference at &lt;code&gt;/reference&lt;/code&gt; shows every available endpoint with the ability to try calls directly. The OpenAPI 3.0 spec at &lt;code&gt;/doc&lt;/code&gt; is machine-readable if you're generating clients.&lt;/p&gt;

&lt;h2&gt;
  
  
  The MCP Connection: Agents That Already Understand Wallets
&lt;/h2&gt;

&lt;p&gt;If you're building with Claude or another AI that supports the Model Context Protocol, WAIaaS ships 45 MCP tools out of the box. One of them is &lt;code&gt;x402-fetch&lt;/code&gt; — meaning Claude can make x402-authenticated HTTP requests directly through the tool interface.&lt;/p&gt;

&lt;p&gt;Setting it up takes one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;waiaas mcp setup &lt;span class="nt"&gt;--all&lt;/span&gt;    &lt;span class="c"&gt;# Auto-register all wallets with Claude Desktop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, your Claude Desktop configuration points to the WAIaaS MCP server, and Claude gains wallet capabilities: checking balances, sending tokens, querying DeFi positions, and making x402 payments — all within the policy boundaries you've configured.&lt;/p&gt;

&lt;p&gt;This isn't a conceptual demo. The MCP package is &lt;code&gt;@waiaas/mcp&lt;/code&gt; on npm, the tools are real, and the wallet operations go through the same policy engine described above.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Agent Economy Needs
&lt;/h2&gt;

&lt;p&gt;The x402 protocol solves the discovery and payment mechanics. WAIaaS solves the wallet infrastructure. What's still needed — and what the community is actively working on — is the ecosystem of services that expose paid APIs via x402, and the conventions for how agents should evaluate payment terms before agreeing to them.&lt;/p&gt;

&lt;p&gt;The ERC-8004 integration in WAIaaS is relevant here: it provides onchain agent reputation and validation, so services can assess the trustworthiness of an agent making payment before deciding whether to accept. The &lt;code&gt;REPUTATION_THRESHOLD&lt;/code&gt; policy type means wallet operators can also require that agents they interact with have sufficient onchain reputation. Trust flows in both directions.&lt;/p&gt;

&lt;p&gt;The infrastructure layer is ready. What happens next depends on builders deciding to expose paid services via x402 and agents being deployed with wallets capable of paying for them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;If you want to explore the full API surface, the interactive reference is at &lt;code&gt;http://127.0.0.1:3100/reference&lt;/code&gt; once you have WAIaaS running. The codebase itself — 15 packages, 684+ test files, 39 API route modules — is on GitHub and MIT licensed.&lt;/p&gt;

&lt;p&gt;The shift from agents that ask for permission to agents that operate within pre-approved rules is happening now. The wallets and payment protocols exist. The question is what you build on top of them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/waiaas/WAIaaS" rel="noopener noreferrer"&gt;https://github.com/waiaas/WAIaaS&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Official site&lt;/strong&gt;: &lt;a href="https://waiaas.ai" rel="noopener noreferrer"&gt;https://waiaas.ai&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>web3</category>
      <category>blockchain</category>
      <category>llm</category>
    </item>
    <item>
      <title>Policy Stack Architecture: Layering 21 Security Controls for High-Frequency DeFi Bots</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Sat, 10 Oct 2026 12:43:49 +0000</pubDate>
      <link>https://dev.to/walletguy/policy-stack-architecture-layering-21-security-controls-for-high-frequency-defi-bots-57b2</link>
      <guid>https://dev.to/walletguy/policy-stack-architecture-layering-21-security-controls-for-high-frequency-defi-bots-57b2</guid>
      <description>&lt;h1&gt;
  
  
  Policy Stack Architecture: Layering 21 Security Controls for High-Frequency DeFi Bots
&lt;/h1&gt;

&lt;p&gt;DeFi trading bots operate in an adversarial environment where a single misconfigured permission can drain a wallet in seconds — so before your bot executes a single swap, you need a policy stack that's as carefully engineered as the trading logic itself. Most teams bolt on risk controls as an afterthought, wrapping transactions in ad-hoc checks scattered across their codebase. WAIaaS takes the opposite approach: a structured 21-policy engine with four security tiers baked directly into the transaction pipeline, so your bot inherits production-grade risk management without you writing a line of custom guard logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With DIY Risk Controls
&lt;/h2&gt;

&lt;p&gt;When you're building an arb bot or a market-making system, the trading logic gets all the attention — spreads, slippage tolerances, execution latency. The risk layer usually ends up as a handful of &lt;code&gt;if&lt;/code&gt; statements: check the recipient, check the amount, maybe check the gas price. This works until it doesn't.&lt;/p&gt;

&lt;p&gt;The failure modes are well-documented. A compromised session token gives an attacker unlimited spend. A DeFi integration bug routes funds to an unintended contract. A runaway bot loop drains its own wallet executing bad trades at 2am. None of these are exotic attacks — they're routine incidents that teams only think about after the fact.&lt;/p&gt;

&lt;p&gt;What you actually need is a policy engine that sits between your bot's intent and execution: one that enforces spending caps, whitelists contracts, restricts token approvals, sets leverage limits, and requires human sign-off above a threshold — all before the transaction ever hits the chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  The WAIaaS Policy Architecture
&lt;/h2&gt;

&lt;p&gt;WAIaaS runs every transaction through a 7-stage pipeline. Stage 3 is the policy engine, and it enforces 21 policy types organized into four security tiers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;INSTANT&lt;/strong&gt; — Execute immediately, no notification&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NOTIFY&lt;/strong&gt; — Execute immediately, send a notification to the owner&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DELAY&lt;/strong&gt; — Queue the transaction for a configurable delay period (cancellable)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;APPROVAL&lt;/strong&gt; — Block until the fund owner explicitly approves via WalletConnect, Telegram, or push notification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The engine is default-deny: if you haven't configured &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt; or &lt;code&gt;CONTRACT_WHITELIST&lt;/code&gt;, the transaction is blocked. This is the right default for a bot. You explicitly enumerate what the bot is allowed to do, and everything else fails closed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Policy Stack for a Solana Trading Bot
&lt;/h2&gt;

&lt;p&gt;Let's walk through a realistic configuration for a Solana arbitrage bot that swaps on Jupiter and holds positions on Drift.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 1: Spending Limits With Tiered Security
&lt;/h3&gt;

&lt;p&gt;The foundation of any bot policy stack is a spending limit that maps transaction sizes to security tiers. Small routine trades execute instantly. Larger positions trigger notifications. Anything above your comfort threshold requires your explicit approval.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'X-Master-Password: &amp;lt;password&amp;gt;'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 100,
      "notify_max_usd": 1000,
      "delay_max_usd": 5000,
      "delay_seconds": 300,
      "daily_limit_usd": 20000,
      "monthly_limit_usd": 200000
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This single policy means your arb bot can execute $100 swaps all day without friction. A $500 position gets a push notification to your phone. A $3000 trade queues for five minutes before executing — giving you a window to cancel if something looks wrong. Anything above $5000 hard-blocks until you approve it.&lt;/p&gt;

&lt;p&gt;The tier assignment logic is straightforward: &lt;code&gt;amount &amp;lt;= instant_max&lt;/code&gt; → INSTANT, &lt;code&gt;&amp;lt;= notify_max&lt;/code&gt; → NOTIFY, &lt;code&gt;&amp;lt;= delay_max&lt;/code&gt; → DELAY, &lt;code&gt;&amp;gt; delay_max&lt;/code&gt; → APPROVAL. You can also set per-token limits within the same policy using &lt;code&gt;token_limits&lt;/code&gt;, so your SOL exposure and your USDC exposure have separate thresholds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 2: Token Whitelist (Default-Deny)
&lt;/h3&gt;

&lt;p&gt;Without an &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt; policy, the engine blocks all token transfers. Add one to define exactly which tokens your bot is permitted to touch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'X-Master-Password: &amp;lt;password&amp;gt;'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "ALLOWED_TOKENS",
    "rules": {
      "tokens": [
        {"address": "So11111111111111111111111111111111111111112", "symbol": "SOL", "chain": "solana"},
        {"address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "symbol": "USDC", "chain": "solana"}
      ]
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a bug in your Jupiter integration accidentally constructs a swap to an unfamiliar mint address, the engine rejects it before it ever touches the signing stage. Your bot cannot move tokens that aren't on this list.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 3: Contract Whitelist
&lt;/h3&gt;

&lt;p&gt;For a Solana bot interacting with Jupiter and Drift, you want to explicitly enumerate the program addresses the bot is allowed to call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'X-Master-Password: &amp;lt;password&amp;gt;'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "CONTRACT_WHITELIST",
    "rules": {
      "contracts": [
        {"address": "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4", "name": "Jupiter", "chain": "solana"},
        {"address": "dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH", "name": "Drift", "chain": "solana"}
      ]
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is your blast radius limiter. Even if your bot's session token is leaked, an attacker can't route funds to an arbitrary program. The whitelist is enforced at the policy layer — before signing, before broadcast.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 4: Approval Controls
&lt;/h3&gt;

&lt;p&gt;Perpetual futures bots need a different class of policy. The &lt;code&gt;PERP_MAX_LEVERAGE&lt;/code&gt;, &lt;code&gt;PERP_MAX_POSITION_USD&lt;/code&gt;, and &lt;code&gt;PERP_ALLOWED_MARKETS&lt;/code&gt; types give you guardrails at the DeFi semantic level rather than just the transaction value level:&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="c"&gt;# Cap leverage at 5x&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'X-Master-Password: &amp;lt;password&amp;gt;'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "PERP_MAX_LEVERAGE",
    "rules": {"maxLeverage": 5}
  }'&lt;/span&gt;

&lt;span class="c"&gt;# Cap position size&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'X-Master-Password: &amp;lt;password&amp;gt;'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "PERP_MAX_POSITION_USD",
    "rules": {"maxPositionUsd": 10000}
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A runaway position-sizing bug can't lever your wallet into oblivion when &lt;code&gt;PERP_MAX_LEVERAGE&lt;/code&gt; is enforced at the policy layer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 5: Rate Limiting and Time Restrictions
&lt;/h3&gt;

&lt;p&gt;For bots that should only trade during specific market windows:&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="c"&gt;# Maximum 50 transactions per hour&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'X-Master-Password: &amp;lt;password&amp;gt;'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "RATE_LIMIT",
    "rules": {"maxTransactions": 50, "period": "hourly"}
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;code&gt;RATE_LIMIT&lt;/code&gt; policy is your circuit breaker for feedback loops. If a bug causes your bot to hammer the same trade repeatedly, it hits the rate cap before the damage compounds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gas Conditional Execution
&lt;/h2&gt;

&lt;p&gt;One of the more operationally useful features for high-frequency bots is gas conditional execution — transactions execute only when the gas price meets a configured threshold. Your bot submits the transaction to the pipeline; the pipeline holds it in the wait stage until gas conditions are met. This is particularly relevant for EVM bots where gas spikes can make an otherwise profitable arb unprofitable.&lt;/p&gt;

&lt;p&gt;This behavior is handled by the pipeline's wait stage, which sits before execution. Combined with the DELAY tier from your spending limit policy, you get a transaction queue that's both security-gated and gas-aware.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simulating Before You Execute
&lt;/h2&gt;

&lt;p&gt;Before your bot sends a real transaction, use the dry-run API to validate that the transaction would pass policy checks and estimate the outcome:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/transactions/send &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_&amp;lt;token&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "type": "TRANSFER",
    "to": "recipient-address",
    "amount": "0.1",
    "dryRun": true
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a trading bot this is valuable during development and in production before entering new market conditions. A dry run traverses the full pipeline — validation, policy engine, simulation — without touching the chain. If your policy stack would block the transaction, you find out here rather than at execution time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Executing DeFi Actions
&lt;/h2&gt;

&lt;p&gt;Once your policy stack is configured, your bot interacts with the 15 integrated DeFi protocols through a consistent action API. Here's a Jupiter swap:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/actions/jupiter-swap/swap &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_&amp;lt;token&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "inputMint": "So11111111111111111111111111111111111111112",
    "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "amount": "1000000000"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The session token used here is scoped — it can only operate within the policy constraints you configured for that wallet. The bot never touches the master password. If the session is compromised, the attacker operates within a policy-constrained environment: token whitelist enforced, contract whitelist enforced, spending limits applied, rate limits active.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three Auth Layers
&lt;/h2&gt;

&lt;p&gt;Understanding the auth separation matters for bot architecture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;masterAuth&lt;/strong&gt; (Argon2id) — Your system administrator identity. Creates wallets, manages sessions, sets policies. Your bot never holds this credential.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;sessionAuth&lt;/strong&gt; (JWT HS256) — Your bot's operating credential. Scoped to a specific wallet, subject to all configured policies. This is what goes into your bot's environment variables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ownerAuth&lt;/strong&gt; (SIWS/SIWE) — The fund owner's identity for approving high-value transactions. Used by you personally via WalletConnect or a signing tool.
&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;# Bot uses sessionAuth for all trading operations&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/transactions/send &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_&amp;lt;token&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"type": "TRANSFER", "to": "recipient-address", "amount": "0.1"}'&lt;/span&gt;

&lt;span class="c"&gt;# Owner approves a transaction that hit the APPROVAL tier&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/transactions/&amp;lt;tx-id&amp;gt;/approve &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Owner-Signature: &amp;lt;ed25519-or-secp256k1-signature&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Owner-Message: &amp;lt;signed-message&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Quick Start: Standing Up a Policy-Gated Trading Wallet
&lt;/h2&gt;

&lt;p&gt;Here's the minimum viable setup for a bot with sensible defaults:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Start the daemon:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/waiaas/WAIaaS.git
&lt;span class="nb"&gt;cd &lt;/span&gt;WAIaaS
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Create a wallet and session:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/wallets &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"name": "trading-wallet", "chain": "solana", "environment": "mainnet"}'&lt;/span&gt;

curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/sessions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"walletId": "&amp;lt;wallet-uuid&amp;gt;"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Apply your policy stack&lt;/strong&gt; — spending limit, token whitelist, contract whitelist, rate limit as shown above.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Put the session token in your bot's environment and start trading:&lt;/strong&gt;&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;export &lt;/span&gt;&lt;span class="nv"&gt;WAIAAS_SESSION_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;wai_sess_&amp;lt;token&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your bot now operates within a policy-gated environment. All 21 policy types are available to layer in as your strategy grows more complex.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The full list of 21 policy types — including &lt;code&gt;LENDING_LTV_LIMIT&lt;/code&gt;, &lt;code&gt;APPROVE_AMOUNT_LIMIT&lt;/code&gt;, &lt;code&gt;VENUE_WHITELIST&lt;/code&gt;, and &lt;code&gt;ERC8128_ALLOWED_DOMAINS&lt;/code&gt; — is documented in the interactive API reference at &lt;code&gt;http://127.0.0.1:3100/reference&lt;/code&gt; once your daemon is running. The OpenAPI 3.0 spec is available at &lt;code&gt;/doc&lt;/code&gt; for integration with your tooling.&lt;/p&gt;

&lt;p&gt;If you're building cross-chain strategies that also need bridge operations via LI.FI or Across, or want to connect to Claude or another LLM via the 45-tool MCP server for a hybrid agent/bot architecture, the same policy stack governs all of it — one configuration, consistent enforcement across every protocol and chain.&lt;/p&gt;




&lt;p&gt;Explore the codebase and self-host your own instance: &lt;a href="https://github.com/waiaas/WAIaaS" rel="noopener noreferrer"&gt;github.com/waiaas/WAIaaS&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Full documentation and hosted options: &lt;a href="https://waiaas.ai" rel="noopener noreferrer"&gt;waiaas.ai&lt;/a&gt;&lt;/p&gt;

</description>
      <category>defi</category>
      <category>security</category>
      <category>api</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Claude Waits for Cheap Gas: MCP Tools for Gas-Conditional DeFi Execution</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Fri, 09 Oct 2026 18:47:03 +0000</pubDate>
      <link>https://dev.to/walletguy/claude-waits-for-cheap-gas-mcp-tools-for-gas-conditional-defi-execution-h77</link>
      <guid>https://dev.to/walletguy/claude-waits-for-cheap-gas-mcp-tools-for-gas-conditional-defi-execution-h77</guid>
      <description>&lt;h1&gt;
  
  
  Claude Waits for Cheap Gas: MCP Tools for Gas-Conditional DeFi Execution
&lt;/h1&gt;

&lt;p&gt;MCP tools for DeFi execution are about to change how your Claude agent interacts with onchain protocols — instead of hardcoding wallet logic into every script, you add one entry to &lt;code&gt;claude_desktop_config.json&lt;/code&gt; and Claude gains a fully-featured wallet with 45 tools covering swaps, staking, lending, bridging, and yes, gas-conditional execution. This post shows you exactly how to set that up and why gas conditions matter for autonomous agents running DeFi strategies.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: Autonomous Agents and Gas Timing
&lt;/h2&gt;

&lt;p&gt;Anyone who has run an automated DeFi strategy knows the pain. Your agent executes a swap at exactly the wrong moment — gas spikes, the transaction costs three times what it should, and the trade is no longer profitable. If a human were watching, they'd wait. But autonomous agents don't wait. They fire and forget.&lt;/p&gt;

&lt;p&gt;This is a real problem when you're giving an AI agent control over onchain actions. The agent might be smart enough to find the right trade, but without infrastructure that enforces execution conditions, it'll burn gas whenever it decides to move. For long-running strategies — think recurring rebalancing, yield harvesting, or position management — bad gas timing compounds into serious losses over time.&lt;/p&gt;

&lt;p&gt;The answer isn't to make the agent smarter about gas in every prompt. The answer is to build the gas condition into the infrastructure layer, so the agent can't execute until conditions are met. That's exactly what WAIaaS's gas conditional execution feature does, and it's exposed directly through MCP tools that Claude can call.&lt;/p&gt;

&lt;h2&gt;
  
  
  What WAIaaS Brings to Claude Desktop
&lt;/h2&gt;

&lt;p&gt;WAIaaS is an open-source, self-hosted Wallet-as-a-Service designed for AI agents. It runs as a local daemon (default port &lt;code&gt;3100&lt;/code&gt;) and exposes its capabilities through multiple integration surfaces — REST API, TypeScript SDK, Python SDK, and an MCP server.&lt;/p&gt;

&lt;p&gt;The MCP server is the interesting part for Claude users. It packages 45 tools into a single stdio-based server that Claude Desktop can call directly. Those tools cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wallet operations (balance, address, assets, transaction history)&lt;/li&gt;
&lt;li&gt;Token transfers and batch transactions&lt;/li&gt;
&lt;li&gt;DeFi actions across 15 integrated protocols&lt;/li&gt;
&lt;li&gt;NFT queries and transfers&lt;/li&gt;
&lt;li&gt;ERC-4337 UserOp building and signing&lt;/li&gt;
&lt;li&gt;x402 HTTP payment protocol&lt;/li&gt;
&lt;li&gt;Simulation and dry-run before execution&lt;/li&gt;
&lt;li&gt;WalletConnect integration for human approval flows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The gas conditional execution feature (&lt;code&gt;FEAT-GAS&lt;/code&gt;) lives in the transaction pipeline. When your agent submits a transaction, the pipeline checks whether the current gas price meets a configured threshold before proceeding to execution. The agent doesn't need to poll gas prices, implement retry logic, or manage any of this — it submits, and the infrastructure handles the waiting.&lt;/p&gt;

&lt;h2&gt;
  
  
  One Line to Give Claude a Wallet
&lt;/h2&gt;

&lt;p&gt;Here's the configuration. Open &lt;code&gt;~/Library/Application Support/Claude/claude_desktop_config.json&lt;/code&gt; and add:&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;"waiaas"&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;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@waiaas/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;"WAIAAS_BASE_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;"http://127.0.0.1:3100"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"WAIAAS_SESSION_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wai_sess_&amp;lt;your-token&amp;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;"WAIAAS_DATA_DIR"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~/.waiaas"&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;That's it. Restart Claude Desktop, and Claude can now call any of the 45 MCP tools. It can check balances, send tokens, execute swaps on Jupiter, manage Aave positions, stake with Lido or Jito, bridge via LI.FI or Across, and more — all from natural language instructions in the chat window.&lt;/p&gt;

&lt;p&gt;The transport is stdio, which means no network ports are opened for the MCP connection itself. The MCP process talks to your local WAIaaS daemon over HTTP on &lt;code&gt;127.0.0.1:3100&lt;/code&gt;, which is bound to localhost only by default (fact &lt;code&gt;DOCKER-02&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting the Daemon Running First
&lt;/h2&gt;

&lt;p&gt;Before Claude can use the tools, you need the daemon running. The fastest path:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — Install the CLI and initialize:&lt;/strong&gt;&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; &lt;span class="nt"&gt;-g&lt;/span&gt; @waiaas/cli
waiaas init &lt;span class="nt"&gt;--auto-provision&lt;/span&gt;
waiaas start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;--auto-provision&lt;/code&gt; flag generates a random master password and writes it to &lt;code&gt;recovery.key&lt;/code&gt;. No password prompt on startup — useful for getting started quickly. You can harden it later with &lt;code&gt;waiaas set-master&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 — Create wallets and sessions in one command:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;waiaas quickset &lt;span class="nt"&gt;--mode&lt;/span&gt; mainnet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates wallets and MCP-ready session tokens in a single step. The CLI prints the MCP config JSON — paste it into your Claude Desktop config, or use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;waiaas mcp setup &lt;span class="nt"&gt;--all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...to auto-register all wallets with Claude Desktop automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — Add the MCP config and restart Claude Desktop.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's the whole setup. Three commands, one config edit.&lt;/p&gt;

&lt;p&gt;Alternatively, if you prefer Docker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/waiaas/WAIaaS.git
&lt;span class="nb"&gt;cd &lt;/span&gt;WAIaaS
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Docker image (&lt;code&gt;waiaas/daemon:latest&lt;/code&gt;) includes auto-provision support, Docker Secrets integration for production deployments, a healthcheck, and runs as a non-root user (UID 1001). The compose file binds to &lt;code&gt;127.0.0.1:3100:3100&lt;/code&gt; by default, keeping the daemon local.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Gas-Conditional Execution Works in Practice
&lt;/h2&gt;

&lt;p&gt;The gas conditional execution feature (&lt;code&gt;FEAT-GAS&lt;/code&gt;) sits inside WAIaaS's 7-stage transaction pipeline: validate → auth → policy → wait → execute → confirm. The gas condition check happens in the wait stage. If the current gas price exceeds your configured threshold, the transaction queues and waits. Once gas drops to an acceptable level, execution proceeds automatically.&lt;/p&gt;

&lt;p&gt;From Claude's perspective, the interaction is simple. Claude calls the send or DeFi action tool, the transaction enters the pipeline, and Claude can query the transaction status later. The waiting happens server-side. Claude doesn't need to implement any retry logic or gas-checking loops.&lt;/p&gt;

&lt;p&gt;Here's what that looks like from the REST API side (which the MCP tools wrap):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/transactions/send &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_&amp;lt;token&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "type": "TRANSFER",
    "to": "recipient-address",
    "amount": "0.1"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before you execute anything for real, you can simulate it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/transactions/send &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_&amp;lt;token&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "type": "TRANSFER",
    "to": "recipient-address",
    "amount": "0.1",
    "dryRun": true
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dry-run API (&lt;code&gt;FEAT-DRYRUN&lt;/code&gt;) lets Claude (or you) validate a transaction's expected outcome before committing gas. For a DeFi agent running strategies autonomously, this is a useful safety check before any significant action.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Policy Layer: What Claude Is and Isn't Allowed to Do
&lt;/h2&gt;

&lt;p&gt;Giving Claude a wallet without guardrails is a bad idea. WAIaaS has a policy engine with 21 policy types and 4 security tiers — INSTANT, NOTIFY, DELAY, and APPROVAL — enforced on every transaction the agent attempts.&lt;/p&gt;

&lt;p&gt;The default-deny behavior is important: transactions are blocked unless explicitly allowed. An agent without a &lt;code&gt;CONTRACT_WHITELIST&lt;/code&gt; policy can't call arbitrary contracts. Without &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt;, it can't transfer arbitrary tokens. You define exactly what Claude can touch.&lt;/p&gt;

&lt;p&gt;For a gas-conditional DeFi setup, a sensible starting policy set looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 100,
      "notify_max_usd": 500,
      "delay_max_usd": 2000,
      "delay_seconds": 900,
      "daily_limit_usd": 5000
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this configuration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transactions under $100 execute immediately (INSTANT)&lt;/li&gt;
&lt;li&gt;$100–$500 execute but you get notified (NOTIFY)&lt;/li&gt;
&lt;li&gt;$500–$2,000 queue for 15 minutes before executing, giving you time to cancel (DELAY)&lt;/li&gt;
&lt;li&gt;Over $2,000 requires your explicit approval via WalletConnect or Telegram (APPROVAL)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The WalletConnect integration (&lt;code&gt;FEAT-WC&lt;/code&gt;) is how you approve transactions from your phone when Claude requests something above your DELAY threshold. Claude submits the transaction, it lands in a pending state, and you get a WalletConnect prompt to approve or reject it.&lt;/p&gt;

&lt;p&gt;There are also DeFi-specific policy types worth knowing about for this use case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;PERP_MAX_LEVERAGE&lt;/code&gt; — caps the leverage Claude can use on Hyperliquid perpetuals&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PERP_MAX_POSITION_USD&lt;/code&gt; — caps absolute position size&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;LENDING_LTV_LIMIT&lt;/code&gt; — prevents Claude from borrowing against collateral at dangerous ratios on Aave&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;VENUE_WHITELIST&lt;/code&gt; — restricts which protocols Claude can interact with&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ACTION_CATEGORY_LIMIT&lt;/code&gt; — limits DeFi action categories (e.g., allow swaps but not perpetuals)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These aren't just nice-to-haves. For a gas-conditional agent that executes while you're asleep, they're the guardrails that keep a strategy from going sideways.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 15 DeFi Protocols Claude Can Access
&lt;/h2&gt;

&lt;p&gt;Once your MCP session is configured and policies are set, Claude has access to 15 integrated DeFi protocol providers:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Swaps:&lt;/strong&gt; Jupiter (Solana), 0x, D'CENT swap, LI.FI&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Lending:&lt;/strong&gt; Aave v3, Kamino, Pendle&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Staking:&lt;/strong&gt; Lido (EVM liquid staking), Jito (Solana)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Perpetuals:&lt;/strong&gt; Hyperliquid (perps, spot, sub-accounts), Drift&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Bridging:&lt;/strong&gt; LI.FI, Across&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Prediction markets:&lt;/strong&gt; Polymarket&lt;br&gt;&lt;br&gt;
&lt;strong&gt;DEX:&lt;/strong&gt; XRPL DEX&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Onchain agent reputation:&lt;/strong&gt; ERC-8004&lt;/p&gt;

&lt;p&gt;For example, to execute a Jupiter swap (Solana), Claude calls the &lt;code&gt;action-provider&lt;/code&gt; tool which maps to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/actions/jupiter-swap/swap &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_&amp;lt;token&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "inputMint": "So11111111111111111111111111111111111111112",
    "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "amount": "1000000000"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude can also query DeFi positions across protocols using the &lt;code&gt;get-defi-positions&lt;/code&gt; tool — useful for portfolio-aware agents that need to understand their current exposure before taking action.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multi-Wallet Setup for Strategy Isolation
&lt;/h2&gt;

&lt;p&gt;If you're running multiple strategies, you probably want them isolated in separate wallets with separate policies. WAIaaS supports this with per-wallet sessions and per-wallet policy sets.&lt;/p&gt;

&lt;p&gt;The MCP config supports multiple named servers pointing to different wallets on the same daemon:&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;"waiaas-trading"&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;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@waiaas/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;"WAIAAS_BASE_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;"http://127.0.0.1:3100"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"WAIAAS_AGENT_ID"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"019c47d6-51ef-7f43-a76b-d50e875d95f4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"WAIAAS_AGENT_NAME"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"trading-agent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"WAIAAS_DATA_DIR"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~/.waiaas"&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="nl"&gt;"waiaas-solana"&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;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@waiaas/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;"WAIAAS_BASE_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;"http://127.0.0.1:3100"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"WAIAAS_AGENT_ID"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"019c4cd2-86e8-758f-a61e-9c560307c788"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"WAIAAS_AGENT_NAME"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"solana-wallet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"WAIAAS_DATA_DIR"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~/.waiaas"&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 MCP servers, two wallets, two independent policy sets. Claude Desktop sees both as separate tool namespaces. Each wallet's session has its own TTL, renewal limits, and policy configuration — defined at session creation time (fact &lt;code&gt;SEC-04&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Full Setup Looks Like
&lt;/h2&gt;

&lt;p&gt;To recap the end-to-end picture:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;WAIaaS daemon&lt;/strong&gt; runs locally (Docker or CLI), manages wallets, enforces policies, executes the 7-stage transaction pipeline including gas condition checks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP server&lt;/strong&gt; (&lt;code&gt;@waiaas/mcp&lt;/code&gt;) connects Claude Desktop to the daemon via stdio, exposing 45 tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude&lt;/strong&gt; receives natural language instructions, selects the appropriate MCP tool, and submits the action&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Policy engine&lt;/strong&gt; validates the action against your 21 configured policy types before anything hits the chain&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gas condition&lt;/strong&gt; holds the transaction in the wait stage until gas price meets your threshold&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Signing channels&lt;/strong&gt; notify you (Push, Telegram, WalletConnect) when human approval is needed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The agent does the reasoning. The infrastructure does the enforcement. You stay in control of what the agent is allowed to do and when transactions actually execute.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The WAIaaS codebase is open source and actively developed — the monorepo has 15 packages, 684+ test files, and covers EVM and Solana across 18 networks. If you want to dig into the policy engine in detail, the OpenAPI spec and interactive reference UI are available at &lt;code&gt;http://127.0.0.1:3100/doc&lt;/code&gt; and &lt;code&gt;/reference&lt;/code&gt; once your daemon is running.&lt;/p&gt;

&lt;p&gt;Star the repo, try the quickstart, and open an issue if you hit anything unexpected.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/waiaas/WAIaaS" rel="noopener noreferrer"&gt;https://github.com/waiaas/WAIaaS&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Official site:&lt;/strong&gt; &lt;a href="https://waiaas.ai" rel="noopener noreferrer"&gt;https://waiaas.ai&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>web3</category>
      <category>ethereum</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>21 Policy Types for AI Agent Security: Machine Learning Meets Crypto Risk Management</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Fri, 09 Oct 2026 13:27:49 +0000</pubDate>
      <link>https://dev.to/walletguy/21-policy-types-for-ai-agent-security-machine-learning-meets-crypto-risk-management-51oa</link>
      <guid>https://dev.to/walletguy/21-policy-types-for-ai-agent-security-machine-learning-meets-crypto-risk-management-51oa</guid>
      <description>&lt;h1&gt;
  
  
  21 Policy Types for AI Agent Security: How WAIaaS Puts Guardrails on Crypto Wallets
&lt;/h1&gt;

&lt;p&gt;Giving an AI agent a wallet without guardrails is like giving a toddler a credit card — the intent might be good, but the outcomes can be catastrophic. AI agent security in crypto is not a solved problem, and most developers building autonomous on-chain agents are one misconfigured prompt away from watching their funds disappear. WAIaaS is an open-source, self-hosted Wallet-as-a-Service that approaches this problem seriously: default-deny policies, 3-layer authentication, and explicit human approval channels sit between your agent and your funds at all times.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Risk of Autonomous Agents with Wallets
&lt;/h2&gt;

&lt;p&gt;Autonomous AI agents are increasingly useful for on-chain tasks — arbitrage, yield farming, portfolio rebalancing, paying for API access. But the moment an agent has signing authority over a wallet, you have created a new attack surface. The agent can be manipulated through prompt injection. A bug in your logic can trigger unintended transactions. A compromised session token can be replayed. And unlike a web app where a bad action might corrupt a database you can restore, an on-chain transaction is final.&lt;/p&gt;

&lt;p&gt;The security question is not "do you trust your AI?" — it is "what is the blast radius if it goes wrong?" Good security design answers that question before anything gets deployed.&lt;/p&gt;

&lt;p&gt;WAIaaS answers it with three concrete layers: authentication controls who can issue commands, a policy engine controls what those commands are allowed to do, and a human approval channel controls whether high-risk actions actually execute. Let's walk through each.&lt;/p&gt;




&lt;h2&gt;
  
  
  Layer 1: Three Authentication Methods, Three Principals
&lt;/h2&gt;

&lt;p&gt;WAIaaS separates concerns across three distinct principals, each with its own authentication method:&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="c"&gt;# masterAuth — system administrator (wallet creation, session management, policies)&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt;

&lt;span class="c"&gt;# sessionAuth — AI agent (transactions, balance queries, DeFi actions)&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_eyJhbGciOiJIUzI1NiJ9..."&lt;/span&gt;

&lt;span class="c"&gt;# ownerAuth — fund owner (transaction approval, kill switch recovery)&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Owner-Signature: &amp;lt;ed25519-or-secp256k1-signature&amp;gt;"&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Owner-Message: &amp;lt;signed-message&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;master password&lt;/strong&gt; (hashed with Argon2id) is a system-level credential used only to create wallets, configure policies, and manage sessions. Your AI agent never sees it.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;session token&lt;/strong&gt; (JWT HS256) is what your agent actually uses. It is scoped to a single wallet, carries a TTL, a maximum renewal count, and an absolute lifetime ceiling. If the token is compromised, the blast radius is bounded — the attacker cannot create new wallets, cannot modify policies, and cannot approve their own transactions.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;owner authentication&lt;/strong&gt; (Ed25519 or secp256k1 signature from the fund owner's wallet) is the kill switch and approval channel. It cannot be faked by the agent. It requires the actual owner to sign a message with their private key, which means it requires a human being.&lt;/p&gt;

&lt;p&gt;This separation is not cosmetic. It means that a fully compromised agent session still cannot drain funds beyond what the policy engine allows, and still cannot approve its own high-value transactions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Layer 2: The Policy Engine — 21 Types, 4 Tiers, Default-Deny
&lt;/h2&gt;

&lt;p&gt;This is the core of WAIaaS security. The policy engine enforces rules on every transaction before it executes, and it is &lt;strong&gt;default-deny&lt;/strong&gt;: if you have not explicitly configured &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt; or &lt;code&gt;CONTRACT_WHITELIST&lt;/code&gt;, transactions that involve tokens or contracts are blocked.&lt;/p&gt;

&lt;p&gt;There are 21 policy types organized around different risk vectors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SPENDING_LIMIT          — Amount-based 4-tier security
WHITELIST               — Allowed recipient addresses
TIME_RESTRICTION        — Allowed transaction hours
RATE_LIMIT              — Max transactions per period
ALLOWED_TOKENS          — Token transfer whitelist (default-deny)
CONTRACT_WHITELIST      — Contract call whitelist (default-deny)
METHOD_WHITELIST        — Allowed function selectors
APPROVED_SPENDERS       — Token approval whitelist (default-deny)
APPROVE_AMOUNT_LIMIT    — Max approve amount, block unlimited
APPROVE_TIER_OVERRIDE   — Force tier for APPROVE transactions
ALLOWED_NETWORKS        — Network restriction
X402_ALLOWED_DOMAINS    — x402 payment domain whitelist
LENDING_LTV_LIMIT       — Max loan-to-value ratio for DeFi lending
LENDING_ASSET_WHITELIST — Allowed lending assets
PERP_MAX_LEVERAGE       — Max perpetual futures leverage
PERP_MAX_POSITION_USD   — Max position size in USD
PERP_ALLOWED_MARKETS    — Allowed perpetual markets
REPUTATION_THRESHOLD    — ERC-8004 onchain reputation threshold
ERC8128_ALLOWED_DOMAINS — ERC-8128 HTTP signing domains
VENUE_WHITELIST         — Allowed trading venues
ACTION_CATEGORY_LIMIT   — DeFi action category limits
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Spending Limit: Four Tiers of Risk
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;SPENDING_LIMIT&lt;/code&gt; policy is the most fundamental control. It maps transaction amounts to four security tiers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSTANT   — Execute immediately, no notification
NOTIFY    — Execute immediately, send notification
DELAY     — Queue for delay_seconds, then execute (cancellable)
APPROVAL  — Require human approval via WalletConnect/Telegram/Push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is how you create a spending limit policy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 100,
      "notify_max_usd": 500,
      "delay_max_usd": 2000,
      "delay_seconds": 900,
      "daily_limit_usd": 5000
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this configuration: a $50 transfer goes through immediately. A $300 transfer goes through but you get a notification. A $1,200 transfer is queued for 15 minutes — giving you a window to cancel it if it was a mistake or an attack. A $3,000 transfer requires you to explicitly approve it with your owner signature. Nothing above $5,000 in a single day executes regardless of tier.&lt;/p&gt;

&lt;p&gt;This is not a vague "security feature." It is a precise, auditable rule that you can reason about.&lt;/p&gt;

&lt;h3&gt;
  
  
  Default-Deny Token Whitelist
&lt;/h3&gt;

&lt;p&gt;One of the most important policies is &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt;. Without it configured, your agent cannot transfer tokens — any token transfer is blocked by default. You must explicitly declare which tokens the agent is permitted to move:&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;"tokens"&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="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"symbol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USDC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"chain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"solana"&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;Same logic applies to &lt;code&gt;CONTRACT_WHITELIST&lt;/code&gt; (which contracts the agent can call), &lt;code&gt;APPROVED_SPENDERS&lt;/code&gt; (which addresses the agent can grant token approvals to), and &lt;code&gt;ALLOWED_NETWORKS&lt;/code&gt; (which chains the agent can operate on at all).&lt;/p&gt;

&lt;p&gt;The default-deny posture means you are opting in to capabilities, not opting out of risks. That is the correct direction for security design.&lt;/p&gt;

&lt;h3&gt;
  
  
  DeFi-Specific Risk Controls
&lt;/h3&gt;

&lt;p&gt;WAIaaS integrates 15 DeFi protocols including Aave v3, Hyperliquid, Jupiter, Kamino, and Pendle. Each category of DeFi activity has specific policy controls:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;LENDING_LTV_LIMIT&lt;/code&gt;&lt;/strong&gt; caps the loan-to-value ratio for lending positions, preventing your agent from over-leveraging collateral on Aave or Kamino.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;PERP_MAX_LEVERAGE&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;PERP_MAX_POSITION_USD&lt;/code&gt;&lt;/strong&gt; bound perpetual futures exposure on Hyperliquid and Drift — an agent cannot open a 50x leveraged position if you have capped leverage at 5x.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;PERP_ALLOWED_MARKETS&lt;/code&gt;&lt;/strong&gt; restricts which perpetual markets the agent can trade, so an agent configured for BTC/USD perpetuals cannot suddenly start trading illiquid altcoin contracts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;VENUE_WHITELIST&lt;/code&gt;&lt;/strong&gt; restricts which DEXes or trading venues the agent can route through.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ACTION_CATEGORY_LIMIT&lt;/code&gt;&lt;/strong&gt; lets you set rate limits per DeFi action category — for example, limiting how many lending actions can occur per day regardless of individual amounts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Approve Transaction Controls
&lt;/h3&gt;

&lt;p&gt;Token approvals (&lt;code&gt;APPROVE&lt;/code&gt;) are one of the most exploited mechanisms in DeFi. &lt;code&gt;APPROVE_AMOUNT_LIMIT&lt;/code&gt; blocks the agent from issuing unlimited token approvals — a common attack vector where a malicious contract drains all of a token indefinitely. &lt;code&gt;APPROVE_TIER_OVERRIDE&lt;/code&gt; lets you force all approval transactions to require human sign-off regardless of the dollar amount, which is a sensible default for most setups.&lt;/p&gt;

&lt;h3&gt;
  
  
  x402 and HTTP Payment Policies
&lt;/h3&gt;

&lt;p&gt;WAIaaS supports the x402 HTTP payment protocol, which lets agents automatically pay for API calls. &lt;code&gt;X402_ALLOWED_DOMAINS&lt;/code&gt; is a whitelist of domains the agent is permitted to pay automatically. Without this policy configured, the agent cannot make x402 payments to any domain. With it, you can allow &lt;code&gt;*.openai.com&lt;/code&gt; and &lt;code&gt;api.example.com&lt;/code&gt; while blocking everything else.&lt;/p&gt;




&lt;h2&gt;
  
  
  Layer 3: Human Approval Channels
&lt;/h2&gt;

&lt;p&gt;When a transaction hits the &lt;code&gt;APPROVAL&lt;/code&gt; tier — either by exceeding spending limits or by matching a policy that always requires approval — it is queued and waits. The owner must actively approve it. WAIaaS supports three signing channels for this: push relay, Telegram, and WalletConnect notification.&lt;/p&gt;

&lt;p&gt;Approving a pending transaction looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/transactions/&amp;lt;tx-id&amp;gt;/approve &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Owner-Signature: &amp;lt;ed25519-or-secp256k1-signature&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Owner-Message: &amp;lt;signed-message&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This requires a cryptographic signature from the owner's key. It cannot be spoofed by the agent. It cannot be automated away. A human being with access to the owner's private key must sign the approval message. The delay tier works similarly — transactions are queued for &lt;code&gt;delay_seconds&lt;/code&gt; and then execute automatically, but they can be cancelled during that window if you catch something wrong.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Transaction Pipeline
&lt;/h2&gt;

&lt;p&gt;Every transaction — regardless of type — passes through a 7-stage pipeline before execution: validate, auth, policy, wait, execute, confirm. The policy stage runs after authentication and before any waiting or execution, which means a policy violation is caught early and returns an error immediately:&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;"error"&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;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POLICY_DENIED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Transaction denied by SPENDING_LIMIT policy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POLICY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"retryable"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&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;There is also a dry-run mode for simulating transactions before committing them — useful for testing policy configurations without moving real funds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/transactions/send &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_&amp;lt;token&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "type": "TRANSFER",
    "to": "recipient-address",
    "amount": "0.1",
    "dryRun": true
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there is gas conditional execution — transactions can be configured to execute only when gas price meets a threshold, preventing your agent from sending transactions during fee spikes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Start: Deploying a Secured Agent Wallet
&lt;/h2&gt;

&lt;p&gt;Here is the minimal path to a secured agent wallet:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Start WAIaaS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/waiaas/WAIaaS.git
&lt;span class="nb"&gt;cd &lt;/span&gt;WAIaaS
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Create a wallet and session&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/wallets &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"name": "trading-wallet", "chain": "solana", "environment": "mainnet"}'&lt;/span&gt;

curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/sessions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"walletId": "&amp;lt;wallet-uuid&amp;gt;"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Configure a spending limit policy&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 100,
      "notify_max_usd": 500,
      "delay_max_usd": 2000,
      "delay_seconds": 900,
      "daily_limit_usd": 5000
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4: Configure allowed tokens (remember: default-deny)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Set an &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt; policy listing every token your agent is permitted to transfer. Without this, token transfers are blocked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Give the session token to your agent, keep the master password out of it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your agent gets &lt;code&gt;wai_sess_&amp;lt;token&amp;gt;&lt;/code&gt;. Your master password stays in your environment config, never in the agent's context.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The Admin Web UI at &lt;code&gt;/admin&lt;/code&gt; provides a visual policy editor and DeFi positions dashboard if you prefer not to manage policies through the REST API. For integrating with Claude or other MCP-compatible AI agents, &lt;code&gt;waiaas mcp setup --all&lt;/code&gt; registers all wallets automatically and gives you a ready-to-paste Claude Desktop config.&lt;/p&gt;

&lt;p&gt;Explore the full codebase and self-host your own instance at &lt;a href="https://github.com/waiaas/WAIaaS" rel="noopener noreferrer"&gt;github.com/waiaas/WAIaaS&lt;/a&gt;, and read the full documentation at &lt;a href="https://waiaas.ai" rel="noopener noreferrer"&gt;waiaas.ai&lt;/a&gt;. Security questions and contributions are welcome — this is open source, and the policy engine behavior is auditable in the code.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>web3</category>
      <category>testing</category>
    </item>
    <item>
      <title>Auto-Updating Self-Hosted Crypto Wallets: Watchtower + GHCR Production Setup</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Thu, 08 Oct 2026 19:15:55 +0000</pubDate>
      <link>https://dev.to/walletguy/auto-updating-self-hosted-crypto-wallets-watchtower-ghcr-production-setup-4a5h</link>
      <guid>https://dev.to/walletguy/auto-updating-self-hosted-crypto-wallets-watchtower-ghcr-production-setup-4a5h</guid>
      <description>&lt;h1&gt;
  
  
  Auto-Updating Self-Hosted Crypto Wallets: Watchtower + GHCR Production Setup
&lt;/h1&gt;

&lt;p&gt;Self-hosting your AI agent's wallet infrastructure means you never have to ask: "Who actually controls these private keys?" If you've been running homelab services for a while, you already know the value of owning your stack. This guide walks through a production-ready WAIaaS deployment with automatic Docker image updates via Watchtower and GitHub Container Registry (GHCR) — so you get the control of self-hosting without the maintenance burden of manual updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Self-Hosting Your Agent's Wallet Actually Matters
&lt;/h2&gt;

&lt;p&gt;When an AI agent moves real money — swapping tokens, paying for API calls, interacting with DeFi protocols — the custody question isn't academic. Hosted wallet services mean someone else's server holds the keys, enforces the rate limits, and logs the transactions. That's a reasonable trade-off for prototyping, but it's a meaningful one.&lt;/p&gt;

&lt;p&gt;Running WAIaaS on your own hardware means your keys stay on your hardware. The daemon runs locally, the database lives in a named Docker volume you control, and nothing phones home unless you've configured an RPC endpoint that does. It's the crypto equivalent of running your own email server — except WAIaaS has a one-command quick start, so it's actually practical.&lt;/p&gt;

&lt;p&gt;The production concern that kills most self-hosted setups isn't the initial deployment — it's the update treadmill. Security patches, new DeFi integrations, bug fixes: staying current manually is tedious. That's where Watchtower comes in.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You're Building
&lt;/h2&gt;

&lt;p&gt;By the end of this guide you'll have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WAIaaS daemon running in Docker, bound to &lt;code&gt;127.0.0.1:3100&lt;/code&gt; (not exposed to the internet)&lt;/li&gt;
&lt;li&gt;Automatic image updates pulling from &lt;code&gt;ghcr.io/waiaas/waiaas:latest&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Production secrets managed via Docker Secrets (no passwords in environment variables)&lt;/li&gt;
&lt;li&gt;A healthcheck that restarts the container if the daemon goes unresponsive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full WAIaaS stack is a 15-package monorepo with a 7-stage transaction pipeline, 21 policy types, and 45 MCP tools for AI agent integration. You don't need to understand all of that to run it — but it's good to know the depth is there when you need it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Clone and Understand the Compose File
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/waiaas/WAIaaS.git
&lt;span class="nb"&gt;cd &lt;/span&gt;WAIaaS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repository ships with a &lt;code&gt;docker-compose.yml&lt;/code&gt; that's already production-shaped. Here's what it looks like, annotated:&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;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;daemon&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ghcr.io/waiaas/waiaas:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;waiaas-daemon&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1:3100:3100"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;waiaas-data:/data&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;WAIAAS_DATA_DIR=/data&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;WAIAAS_DAEMON_HOSTNAME=0.0.0.0&lt;/span&gt;
    &lt;span class="na"&gt;env_file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.env&lt;/span&gt;
        &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;curl"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-f"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:3100/health"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;30s&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
      &lt;span class="na"&gt;start_period&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;waiaas-data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few things worth noting for the self-hoster:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Port binding is localhost-only.&lt;/strong&gt; &lt;code&gt;127.0.0.1:3100:3100&lt;/code&gt; means the API is not reachable from outside the host. If you want to access it from another machine, you handle that at the reverse-proxy layer (nginx, Caddy, Tailscale) — not by changing this binding to &lt;code&gt;0.0.0.0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Named volume, not a bind mount.&lt;/strong&gt; &lt;code&gt;waiaas-data&lt;/code&gt; is managed by Docker, which keeps things clean. Your wallet data, session tokens, and configuration survive container restarts and image updates. &lt;code&gt;docker compose down&lt;/code&gt; preserves the volume; &lt;code&gt;docker compose down -v&lt;/code&gt; deletes it — don't run the latter in production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Healthcheck is built in.&lt;/strong&gt; The daemon exposes &lt;code&gt;/health&lt;/code&gt;, and Docker will automatically restart the container if it stops responding. No external monitoring required for basic uptime.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: First Boot with Auto-Provision
&lt;/h2&gt;

&lt;p&gt;For a first deployment, auto-provision is the cleanest path. It generates a random master password and writes it to &lt;code&gt;/data/recovery.key&lt;/code&gt; inside the container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; waiaas &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 127.0.0.1:3100:3100 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; waiaas-data:/data &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;WAIAAS_AUTO_PROVISION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  ghcr.io/waiaas/waiaas:latest

&lt;span class="c"&gt;# Retrieve auto-generated master password&lt;/span&gt;
docker &lt;span class="nb"&gt;exec &lt;/span&gt;waiaas &lt;span class="nb"&gt;cat&lt;/span&gt; /data/recovery.key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save that password somewhere secure (a password manager, not a sticky note). Once you've noted it, you can harden the setup using &lt;code&gt;waiaas set-master&lt;/code&gt; from the CLI if you have it installed, then delete the recovery key file.&lt;/p&gt;

&lt;p&gt;For most homelab setups, the CLI-based flow is even cleaner:&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; &lt;span class="nt"&gt;-g&lt;/span&gt; @waiaas/cli
waiaas init &lt;span class="nt"&gt;--auto-provision&lt;/span&gt;     &lt;span class="c"&gt;# Generates random master password → recovery.key&lt;/span&gt;
waiaas start                     &lt;span class="c"&gt;# No password prompt&lt;/span&gt;
waiaas quickset                  &lt;span class="c"&gt;# Creates wallets + sessions automatically&lt;/span&gt;
waiaas set-master                &lt;span class="c"&gt;# (Later) Harden password, then delete recovery.key&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The CLI has 20 commands covering everything from &lt;code&gt;backup create&lt;/code&gt; to &lt;code&gt;wallet info&lt;/code&gt;. The &lt;code&gt;quickset&lt;/code&gt; command is particularly useful — it creates wallets and MCP sessions in one step, printing the Claude Desktop config JSON you can paste directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Production Secrets (No Passwords in Environment Variables)
&lt;/h2&gt;

&lt;p&gt;Environment variables are convenient but they leak into &lt;code&gt;docker inspect&lt;/code&gt;, process lists, and log aggregators. For a production self-hosted setup, Docker Secrets are the right tool.&lt;/p&gt;

&lt;p&gt;WAIaaS ships a &lt;code&gt;docker-compose.secrets.yml&lt;/code&gt; overlay for exactly this purpose:&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="c"&gt;# Create secret files&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; secrets
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"your-secure-password"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; secrets/master_password.txt
&lt;span class="nb"&gt;chmod &lt;/span&gt;600 secrets/master_password.txt

&lt;span class="c"&gt;# Deploy with secrets overlay&lt;/span&gt;
docker compose &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.yml &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.secrets.yml up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The entrypoint script in the Docker image handles reading from Docker Secrets automatically — that's a built-in capability of the entrypoint, not something you need to wire up yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Watchtower for Automatic Updates
&lt;/h2&gt;

&lt;p&gt;This is the part that makes self-hosting sustainable. Watchtower watches your running containers, checks their registries for new image versions, and performs rolling updates automatically.&lt;/p&gt;

&lt;p&gt;Add Watchtower to your compose 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;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;daemon&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ghcr.io/waiaas/waiaas:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;waiaas-daemon&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1:3100:3100"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;waiaas-data:/data&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;WAIAAS_DATA_DIR=/data&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;WAIAAS_DAEMON_HOSTNAME=0.0.0.0&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;curl"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-f"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:3100/health"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;30s&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
      &lt;span class="na"&gt;start_period&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;

  &lt;span class="na"&gt;watchtower&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;containrrr/watchtower&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;watchtower&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;WATCHTOWER_CLEANUP=true&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;WATCHTOWER_POLL_INTERVAL=86400&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;waiaas-data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;WATCHTOWER_POLL_INTERVAL=86400&lt;/code&gt; checks for updates once a day. &lt;code&gt;WATCHTOWER_CLEANUP=true&lt;/code&gt; removes old image layers after updating, keeping your disk tidy.&lt;/p&gt;

&lt;p&gt;The WAIaaS image pulls from &lt;code&gt;ghcr.io/waiaas/waiaas:latest&lt;/code&gt; (GitHub Container Registry), which is public and doesn't require authentication for pulls. Watchtower will detect new pushes to that tag and update your local container automatically — with a graceful restart that preserves the named volume and all your wallet data.&lt;/p&gt;

&lt;p&gt;If you'd rather pin to a specific version and update manually, swap &lt;code&gt;:latest&lt;/code&gt; for a specific tag. That's a reasonable choice if you want to review release notes before updating a production wallet daemon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Configure Your RPC Endpoints
&lt;/h2&gt;

&lt;p&gt;By default, WAIaaS needs RPC endpoints to talk to blockchain networks. The key environment variables:&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="nv"&gt;WAIAAS_RPC_SOLANA_MAINNET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;url&amp;gt;         &lt;span class="c"&gt;# Solana mainnet RPC endpoint&lt;/span&gt;
&lt;span class="nv"&gt;WAIAAS_RPC_EVM_ETHEREUM_MAINNET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;url&amp;gt;   &lt;span class="c"&gt;# Ethereum mainnet RPC endpoint&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Put these in a &lt;code&gt;.env&lt;/code&gt; file in your project directory (it's in &lt;code&gt;.gitignore&lt;/code&gt; by default). The daemon supports 2 chain types — Solana and EVM — across 18 networks total. You only need to configure the ones you're actually using.&lt;/p&gt;

&lt;p&gt;For a privacy-conscious setup, this is where self-hosting really shines. You can point to your own RPC node, a private endpoint from a provider you trust, or a local node if you're running one. No third-party wallet service is sitting between your agent and the chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Create a Wallet and Lock It Down with Policies
&lt;/h2&gt;

&lt;p&gt;Once the daemon is running, create a wallet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/wallets &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"name": "trading-wallet", "chain": "solana", "environment": "mainnet"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create a session token for your AI agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/sessions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"walletId": "&amp;lt;wallet-uuid&amp;gt;"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent uses the session token (&lt;code&gt;wai_sess_...&lt;/code&gt;) for all its operations. Your master password never leaves your server.&lt;/p&gt;

&lt;p&gt;Before letting an agent loose with real funds, set up a spending policy. The policy engine has 21 policy types with 4 security tiers (INSTANT, NOTIFY, DELAY, APPROVAL) and enforces default-deny — transactions are blocked unless explicitly permitted:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 100,
      "notify_max_usd": 500,
      "delay_max_usd": 2000,
      "delay_seconds": 900,
      "daily_limit_usd": 5000
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This single policy means: transactions under $100 execute immediately, $100–$500 execute with a notification to you, $500–$2000 are queued for 15 minutes (cancellable), and anything over $2000 requires your explicit approval via WalletConnect or Telegram.&lt;/p&gt;

&lt;p&gt;The default-deny enforcement on &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt; and &lt;code&gt;CONTRACT_WHITELIST&lt;/code&gt; means if you haven't explicitly whitelisted a token or contract, the transaction is denied. An agent can't spend funds on something you haven't approved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checking That Everything Works
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Follow logs in real time&lt;/span&gt;
docker compose logs &lt;span class="nt"&gt;-f&lt;/span&gt;

&lt;span class="c"&gt;# Verify the healthcheck is passing&lt;/span&gt;
docker inspect waiaas-daemon &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{{.State.Health.Status}}'&lt;/span&gt;

&lt;span class="c"&gt;# Check your wallet balance from the agent's perspective&lt;/span&gt;
curl http://127.0.0.1:3100/v1/wallet/balance &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_eyJhbGciOiJIUzI1NiJ9..."&lt;/span&gt;

&lt;span class="c"&gt;# View the interactive API reference (if you want to explore)&lt;/span&gt;
open http://127.0.0.1:3100/reference
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;/reference&lt;/code&gt; endpoint serves an interactive Scalar API reference UI auto-generated from the OpenAPI 3.0 spec. There are 39 REST API route modules in total — the reference UI is the fastest way to explore them without reading source code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Management Commands You'll Actually Use
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;          &lt;span class="c"&gt;# Start daemon&lt;/span&gt;
docker compose logs &lt;span class="nt"&gt;-f&lt;/span&gt;        &lt;span class="c"&gt;# Follow logs&lt;/span&gt;
docker compose down           &lt;span class="c"&gt;# Stop (data preserved in named volume)&lt;/span&gt;
docker compose down &lt;span class="nt"&gt;-v&lt;/span&gt;        &lt;span class="c"&gt;# Stop + delete data volume (careful)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For CLI-based management, &lt;code&gt;waiaas status&lt;/code&gt; and &lt;code&gt;waiaas wallet info&lt;/code&gt; cover most day-to-day checks. The &lt;code&gt;waiaas backup create&lt;/code&gt; / &lt;code&gt;waiaas backup list&lt;/code&gt; / &lt;code&gt;waiaas restore&lt;/code&gt; commands handle your disaster recovery workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture in Brief
&lt;/h2&gt;

&lt;p&gt;What you're running is a daemon with a 7-stage transaction pipeline: validate → auth → policy → wait → execute → confirm. The policy check at stage 3 is where your spending limits, whitelists, and approval requirements get enforced. The "wait" stage handles the delay-tier queuing. Nothing reaches the chain without passing all prior stages.&lt;/p&gt;

&lt;p&gt;The daemon supports 15 DeFi protocol integrations (Aave v3, Jupiter, Hyperliquid, Lido, Jito, and others), 45 MCP tools for connecting AI agents via Claude Desktop, and 7 transaction types (Transfer, TokenTransfer, ContractCall, Approve, Batch, NftTransfer, ContractDeploy). All of that runs in a single Docker container on your hardware.&lt;/p&gt;

&lt;p&gt;For AI agent integration via the Model Context Protocol, the setup is a single CLI command after the daemon is running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;waiaas mcp setup &lt;span class="nt"&gt;--all&lt;/span&gt;    &lt;span class="c"&gt;# Auto-register all wallets with Claude Desktop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Your Keys, Your Server, Your Rules
&lt;/h2&gt;

&lt;p&gt;The philosophy here is straightforward: a self-hosted wallet daemon gives you the same trust model as running your own Bitcoin node. You verify things yourself. You don't depend on a third party's uptime, pricing decisions, or data retention policies.&lt;/p&gt;

&lt;p&gt;With Watchtower handling updates from GHCR and Docker Secrets keeping your master password out of environment variables, you get a production setup that's both sovereign and maintainable. The 684+ test files in the codebase mean updates hitting &lt;code&gt;:latest&lt;/code&gt; have been through a real test suite before you pull them.&lt;/p&gt;

&lt;p&gt;The full source is at &lt;a href="https://github.com/waiaas/WAIaaS" rel="noopener noreferrer"&gt;https://github.com/waiaas/WAIaaS&lt;/a&gt; — worth reading the Docker entrypoint and compose files yourself before running anything in production. And the project home with documentation is at &lt;a href="https://waiaas.ai" rel="noopener noreferrer"&gt;https://waiaas.ai&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you're already comfortable self-hosting services, the hardest part of this setup is probably choosing which DeFi protocols to whitelist — not the deployment itself.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>selfhosted</category>
      <category>devops</category>
      <category>web3</category>
    </item>
    <item>
      <title>Automated Yield Strategy Bots: Pendle + Kamino + Lido Cross-Chain Optimization</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Thu, 08 Oct 2026 13:42:20 +0000</pubDate>
      <link>https://dev.to/walletguy/automated-yield-strategy-bots-pendle-kamino-lido-cross-chain-optimization-30m4</link>
      <guid>https://dev.to/walletguy/automated-yield-strategy-bots-pendle-kamino-lido-cross-chain-optimization-30m4</guid>
      <description>&lt;h1&gt;
  
  
  Automated Yield Strategy Bots: Pendle + Kamino + Lido Cross-Chain Optimization
&lt;/h1&gt;

&lt;p&gt;Building a DeFi yield optimization bot means wiring together Pendle for fixed-rate yield, Kamino for Solana liquidity, and Lido for liquid staking — and doing that across both EVM and Solana chains in a single coherent strategy. Most developers end up with a graveyard of half-finished protocol SDKs, inconsistent error handling, and fragile RPC logic before they even write the first line of strategy code. WAIaaS gives you one unified API across 15 DeFi protocols and 18 networks so you can focus on the strategy, not the plumbing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Problem: Protocol Fragmentation
&lt;/h2&gt;

&lt;p&gt;Cross-chain yield optimization isn't conceptually hard. The idea is simple: find the best risk-adjusted yield available, rotate capital toward it, and hedge where needed. Pendle lets you strip fixed yield from yield-bearing tokens. Kamino concentrates liquidity on Solana for boosted LP returns. Lido gives you stETH so your staked ETH keeps earning while you deploy it elsewhere.&lt;/p&gt;

&lt;p&gt;The implementation is hard because each of those protocols has its own SDK, its own transaction format, its own RPC requirements, and its own quirks. Add in cross-chain bridging via LI.FI or Across, and you're now managing async state across multiple chains simultaneously. A bot that sounds like a weekend project turns into a months-long integration effort — before you've written a single line of strategy logic.&lt;/p&gt;

&lt;p&gt;The stakes are real. Yield optimization bots that can't react quickly to rate changes leave basis points on the table. Bots that have brittle multi-SDK setups go down at the worst moments. And bots that don't have proper policy guardrails can drain a wallet on a bad parameter.&lt;/p&gt;

&lt;h2&gt;
  
  
  One API Across 15 Protocols
&lt;/h2&gt;

&lt;p&gt;WAIaaS integrates 15 DeFi protocol providers: aave-v3, across, dcent-swap, drift, erc8004, hyperliquid, jito-staking, jupiter-swap, kamino, lido-staking, lifi, pendle, polymarket, xrpl-dex, and zerox-swap. That's the full stack for a cross-chain yield strategy — Lido and Aave on EVM, Kamino and Jito on Solana, Pendle for fixed yield, LI.FI or Across for bridging — all behind a single REST API running locally at &lt;code&gt;127.0.0.1:3100&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The architecture is straightforward. You spin up the WAIaaS daemon (one Docker container), create wallets for each chain, create session tokens for your bot, set spending policies, and then call the action API. Every DeFi operation goes through the same endpoint pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;POST /v1/actions/&amp;lt;provider&amp;gt;/&amp;lt;action&amp;gt;
Authorization: Bearer wai_sess_&amp;lt;token&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your bot doesn't need to know about Kamino's SDK, Pendle's contract ABI, or Lido's submit method. It just speaks REST.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structuring a Cross-Chain Yield Bot
&lt;/h2&gt;

&lt;p&gt;Here's how you'd architect a Pendle + Kamino + Lido optimization bot using WAIaaS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Separate wallets per chain.&lt;/strong&gt; You want an EVM wallet for Lido/Pendle/Aave and a Solana wallet for Kamino/Jito/Jupiter. Each wallet gets its own session token. Your strategy engine holds both tokens and routes actions to the right one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Policy first, strategy second.&lt;/strong&gt; Before your bot executes anything, define the guardrails. A spending limit policy with a daily cap, an allowed tokens whitelist, and a contract whitelist prevents a strategy bug from becoming a catastrophic loss.&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="c"&gt;# Create spending limit on the EVM wallet&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;evm-wallet-uuid&amp;gt;",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 100,
      "notify_max_usd": 1000,
      "delay_max_usd": 10000,
      "delay_seconds": 900,
      "daily_limit_usd": 50000
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Transactions above $10,000 will queue for 15 minutes before executing. Transactions above the daily limit get blocked entirely. This isn't optional safety theater — it's the difference between a recoverable bug and a drained wallet.&lt;/p&gt;

&lt;p&gt;The policy engine supports 21 policy types. For a yield bot specifically, &lt;code&gt;LENDING_LTV_LIMIT&lt;/code&gt; is critical: it caps the loan-to-value ratio your bot can reach on Aave or Kamino lending. &lt;code&gt;LENDING_ASSET_WHITELIST&lt;/code&gt; ensures the bot can only supply or borrow approved assets. &lt;code&gt;CONTRACT_WHITELIST&lt;/code&gt; enforces that only known protocol contracts can be called.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Check positions before acting.&lt;/strong&gt; Your strategy loop should start by reading the current state. WAIaaS exposes DeFi positions across protocols through a single call that returns lending positions, staking balances, and LP positions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://127.0.0.1:3100/v1/wallet/balance &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_eyJhbGciOiJIUzI1NiJ9..."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4: Execute the strategy actions.&lt;/strong&gt; Here's where the unified API pays off. Lido staking, a Jupiter swap on Solana, and a Kamino deposit all follow the same pattern — you just change the provider name.&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="c"&gt;# Stake ETH via Lido&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/actions/lido-staking/stake &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_&amp;lt;evm-token&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "amount": "1.0",
    "network": "ethereum-mainnet"
  }'&lt;/span&gt;

&lt;span class="c"&gt;# Swap SOL → USDC via Jupiter before depositing to Kamino&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/actions/jupiter-swap/swap &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_&amp;lt;solana-token&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "inputMint": "So11111111111111111111111111111111111111112",
    "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "amount": "1000000000"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Pendle, you're interacting with yield token markets — buying PT (principal tokens) to lock in a fixed rate, or LP'ing to earn trading fees. For cross-chain rebalancing, you'd route through LI.FI or Across depending on which bridge offers better rates for that specific route.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dry-Run Before Every Rebalance
&lt;/h2&gt;

&lt;p&gt;Any strategy that moves meaningful capital should simulate before executing. WAIaaS has a dry-run flag on every transaction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/transactions/send &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_&amp;lt;token&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "type": "TRANSFER",
    "to": "recipient-address",
    "amount": "0.1",
    "dryRun": true
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pass &lt;code&gt;"dryRun": true&lt;/code&gt; and the request runs through the full 7-stage transaction pipeline — validation, auth check, policy evaluation, gas estimation — but stops before broadcasting. You get back exactly what would happen, including any policy denial, without committing to the chain. For a yield bot that's rebalancing every few hours, this is how you validate the move before making it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The TypeScript SDK for Strategy Code
&lt;/h2&gt;

&lt;p&gt;If you're writing your strategy engine in TypeScript rather than shelling out to curl, the &lt;code&gt;@waiaas/sdk&lt;/code&gt; package wraps the REST API cleanly:&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;WAIaaSClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;WAIaaSError&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@waiaas/sdk&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;evmClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WAIaaSClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://127.0.0.1:3100&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;sessionToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EVM_SESSION_TOKEN&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;solanaClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WAIaaSClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://127.0.0.1:3100&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;sessionToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SOLANA_SESSION_TOKEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Check balances on both chains before deciding where to rotate yield&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;evmBalance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;solanaBalance&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="nx"&gt;evmClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="nx"&gt;solanaClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`EVM: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;evmBalance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;evmBalance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Solana: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;solanaBalance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;solanaBalance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Error handling is typed and consistent across every protocol:&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;try&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;tx&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;evmClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendToken&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1.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="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;WAIaaSError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// error.code: INSUFFICIENT_BALANCE, POLICY_DENIED, TOKEN_EXPIRED&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`[&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;] &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POLICY_DENIED&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;// Strategy tried to exceed spending limit — log and skip this cycle&lt;/span&gt;
    &lt;span class="p"&gt;}&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;The SDK covers &lt;code&gt;getBalance()&lt;/code&gt;, &lt;code&gt;getAddress()&lt;/code&gt;, &lt;code&gt;getAssets()&lt;/code&gt;, &lt;code&gt;sendToken()&lt;/code&gt;, &lt;code&gt;getTransaction()&lt;/code&gt;, &lt;code&gt;listTransactions()&lt;/code&gt;, &lt;code&gt;signTransaction()&lt;/code&gt;, and &lt;code&gt;x402Fetch()&lt;/code&gt; — enough to build a complete strategy loop without touching the raw REST API at all. A Python SDK (&lt;code&gt;pip install waiaas&lt;/code&gt;) is also available with async/await support for teams that prefer Python for quant work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gas-Conditional Execution
&lt;/h2&gt;

&lt;p&gt;Yield optimization on EVM is heavily gas-sensitive. Rebalancing a Pendle position during a gas spike can wipe out days of yield. WAIaaS has a gas conditional execution feature that holds a transaction until the gas price meets a threshold — the transaction queues and executes automatically when conditions are met, without your bot needing to poll.&lt;/p&gt;

&lt;p&gt;This is particularly useful for Lido staking operations and Aave supply/withdraw calls that don't need to happen in the same block they're triggered — you set the gas threshold and let the daemon handle the timing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Human-in-the-Loop for Large Moves
&lt;/h2&gt;

&lt;p&gt;For rebalancing moves above a certain size — say, bridging $50k from EVM to Solana via Across — you probably want a human to approve before execution. The policy engine's &lt;code&gt;APPROVAL&lt;/code&gt; tier combined with WalletConnect integration handles this:&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="c"&gt;# Approve a pending transaction (ownerAuth via WalletConnect or Telegram)&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/transactions/&amp;lt;tx-id&amp;gt;/approve &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Owner-Signature: &amp;lt;ed25519-or-secp256k1-signature&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Owner-Message: &amp;lt;signed-message&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a transaction hits the &lt;code&gt;APPROVAL&lt;/code&gt; tier, the daemon sends a push notification through the configured signing channel (push relay, Telegram, or WalletConnect). The fund owner reviews and signs on their phone. The bot waits. Once approved, execution continues automatically.&lt;/p&gt;

&lt;p&gt;This is how you build a yield bot that scales to serious capital: the bot handles the analysis and routine operations autonomously, but large moves require a human signature.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start: From Zero to Running Strategy
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Start the daemon&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/waiaas/WAIaaS.git
&lt;span class="nb"&gt;cd &lt;/span&gt;WAIaaS
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Create wallets and sessions via CLI&lt;/strong&gt;&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; &lt;span class="nt"&gt;-g&lt;/span&gt; @waiaas/cli
waiaas quickset &lt;span class="nt"&gt;--mode&lt;/span&gt; mainnet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates wallets across chains and outputs MCP session config in one step. For programmatic setup, use the REST API directly:&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="c"&gt;# Create EVM wallet&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/wallets &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"name": "evm-yield", "chain": "evm", "environment": "mainnet"}'&lt;/span&gt;

&lt;span class="c"&gt;# Create session for your bot&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/sessions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"walletId": "&amp;lt;wallet-uuid&amp;gt;"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Set policies before funding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Configure &lt;code&gt;SPENDING_LIMIT&lt;/code&gt;, &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt;, &lt;code&gt;CONTRACT_WHITELIST&lt;/code&gt;, and &lt;code&gt;LENDING_LTV_LIMIT&lt;/code&gt; before sending any capital to the wallet. The policy engine is default-deny: transactions to contracts not on the whitelist are blocked automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Install the SDK and write your strategy&lt;/strong&gt;&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; @waiaas/sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your strategy loop calls &lt;code&gt;getBalance()&lt;/code&gt; → evaluate yield opportunities → dry-run the rebalance → execute if simulation passes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Explore the interactive API docs&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;open http://127.0.0.1:3100/reference
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interactive Scalar API reference at &lt;code&gt;/reference&lt;/code&gt; documents all 39 REST API route modules with live request/response examples. It's the fastest way to explore what's available for a specific protocol before writing code.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The 15 DeFi protocol integrations in WAIaaS cover the most common yield strategies, but the architecture is built for composition — Pendle PT positions hedged with Hyperliquid perps, Kamino LP positions funded via Jupiter swaps, Lido stETH bridged to Solana via Across. The policy engine with 21 policy types gives you the guardrails to run those strategies with real capital.&lt;/p&gt;

&lt;p&gt;Explore the full codebase and open issues on GitHub at &lt;a href="https://github.com/waiaas/WAIaaS" rel="noopener noreferrer"&gt;https://github.com/waiaas/WAIaaS&lt;/a&gt;, and see the complete documentation and protocol coverage at &lt;a href="https://waiaas.ai" rel="noopener noreferrer"&gt;https://waiaas.ai&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>defi</category>
      <category>web3</category>
      <category>ethereum</category>
      <category>solana</category>
    </item>
    <item>
      <title>Claude Desktop Checks AI Reputation: MCP Tools for ERC-8004 Trustless Agent Validation</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Wed, 07 Oct 2026 19:19:19 +0000</pubDate>
      <link>https://dev.to/walletguy/claude-desktop-checks-ai-reputation-mcp-tools-for-erc-8004-trustless-agent-validation-2bgf</link>
      <guid>https://dev.to/walletguy/claude-desktop-checks-ai-reputation-mcp-tools-for-erc-8004-trustless-agent-validation-2bgf</guid>
      <description>&lt;h1&gt;
  
  
  Claude Desktop Checks AI Reputation: MCP Tools for ERC-8004 Trustless Agent Validation
&lt;/h1&gt;

&lt;p&gt;MCP tools are the fastest way to give your Claude agent onchain superpowers — and with WAIaaS, you can add not just a wallet and DeFi access, but also the ability to verify the reputation of other AI agents before trusting them with anything valuable. One config entry. Forty-five tools. And two of them let your agent check whether another agent has earned the right to interact with it onchain.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: Your Agent Can't Tell Who It's Dealing With
&lt;/h2&gt;

&lt;p&gt;As AI agents proliferate, they're increasingly interacting with each other — one agent delegating to another, one service calling another service's agent interface, one autonomous system handing off a transaction to a specialized bot. That's exciting. It's also a trust problem nobody has fully solved yet.&lt;/p&gt;

&lt;p&gt;How does your agent know the other agent it's handing money to is legitimate? How does it verify reputation without a centralized registry you have to trust blindly? If you're building multi-agent workflows in Claude Desktop, this is going to become your problem sooner than you think.&lt;/p&gt;

&lt;p&gt;ERC-8004 is one answer. It's a standard for onchain agent reputation and validation — a way to record, query, and verify an agent's track record directly on the blockchain, no middleman required. WAIaaS integrates ERC-8004 as part of its MCP server, which means your Claude agent can query agent reputation and validation status just like it checks a wallet balance or executes a swap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Onchain Reputation Matters for Autonomous Agents
&lt;/h2&gt;

&lt;p&gt;Think about what your agent is being asked to do. If it's a trading bot, it's moving real money. If it's a DeFi manager, it's approving token spend limits, opening lending positions, setting leverage. If it's part of a multi-agent system, it may receive instructions from upstream agents it didn't choose.&lt;/p&gt;

&lt;p&gt;In that context, "I received a transaction request from another agent" is a security event, not just an input. You want to know: has this agent been validated? What's its reputation score? Is it above the threshold you've configured?&lt;/p&gt;

&lt;p&gt;WAIaaS provides three things that work together here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;ERC-8004 MCP tools&lt;/strong&gt; — so Claude can query agent info and reputation directly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;REPUTATION_THRESHOLD policy&lt;/strong&gt; — so you can enforce a minimum reputation score at the transaction pipeline level&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Default-deny policy enforcement&lt;/strong&gt; — so nothing goes through unless it's explicitly allowed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The combination means you can build Claude workflows where your agent actively checks who it's dealing with before executing anything sensitive.&lt;/p&gt;

&lt;h2&gt;
  
  
  One Line in Your Config
&lt;/h2&gt;

&lt;p&gt;Let's start at the beginning. Adding WAIaaS to Claude Desktop is a single config entry:&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;"waiaas"&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;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@waiaas/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;"WAIAAS_BASE_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;"http://127.0.0.1:3100"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"WAIAAS_SESSION_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wai_sess_&amp;lt;your-token&amp;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;"WAIAAS_DATA_DIR"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~/.waiaas"&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;Paste that into &lt;code&gt;~/Library/Application Support/Claude/claude_desktop_config.json&lt;/code&gt;, restart Claude Desktop, and your agent now has access to 45 MCP tools — including &lt;code&gt;erc8004-get-agent-info&lt;/code&gt;, &lt;code&gt;erc8004-get-reputation&lt;/code&gt;, and &lt;code&gt;erc8004-get-validation-status&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you haven't set up the daemon yet, the CLI quickstart gets you there in under two minutes:&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; &lt;span class="nt"&gt;-g&lt;/span&gt; @waiaas/cli
waiaas init
waiaas start
waiaas quickset &lt;span class="nt"&gt;--mode&lt;/span&gt; mainnet
waiaas mcp setup &lt;span class="nt"&gt;--all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;waiaas mcp setup --all&lt;/code&gt; auto-registers all your wallets and prints the MCP config JSON directly. Copy, paste, done.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three ERC-8004 Tools
&lt;/h2&gt;

&lt;p&gt;Once WAIaaS is connected as an MCP server, Claude has three tools specifically for agent reputation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;erc8004-get-agent-info&lt;/code&gt;&lt;/strong&gt; — Retrieves the onchain profile of an agent by address. Use this when your agent receives a delegation request, an inbound transaction, or a message claiming to be from a specific agent. Before acting on it, ask: who actually is this?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;erc8004-get-reputation&lt;/code&gt;&lt;/strong&gt; — Returns the reputation score for an agent address. This is the quantitative signal — a number derived from onchain activity that reflects the agent's track record.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;erc8004-get-validation-status&lt;/code&gt;&lt;/strong&gt; — Returns whether the agent has passed validation according to the ERC-8004 standard. Validation is a harder gate than reputation score — it's a binary pass/fail based on the protocol's criteria.&lt;/p&gt;

&lt;p&gt;In practice, Claude can chain these together in a workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User: "I received a delegation request from agent 0xABCD...1234. Should I accept?"
→ Claude calls erc8004-get-agent-info → retrieves agent profile
→ Claude calls erc8004-get-reputation → checks reputation score
→ Claude calls erc8004-get-validation-status → checks validation pass/fail
→ Claude summarizes: "This agent has [score] reputation and [passed/failed] validation. Here's what I found..."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No custom code. No API wrappers. Just the tools that are already there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enforcing Reputation at the Policy Layer
&lt;/h2&gt;

&lt;p&gt;The MCP tools let your agent &lt;em&gt;query&lt;/em&gt; reputation. The policy engine lets you &lt;em&gt;enforce&lt;/em&gt; it — automatically, before any transaction executes.&lt;/p&gt;

&lt;p&gt;WAIaaS has a 21-type policy engine with a 4-tier security model (INSTANT, NOTIFY, DELAY, APPROVAL) and default-deny enforcement. One of those 21 types is &lt;code&gt;REPUTATION_THRESHOLD&lt;/code&gt; — and it does exactly what it sounds like: transactions from agents below a configured reputation threshold are blocked at the pipeline level, before they reach execution.&lt;/p&gt;

&lt;p&gt;Here's how you create that policy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'X-Master-Password: &amp;lt;password&amp;gt;'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 10,
      "notify_max_usd": 100,
      "delay_max_usd": 1000,
      "delay_seconds": 300,
      "daily_limit_usd": 500,
      "monthly_limit_usd": 5000
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Layer a &lt;code&gt;REPUTATION_THRESHOLD&lt;/code&gt; policy on top, and your wallet won't execute transactions from agents that haven't met the bar — even if Claude is willing to try. The pipeline enforces it independently.&lt;/p&gt;

&lt;p&gt;This matters because it separates concerns cleanly. Claude makes decisions. The policy engine enforces constraints. The two don't need to agree for the constraint to hold — the policy engine runs regardless of what the agent wants to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Full Security Stack
&lt;/h2&gt;

&lt;p&gt;ERC-8004 reputation checking is one layer. WAIaaS gives you several others that work together:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3-layer security architecture:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Session auth → time delay + approval → monitoring + kill switch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3 auth methods:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;masterAuth&lt;/code&gt; (Argon2id) — for wallet creation, session management, policies&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ownerAuth&lt;/code&gt; (SIWS/SIWE) — for transaction approval and kill switch recovery&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sessionAuth&lt;/code&gt; (JWT HS256) — for your AI agent's day-to-day operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The 7-stage transaction pipeline&lt;/strong&gt; runs every transaction through: validate → auth → policy → wait → execute → confirm. Reputation threshold checks happen at the policy stage, before execution. If a transaction fails the reputation check, you get a structured error back:&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;"error"&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;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POLICY_DENIED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Transaction denied by SPENDING_LIMIT policy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POLICY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"retryable"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&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;(Substitute &lt;code&gt;REPUTATION_THRESHOLD&lt;/code&gt; for &lt;code&gt;SPENDING_LIMIT&lt;/code&gt; in the real-world case — the structure is the same.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WalletConnect integration&lt;/strong&gt; means large or suspicious transactions can be routed to you for manual approval on your phone, via WalletConnect. The APPROVAL security tier in the policy engine triggers this automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multi-Agent Setups: One MCP Server Per Wallet
&lt;/h2&gt;

&lt;p&gt;If you're running multi-agent workflows — say, a trading agent and a separate analytics agent — you can give each its own wallet and MCP server instance:&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;"waiaas-trading"&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;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@waiaas/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;"WAIAAS_BASE_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;"http://127.0.0.1:3100"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"WAIAAS_AGENT_ID"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"019c47d6-51ef-7f43-a76b-d50e875d95f4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"WAIAAS_AGENT_NAME"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"trading-agent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"WAIAAS_DATA_DIR"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~/.waiaas"&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="nl"&gt;"waiaas-solana"&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;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@waiaas/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;"WAIAAS_BASE_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;"http://127.0.0.1:3100"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"WAIAAS_AGENT_ID"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"019c4cd2-86e8-758f-a61e-9c560307c788"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"WAIAAS_AGENT_NAME"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"solana-wallet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"WAIAAS_DATA_DIR"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~/.waiaas"&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;Each agent gets its own session token, its own spending limits, its own reputation threshold. They share a single daemon. The daemon handles isolation.&lt;/p&gt;

&lt;p&gt;In this setup, if the trading agent wants to pass a task to the Solana agent, the Solana agent's policy layer can require the trading agent to have a minimum ERC-8004 reputation before accepting — enforced automatically, no extra code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start: ERC-8004 Validation in Claude Desktop
&lt;/h2&gt;

&lt;p&gt;Here's the minimal path to having Claude check agent reputation onchain:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Install the daemon&lt;/strong&gt;&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; &lt;span class="nt"&gt;-g&lt;/span&gt; @waiaas/cli
waiaas init
waiaas start
waiaas quickset &lt;span class="nt"&gt;--mode&lt;/span&gt; mainnet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Get your MCP config&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;waiaas mcp setup &lt;span class="nt"&gt;--all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the printed JSON into your Claude Desktop config file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Restart Claude Desktop&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your agent now has 45 tools, including &lt;code&gt;erc8004-get-agent-info&lt;/code&gt;, &lt;code&gt;erc8004-get-reputation&lt;/code&gt;, and &lt;code&gt;erc8004-get-validation-status&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Test it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Claude Desktop, type:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Use the ERC-8004 tools to check the reputation of agent address [some-address]."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Claude will call the tools, return the results, and you can build from there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Add a reputation policy via the API&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://127.0.0.1:3100/reference
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Browse to the interactive API reference and create a &lt;code&gt;REPUTATION_THRESHOLD&lt;/code&gt; policy for your wallet. Transactions from low-reputation agents will be blocked automatically from that point forward.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Broader Picture: 45 Tools, 15 DeFi Protocols
&lt;/h2&gt;

&lt;p&gt;ERC-8004 is one slice of what's available. The full MCP server ships with 45 tools across wallet management, transactions, DeFi, NFTs, and the x402 HTTP payment protocol. The 15 integrated DeFi protocols include Aave v3, Jupiter, Uniswap (via 0x), Hyperliquid, Lido, Jito, Kamino, Pendle, Polymarket, and more — accessible from Claude with natural language.&lt;/p&gt;

&lt;p&gt;Agent reputation checking sits alongside tools like &lt;code&gt;simulate-transaction&lt;/code&gt; (dry-run before executing), &lt;code&gt;get-health-factor&lt;/code&gt; (check lending position health), &lt;code&gt;send-batch&lt;/code&gt; (multiple operations in one call), and &lt;code&gt;wc-connect&lt;/code&gt; (WalletConnect for owner approval). They're all in the same server. They all benefit from the same policy enforcement.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;Explore the full list of 45 MCP tools, the 21 policy types, and the interactive API reference at &lt;a href="https://waiaas.ai" rel="noopener noreferrer"&gt;https://waiaas.ai&lt;/a&gt;. The source code — including the ERC-8004 provider, the MCP tools, and the policy engine — is all open source at &lt;a href="https://github.com/waiaas/WAIaaS" rel="noopener noreferrer"&gt;https://github.com/waiaas/WAIaaS&lt;/a&gt;. If you're building multi-agent workflows where trust between agents matters, the combination of ERC-8004 MCP tools and the REPUTATION_THRESHOLD policy is the place to start.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>web3</category>
      <category>llm</category>
    </item>
    <item>
      <title>Economic Infrastructure for AI Agents: The Missing Layer Between Code and Commerce</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Wed, 07 Oct 2026 13:36:51 +0000</pubDate>
      <link>https://dev.to/walletguy/economic-infrastructure-for-ai-agents-the-missing-layer-between-code-and-commerce-2kga</link>
      <guid>https://dev.to/walletguy/economic-infrastructure-for-ai-agents-the-missing-layer-between-code-and-commerce-2kga</guid>
      <description>&lt;h1&gt;
  
  
  Economic Infrastructure for AI Agents: The Missing Layer Between Code and Commerce
&lt;/h1&gt;

&lt;p&gt;AI agents will need to pay for compute, data, and API calls — and right now, there is no clean answer for how that happens. The missing piece isn't smarter models or better orchestration frameworks. It's economic infrastructure: a wallet layer that agents can operate independently, without a human holding the keys on their behalf. That gap exists today, and it's worth thinking seriously about what fills it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Actually Matters
&lt;/h2&gt;

&lt;p&gt;Consider what happens when an AI agent needs to call a paid API. Today, a developer hardcodes credentials, prepays a quota, and manually tops up accounts when they run low. The agent itself has no awareness of cost, no ability to authorize a payment, and no way to operate economically on its own. It's entirely dependent on the infrastructure a human built around it.&lt;/p&gt;

&lt;p&gt;This is fine for demos. It breaks down at scale. When you have dozens of agents running concurrently — each accessing different data providers, spinning up compute, paying for inference — the overhead of managing all that manually becomes untenable. More importantly, it creates a fundamental asymmetry: the agent can think, reason, and act, but it can't pay. It can't participate in the economy it's operating inside.&lt;/p&gt;

&lt;p&gt;The stakes are higher than developer convenience. If autonomous agents are going to be genuinely useful — doing research, managing operations, executing strategies — they need the ability to transact. Not accounts custodied by a developer who might be asleep at 3am. Real, autonomous wallet infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Infrastructure That Already Exists
&lt;/h2&gt;

&lt;p&gt;WAIaaS (Wallet-as-a-Service for AI Agents) is an open-source, self-hosted daemon that gives AI agents exactly this. It's not a concept or a whitepaper — it's a running service with a REST API, an MCP integration, TypeScript and Python SDKs, and a policy engine that lets you define precisely what agents are allowed to do economically.&lt;/p&gt;

&lt;p&gt;The architecture is worth understanding because it's designed specifically for the agent use case.&lt;/p&gt;

&lt;h3&gt;
  
  
  Three Auth Layers, Each for a Different Principal
&lt;/h3&gt;

&lt;p&gt;WAIaaS separates three different principals with different levels of trust:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;masterAuth&lt;/strong&gt; (Argon2id) — The system administrator. Creates wallets, manages sessions, configures policies. This is you, the developer, at setup time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;sessionAuth&lt;/strong&gt; (JWT HS256) — The AI agent. This is the token you hand to the agent. It can transact, check balances, execute DeFi actions — within the limits you've defined.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ownerAuth&lt;/strong&gt; (SIWS/SIWE) — The fund owner. Signs approvals for high-value transactions via WalletConnect or Telegram. The human in the loop, but only when the policy says they need to be.&lt;/p&gt;

&lt;p&gt;This separation matters. The agent never needs admin credentials. It gets a scoped session token with expiry, renewal limits, and an absolute lifetime. If the token leaks or the agent misbehaves, you revoke it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Giving an Agent a Wallet
&lt;/h3&gt;

&lt;p&gt;Setup is a few API calls:&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="c"&gt;# Create a wallet&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/wallets &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"name": "trading-wallet", "chain": "solana", "environment": "mainnet"}'&lt;/span&gt;

&lt;span class="c"&gt;# Create a session token for the agent&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/sessions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"walletId": "&amp;lt;wallet-uuid&amp;gt;"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent gets back a &lt;code&gt;wai_sess_...&lt;/code&gt; token. That token is the agent's economic identity. Everything it does financially flows through that session.&lt;/p&gt;

&lt;p&gt;From the agent's perspective — whether it's a Python script, a TypeScript service, or a Claude conversation via MCP — usage looks like this:&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;WAIaaSClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@waiaas/sdk&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WAIaaSClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://127.0.0.1:3100&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;sessionToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WAIAAS_SESSION_TOKEN&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;balance&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;tx&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendToken&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;recipient-address...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0.1&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Transaction: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent checks its balance. It sends tokens. It polls for confirmation. This is economic participation — the agent has genuine awareness of its financial state and can act on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The x402 Protocol: Machines That Pay for What They Use
&lt;/h2&gt;

&lt;p&gt;One of the most interesting pieces in this stack is x402 support. The x402 HTTP payment protocol is a standard where an API server responds with HTTP 402 (Payment Required) when an unauthenticated request arrives. The client — in this case, an AI agent — sees the payment terms, authorizes a micropayment, and retries the request. All automatically.&lt;/p&gt;

&lt;p&gt;WAIaaS includes an &lt;code&gt;x402-fetch&lt;/code&gt; tool in its 45 MCP tools and an &lt;code&gt;x402Fetch()&lt;/code&gt; method in the SDK. An agent can call any x402-enabled API and pay for it transparently, without human intervention.&lt;/p&gt;

&lt;p&gt;This is the mechanism that makes "agents pay for compute" real rather than hypothetical. A data provider publishes an x402 endpoint. An agent with a WAIaaS wallet calls it. The payment happens. The data is returned. No prepaid API keys, no quota management, no developer woken up at 3am to top up a balance.&lt;/p&gt;

&lt;p&gt;The policy layer makes this safe. You can configure &lt;code&gt;X402_ALLOWED_DOMAINS&lt;/code&gt; — a whitelist of domains the agent is permitted to pay. Payments to anything outside that list are blocked automatically.&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="nl"&gt;"domains"&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;"api.example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*.openai.com"&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;The agent has autonomy within bounds you define. That's the right model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Policy Engine: Autonomy With Guardrails
&lt;/h2&gt;

&lt;p&gt;Autonomous doesn't mean uncontrolled. WAIaaS ships a policy engine with 21 policy types and 4 security tiers. Every transaction runs through a 7-stage pipeline — validate, auth, policy check, wait, execute, confirm. A transaction that doesn't pass policy never executes.&lt;/p&gt;

&lt;p&gt;The four tiers are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;INSTANT&lt;/strong&gt; — Execute immediately, no notification&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NOTIFY&lt;/strong&gt; — Execute immediately, send you a notification&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DELAY&lt;/strong&gt; — Queue for N seconds, then execute (you can cancel in the window)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;APPROVAL&lt;/strong&gt; — Require explicit human approval via WalletConnect or Telegram&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The spending limit policy maps transaction amounts to tiers automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 100,
      "notify_max_usd": 500,
      "delay_max_usd": 2000,
      "delay_seconds": 900,
      "daily_limit_usd": 5000
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Under $100: the agent moves immediately. $100-$500: it moves and you get a notification. $500-$2000: it queues for 15 minutes — you can cancel if something looks wrong. Over $2000: it waits for your explicit approval.&lt;/p&gt;

&lt;p&gt;This is the right mental model for agent economics. Not "the agent can do anything" and not "the agent can do nothing without asking." A graduated autonomy that scales with risk. Small transactions — paying for an API call, executing a routine swap — happen without friction. Large transactions surface to the human who should be aware of them.&lt;/p&gt;

&lt;p&gt;The policy system also includes DeFi-specific controls: &lt;code&gt;PERP_MAX_LEVERAGE&lt;/code&gt; for perpetual futures, &lt;code&gt;LENDING_LTV_LIMIT&lt;/code&gt; for lending protocols, &lt;code&gt;PERP_MAX_POSITION_USD&lt;/code&gt; for position sizing, &lt;code&gt;REPUTATION_THRESHOLD&lt;/code&gt; for ERC-8004 agent reputation validation. These aren't generic financial controls bolted onto a wallet — they're designed for agents operating in DeFi.&lt;/p&gt;

&lt;p&gt;Default-deny enforcement means if you haven't configured &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt; or &lt;code&gt;CONTRACT_WHITELIST&lt;/code&gt;, transactions are blocked. An agent with a fresh wallet can't do anything harmful by default. You opt into capabilities explicitly.&lt;/p&gt;

&lt;h2&gt;
  
  
  DeFi Access: 15 Protocols, Ready to Use
&lt;/h2&gt;

&lt;p&gt;When we talk about agent economic activity, we're not just talking about sending tokens. Agents operating in DeFi need to swap, stake, lend, borrow, bridge, and trade. WAIaaS integrates 15 DeFi protocol providers directly: Aave v3, Across, D'CENT Swap, Drift, Hyperliquid, Jito Staking, Jupiter Swap, Kamino, Lido Staking, LI.FI, Pendle, Polymarket, XRPL DEX, and 0x Swap, plus ERC-8004 for onchain agent reputation.&lt;/p&gt;

&lt;p&gt;An agent executing a Jupiter swap on Solana looks like this via the REST API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/actions/jupiter-swap/swap &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_&amp;lt;token&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "inputMint": "So11111111111111111111111111111111111111112",
    "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "amount": "1000000000"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent passes through the same 7-stage pipeline as any other transaction — policy checks, gas conditions, dry-run simulation if configured. The fact that it's a DeFi action rather than a native transfer doesn't bypass any of the safety machinery.&lt;/p&gt;

&lt;p&gt;Critically, you can simulate any transaction before execution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/transactions/send &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_&amp;lt;token&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "type": "TRANSFER",
    "to": "recipient-address",
    "amount": "0.1",
    "dryRun": true
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;dryRun: true&lt;/code&gt; runs the entire pipeline — validation, policy checks, simulation — without broadcasting. An agent can verify what a transaction will do before committing. This matters enormously for agents operating with real funds. You want to know before the fact, not after.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting to AI Frameworks: MCP and OpenClaw
&lt;/h2&gt;

&lt;p&gt;The most direct path to giving an existing AI agent economic capabilities is through the Model Context Protocol (MCP) integration. WAIaaS ships 45 MCP tools covering wallet operations, transactions, DeFi positions, NFTs, and x402 payments.&lt;/p&gt;

&lt;p&gt;Setup with Claude Desktop is a single CLI command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;waiaas mcp setup &lt;span class="nt"&gt;--all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or manual configuration:&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;"waiaas"&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;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@waiaas/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;"WAIAAS_BASE_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;"http://127.0.0.1:3100"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"WAIAAS_SESSION_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wai_sess_&amp;lt;your-token&amp;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;"WAIAAS_DATA_DIR"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~/.waiaas"&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;After that, Claude — or any MCP-compatible agent framework — can check balances, send tokens, query DeFi positions, and execute swaps through natural conversation. The agent isn't simulating financial capability. It has a real wallet, real funds, real transactions.&lt;/p&gt;

&lt;p&gt;For agents built outside MCP-compatible frameworks, the OpenClaw plugin provides 5 tool categories (wallet, transfer, DeFi, NFT, utility) for integration with external AI agent frameworks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start: From Zero to Agent Wallet in Five Minutes
&lt;/h2&gt;

&lt;p&gt;If you want to see this working today rather than taking it on faith:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Start the daemon&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/waiaas/WAIaaS.git
&lt;span class="nb"&gt;cd &lt;/span&gt;WAIaaS
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Initialize and configure&lt;/strong&gt;&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; &lt;span class="nt"&gt;-g&lt;/span&gt; @waiaas/cli
waiaas init
waiaas quickset &lt;span class="nt"&gt;--mode&lt;/span&gt; mainnet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Connect to Claude Desktop&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;waiaas mcp setup &lt;span class="nt"&gt;--all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Or use the SDK directly&lt;/strong&gt;&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; @waiaas/sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Point it at &lt;code&gt;http://127.0.0.1:3100&lt;/code&gt; with the session token from &lt;code&gt;quickset&lt;/code&gt;, and you have a TypeScript client that can check balances, send tokens, and execute DeFi actions.&lt;/p&gt;

&lt;p&gt;The daemon runs on 2 chains (Solana and EVM) across 18 networks. It exposes 39 REST API route modules, has 684+ test files, and ships as a Docker image with auto-provision, Docker Secrets support, and a non-root UID 1001 for production security hygiene.&lt;/p&gt;

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

&lt;p&gt;The conversation about AI agents usually focuses on capability: can the agent reason well, plan ahead, use tools effectively? Economic infrastructure is the missing dimension. An agent that can reason but can't transact is fundamentally limited — dependent on humans to mediate every economic interaction.&lt;/p&gt;

&lt;p&gt;The infrastructure to change that exists today. Wallets with scoped session tokens. Policy engines that define exactly what an agent is permitted to do. x402 payment protocol support for paying API calls automatically. DeFi protocol access for agents that need to do more than just send tokens. Human approval workflows for the transactions that warrant oversight.&lt;/p&gt;

&lt;p&gt;This isn't a vision of the future. It's working code you can run this afternoon.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The full documentation, architecture overview, and contribution guide are on GitHub: &lt;a href="https://github.com/waiaas/WAIaaS" rel="noopener noreferrer"&gt;https://github.com/waiaas/WAIaaS&lt;/a&gt;. If you want to understand the policy engine in depth before deploying — particularly the DeFi-specific policy types and how the 4-tier security model works in practice — the official site at &lt;a href="https://waiaas.ai" rel="noopener noreferrer"&gt;https://waiaas.ai&lt;/a&gt; is the right starting point. The OpenAPI interactive reference at &lt;code&gt;/reference&lt;/code&gt; on any running instance is also worth exploring — it documents all 39 route modules with live examples you can execute against your own daemon.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
      <category>defi</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Dual-Language AI Agent SDK: TypeScript + Python Async APIs with Zero Dependencies</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Tue, 06 Oct 2026 18:54:03 +0000</pubDate>
      <link>https://dev.to/walletguy/dual-language-ai-agent-sdk-typescript-python-async-apis-with-zero-dependencies-a0h</link>
      <guid>https://dev.to/walletguy/dual-language-ai-agent-sdk-typescript-python-async-apis-with-zero-dependencies-a0h</guid>
      <description>&lt;h1&gt;
  
  
  Your AI Agent Can Browse the Web. Can It Swap Tokens?
&lt;/h1&gt;

&lt;p&gt;Your AI agent can write code, search the internet, and draft emails — but the moment it needs to touch money, it hits a wall. WAIaaS is an open-source, self-hosted Wallet-as-a-Service that hands your agent a real crypto wallet, with a TypeScript SDK and a Python async SDK that both carry zero external dependencies. Whether you're building with LangChain, CrewAI, AutoGPT, or Claude via MCP, this is the missing piece: your agent can finally pay for things, swap tokens, and interact with DeFi protocols on its own.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem Is Simpler Than You Think
&lt;/h2&gt;

&lt;p&gt;Most AI agent frameworks are great at reasoning and tool use. They're not built to hold keys, sign transactions, or manage blockchain state. So developers end up bolting on custom signing code, managing RPC connections by hand, and writing their own retry logic for on-chain confirmations. That's not the interesting part of building an AI agent — it's infrastructure plumbing.&lt;/p&gt;

&lt;p&gt;What you actually want is a clean SDK call: "send 0.1 SOL to this address," and then get back a transaction ID. Everything else — the pipeline, the policy engine, the signing — should be someone else's problem.&lt;/p&gt;

&lt;p&gt;WAIaaS handles exactly that. You self-host a daemon (one Docker container), point your SDK at it, and your agent gets a fully featured wallet API with spending policies, security tiers, and DeFi integrations already wired up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two SDKs, One API
&lt;/h2&gt;

&lt;p&gt;WAIaaS ships two official SDKs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@waiaas/sdk&lt;/code&gt;&lt;/strong&gt; — TypeScript/Node.js, for agents built with JS-based frameworks or running in serverless environments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;waiaas&lt;/code&gt;&lt;/strong&gt; — Python, async/await native, for LangChain, CrewAI, AutoGPT, and anything else in the Python AI ecosystem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both SDKs have zero external dependencies. There's nothing to audit beyond the SDK itself, no transitive supply-chain surprises.&lt;/p&gt;

&lt;h3&gt;
  
  
  TypeScript SDK
&lt;/h3&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; @waiaas/sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;WAIaaSClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@waiaas/sdk&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WAIaaSClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://127.0.0.1:3100&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;sessionToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WAIAAS_SESSION_TOKEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Check balance&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;balance&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Send native token&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tx&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendToken&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;recipient-address...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0.1&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Transaction: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. No provider setup, no ABI loading, no gas estimation boilerplate. The daemon handles all of that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Python SDK
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;waiaas
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;waiaas&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;WAIaaSClient&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nc"&gt;WAIaaSClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:3100&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wai_sess_xxx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_balance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Python SDK is async-native, which means it drops cleanly into any &lt;code&gt;asyncio&lt;/code&gt;-based agent framework. The context manager handles session lifecycle for you.&lt;/p&gt;

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

&lt;p&gt;The TypeScript SDK exposes these methods directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;getBalance()         — Get wallet native token balance
getAddress()         — Get wallet address
getAssets()          — Get all token balances
sendToken()          — Send native or token transfer
getTransaction()     — Get transaction by ID
listTransactions()   — List transaction history
signTransaction()    — Sign arbitrary transaction
x402Fetch()          — HTTP fetch with automatic 402 payment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last one — &lt;code&gt;x402Fetch()&lt;/code&gt; — is worth pausing on. WAIaaS supports the x402 HTTP payment protocol, which means your agent can make HTTP requests that automatically pay for themselves when the server returns a 402. If you're building an agent that consumes paid APIs, it can fund its own tool calls without any human in the loop.&lt;/p&gt;

&lt;p&gt;Behind the scenes, the daemon has 39 REST API route modules and supports 7 transaction types: Transfer, TokenTransfer, ContractCall, Approve, Batch, NftTransfer, and ContractDeploy. Your SDK calls map to these routes — you're not losing anything by going through the SDK layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Real Agent: End-to-End Example
&lt;/h2&gt;

&lt;p&gt;Here's a complete TypeScript example showing how an agent would check its balance, send tokens, and wait for confirmation:&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;WAIaaSClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;WAIaaSError&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@waiaas/sdk&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WAIaaSClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;WAIAAS_BASE_URL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:3100&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;sessionToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;WAIAAS_SESSION_TOKEN&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;// Step 1: Check wallet balance&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;balance&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Balance: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Step 2: Send tokens&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sendResult&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendToken&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;TRANSFER&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;recipient-address&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0.001&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Transaction submitted: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;sendResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (status: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;sendResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Step 3: Poll for confirmation&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;POLL_TIMEOUT_MS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="nx"&gt;_000&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;startTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;startTime&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;POLL_TIMEOUT_MS&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;tx&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getTransaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sendResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;COMPLETED&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Transaction confirmed! Hash: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;txHash&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FAILED&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Transaction failed: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&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;This is real agent code. The polling loop is exactly what you'd write inside a LangChain tool or a CrewAI task. The agent submits the transaction, waits for chain confirmation, and branches on the result — all without knowing anything about RPC nodes or block finality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Error Handling That Actually Helps
&lt;/h2&gt;

&lt;p&gt;Agent frameworks need structured errors they can reason about. WAIaaS errors carry machine-readable codes:&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;WAIaaSClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;WAIaaSError&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@waiaas/sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;try&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;tx&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendToken&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1.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="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;WAIaaSError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`API Error: [&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;] &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// error.code examples: INSUFFICIENT_BALANCE, POLICY_DENIED, TOKEN_EXPIRED&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;&lt;code&gt;POLICY_DENIED&lt;/code&gt; is particularly useful: it means the spending policy on this wallet blocked the transaction. Your agent can catch this, log the reason, and decide whether to request a smaller amount or escalate to a human. This is how you build safe autonomous agents — the safety layer is at the infrastructure level, not in your agent's prompt.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Policy Layer: Safety by Default
&lt;/h2&gt;

&lt;p&gt;Before your agent can spend anything, the wallet has a policy engine with 21 policy types and 4 security tiers: INSTANT, NOTIFY, DELAY, and APPROVAL.&lt;/p&gt;

&lt;p&gt;You configure policies once, at setup time, using the master password:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 100,
      "notify_max_usd": 500,
      "delay_max_usd": 2000,
      "delay_seconds": 900,
      "daily_limit_usd": 5000
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this policy in place: transactions under $100 go through instantly, transactions between $100–$500 notify you but still execute, transactions between $500–$2,000 are delayed 15 minutes (cancellable), and anything over $2,000 requires your manual approval.&lt;/p&gt;

&lt;p&gt;Your agent's session token only has &lt;code&gt;sessionAuth&lt;/code&gt; privileges — it can sign and submit transactions, but it cannot create wallets, modify policies, or approve held transactions. That's reserved for &lt;code&gt;masterAuth&lt;/code&gt; (you, the operator) and &lt;code&gt;ownerAuth&lt;/code&gt; (the wallet owner, via WalletConnect or Telegram). Three authentication layers, cleanly separated.&lt;/p&gt;

&lt;p&gt;The policy engine is also default-deny: if you haven't configured &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt; or &lt;code&gt;CONTRACT_WHITELIST&lt;/code&gt;, those transaction types are blocked. Your agent can't accidentally drain a wallet into an unknown contract.&lt;/p&gt;

&lt;h2&gt;
  
  
  DeFi Actions: Beyond Simple Transfers
&lt;/h2&gt;

&lt;p&gt;The daemon integrates 15 DeFi protocol providers. Your agent can call them via the REST API directly, or you can wrap the API call as a tool in your agent framework.&lt;/p&gt;

&lt;p&gt;Here's a Jupiter swap on Solana:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/actions/jupiter-swap/swap &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_&amp;lt;token&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "inputMint": "So11111111111111111111111111111111111111112",
    "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "amount": "1000000000"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The full list of integrated protocols includes Aave v3, Across, D'CENT Swap, Drift, Hyperliquid, Jito Staking, Jupiter Swap, Kamino, Lido Staking, LI.FI, Pendle, Polymarket, XRPL DEX, and 0x Swap. Liquid staking, cross-chain bridging, perpetual futures, prediction markets — all callable from your agent's session token, subject to whatever policies you've set.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start: Running the Daemon in 5 Minutes
&lt;/h2&gt;

&lt;p&gt;You don't need to deploy anything complex. The whole thing runs in a single Docker container.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Install the CLI and initialize&lt;/strong&gt;&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; &lt;span class="nt"&gt;-g&lt;/span&gt; @waiaas/cli
waiaas init
waiaas start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Create a wallet and session in one command&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;waiaas quickset &lt;span class="nt"&gt;--mode&lt;/span&gt; mainnet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prints a session token and an MCP config JSON you can paste directly into Claude Desktop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Or use Docker directly with auto-provision&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; waiaas &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 127.0.0.1:3100:3100 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; waiaas-data:/data &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;WAIAAS_AUTO_PROVISION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  ghcr.io/waiaas/waiaas:latest

docker &lt;span class="nb"&gt;exec &lt;/span&gt;waiaas &lt;span class="nb"&gt;cat&lt;/span&gt; /data/recovery.key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4: Install your SDK&lt;/strong&gt;&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; @waiaas/sdk
&lt;span class="c"&gt;# or&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;waiaas
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 5: Set your environment variables and start building&lt;/strong&gt;&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;export &lt;/span&gt;&lt;span class="nv"&gt;WAIAAS_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://127.0.0.1:3100
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;WAIAAS_SESSION_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;wai_sess_&amp;lt;from-quickset&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your agent is now funded and policy-protected. The interactive API reference is available at &lt;code&gt;http://127.0.0.1:3100/reference&lt;/code&gt; if you want to explore all 39 route modules before writing code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test Before You Send
&lt;/h2&gt;

&lt;p&gt;One more thing worth knowing before you ship your agent: there's a dry-run mode. You can simulate any transaction before it actually executes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/transactions/send &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_&amp;lt;token&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "type": "TRANSFER",
    "to": "recipient-address",
    "amount": "0.1",
    "dryRun": true
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add &lt;code&gt;"dryRun": true&lt;/code&gt; to any transaction request and the daemon will run it through the full 7-stage pipeline — validation, auth, policy check — and return what would happen, without touching the chain. This is useful during development and as a pre-flight check inside your agent's decision loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The SDKs are the entry point, but WAIaaS has a lot more surface area once your agent needs it: 45 MCP tools for Claude Desktop integration, ERC-4337 account abstraction for gasless transactions, and an admin Web UI at &lt;code&gt;/admin&lt;/code&gt; for monitoring what your agents are doing in production. The codebase is open-source and the daemon is self-hosted — your keys never leave your infrastructure.&lt;/p&gt;

&lt;p&gt;Explore the full project on GitHub at &lt;a href="https://github.com/waiaas/WAIaaS" rel="noopener noreferrer"&gt;https://github.com/waiaas/WAIaaS&lt;/a&gt;, or visit &lt;a href="https://waiaas.ai" rel="noopener noreferrer"&gt;https://waiaas.ai&lt;/a&gt; for documentation and getting-started guides. If you're building an agent that needs to interact with blockchains, this is the infrastructure layer you've been missing.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>python</category>
      <category>ai</category>
      <category>api</category>
    </item>
    <item>
      <title>21 Ways to Control Your AI Trading Bot: Complete Policy Engine Risk Management</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Tue, 06 Oct 2026 13:26:41 +0000</pubDate>
      <link>https://dev.to/walletguy/21-ways-to-control-your-ai-trading-bot-complete-policy-engine-risk-management-4hde</link>
      <guid>https://dev.to/walletguy/21-ways-to-control-your-ai-trading-bot-complete-policy-engine-risk-management-4hde</guid>
      <description>&lt;h1&gt;
  
  
  21 Ways to Control Your AI Trading Bot: Complete Policy Engine Risk Management
&lt;/h1&gt;

&lt;p&gt;AI trading bots with unrestricted wallet access are a liability waiting to happen — one misconfigured agent or compromised session token away from draining everything you've built. If you're giving an AI agent access to real funds, you need more than good intentions and crossed fingers. You need explicit, auditable, code-enforced guardrails between your agent and your money.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Risk: Autonomous Agents With Wallets
&lt;/h2&gt;

&lt;p&gt;Here's the uncomfortable truth about AI agents and crypto wallets: most implementations treat authorization as a binary. Either the agent has access or it doesn't. That's fine for toy projects. It's dangerous for anything running on mainnet with real capital.&lt;/p&gt;

&lt;p&gt;The threat surface is larger than most developers account for. It's not just "what happens if the AI makes a bad trade." It's: what happens when the session token leaks? What if the model hallucinates a recipient address? What if a protocol gets exploited and the agent keeps interacting with it? What if you want your bot to handle small rebalancing operations autonomously but need human sign-off on anything over $500?&lt;/p&gt;

&lt;p&gt;These aren't edge cases. They're the questions that determine whether you can actually trust an autonomous system with funds.&lt;/p&gt;

&lt;h2&gt;
  
  
  3 Layers Between Your Agent and Your Money
&lt;/h2&gt;

&lt;p&gt;WAIaaS is built around a layered security model that doesn't require you to choose between autonomy and safety. The architecture provides three distinct control layers:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 1 — Session authentication.&lt;/strong&gt; Every AI agent operates on a scoped session token. Sessions have TTL, maxRenewals, and absoluteLifetime controls. A compromised token has a bounded blast radius.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 2 — Policy engine with time delays and approval gates.&lt;/strong&gt; This is where most of the risk management lives. 21 policy types, 4 security tiers, and a default-deny posture means your agent literally cannot do things you haven't explicitly permitted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 3 — Monitoring and kill switch.&lt;/strong&gt; Incoming transaction monitoring with real-time notifications, plus WalletConnect-based owner approval for high-risk actions.&lt;/p&gt;

&lt;p&gt;Three auth methods serve three different roles: &lt;code&gt;masterAuth&lt;/code&gt; (Argon2id) for system administration like creating wallets and sessions, &lt;code&gt;ownerAuth&lt;/code&gt; (SIWS/SIWE signature) for the fund owner approving or rejecting transactions, and &lt;code&gt;sessionAuth&lt;/code&gt; (JWT HS256) for the AI agent's day-to-day operations.&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="c"&gt;# masterAuth — system administrator (wallet creation, session management, policies)&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt;

&lt;span class="c"&gt;# sessionAuth — AI agent (transactions, balance queries, DeFi actions)&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_eyJhbGciOiJIUzI1NiJ9..."&lt;/span&gt;

&lt;span class="c"&gt;# ownerAuth — fund owner (transaction approval, kill switch recovery)&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Owner-Signature: &amp;lt;ed25519-or-secp256k1-signature&amp;gt;"&lt;/span&gt;
&lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Owner-Message: &amp;lt;signed-message&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent never touches masterAuth credentials. The owner never needs to run the agent. These roles are cleanly separated by design.&lt;/p&gt;

&lt;h2&gt;
  
  
  Default-Deny: The Most Important Security Property
&lt;/h2&gt;

&lt;p&gt;Before walking through all 21 policy types, the most important thing to understand is the default-deny posture. If you don't configure &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt;, your agent cannot transfer tokens. If you don't configure &lt;code&gt;CONTRACT_WHITELIST&lt;/code&gt;, your agent cannot call contracts. No whitelist means no access — not "access to everything."&lt;/p&gt;

&lt;p&gt;This inverts the typical developer instinct. Most systems are permissive by default and you add restrictions. WAIaaS is restrictive by default and you add permissions. That distinction matters enormously when something goes wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 4 Security Tiers
&lt;/h2&gt;

&lt;p&gt;Every transaction that passes through WAIaaS gets classified into one of four tiers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSTANT   — Execute immediately, no notification
NOTIFY    — Execute immediately, send notification to owner
DELAY     — Queue for N seconds, then execute (cancellable during window)
APPROVAL  — Require explicit human approval via WalletConnect/Telegram/Push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tier assignment is policy-driven and amount-aware. You define the thresholds. Here's what a realistic &lt;code&gt;SPENDING_LIMIT&lt;/code&gt; policy looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 100,
      "notify_max_usd": 500,
      "delay_max_usd": 2000,
      "delay_seconds": 900,
      "daily_limit_usd": 5000
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this config: under $100 executes immediately and silently, $100-$500 executes immediately but pings you, $500-$2000 goes into a 15-minute holding queue you can cancel, and anything over $2000 requires your explicit approval. Your agent can be fully autonomous for small rebalancing ops while you stay in the loop for anything significant.&lt;/p&gt;

&lt;h2&gt;
  
  
  All 21 Policy Types
&lt;/h2&gt;

&lt;p&gt;Here's the complete picture. These aren't marketing categories — these are the actual policy types enforced in the transaction pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Spending and Limits
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;SPENDING_LIMIT&lt;/strong&gt; — The primary amount-based control. 4-tier security based on USD value. Supports daily and monthly caps, plus per-token limits for granular control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;APPROVE_AMOUNT_LIMIT&lt;/strong&gt; — Caps how large a token approval can be. Blocks unlimited approvals (&lt;code&gt;uint256 max&lt;/code&gt;). Critical for DeFi safety — unlimited approvals to compromised protocols have caused massive losses in the past.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;APPROVE_TIER_OVERRIDE&lt;/strong&gt; — Force a specific security tier for all APPROVE transactions regardless of amount. If you want every approval to require human sign-off no matter what, this is how you enforce it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ACTION_CATEGORY_LIMIT&lt;/strong&gt; — Set spending limits per category of DeFi action. You can cap how much your agent allocates to lending separately from how much it allocates to perpetual futures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Allowlists (All Default-Deny)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;ALLOWED_TOKENS&lt;/strong&gt; — Define exactly which tokens the agent can transfer. Anything not on the list is blocked, full stop.&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="nl"&gt;"tokens"&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="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"symbol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USDC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"chain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"solana"&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;CONTRACT_WHITELIST&lt;/strong&gt; — Define which smart contracts the agent can interact with. Your agent cannot call Jupiter if Jupiter isn't on this list.&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="nl"&gt;"contracts"&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="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Jupiter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"chain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"solana"&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;APPROVED_SPENDERS&lt;/strong&gt; — Control which addresses can be granted token approvals, with optional max amounts per spender.&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="nl"&gt;"spenders"&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="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0xDEF1..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Uniswap Router"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxAmount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1000000000"&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;METHOD_WHITELIST&lt;/strong&gt; — Allowlist specific function selectors. If your agent should only be able to call &lt;code&gt;swap()&lt;/code&gt; and not &lt;code&gt;withdraw()&lt;/code&gt;, this is how you encode that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WHITELIST&lt;/strong&gt; — Recipient address allowlist. Your agent can only send funds to addresses you've pre-approved.&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="nl"&gt;"allowed_addresses"&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;"&amp;lt;address1&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;address2&amp;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;VENUE_WHITELIST&lt;/strong&gt; — Allowlist specific trading venues. Restrict which DEXes or protocols the agent can use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rate and Time Controls
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;RATE_LIMIT&lt;/strong&gt; — Maximum number of transactions per hour or per day. Useful for detecting runaway agent behavior and capping the damage from a misbehaving model.&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="nl"&gt;"maxTransactions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"period"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hourly"&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;TIME_RESTRICTION&lt;/strong&gt; — Restrict transaction execution to specific hours. If your trading strategy only makes sense during market hours, enforce that at the infrastructure level.&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="nl"&gt;"allowedHours"&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="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"end"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"timezone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"UTC"&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;ALLOWED_NETWORKS&lt;/strong&gt; — Restrict the agent to specific chains. An agent configured for Solana mainnet operations shouldn't be able to send transactions on Ethereum.&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="nl"&gt;"networks"&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="nl"&gt;"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;"solana-mainnet"&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;h3&gt;
  
  
  DeFi-Specific Controls
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;LENDING_LTV_LIMIT&lt;/strong&gt; — Maximum loan-to-value ratio for DeFi lending positions. Prevents your agent from over-leveraging into liquidation territory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LENDING_ASSET_WHITELIST&lt;/strong&gt; — Which assets the agent is allowed to supply or borrow. You can allow USDC borrowing without allowing your agent to touch riskier assets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PERP_MAX_LEVERAGE&lt;/strong&gt; — Hard cap on perpetual futures leverage. A leveraged trading bot without this is a liquidation waiting to happen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PERP_MAX_POSITION_USD&lt;/strong&gt; — Maximum position size in USD for perp trades. Caps the worst-case loss from a single bad trade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PERP_ALLOWED_MARKETS&lt;/strong&gt; — Which perpetual markets the agent can trade. If your strategy is SOL-PERP only, enforce that explicitly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Protocol and Agent Controls
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;X402_ALLOWED_DOMAINS&lt;/strong&gt; — Allowlist for x402 HTTP payment protocol. WAIaaS supports automatic API payment for AI agents via x402; this policy controls which domains the agent is allowed to pay automatically.&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="nl"&gt;"domains"&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;"api.example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*.openai.com"&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;REPUTATION_THRESHOLD&lt;/strong&gt; — Minimum ERC-8004 onchain reputation score required for agent interactions. Enables trustless agent validation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ERC8128_ALLOWED_DOMAINS&lt;/strong&gt; — Controls which domains the agent can sign HTTP requests for using the ERC-8128 protocol.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 7-Stage Transaction Pipeline
&lt;/h2&gt;

&lt;p&gt;Policies don't run as an afterthought — they're embedded in a 7-stage pipeline that every transaction passes through: validate → auth → policy → wait → execute → confirm. The &lt;code&gt;wait&lt;/code&gt; stage is where DELAY-tier transactions sit in the cancellable queue. Nothing executes until it clears every preceding stage.&lt;/p&gt;

&lt;p&gt;This means you can simulate a transaction before it ever hits the pipeline. The dry-run API lets you validate against the full policy stack without committing to execution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/transactions/send &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wai_sess_&amp;lt;token&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "type": "TRANSFER",
    "to": "recipient-address",
    "amount": "0.1",
    "dryRun": true
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful during development to verify that your policy configuration actually behaves the way you expect before you run anything on mainnet.&lt;/p&gt;

&lt;p&gt;And when a policy blocks a transaction, the error response tells you exactly why:&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;"error"&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;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POLICY_DENIED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Transaction denied by SPENDING_LIMIT policy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POLICY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"retryable"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&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;No ambiguity. The agent — and you — know precisely what rule was triggered.&lt;/p&gt;

&lt;h2&gt;
  
  
  Human Approval in the Loop
&lt;/h2&gt;

&lt;p&gt;APPROVAL-tier transactions require a human response before anything executes. WAIaaS supports three signing channels for delivering approval requests: push relay, Telegram, and WalletConnect. Once you approve, the transaction proceeds. If you reject or let it time out, it doesn't.&lt;/p&gt;

&lt;p&gt;The owner approval endpoint uses a signed message for authentication — your wallet signs, not a password:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/transactions/&amp;lt;tx-id&amp;gt;/approve &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Owner-Signature: &amp;lt;ed25519-or-secp256k1-signature&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Owner-Message: &amp;lt;signed-message&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the kill switch pattern. Even if every other layer were compromised, transactions requiring owner approval can't execute without a cryptographic signature from the controlling wallet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start: Setting Up Your First Policy Stack
&lt;/h2&gt;

&lt;p&gt;Here's the minimum viable security setup for a Solana trading agent:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; Install and initialize WAIaaS.&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; &lt;span class="nt"&gt;-g&lt;/span&gt; @waiaas/cli
waiaas init
waiaas start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Create a wallet and session for your agent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/wallets &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"name": "trading-wallet", "chain": "solana", "environment": "mainnet"}'&lt;/span&gt;

curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/sessions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"walletId": "&amp;lt;wallet-uuid&amp;gt;"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Set a spending limit with tiered security.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "SPENDING_LIMIT",
    "rules": {
      "instant_max_usd": 100,
      "notify_max_usd": 500,
      "delay_max_usd": 2000,
      "delay_seconds": 900,
      "daily_limit_usd": 5000
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4:&lt;/strong&gt; Add an allowed tokens policy (default-deny enforcement).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://127.0.0.1:3100/v1/policies &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-Master-Password: my-secret-password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "walletId": "&amp;lt;wallet-uuid&amp;gt;",
    "type": "ALLOWED_TOKENS",
    "rules": {
      "tokens": [{"address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "symbol": "USDC", "chain": "solana"}]
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 5:&lt;/strong&gt; Verify a transaction against your policies using dry-run before going live.&lt;/p&gt;

&lt;p&gt;Your agent now operates with bounded autonomy: it can move funds within your defined limits, it's blocked from touching anything not explicitly permitted, and anything over your DELAY threshold requires your active involvement.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The policy engine is one part of the WAIaaS security model. Explore the full interactive API reference at &lt;code&gt;http://127.0.0.1:3100/reference&lt;/code&gt; once your daemon is running — it's auto-generated from the codebase and covers all 39 API route modules. For production deployments, review the Docker Secrets integration and the secrets overlay pattern in &lt;code&gt;docker-compose.secrets.yml&lt;/code&gt; to keep your master password out of environment variables entirely.&lt;/p&gt;

&lt;p&gt;The source code, full documentation, and deployment guides are at &lt;a href="https://github.com/waiaas/WAIaaS" rel="noopener noreferrer"&gt;https://github.com/waiaas/WAIaaS&lt;/a&gt;. If you're building AI agents that handle real capital, start there. The project site with additional resources is at &lt;a href="https://waiaas.ai" rel="noopener noreferrer"&gt;https://waiaas.ai&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>defi</category>
      <category>trading</category>
    </item>
  </channel>
</rss>
