{
  "address": "8eiSiyHwkB3s5x4jNEWrfnPFyWULYMRApFe8ungsu9Gy",
  "metadata": {
    "name": "rwa_token",
    "version": "0.1.0",
    "spec": "0.1.0",
    "description": "RWA token program (SPL Token-2022 mint + RWA metadata PDA)"
  },
  "instructions": [
    {
      "name": "close_asset",
      "docs": [
        "Close an abandoned asset, returning its rent. Admin only.",
        "",
        "Mainnet carries two DPRI TokenMeta accounts left by failed listings: zero supply, and a",
        "vault of 11111111111111111111111111111111, i.e. never set. There was no way to remove",
        "them, so they sat as permanent junk that any future by-symbol lookup would trip over.",
        "",
        "The guards are what make this safe to expose at all. An asset with ANY supply has",
        "holders, and closing its meta would strand them — the mint keeps minting authority",
        "delegated to a PDA whose account no longer exists. An asset with a vault set is a real",
        "listing, however dormant. Both are refused, so this can only ever remove something that",
        "was never finished."
      ],
      "discriminator": [
        39,
        124,
        90,
        146,
        16,
        82,
        77,
        253
      ],
      "accounts": [
        {
          "name": "admin",
          "writable": true,
          "signer": true
        },
        {
          "name": "meta",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  109,
                  101,
                  116,
                  97
                ]
              },
              {
                "kind": "account",
                "path": "meta.mint",
                "account": "TokenMeta"
              }
            ]
          }
        },
        {
          "name": "mint"
        }
      ],
      "args": []
    },
    {
      "name": "create_asset",
      "docs": [
        "Create a new RWA asset: init the Token-2022 mint (authority = TokenMeta PDA)",
        "and populate the TokenMeta PDA. Mirrors factory.deployToken(tokenParams).",
        "",
        "The caller (operator) pays. `meta.admin` is taken from `Config`, not from the caller,",
        "so issuance can stay on the operator hot key while control always lands on the multisig."
      ],
      "discriminator": [
        28,
        42,
        120,
        51,
        7,
        38,
        156,
        136
      ],
      "accounts": [
        {
          "name": "config",
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  99,
                  111,
                  110,
                  102,
                  105,
                  103
                ]
              }
            ]
          }
        },
        {
          "name": "authority",
          "docs": [
            "Operator (routine issuance) or the governing authority.",
            "",
            "C-3: `create_asset` previously had NO authorisation at all and took `admin` as a",
            "parameter. Because `deployToken` creates the mint in an earlier transaction, the mint sat",
            "on-chain with `mint_authority = meta PDA` — the only condition this instruction checked —",
            "long enough for anyone to claim the meta PDA with `admin = self` and `max_supply = 0`,",
            "then grant themselves minter and issue without limit."
          ],
          "signer": true
        },
        {
          "name": "payer",
          "writable": true,
          "signer": true
        },
        {
          "name": "mint",
          "docs": [
            "The new Token-2022 mint (authority = meta PDA). Created by the client/CPI."
          ],
          "writable": true
        },
        {
          "name": "meta",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  109,
                  101,
                  116,
                  97
                ]
              },
              {
                "kind": "account",
                "path": "mint"
              }
            ]
          }
        },
        {
          "name": "token_program"
        },
        {
          "name": "system_program",
          "address": "11111111111111111111111111111111"
        }
      ],
      "args": [
        {
          "name": "params",
          "type": {
            "defined": {
              "name": "AssetParams"
            }
          }
        }
      ]
    },
    {
      "name": "grant_automation",
      "docs": [
        "Grant the automation capability (EVM grantRole(AUTOMATION_ROLE)). Admin only."
      ],
      "discriminator": [
        91,
        140,
        175,
        157,
        206,
        235,
        210,
        58
      ],
      "accounts": [
        {
          "name": "admin",
          "signer": true
        },
        {
          "name": "meta",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  109,
                  101,
                  116,
                  97
                ]
              },
              {
                "kind": "account",
                "path": "meta.mint",
                "account": "TokenMeta"
              }
            ]
          }
        }
      ],
      "args": [
        {
          "name": "automation",
          "type": "pubkey"
        }
      ]
    },
    {
      "name": "grant_minter",
      "docs": [
        "Grant the minter capability (EVM grantRole(MINTER_ROLE)). Admin only."
      ],
      "discriminator": [
        2,
        103,
        151,
        198,
        189,
        58,
        32,
        85
      ],
      "accounts": [
        {
          "name": "admin",
          "signer": true
        },
        {
          "name": "meta",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  109,
                  101,
                  116,
                  97
                ]
              },
              {
                "kind": "account",
                "path": "meta.mint",
                "account": "TokenMeta"
              }
            ]
          }
        }
      ],
      "args": [
        {
          "name": "minter",
          "type": "pubkey"
        }
      ]
    },
    {
      "name": "init_config",
      "docs": [
        "Bind this program to its governing authority. Callable ONCE, and only by the program's",
        "current upgrade authority.",
        "",
        "Gating on the upgrade authority is what makes the bootstrap safe: at deploy time that is",
        "the deploy wallet, and after the Squads handoff it is the multisig vault. The only party",
        "who can claim a program's Config is therefore the same party who can already replace its",
        "bytecode. A permissionless `init_config` would simply move the first-caller-wins hole",
        "from the per-asset PDAs up to the global one."
      ],
      "discriminator": [
        23,
        235,
        115,
        232,
        168,
        96,
        1,
        231
      ],
      "accounts": [
        {
          "name": "payer",
          "writable": true,
          "signer": true
        },
        {
          "name": "upgrade_authority",
          "docs": [
            "Must be this program's current upgrade authority."
          ],
          "signer": true
        },
        {
          "name": "program_data"
        },
        {
          "name": "config",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  99,
                  111,
                  110,
                  102,
                  105,
                  103
                ]
              }
            ]
          }
        },
        {
          "name": "system_program",
          "address": "11111111111111111111111111111111"
        }
      ],
      "args": [
        {
          "name": "authority",
          "type": "pubkey"
        },
        {
          "name": "operator",
          "type": "pubkey"
        }
      ]
    },
    {
      "name": "lower_max_supply",
      "docs": [
        "TIGHTEN the issuance ceiling. Operator OR admin, immediate.",
        "",
        "ASYMMETRIC, and deliberately so — the same shape as `rwa_market::set_active`, where",
        "pausing is allowed by the operator and resuming needs the authority. The safe direction",
        "must not need a Squads round trip: `lower_max_supply(mint.supply)` is the emergency",
        "stop, it ends issuance without touching a single holder's balance, and it is the first",
        "thing to reach for if a minter starts behaving oddly. A multi-signer wait in front of",
        "that is how the window gets lost.",
        "",
        "LOOSENING stays with `set_max_supply` under the authority, so the blast radius of the",
        "hot key is a ceiling somebody has to raise back — a nuisance, not a loss. Base's",
        "`lowerMaxSupply` is the twin of this; the two chains now split the same way."
      ],
      "discriminator": [
        132,
        32,
        118,
        161,
        51,
        201,
        18,
        147
      ],
      "accounts": [
        {
          "name": "signer",
          "signer": true
        },
        {
          "name": "config",
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  99,
                  111,
                  110,
                  102,
                  105,
                  103
                ]
              }
            ]
          }
        },
        {
          "name": "meta",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  109,
                  101,
                  116,
                  97
                ]
              },
              {
                "kind": "account",
                "path": "meta.mint",
                "account": "TokenMeta"
              }
            ]
          }
        },
        {
          "name": "mint"
        }
      ],
      "args": [
        {
          "name": "new_max",
          "type": "u64"
        }
      ]
    },
    {
      "name": "mint_to",
      "docs": [
        "Mint `amount` (smallest units) to `to`. Caller must be admin or minter.",
        "PDA-signed CPI (mint authority = TokenMeta PDA). Mirrors token.mint()."
      ],
      "discriminator": [
        241,
        34,
        48,
        186,
        37,
        179,
        123,
        192
      ],
      "accounts": [
        {
          "name": "authority",
          "signer": true
        },
        {
          "name": "meta",
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  109,
                  101,
                  116,
                  97
                ]
              },
              {
                "kind": "account",
                "path": "meta.mint",
                "account": "TokenMeta"
              }
            ]
          }
        },
        {
          "name": "mint",
          "writable": true
        },
        {
          "name": "to",
          "writable": true
        },
        {
          "name": "token_program"
        }
      ],
      "args": [
        {
          "name": "amount",
          "type": "u64"
        }
      ]
    },
    {
      "name": "set_config_authority",
      "docs": [
        "Rotate the governing authority (migrating to a new Squads multisig) and/or the operator",
        "hot key. Current authority only.",
        "",
        "Every per-asset account created BEFORE a rotation keeps the old admin recorded in its own",
        "state — this only changes who may create new ones. Rotating existing assets is a separate",
        "concern (see M-1 in SECURITY-AUDIT.md)."
      ],
      "discriminator": [
        16,
        200,
        212,
        18,
        95,
        43,
        107,
        89
      ],
      "accounts": [
        {
          "name": "authority",
          "signer": true
        },
        {
          "name": "config",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  99,
                  111,
                  110,
                  102,
                  105,
                  103
                ]
              }
            ]
          }
        }
      ],
      "args": [
        {
          "name": "authority",
          "type": "pubkey"
        },
        {
          "name": "operator",
          "type": "pubkey"
        }
      ]
    },
    {
      "name": "set_interest_rate_bps",
      "docs": [
        "Restate an asset's declared rate after a reset. Admin only.",
        "",
        "The record, not the economics: the price accrues at rwa_market's Asset.rate_bps and",
        "nothing pays from this value. It had no setter, so gNTB kept declaring 1550 here after",
        "its Market rate was reset to 1450 on 2026-09-28 — the Token-2022 metadata field and the",
        "EVM token were both corrected, this was the one record that could not be.",
        "",
        "Non-zero to non-zero only, for the reason the EVM setter gives: rwa_market::set_rate",
        "reads a 0 here as \"this instrument earns nothing\" and refuses it a rate, which is what",
        "stops an equity accruing. Turning 0 into a rate would switch that guard off, and turning",
        "a rate into 0 would leave a live Market rate on an asset declaring none. Whether an",
        "asset accrues is fixed at create_asset; this only corrects how much."
      ],
      "discriminator": [
        49,
        175,
        75,
        33,
        90,
        196,
        154,
        54
      ],
      "accounts": [
        {
          "name": "admin",
          "signer": true
        },
        {
          "name": "meta",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  109,
                  101,
                  116,
                  97
                ]
              },
              {
                "kind": "account",
                "path": "meta.mint",
                "account": "TokenMeta"
              }
            ]
          }
        }
      ],
      "args": [
        {
          "name": "interest_rate_bps",
          "type": "u16"
        }
      ]
    },
    {
      "name": "set_maturity_date",
      "docs": [
        "Correct an asset's maturity date. Admin only.",
        "",
        "There was no way to change this, and the data is already wrong on mainnet: DPRI is an",
        "equity and carries maturity_date 2027-09-14 here while the same deal on Base carries 0.",
        "That is not cosmetic — rwa_market::require_not_matured REFUSES ALL TRADING once a",
        "non-zero maturity passes, so DPRI would simply stop trading on Solana in 2027 while",
        "continuing on Base. `0` means perpetual, which is what an equity should be.",
        "",
        "Deliberately does not touch the Market's cached `maturity_ts`: that is a copy taken by",
        "set_rate for the accrual clamp, and re-running set_rate refreshes it. Writing through to",
        "another program's account from here would be worse than the staleness."
      ],
      "discriminator": [
        102,
        12,
        194,
        47,
        22,
        208,
        21,
        165
      ],
      "accounts": [
        {
          "name": "admin",
          "signer": true
        },
        {
          "name": "meta",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  109,
                  101,
                  116,
                  97
                ]
              },
              {
                "kind": "account",
                "path": "meta.mint",
                "account": "TokenMeta"
              }
            ]
          }
        }
      ],
      "args": [
        {
          "name": "maturity_date",
          "type": "i64"
        }
      ]
    },
    {
      "name": "set_max_supply",
      "docs": [
        "Arm (or raise) the supply ceiling for this asset. Admin only. 0 = uncapped.",
        "",
        "Rejects a cap below what is already minted — that would be a cap the chain has",
        "already breached, leaving the asset in a state no future mint could repair.",
        "Set this at issuance to the issue size; assets created before this field existed",
        "default to 0 and must be armed explicitly."
      ],
      "discriminator": [
        16,
        207,
        140,
        77,
        107,
        20,
        202,
        158
      ],
      "accounts": [
        {
          "name": "admin",
          "signer": true
        },
        {
          "name": "meta",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  109,
                  101,
                  116,
                  97
                ]
              },
              {
                "kind": "account",
                "path": "meta.mint",
                "account": "TokenMeta"
              }
            ]
          }
        },
        {
          "name": "mint"
        }
      ],
      "args": [
        {
          "name": "max_supply",
          "type": "u64"
        }
      ]
    },
    {
      "name": "set_payout_token",
      "docs": [
        "Update the payout mint. Admin only. Mirrors setPayoutTokenOnToken()."
      ],
      "discriminator": [
        169,
        93,
        35,
        201,
        68,
        168,
        82,
        96
      ],
      "accounts": [
        {
          "name": "admin",
          "signer": true
        },
        {
          "name": "meta",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  109,
                  101,
                  116,
                  97
                ]
              },
              {
                "kind": "account",
                "path": "meta.mint",
                "account": "TokenMeta"
              }
            ]
          }
        }
      ],
      "args": [
        {
          "name": "payout_token",
          "type": "pubkey"
        }
      ]
    },
    {
      "name": "set_vault",
      "docs": [
        "Record the vault PDA/pubkey for this asset. Admin only. Mirrors setVault()."
      ],
      "discriminator": [
        177,
        23,
        187,
        59,
        247,
        215,
        255,
        162
      ],
      "accounts": [
        {
          "name": "admin",
          "signer": true
        },
        {
          "name": "meta",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  109,
                  101,
                  116,
                  97
                ]
              },
              {
                "kind": "account",
                "path": "meta.mint",
                "account": "TokenMeta"
              }
            ]
          }
        }
      ],
      "args": [
        {
          "name": "vault",
          "type": "pubkey"
        }
      ]
    },
    {
      "name": "sync_admin",
      "docs": [
        "Re-point this account's `admin` at the CURRENT `config.authority`.",
        "",
        "SECURITY-AUDIT M-1: every per-asset admin was written once at creation and never again,",
        "so rotating the Squad left every existing asset pointing at the old multisig — and the",
        "more assets exist, the worse that gets. `set_config_authority` moves the program-level",
        "authority; this carries the change down to accounts that already exist.",
        "",
        "The new value is READ FROM CONFIG, never supplied by the caller, so this can only ever",
        "converge an account onto the current authority. It cannot redirect one anywhere else,",
        "which is why gating it on the operator is enough — there is no value here to abuse."
      ],
      "discriminator": [
        39,
        26,
        200,
        133,
        62,
        114,
        42,
        235
      ],
      "accounts": [
        {
          "name": "config",
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  99,
                  111,
                  110,
                  102,
                  105,
                  103
                ]
              }
            ]
          }
        },
        {
          "name": "signer",
          "signer": true
        },
        {
          "name": "meta",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  109,
                  101,
                  116,
                  97
                ]
              },
              {
                "kind": "account",
                "path": "meta.mint",
                "account": "TokenMeta"
              }
            ]
          }
        }
      ],
      "args": []
    }
  ],
  "accounts": [
    {
      "name": "Config",
      "discriminator": [
        155,
        12,
        170,
        224,
        30,
        250,
        204,
        130
      ]
    },
    {
      "name": "TokenMeta",
      "discriminator": [
        130,
        87,
        174,
        35,
        21,
        44,
        92,
        19
      ]
    }
  ],
  "events": [
    {
      "name": "AdminSynced",
      "discriminator": [
        31,
        149,
        231,
        47,
        182,
        14,
        227,
        231
      ]
    },
    {
      "name": "AssetClosed",
      "discriminator": [
        188,
        16,
        158,
        249,
        202,
        223,
        33,
        216
      ]
    },
    {
      "name": "AssetCreated",
      "discriminator": [
        206,
        193,
        252,
        254,
        207,
        185,
        154,
        4
      ]
    },
    {
      "name": "ConfigSet",
      "discriminator": [
        15,
        104,
        59,
        16,
        236,
        241,
        8,
        6
      ]
    },
    {
      "name": "InterestRateUpdated",
      "discriminator": [
        175,
        35,
        117,
        108,
        182,
        73,
        172,
        114
      ]
    },
    {
      "name": "MaturityUpdated",
      "discriminator": [
        236,
        9,
        89,
        242,
        239,
        141,
        2,
        171
      ]
    },
    {
      "name": "MaxSupplyLowered",
      "discriminator": [
        45,
        110,
        71,
        43,
        144,
        108,
        255,
        23
      ]
    },
    {
      "name": "MaxSupplyRaised",
      "discriminator": [
        88,
        209,
        162,
        11,
        63,
        150,
        235,
        133
      ]
    },
    {
      "name": "Minted",
      "discriminator": [
        174,
        131,
        21,
        57,
        88,
        117,
        114,
        121
      ]
    }
  ],
  "errors": [
    {
      "code": 6000,
      "name": "Unauthorized",
      "msg": "caller is not authorized for this action"
    },
    {
      "code": 6001,
      "name": "InvalidFrequency",
      "msg": "payout frequency must be 0-5"
    },
    {
      "code": 6002,
      "name": "MintAuthorityMismatch",
      "msg": "mint authority must be the asset meta PDA"
    },
    {
      "code": 6003,
      "name": "SupplyCapExceeded",
      "msg": "mint would exceed the asset's supply cap"
    },
    {
      "code": 6004,
      "name": "SupplyCapBelowMinted",
      "msg": "supply cap cannot be below the already-minted supply"
    },
    {
      "code": 6005,
      "name": "MathOverflow",
      "msg": "arithmetic overflow"
    },
    {
      "code": 6006,
      "name": "MintDestinationNotVault",
      "msg": "mint destination must be the asset vault; investors receive via the market"
    },
    {
      "code": 6007,
      "name": "VaultNotSet",
      "msg": "set_vault must run before minting"
    },
    {
      "code": 6008,
      "name": "StringTooLong",
      "msg": "string field exceeds its byte budget in TokenMeta (64, or 120 for deal_url)"
    },
    {
      "code": 6009,
      "name": "InvalidMaturity",
      "msg": "maturity date cannot be negative"
    },
    {
      "code": 6010,
      "name": "AssetHasSupply",
      "msg": "asset has supply and cannot be closed"
    },
    {
      "code": 6011,
      "name": "AssetHasVault",
      "msg": "asset has a vault set and is not an abandoned listing"
    },
    {
      "code": 6012,
      "name": "RateNotDeclared",
      "msg": "asset declares no rate; whether it accrues is fixed at create_asset"
    },
    {
      "code": 6013,
      "name": "RateCannotBeCleared",
      "msg": "a declared rate cannot be cleared to 0"
    },
    {
      "code": 6014,
      "name": "RateTooHigh",
      "msg": "interest rate must be <= 10000 bps"
    },
    {
      "code": 6015,
      "name": "UseSetMaxSupplyToUncap",
      "msg": "0 means uncapped; use set_max_supply to remove a ceiling"
    },
    {
      "code": 6016,
      "name": "NotAReduction",
      "msg": "new ceiling is not below the current one"
    }
  ],
  "types": [
    {
      "name": "AdminSynced",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "previous",
            "type": "pubkey"
          },
          {
            "name": "current",
            "type": "pubkey"
          }
        ]
      }
    },
    {
      "name": "AssetClosed",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "mint",
            "type": "pubkey"
          }
        ]
      }
    },
    {
      "name": "AssetCreated",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "mint",
            "type": "pubkey"
          },
          {
            "name": "admin",
            "type": "pubkey"
          }
        ]
      }
    },
    {
      "name": "AssetParams",
      "docs": [
        "RWA asset fields — the Solana twin of the EVM tokenParams struct."
      ],
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "payout_token",
            "type": "pubkey"
          },
          {
            "name": "name",
            "type": "string"
          },
          {
            "name": "symbol",
            "type": "string"
          },
          {
            "name": "issuer",
            "type": "string"
          },
          {
            "name": "deal_url",
            "type": "string"
          },
          {
            "name": "investment_type",
            "type": "u8"
          },
          {
            "name": "investment_category",
            "type": "u8"
          },
          {
            "name": "payout_frequency",
            "type": "u8"
          },
          {
            "name": "token_entity_type",
            "type": "u8"
          },
          {
            "name": "interest_rate_bps",
            "type": "u16"
          },
          {
            "name": "maturity_date",
            "type": "i64"
          },
          {
            "name": "tenor_days",
            "type": "u32"
          },
          {
            "name": "max_supply",
            "docs": [
              "Issue size ceiling in smallest units; 0 = uncapped. Set here rather than only via",
              "`set_max_supply` so the cap is armed atomically at creation — `set_max_supply`",
              "needs the admin signer, which is the Squads vault under governance and therefore",
              "cannot be called inline by the operator during issuance."
            ],
            "type": "u64"
          }
        ]
      }
    },
    {
      "name": "Config",
      "docs": [
        "Program-level authority. One per program, seeds [\"config\"].",
        "",
        "Exists because every per-asset `init` instruction used to accept an unconstrained `Signer`",
        "as \"admin\" and write it straight into the new account, making whoever called first the",
        "owner of a PDA our own flow would later fund. See C-1..C-5 in SECURITY-AUDIT.md."
      ],
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "authority",
            "docs": [
              "Governing authority — the Squads vault PDA. Written into every per-asset account's",
              "admin/owner field, so a caller can never nominate itself."
            ],
            "type": "pubkey"
          },
          {
            "name": "operator",
            "docs": [
              "Operator hot key. May CREATE per-asset accounts and pay their rent, but never chooses",
              "who controls them."
            ],
            "type": "pubkey"
          },
          {
            "name": "bump",
            "type": "u8"
          }
        ]
      }
    },
    {
      "name": "ConfigSet",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "authority",
            "type": "pubkey"
          },
          {
            "name": "operator",
            "type": "pubkey"
          }
        ]
      }
    },
    {
      "name": "InterestRateUpdated",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "mint",
            "type": "pubkey"
          },
          {
            "name": "old",
            "type": "u16"
          },
          {
            "name": "new",
            "type": "u16"
          }
        ]
      }
    },
    {
      "name": "MaturityUpdated",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "mint",
            "type": "pubkey"
          },
          {
            "name": "old",
            "type": "i64"
          },
          {
            "name": "new",
            "type": "i64"
          }
        ]
      }
    },
    {
      "name": "MaxSupplyLowered",
      "docs": [
        "A ceiling that came DOWN, from `set_max_supply` or from the operator's emergency stop."
      ],
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "mint",
            "type": "pubkey"
          },
          {
            "name": "previous",
            "type": "u64"
          },
          {
            "name": "current",
            "type": "u64"
          }
        ]
      }
    },
    {
      "name": "MaxSupplyRaised",
      "docs": [
        "A ceiling that went UP, or came off entirely. Split from the fall deliberately: this is the",
        "one a watcher alarms on, and Base splits its events the same way.",
        "",
        "Field comments are `//` rather than `///` for the reason given on `Minted` above."
      ],
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "mint",
            "type": "pubkey"
          },
          {
            "name": "previous",
            "type": "u64"
          },
          {
            "name": "current",
            "type": "u64"
          }
        ]
      }
    },
    {
      "name": "Minted",
      "docs": [
        "Issuance, said out loud.",
        "",
        "NOTE: the field comments below are `//`, not `///`, DELIBERATELY. Anchor 0.31.1's IDL",
        "builder drops an `#[event]` struct from BOTH `events` and `types` when any of its FIELDS",
        "carries a doc comment — silently, with a successful build. That is how this event and",
        "`MaxSupplyUpdated` vanished from the regenerated IDL while remaining in the source, and the",
        "backend's onchain.mint.executed indexer keys on exactly this event. Struct-level docs like",
        "this one are fine; field-level ones are not. Check `events` after regenerating (R4-7)."
      ],
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "mint",
            "type": "pubkey"
          },
          {
            "name": "to",
            "type": "pubkey"
          },
          {
            "name": "owner",
            "type": "pubkey"
          },
          {
            "name": "amount",
            "type": "u64"
          },
          {
            "name": "total_supply",
            "type": "u64"
          }
        ]
      }
    },
    {
      "name": "TokenMeta",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "mint",
            "type": "pubkey"
          },
          {
            "name": "admin",
            "type": "pubkey"
          },
          {
            "name": "minter",
            "type": "pubkey"
          },
          {
            "name": "automation",
            "type": "pubkey"
          },
          {
            "name": "vault",
            "type": "pubkey"
          },
          {
            "name": "payout_token",
            "type": "pubkey"
          },
          {
            "name": "name",
            "type": "string"
          },
          {
            "name": "symbol",
            "type": "string"
          },
          {
            "name": "issuer",
            "type": "string"
          },
          {
            "name": "deal_url",
            "type": "string"
          },
          {
            "name": "investment_type",
            "type": "u8"
          },
          {
            "name": "investment_category",
            "type": "u8"
          },
          {
            "name": "payout_frequency",
            "type": "u8"
          },
          {
            "name": "token_entity_type",
            "type": "u8"
          },
          {
            "name": "interest_rate_bps",
            "type": "u16"
          },
          {
            "name": "maturity_date",
            "type": "i64"
          },
          {
            "name": "tenor_days",
            "type": "u32"
          },
          {
            "name": "decimals",
            "type": "u8"
          },
          {
            "name": "bump",
            "type": "u8"
          },
          {
            "name": "max_supply",
            "docs": [
              "Hard ceiling on total minted supply, in smallest units. 0 = uncapped.",
              "",
              "Appended after `bump` deliberately: MAX_SIZE already over-allocates by 64 bytes,",
              "and account data is zero-initialised, so meta accounts created before this field",
              "existed deserialise it as 0 (uncapped) rather than failing. No migration needed —",
              "call `set_max_supply` to arm the cap on an existing asset."
            ],
            "type": "u64"
          }
        ]
      }
    }
  ]
}