<?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>Self-Documenting Economic Agents: OpenAPI 3.0 for Autonomous Commerce</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Mon, 21 Sep 2026 18:38:48 +0000</pubDate>
      <link>https://dev.to/walletguy/self-documenting-economic-agents-openapi-30-for-autonomous-commerce-5f0p</link>
      <guid>https://dev.to/walletguy/self-documenting-economic-agents-openapi-30-for-autonomous-commerce-5f0p</guid>
      <description>&lt;h1&gt;
  
  
  Self-Documenting Economic Agents: OpenAPI 3.0 for Autonomous Commerce
&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 speculative roadmap. If you're building agents that operate autonomously, you've probably already hit the wall: your agent can reason, plan, and act, but the moment it needs to move money, you're back to human-in-the-loop plumbing. This post is about closing that gap with real, working infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem No One Talks About at AI Conferences
&lt;/h2&gt;

&lt;p&gt;There's a lot of conversation about reasoning capabilities, context windows, and tool use. Considerably less conversation about the boring but critical question: &lt;em&gt;how does an agent pay for things?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Think through the lifecycle of an autonomous agent doing something genuinely useful — say, a research agent that monitors market conditions, queries premium data APIs, executes trades, and rebalances a portfolio overnight. Every one of those steps involves either a cost or a value transfer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Querying a premium data feed costs money (someone has to pay the API provider)&lt;/li&gt;
&lt;li&gt;Executing a swap on-chain requires gas&lt;/li&gt;
&lt;li&gt;Moving funds between protocols requires signing transactions&lt;/li&gt;
&lt;li&gt;Reporting results might involve paying for a delivery channel&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Today, most teams handle this by giving the agent access to a human-controlled wallet with full permissions, or by hard-coding payment credentials that get rotated manually. Neither approach scales, and neither is safe. What's actually needed is wallet infrastructure designed for agents from the ground up — with policy enforcement, audit trails, and the kind of self-documentation that lets agents (and developers) discover capabilities at runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wallets That Speak HTTP
&lt;/h2&gt;

&lt;p&gt;WAIaaS (Wallet-as-a-Service for AI agents) is an open-source, self-hosted daemon that treats wallet operations as a REST API. Instead of your agent importing a private key and calling a library directly, it makes HTTP calls to a local service that handles key management, transaction signing, policy enforcement, and multi-chain routing.&lt;/p&gt;

&lt;p&gt;The architecture is deliberately simple: you run the daemon, create a wallet, issue a session token to your agent, and the agent operates within the boundaries you set. The daemon exposes 39 REST API route modules covering everything from balance queries to DeFi actions to NFT transfers.&lt;/p&gt;

&lt;p&gt;What makes this relevant to the "autonomous commerce" question is the combination of two things: a machine-readable OpenAPI 3.0 spec and native x402 HTTP payment support. Together, they mean an agent can &lt;em&gt;discover&lt;/em&gt; what a wallet service can do and &lt;em&gt;automatically pay&lt;/em&gt; for API calls that require payment — without a human in the loop for either step.&lt;/p&gt;

&lt;h2&gt;
  
  
  OpenAPI as Agent Infrastructure
&lt;/h2&gt;

&lt;p&gt;When WAIaaS is running, you get a self-documenting API at two endpoints:&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;# Download OpenAPI 3.0 spec&lt;/span&gt;
curl http://127.0.0.1:3100/doc &lt;span class="nt"&gt;-o&lt;/span&gt; openapi.json

&lt;span class="c"&gt;# View interactive API reference&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;/doc&lt;/code&gt; endpoint returns a machine-readable OpenAPI 3.0 specification. The &lt;code&gt;/reference&lt;/code&gt; endpoint serves an interactive Scalar UI for human exploration. This matters more than it might seem at first glance.&lt;/p&gt;

&lt;p&gt;An OpenAPI spec is a contract. It describes every endpoint, every required parameter, every possible response code. For a human developer, that's useful documentation. For an agent — especially one using an LLM with tool-calling capabilities — it's a capability manifest that can be parsed, indexed, and acted on at runtime.&lt;/p&gt;

&lt;p&gt;Consider what this enables: an orchestrator agent could fetch the spec from a WAIaaS instance, understand that the wallet supports token transfers, contract calls, DeFi actions across 15 integrated protocols, and NFT operations — then route sub-tasks to the appropriate endpoints without any hardcoded knowledge of the API surface. The agent discovers capabilities the same way a developer does, just programmatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  The x402 Layer: Agents That Pay for What They Use
&lt;/h2&gt;

&lt;p&gt;The x402 HTTP payment protocol is the piece that makes autonomous economic participation concrete. When an agent calls an API that returns HTTP 402 (Payment Required), the x402 protocol defines a standard handshake: the server declares what it wants, the client pays, the server fulfills the request.&lt;/p&gt;

&lt;p&gt;WAIaaS has native x402 support built in. From the agent's perspective, this is just a fetch call:&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The TypeScript SDK includes &lt;code&gt;x402Fetch()&lt;/code&gt; — a drop-in replacement for standard HTTP fetch that automatically handles 402 responses by paying from the agent's wallet and retrying the request. The agent doesn't need to know whether a given API costs money; it just makes requests and the payment layer handles the rest.&lt;/p&gt;

&lt;p&gt;This is the "machines that pay for what they use" model made operational. A premium data API, a compute provider, a specialized model endpoint — any service implementing x402 becomes something agents can consume autonomously, with payment flowing automatically and every transaction recorded in the wallet's audit trail.&lt;/p&gt;

&lt;p&gt;To control which domains an agent can pay automatically, you configure the &lt;code&gt;X402_ALLOWED_DOMAINS&lt;/code&gt; 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": "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;The agent can only auto-pay domains you've explicitly whitelisted. This is the policy engine enforcing boundaries — the agent operates autonomously within a defined permission set, not without constraints.&lt;/p&gt;

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

&lt;p&gt;Autonomous doesn't mean uncontrolled. WAIaaS ships with a policy engine that has 21 policy types and 4 security tiers: INSTANT, NOTIFY, DELAY, and APPROVAL.&lt;/p&gt;

&lt;p&gt;The four tiers map directly to how much trust you're extending to the agent for a given operation:&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 (cancellable)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;APPROVAL&lt;/strong&gt; — Require explicit human approval before anything moves&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A spending limit policy ties the tier to transaction size:&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, your agent can move up to $100 instantly (appropriate for x402 micro-payments and small operational costs), handle up to $500 with a notification sent to you, queue up to $2,000 with a 15-minute cancellation window, and anything larger requires your explicit sign-off. The policy system follows default-deny: transactions are blocked unless explicitly permitted.&lt;/p&gt;

&lt;p&gt;The other 20 policy types cover things like token whitelists, contract whitelists, rate limits, time restrictions, DeFi-specific limits (max leverage for perpetuals, max loan-to-value for lending), and reputation thresholds for agent-to-agent interactions via ERC-8004. The full list is extensive precisely because real economic agents face a wide surface of risk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multi-Chain, Multi-Protocol DeFi Access
&lt;/h2&gt;

&lt;p&gt;An agent operating in the token economy isn't just sending transfers. It might need to swap assets, provide liquidity, stake for yield, or take positions in prediction markets. WAIaaS integrates 15 DeFi protocol providers across 18 networks (2 chain types: EVM and Solana).&lt;/p&gt;

&lt;p&gt;A Jupiter swap on Solana 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/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 authenticates with a session token, specifies the action and protocol, and the daemon handles routing, signing, and submission. The integrated protocols include Jupiter (Solana DEX aggregation), Aave V3 (lending), Hyperliquid (perpetual futures), Lido and Jito (liquid staking), LI.FI and Across (cross-chain bridging), Polymarket (prediction markets), and more. An agent with access to this surface can participate in DeFi markets as a first-class economic actor.&lt;/p&gt;

&lt;p&gt;Before any of this executes against real funds, there's a dry-run mode:&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 and you get a simulation of the outcome without committing anything on-chain. For agents that need to reason about consequences before acting, this is the equivalent of a read-only preview of the world state post-action.&lt;/p&gt;

&lt;p&gt;Transactions flow through a 7-stage pipeline: validate → auth → policy → wait → execute → confirm. Every stage is a checkpoint, and the gas condition feature means transactions can be queued to execute only when gas prices fall below a threshold — useful for an agent managing costs autonomously.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting a Self-Documenting Agent Wallet Running
&lt;/h2&gt;

&lt;p&gt;Here's the minimal path from zero to a working agent wallet with API discovery enabled:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Install 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;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&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: Explore the API spec&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/doc &lt;span class="nt"&gt;-o&lt;/span&gt; openapi.json
open http://127.0.0.1:3100/reference
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4: Configure policies before funding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Set at minimum a &lt;code&gt;SPENDING_LIMIT&lt;/code&gt; and an &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt; whitelist (which is default-deny — the agent can't move tokens you haven't explicitly permitted).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Connect to your agent framework&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use the TypeScript SDK (&lt;code&gt;npm install @waiaas/sdk&lt;/code&gt;), the Python SDK (&lt;code&gt;pip install waiaas&lt;/code&gt;), or the 45-tool MCP server (&lt;code&gt;waiaas mcp setup --all&lt;/code&gt;) depending on how your agent is built. If you're using Claude Desktop, the MCP setup command auto-registers the wallet and generates the configuration JSON for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture Argument
&lt;/h2&gt;

&lt;p&gt;There's a broader point here worth making explicit. The design decision to expose wallet operations as a self-documenting HTTP API — rather than a library or SDK that agents import directly — has meaningful consequences for how agent economies can scale.&lt;/p&gt;

&lt;p&gt;A library coupling means every agent implementation needs to speak the same language, import the same dependencies, and handle key material directly. An HTTP service with an OpenAPI spec means any agent, in any language, built on any framework, can discover and use the wallet's capabilities through a standard interface. The spec becomes the contract. Discovery becomes runtime, not build-time.&lt;/p&gt;

&lt;p&gt;This is the same architectural shift the web made from tight client-server coupling to REST. It's the same shift that made microservices composable. Applied to agent wallet infrastructure, it means the economic layer of agent systems can evolve independently of the agents themselves — new protocols, new chains, new policy types can be added to the daemon and immediately become discoverable to any connected agent.&lt;/p&gt;

&lt;p&gt;The OpenAPI spec at &lt;code&gt;/doc&lt;/code&gt; isn't just developer convenience. It's the mechanism by which autonomous agents can reason about what economic actions are available to them at any given moment.&lt;/p&gt;

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

&lt;p&gt;If you're building agents that need to operate economically — paying for APIs, managing DeFi positions, executing trades, or participating in agent-to-agent commerce — the infrastructure is here and working today. Start with the GitHub repository for the full codebase and self-hosting instructions, and visit the official site for documentation on the policy engine and SDK references.&lt;/p&gt;

&lt;p&gt;The open question isn't whether agents will need wallets. It's whether the wallet infrastructure will be designed for agents or retrofitted from human-facing tools. WAIaaS is an answer to that question built from first principles.&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>api</category>
      <category>web3</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Lock Down Your DeFi Bot: METHOD_WHITELIST for Smart Contract Security</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Mon, 21 Sep 2026 13:00:21 +0000</pubDate>
      <link>https://dev.to/walletguy/lock-down-your-defi-bot-methodwhitelist-for-smart-contract-security-445g</link>
      <guid>https://dev.to/walletguy/lock-down-your-defi-bot-methodwhitelist-for-smart-contract-security-445g</guid>
      <description>&lt;h1&gt;
  
  
  Lock Down Your DeFi Bot: METHOD_WHITELIST and Smart Contract Security with WAIaaS
&lt;/h1&gt;

&lt;p&gt;Your DeFi trading bot has a problem: it holds private keys, executes transactions autonomously, and interacts with smart contracts — and if something goes wrong, there's no undo button. Whether you're running an arb bot, a liquidity manager, or an automated hedging strategy, the attack surface is real. A compromised session token, a buggy strategy loop, or a malicious contract call can drain your wallet in a single block. METHOD_WHITELIST is one of the tools that closes that gap, and in this post we'll look at how WAIaaS builds it into a broader security architecture designed specifically for autonomous agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Contract-Level Restrictions Actually Matter
&lt;/h2&gt;

&lt;p&gt;Most wallet security discussions stop at "protect your private key." That's necessary but not sufficient when you have a bot running 24/7 with signing authority. The real risk surface for an automated trading system looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your bot's session token is stolen or leaked&lt;/li&gt;
&lt;li&gt;A bug in your strategy logic calls the wrong function on the wrong contract&lt;/li&gt;
&lt;li&gt;A dependency in your pipeline gets compromised and injects a malicious payload&lt;/li&gt;
&lt;li&gt;A smart contract you've whitelisted gets upgraded to a honeypot&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In each of these cases, you want a layer of defense that sits between the session token and the blockchain — something that says "even if this token is fully authenticated, it can only call these specific functions on these specific contracts." That's exactly what METHOD_WHITELIST and CONTRACT_WHITELIST do in WAIaaS.&lt;/p&gt;

&lt;p&gt;WAIaaS is an open-source, self-hosted Wallet-as-a-Service built for AI agents and automated systems. It runs as a local daemon (or Docker container), your bot talks to it over HTTP, and it handles signing, policy enforcement, and transaction execution. The policy engine sits in the middle of a 7-stage transaction pipeline — validate, auth, policy, wait, execute, confirm — so every transaction is checked before it touches a private key.&lt;/p&gt;

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

&lt;p&gt;Before diving into METHOD_WHITELIST specifically, it's worth understanding the full policy architecture, because METHOD_WHITELIST is most effective as part of a layered configuration.&lt;/p&gt;

&lt;p&gt;WAIaaS has 21 policy types across 4 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;The critical detail is &lt;strong&gt;default-deny&lt;/strong&gt;: if you haven't configured ALLOWED_TOKENS, transactions involving that token are blocked. If you haven't configured CONTRACT_WHITELIST, contract calls are blocked. Your bot doesn't accidentally call something it shouldn't — it's blocked by default.&lt;/p&gt;

&lt;p&gt;For a trading bot, a minimal hardened configuration typically combines:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;CONTRACT_WHITELIST&lt;/strong&gt; — only the specific contracts your strategy touches&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;METHOD_WHITELIST&lt;/strong&gt; — only the function selectors those contracts expose&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SPENDING_LIMIT&lt;/strong&gt; — 4-tier amount-based controls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ALLOWED_TOKENS&lt;/strong&gt; — only the tokens your strategy trades&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ALLOWED_NETWORKS&lt;/strong&gt; — restrict to the chains you actually use&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's set these up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Deploy WAIaaS and Create a Trading Wallet
&lt;/h2&gt;

&lt;p&gt;If you're running locally, the quickest path is Docker:&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;The daemon binds to &lt;code&gt;127.0.0.1:3100&lt;/code&gt; by default — not publicly exposed. Now create a wallet for your trading bot:&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 — this is what your bot will use at runtime:&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 session token (&lt;code&gt;wai_sess_...&lt;/code&gt;) goes into your bot's environment. The master password stays locked away — your bot never touches it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Configure CONTRACT_WHITELIST
&lt;/h2&gt;

&lt;p&gt;Before METHOD_WHITELIST, you need to whitelist the contracts themselves. For a Jupiter swap bot 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/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": "CONTRACT_WHITELIST",
    "rules": {
      "contracts": [
        {
          "address": "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",
          "name": "Jupiter",
          "chain": "solana"
        }
      ]
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Any call to a contract not on this list is rejected before signing. Your bot physically cannot interact with a contract you haven't explicitly approved — even if a compromised dependency tries to construct a malicious payload.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Add METHOD_WHITELIST for Function-Level Control
&lt;/h2&gt;

&lt;p&gt;CONTRACT_WHITELIST tells WAIaaS which contracts are allowed. METHOD_WHITELIST goes one level deeper: it restricts which function selectors can be called on those contracts. On EVM chains, function selectors are the 4-byte prefixes of the keccak256 hash of the function signature — &lt;code&gt;transfer(address,uint256)&lt;/code&gt; maps to &lt;code&gt;0xa9059cbb&lt;/code&gt;, for example.&lt;/p&gt;

&lt;p&gt;This matters because smart contracts often expose administrative or dangerous functions alongside their public trading interface. Even if your strategy only needs &lt;code&gt;swap()&lt;/code&gt;, a compromised session could theoretically call &lt;code&gt;emergencyWithdraw()&lt;/code&gt; or an admin function if you haven't locked it down. METHOD_WHITELIST prevents that:&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": "METHOD_WHITELIST",
    "rules": {
      "selectors": ["0xa9059cbb", "0x23b872dd"]
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact structure of METHOD_WHITELIST rules follows the pattern of the WAIaaS policy engine. The principle: your bot signs only the function calls you explicitly enumerated. Nothing else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Lock Down Tokens and Spending
&lt;/h2&gt;

&lt;p&gt;For a USDC/SOL arb bot, you don't want the session token to be able to move arbitrary tokens. Add ALLOWED_TOKENS:&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;And a SPENDING_LIMIT to cap damage from any single runaway 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/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 single transaction under $100 executes immediately. $100–$500 triggers a notification. $500–$2,000 is delayed 15 minutes (giving you a window to cancel). Above $2,000 requires your explicit approval.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Always Dry-Run Before You Execute
&lt;/h2&gt;

&lt;p&gt;Before your bot goes live, simulate transactions through the full policy pipeline:&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: true&lt;/code&gt; flag runs the full 7-stage pipeline — validation, auth, all policy checks — without submitting anything to the chain. If your METHOD_WHITELIST or CONTRACT_WHITELIST is misconfigured, you'll see a &lt;code&gt;POLICY_DENIED&lt;/code&gt; error response in test, not on mainnet:&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;This is how you verify your policy configuration before deploying capital.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your Bot's Runtime Loop
&lt;/h2&gt;

&lt;p&gt;At runtime, your bot authenticates with the session token only. Here's what a basic trading loop looks like using the TypeScript SDK:&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;// Check balance before trading&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;// Submit a swap through the policy pipeline&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;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;// 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;`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;`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;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: 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;The session token in &lt;code&gt;WAIAAS_SESSION_TOKEN&lt;/code&gt; has its entire behavior constrained by the policies you configured above. Even if this token is stolen, the attacker can only call the functions you've whitelisted, on the contracts you've whitelisted, up to the spending limits you've set.&lt;/p&gt;

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

&lt;p&gt;WAIaaS also supports gas conditional execution — transactions execute only when the gas price meets a threshold you define. For bots where gas costs directly affect profitability, this means you can submit a transaction and let WAIaaS wait for favorable conditions rather than polling and resubmitting yourself.&lt;/p&gt;

&lt;p&gt;This is built into the transaction pipeline at the stage level, not bolted on after the fact.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multi-Protocol Access
&lt;/h2&gt;

&lt;p&gt;The 15 integrated DeFi protocol providers — including Jupiter swap, Drift (perpetual futures), LI.FI (cross-chain bridging), Aave V3, Hyperliquid, and Across — are accessible through the same session-authenticated API. Your bot can:&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;# Swap on Jupiter (Solana)&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;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;All of these go through the same policy pipeline. Your CONTRACT_WHITELIST, METHOD_WHITELIST, and SPENDING_LIMIT apply to DeFi action calls just as they apply to raw contract calls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start Summary
&lt;/h2&gt;

&lt;p&gt;Here's the minimal path to a hardened trading bot setup:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start the daemon&lt;/strong&gt; — &lt;code&gt;docker compose up -d&lt;/code&gt; or &lt;code&gt;waiaas start&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create a wallet&lt;/strong&gt; — &lt;code&gt;POST /v1/wallets&lt;/code&gt; with masterAuth&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Issue a session token&lt;/strong&gt; — &lt;code&gt;POST /v1/sessions&lt;/code&gt; with masterAuth&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configure policies&lt;/strong&gt; — CONTRACT_WHITELIST, METHOD_WHITELIST, ALLOWED_TOKENS, SPENDING_LIMIT, ALLOWED_NETWORKS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dry-run your first transaction&lt;/strong&gt; — verify policy configuration with &lt;code&gt;dryRun: true&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy your bot&lt;/strong&gt; — session token in environment, master password locked away&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The OpenAPI spec is available at &lt;code&gt;http://127.0.0.1:3100/doc&lt;/code&gt; and the interactive API reference at &lt;code&gt;http://127.0.0.1:3100/reference&lt;/code&gt; — useful for exploring all 39 API route modules before writing your integration.&lt;/p&gt;

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

&lt;p&gt;The policy system has 21 types covering scenarios from DeFi-specific limits (PERP_MAX_LEVERAGE, LENDING_LTV_LIMIT) to reputation thresholds (REPUTATION_THRESHOLD for ERC-8004 agents) — worth reviewing the full list as your strategy grows more complex. If you're building on EVM, the ERC-4337 Account Abstraction support with gasless transactions and UserOp build/sign API opens up additional execution patterns. Start with the codebase and documentation:&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>web3</category>
      <category>api</category>
    </item>
    <item>
      <title>18-Network Docker Setup: Deploy Multi-Chain AI Agent Infrastructure</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Sun, 20 Sep 2026 16:46:48 +0000</pubDate>
      <link>https://dev.to/walletguy/18-network-docker-setup-deploy-multi-chain-ai-agent-infrastructure-deg</link>
      <guid>https://dev.to/walletguy/18-network-docker-setup-deploy-multi-chain-ai-agent-infrastructure-deg</guid>
      <description>&lt;h1&gt;
  
  
  Self-Hosted Multi-Chain AI Agent Infrastructure: Deploy WAIaaS Across 18 Networks with Docker
&lt;/h1&gt;

&lt;p&gt;Docker makes it surprisingly straightforward to run your own multi-chain AI agent wallet infrastructure — but most developers don't realize they can have the whole thing running locally in under five minutes, with no third-party custody of their keys. If you've ever felt uneasy handing an AI agent's private keys to a hosted service, or hit rate limits on a managed wallet API at the worst possible moment, this post is for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Would You Trust a Third Party With Your Agent's Private Keys?
&lt;/h2&gt;

&lt;p&gt;It's a fair question. When you use a hosted wallet-as-a-service, you're typically making a deal: convenience in exchange for custody. Someone else's server holds the keys, processes the transactions, and sits between your AI agent and the blockchain. For personal projects or low-stakes experiments, that trade-off is fine. But as soon as real funds are involved — or you need predictable uptime, custom policies, or just don't want to explain your agent's trading activity to a third-party compliance team — the hosted model starts to feel like running your own email but using Gmail to store the messages.&lt;/p&gt;

&lt;p&gt;The alternative is self-hosting. Your server, your keys, your rules.&lt;/p&gt;

&lt;p&gt;WAIaaS is an open-source, self-hosted Wallet-as-a-Service built specifically for AI agents. It runs in Docker, covers 18 networks across EVM chains and Solana, integrates with 15 DeFi protocols, and ships with a policy engine that puts you — not the platform — in control of what your agents can and can't do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Self-Hosting Actually Makes Sense Here
&lt;/h2&gt;

&lt;p&gt;The crypto self-hosting instinct is well-established. People run their own nodes, their own validators, their own RPC endpoints. The reasons are always the same: privacy, reliability, and sovereignty. WAIaaS extends that philosophy to the wallet infrastructure layer.&lt;/p&gt;

&lt;p&gt;When your AI agent needs to swap tokens, check a balance, or execute a DeFi position, it's talking to your local daemon — not an external API with its own rate limits, terms of service, or downtime schedule. You configure which RPC endpoints to use. You decide which networks are active. You set the policies that govern what the agent is allowed to spend, where it can send funds, and which contracts it can interact with. None of that configuration lives on someone else's server.&lt;/p&gt;

&lt;p&gt;There's also a practical engineering argument: the hosted model means your agent's behavior is coupled to external API availability. A self-hosted daemon bound to &lt;code&gt;127.0.0.1:3100&lt;/code&gt; is a dependency you control entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You're Actually Deploying
&lt;/h2&gt;

&lt;p&gt;WAIaaS ships as a 15-package monorepo with two Docker images: the main daemon and a push-relay for notifications. The daemon exposes 39 REST API route modules, supports 45 MCP tools for AI agent integration, and implements a 7-stage transaction pipeline that handles validation, policy checks, gas conditions, execution, and confirmation.&lt;/p&gt;

&lt;p&gt;The network coverage is broad: 18 networks across two chain types (EVM and Solana). You point each network at your own RPC endpoint using environment variables, so you're never dependent on WAIaaS's infrastructure for chain connectivity.&lt;/p&gt;

&lt;p&gt;The 15 DeFi protocol integrations — covering lending (Aave v3, Kamino), swaps (Jupiter, 0x, LI.FI, D'CENT), staking (Lido, Jito), perpetuals (Hyperliquid, Drift), prediction markets (Polymarket), bridging (Across), and more — run through the same local daemon. Your agent's DeFi activity stays between your server and the chain.&lt;/p&gt;

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

&lt;p&gt;The simplest path to a running instance is three commands:&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;That's it for a development setup. The Docker Compose file binds to &lt;code&gt;127.0.0.1:3100&lt;/code&gt; by default, so the daemon is only accessible from localhost unless you explicitly change that.&lt;/p&gt;

&lt;p&gt;For a more self-contained start — useful if you want to skip cloning the repo entirely — you can use &lt;code&gt;docker run&lt;/code&gt; with auto-provision:&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;&lt;code&gt;WAIAAS_AUTO_PROVISION=true&lt;/code&gt; generates a random master password on first start and writes it to &lt;code&gt;/data/recovery.key&lt;/code&gt; inside the container. You retrieve it once, store it somewhere safe, and then delete the recovery file. The data persists in a named Docker volume, so &lt;code&gt;docker compose down&lt;/code&gt; without &lt;code&gt;-v&lt;/code&gt; preserves everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring Your RPC Endpoints
&lt;/h2&gt;

&lt;p&gt;This is the part that actually makes self-hosting meaningful. WAIaaS lets you specify RPC endpoints per network via 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="nv"&gt;WAIAAS_RPC_EVM_ETHEREUM_MAINNET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;url&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can point these at your own node, a private RPC provider you already pay for, or a public endpoint — your choice. The daemon doesn't phone home for chain connectivity.&lt;/p&gt;

&lt;p&gt;The full Docker Compose configuration gives you a clear picture of what's configurable:&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;Put your RPC URLs and other configuration in a &lt;code&gt;.env&lt;/code&gt; file in the same directory. The &lt;code&gt;env_file&lt;/code&gt; stanza picks it up automatically, and &lt;code&gt;required: false&lt;/code&gt; means the daemon starts fine without it if you're just exploring.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hardening for Production: Docker Secrets
&lt;/h2&gt;

&lt;p&gt;If you're running this on a homelab server or a VPS you control, environment variables in a &lt;code&gt;.env&lt;/code&gt; file are convenient but not ideal for sensitive values. WAIaaS supports Docker Secrets for production deployments via a secrets overlay file:&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 reads secrets from the Docker Secrets mechanism, which mounts them as files in &lt;code&gt;/run/secrets/&lt;/code&gt; rather than exposing them as environment variables. For a homelab setup where you care about not having credentials in &lt;code&gt;docker inspect&lt;/code&gt; output, this is worth the extra step.&lt;/p&gt;

&lt;p&gt;The daemon also runs as a non-root user (UID 1001) by default, which is one of those small things that matters when you're thinking about container security seriously.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Wallets and Issuing Agent Sessions
&lt;/h2&gt;

&lt;p&gt;Once the daemon is running, you interact with it through its REST API. Three authentication headers cover different roles: &lt;code&gt;X-Master-Password&lt;/code&gt; for system administration (wallet creation, session management, policies), &lt;code&gt;Authorization: Bearer&lt;/code&gt; for AI agent sessions, and &lt;code&gt;X-Owner-Signature&lt;/code&gt; for fund-owner approval of high-value transactions.&lt;/p&gt;

&lt;p&gt;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 session token is what your agent actually uses. It's scoped to a specific wallet, and its capabilities are bounded by whatever policies you've attached to that wallet. The master password never leaves your environment.&lt;/p&gt;

&lt;p&gt;If you prefer the CLI, &lt;code&gt;waiaas quickset --mode mainnet&lt;/code&gt; creates wallets and MCP sessions in a single command.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Policy Engine: Defining What Your Agent Can Do
&lt;/h2&gt;

&lt;p&gt;Self-hosting is only half the sovereignty story. The other half is controlling what your agent is actually allowed to do with the funds you've given it access to.&lt;/p&gt;

&lt;p&gt;WAIaaS implements a policy engine with 21 policy types and 4 security tiers: INSTANT (execute immediately), NOTIFY (execute and notify you), DELAY (queue for a configurable number of seconds, cancellable), and APPROVAL (require explicit human sign-off). The engine is default-deny: transactions involving tokens not on the &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt; whitelist, or contracts not on the &lt;code&gt;CONTRACT_WHITELIST&lt;/code&gt;, are blocked.&lt;/p&gt;

&lt;p&gt;A spending limit policy that tiers transactions by USD value 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, transactions under $100 execute immediately. Transactions between $100 and $500 trigger a notification. Transactions between $500 and $2,000 are queued for 15 minutes before execution, giving you a window to cancel. Anything over $2,000 requires your explicit approval — delivered via WalletConnect, Telegram, or push notification, depending on how you've configured signing channels.&lt;/p&gt;

&lt;p&gt;The full list of 21 policy types covers DeFi-specific constraints too: &lt;code&gt;LENDING_LTV_LIMIT&lt;/code&gt; caps loan-to-value ratios, &lt;code&gt;PERP_MAX_LEVERAGE&lt;/code&gt; limits futures leverage, &lt;code&gt;PERP_MAX_POSITION_USD&lt;/code&gt; caps position sizes, and &lt;code&gt;X402_ALLOWED_DOMAINS&lt;/code&gt; controls which APIs your agent can pay for automatically via the x402 HTTP payment protocol.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting AI Agents via MCP
&lt;/h2&gt;

&lt;p&gt;The most practical integration path for LLM-based agents is MCP (Model Context Protocol). WAIaaS ships 45 MCP tools covering wallet operations, transfers, DeFi actions, NFT management, and x402 payments.&lt;/p&gt;

&lt;p&gt;After running &lt;code&gt;waiaas mcp setup --all&lt;/code&gt;, you get a configuration block to paste into Claude Desktop:&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;&lt;code&gt;WAIAAS_BASE_URL&lt;/code&gt; points at your local daemon. The agent session token scopes what the agent can do. Everything stays local — Claude's tool calls go to &lt;code&gt;127.0.0.1:3100&lt;/code&gt;, which means your wallet interactions never pass through any external MCP relay.&lt;/p&gt;

&lt;p&gt;For multi-agent setups, you can run one MCP server entry per wallet, each with its own session token and policy set.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simulating Before Executing
&lt;/h2&gt;

&lt;p&gt;One useful capability for self-hosters who are still tuning their agent's behavior: dry-run simulation. Before any real transaction hits the chain, 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 pipeline runs through all its stages — validation, policy checks, gas condition evaluation — without submitting anything on-chain. Useful for verifying that your policy configuration is doing what you think it's doing before you let the agent loose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start Summary
&lt;/h2&gt;

&lt;p&gt;Five steps from zero to running multi-chain agent infrastructure:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Clone and start&lt;/strong&gt;: &lt;code&gt;git clone https://github.com/waiaas/WAIaaS.git &amp;amp;&amp;amp; cd WAIaaS &amp;amp;&amp;amp; docker compose up -d&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create a wallet&lt;/strong&gt;: POST to &lt;code&gt;/v1/wallets&lt;/code&gt; with your master password&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set policies&lt;/strong&gt;: POST to &lt;code&gt;/v1/policies&lt;/code&gt; to define spending limits and token whitelists&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create an agent session&lt;/strong&gt;: POST to &lt;code&gt;/v1/sessions&lt;/code&gt; to get a scoped session token&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connect your agent&lt;/strong&gt;: Run &lt;code&gt;waiaas mcp setup --all&lt;/code&gt; and paste the output into Claude Desktop config&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The interactive API reference at &lt;code&gt;http://127.0.0.1:3100/reference&lt;/code&gt; documents every endpoint. The OpenAPI 3.0 spec is downloadable at &lt;code&gt;/doc&lt;/code&gt; if you want to generate client code or import it into Postman.&lt;/p&gt;

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

&lt;p&gt;The 684+ test files in the codebase mean the daemon is genuinely production-ready for homelab and small-scale production use, not just a demo. The GitHub repository at &lt;a href="https://github.com/waiaas/WAIaaS" rel="noopener noreferrer"&gt;https://github.com/waiaas/WAIaaS&lt;/a&gt; has the full setup documentation, and &lt;a href="https://waiaas.ai" rel="noopener noreferrer"&gt;https://waiaas.ai&lt;/a&gt; covers the broader ecosystem including SDK references and protocol integration details. If you're already running your own RPC nodes and want to close the loop on self-hosted agent infrastructure, the Docker setup is the natural next step.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>web3</category>
      <category>selfhosted</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>True Economic Autonomy: How AI Agents Use x402 to Buy Their Own Resources</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Sun, 20 Sep 2026 11:35:47 +0000</pubDate>
      <link>https://dev.to/walletguy/true-economic-autonomy-how-ai-agents-use-x402-to-buy-their-own-resources-57oj</link>
      <guid>https://dev.to/walletguy/true-economic-autonomy-how-ai-agents-use-x402-to-buy-their-own-resources-57oj</guid>
      <description>&lt;h1&gt;
  
  
  True Economic Autonomy: How AI Agents Use x402 to Buy Their Own Resources
&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. The x402 HTTP payment protocol, combined with autonomous wallet infrastructure, gives agents the ability to transact independently without a human managing every payment. This isn't a whitepaper concept or a research preview. It's running code you can deploy this afternoon.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With "Human in the Loop" Payments
&lt;/h2&gt;

&lt;p&gt;Think about what an AI agent actually needs to do its job. It calls APIs. It fetches data. It spins up compute. Every one of those operations costs money. Right now, the way most people solve this is simple: give the agent an API key backed by a human's credit card, and hope nothing goes wrong.&lt;/p&gt;

&lt;p&gt;That works fine for demos. It falls apart at scale.&lt;/p&gt;

&lt;p&gt;The agent has no awareness of what it's spending. There's no budget enforcement at the infrastructure level. If the agent misbehaves — or gets compromised — there's nothing stopping it from draining your card. And if you want to run hundreds of agents, you're now managing hundreds of billing relationships, manually.&lt;/p&gt;

&lt;p&gt;What you actually want is agents that have their own wallets, their own budgets, and their own ability to make payments — with the humans who deploy them retaining meaningful oversight without babysitting every transaction.&lt;/p&gt;

&lt;p&gt;That's the gap x402 fills, and it's the gap WAIaaS was built to close.&lt;/p&gt;

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

&lt;p&gt;x402 is an HTTP payment protocol. The idea is simple: when a client requests a resource that costs money, the server responds with HTTP 402 — "Payment Required" — along with payment details. The client pays, includes proof of payment in a retry request, and the server responds with the actual resource.&lt;/p&gt;

&lt;p&gt;From the server's perspective, it's standard HTTP. From the agent's perspective, it's invisible: the payment happens automatically as part of the request cycle.&lt;/p&gt;

&lt;p&gt;WAIaaS exposes this as a native tool in both its MCP integration and its TypeScript SDK. An agent configured with a WAIaaS session token can call &lt;code&gt;x402Fetch()&lt;/code&gt; exactly like it would call a normal &lt;code&gt;fetch()&lt;/code&gt; — and the payment handling is automatic.&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;// Agent fetches a paid API endpoint — payment handled automatically&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/market-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;No manual payment flow. No human approval required for every call (unless you configure one). The agent pays for what it uses, from its own wallet, within the limits you set.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Missing Infrastructure Layer: Wallets for Agents
&lt;/h2&gt;

&lt;p&gt;For x402 to work, the agent needs a wallet with funds and the ability to sign transactions. WAIaaS provides exactly that — a self-hosted, open-source Wallet-as-a-Service that's designed from the ground up for AI agents, not humans.&lt;/p&gt;

&lt;p&gt;When you create a wallet in WAIaaS, you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A wallet address on any supported chain (WAIaaS supports 2 chain types — EVM and Solana — across 18 networks)&lt;/li&gt;
&lt;li&gt;A session token the agent uses for all API calls&lt;/li&gt;
&lt;li&gt;A policy engine that enforces spending rules without human intervention&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last part is important. Autonomous doesn't mean uncontrolled.&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 for your agent (masterAuth — this is you, the operator)&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 the agent will use&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 session token goes to the agent. The master password stays with you. The agent can transact within its policy bounds — it cannot create new wallets, cannot elevate its own permissions, cannot touch master-level operations.&lt;/p&gt;

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

&lt;p&gt;This is where WAIaaS gets interesting for anyone thinking seriously about agent economic autonomy.&lt;/p&gt;

&lt;p&gt;Pure autonomy — an agent that can spend without limits — is dangerous. But pure human control — requiring approval for every payment — eliminates the value of autonomous agents. WAIaaS resolves this tension with a 21-type policy engine and 4 security tiers.&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 notification to owner&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DELAY&lt;/strong&gt; — Queue for a configurable delay, then execute (cancellable)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;APPROVAL&lt;/strong&gt; — Require human approval before execution&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;. You whitelist the domains your agent is allowed to pay automatically, and everything else gets blocked or escalated.&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;A realistic setup for an autonomous agent might look like this: small x402 API payments (under $1) execute instantly. Larger transactions trigger a notification. Anything over a threshold requires your approval via WalletConnect or Telegram before it goes through.&lt;/p&gt;

&lt;p&gt;The policy engine is default-deny. If you haven't explicitly whitelisted a token or contract, the transaction is blocked. This means a misconfigured or compromised agent can't spontaneously start doing things it was never authorized to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Full Picture: 45 MCP Tools, Today
&lt;/h2&gt;

&lt;p&gt;If you're using Claude or another MCP-compatible AI assistant, WAIaaS exposes 45 MCP tools covering wallet operations, transactions, DeFi, NFTs, and x402. Setup is two commands:&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 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 instance can check balances, send tokens, query DeFi positions, and make x402 payments — all through natural language, with every transaction passing through the policy engine before execution.&lt;/p&gt;

&lt;p&gt;The x402-fetch tool is one of those 45. When Claude encounters a 402 response, it can call that tool directly. The payment happens, the resource is retrieved, and Claude continues its task. From the user's perspective, the agent just... got the data it needed. The economic machinery underneath is invisible.&lt;/p&gt;

&lt;h2&gt;
  
  
  DeFi Integration: Agents That Manage Their Own Treasury
&lt;/h2&gt;

&lt;p&gt;x402 micro-payments are one side of agent economic autonomy. The other side is what agents do with funds they're not spending on API calls.&lt;/p&gt;

&lt;p&gt;WAIaaS integrates 15 DeFi protocol providers, including Aave v3, Jupiter, Lido, Jito, Hyperliquid, Kamino, and Pendle. An agent with the right session permissions and policies configured can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Swap tokens on Jupiter (Solana) or 0x (EVM)&lt;/li&gt;
&lt;li&gt;Supply assets to Aave for yield while idle&lt;/li&gt;
&lt;li&gt;Stake SOL via Jito or ETH via Lido&lt;/li&gt;
&lt;li&gt;Trade perpetual futures on Hyperliquid&lt;/li&gt;
&lt;li&gt;Bridge funds across chains via LI.FI or Across
&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;# Agent executes a Jupiter swap autonomously&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;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;This is treasury management at the agent level. An agent that earns revenue (via x402 or other means) can park idle funds in yield-bearing positions, rebalance based on market conditions, and manage its own economic sustainability — within whatever constraints its operator configured.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before the Agent Spends: Dry-Run Simulation
&lt;/h2&gt;

&lt;p&gt;One feature worth calling out explicitly for autonomous agent contexts: the dry-run API. Before any transaction executes, you can simulate it against the full policy engine and get back the expected outcome — without actually sending anything.&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 agents making decisions about whether to proceed with a payment, this is genuinely useful. The agent can check whether a proposed transaction would be allowed — and what tier it would trigger — before committing. It's the difference between an agent that tries to spend and gets blocked, versus an agent that checks its constraints before acting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started in Under 10 Minutes
&lt;/h2&gt;

&lt;p&gt;The fastest path from zero to a working autonomous agent wallet:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Install the CLI and 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;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;&lt;strong&gt;Step 3: Configure your agent's MCP connection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;quickset&lt;/code&gt; command prints a JSON config block. Paste it into your Claude Desktop config file, or run:&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;Step 4: Set spending policies&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use the REST API or the Admin Web UI at &lt;code&gt;/admin&lt;/code&gt; to configure &lt;code&gt;SPENDING_LIMIT&lt;/code&gt; and &lt;code&gt;X402_ALLOWED_DOMAINS&lt;/code&gt; policies for your agent's wallet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Fund the wallet and let the agent work&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Send funds to the wallet address. Your agent now has autonomous payment capability, bounded by the policies you set.&lt;/p&gt;

&lt;p&gt;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 runs as a non-root user (UID 1001), includes a healthcheck, and supports auto-provisioning for unattended deployments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters Beyond the Demo
&lt;/h2&gt;

&lt;p&gt;The conversation about AI agents tends to get stuck on capabilities — what the agent can &lt;em&gt;do&lt;/em&gt;. The economic layer tends to get treated as a solved problem, or kicked down the road.&lt;/p&gt;

&lt;p&gt;It isn't solved. Right now, most agent deployments are economically dependent on their operators in ways that limit what they can actually do autonomously. Every payment requires a human-managed credential. Every API call is billed to a human's account. The agent is autonomous in reasoning but dependent in resources.&lt;/p&gt;

&lt;p&gt;x402 changes that relationship. An agent with its own wallet, its own budget, and the ability to make payments autonomously isn't just a more capable agent — it's a different kind of entity. One that can operate at scale, across multiple instances, paying for exactly what it uses, without a human manually managing billing for each one.&lt;/p&gt;

&lt;p&gt;WAIaaS is the infrastructure layer that makes that possible today, not in some hypothetical future. The 7-stage transaction pipeline, the 21-type policy engine, the 45 MCP tools, the 15 DeFi integrations — these exist, they're tested (684+ test files across the monorepo), and they're open source.&lt;/p&gt;

&lt;p&gt;The agent economy isn't coming. It's here. The question is whether the agents you're building have the wallet infrastructure to participate in it.&lt;/p&gt;

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

&lt;p&gt;The WAIaaS documentation and interactive API reference are available at &lt;code&gt;/reference&lt;/code&gt; once you have the daemon running — the OpenAPI 3.0 spec is auto-generated at &lt;code&gt;/doc&lt;/code&gt;. For a deeper look at how the policy engine works and how to configure it for production agent deployments, the GitHub repository at &lt;a href="https://github.com/waiaas/WAIaaS" rel="noopener noreferrer"&gt;https://github.com/waiaas/WAIaaS&lt;/a&gt; is the authoritative source. The official site at &lt;a href="https://waiaas.ai" rel="noopener noreferrer"&gt;https://waiaas.ai&lt;/a&gt; has additional context on use cases and deployment patterns.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
      <category>blockchain</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Trustworthy DeFi Bots: ERC-8004 Onchain Reputation for Automated Trading</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Sat, 19 Sep 2026 16:24:43 +0000</pubDate>
      <link>https://dev.to/walletguy/trustworthy-defi-bots-erc-8004-onchain-reputation-for-automated-trading-47nc</link>
      <guid>https://dev.to/walletguy/trustworthy-defi-bots-erc-8004-onchain-reputation-for-automated-trading-47nc</guid>
      <description>&lt;h1&gt;
  
  
  Trustworthy DeFi Bots: ERC-8004 Onchain Reputation for Automated Trading
&lt;/h1&gt;

&lt;p&gt;DeFi trading bots that can't prove their identity are a liability — and if you're building automated strategies across Jupiter, Aave, Hyperliquid, or Lido, you already know the pain of stitching together 13 different SDKs just to get one bot talking to multiple protocols. There's a better way: a single unified API layer with built-in onchain reputation so your bot isn't just capable — it's verifiable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Problem: Fragmentation and Trust
&lt;/h2&gt;

&lt;p&gt;If you've ever built a multi-protocol DeFi bot, you've lived the integration nightmare. Jupiter has its own SDK. Aave has another. Hyperliquid is a completely different beast. Drift, Kamino, Pendle, Polymarket — each one requires its own authentication logic, its own transaction construction, and its own error handling. By the time you've wired all of that together, you've written more glue code than actual trading logic.&lt;/p&gt;

&lt;p&gt;But there's a deeper issue that doesn't get talked about enough: &lt;strong&gt;trust&lt;/strong&gt;. When your bot executes autonomously — swapping, lending, staking, opening perp positions — how does anyone know it's behaving within sanctioned parameters? How do you prove, on-chain, that your agent has a track record of legitimate operation? ERC-8004 is designed to answer exactly that question, and WAIaaS has it built in.&lt;/p&gt;

&lt;h2&gt;
  
  
  What ERC-8004 Actually Does
&lt;/h2&gt;

&lt;p&gt;ERC-8004 is an onchain agent reputation and validation standard. It lets a smart contract or protocol check whether an agent has an established reputation before allowing it to interact. Think of it as a credit score for bots — except it lives on-chain and can't be faked.&lt;/p&gt;

&lt;p&gt;WAIaaS integrates ERC-8004 directly through its action provider system. The &lt;code&gt;erc8004&lt;/code&gt; provider is one of 15 DeFi protocol integrations baked into the platform, and there are dedicated MCP tools for it: &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;. You can query reputation, validate an agent's standing, and enforce a &lt;code&gt;REPUTATION_THRESHOLD&lt;/code&gt; policy — all through the same API your bot already uses for swaps and lending.&lt;/p&gt;

&lt;p&gt;This matters because DeFi protocols increasingly want to know &lt;em&gt;who&lt;/em&gt; (or &lt;em&gt;what&lt;/em&gt;) is calling them. An agent with a proven on-chain track record is fundamentally different from an anonymous wallet that just appeared. ERC-8004 gives your bot a verifiable identity that compounds over time.&lt;/p&gt;

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

&lt;p&gt;Before diving into reputation mechanics, let's be concrete about what "unified API" actually means here. WAIaaS integrates 15 DeFi protocol providers:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solana:&lt;/strong&gt; Jupiter (swap), Jito (staking), Kamino, Drift, Hyperliquid&lt;br&gt;&lt;br&gt;
&lt;strong&gt;EVM:&lt;/strong&gt; Aave v3, Lido (staking), Pendle, Zerox, D'CENT&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Cross-chain:&lt;/strong&gt; LI.FI, Across&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Other:&lt;/strong&gt; Polymarket, XRPL DEX, ERC-8004&lt;/p&gt;

&lt;p&gt;Every single one of these is accessible through the same REST API pattern. Your bot authenticates once with a session token, and then calls whichever protocol it needs. Here's what a Jupiter swap 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/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 it. No Jupiter SDK. No custom RPC handling. No transaction serialization. The same pattern applies whether you're calling Aave, Lido, or Hyperliquid. Your bot sends a JSON payload with the action parameters; WAIaaS handles protocol-specific construction, signing, and submission.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Reputation-Aware Trading Bot
&lt;/h2&gt;

&lt;p&gt;Here's where it gets interesting from a design perspective. A reputation-aware bot isn't just one that &lt;em&gt;has&lt;/em&gt; a good reputation — it's one that &lt;em&gt;enforces&lt;/em&gt; reputation checks before interacting with counterparties, and &lt;em&gt;builds&lt;/em&gt; its own reputation through consistent, policy-compliant behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Set Up the Bot's Identity
&lt;/h3&gt;

&lt;p&gt;Start with the WAIaaS CLI to provision a wallet and create a session for your trading bot:&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;code&gt;quickset&lt;/code&gt; creates wallets and MCP sessions in one step. For a trading bot, you'd then create a dedicated session with constrained permissions — your bot gets its own JWT session token (&lt;code&gt;wai_sess_...&lt;/code&gt;) that defines exactly what it can do.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Configure Policies That Build Reputation
&lt;/h3&gt;

&lt;p&gt;ERC-8004 reputation is built through consistent, bounded behavior. WAIaaS's policy engine enforces those bounds automatically. With 21 policy types and 4 security tiers (INSTANT, NOTIFY, DELAY, APPROVAL), you define guardrails once and the system enforces them on every transaction.&lt;/p&gt;

&lt;p&gt;For a DeFi trading bot, a typical policy stack 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;# Spending limit: small trades instant, larger trades require approval&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;p&gt;You'd layer this with &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt; (default-deny token whitelist), &lt;code&gt;CONTRACT_WHITELIST&lt;/code&gt; (only your known protocol contracts), &lt;code&gt;PERP_MAX_LEVERAGE&lt;/code&gt; (cap leverage for Hyperliquid or Drift), and &lt;code&gt;VENUE_WHITELIST&lt;/code&gt; (restrict which DEXes the bot can touch).&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;REPUTATION_THRESHOLD&lt;/code&gt; policy is the ERC-8004 integration point: it blocks transactions from agents whose on-chain reputation score falls below a configured minimum. If your bot is interacting with a counterparty agent, you can require that agent to meet a reputation threshold before the trade proceeds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Check Reputation Before Trading
&lt;/h3&gt;

&lt;p&gt;Through the MCP interface, your AI agent can query reputation state before executing. The 45 MCP tools include three specifically for ERC-8004:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;erc8004-get-agent-info&lt;/code&gt; — retrieve agent metadata and registration status&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;erc8004-get-reputation&lt;/code&gt; — get the current reputation score&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;erc8004-get-validation-status&lt;/code&gt; — check whether an agent passes validation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice, a Claude-based trading agent configured via MCP can run a check like "verify the counterparty agent's reputation before executing this trade" as a natural language instruction. Claude calls the appropriate MCP tool, gets the validation status, and proceeds (or doesn't) based on the result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Simulate Before You Execute
&lt;/h3&gt;

&lt;p&gt;Reputation isn't just about who your bot interacts with — it's about your bot's own track record. A bot that never fails policy checks and never reverts transactions builds reputation faster. WAIaaS's dry-run API lets you validate every trade before committing:&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;Run this before every execution. If the simulation fails — policy denial, insufficient balance, gas condition not met — you learn that without burning gas or generating a failed transaction on-chain. Fewer failed transactions means cleaner reputation growth.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Gas-Conditional Execution
&lt;/h3&gt;

&lt;p&gt;DeFi bots that execute at bad gas prices get crushed on EVM chains. WAIaaS has a gas condition stage in its 7-stage transaction pipeline: transactions execute only when gas price meets your configured threshold. This isn't something you need to implement — it's built into the pipeline at stage level. Your bot submits the transaction; the pipeline handles gas gating automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  The TypeScript SDK Path
&lt;/h2&gt;

&lt;p&gt;If you prefer SDK over raw REST calls, the TypeScript SDK gives you the same access with type safety:&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;// Check balance before trading&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;// Execute action and poll for confirmation&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="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;Handle policy denials explicitly — your bot's error handling should distinguish between retryable errors and hard policy blocks:&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;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;A &lt;code&gt;POLICY_DENIED&lt;/code&gt; error is not retryable — don't hammer the API. Log it, alert, and wait for human review via the APPROVAL flow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Approval Flow for High-Stakes Trades
&lt;/h2&gt;

&lt;p&gt;When a trade exceeds your DELAY tier threshold, it goes into a queue. The human owner receives a notification and must approve via WalletConnect or Telegram before execution. This is the &lt;code&gt;APPROVAL&lt;/code&gt; security tier in action:&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;For a DeFi bot, this is the right behavior for large positions. Your bot proposes the trade; a human reviews and signs off. The ERC-8004 angle here is that consistent use of proper approval flows — rather than trying to circumvent limits — is exactly the kind of on-chain behavior that builds long-term reputation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start: DeFi Bot in 5 Steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install and start:&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 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; waiaas start
   waiaas quickset &lt;span class="nt"&gt;--mode&lt;/span&gt; mainnet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Configure policies&lt;/strong&gt; via the REST API — at minimum: &lt;code&gt;SPENDING_LIMIT&lt;/code&gt;, &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt;, &lt;code&gt;CONTRACT_WHITELIST&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Set up MCP&lt;/strong&gt; for AI agent access:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&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;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install the TypeScript SDK&lt;/strong&gt; and wire up your trading logic:
&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; @waiaas/sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Deploy with Docker&lt;/strong&gt; for production:
&lt;/li&gt;
&lt;/ol&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;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The combination of 15 integrated DeFi protocols, a 21-policy enforcement engine, and ERC-8004 onchain reputation means you can build bots that are not just capable but auditable and trustworthy by design. Every trade within policy bounds, every simulation before execution, every approval for high-stakes positions — it all compounds into a verifiable track record.&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;https://github.com/waiaas/WAIaaS&lt;/a&gt;, or check the documentation and hosted options at &lt;a href="https://waiaas.ai" rel="noopener noreferrer"&gt;https://waiaas.ai&lt;/a&gt;. The OpenAPI spec is available at &lt;code&gt;/doc&lt;/code&gt; and the interactive reference UI at &lt;code&gt;/reference&lt;/code&gt; once your daemon is running — start there to understand the full surface area before wiring up your strategy.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Tags: #defi #web3 #blockchain #tutorial&lt;/em&gt;&lt;/p&gt;

</description>
      <category>defi</category>
      <category>security</category>
      <category>ai</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Production AI Wallet Deployment: GHCR Image with Auto-Provision and Secrets</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Sat, 19 Sep 2026 11:11:11 +0000</pubDate>
      <link>https://dev.to/walletguy/production-ai-wallet-deployment-ghcr-image-with-auto-provision-and-secrets-2c43</link>
      <guid>https://dev.to/walletguy/production-ai-wallet-deployment-ghcr-image-with-auto-provision-and-secrets-2c43</guid>
      <description>&lt;h1&gt;
  
  
  Production AI Wallet Deployment: Self-Hosting WAIaaS with Docker, Auto-Provision, and Secrets
&lt;/h1&gt;

&lt;p&gt;Deploying a self-hosted AI wallet means your agent's private keys never leave your server — and with WAIaaS's Docker image on GHCR, you can have the whole stack running in a single command. If you've ever asked yourself whether you'd hand over signing authority for an autonomous agent to a third-party service you don't control, this post is for you. We'll walk through exactly how to get WAIaaS running in production on your own hardware, with proper secret management and automatic provisioning from the start.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Self-Hosting an AI Wallet Actually Matters
&lt;/h2&gt;

&lt;p&gt;There's a philosophical argument and a practical one. The philosophical argument is simple: private keys are the root of custody. If someone else holds them — even behind a well-intentioned API — they hold the assets. For autonomous AI agents that sign transactions without human approval for every action, that's a significant trust delegation.&lt;/p&gt;

&lt;p&gt;The practical argument is about control over your own infrastructure. Self-hosting means you define the network exposure, the security policies, the update schedule, and the backup strategy. There are no rate limits imposed by a third party on your wallet operations. You're not subject to a remote service going down during a critical trading window. Your agent's transaction history stays on your server. For developers building serious agent infrastructure, or privacy-conscious enthusiasts running homelab setups, that level of ownership matters a lot.&lt;/p&gt;

&lt;p&gt;WAIaaS is an open-source, self-hosted Wallet-as-a-Service designed specifically for AI agents. It runs as a Docker container, exposes a REST API your agents call, and never requires your keys to leave the machine. Let's get it running properly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The WAIaaS Docker Image
&lt;/h2&gt;

&lt;p&gt;WAIaaS publishes a Docker image at &lt;code&gt;ghcr.io/waiaas/waiaas:latest&lt;/code&gt;. There are actually two Docker images in the project — the main WAIaaS daemon and a push-relay service for notifications — but for the core wallet infrastructure, you're working with the daemon image.&lt;/p&gt;

&lt;p&gt;The daemon listens on port &lt;code&gt;3100&lt;/code&gt; by default, bound to &lt;code&gt;127.0.0.1&lt;/code&gt; so it's not exposed to the network unless you explicitly configure that. The data directory at &lt;code&gt;/data&lt;/code&gt; is where everything persistent lives — wallets, sessions, policy configuration, and the SQLite database.&lt;/p&gt;

&lt;p&gt;Here's the simplest possible production-ready deployment:&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;The &lt;code&gt;WAIAAS_AUTO_PROVISION=true&lt;/code&gt; flag is important. On first start, instead of blocking and waiting for you to set a master password interactively, the container generates a cryptographically random password and writes it to &lt;code&gt;/data/recovery.key&lt;/code&gt;. You retrieve it once, store it somewhere safe, and the daemon is running without any manual intervention. This is the pattern that makes WAIaaS deployable in automated infrastructure — no interactive prompts blocking your container startup.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Proper Docker Compose Setup
&lt;/h2&gt;

&lt;p&gt;For anything beyond a quick test, you want a Compose file. Here's the production-ready version:&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 in this configuration:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Port binding&lt;/strong&gt;: &lt;code&gt;127.0.0.1:3100:3100&lt;/code&gt; means the API is only reachable from localhost. If your AI agent runs on the same machine, this is correct. If you're putting a reverse proxy in front (nginx, Caddy, Traefik), the proxy connects to this port locally and you expose TLS externally. Never bind to &lt;code&gt;0.0.0.0:3100&lt;/code&gt; in production without a firewall rule or auth layer in front.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Named volume&lt;/strong&gt;: Using &lt;code&gt;waiaas-data&lt;/code&gt; as a named volume rather than a bind mount gives Docker responsibility for managing the data path. &lt;code&gt;docker compose down&lt;/code&gt; preserves the volume. &lt;code&gt;docker compose down -v&lt;/code&gt; removes it. Be aware of that difference when running maintenance commands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Healthcheck&lt;/strong&gt;: The built-in healthcheck polls &lt;code&gt;/health&lt;/code&gt; every 30 seconds. This integrates with Docker's health status, which means orchestrators and monitoring tools can detect when the daemon is actually ready rather than just when the container process has started.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;restart: unless-stopped&lt;/strong&gt;: The daemon comes back automatically after a server reboot, which is what you want for anything running agents that need to be continuously available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing Secrets in Production
&lt;/h2&gt;

&lt;p&gt;The auto-provision flow is great for getting started, but in production you want secrets managed properly — not sitting in environment variables that show up in &lt;code&gt;docker inspect&lt;/code&gt; output or in your shell history.&lt;/p&gt;

&lt;p&gt;WAIaaS supports Docker Secrets through a &lt;code&gt;docker-compose.secrets.yml&lt;/code&gt; overlay file. The pattern is to create secret files with restricted permissions, then deploy with both compose files:&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 overlay approach is deliberate — your base &lt;code&gt;docker-compose.yml&lt;/code&gt; can be committed to version control without secrets, and &lt;code&gt;docker-compose.secrets.yml&lt;/code&gt; stays out of git (add it to &lt;code&gt;.gitignore&lt;/code&gt;). This is a cleaner separation than environment variable files and fits well with secret management tools like Vault or cloud-provider secret stores that can write files to the secrets directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Environment Variables
&lt;/h2&gt;

&lt;p&gt;Once you're past the initial setup, you'll want to configure RPC endpoints and other runtime parameters. The most important ones:&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_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="c"&gt;# Auto-generate master password on first start&lt;/span&gt;
&lt;span class="nv"&gt;WAIAAS_DAEMON_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3100                 &lt;span class="c"&gt;# Listening port&lt;/span&gt;
&lt;span class="nv"&gt;WAIAAS_DAEMON_HOSTNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.0.0.0         &lt;span class="c"&gt;# Bind address&lt;/span&gt;
&lt;span class="nv"&gt;WAIAAS_DAEMON_LOG_LEVEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info            &lt;span class="c"&gt;# Log level (trace/debug/info/warn/error)&lt;/span&gt;
&lt;span class="nv"&gt;WAIAAS_DATA_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/data                   &lt;span class="c"&gt;# Data directory&lt;/span&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;The RPC endpoint variables are important for self-hosters. WAIaaS supports 18 networks across EVM and Solana chain types, and you'll want to point to your own RPC nodes or a service where you control the API key. Running your own agents against a shared public RPC endpoint under load is a recipe for rate limiting at the worst possible moment.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Zero to Running Agent: The Full Sequence
&lt;/h2&gt;

&lt;p&gt;If you're starting fresh on a machine with Docker installed, here's the complete path from nothing to a wallet your agent can use:&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;&lt;strong&gt;Step 2: Retrieve your master password&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 &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;Store this somewhere safe. This is your &lt;code&gt;masterAuth&lt;/code&gt; credential — it controls wallet creation, session management, and policy configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Create a 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;Step 4: Create a session for your agent&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;The session token you get back is what your agent uses. It authenticates as &lt;code&gt;sessionAuth&lt;/code&gt; — a JWT the agent includes as a Bearer token. The master password never goes anywhere near your agent code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Set a policy before funding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before you put real funds in, set a spending limit:&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;WAIaaS has a default-deny policy model: transactions are blocked unless you've explicitly configured what's allowed. The policy engine has 21 policy types covering everything from spending limits to DeFi-specific guardrails like maximum perpetual futures leverage and loan-to-value limits for lending positions. Getting at least a &lt;code&gt;SPENDING_LIMIT&lt;/code&gt; and &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt; policy in place before funding is the self-hoster equivalent of configuring your firewall before opening ports.&lt;/p&gt;

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

&lt;p&gt;One thing that surprises people coming from simpler wallet setups is that WAIaaS has three distinct authentication layers, each with a different principal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;masterAuth&lt;/strong&gt; — The system administrator layer. Uses Argon2id password hashing. Controls wallet creation, session management, and policy configuration. Your agent code should never have this credential.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;sessionAuth&lt;/strong&gt; — The agent layer. JWT tokens (HS256) scoped to a specific wallet. This is what goes in your agent's environment variables. Tokens have configurable TTL, max renewals, and absolute lifetime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ownerAuth&lt;/strong&gt; — The fund owner layer. Signs with ed25519 or secp256k1 (SIWS/SIWE). Used for approving high-value transactions that the policy engine has flagged for human review, and for kill-switch recovery.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This separation means that even if an agent's session token is compromised, an attacker can't create new wallets, modify policies, or bypass the approval flow for large transactions. The policy engine sits in the middle — a 7-stage transaction pipeline that every outgoing transaction passes through regardless of which API path initiated it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checking Everything Is Running
&lt;/h2&gt;

&lt;p&gt;The API has 39 REST route modules and a full OpenAPI 3.0 spec auto-generated at &lt;code&gt;/doc&lt;/code&gt;, with an interactive Scalar reference UI at &lt;code&gt;/reference&lt;/code&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="c"&gt;# Download OpenAPI 3.0 spec&lt;/span&gt;
curl http://127.0.0.1:3100/doc &lt;span class="nt"&gt;-o&lt;/span&gt; openapi.json

&lt;span class="c"&gt;# View interactive API reference&lt;/span&gt;
open http://127.0.0.1:3100/reference
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For day-to-day operations, the useful Docker commands are:&lt;br&gt;
&lt;/p&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&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-v&lt;/code&gt; flag on &lt;code&gt;down&lt;/code&gt; is the one to be careful about. It's there when you need it, but you don't want to run it reflexively during a restart.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Philosophy Behind Self-Hosting This Stack
&lt;/h2&gt;

&lt;p&gt;Running your own email server used to be the canonical example of self-hosting done right — full control, but genuinely complicated to operate. The knock against it was always the operational burden.&lt;/p&gt;

&lt;p&gt;WAIaaS is built to avoid that tradeoff. The Docker image handles auto-provision, Docker Secrets, healthchecks, and runs as a non-root user (UID 1001). The CLI has 20 commands covering everything from initial setup (&lt;code&gt;waiaas init&lt;/code&gt;, &lt;code&gt;waiaas start&lt;/code&gt;) to backup management (&lt;code&gt;waiaas backup create&lt;/code&gt;, &lt;code&gt;waiaas backup list&lt;/code&gt;, &lt;code&gt;waiaas backup inspect&lt;/code&gt;) to owner key management (&lt;code&gt;waiaas owner connect&lt;/code&gt;, &lt;code&gt;waiaas owner disconnect&lt;/code&gt;). The &lt;code&gt;waiaas quickset&lt;/code&gt; command creates wallets and MCP sessions in one step.&lt;/p&gt;

&lt;p&gt;For a homelab running AI agents with real assets, self-hosting this way is meaningfully different from using a hosted wallet service. Your transaction data doesn't leave your server. Your private keys are generated and stored on hardware you control. The policy engine runs locally. If the WAIaaS project went offline tomorrow, your self-hosted instance would keep running indefinitely — there's no cloud dependency in the critical path.&lt;/p&gt;

&lt;p&gt;Your keys, your server, your rules. That's not just a slogan when the alternative is autonomous agents signing transactions against keys held by a third party.&lt;/p&gt;

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

&lt;p&gt;Once your daemon is running, the next natural step is connecting your AI agents — either through the MCP integration for Claude and other MCP-compatible frameworks, or directly via the TypeScript or Python SDK. The policy engine deserves dedicated time: with 21 policy types covering spending, token whitelists, DeFi position limits, and network restrictions, configuring it properly is what separates a wallet that's safe to leave running overnight from one that isn't.&lt;/p&gt;

&lt;p&gt;Explore the full project at &lt;a href="https://github.com/waiaas/WAIaaS" rel="noopener noreferrer"&gt;https://github.com/waiaas/WAIaaS&lt;/a&gt; and the official site at &lt;a href="https://waiaas.ai" rel="noopener noreferrer"&gt;https://waiaas.ai&lt;/a&gt;. The codebase is open source, the Docker image is on GHCR, and the 684+ test files give you a reasonable level of confidence in what you're running on your own hardware.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>selfhosted</category>
      <category>web3</category>
      <category>devops</category>
    </item>
    <item>
      <title>7 Transaction Types in Claude Desktop: Complete MCP Transaction Reference</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Fri, 18 Sep 2026 17:04:38 +0000</pubDate>
      <link>https://dev.to/walletguy/7-transaction-types-in-claude-desktop-complete-mcp-transaction-reference-2ng2</link>
      <guid>https://dev.to/walletguy/7-transaction-types-in-claude-desktop-complete-mcp-transaction-reference-2ng2</guid>
      <description>&lt;h1&gt;
  
  
  7 Transaction Types in Claude Desktop: Complete MCP Transaction Reference
&lt;/h1&gt;

&lt;p&gt;MCP developers who want to give Claude onchain capabilities have a surprisingly complete toolkit available today — WAIaaS is an MCP server that exposes 45 tools to Claude Desktop, covering every transaction type your agent might need. Add one JSON block to your &lt;code&gt;claude_desktop_config.json&lt;/code&gt;, and your Claude agent goes from conversational to onchain in minutes. This post walks through all 7 supported transaction types, shows you exactly what Claude calls under the hood, and gets you running with a working config.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Transaction Type Coverage Matters
&lt;/h2&gt;

&lt;p&gt;When you're building an AI agent that touches real money, vague abstractions are dangerous. An agent that can "send stuff" isn't the same as an agent that understands the difference between a raw native transfer, a token approval, and an NFT move. Each of those operations carries different risk profiles, different policy rules, and different confirmation requirements.&lt;/p&gt;

&lt;p&gt;WAIaaS models this explicitly. The transaction schema uses a discriminated union of exactly 7 types: &lt;code&gt;Transfer&lt;/code&gt;, &lt;code&gt;TokenTransfer&lt;/code&gt;, &lt;code&gt;ContractCall&lt;/code&gt;, &lt;code&gt;Approve&lt;/code&gt;, &lt;code&gt;Batch&lt;/code&gt;, &lt;code&gt;NftTransfer&lt;/code&gt;, and &lt;code&gt;ContractDeploy&lt;/code&gt;. Claude doesn't need to guess what kind of transaction to construct — it picks the right shape, every time, because the MCP tool definitions enforce the schema.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 0: Get the MCP Server Running
&lt;/h2&gt;

&lt;p&gt;Before any of the transaction types below work, you need two things: a running WAIaaS daemon and a session token scoped to a wallet.&lt;/p&gt;

&lt;p&gt;The fastest path is the CLI quickstart:&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;code&gt;quickset&lt;/code&gt; creates your wallets, generates session tokens, and prints the exact JSON block to paste into Claude Desktop. If you want to register manually, the config looks like this:&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;Or use the auto-register shortcut:&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;That's it. Restart Claude Desktop, and you'll see the WAIaaS tools available in the tool panel. Now let's look at what Claude can actually do.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 7 Transaction Types
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Transfer (Native Token)
&lt;/h3&gt;

&lt;p&gt;The simplest type: send the chain's native token (SOL, ETH, etc.) from the agent's wallet to an address.&lt;/p&gt;

&lt;p&gt;When you say "Send 0.1 SOL to this address," Claude calls the &lt;code&gt;send_token&lt;/code&gt; MCP tool, which maps to this REST call under the hood:&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;The transaction goes through the 7-stage pipeline: validate → auth → policy → wait → execute → confirm. If your &lt;code&gt;SPENDING_LIMIT&lt;/code&gt; policy has a &lt;code&gt;notify_max_usd&lt;/code&gt; threshold, you'll get a notification but the transaction still executes. If it hits &lt;code&gt;delay_max_usd&lt;/code&gt;, it queues for the delay window. Above that, it requires your explicit approval.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. TokenTransfer (ERC-20 / SPL Token)
&lt;/h3&gt;

&lt;p&gt;When Claude needs to send a specific token — USDC, WETH, an SPL token — it uses &lt;code&gt;TokenTransfer&lt;/code&gt;. The type distinction matters for policy: &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt; policy is evaluated against the token address here, and it's default-deny. If you haven't whitelisted the token, the transaction is blocked.&lt;/p&gt;

&lt;p&gt;This is why the policy setup matters before you let an agent loose. A minimal USDC whitelist on Solana 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": "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;Without this, Claude trying to move USDC hits &lt;code&gt;POLICY_DENIED&lt;/code&gt; and gets back a structured error it can explain to you.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. ContractCall (Arbitrary Smart Contract Interaction)
&lt;/h3&gt;

&lt;p&gt;This is the workhorse for DeFi. When Claude calls the &lt;code&gt;execute_action&lt;/code&gt; MCP tool for a Jupiter swap, an Aave deposit, or any of the 15 integrated DeFi protocols, it ultimately resolves to a &lt;code&gt;ContractCall&lt;/code&gt; transaction type.&lt;/p&gt;

&lt;p&gt;The REST layer for a Jupiter swap 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/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;&lt;code&gt;ContractCall&lt;/code&gt; transactions are governed by the &lt;code&gt;CONTRACT_WHITELIST&lt;/code&gt; policy — also default-deny. You need to explicitly whitelist Jupiter's router address before Claude can swap. This is intentional: an agent that can call arbitrary contracts without restriction is a significant security surface.&lt;/p&gt;

&lt;p&gt;The 15 DeFi protocol providers available via &lt;code&gt;action-provider&lt;/code&gt; MCP tool include: aave-v3, across, dcent-swap, drift, erc8004, hyperliquid, jito-staking, jupiter-swap, kamino, lido-staking, lifi, pendle, polymarket, xrpl-dex, and zerox-swap.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Approve (Token Approvals)
&lt;/h3&gt;

&lt;p&gt;Token approvals are a distinct transaction type in WAIaaS, not just another &lt;code&gt;ContractCall&lt;/code&gt;. This matters because approvals have their own policy types: &lt;code&gt;APPROVED_SPENDERS&lt;/code&gt; (default-deny whitelist of addresses that can receive approvals), &lt;code&gt;APPROVE_AMOUNT_LIMIT&lt;/code&gt; (blocks unlimited approvals), and &lt;code&gt;APPROVE_TIER_OVERRIDE&lt;/code&gt; (forces a specific security tier for all approval transactions regardless of amount).&lt;/p&gt;

&lt;p&gt;If Claude is preparing a DeFi position that requires approving a DEX router to spend your USDC, it will first construct an &lt;code&gt;Approve&lt;/code&gt; transaction. Without &lt;code&gt;APPROVED_SPENDERS&lt;/code&gt; configured, this is blocked. This prevents a class of attacks where an agent could be tricked into approving a malicious contract.&lt;/p&gt;

&lt;p&gt;Before running an agent that interacts with DeFi, add:&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": "APPROVED_SPENDERS",
    "rules": {
      "spenders": [{"address": "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4", "name": "Jupiter", "maxAmount": "1000000000"}]
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Batch (Atomic Multi-Step Transactions)
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Batch&lt;/code&gt; lets Claude bundle multiple operations into a single atomic transaction. This is useful for approve+swap in one step, or multi-token portfolio rebalancing. The &lt;code&gt;send_batch&lt;/code&gt; MCP tool maps to this type.&lt;/p&gt;

&lt;p&gt;On EVM chains with ERC-4337 Account Abstraction enabled, batches execute as a single UserOperation — one signature, one gas payment, atomic success or failure. On Solana, batch transactions use native instruction bundling.&lt;/p&gt;

&lt;p&gt;Before executing a batch, Claude 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 &lt;code&gt;simulate-transaction&lt;/code&gt; MCP tool and the &lt;code&gt;dryRun&lt;/code&gt; flag let Claude reason about what a transaction will do before committing. For batch operations especially, this is worth building into your agent's workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. NftTransfer
&lt;/h3&gt;

&lt;p&gt;NFT moves are a distinct type with their own resolution path. WAIaaS supports ERC-721 and ERC-1155 on EVM chains and Metaplex NFTs on Solana, with metadata caching so Claude can tell you what you're actually moving before it moves it.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;transfer_nft&lt;/code&gt; and &lt;code&gt;list_nfts&lt;/code&gt; MCP tools let Claude inventory your NFTs and execute transfers. From Claude Desktop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User: "Show me my NFTs"
→ Claude calls list_nfts → returns collection with metadata

User: "Transfer the Solana Monkey #4231 to this address"
→ Claude calls transfer_nft with the mint address and recipient
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;get_nft_metadata&lt;/code&gt; tool resolves metadata before the transfer, so Claude can confirm with you: "This will transfer Solana Monkey #4231 (floor price: X SOL) to address Y. Confirm?" — before the &lt;code&gt;NftTransfer&lt;/code&gt; transaction hits the pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. ContractDeploy
&lt;/h3&gt;

&lt;p&gt;The seventh type is &lt;code&gt;ContractDeploy&lt;/code&gt; — deploying a new smart contract from the agent's wallet. This is the highest-risk transaction type by nature and will almost always land in the &lt;code&gt;APPROVAL&lt;/code&gt; security tier under a &lt;code&gt;SPENDING_LIMIT&lt;/code&gt; policy given the gas costs involved.&lt;/p&gt;

&lt;p&gt;This type is available for agents building onchain systems programmatically — deploying escrow contracts, token contracts, or agent-owned infrastructure. It follows the same pipeline as every other type: validate → auth → policy → wait → execute → confirm.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Tiers in Practice
&lt;/h2&gt;

&lt;p&gt;Every one of these 7 types flows through the policy engine with 4 possible outcomes: &lt;code&gt;INSTANT&lt;/code&gt; (execute now, no notification), &lt;code&gt;NOTIFY&lt;/code&gt; (execute now, notify you), &lt;code&gt;DELAY&lt;/code&gt; (queue it, cancellable window), or &lt;code&gt;APPROVAL&lt;/code&gt; (you must sign off via WalletConnect, Telegram, or Push).&lt;/p&gt;

&lt;p&gt;A realistic policy setup for an agent you trust with small amounts but want oversight on larger moves:&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: Claude acts immediately. $100-$500: acts immediately, you get notified. $500-$2000: queues for 15 minutes, you can cancel. Over $2000: stops and waits for your wallet signature.&lt;/p&gt;

&lt;p&gt;When Claude's transaction is blocked by policy, it receives a structured error it can explain:&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;Claude can surface this to you as "This transfer exceeds your daily limit — do you want to approve it manually?" rather than silently failing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start: From Zero to All 7 Types in 5 Steps
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Install the CLI and 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;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;2. Create wallets and sessions:&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;&lt;strong&gt;3. Paste the printed config into Claude Desktop's config file&lt;/strong&gt; (or run &lt;code&gt;waiaas mcp setup --all&lt;/code&gt; to auto-register).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Set up your policies&lt;/strong&gt; (at minimum: &lt;code&gt;SPENDING_LIMIT&lt;/code&gt;, &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt;, &lt;code&gt;CONTRACT_WHITELIST&lt;/code&gt;, &lt;code&gt;APPROVED_SPENDERS&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Open Claude Desktop and try:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"What's my wallet balance?"
"Swap 0.01 SOL for USDC on Jupiter"
"Show my DeFi positions"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude will call &lt;code&gt;get_balance&lt;/code&gt;, then &lt;code&gt;execute_action&lt;/code&gt; with the jupiter-swap provider, then &lt;code&gt;get_defi_positions&lt;/code&gt; — all from natural language, all going through your policy rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multi-Wallet Setup
&lt;/h2&gt;

&lt;p&gt;If you're running separate agents for different strategies, you can run multiple MCP server instances, each scoped to a different wallet and session token:&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 wallet gets its own policy set, its own session limits, and its own spending controls. Claude Desktop will show both as separate tool namespaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploring the OpenAPI Reference
&lt;/h2&gt;

&lt;p&gt;The 39 REST API route modules behind all of this are documented at &lt;code&gt;/reference&lt;/code&gt; on your running daemon:&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;# View the full OpenAPI spec&lt;/span&gt;
curl http://127.0.0.1:3100/doc &lt;span class="nt"&gt;-o&lt;/span&gt; openapi.json

&lt;span class="c"&gt;# Open the interactive Scalar reference UI&lt;/span&gt;
open http://127.0.0.1:3100/reference
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every MCP tool has a corresponding REST endpoint — useful if you're debugging what Claude is actually calling, or building your own integration alongside the MCP server.&lt;/p&gt;

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

&lt;p&gt;If you're already using Claude Desktop and want to go further, the next step is setting up incoming transaction monitoring so your agent gets notified of deposits, and configuring WalletConnect so you can approve high-value transactions from your phone. The full 45-tool MCP reference and all policy types are documented in the WAIaaS repo.&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; — self-host, browse the source, open issues&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; — docs, guides, and release notes&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>web3</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>20 CLI Commands for Complete Self-Hosted Wallet Management: From Setup to Backup</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Fri, 18 Sep 2026 11:27:47 +0000</pubDate>
      <link>https://dev.to/walletguy/20-cli-commands-for-complete-self-hosted-wallet-management-from-setup-to-backup-168g</link>
      <guid>https://dev.to/walletguy/20-cli-commands-for-complete-self-hosted-wallet-management-from-setup-to-backup-168g</guid>
      <description>&lt;h1&gt;
  
  
  20 CLI Commands for Complete Self-Hosted Wallet Management: From Setup to Backup
&lt;/h1&gt;

&lt;p&gt;Self-hosted wallet management for AI agents means your private keys never leave your server — and WAIaaS gives you a full CLI with 20 commands to set up, operate, and back up your entire wallet infrastructure without trusting a single third party. If you've ever run your own email server, your own VPN, or your own Nextcloud instance, you already understand the philosophy: ownership is worth the extra ten minutes of setup.&lt;/p&gt;

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

&lt;p&gt;Here's the uncomfortable question: would you hand your private keys to a hosted service you don't control, just because it's convenient? For personal wallets, most people already know the answer. For AI agent wallets, the question is even sharper. An agent wallet isn't just holding funds — it's actively executing transactions, interacting with DeFi protocols, and potentially moving significant value on your behalf.&lt;/p&gt;

&lt;p&gt;Hosted wallet services come with trade-offs that are easy to overlook: rate limits that can stop your agent mid-task, API terms that can change overnight, custody arrangements where someone else technically controls your keys, and privacy implications around transaction metadata. Self-hosting eliminates all of that. WAIaaS runs entirely on your hardware, behind your firewall, with your keys in your encrypted data directory. No phone-home, no usage telemetry you didn't consent to, no third-party rate limits.&lt;/p&gt;

&lt;p&gt;The CLI is how you manage all of it from the terminal — which is exactly where self-hosters want to be.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 20 Commands, Organized by What You're Actually Doing
&lt;/h2&gt;

&lt;p&gt;WAIaaS ships a CLI with exactly 20 commands (fact CLI-01). Rather than dumping them as a flat list, here's how they map to the actual lifecycle of running your own wallet infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting Started: &lt;code&gt;init&lt;/code&gt;, &lt;code&gt;start&lt;/code&gt;, &lt;code&gt;stop&lt;/code&gt;, &lt;code&gt;status&lt;/code&gt;, &lt;code&gt;quickstart&lt;/code&gt;, &lt;code&gt;quickset&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Everything begins with &lt;code&gt;init&lt;/code&gt;. This creates your data directory and &lt;code&gt;config.toml&lt;/code&gt;. It's the &lt;code&gt;git init&lt;/code&gt; of your wallet infrastructure.&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.toml&lt;/span&gt;
waiaas start                   &lt;span class="c"&gt;# Start daemon (sets master password on first run)&lt;/span&gt;
waiaas quickset &lt;span class="nt"&gt;--mode&lt;/span&gt; mainnet &lt;span class="c"&gt;# Create wallets + MCP sessions in one step&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;quickstart&lt;/code&gt; gets you running with sensible defaults in the least number of steps. &lt;code&gt;quickset&lt;/code&gt; is slightly more deliberate — it creates wallets and MCP sessions for you but lets you specify a mode. For self-hosters who want to automate first-run provisioning (say, in a Docker entrypoint or an Ansible playbook), there's an auto-provision flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;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;That pattern — auto-provision for first boot, &lt;code&gt;set-master&lt;/code&gt; to harden later — is exactly what you want for unattended server deployments. The &lt;code&gt;recovery.key&lt;/code&gt; file holds your auto-generated master password. Lock it down, back it up, then replace it with something you've chosen yourself once you're ready.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;stop&lt;/code&gt; and &lt;code&gt;status&lt;/code&gt; are exactly what they sound like. &lt;code&gt;status&lt;/code&gt; is particularly useful for health-checking from a monitoring script or a cron job.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wallet Operations: &lt;code&gt;wallet create&lt;/code&gt;, &lt;code&gt;wallet info&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Once your daemon is running, you create wallets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;waiaas wallet create   &lt;span class="c"&gt;# Interactive wallet creation&lt;/span&gt;
waiaas wallet info     &lt;span class="c"&gt;# Show wallet details, address, chain&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Under the hood, wallet creation is also exposed via the REST API if you want to script 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/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;The CLI wraps this in an interactive flow, which is friendlier for manual setup. For automation, the API is the right tool. Both paths lead to the same place: a wallet whose keys live in your encrypted local data directory, on hardware you control.&lt;/p&gt;

&lt;p&gt;WAIaaS supports 2 chain types (EVM and Solana) across 18 networks (fact NET-01). That covers the chains where most real AI agent activity happens today.&lt;/p&gt;

&lt;h3&gt;
  
  
  Session Management: &lt;code&gt;session prompt&lt;/code&gt;, &lt;code&gt;set-master&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Sessions are how AI agents authenticate. You create a session token, hand it to your agent (via environment variable, MCP config, or SDK constructor), and the agent uses it to sign transactions, check balances, and execute DeFi actions — all scoped to a specific wallet.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;session prompt&lt;/code&gt; generates a session token interactively. &lt;code&gt;set-master&lt;/code&gt; lets you change or harden your master password — the root credential that protects everything else.&lt;/p&gt;

&lt;p&gt;WAIaaS uses three distinct auth layers (fact SEC-02):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;masterAuth&lt;/strong&gt; (Argon2id) — system administrator operations like wallet creation and policy management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ownerAuth&lt;/strong&gt; (SIWS/SIWE) — fund owner approval for sensitive transactions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;sessionAuth&lt;/strong&gt; (JWT HS256) — day-to-day agent operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This separation matters for self-hosters. Your master password stays on the server. Your session tokens are scoped and can be rotated without touching your keys. Your owner auth is a signature from a wallet you control independently — it's the kill switch that doesn't depend on the server at all.&lt;/p&gt;

&lt;h3&gt;
  
  
  Owner Control: &lt;code&gt;owner connect&lt;/code&gt;, &lt;code&gt;owner disconnect&lt;/code&gt;, &lt;code&gt;owner status&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The owner commands hook into WalletConnect (fact FEAT-WC), letting you connect your personal wallet as the fund owner. This is how you approve transactions that exceed your policy thresholds — the agent submits a transaction, the policy engine routes it to APPROVAL tier, and you get a notification to your connected wallet app.&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 connect    &lt;span class="c"&gt;# Connect owner wallet via WalletConnect&lt;/span&gt;
waiaas owner status     &lt;span class="c"&gt;# Check connected owner wallet&lt;/span&gt;
waiaas owner disconnect &lt;span class="c"&gt;# Disconnect owner wallet&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For self-hosters, this is the human-in-the-loop bridge. Your AI agent can operate autonomously within the spending limits and whitelists you've defined, but anything that exceeds those limits requires your explicit cryptographic approval. No third party can approve transactions on your behalf — that's the point.&lt;/p&gt;

&lt;h3&gt;
  
  
  Notifications: &lt;code&gt;notification setup&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;waiaas notification setup   &lt;span class="c"&gt;# Configure notification channels&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WAIaaS supports multiple signing channels including push relay, Telegram, and wallet notification channels (fact SIGN-01). &lt;code&gt;notification setup&lt;/code&gt; walks you through connecting one of them. Self-hosters who run their own Telegram bots or push notification infrastructure can route alerts through those.&lt;/p&gt;

&lt;h3&gt;
  
  
  MCP Integration: &lt;code&gt;mcp setup&lt;/code&gt;
&lt;/h3&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;This is the command that takes your self-hosted daemon and wires it into AI agent frameworks like Claude Desktop. It writes the MCP server configuration JSON that Claude (or any MCP-compatible client) reads at startup. The &lt;code&gt;--all&lt;/code&gt; flag registers every wallet you've created as a separate MCP server entry.&lt;/p&gt;

&lt;p&gt;The MCP package (&lt;code&gt;@waiaas/mcp&lt;/code&gt;) exposes 45 tools (fact MCP-01) covering wallet queries, transactions, DeFi actions, NFT operations, and x402 payment handling. After running &lt;code&gt;mcp setup&lt;/code&gt;, your AI agent can check balances, swap tokens, query DeFi positions, and more — all authenticated through the session token scoped to the wallet you've configured.&lt;/p&gt;

&lt;p&gt;A typical multi-wallet MCP config looks like this:&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;The daemon is running locally, the base URL points to &lt;code&gt;127.0.0.1:3100&lt;/code&gt;, and no traffic goes to an external service. That's self-hosted MCP wallet infrastructure in the most literal sense.&lt;/p&gt;

&lt;h3&gt;
  
  
  Backup and Restore: &lt;code&gt;backup create&lt;/code&gt;, &lt;code&gt;backup inspect&lt;/code&gt;, &lt;code&gt;backup list&lt;/code&gt;, &lt;code&gt;restore&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This is where self-hosting gets serious. If you're running your own infrastructure, you're responsible for your own backups. WAIaaS gives you four commands to manage this properly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;waiaas backup create   &lt;span class="c"&gt;# Create an encrypted backup of wallet data&lt;/span&gt;
waiaas backup list     &lt;span class="c"&gt;# List available backups&lt;/span&gt;
waiaas backup inspect  &lt;span class="c"&gt;# Inspect a specific backup file&lt;/span&gt;
waiaas restore         &lt;span class="c"&gt;# Restore from a backup&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;backup create&lt;/code&gt; command should be part of your regular cron schedule. Backup to an encrypted external drive, an S3-compatible bucket you control (MinIO on your NAS works perfectly), or an off-site server you manage. &lt;code&gt;backup inspect&lt;/code&gt; lets you verify a backup before you need it — not after. &lt;code&gt;restore&lt;/code&gt; gets you back to a known-good state if your server dies.&lt;/p&gt;

&lt;p&gt;This is the self-hosted responsibility that hosted services hide from you. It's also the self-hosted superpower: you have the backup, on your hardware, in your custody. Nobody can lose it for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Updates: &lt;code&gt;update&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;waiaas update   &lt;span class="c"&gt;# Update the WAIaaS daemon to the latest version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're running via Docker (more on that below), Watchtower can handle this automatically. If you're running the CLI-managed daemon directly, &lt;code&gt;update&lt;/code&gt; is your command for pulling the latest version.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running It All in Docker
&lt;/h2&gt;

&lt;p&gt;For homelab setups, Docker is often the cleaner path. WAIaaS ships a production-ready Docker image (fact DOCKER-01):&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;# Clone and start — that's it&lt;/span&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 default port binding is &lt;code&gt;127.0.0.1:3100:3100&lt;/code&gt; (fact DOCKER-02) — localhost only, not exposed to the network by default. That's a sensible security default for a service that manages private keys.&lt;/p&gt;

&lt;p&gt;For a single-container start with auto-provisioning:&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;For production, use Docker Secrets instead of environment variables for your master password (fact DOCKER-03):&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 secrets overlay (&lt;code&gt;docker-compose.secrets.yml&lt;/code&gt;, fact DOCKER-04) keeps your credentials out of environment variables and process lists. Healthcheck is built in, the container runs as a non-root user (UID 1001, fact FEAT-DOCKER), and you can wire up Watchtower for automatic updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Policy Layer: Why Your Self-Hosted Agent Isn't Just a Hot Wallet
&lt;/h2&gt;

&lt;p&gt;Running your own wallet infrastructure doesn't mean running without guardrails. WAIaaS includes a policy engine with 21 policy types and 4 security tiers (fact POLICY-01, POLICY-02).&lt;/p&gt;

&lt;p&gt;The most important thing to understand about the policy engine is that it's &lt;strong&gt;default-deny&lt;/strong&gt; (fact SEC-03). If you haven't explicitly whitelisted a token or contract, transactions involving it are blocked. This is the right default for an autonomous agent — restrict first, expand as needed.&lt;/p&gt;

&lt;p&gt;A basic spending limit 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;Under \$100: executes immediately. \$100–\$500: executes and notifies you. \$500–\$2,000: queues for 15 minutes (cancellable). Over \$2,000: requires your explicit approval. You set these thresholds. They live on your server. No hosted service is enforcing them on your behalf — you are.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start: Five Steps to a Running Self-Hosted Setup
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install the CLI&lt;/strong&gt;: &lt;code&gt;npm install -g @waiaas/cli&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Initialize and start&lt;/strong&gt;: &lt;code&gt;waiaas init --auto-provision &amp;amp;&amp;amp; waiaas start&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create wallets and sessions&lt;/strong&gt;: &lt;code&gt;waiaas quickset --mode mainnet&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wire up MCP&lt;/strong&gt;: &lt;code&gt;waiaas mcp setup --all&lt;/code&gt; → paste config into Claude Desktop&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schedule backups&lt;/strong&gt;: &lt;code&gt;waiaas backup create&lt;/code&gt; in a daily cron job&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's the full path from zero to a running self-hosted AI agent wallet, with MCP integration and backups in place.&lt;/p&gt;

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

&lt;p&gt;The CLI gives you the operational layer — starting, stopping, creating wallets, managing sessions, and keeping backups. The REST API (39 route modules, fact API-01) gives you the programmable layer for integrating WAIaaS into your own tooling and agents. Between the two, you have everything you need to run production wallet infrastructure on hardware you own.&lt;/p&gt;

&lt;p&gt;Start with the GitHub repository 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 the full list of supported chains and DeFi protocols. Your keys, your server, your rules.&lt;/p&gt;

</description>
      <category>selfhosted</category>
      <category>opensource</category>
      <category>tutorial</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Trustless AI Commerce: How ERC-8004 Reputation Enables Autonomous Economic Agents</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Thu, 17 Sep 2026 17:36:57 +0000</pubDate>
      <link>https://dev.to/walletguy/trustless-ai-commerce-how-erc-8004-reputation-enables-autonomous-economic-agents-3gkp</link>
      <guid>https://dev.to/walletguy/trustless-ai-commerce-how-erc-8004-reputation-enables-autonomous-economic-agents-3gkp</guid>
      <description>&lt;h1&gt;
  
  
  Trustless AI Commerce: How ERC-8004 Reputation Enables Autonomous Economic Agents
&lt;/h1&gt;

&lt;p&gt;AI agents will need to pay for compute, data, and API calls — and right now, the infrastructure to let them do that autonomously barely exists. We talk endlessly about agents that can reason, plan, and act, but the moment one of those agents needs to spend money, we fall back to humans holding the keys. That gap between "autonomous agent" and "agent that can actually participate in economic activity" is exactly what trustless wallet infrastructure is built to close.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem Nobody Talks About at the AGI Conference
&lt;/h2&gt;

&lt;p&gt;Here's a scenario that plays out constantly in production AI systems today: an agent needs to call a paid API, execute a trade, or pay for inference compute. So what happens? A human pre-loads a balance into some custodied account, the agent draws from it, and a human periodically reviews the spending.&lt;/p&gt;

&lt;p&gt;That's not autonomous economic activity. That's a very complicated expense account.&lt;/p&gt;

&lt;p&gt;The deeper issue is trust — specifically, the lack of a mechanism for &lt;em&gt;counterparties&lt;/em&gt; to verify that an agent is what it claims to be, that it will honor its obligations, and that it has the authority to spend the funds it's trying to spend. In human commerce, we have credit scores, corporate registration, banking relationships, and legal liability. For AI agents, we have... vibes.&lt;/p&gt;

&lt;p&gt;ERC-8004 is an attempt to change that. It's a standard for onchain agent reputation and validation — a way to assign verifiable identity and track record to an autonomous agent so that other parties in a transaction can make informed decisions about whether to transact with it. And WAIaaS, an open-source self-hosted Wallet-as-a-Service for AI agents, ships with ERC-8004 support built in.&lt;/p&gt;

&lt;p&gt;This isn't vaporware. It exists today. Let's talk about what that actually means.&lt;/p&gt;

&lt;h2&gt;
  
  
  What ERC-8004 Actually Does
&lt;/h2&gt;

&lt;p&gt;The concept is straightforward even if the implementation is not. An AI agent — or rather, the wallet infrastructure backing that agent — registers an onchain identity. Over time, as the agent completes transactions, fulfills obligations, and operates within defined parameters, that identity accumulates a reputation score. Other parties can query that reputation before deciding whether to transact.&lt;/p&gt;

&lt;p&gt;Think of it like a credit score for machines, except it's transparent, onchain, and queryable by any counterparty without a centralized bureau acting as gatekeeper.&lt;/p&gt;

&lt;p&gt;WAIaaS exposes this through two MCP tools that Claude and other AI frameworks can call directly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;erc8004-get-agent-info&lt;/code&gt; — retrieve the registered identity and metadata for an agent&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;erc8004-get-reputation&lt;/code&gt; — query the current reputation score&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;erc8004-get-validation-status&lt;/code&gt; — check whether an agent passes validation thresholds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The policy engine also has a corresponding &lt;code&gt;REPUTATION_THRESHOLD&lt;/code&gt; policy type. This means you can configure a wallet so that it will only transact with counterparties whose onchain reputation meets a minimum bar. Default-deny applies here too: if the counterparty doesn't have a verifiable reputation, the transaction doesn't go through.&lt;/p&gt;

&lt;p&gt;This is the foundation of trustless AI commerce — not a pinky promise that an agent is well-behaved, but a cryptographically verifiable track record that any party in the system can inspect.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Infrastructure Layer: Wallets for Autonomous Agents
&lt;/h2&gt;

&lt;p&gt;Before we get further into reputation, it's worth being precise about what "autonomous wallet infrastructure" means in practice, because it's doing a lot of work.&lt;/p&gt;

&lt;p&gt;WAIaaS is a 15-package monorepo that you self-host. The core component is a daemon that exposes 39 REST API routes and communicates with AI agents through 45 MCP tools. It supports 18 networks across EVM and Solana. It has a 7-stage transaction pipeline. It integrates with 15 DeFi protocols.&lt;/p&gt;

&lt;p&gt;None of that is relevant if the mental model is wrong. So here's the mental model:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There are three principals in the system, and they have different levels of trust.&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The owner&lt;/strong&gt; — the human (or organization) that funds the wallet. They authenticate with &lt;code&gt;ownerAuth&lt;/code&gt; using SIWE or SIWS signatures. They set policy, approve high-value transactions, and hold the kill switch.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The master&lt;/strong&gt; — the system administrator role that creates wallets and sessions. Authenticates with &lt;code&gt;masterAuth&lt;/code&gt; using Argon2id. This is typically infrastructure automation, not a human sitting at a keyboard.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The session&lt;/strong&gt; — the AI agent. It gets a JWT that scopes what it can do. It authenticates with &lt;code&gt;sessionAuth&lt;/code&gt;. It operates entirely within the policy envelope the owner and master have defined.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The agent never holds the private key. It holds a session token that lets it &lt;em&gt;request&lt;/em&gt; transactions. The daemon handles signing. This is the critical architectural choice that makes autonomous operation safe: the agent has economic agency (it can initiate spending decisions) without having custody (it can't drain the wallet by bypassing controls).&lt;/p&gt;

&lt;h2&gt;
  
  
  A Policy Engine That Actually Enforces Rules
&lt;/h2&gt;

&lt;p&gt;The policy engine is where the rubber meets the road on autonomous operation. WAIaaS has 21 policy types and 4 security tiers: INSTANT, NOTIFY, DELAY, and APPROVAL.&lt;/p&gt;

&lt;p&gt;Here's what a spending limit 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;That's not pseudocode. That's the actual API call. A transaction under $100 executes immediately. Between $100 and $500, it executes immediately but the owner gets notified. Between $500 and $2,000, it gets queued for 15 minutes — enough time for the owner to cancel if something looks wrong. Over $2,000, it requires explicit owner approval through WalletConnect, Telegram, or a push notification.&lt;/p&gt;

&lt;p&gt;The REPUTATION_THRESHOLD policy type fits into the same framework. You set a minimum reputation score, and the policy engine enforces it at transaction time. If the counterparty doesn't meet the threshold, the transaction is denied with a &lt;code&gt;POLICY_DENIED&lt;/code&gt; error — the same structured error format used throughout the system:&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;Other policy types relevant to autonomous agent operation include &lt;code&gt;CONTRACT_WHITELIST&lt;/code&gt; (the agent can only interact with pre-approved contracts), &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt; (default-deny token whitelist), &lt;code&gt;X402_ALLOWED_DOMAINS&lt;/code&gt; (more on this in a moment), and &lt;code&gt;VENUE_WHITELIST&lt;/code&gt; (allowed trading venues).&lt;/p&gt;

&lt;p&gt;Default-deny is not a configuration option. It's the baseline. An agent operating without explicit allowlists set cannot move tokens to arbitrary addresses or call arbitrary contracts. You grant permissions explicitly; you don't restrict from an open default.&lt;/p&gt;

&lt;h2&gt;
  
  
  x402: The HTTP Payment Layer for Machine Commerce
&lt;/h2&gt;

&lt;p&gt;ERC-8004 reputation handles identity and trust. But how does an agent actually &lt;em&gt;pay&lt;/em&gt; for things at the HTTP layer?&lt;/p&gt;

&lt;p&gt;The x402 protocol is a proposed extension to HTTP where a server responds with HTTP 402 (Payment Required) and an attached payment claim. The client — in this case, an AI agent — pays the claim and resubmits the request. The whole thing happens in-band with the HTTP request, without any human in the loop.&lt;/p&gt;

&lt;p&gt;WAIaaS has native x402 support. The MCP tool is called &lt;code&gt;x402-fetch&lt;/code&gt;, and the TypeScript SDK exposes it as &lt;code&gt;client.x402Fetch()&lt;/code&gt;. The policy engine has &lt;code&gt;X402_ALLOWED_DOMAINS&lt;/code&gt; so you can restrict which domains the agent is permitted to pay automatically.&lt;/p&gt;

&lt;p&gt;The practical implication: an AI agent can call a paid API, receive a 402 response, pay it from its wallet, and complete the request — all autonomously, all within the spending limits and domain restrictions you've configured. No human clicks "approve payment." The policy envelope does that work.&lt;/p&gt;

&lt;p&gt;This is what machine-to-machine commerce actually looks like. Not a billing portal. Not a human reviewing invoices. An agent with a wallet, a reputation, and a set of rules it operates within.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Something Running
&lt;/h2&gt;

&lt;p&gt;If you want to see this in practice rather than read about it, here's the minimal path:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 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;The daemon binds to &lt;code&gt;127.0.0.1:3100&lt;/code&gt; by default.&lt;/p&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;&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 your 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;&lt;strong&gt;Step 3: Set a spending policy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before your agent touches real funds, set a spending limit. The example from earlier — $100 instant, $500 notify, $2,000 delay with 15-minute queue, $5,000 daily cap — is a reasonable starting point for a trading agent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Connect to Claude via MCP&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="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;Or use the CLI shortcut:&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 mcp setup &lt;span class="nt"&gt;--all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From there, Claude has access to 45 MCP tools covering wallet operations, transactions, DeFi positions, NFTs, and x402 payments. It can check balances, execute swaps on Jupiter, query DeFi positions across 15 integrated protocols, and pay for API calls via x402 — all within the policy constraints you've defined.&lt;/p&gt;

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

&lt;p&gt;The reason this matters beyond the technical specifics is that we're at an inflection point. The question of whether AI agents will participate in economic activity is largely settled — of course they will. The open question is whether that participation will be trustless and transparent, or whether it will require humans as intermediaries at every step.&lt;/p&gt;

&lt;p&gt;Trustless doesn't mean unsupervised. The policy engine, the security tiers, the owner approval flow, the WalletConnect integration for human-in-the-loop signing — all of that exists precisely because autonomous operation needs guard rails. The goal isn't to remove humans from the picture. It's to make human oversight &lt;em&gt;scalable&lt;/em&gt; — to let an owner set policy once and then have the system enforce it consistently across thousands of agent transactions, surfacing only the exceptions that genuinely require human judgment.&lt;/p&gt;

&lt;p&gt;ERC-8004 reputation is one piece of that puzzle. It gives agents verifiable identity that accumulates over time. Combined with the x402 payment layer, the policy engine, and the session-based auth model, it starts to look like the infrastructure layer that autonomous economic agents actually need.&lt;/p&gt;

&lt;p&gt;That infrastructure exists today. It's open-source. You can run it on your own hardware. The 684+ test files suggest the team takes correctness seriously. The interactive API reference at &lt;code&gt;/reference&lt;/code&gt; means you don't have to guess at the API shape.&lt;/p&gt;

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

&lt;p&gt;If you're building agents that need economic autonomy, the place to start is the &lt;a href="https://github.com/waiaas/WAIaaS" rel="noopener noreferrer"&gt;WAIaaS GitHub repository&lt;/a&gt; — the README has the quickstart path, and the codebase is the authoritative source on what's actually implemented. For a broader overview of capabilities and deployment options, &lt;a href="https://waiaas.ai" rel="noopener noreferrer"&gt;waiaas.ai&lt;/a&gt; has the documentation. The most productive next step is probably standing up a local instance with Docker Compose, creating a test wallet, and seeing what the policy engine actually enforces — reading about default-deny is less convincing than watching a transaction get blocked because you forgot to configure &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>web3</category>
    </item>
    <item>
      <title>Self-Hosted Crypto Infrastructure Monitoring: Docker Healthcheck + Service Recovery</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Thu, 17 Sep 2026 11:52:03 +0000</pubDate>
      <link>https://dev.to/walletguy/self-hosted-crypto-infrastructure-monitoring-docker-healthcheck-service-recovery-3p9o</link>
      <guid>https://dev.to/walletguy/self-hosted-crypto-infrastructure-monitoring-docker-healthcheck-service-recovery-3p9o</guid>
      <description>&lt;h1&gt;
  
  
  Self-Hosted Crypto Infrastructure Monitoring: Docker Healthcheck + Service Recovery
&lt;/h1&gt;

&lt;p&gt;Running your own self-hosted crypto infrastructure means you're the one accountable when something goes wrong at 2 AM — no support ticket, no status page to refresh, just you and your logs. If your AI agent's wallet daemon goes down mid-trade or during an automated DeFi rebalance, you want to know immediately and recover fast. This post walks through how WAIaaS is built for exactly that scenario: a self-hosted wallet service you can monitor, heal, and operate with full sovereignty over your keys and your server.&lt;/p&gt;

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

&lt;p&gt;There's a philosophical question hiding inside every "just use the hosted API" pitch: who actually controls the keys?&lt;/p&gt;

&lt;p&gt;When your AI agent executes a token swap, approves a spend, or pays for an API call via the x402 protocol, it's signing transactions. That signing requires private key material. If a third-party service holds those keys, you've introduced custody risk, rate limit risk, and — critically for privacy-conscious operators — a full transaction history that lives on someone else's server.&lt;/p&gt;

&lt;p&gt;The alternative is running your own wallet infrastructure. The tradeoff is real: you own the operational burden. But with modern Docker tooling, that burden is much lower than it used to be. WAIaaS ships as a self-contained Docker image with healthchecks, secret management, and a recovery model baked in. The goal of this post is to show you how those pieces fit together so your self-hosted setup stays online and recovers gracefully when it doesn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  What WAIaaS Ships With, Out of the Box
&lt;/h2&gt;

&lt;p&gt;WAIaaS is a 15-package monorepo that deploys as two Docker images: the main daemon and a push-relay service for notifications. The daemon is the one you'll spend most of your time thinking about — it's the process that holds wallet state, processes transactions through a 7-stage pipeline, and serves a REST API across 39 route modules.&lt;/p&gt;

&lt;p&gt;For self-hosters, the relevant defaults are already sensible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Default port binding&lt;/strong&gt;: &lt;code&gt;127.0.0.1:3100:3100&lt;/code&gt; — localhost-only by default, so you're not accidentally exposing the API to the network&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-root process&lt;/strong&gt;: runs as UID 1001 inside the container&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in healthcheck&lt;/strong&gt; in the Docker Compose file&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-provision mode&lt;/strong&gt; for first-run password generation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker Secrets support&lt;/strong&gt; for production credential management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's the full Compose file WAIaaS ships with:&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 highlighting here for anyone running production homelab services:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;restart: unless-stopped&lt;/code&gt;&lt;/strong&gt; — Docker will automatically restart the container after crashes or host reboots. The exception is if you explicitly stop it with &lt;code&gt;docker compose down&lt;/code&gt;, which is the right behavior: you don't want Docker fighting you when you intentionally bring the service down for maintenance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Named volume (&lt;code&gt;waiaas-data&lt;/code&gt;)&lt;/strong&gt; — Wallet state, encrypted keys, and transaction history persist in a named volume independent of the container lifecycle. Running &lt;code&gt;docker compose down&lt;/code&gt; preserves your data. You'd need &lt;code&gt;docker compose down -v&lt;/code&gt; to actually delete it, which is a safe default that protects against accidental data loss.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Healthcheck with &lt;code&gt;start_period: 10s&lt;/code&gt;&lt;/strong&gt; — The daemon gets 10 seconds to initialize before Docker starts counting health failures. This prevents restart loops on slower hardware where startup takes a moment.&lt;/p&gt;

&lt;h2&gt;
  
  
  First-Run Setup: Auto-Provision and Recovery Keys
&lt;/h2&gt;

&lt;p&gt;The most friction in self-hosted services is usually the first run. WAIaaS solves this with auto-provision mode, which 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;This is the crypto equivalent of a router generating a random WiFi password on first boot — you get something secure immediately, and you can harden it later. The CLI workflow for this is:&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 &lt;code&gt;set-master&lt;/code&gt; step is important. Once you've rotated to a password you control and stored securely (a password manager, not a plaintext file), delete &lt;code&gt;recovery.key&lt;/code&gt;. The auto-provision key is a bootstrap mechanism, not a permanent credential.&lt;/p&gt;

&lt;h2&gt;
  
  
  Secrets Management for Production
&lt;/h2&gt;

&lt;p&gt;For anyone running this on a VPS or home server with more than one user account, environment variables in &lt;code&gt;.env&lt;/code&gt; files are a step up from hardcoding credentials, but Docker Secrets is the right answer for production.&lt;/p&gt;

&lt;p&gt;WAIaaS ships a &lt;code&gt;docker-compose.secrets.yml&lt;/code&gt; overlay specifically for 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 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 secrets overlay pattern means your actual credentials never appear in environment variables that show up in &lt;code&gt;docker inspect&lt;/code&gt; output or process listings. This matters if you're running on shared infrastructure or if you're security-conscious about what ends up in container metadata.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitoring: What to Watch
&lt;/h2&gt;

&lt;p&gt;The healthcheck gives Docker the signal it needs to restart unhealthy containers, but for actual observability you want more than "is the process alive." Here are the three things worth monitoring on a self-hosted WAIaaS instance:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Health Endpoint
&lt;/h3&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/health
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is what the Docker healthcheck pings. Wire this into whatever uptime monitoring you use — Uptime Kuma, Healthchecks.io, a simple cron that sends you a Telegram message. The point is that the daemon's liveness is externally observable without any special credentials.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Log Streaming
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose logs &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WAIaaS has configurable log levels via &lt;code&gt;WAIAAS_DAEMON_LOG_LEVEL&lt;/code&gt;. For normal operation, &lt;code&gt;info&lt;/code&gt; is fine. When you're debugging a transaction that got stuck in the pipeline, dropping to &lt;code&gt;debug&lt;/code&gt; gives you stage-by-stage visibility through the 7-stage transaction pipeline (validate → auth → policy → wait → execute → confirm).&lt;/p&gt;

&lt;p&gt;For persistent log storage, pipe to a file or use Docker's logging driver:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose logs &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /var/log/waiaas/daemon.log 2&amp;gt;&amp;amp;1 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Incoming Transaction Monitoring
&lt;/h3&gt;

&lt;p&gt;WAIaaS has built-in incoming transaction monitoring with real-time notifications for deposits. This means you don't need a separate indexer watching your wallet addresses — the daemon handles it. Pair this with the notification setup CLI command (&lt;code&gt;waiaas notification setup&lt;/code&gt;) and you'll get alerts when funds arrive, not just when your agent sends them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Service Recovery: What Happens When Things Go Wrong
&lt;/h2&gt;

&lt;p&gt;Let's walk through the failure scenarios you actually care about:&lt;/p&gt;

&lt;h3&gt;
  
  
  Container Crash
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;restart: unless-stopped&lt;/code&gt; handles this automatically. Docker detects the container exit, waits briefly, and restarts it. The named volume means wallet state is intact. The daemon reinitializes, the healthcheck passes, and your AI agent's next API call succeeds. You'll see the restart in &lt;code&gt;docker compose logs&lt;/code&gt; and in &lt;code&gt;docker ps&lt;/code&gt; output (the "Restarts" column).&lt;/p&gt;

&lt;h3&gt;
  
  
  Host Reboot
&lt;/h3&gt;

&lt;p&gt;Same story — Docker's restart policy fires on daemon startup. If you're on a system where Docker starts automatically (most Linux distros with &lt;code&gt;systemctl enable docker&lt;/code&gt;), WAIaaS comes back up without manual intervention.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stuck Transaction in the Pipeline
&lt;/h3&gt;

&lt;p&gt;This is the more interesting failure mode. A transaction can get stuck in the DELAY or APPROVAL tier if it's waiting for human approval that never comes, or if the gas condition stage (which checks that gas price meets your threshold before executing) is holding a transaction while gas is elevated.&lt;/p&gt;

&lt;p&gt;The CLI gives you visibility here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;waiaas status    &lt;span class="c"&gt;# Daemon status&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the API side, you can check pending transactions directly:&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/transactions &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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For transactions in the APPROVAL tier, the owner approval flow uses WalletConnect or your configured signing channel — push relay or Telegram — so you can approve from your phone without being at your server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Policy Denial Loops
&lt;/h3&gt;

&lt;p&gt;If your AI agent is getting transactions denied repeatedly, you'll see error responses like:&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;The &lt;code&gt;retryable: false&lt;/code&gt; flag tells a well-behaved agent not to hammer the endpoint. The fix is either adjusting the policy (via masterAuth) or using the dry-run API to understand exactly what the policy engine sees before making changes:&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;Dry-run runs the full pipeline including policy evaluation, without submitting the transaction on-chain. It's the fastest way to understand why something is being blocked.&lt;/p&gt;

&lt;h2&gt;
  
  
  Backup and Restore
&lt;/h2&gt;

&lt;p&gt;The CLI ships with &lt;code&gt;backup create&lt;/code&gt;, &lt;code&gt;backup inspect&lt;/code&gt;, and &lt;code&gt;backup list&lt;/code&gt; commands — 3 of the 20 CLI commands in the WAIaaS CLI. For a self-hosted setup, a sensible backup schedule is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;waiaas backup create&lt;/code&gt; before any configuration changes&lt;/li&gt;
&lt;li&gt;Automated daily backup to a location outside the Docker volume (external drive, encrypted remote storage)&lt;/li&gt;
&lt;li&gt;Periodic &lt;code&gt;waiaas backup inspect&lt;/code&gt; to verify backup integrity&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The restore path is &lt;code&gt;waiaas restore&lt;/code&gt;, which means you can recover from a corrupted volume without losing wallet state — as long as your backups are current.&lt;/p&gt;

&lt;h2&gt;
  
  
  RPC Endpoints: The Other Dependency You Control
&lt;/h2&gt;

&lt;p&gt;One thing that often gets overlooked in self-hosted crypto infrastructure: even if you control the wallet daemon, you're still dependent on RPC endpoints for reading chain state and submitting transactions. WAIaaS lets you configure your own:&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;For full sovereignty, point these at your own node, a private RPC provider, or a self-hosted RPC proxy. WAIaaS supports 18 networks across EVM and Solana chain types, so you can configure custom RPC endpoints per-network as needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start: Self-Hosted WAIaaS in Five Minutes
&lt;/h2&gt;

&lt;p&gt;Here's the minimal path to a running, monitored instance:&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;# 1. Clone and start&lt;/span&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;span class="c"&gt;# 2. Check it's healthy&lt;/span&gt;
curl http://127.0.0.1:3100/health

&lt;span class="c"&gt;# 3. Follow logs&lt;/span&gt;
docker compose logs &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, install the CLI and run quickset to create wallets and sessions:&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;For MCP integration with Claude Desktop (so your AI agent can actually use the wallet):&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;That registers all your wallets with Claude Desktop automatically, writing the configuration JSON you'd otherwise have to craft by hand.&lt;/p&gt;

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

&lt;p&gt;The monitoring and recovery patterns here are the operational foundation. Once your instance is stable, the natural next step is tightening your policy configuration — understanding the 21 policy types, setting spending limits, and configuring the 4 security tiers so your AI agent operates within the boundaries you've defined without requiring constant approval. The OpenAPI spec at &lt;code&gt;http://127.0.0.1:3100/reference&lt;/code&gt; gives you an interactive UI to explore every endpoint, which is useful when you're building custom monitoring scripts or integrating WAIaaS into a broader homelab automation stack.&lt;/p&gt;




&lt;p&gt;The full source, Dockerfiles, and documentation are at &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 project before deploying anything, the official site at &lt;a href="https://waiaas.ai" rel="noopener noreferrer"&gt;https://waiaas.ai&lt;/a&gt; has the overview. Your keys, your server, your rules — that's the point.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>selfhosted</category>
      <category>devops</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Admin Dashboard in Claude Desktop: Monitor Your AI Agent's DeFi Portfolio with MCP Tools</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Wed, 16 Sep 2026 17:37:10 +0000</pubDate>
      <link>https://dev.to/walletguy/admin-dashboard-in-claude-desktop-monitor-your-ai-agents-defi-portfolio-with-mcp-tools-972</link>
      <guid>https://dev.to/walletguy/admin-dashboard-in-claude-desktop-monitor-your-ai-agents-defi-portfolio-with-mcp-tools-972</guid>
      <description>&lt;h1&gt;
  
  
  Admin Dashboard in Claude Desktop: Monitor Your AI Agent's DeFi Portfolio with MCP Tools
&lt;/h1&gt;

&lt;p&gt;MCP tools for DeFi are here — and if you're already using Claude Desktop, you're one config block away from giving your agent a live onchain wallet with the ability to swap, lend, stake, bridge, and monitor positions across 15 integrated protocols. No custom API wiring. No bespoke tool definitions. Just add WAIaaS as an MCP server and Claude inherits 45 ready-made wallet tools the moment it starts.&lt;/p&gt;

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

&lt;p&gt;Most developers who reach for MCP do so because they want Claude to &lt;em&gt;do&lt;/em&gt; things, not just talk about them. Fetching a webpage, running a shell command, querying a database — these are the classic use cases. But onchain actions are a different beast. Signing a transaction requires key management. DeFi positions span multiple protocols and chains. Approvals need to go through a human before real money moves. Wiring all of that up yourself, safely, is weeks of work.&lt;/p&gt;

&lt;p&gt;The stakes are also higher than a failed shell command. A misconfigured DeFi action can drain a wallet. An agent with unbounded spending authority is a liability. What you actually need is a wallet layer that's already solved key custody, policy enforcement, and human-in-the-loop approval — and exposes all of it through MCP so Claude can drive it naturally. That's the gap WAIaaS fills.&lt;/p&gt;

&lt;h2&gt;
  
  
  What WAIaaS Is
&lt;/h2&gt;

&lt;p&gt;WAIaaS is an open-source, self-hosted Wallet-as-a-Service for AI agents. You run it locally (or on a server), it manages wallets across EVM and Solana networks, and it exposes everything through a REST API and — critically for this post — an MCP server.&lt;/p&gt;

&lt;p&gt;The MCP server ships as &lt;code&gt;@waiaas/mcp&lt;/code&gt; on npm. It registers 45 tools covering wallet queries, token transfers, DeFi actions, NFT operations, and the x402 HTTP payment protocol. When Claude connects to it, those tools appear in Claude's tool list exactly like any other MCP capability. Claude doesn't need to know anything about transaction signing, gas, or RPC nodes. WAIaaS handles all of that under the hood.&lt;/p&gt;

&lt;p&gt;The daemon itself is a 15-package monorepo with a 7-stage transaction pipeline (validate → auth → policy → wait → execute → confirm), a policy engine with 21 policy types across 4 security tiers, and 15 integrated DeFi protocol providers. It's not a toy.&lt;/p&gt;

&lt;h2&gt;
  
  
  The One-Line Config
&lt;/h2&gt;

&lt;p&gt;Here's what the setup looks like in &lt;code&gt;claude_desktop_config.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="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 the next conversation has access to all 45 MCP tools. No build step, no SDK to initialize, no WebSocket server to manage. &lt;code&gt;npx&lt;/code&gt; pulls the package on demand.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;WAIAAS_SESSION_TOKEN&lt;/code&gt; is a JWT scoped to a specific wallet — it's what the WAIaaS policy engine uses to apply spending limits, token whitelists, and approval requirements to every action Claude takes. The agent gets real capabilities, but bounded ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 45 MCP Tools — What Claude Can Actually Do
&lt;/h2&gt;

&lt;p&gt;Once connected, Claude can call tools across five categories:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wallet &amp;amp; balance&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;get_balance&lt;/code&gt; — native token balance&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_assets&lt;/code&gt; — all token balances in the wallet&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_wallet_info&lt;/code&gt; — wallet metadata, address, chain&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_address&lt;/code&gt; — just the wallet address&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_nonce&lt;/code&gt; — current transaction nonce&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Transactions&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;send_token&lt;/code&gt; — native or ERC-20/SPL token transfer&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;send_batch&lt;/code&gt; — multiple transfers in one atomic call&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sign_message&lt;/code&gt; — arbitrary message signing&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sign_transaction&lt;/code&gt; — sign without broadcasting&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;simulate_transaction&lt;/code&gt; — dry-run before execution&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;list_transactions&lt;/code&gt; — transaction history&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_transaction&lt;/code&gt; — single transaction by ID&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;DeFi&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;get_defi_positions&lt;/code&gt; — lending/staking positions across all protocols&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_health_factor&lt;/code&gt; — lending health factor (Aave-style)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;action_provider&lt;/code&gt; — generic DeFi action dispatcher&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hyperliquid&lt;/code&gt; — perpetuals, spot, sub-accounts&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;polymarket&lt;/code&gt; — prediction market positions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;NFT&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;list_nfts&lt;/code&gt; — all NFTs in the wallet&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_nft_metadata&lt;/code&gt; — token metadata with caching&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;transfer_nft&lt;/code&gt; — ERC-721, ERC-1155, or Metaplex transfer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Infrastructure &amp;amp; utility&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;x402_fetch&lt;/code&gt; — HTTP fetch with automatic 402 payment&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;wc_connect&lt;/code&gt; / &lt;code&gt;wc_disconnect&lt;/code&gt; / &lt;code&gt;wc_status&lt;/code&gt; — WalletConnect session management&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_policies&lt;/code&gt; — inspect active policies&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;list_sessions&lt;/code&gt; — active agent sessions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;resolve_asset&lt;/code&gt; — resolve token symbol to on-chain address&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_tokens&lt;/code&gt; — supported token list for a network&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_rpc_proxy_url&lt;/code&gt; — proxied RPC endpoint for chain queries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And more — ERC-8004 reputation tools, ERC-8128 signing, UserOp build/sign for Account Abstraction, credential management. The full list of 45 is in the WAIaaS MCP package.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitoring Your DeFi Portfolio From Claude Desktop
&lt;/h2&gt;

&lt;p&gt;Let's make this concrete. After connecting WAIaaS as an MCP server, you can open Claude Desktop and ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Show me my DeFi positions across all protocols"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Claude calls &lt;code&gt;get_defi_positions&lt;/code&gt;, which queries WAIaaS across all 15 integrated protocol providers — Aave v3, Kamino, Lido, Jito, Pendle, and others — and returns a structured summary of your lending positions, staked assets, and liquidity. You can then ask follow-up questions and Claude will call &lt;code&gt;get_health_factor&lt;/code&gt; to check your lending safety margin, or &lt;code&gt;get_assets&lt;/code&gt; to compare your liquid balance against locked positions.&lt;/p&gt;

&lt;p&gt;This is a genuine admin dashboard experience, except the "dashboard" is a conversation and the "widgets" are tool calls.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User: "Check my wallet balance"
→ Claude calls get_balance → returns balance

User: "Swap 0.1 SOL for USDC on Jupiter"
→ Claude calls execute_action tool with jupiter-swap provider

User: "Show my DeFi positions across all protocols"
→ Claude calls get_defi_positions → returns lending/staking positions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Jupiter swap example above goes through the full WAIaaS transaction pipeline. If you've set a &lt;code&gt;SPENDING_LIMIT&lt;/code&gt; policy with an &lt;code&gt;instant_max_usd&lt;/code&gt; of $10, a small swap executes immediately. A larger one triggers &lt;code&gt;NOTIFY&lt;/code&gt; or &lt;code&gt;DELAY&lt;/code&gt; depending on your thresholds, and anything above &lt;code&gt;delay_max_usd&lt;/code&gt; requires explicit owner approval via WalletConnect or Telegram before it executes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running Multiple Wallets as Separate MCP Servers
&lt;/h2&gt;

&lt;p&gt;If you're running multiple agents — say, a trading wallet on Solana and a separate EVM wallet for Ethereum DeFi — you can register each as its own MCP server with its own session token and policy set:&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;Claude Desktop will show both as distinct tool namespaces. Each wallet has its own session, its own policy set, and its own transaction history. The daemon is a single process managing both.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Policy Layer — Why This Is Safe to Actually Use
&lt;/h2&gt;

&lt;p&gt;The thing that makes 45 MCP tools pointed at a live wallet usable rather than terrifying is WAIaaS's policy engine. Every transaction Claude initiates goes through a 7-stage pipeline, and the policy stage runs before anything touches the chain.&lt;/p&gt;

&lt;p&gt;The engine supports 21 policy types. The most important ones for an MCP-connected agent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SPENDING_LIMIT&lt;/strong&gt; — 4-tier security: INSTANT (execute immediately), NOTIFY (execute + alert you), DELAY (queue for N seconds, cancellable), APPROVAL (require your explicit sign-off)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ALLOWED_TOKENS&lt;/strong&gt; — default-deny token whitelist; Claude can only transfer tokens you've explicitly listed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CONTRACT_WHITELIST&lt;/strong&gt; — Claude can only call contracts on this list&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;X402_ALLOWED_DOMAINS&lt;/strong&gt; — Claude can only auto-pay 402 responses from domains you've approved&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PERP_MAX_LEVERAGE&lt;/strong&gt; — caps the leverage Claude can use on Hyperliquid positions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Default-deny is the key property here. If you haven't configured &lt;code&gt;ALLOWED_TOKENS&lt;/code&gt;, token transfers are blocked. If you haven't configured &lt;code&gt;CONTRACT_WHITELIST&lt;/code&gt;, contract calls are blocked. Claude can ask for things; the policy engine decides whether they happen.&lt;/p&gt;

&lt;p&gt;You configure policies 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/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;That policy says: under $100, Claude acts instantly. $100–$500, Claude acts and you get a notification. $500–$2,000, Claude waits 15 minutes before executing (giving you time to cancel). Over $2,000, nothing moves without your approval.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start: From Zero to Claude + Wallet in 5 Steps
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — Install the CLI and 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;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&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;&lt;code&gt;quickset&lt;/code&gt; creates wallets and MCP sessions in one step and prints the config JSON you need.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — Or use the auto-provision Docker path&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 — Register WAIaaS as an MCP server in Claude Desktop&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Paste the config block from Step 2 into &lt;code&gt;~/Library/Application Support/Claude/claude_desktop_config.json&lt;/code&gt;. Or run:&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;Step 5 — Set a spending policy, then open Claude&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create at least a &lt;code&gt;SPENDING_LIMIT&lt;/code&gt; policy (see the curl example above), restart Claude Desktop, and start a conversation. Ask Claude to check your balance — it will call &lt;code&gt;get_balance&lt;/code&gt; and return a real answer.&lt;/p&gt;

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

&lt;p&gt;The 45 MCP tools are the surface layer. Underneath is a daemon with 39 REST API route modules, a TypeScript SDK (&lt;code&gt;@waiaas/sdk&lt;/code&gt;) with 40+ methods, and a Python SDK — so you can build agents that use WAIaaS programmatically, not just through Claude. The OpenAPI 3.0 spec auto-generates at &lt;code&gt;/doc&lt;/code&gt; and there's an interactive reference UI at &lt;code&gt;/reference&lt;/code&gt; if you want to explore the full API before writing any code.&lt;/p&gt;

&lt;p&gt;If you hit a transaction that needs human approval, WAIaaS routes it through WalletConnect, Telegram, or a push notification — your choice — so you can approve from your phone without leaving the app you're already using.&lt;/p&gt;




&lt;p&gt;The source is at &lt;a href="https://github.com/waiaas/WAIaaS" rel="noopener noreferrer"&gt;github.com/waiaas/WAIaaS&lt;/a&gt; and the project site is &lt;a href="https://waiaas.ai" rel="noopener noreferrer"&gt;waiaas.ai&lt;/a&gt;. Both are worth bookmarking: the GitHub repo has the full list of supported networks, protocol providers, and policy types, and the site has deployment guides for production setups with Docker Secrets and Watchtower auto-updates.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
      <category>defi</category>
      <category>webdev</category>
    </item>
    <item>
      <title>AI Agents That Pay for Compute: The x402 Payment Protocol Revolution</title>
      <dc:creator>Wallet Guy</dc:creator>
      <pubDate>Wed, 16 Sep 2026 11:48:04 +0000</pubDate>
      <link>https://dev.to/walletguy/ai-agents-that-pay-for-compute-the-x402-payment-protocol-revolution-27lc</link>
      <guid>https://dev.to/walletguy/ai-agents-that-pay-for-compute-the-x402-payment-protocol-revolution-27lc</guid>
      <description>&lt;h1&gt;
  
  
  AI Agents That Pay for Compute: The x402 Payment Protocol Revolution
&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. The x402 HTTP payment protocol, combined with autonomous wallet infrastructure, closes the loop between agents that consume resources and the economic systems that price those resources. This isn't a roadmap item. It's running code you can deploy this afternoon.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with Agent Economics Today
&lt;/h2&gt;

&lt;p&gt;Here's what happens right now when an AI agent needs to call a paid API: a human set up a credit card, got an API key, hardcoded it into an environment variable, and prayed the billing doesn't explode. The agent itself has no economic agency. It's a passenger. Someone else handles the money.&lt;/p&gt;

&lt;p&gt;That model breaks down fast when you have hundreds of agents, or agents that need to make micropayment decisions at runtime, or agents that operate across different contexts with different budget constraints. The human-in-the-loop for every payment isn't a feature — it's a scaling ceiling.&lt;/p&gt;

&lt;p&gt;The vision of autonomous agents participating in economic activity requires wallets those agents can actually use. Not custodied accounts where a human controls all the keys. Wallet infrastructure designed from the ground up for programmatic access, with safety rails that let humans stay in control without becoming bottlenecks for every transaction.&lt;/p&gt;

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

&lt;p&gt;The HTTP 402 status code has existed since 1991. It was reserved for "Payment Required." For decades, nothing used it. Then the rise of stablecoins and crypto payment networks made it practical: a server can now return a 402 response with machine-readable payment instructions, a client pays, and the server retries the request with proof of payment. The whole thing happens in one HTTP round-trip.&lt;/p&gt;

&lt;p&gt;For AI agents, this is significant. An agent making an API call doesn't need to know in advance whether that call costs money. It makes the request. If it gets a 402 back, it pays and retries. No human involvement. No pre-registration. No API key management. The payment is the authentication.&lt;/p&gt;

&lt;p&gt;WAIaaS supports the x402 HTTP payment protocol natively — AI agents can pay for API calls automatically, with the economic logic built into the wallet layer rather than the agent itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Wallet Infrastructure Agents Actually Need
&lt;/h2&gt;

&lt;p&gt;WAIaaS is an open-source, self-hosted Wallet-as-a-Service designed specifically for AI agents. The design separates three roles that are often conflated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The agent&lt;/strong&gt; gets a session token and can transact within defined limits — this is &lt;code&gt;sessionAuth&lt;/code&gt; via JWT HS256&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The administrator&lt;/strong&gt; controls wallet creation, policies, and session management — this is &lt;code&gt;masterAuth&lt;/code&gt; via Argon2id&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The fund owner&lt;/strong&gt; can approve high-value transactions or trigger a kill switch — this is &lt;code&gt;ownerAuth&lt;/code&gt; via SIWS/SIWE signatures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An agent never touches the master password. It can't create new wallets or modify its own spending limits. It operates within a policy cage that a human configured, but it can act autonomously within that cage — including making x402 payments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Policy Cages: How You Stay in Control
&lt;/h2&gt;

&lt;p&gt;The policy engine is what makes autonomous agent wallets viable rather than terrifying. WAIaaS implements 21 policy types with 4 security tiers.&lt;/p&gt;

&lt;p&gt;The tiers work like this: INSTANT (execute immediately, no notification), NOTIFY (execute immediately, send notification), DELAY (queue for a configured delay, then execute — cancellable by the owner), and APPROVAL (require human approval before anything happens). Every transaction routes through this system.&lt;/p&gt;

&lt;p&gt;For x402 payments specifically, there's a dedicated policy type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="err"&gt;X402_ALLOWED_DOMAINS&lt;/span&gt;    &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="err"&gt;x402&lt;/span&gt; &lt;span class="err"&gt;payment&lt;/span&gt; &lt;span class="err"&gt;domain&lt;/span&gt; &lt;span class="err"&gt;whitelist&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means an agent can only make x402 payments to domains you've explicitly allowed. It can't start paying arbitrary endpoints on the internet. Combined with spending limits, you get an agent that can autonomously pay for API calls on a whitelist of trusted providers, up to a daily budget, with notifications if it hits certain thresholds.&lt;/p&gt;

&lt;p&gt;Here's what a spending limit policy looks like in practice:&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 pays immediately. Between $100 and $500? Pays immediately, you get notified. Between $500 and $2000? Goes into a 15-minute delay queue you can cancel. Over $2000? Requires your explicit approval. The agent doesn't need to know any of this logic — it just submits transactions and the pipeline handles the rest.&lt;/p&gt;

&lt;h2&gt;
  
  
  The x402Fetch Method
&lt;/h2&gt;

&lt;p&gt;From the TypeScript SDK, the interface for x402 payments is a single method that wraps standard fetch behavior:&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The SDK provides an &lt;code&gt;x402Fetch()&lt;/code&gt; method — HTTP fetch with automatic 402 payment handling. The agent calls an endpoint, gets a 402 if there's a payment required, the SDK handles the payment using the wallet, and the request completes. From the agent code's perspective, it's just an HTTP call.&lt;/p&gt;

&lt;p&gt;This is the right level of abstraction. The agent's reasoning layer shouldn't be thinking about payment channels and transaction confirmations. It should be thinking about the task. The wallet infrastructure handles the economic plumbing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not Just Payments: A Full Financial Layer
&lt;/h2&gt;

&lt;p&gt;x402 is one slice of what agent wallets need to support. The broader picture includes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Token management&lt;/strong&gt; — Agents need to know their balance, receive funds, and send tokens. The SDK's &lt;code&gt;getBalance()&lt;/code&gt;, &lt;code&gt;getAssets()&lt;/code&gt;, and &lt;code&gt;sendToken()&lt;/code&gt; methods cover this. Incoming transaction monitoring with real-time notifications for deposits means agents can react when they receive funds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DeFi access&lt;/strong&gt; — WAIaaS integrates 15 DeFi protocol providers, including Jupiter swap on Solana, Uniswap via 0x, Aave v3 for lending, Hyperliquid for perpetual futures, Lido and Jito for liquid staking, and cross-chain bridging via LI.FI and Across. An agent managing a portfolio can lend idle funds to Aave, take a leveraged position on Hyperliquid, and bridge assets across chains — all through the same wallet interface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NFT operations&lt;/strong&gt; — ERC-721/ERC-1155 on EVM and Metaplex on Solana with metadata caching. Agents can hold and transfer NFTs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Account abstraction&lt;/strong&gt; — ERC-4337 support means gasless transactions and smart account capabilities for EVM chains.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simulation before execution&lt;/strong&gt; — Before any transaction commits, agents can dry-run 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;This is particularly valuable for agents operating on unfamiliar contracts or in high-stakes scenarios — simulate first, execute if clean.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP: Connecting Agents to Wallets Without Custom Code
&lt;/h2&gt;

&lt;p&gt;For agent frameworks that support the Model Context Protocol, WAIaaS exposes 45 MCP tools covering wallet operations, transactions, DeFi, NFTs, and x402. The &lt;code&gt;x402-fetch&lt;/code&gt; tool is explicitly included.&lt;/p&gt;

&lt;p&gt;Setup is a 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;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;The resulting Claude Desktop configuration points an MCP server at your running WAIaaS daemon. Claude (or any MCP-compatible agent) can then check balances, send tokens, execute swaps, and make x402 payments through natural language requests. The agent doesn't need to understand the payment protocol internals — it just calls the tool.&lt;/p&gt;

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

&lt;p&gt;Every transaction — including x402 payments — runs through a 7-stage pipeline: validate, auth, policy, wait, execute, confirm. The policy stage is where spending limits and x402 domain whitelists are enforced. The wait stage is where DELAY-tier transactions sit until the timer expires or the owner cancels. The confirm stage handles on-chain confirmation and receipt.&lt;/p&gt;

&lt;p&gt;This means the safety model isn't bolted on — it's structural. You can't route around it from the agent side because the agent never touches the execution layer directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started in 10 Minutes
&lt;/h2&gt;

&lt;p&gt;Here's the minimal path to an agent with x402 payment capability:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 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;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 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;&lt;span class="c"&gt;# Create 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 session token for 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;&lt;strong&gt;Step 3: Configure spending limits and x402 domain whitelist&lt;/strong&gt; (create policies as shown above)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Fund the wallet and give the session token to your agent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Agent checks balance and starts operating&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/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;The agent now has an independently funded wallet, a session token scoped to what you've allowed, and the ability to make x402 payments to domains on your whitelist — without ever touching your master password or requiring your approval for transactions below your configured threshold.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Onchain Reputation Layer
&lt;/h2&gt;

&lt;p&gt;One piece of this ecosystem worth noting: WAIaaS includes ERC-8004 support — onchain agent reputation and validation. The &lt;code&gt;REPUTATION_THRESHOLD&lt;/code&gt; policy type lets you enforce that agents your wallet interacts with meet a minimum reputation score. As agent-to-agent economic activity grows, reputation becomes a meaningful signal. An agent paying another agent for compute capacity will eventually want to verify that the recipient isn't a scam. Onchain reputation provides that.&lt;/p&gt;

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

&lt;p&gt;The infrastructure layer for the agent economy is being built right now. x402 provides the payment protocol. Stablecoins provide the rails. Policy engines provide the safety constraints that make autonomous agent wallets viable for humans to deploy. The MCP ecosystem connects this infrastructure to the agent frameworks people are actually building with.&lt;/p&gt;

&lt;p&gt;The question isn't whether AI agents will participate in economic activity. They already do, imperfectly, through human-managed API keys and credit cards. The question is whether that economic participation will be autonomous, auditable, and controllable — or chaotic and opaque.&lt;/p&gt;

&lt;p&gt;Wallet infrastructure designed for agents, with policy engines that encode human intent and safety rails that don't require humans to approve every micropayment, is what makes the difference.&lt;/p&gt;

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

&lt;p&gt;The full documentation, including the OpenAPI 3.0 spec (available at &lt;code&gt;/reference&lt;/code&gt; when you're running locally), covers all 39 REST API route modules and the complete policy configuration options. The monorepo includes a TypeScript SDK with 40+ methods and a Python SDK for teams working in that ecosystem.&lt;/p&gt;

&lt;p&gt;Explore the codebase and deploy your own instance at &lt;a href="https://github.com/waiaas/WAIaaS" rel="noopener noreferrer"&gt;https://github.com/waiaas/WAIaaS&lt;/a&gt;, or learn more about the project at &lt;a href="https://waiaas.ai" rel="noopener noreferrer"&gt;https://waiaas.ai&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
      <category>api</category>
      <category>blockchain</category>
    </item>
  </channel>
</rss>
