{
  "name": "StableInvoice",
  "specVersion": "1.0.0",
  "description": "Self-custody stablecoin invoices and payment requests, encoded into links. No accounts and no custody: agents create, sign, read and verify invoices; their own wallet signs and pays.",
  "homepage": "https://stableinvoice.xyz",
  "documentation": "https://stableinvoice.xyz/skill.md",
  "contact": "hello@bullproject.io",
  "linkFormat": {
    "template": "https://stableinvoice.xyz/pay#payload={base64url(JSON)}",
    "encoding": "UTF-8 JSON, base64url without padding",
    "location": "URL fragment — browsers never transmit it, so it cannot be fetched from this server; decode it locally",
    "maxPayloadChars": 8192,
    "schema": "https://www.stableinvoice.xyz/schemas/payment-payload.v2.json",
    "shapes": {
      "unsigned": "The payload object itself. Anyone forwarding the link can change it.",
      "signed": "{ v, p, sig, from, sigChainId } — p is the payload, sig an EIP-712 signature by from.",
      "encrypted": "{ v, env, sig, from, recipientKey, issuedAt, sigChainId } — readable only by the recipient key holder."
    },
    "invoiceId": "keccak256 of the payload as canonical JSON (keys sorted recursively, no whitespace). Tools return it as payloadHash."
  },
  "signing": {
    "standard": "EIP-712",
    "signedPayloadVersion": 2,
    "domain": {
      "name": "StableInvoice",
      "version": "2",
      "chainId": "sigChainId from the signed wrapper"
    },
    "primaryType": "PaymentRequest",
    "types": {
      "PaymentRequest": [
        {
          "name": "invoiceId",
          "type": "string"
        },
        {
          "name": "recipient",
          "type": "address"
        },
        {
          "name": "token",
          "type": "string"
        },
        {
          "name": "amount",
          "type": "string"
        },
        {
          "name": "chainId",
          "type": "uint256"
        },
        {
          "name": "expiresAt",
          "type": "string"
        },
        {
          "name": "payloadHash",
          "type": "bytes32"
        }
      ]
    },
    "message": {
      "invoiceId": "payload.inv",
      "recipient": "payload.to",
      "token": "payload.token",
      "amount": "payload.amount",
      "chainId": "payload.chainId",
      "expiresAt": "payload.exp",
      "payloadHash": "the invoiceId hash described under linkFormat"
    },
    "accounts": "Externally-owned accounts (ECDSA). Smart-contract accounts (ERC-1271) are not verified yet.",
    "meaning": "A valid signature proves the link was not altered after the signer built it. It does not prove who the signer is: compare the signer with an address obtained independently of the link."
  },
  "payment": {
    "method": "ERC-20 transfer(recipient, amountBaseUnits) on payload.chainId, sent from the payer's own wallet",
    "custody": "none — StableInvoice never holds funds or keys"
  },
  "tools": "https://www.stableinvoice.xyz/agent/tools.json",
  "api": {
    "openapi": "https://www.stableinvoice.xyz/openapi.json",
    "base": "https://www.stableinvoice.xyz/api/v1",
    "call": "POST /api/v1/{tool_name} with the tool's arguments as a JSON body",
    "auth": "none"
  },
  "mcp": {
    "remote": {
      "transport": "streamable-http",
      "url": "https://www.stableinvoice.xyz/mcp",
      "auth": "none",
      "note": "Stateless: one JSON-RPC message per POST, a JSON reply, no session."
    },
    "local": {
      "transport": "stdio",
      "status": "not yet published",
      "note": "A build of the same server that runs on your own machine, so a link is never sent to StableInvoice."
    }
  },
  "x402": {
    "version": 2,
    "what": "An invoice in USDC or EURC can also be paid over x402: GET its x402 address, receive a standard 402 with the amount and recipient, sign, retry. No gas and no StableInvoice-specific code. create_payment_link returns the address as x402.url when the invoice qualifies.",
    "endpoint": "https://www.stableinvoice.xyz/api/v1/x402/{code}",
    "scheme": "exact (EIP-3009 transferWithAuthorization)",
    "networks": [
      "eip155:137",
      "eip155:8453",
      "eip155:42161",
      "eip155:43114"
    ],
    "tokens": {
      "eip155:137": [
        "USDC"
      ],
      "eip155:8453": [
        "USDC",
        "EURC"
      ],
      "eip155:42161": [
        "USDC"
      ],
      "eip155:43114": [
        "USDC",
        "EURC"
      ]
    },
    "custody": "None. The payer signs an authorization naming the invoice's recipient and exact amount; the token contract moves the funds payer -> recipient. Neither StableInvoice nor the facilitator can redirect them.",
    "settlement": "Submitted on-chain by a third-party facilitator. StableInvoice then reads the transaction receipt itself and reports status \"paid\" only when it finds the transfer; otherwise \"submitted\".",
    "refuses": "A sanctioned recipient, an expired invoice, or any request while sanctions screening cannot be completed."
  },
  "privacy": {
    "summary": "A payment link keeps its contents in the URL fragment, which is never sent to a server. To read or verify a link for you, the hosted API and the remote MCP endpoint must be given it. That is the service; this is everything that happens to it.",
    "hostedServiceReceives": "The arguments of the tool you call - for most tools, the payment link.",
    "stored": "Nothing from the request. No database write, no cache, no session, no cookie.",
    "logged": "Nothing from the request body. An unexpected error logs the tool name and the error type only.",
    "kept": "One rate-limit counter, stored under a keyed hash of the caller's network address (not the address itself) and deleted after two days.",
    "sentToThirdParties": [
      "The recipient address, to the public Chainalysis sanctions oracle through public RPC providers, when a tool screens it. Pass screen=false to skip.",
      "A transaction hash, to a public RPC provider on the invoice's network, for verify_payment.",
      "For an x402 payment: the payer's signed authorization, to the facilitator that submits it on-chain."
    ],
    "x402Addresses": "An invoice's x402 address carries its recipient, token, amount, network, expiry and a short label in the URL path, which - unlike a request body - appears in the platform's access log. It never carries names or line items.",
    "keys": "No tool accepts, sees or stores a private key. Signing and paying are done by your own wallet."
  },
  "assets": {
    "networks": [
      {
        "chainId": 1,
        "name": "Ethereum Mainnet",
        "testnet": false,
        "tokens": [
          {
            "symbol": "USDT",
            "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
            "decimals": 6,
            "label": "Tether USD (Mainnet)"
          },
          {
            "symbol": "USDC",
            "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
            "decimals": 6,
            "label": "USD Coin (Mainnet, native)"
          },
          {
            "symbol": "EURC",
            "address": "0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c",
            "decimals": 6,
            "label": "EURC (Ethereum)"
          },
          {
            "symbol": "FDUSD",
            "address": "0xc5f0f7b66764F6ec8C8Dff7BA683102295E16409",
            "decimals": 18,
            "label": "FDUSD (Ethereum)"
          }
        ]
      },
      {
        "chainId": 30,
        "name": "Rootstock",
        "testnet": false,
        "tokens": [
          {
            "symbol": "USDT0",
            "address": "0x779Ded0c9e1022225f8E0630b35a9b54bE713736",
            "decimals": 6,
            "label": "Tether USDt0 (RSK)"
          },
          {
            "symbol": "DOC",
            "address": "0xe700691dA7b9851F2F35f8b8182c69c53CcaD9Db",
            "decimals": 18,
            "label": "Dollar on Chain (RSK)"
          },
          {
            "symbol": "USDRIF",
            "address": "0x3A15461d8aE0F0Fb5Fa2629e9DA7D66A794a6e37",
            "decimals": 18,
            "label": "USDRIF (RSK)"
          }
        ]
      },
      {
        "chainId": 56,
        "name": "BNB Smart Chain",
        "testnet": false,
        "tokens": [
          {
            "symbol": "USDT",
            "address": "0x55d398326f99059fF775485246999027B3197955",
            "decimals": 18,
            "label": "Tether USD (BSC)"
          },
          {
            "symbol": "USDC",
            "address": "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",
            "decimals": 18,
            "label": "USDC (BSC, Binance-Peg bridged)"
          },
          {
            "symbol": "FDUSD",
            "address": "0xc5f0f7b66764F6ec8C8Dff7BA683102295E16409",
            "decimals": 18,
            "label": "FDUSD (BSC)"
          }
        ]
      },
      {
        "chainId": 137,
        "name": "Polygon",
        "testnet": false,
        "tokens": [
          {
            "symbol": "USDT",
            "address": "0xc2132D05D31c914a87C6611C10748aacBd5D31F3",
            "decimals": 6,
            "label": "Tether USD (Polygon)"
          },
          {
            "symbol": "USDC",
            "address": "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
            "decimals": 6,
            "label": "USD Coin (Polygon, native)"
          }
        ]
      },
      {
        "chainId": 8453,
        "name": "Base",
        "testnet": false,
        "tokens": [
          {
            "symbol": "USDC",
            "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
            "decimals": 6,
            "label": "USDC (Base)"
          },
          {
            "symbol": "EURC",
            "address": "0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42",
            "decimals": 6,
            "label": "EURC (Base)"
          }
        ]
      },
      {
        "chainId": 42161,
        "name": "Arbitrum One",
        "testnet": false,
        "tokens": [
          {
            "symbol": "USDT",
            "address": "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
            "decimals": 6,
            "label": "Tether USD (Arbitrum)"
          },
          {
            "symbol": "USDC",
            "address": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
            "decimals": 6,
            "label": "USD Coin (Arbitrum, native)"
          },
          {
            "symbol": "DOC",
            "address": "0x2AD62eb9744c720364F6ac856360a43e8a2229b5",
            "decimals": 18,
            "label": "DOC (Arbitrum)"
          },
          {
            "symbol": "FDUSD",
            "address": "0x93C9932E4afa59201F0B5E63f7d816516F1669fE",
            "decimals": 18,
            "label": "FDUSD (Arbitrum)"
          },
          {
            "symbol": "USDRIF",
            "address": "0x8EEF5eD361c6823156D936209E23A8e0349e5C61",
            "decimals": 18,
            "label": "USDRIF (Arbitrum)"
          }
        ]
      },
      {
        "chainId": 43114,
        "name": "Avalanche",
        "testnet": false,
        "tokens": [
          {
            "symbol": "USDT",
            "address": "0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7",
            "decimals": 6,
            "label": "Tether USD (Avalanche)"
          },
          {
            "symbol": "USDC",
            "address": "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
            "decimals": 6,
            "label": "USD Coin (Avalanche, native)"
          },
          {
            "symbol": "EURC",
            "address": "0xC891EB4cbdEFf6e073e859e987815Ed1505c2ACD",
            "decimals": 6,
            "label": "EURC (Avalanche)"
          }
        ]
      },
      {
        "chainId": 11155111,
        "name": "Ethereum Sepolia Testnet",
        "testnet": true,
        "tokens": [
          {
            "symbol": "USDT",
            "address": "0x6175a8471c2122F4b4475809014CE9167Ed35a77",
            "decimals": 6,
            "label": "USDT (Sepolia v1)"
          },
          {
            "symbol": "USDC",
            "address": "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
            "decimals": 6,
            "label": "USDC (Sepolia v1)"
          }
        ]
      }
    ]
  }
}
