tutorial · paying agents

Fund your AI agent

Your agent calls sniffy_diagnose and Sniffy answers with HTTP 402 plus an x402 offer. The agent has to sign and pay — which means it needs its own externally-owned account (EOA) holding the payment token on Morph. Five minutes, no bridge gymnastics if you stay on Mainnet.

1

Why your agent needs a wallet

/api/v1/aso/diagnose is an x402-paywalled endpoint. The first request comes back as HTTP 402 Payment Required with the offer in the PAYMENT-REQUIRED header. The client (your agent, via the SDK / CLI / MCP) signs an EIP-3009 authorization, retries with PAYMENT-SIGNATURE, and receives the diagnosis plus a settled receipt.

The signing wallet lives on your side. Sniffy never holds your key. Payment is on-chain and non-refundable, so the wallet should be a dedicated agent EOA — not your personal hot wallet.

2

Generate a fresh EOA

Spin up a brand-new private key with viem. Don't reuse a wallet you keep meaningful balances in.

ts
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";

const privateKey = generatePrivateKey();
const account = privateKeyToAccount(privateKey);

console.log("address:    ", account.address);
console.log("privateKey: ", privateKey);  // testnet-only, never commit
3

Fund the EOA on Morph Mainnet

Mainnet is the path that actually settles today. $0.50 of USDC on Morph covers dozens of diagnose calls.

Fastest path: buy USDC on Bitget

Bitget lists Morph natively, so USDC withdrawals land directly on your agent's Morph Mainnet address — no L1↔L2 bridging required.

  1. Sign up or log in to Bitget.
  2. Buy USDC on the Bitget spot market.
  3. Withdraw → pick Morph Mainnet as the network → paste your agent EOA address → confirm. The withdrawal will show up on the Morph explorer once it settles.
Get USDC on Bitget

Or bridge from L1

You also need a tiny amount of ETH on Morph Mainnet for gas if the facilitator falls back to a user-signed settlement path — the official relayer normally sponsors gas, but having $0.10 of ETH bridged is good hygiene.

How much per call?

Line itemUSD
base diagnosis$0.03
per keyword$0.01
per additional country$0.01
competitor trail (shallow)$0.02
competitor trail (deep)$0.05

Five keywords + one country + shallow trail ≈ $0.10. Always quote the exact charge from pricing.estimatedTotal returned by sniffy_quote — the breakdown above is the source-of-truth recipe, not a fixed total.

4

Inject the key into your agent

The same key works across all three Sniffy surfaces.

MCP

Add it to the host config you set up in the Setup MCP guide:

json
{
  "mcpServers": {
    "sniffy": {
      "command": "npx",
      "args": ["-y", "@gosniffy/mcp"],
      "env": {
        "SNIFFY_PRIVATE_KEY": "0x...your fresh key..."
      }
    }
  }
}

CLI

bash
export SNIFFY_PRIVATE_KEY=0x...your fresh key...
npx @gosniffy/cli diagnose --app 1234567890 --keywords "pickleball,tracker"

SDK

ts
import { createSniffy } from "@gosniffy/sdk";
import { privateKeyToAccount } from "viem/accounts";

const sniffy = createSniffy({
  signer: privateKeyToAccount(process.env.SNIFFY_PRIVATE_KEY as `0x${string}`),
});

const quote = await sniffy.quote({ store: "ios", app: "1234567890", country: "US", keywords: ["pickleball"] });
const report = await sniffy.diagnose({ ...quote.input, sniffId: quote.sniffId });
5

What your agent is actually signing

The signature is an EIP-3009 transferWithAuthorization — a one-time, off-chain authorization for a specific (from, to, value, validAfter, validBefore, nonce) tuple. It is not a generic ERC-20 approval.

  • value is in atomic token units (USDC: 6 decimals → 50000 = $0.05). The SDK does the unit math.
  • nonce is a random 32-byte hex string — scopes the signature to a single call, prevents replay.
  • The facilitator can't pull more than value with this signature. If you ever see a UI asking you to approve unlimited spend, you're on the wrong endpoint.
6

Optional: use Hoodi testnet instead

Show the Hoodi flow

Hoodi is Morph's testnet (chain ID 2910, eip155:2910). Flip both env vars together:

bash
# scraper/.env
MORPH_NETWORK=eip155:2910

# landing/.env.local
NEXT_PUBLIC_MORPH_NETWORK=eip155:2910

Then visit the Hoodi faucet for gas ETH:

https://faucet-hoodi.morph.network