{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/insumermodel-com/json-schema/insumermodel-com-token-config-schema.json",
  "title": "TokenConfig",
  "x-generated": "2026-10-30",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/insumermodel-com-openapi.json#/components/schemas/TokenConfig",
  "type": "object",
  "required": [
    "symbol",
    "chainId",
    "contractAddress",
    "decimals",
    "tiers"
  ],
  "properties": {
    "symbol": {
      "type": "string",
      "maxLength": 10
    },
    "name": {
      "type": "string",
      "maxLength": 100,
      "description": "Optional display name shown in the public directory listing (without it the entry shows a bare symbol)."
    },
    "logo": {
      "type": "string",
      "maxLength": 500,
      "description": "Optional logo URL shown in the public directory listing."
    },
    "chainId": {
      "$ref": "#/$defs/OnboardingChainId"
    },
    "contractAddress": {
      "type": "string",
      "description": "Token address, validated per chain: 0x + 40 hex on EVM chains, or \"native\" for the chain's own coin (ETH on Ethereum or Base, POL on Polygon); on Solana \"native\" for SOL or the mint address (base58, 32 to 44 characters); on XRPL \"native\" for XRP or the issuer r-address, whose base58 checksum is verified. Anything else is a 400."
    },
    "decimals": {
      "type": "integer",
      "minimum": 0,
      "maximum": 18,
      "description": "Token decimals. Required; a missing or non-numeric value is rejected with 400. When a discount is evaluated the token's decimals are read from the chain; this stored value is not used."
    },
    "currency": {
      "type": "string",
      "description": "XRPL trust line currency code (e.g. \"USD\", \"RLUSD\"). Required for XRPL trust line tokens. Enter the currency code exactly as the issuer created it. Codes are case-sensitive, and the code is stored as entered. It is validated by the same rule as the `currency` of an attest condition: a 3-character standard code, a token name of 1 to 20 printable ASCII characters, or a 40-character hex code; anything else is a 400, and so is `XRP`, which is the native coin (use contractAddress \"native\")."
    },
    "tiers": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/Tier"
      },
      "minItems": 1,
      "maxItems": 4
    },
    "alsoOn": {
      "type": "array",
      "maxItems": 9,
      "description": "Optional. The same token on other networks, each as { chainId, contractAddress }: EVM chains and Solana, not the XRP Ledger and not a chain's native coin. The discount check and the verification (verify, ACP, UCP) read every network listed plus the token's own, add the balances exactly, and award the token's tier once, so the token appears once in the breakdown and uses one of the 8 token slots. The store decides which deployments count as the same token; each network's balance is read in that token's own decimals there. A read that fails on any listed network refuses the whole check (503 rpc_failure), never a total from the networks that answered. Leave it out and only chainId and contractAddress are read, as before. A network listed twice, or already listed by another token, is a 400. Not available on an XRP Ledger token.",
      "items": {
        "type": "object",
        "required": [
          "chainId",
          "contractAddress"
        ],
        "properties": {
          "chainId": {
            "$ref": "#/$defs/OnboardingChainId"
          },
          "contractAddress": {
            "type": "string",
            "description": "0x + 40 hex on EVM chains, or the mint address on Solana."
          }
        }
      }
    },
    "enabled": {
      "type": "boolean",
      "default": true,
      "description": "Read on ownToken only. `false` switches the own token off (the same as sending ownToken as null), and the other fields are then not required. `true`, or leaving it out, saves the token switched on. Any other value is a 400; text such as \"true\" or \"false\" is not a boolean."
    }
  },
  "$defs": {
    "OnboardingChainId": {
      "oneOf": [
        {
          "type": "integer",
          "enum": [
            1,
            56,
            8453,
            43114,
            137,
            42161,
            10,
            88888,
            1868,
            98866,
            146,
            100,
            5000,
            534352,
            59144,
            324,
            81457,
            167000,
            2020,
            42220,
            88,
            204,
            480,
            130,
            57073,
            1329,
            80094,
            33139,
            50,
            4663,
            5042
          ]
        },
        {
          "type": "string",
          "enum": [
            "solana",
            "xrpl"
          ]
        }
      ],
      "description": "Chains supported for merchant token/NFT configuration: all 31 EVM chains (same integer IDs as ChainId) plus Solana (\"solana\") and XRP Ledger (\"xrpl\"). Bitcoin, Tron, Stellar, and Sui are not available for merchant registry configuration, though they remain queryable via /v1/attest and /v1/trust.\n"
    },
    "Tier": {
      "type": "object",
      "required": [
        "name",
        "threshold",
        "discount"
      ],
      "properties": {
        "name": {
          "type": "string",
          "maxLength": 30
        },
        "threshold": {
          "type": "number",
          "exclusiveMinimum": 0
        },
        "discount": {
          "type": "integer",
          "minimum": 1,
          "maximum": 50,
          "description": "Discount percentage: a whole number from 1 to 50, as a JSON number or its digits as a string. A value with a fraction (10.5) is a 400; \"10.0\" is accepted as 10."
        }
      }
    }
  }
}