{
  "address": "FxmpWaFwkyqWug7hmPTaHWWqZTqevSunr3q9WJp5MYvD",
  "metadata": {
    "name": "anvora",
    "version": "1.0.0",
    "spec": "0.1.0",
    "description": "Anchor program for prelaunch-only bonding-curve fundraising on Solana"
  },
  "instructions": [
    {
      "name": "accept_protocol_authority",
      "discriminator": [
        237,
        122,
        6,
        39,
        53,
        202,
        141,
        113
      ],
      "accounts": [
        {
          "name": "new_authority",
          "docs": [
            "Must equal the staged `pending_authority` and sign it. Without this",
            "co-signature the rotation stays staged and never takes effect."
          ],
          "signer": true
        },
        {
          "name": "protocol_treasury",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  112,
                  114,
                  111,
                  116,
                  111,
                  99,
                  111,
                  108,
                  95,
                  116,
                  114,
                  101,
                  97,
                  115,
                  117,
                  114,
                  121
                ]
              }
            ]
          }
        },
        {
          "name": "event_authority"
        },
        {
          "name": "program"
        }
      ],
      "args": []
    },
    {
      "name": "buy",
      "discriminator": [
        102,
        6,
        61,
        18,
        1,
        218,
        235,
        234
      ],
      "accounts": [
        {
          "name": "buyer",
          "writable": true,
          "signer": true
        },
        {
          "name": "campaign",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  99,
                  97,
                  109,
                  112,
                  97,
                  105,
                  103,
                  110
                ]
              },
              {
                "kind": "account",
                "path": "campaign.creator",
                "account": "Campaign"
              },
              {
                "kind": "account",
                "path": "campaign.slug",
                "account": "Campaign"
              }
            ]
          }
        },
        {
          "name": "mint",
          "writable": true
        },
        {
          "name": "vault",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "account",
                "path": "campaign"
              },
              {
                "kind": "account",
                "path": "token_program"
              },
              {
                "kind": "account",
                "path": "mint"
              }
            ],
            "program": {
              "kind": "const",
              "value": [
                140,
                151,
                37,
                143,
                78,
                36,
                137,
                241,
                187,
                61,
                16,
                41,
                20,
                142,
                13,
                131,
                11,
                90,
                19,
                153,
                218,
                255,
                16,
                132,
                4,
                142,
                123,
                216,
                219,
                233,
                248,
                89
              ]
            }
          }
        },
        {
          "name": "buyer_campaign_ata",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "account",
                "path": "buyer"
              },
              {
                "kind": "account",
                "path": "token_program"
              },
              {
                "kind": "account",
                "path": "mint"
              }
            ],
            "program": {
              "kind": "const",
              "value": [
                140,
                151,
                37,
                143,
                78,
                36,
                137,
                241,
                187,
                61,
                16,
                41,
                20,
                142,
                13,
                131,
                11,
                90,
                19,
                153,
                218,
                255,
                16,
                132,
                4,
                142,
                123,
                216,
                219,
                233,
                248,
                89
              ]
            }
          }
        },
        {
          "name": "token_program"
        },
        {
          "name": "associated_token_program",
          "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
        },
        {
          "name": "system_program",
          "address": "11111111111111111111111111111111"
        },
        {
          "name": "event_authority"
        },
        {
          "name": "program"
        }
      ],
      "args": [
        {
          "name": "token_amount",
          "type": "u64"
        },
        {
          "name": "max_sol_cost",
          "type": "u64"
        }
      ]
    },
    {
      "name": "claim_referral_fees",
      "discriminator": [
        208,
        216,
        137,
        78,
        36,
        103,
        162,
        49
      ],
      "accounts": [
        {
          "name": "referrer",
          "docs": [
            "Must own the vault and sign. The `seeds` derivation below already binds",
            "the vault to this key; the stored `referrer` is checked too so the two can",
            "never drift apart."
          ],
          "signer": true
        },
        {
          "name": "referral_vault",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  114,
                  101,
                  102,
                  101,
                  114,
                  114,
                  97,
                  108,
                  95,
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "referrer"
              }
            ]
          }
        },
        {
          "name": "destination",
          "docs": [
            "constrained to differ from the vault itself: aliasing the two would net to",
            "a no-op while still emitting a claim event for lamports that never moved."
          ],
          "writable": true
        },
        {
          "name": "event_authority"
        },
        {
          "name": "program"
        }
      ],
      "args": []
    },
    {
      "name": "claim_revenue",
      "discriminator": [
        4,
        22,
        151,
        70,
        183,
        79,
        73,
        189
      ],
      "accounts": [
        {
          "name": "user",
          "writable": true,
          "signer": true
        },
        {
          "name": "campaign",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  99,
                  97,
                  109,
                  112,
                  97,
                  105,
                  103,
                  110
                ]
              },
              {
                "kind": "account",
                "path": "campaign.creator",
                "account": "Campaign"
              },
              {
                "kind": "account",
                "path": "campaign.slug",
                "account": "Campaign"
              }
            ]
          }
        },
        {
          "name": "stake_position",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  115,
                  116,
                  97,
                  107,
                  101,
                  95,
                  112,
                  111,
                  115,
                  105,
                  116,
                  105,
                  111,
                  110
                ]
              },
              {
                "kind": "account",
                "path": "campaign"
              },
              {
                "kind": "account",
                "path": "user"
              }
            ]
          }
        },
        {
          "name": "revenue_vault",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  114,
                  101,
                  118,
                  101,
                  110,
                  117,
                  101,
                  95,
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "campaign"
              }
            ]
          }
        },
        {
          "name": "event_authority"
        },
        {
          "name": "program"
        }
      ],
      "args": []
    },
    {
      "name": "close_position",
      "discriminator": [
        123,
        134,
        81,
        0,
        49,
        68,
        98,
        98
      ],
      "accounts": [
        {
          "name": "staker",
          "writable": true,
          "signer": true
        },
        {
          "name": "campaign",
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  99,
                  97,
                  109,
                  112,
                  97,
                  105,
                  103,
                  110
                ]
              },
              {
                "kind": "account",
                "path": "campaign.creator",
                "account": "Campaign"
              },
              {
                "kind": "account",
                "path": "campaign.slug",
                "account": "Campaign"
              }
            ]
          }
        },
        {
          "name": "stake_position",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  115,
                  116,
                  97,
                  107,
                  101,
                  95,
                  112,
                  111,
                  115,
                  105,
                  116,
                  105,
                  111,
                  110
                ]
              },
              {
                "kind": "account",
                "path": "campaign"
              },
              {
                "kind": "account",
                "path": "staker"
              }
            ]
          }
        }
      ],
      "args": []
    },
    {
      "name": "create_campaign",
      "discriminator": [
        111,
        131,
        187,
        98,
        160,
        193,
        114,
        244
      ],
      "accounts": [
        {
          "name": "creator",
          "writable": true,
          "signer": true
        },
        {
          "name": "protocol_treasury",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  112,
                  114,
                  111,
                  116,
                  111,
                  99,
                  111,
                  108,
                  95,
                  116,
                  114,
                  101,
                  97,
                  115,
                  117,
                  114,
                  121
                ]
              }
            ]
          }
        },
        {
          "name": "campaign",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  99,
                  97,
                  109,
                  112,
                  97,
                  105,
                  103,
                  110
                ]
              },
              {
                "kind": "account",
                "path": "creator"
              },
              {
                "kind": "arg",
                "path": "args.slug"
              }
            ]
          }
        },
        {
          "name": "mint",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  109,
                  105,
                  110,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "campaign"
              }
            ]
          }
        },
        {
          "name": "vault",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "account",
                "path": "campaign"
              },
              {
                "kind": "account",
                "path": "token_program"
              },
              {
                "kind": "account",
                "path": "mint"
              }
            ],
            "program": {
              "kind": "const",
              "value": [
                140,
                151,
                37,
                143,
                78,
                36,
                137,
                241,
                187,
                61,
                16,
                41,
                20,
                142,
                13,
                131,
                11,
                90,
                19,
                153,
                218,
                255,
                16,
                132,
                4,
                142,
                123,
                216,
                219,
                233,
                248,
                89
              ]
            }
          }
        },
        {
          "name": "stake_vault",
          "docs": [
            "Per-campaign stake vault, created up front so the first staker pays no",
            "account-creation cost (the creator funds it at launch — this removes the",
            "\"wait for someone else to stake first\" disincentive). PDA owned by the",
            "campaign so `stake`/`unstake` move tokens in and out. Custodies the sum",
            "of every staker's tokens."
          ],
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  115,
                  116,
                  97,
                  107,
                  101,
                  95,
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "campaign"
              }
            ]
          }
        },
        {
          "name": "revenue_vault",
          "docs": [
            "RevenueVault PDA, created up front so revenue can flow from the first",
            "sell onwards. It receives the holder share of every sell and every",
            "`deposit_revenue`, and pays claims in either phase."
          ],
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  114,
                  101,
                  118,
                  101,
                  110,
                  117,
                  101,
                  95,
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "campaign"
              }
            ]
          }
        },
        {
          "name": "referral_vault",
          "docs": [
            "Escrow for the creator's referrer, created here so the cut at settle never",
            "has to touch an address the creator did not author. Required exactly when",
            "`args.referral` is set, and forbidden otherwise — the handler enforces both",
            "directions.",
            "",
            "`init_if_needed` because the vault is global per referrer, not per campaign:",
            "a referrer working with several creators keeps a single vault, and only the",
            "first campaign naming them pays its rent. The handler detects that first",
            "creation with the zeroed-`referrer` sentinel and charges the rent only then."
          ],
          "writable": true,
          "optional": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  114,
                  101,
                  102,
                  101,
                  114,
                  114,
                  97,
                  108,
                  95,
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "arg",
                "path": "args.referral"
              }
            ]
          }
        },
        {
          "name": "token_program"
        },
        {
          "name": "associated_token_program",
          "address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
        },
        {
          "name": "system_program",
          "address": "11111111111111111111111111111111"
        },
        {
          "name": "event_authority"
        },
        {
          "name": "program"
        }
      ],
      "args": [
        {
          "name": "args",
          "type": {
            "defined": {
              "name": "CreateCampaignArgs"
            }
          }
        }
      ]
    },
    {
      "name": "deposit_revenue",
      "discriminator": [
        224,
        212,
        82,
        100,
        60,
        240,
        220,
        29
      ],
      "accounts": [
        {
          "name": "depositor",
          "writable": true,
          "signer": true
        },
        {
          "name": "campaign",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  99,
                  97,
                  109,
                  112,
                  97,
                  105,
                  103,
                  110
                ]
              },
              {
                "kind": "account",
                "path": "campaign.creator",
                "account": "Campaign"
              },
              {
                "kind": "account",
                "path": "campaign.slug",
                "account": "Campaign"
              }
            ]
          }
        },
        {
          "name": "revenue_vault",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  114,
                  101,
                  118,
                  101,
                  110,
                  117,
                  101,
                  95,
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "campaign"
              }
            ]
          }
        },
        {
          "name": "system_program",
          "address": "11111111111111111111111111111111"
        },
        {
          "name": "event_authority"
        },
        {
          "name": "program"
        }
      ],
      "args": [
        {
          "name": "amount",
          "type": "u64"
        }
      ]
    },
    {
      "name": "initialize_protocol_treasury",
      "discriminator": [
        125,
        148,
        53,
        197,
        136,
        81,
        65,
        58
      ],
      "accounts": [
        {
          "name": "payer",
          "writable": true,
          "signer": true
        },
        {
          "name": "program",
          "address": "FxmpWaFwkyqWug7hmPTaHWWqZTqevSunr3q9WJp5MYvD"
        },
        {
          "name": "program_data"
        },
        {
          "name": "protocol_treasury",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  112,
                  114,
                  111,
                  116,
                  111,
                  99,
                  111,
                  108,
                  95,
                  116,
                  114,
                  101,
                  97,
                  115,
                  117,
                  114,
                  121
                ]
              }
            ]
          }
        },
        {
          "name": "system_program",
          "address": "11111111111111111111111111111111"
        }
      ],
      "args": []
    },
    {
      "name": "rotate_protocol_authority",
      "discriminator": [
        102,
        188,
        108,
        203,
        228,
        162,
        128,
        196
      ],
      "accounts": [
        {
          "name": "current_authority",
          "signer": true
        },
        {
          "name": "protocol_treasury",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  112,
                  114,
                  111,
                  116,
                  111,
                  99,
                  111,
                  108,
                  95,
                  116,
                  114,
                  101,
                  97,
                  115,
                  117,
                  114,
                  121
                ]
              }
            ]
          }
        },
        {
          "name": "event_authority"
        },
        {
          "name": "program"
        }
      ],
      "args": [
        {
          "name": "new_authority",
          "type": "pubkey"
        }
      ]
    },
    {
      "name": "sell",
      "discriminator": [
        51,
        230,
        133,
        164,
        1,
        127,
        131,
        173
      ],
      "accounts": [
        {
          "name": "seller",
          "writable": true,
          "signer": true
        },
        {
          "name": "campaign",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  99,
                  97,
                  109,
                  112,
                  97,
                  105,
                  103,
                  110
                ]
              },
              {
                "kind": "account",
                "path": "campaign.creator",
                "account": "Campaign"
              },
              {
                "kind": "account",
                "path": "campaign.slug",
                "account": "Campaign"
              }
            ]
          }
        },
        {
          "name": "mint",
          "writable": true
        },
        {
          "name": "vault",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "account",
                "path": "campaign"
              },
              {
                "kind": "account",
                "path": "token_program"
              },
              {
                "kind": "account",
                "path": "mint"
              }
            ],
            "program": {
              "kind": "const",
              "value": [
                140,
                151,
                37,
                143,
                78,
                36,
                137,
                241,
                187,
                61,
                16,
                41,
                20,
                142,
                13,
                131,
                11,
                90,
                19,
                153,
                218,
                255,
                16,
                132,
                4,
                142,
                123,
                216,
                219,
                233,
                248,
                89
              ]
            }
          }
        },
        {
          "name": "seller_campaign_ata",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "account",
                "path": "seller"
              },
              {
                "kind": "account",
                "path": "token_program"
              },
              {
                "kind": "account",
                "path": "mint"
              }
            ],
            "program": {
              "kind": "const",
              "value": [
                140,
                151,
                37,
                143,
                78,
                36,
                137,
                241,
                187,
                61,
                16,
                41,
                20,
                142,
                13,
                131,
                11,
                90,
                19,
                153,
                218,
                255,
                16,
                132,
                4,
                142,
                123,
                216,
                219,
                233,
                248,
                89
              ]
            }
          }
        },
        {
          "name": "revenue_vault",
          "docs": [
            "Receives the holder cut as it is earned. Per-campaign, so naming it here",
            "costs nothing in contention — unlike the protocol treasury, which is",
            "global and is deliberately not in this list."
          ],
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  114,
                  101,
                  118,
                  101,
                  110,
                  117,
                  101,
                  95,
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "campaign"
              }
            ]
          }
        },
        {
          "name": "token_program"
        },
        {
          "name": "event_authority"
        },
        {
          "name": "program"
        }
      ],
      "args": [
        {
          "name": "token_amount",
          "type": "u64"
        },
        {
          "name": "min_sol_output",
          "type": "u64"
        }
      ]
    },
    {
      "name": "settle",
      "discriminator": [
        175,
        42,
        185,
        87,
        144,
        131,
        102,
        212
      ],
      "accounts": [
        {
          "name": "caller",
          "docs": [
            "The wallet signing the TX and paying for it. Always receives the bounty,",
            "including when it is the campaign's creator."
          ],
          "writable": true,
          "signer": true
        },
        {
          "name": "campaign",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  99,
                  97,
                  109,
                  112,
                  97,
                  105,
                  103,
                  110
                ]
              },
              {
                "kind": "account",
                "path": "campaign.creator",
                "account": "Campaign"
              },
              {
                "kind": "account",
                "path": "campaign.slug",
                "account": "Campaign"
              }
            ]
          }
        },
        {
          "name": "creator",
          "docs": [
            "`address` constraint forces it to match the on-chain stored creator,",
            "so a malicious caller cannot redirect the creator's share elsewhere."
          ],
          "writable": true
        },
        {
          "name": "protocol_treasury",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  112,
                  114,
                  111,
                  116,
                  111,
                  99,
                  111,
                  108,
                  95,
                  116,
                  114,
                  101,
                  97,
                  115,
                  117,
                  114,
                  121
                ]
              }
            ]
          }
        },
        {
          "name": "mint",
          "writable": true
        },
        {
          "name": "vault",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "account",
                "path": "campaign"
              },
              {
                "kind": "account",
                "path": "token_program"
              },
              {
                "kind": "account",
                "path": "mint"
              }
            ],
            "program": {
              "kind": "const",
              "value": [
                140,
                151,
                37,
                143,
                78,
                36,
                137,
                241,
                187,
                61,
                16,
                41,
                20,
                142,
                13,
                131,
                11,
                90,
                19,
                153,
                218,
                255,
                16,
                132,
                4,
                142,
                123,
                216,
                219,
                233,
                248,
                89
              ]
            }
          }
        },
        {
          "name": "revenue_vault",
          "docs": [
            "RevenueVault PDA, already created at `create_campaign`. Settle neither",
            "credits nor drains it: every entitlement was fixed when the money arrived,",
            "and the lamports followed at the same time. Named here only so the",
            "campaign's stored key is re-affirmed at settlement."
          ],
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  114,
                  101,
                  118,
                  101,
                  110,
                  117,
                  101,
                  95,
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "campaign"
              }
            ]
          }
        },
        {
          "name": "token_program"
        },
        {
          "name": "referral_vault",
          "docs": [
            "Escrow for the creator's referrer, created at `create_campaign`. Required",
            "exactly when `campaign.creator_referrer` is set, and forbidden otherwise.",
            "",
            "This is a program-derived address, not the referrer's wallet, and that is",
            "the point. Settle is permissionless, so a caller must not be able to skip",
            "the payout by omitting an account; and settle is the only instruction that",
            "can close a campaign, so no address the creator did not author may sit in",
            "its critical path — a referral link carrying a poisoned address would",
            "otherwise freeze a campaign whose creator did nothing wrong. Deriving the",
            "vault from `campaign.creator_referrer` closes both directions at once."
          ],
          "writable": true,
          "optional": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  114,
                  101,
                  102,
                  101,
                  114,
                  114,
                  97,
                  108,
                  95,
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "campaign.creator_referrer",
                "account": "Campaign"
              }
            ]
          }
        },
        {
          "name": "event_authority"
        },
        {
          "name": "program"
        }
      ],
      "args": []
    },
    {
      "name": "stake",
      "discriminator": [
        206,
        176,
        202,
        18,
        200,
        209,
        179,
        108
      ],
      "accounts": [
        {
          "name": "staker",
          "writable": true,
          "signer": true
        },
        {
          "name": "campaign",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  99,
                  97,
                  109,
                  112,
                  97,
                  105,
                  103,
                  110
                ]
              },
              {
                "kind": "account",
                "path": "campaign.creator",
                "account": "Campaign"
              },
              {
                "kind": "account",
                "path": "campaign.slug",
                "account": "Campaign"
              }
            ]
          }
        },
        {
          "name": "mint"
        },
        {
          "name": "staker_ata",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "account",
                "path": "staker"
              },
              {
                "kind": "account",
                "path": "token_program"
              },
              {
                "kind": "account",
                "path": "mint"
              }
            ],
            "program": {
              "kind": "const",
              "value": [
                140,
                151,
                37,
                143,
                78,
                36,
                137,
                241,
                187,
                61,
                16,
                41,
                20,
                142,
                13,
                131,
                11,
                90,
                19,
                153,
                218,
                255,
                16,
                132,
                4,
                142,
                123,
                216,
                219,
                233,
                248,
                89
              ]
            }
          }
        },
        {
          "name": "stake_vault",
          "docs": [
            "Single per-campaign vault custodying every staker's tokens. Created up",
            "front at `create_campaign` (funded by the creator, so the first staker",
            "pays nothing extra); authority is the campaign PDA so `unstake` can pay",
            "back out."
          ],
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  115,
                  116,
                  97,
                  107,
                  101,
                  95,
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "campaign"
              }
            ]
          }
        },
        {
          "name": "stake_position",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  115,
                  116,
                  97,
                  107,
                  101,
                  95,
                  112,
                  111,
                  115,
                  105,
                  116,
                  105,
                  111,
                  110
                ]
              },
              {
                "kind": "account",
                "path": "campaign"
              },
              {
                "kind": "account",
                "path": "staker"
              }
            ]
          }
        },
        {
          "name": "token_program"
        },
        {
          "name": "system_program",
          "address": "11111111111111111111111111111111"
        },
        {
          "name": "event_authority"
        },
        {
          "name": "program"
        }
      ],
      "args": [
        {
          "name": "amount",
          "type": "u64"
        }
      ]
    },
    {
      "name": "unstake",
      "discriminator": [
        90,
        95,
        107,
        42,
        205,
        124,
        50,
        225
      ],
      "accounts": [
        {
          "name": "staker",
          "writable": true,
          "signer": true
        },
        {
          "name": "campaign",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  99,
                  97,
                  109,
                  112,
                  97,
                  105,
                  103,
                  110
                ]
              },
              {
                "kind": "account",
                "path": "campaign.creator",
                "account": "Campaign"
              },
              {
                "kind": "account",
                "path": "campaign.slug",
                "account": "Campaign"
              }
            ]
          }
        },
        {
          "name": "mint"
        },
        {
          "name": "staker_ata",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "account",
                "path": "staker"
              },
              {
                "kind": "account",
                "path": "token_program"
              },
              {
                "kind": "account",
                "path": "mint"
              }
            ],
            "program": {
              "kind": "const",
              "value": [
                140,
                151,
                37,
                143,
                78,
                36,
                137,
                241,
                187,
                61,
                16,
                41,
                20,
                142,
                13,
                131,
                11,
                90,
                19,
                153,
                218,
                255,
                16,
                132,
                4,
                142,
                123,
                216,
                219,
                233,
                248,
                89
              ]
            }
          }
        },
        {
          "name": "stake_vault",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  115,
                  116,
                  97,
                  107,
                  101,
                  95,
                  118,
                  97,
                  117,
                  108,
                  116
                ]
              },
              {
                "kind": "account",
                "path": "campaign"
              }
            ]
          }
        },
        {
          "name": "stake_position",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  115,
                  116,
                  97,
                  107,
                  101,
                  95,
                  112,
                  111,
                  115,
                  105,
                  116,
                  105,
                  111,
                  110
                ]
              },
              {
                "kind": "account",
                "path": "campaign"
              },
              {
                "kind": "account",
                "path": "staker"
              }
            ]
          }
        },
        {
          "name": "token_program"
        },
        {
          "name": "event_authority"
        },
        {
          "name": "program"
        }
      ],
      "args": [
        {
          "name": "amount",
          "type": "u64"
        }
      ]
    },
    {
      "name": "withdraw_protocol_fees",
      "discriminator": [
        11,
        68,
        165,
        98,
        18,
        208,
        134,
        73
      ],
      "accounts": [
        {
          "name": "authority",
          "signer": true
        },
        {
          "name": "protocol_treasury",
          "writable": true,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "value": [
                  112,
                  114,
                  111,
                  116,
                  111,
                  99,
                  111,
                  108,
                  95,
                  116,
                  114,
                  101,
                  97,
                  115,
                  117,
                  114,
                  121
                ]
              }
            ]
          }
        },
        {
          "name": "destination",
          "writable": true
        },
        {
          "name": "event_authority"
        },
        {
          "name": "program"
        }
      ],
      "args": []
    }
  ],
  "accounts": [
    {
      "name": "Campaign",
      "discriminator": [
        50,
        40,
        49,
        11,
        157,
        220,
        229,
        192
      ]
    },
    {
      "name": "ProtocolTreasury",
      "discriminator": [
        162,
        26,
        123,
        61,
        102,
        146,
        47,
        73
      ]
    },
    {
      "name": "ReferralVault",
      "discriminator": [
        220,
        195,
        105,
        198,
        64,
        73,
        75,
        240
      ]
    },
    {
      "name": "RevenueVault",
      "discriminator": [
        250,
        185,
        203,
        19,
        174,
        243,
        224,
        181
      ]
    },
    {
      "name": "StakePosition",
      "discriminator": [
        78,
        165,
        30,
        111,
        171,
        125,
        11,
        220
      ]
    }
  ],
  "events": [
    {
      "name": "CampaignBuy",
      "discriminator": [
        122,
        148,
        213,
        227,
        239,
        127,
        93,
        75
      ]
    },
    {
      "name": "CampaignCreated",
      "discriminator": [
        9,
        98,
        69,
        61,
        53,
        131,
        64,
        152
      ]
    },
    {
      "name": "CampaignSell",
      "discriminator": [
        167,
        86,
        179,
        244,
        232,
        228,
        172,
        228
      ]
    },
    {
      "name": "CampaignSettled",
      "discriminator": [
        117,
        145,
        212,
        210,
        201,
        63,
        135,
        24
      ]
    },
    {
      "name": "ProtocolAuthorityRotated",
      "discriminator": [
        128,
        149,
        152,
        210,
        32,
        222,
        155,
        139
      ]
    },
    {
      "name": "ProtocolAuthorityRotationProposed",
      "discriminator": [
        40,
        207,
        114,
        45,
        147,
        59,
        135,
        77
      ]
    },
    {
      "name": "ProtocolFeesWithdrawn",
      "discriminator": [
        202,
        213,
        134,
        216,
        108,
        14,
        84,
        99
      ]
    },
    {
      "name": "ReferralFeesClaimed",
      "discriminator": [
        118,
        130,
        122,
        41,
        74,
        34,
        240,
        48
      ]
    },
    {
      "name": "RevenueClaimed",
      "discriminator": [
        5,
        254,
        104,
        87,
        133,
        137,
        45,
        116
      ]
    },
    {
      "name": "RevenueDeposited",
      "discriminator": [
        97,
        189,
        62,
        159,
        189,
        208,
        43,
        181
      ]
    },
    {
      "name": "Staked",
      "discriminator": [
        11,
        146,
        45,
        205,
        230,
        58,
        213,
        240
      ]
    },
    {
      "name": "Unstaked",
      "discriminator": [
        27,
        179,
        156,
        215,
        47,
        71,
        195,
        7
      ]
    }
  ],
  "errors": [
    {
      "code": 6000,
      "name": "InvalidSlug",
      "msg": "Slug must be 1-32 characters of lowercase letters, digits and hyphens, and cannot start or end with a hyphen."
    },
    {
      "code": 6001,
      "name": "InvalidMetadataUri",
      "msg": "Metadata URI must start with https:// or ipfs://, be at most 128 bytes, and contain only printable ASCII."
    },
    {
      "code": 6002,
      "name": "InvalidCampaignEnd",
      "msg": "The campaign end timestamp must be in the future."
    },
    {
      "code": 6003,
      "name": "CampaignDurationTooShort",
      "msg": "The campaign duration is shorter than the minimum allowed."
    },
    {
      "code": 6004,
      "name": "CampaignDurationTooLong",
      "msg": "The campaign duration is longer than the maximum allowed."
    },
    {
      "code": 6005,
      "name": "InvalidQuantity",
      "msg": "The quantity must be greater than zero."
    },
    {
      "code": 6006,
      "name": "MathOverflow",
      "msg": "Arithmetic overflow."
    },
    {
      "code": 6007,
      "name": "CampaignClosed",
      "msg": "The campaign trading window has not started or is already closed."
    },
    {
      "code": 6008,
      "name": "CampaignExpired",
      "msg": "The campaign trading window has expired; only settlement is allowed now."
    },
    {
      "code": 6009,
      "name": "CampaignAlreadySettled",
      "msg": "The campaign is already settled."
    },
    {
      "code": 6010,
      "name": "CampaignSettledRequired",
      "msg": "The campaign is not settled yet."
    },
    {
      "code": 6011,
      "name": "CampaignNotEnded",
      "msg": "The campaign cannot be settled before the end timestamp."
    },
    {
      "code": 6012,
      "name": "InsufficientCurveLiquidity",
      "msg": "Not enough liquidity remains in the curve."
    },
    {
      "code": 6013,
      "name": "SlippageExceeded",
      "msg": "The slippage limit was exceeded."
    },
    {
      "code": 6014,
      "name": "InvalidRevenueVault",
      "msg": "The provided revenue vault does not match the campaign."
    },
    {
      "code": 6015,
      "name": "NoFundsAvailable",
      "msg": "No funds are currently withdrawable."
    },
    {
      "code": 6016,
      "name": "NoClaimAvailable",
      "msg": "No revenue is currently claimable."
    },
    {
      "code": 6017,
      "name": "NoStakersToReward",
      "msg": "No tokens are staked, so a deposit has no one to distribute to."
    },
    {
      "code": 6018,
      "name": "VaultBalanceMismatch",
      "msg": "The vault balance is inconsistent with the recorded reserves."
    },
    {
      "code": 6019,
      "name": "InvalidStakePositionOwner",
      "msg": "The provided stake position owner does not match the signer."
    },
    {
      "code": 6020,
      "name": "InvalidStakePositionCampaign",
      "msg": "The provided stake position campaign does not match the campaign."
    },
    {
      "code": 6021,
      "name": "Unauthorized",
      "msg": "Signer is not authorized to perform this action."
    },
    {
      "code": 6022,
      "name": "ProtocolUpgradeAuthorityRequired",
      "msg": "Only the program upgrade authority can initialize the protocol treasury."
    },
    {
      "code": 6023,
      "name": "RewardAccountingError",
      "msg": "Reward accounting invariant violated: accumulator < checkpoint."
    },
    {
      "code": 6024,
      "name": "InsufficientStake",
      "msg": "Cannot unstake more than the staked amount."
    },
    {
      "code": 6025,
      "name": "StakeStillActive",
      "msg": "Cannot close a stake position that still has staked tokens."
    },
    {
      "code": 6026,
      "name": "UnclaimedRewards",
      "msg": "Cannot close a stake position with unclaimed rewards."
    },
    {
      "code": 6027,
      "name": "SelfReferral",
      "msg": "A referrer cannot be the same wallet as the referred user."
    },
    {
      "code": 6028,
      "name": "InvalidReferrer",
      "msg": "The provided referral vault does not match the campaign's creator referrer."
    },
    {
      "code": 6029,
      "name": "CreationCostBelowRent",
      "msg": "The fixed creation cost is lower than the rent of the accounts being created."
    },
    {
      "code": 6030,
      "name": "InvalidWithdrawDestination",
      "msg": "The withdrawal destination cannot be the protocol treasury itself."
    },
    {
      "code": 6031,
      "name": "InvalidTokenName",
      "msg": "Token name must be 1-32 bytes, without surrounding whitespace or characters that alter how it renders."
    },
    {
      "code": 6032,
      "name": "InvalidTokenSymbol",
      "msg": "Token symbol must be 2-3 characters of uppercase letters and digits, starting with a letter."
    },
    {
      "code": 6033,
      "name": "MetadataAuthorityInvalid",
      "msg": "The campaign PDA could not be set as the mint metadata update authority."
    }
  ],
  "types": [
    {
      "name": "Campaign",
      "docs": [
        "Persisted campaign state."
      ],
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "creator",
            "type": "pubkey"
          },
          {
            "name": "creator_referrer",
            "docs": [
              "Referrer of the campaign creator. Set once at `create_campaign` from the",
              "app's off-chain attribution; `Pubkey::default()` means none. Read at",
              "`settle` to credit `REFERRAL_SETTLE_BPS` of the protocol's share to that",
              "referrer's vault. Immutable after creation."
            ],
            "type": "pubkey"
          },
          {
            "name": "protocol_treasury",
            "type": "pubkey"
          },
          {
            "name": "mint",
            "type": "pubkey"
          },
          {
            "name": "vault",
            "type": "pubkey"
          },
          {
            "name": "revenue_vault",
            "docs": [
              "Set to the RevenueVault PDA at `create_campaign` (the vault is created",
              "up front so revenue can be deposited during the trading window).",
              "`deposit_revenue` and `claim_revenue` validate against this stored key",
              "in addition to the canonical PDA seeds."
            ],
            "type": "pubkey"
          },
          {
            "name": "slug",
            "type": "string"
          },
          {
            "name": "start_ts",
            "type": "i64"
          },
          {
            "name": "end_ts",
            "type": "i64"
          },
          {
            "name": "settled_at",
            "type": "i64"
          },
          {
            "name": "status",
            "type": {
              "defined": {
                "name": "CampaignStatus"
              }
            }
          },
          {
            "name": "virtual_token_reserves",
            "type": "u64"
          },
          {
            "name": "virtual_sol_reserves",
            "type": "u64"
          },
          {
            "name": "real_token_reserves",
            "type": "u64"
          },
          {
            "name": "real_sol_reserves",
            "type": "u64"
          },
          {
            "name": "total_staked",
            "docs": [
              "Total tokens currently staked across all `StakePosition`s — the",
              "denominator of the reward accumulator, maintained by `stake`/`unstake`."
            ],
            "type": "u64"
          },
          {
            "name": "reward_per_token_accumulator",
            "docs": [
              "Per-token reward accumulator (REWARD_SCALE-scaled). Incremented by",
              "`sell` and `deposit_revenue`; settle never moves it. A staker's",
              "claimable lamports since their last mark =",
              "`staked_amount × (accumulator − reward_checkpoint) / SCALE`,",
              "where `reward_checkpoint` (see StakePosition) stores the accumulator",
              "value last settled against — not `staked × accumulator` — so the",
              "`/ SCALE` flooring happens exactly once at credit time and a tiny-",
              "`total_staked` deposit can't overflow the checkpoint."
            ],
            "type": "u128"
          },
          {
            "name": "carry_revenue_scaled",
            "docs": [
              "Rounding-dust carry, held in the same REWARD_SCALE domain as the",
              "accumulator (not lamports). The remainder of a deposit that cannot be",
              "assigned per-token (`(amount × SCALE + carry) % total_staked`) is kept",
              "here and rolled into the next deposit's `delta` so no value is lost.",
              "Keeping it scaled — rather than re-expressing it as redistributable",
              "lamports — is what stops the fractional part of each `delta` from being",
              "counted twice (once in the carry, again by the once-at-claim flooring),",
              "which previously left the RevenueVault short for the final claimant.",
              "Always strictly less than `total_staked` after an accrue with stakers."
            ],
            "type": "u128"
          },
          {
            "name": "holder_fees_unallocated",
            "docs": [
              "The same fee, collected while nobody was staked. It has no holder to pay,",
              "so it goes to the creator at settlement.",
              "",
              "It is kept apart rather than pooled because pooling it would hand it to",
              "whoever staked next: the carry is flushed on the following accrual, so a",
              "bot could stake one raw unit, wait for a single sell, and take everything",
              "collected before it arrived. Fees with no holder are not a prize."
            ],
            "type": "u64"
          },
          {
            "name": "pending_protocol_revenue",
            "docs": [
              "Accumulator for the protocol portion of sell fees (SELL_FEE_PROTOCOL_BPS),",
              "swept to the treasury at settle. Held on the campaign rather than paid",
              "out per sell, and it",
              "exists for a throughput reason rather than an accounting one.",
              "",
              "Paying the treasury at sell time put a write lock on one global account in",
              "every sell of every campaign. Solana serialises transactions that share a",
              "writable account, so each sell queued behind every other sell in the whole",
              "protocol — campaigns that have nothing to do with each other contending on",
              "a single hot account. Accruing here instead means a sell writes only",
              "campaign-scoped accounts and sells parallelise across campaigns; the",
              "treasury is touched once per campaign, at settle.",
              "",
              "Buys never touched the treasury (no buy fee), so they were already free."
            ],
            "type": "u64"
          },
          {
            "name": "bump",
            "type": "u8"
          },
          {
            "name": "_reserved",
            "docs": [
              "Padding, so a future field costs an upgrade instead of a migration.",
              "",
              "A Solana account's size is fixed at creation. Adding a field to this",
              "struct after launch would make every existing campaign the wrong length",
              "and unreadable, and recovering would mean an instruction that grows each",
              "live account one at a time. Reserving the bytes up front means the next",
              "field is taken from this array — `pub new_field: u64` plus",
              "`_reserved: [u8; 56]` — leaving the total unchanged and old accounts",
              "readable.",
              "",
              "Two rules for whoever spends it: this array stays last, and a new field",
              "must treat 0 as a valid initial value, because that is what pre-existing",
              "accounts will hold.",
              "",
              "Costs ~0.00045 SOL of rent per campaign, out of the protocol's share",
              "since the creation price is fixed."
            ],
            "type": {
              "array": [
                "u8",
                64
              ]
            }
          }
        ]
      }
    },
    {
      "name": "CampaignBuy",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "campaign",
            "type": "pubkey"
          },
          {
            "name": "buyer",
            "type": "pubkey"
          },
          {
            "name": "token_amount",
            "type": "u64"
          },
          {
            "name": "sol_amount",
            "type": "u64"
          },
          {
            "name": "virtual_sol_reserves",
            "docs": [
              "Campaign `virtual_sol_reserves` after this trade was applied.",
              "Emitted so off-chain indexers can price each trade independently,",
              "without replaying the whole trade history in order — a replay is",
              "order-sensitive and a late-arriving trade silently mis-attributes",
              "prices to timestamps."
            ],
            "type": "u64"
          },
          {
            "name": "virtual_token_reserves",
            "docs": [
              "Campaign `virtual_token_reserves` after this trade was applied.",
              "Together with `virtual_sol_reserves` this fully determines the",
              "marginal price at this trade, making the event self-describing."
            ],
            "type": "u64"
          }
        ]
      }
    },
    {
      "name": "CampaignCreated",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "campaign",
            "type": "pubkey"
          },
          {
            "name": "creator",
            "type": "pubkey"
          },
          {
            "name": "slug",
            "type": "string"
          },
          {
            "name": "end_ts",
            "type": "i64"
          },
          {
            "name": "creation_fee",
            "docs": [
              "Flat creation fee routed to the protocol treasury (the remainder of the",
              "fixed `CREATE_CAMPAIGN_COST_LAMPORTS` over the accounts' rent)."
            ],
            "type": "u64"
          },
          {
            "name": "mint",
            "docs": [
              "The campaign's SPL mint. Written once at creation and never mutated."
            ],
            "type": "pubkey"
          },
          {
            "name": "metadata_uri",
            "docs": [
              "The campaign's off-chain metadata URI (`MAX_URI_LEN` bytes at most).",
              "Written once at creation and never mutated. Emitted with `mint` so an",
              "indexer can render a new campaign straight from the event, instead of",
              "polling the campaign account until it lands."
            ],
            "type": "string"
          },
          {
            "name": "creator_referrer",
            "docs": [
              "The creator's referrer, or `Pubkey::default()` if none. Written once at",
              "creation and never mutated. The client needs it to derive the referral",
              "vault when building the settle transaction."
            ],
            "type": "pubkey"
          }
        ]
      }
    },
    {
      "name": "CampaignSell",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "campaign",
            "type": "pubkey"
          },
          {
            "name": "seller",
            "type": "pubkey"
          },
          {
            "name": "token_amount",
            "type": "u64"
          },
          {
            "name": "sol_amount",
            "docs": [
              "What the seller actually received (gross − protocol_fee − holder_fee)."
            ],
            "type": "u64"
          },
          {
            "name": "protocol_fee",
            "docs": [
              "The protocol's share of this sell. Accrued on the campaign — see",
              "`pending_protocol_revenue` below — and swept to `protocol_treasury` at",
              "settle, not transferred here. Sells carry no affiliation cut: paying",
              "anyone to bring a seller would subsidise exits."
            ],
            "type": "u64"
          },
          {
            "name": "holder_fee",
            "docs": [
              "Assigned to the stakers present at this sell, or held for the creator",
              "when nobody was staked. See the two campaign totals below."
            ],
            "type": "u64"
          },
          {
            "name": "virtual_sol_reserves",
            "docs": [
              "Campaign `virtual_sol_reserves` after this trade was applied.",
              "Emitted so off-chain indexers can price each trade independently,",
              "without replaying the whole trade history in order — a replay is",
              "order-sensitive and a late-arriving trade silently mis-attributes",
              "prices to timestamps."
            ],
            "type": "u64"
          },
          {
            "name": "virtual_token_reserves",
            "docs": [
              "Campaign `virtual_token_reserves` after this trade was applied.",
              "Together with `virtual_sol_reserves` this fully determines the",
              "marginal price at this trade, making the event self-describing."
            ],
            "type": "u64"
          },
          {
            "name": "holder_fees_unallocated",
            "docs": [
              "Campaign total after this sell of the holder cut collected while nobody",
              "was staked — the part that goes to the creator at settlement. Unchanged",
              "from the previous sell means this one's `holder_fee` went to the stakers",
              "instead, which is the only way to tell the two paths apart."
            ],
            "type": "u64"
          },
          {
            "name": "total_staked",
            "docs": [
              "`total_staked` at the instant this sell was assigned, and the accumulators",
              "after it. A sell now does what a deposit does — it advances",
              "`reward_per_token_accumulator` — so it has to report the same three",
              "numbers `RevenueDeposited` reports, and for the same reason: an",
              "accumulator can only be followed, never recomputed. An indexer that misses",
              "one write never catches up, because every later sell adds to a number it",
              "no longer knows."
            ],
            "type": "u64"
          },
          {
            "name": "reward_per_token_accumulator",
            "type": "u128"
          },
          {
            "name": "carry_revenue_scaled",
            "type": "u128"
          },
          {
            "name": "pending_protocol_revenue",
            "docs": [
              "Campaign `pending_protocol_revenue` after `protocol_fee` was accrued.",
              "The protocol's cut is no longer paid out at sell time — see the field's",
              "doc on `Campaign` for why — so this is what the treasury will receive at",
              "settle, not what it received now."
            ],
            "type": "u64"
          }
        ]
      }
    },
    {
      "name": "CampaignSettled",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "campaign",
            "type": "pubkey"
          },
          {
            "name": "total_staked",
            "type": "u64"
          },
          {
            "name": "creator_cut",
            "type": "u64"
          },
          {
            "name": "protocol_cut",
            "docs": [
              "Protocol share at settle, already net of `referral_settle`."
            ],
            "type": "u64"
          },
          {
            "name": "referral_settle",
            "docs": [
              "Creator-side affiliation cut, credited to the referrer's vault (not their",
              "wallet) out of the protocol share. Zero when the campaign has no referrer."
            ],
            "type": "u64"
          },
          {
            "name": "referrer",
            "docs": [
              "The campaign's creator referrer, or `Pubkey::default()` if none."
            ],
            "type": "pubkey"
          },
          {
            "name": "caller_bounty",
            "docs": [
              "Lamports paid to the wallet that signed the settle TX. Paid on every",
              "settle, including when the creator settles their own campaign — the",
              "handler has no branch on caller identity. Only floors to zero when",
              "`real_sol_reserves` is small enough that 100 bps rounds down."
            ],
            "type": "u64"
          },
          {
            "name": "caller",
            "docs": [
              "The wallet that signed the settle TX. Equals `campaign.creator` when",
              "the creator self-settles."
            ],
            "type": "pubkey"
          },
          {
            "name": "settled_at",
            "type": "i64"
          },
          {
            "name": "creator_folded",
            "docs": [
              "What the creator was owed but could not be credited, because the payment",
              "would have left their wallet below the rent-exempt minimum. Folded to the",
              "treasury. Zero on every ordinary settle."
            ],
            "type": "u64"
          },
          {
            "name": "protocol_revenue_swept",
            "docs": [
              "Sell fees accrued to the protocol across the trading window and swept to",
              "the treasury by this settle. Separate from `protocol_cut`, which is the",
              "settlement share of `real_sol_reserves`; the treasury receives both."
            ],
            "type": "u64"
          },
          {
            "name": "holder_fees_unallocated",
            "docs": [
              "Holder fees collected while nobody was staked, paid to the creator here."
            ],
            "type": "u64"
          },
          {
            "name": "reward_per_token_accumulator",
            "docs": [
              "Campaign accumulators at settlement. Settle does not move them — every",
              "entitlement was fixed when the money arrived — so these are a checkpoint",
              "rather than a delta: an indexer following sells and deposits can",
              "reconcile its running total against them here, once per campaign."
            ],
            "type": "u128"
          },
          {
            "name": "carry_revenue_scaled",
            "type": "u128"
          }
        ]
      }
    },
    {
      "name": "CampaignStatus",
      "type": {
        "kind": "enum",
        "variants": [
          {
            "name": "Active"
          },
          {
            "name": "Settled"
          }
        ]
      }
    },
    {
      "name": "CreateCampaignArgs",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "slug",
            "type": "string"
          },
          {
            "name": "name",
            "docs": [
              "What wallets show for this campaign's token. Supplied by the creator",
              "rather than derived from the slug: the slug is a url path segment",
              "(lowercase, hyphenated) and reads as one, whereas this is a display",
              "name."
            ],
            "type": "string"
          },
          {
            "name": "symbol",
            "docs": [
              "The ticker. Chosen by the creator because every campaign minting the",
              "same symbol makes a wallet holding several of them unreadable."
            ],
            "type": "string"
          },
          {
            "name": "metadata_uri",
            "type": "string"
          },
          {
            "name": "end_ts",
            "type": "i64"
          },
          {
            "name": "referral",
            "docs": [
              "Affiliation: the creator's referrer, from the app's off-chain attribution.",
              "`Pubkey::default()` = none. Stored immutably as `campaign.creator_referrer`",
              "and credited to that referrer's vault at settle."
            ],
            "type": "pubkey"
          }
        ]
      }
    },
    {
      "name": "ProtocolAuthorityRotated",
      "docs": [
        "Emitted by `accept_protocol_authority` (step 2): the staged authority has",
        "co-signed and is now the effective authority."
      ],
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "previous",
            "type": "pubkey"
          },
          {
            "name": "new",
            "type": "pubkey"
          }
        ]
      }
    },
    {
      "name": "ProtocolAuthorityRotationProposed",
      "docs": [
        "Emitted by `rotate_protocol_authority` (step 1 of the two-step rotation):",
        "the new authority is only staged here, not yet effective."
      ],
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "current",
            "type": "pubkey"
          },
          {
            "name": "pending",
            "type": "pubkey"
          }
        ]
      }
    },
    {
      "name": "ProtocolFeesWithdrawn",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "authority",
            "type": "pubkey"
          },
          {
            "name": "destination",
            "type": "pubkey"
          },
          {
            "name": "amount",
            "type": "u64"
          }
        ]
      }
    },
    {
      "name": "ProtocolTreasury",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "authority",
            "type": "pubkey"
          },
          {
            "name": "pending_authority",
            "docs": [
              "Staged next authority for the two-step rotation (Ownable2Step). Set by",
              "`rotate_protocol_authority`; promoted to `authority` only when this key",
              "co-signs `accept_protocol_authority`. `Pubkey::default()` when no",
              "rotation is pending. This guarantees a mistyped or non-signable address",
              "can never irrecoverably brick the treasury, since the current authority",
              "keeps control until the new key proves it can sign."
            ],
            "type": "pubkey"
          },
          {
            "name": "bump",
            "type": "u8"
          }
        ]
      }
    },
    {
      "name": "ReferralFeesClaimed",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "referrer",
            "type": "pubkey"
          },
          {
            "name": "destination",
            "docs": [
              "Where the referrer chose to send the swept balance."
            ],
            "type": "pubkey"
          },
          {
            "name": "amount",
            "docs": [
              "Swept amount, i.e. the vault balance above its rent-exempt minimum."
            ],
            "type": "u64"
          }
        ]
      }
    },
    {
      "name": "ReferralVault",
      "docs": [
        "Per-referrer escrow for the creator-side affiliation cut.",
        "",
        "Settlement credits this program-owned PDA instead of paying the referrer's",
        "wallet directly. Two properties follow, and both are the reason it exists:",
        "",
        "1. The address is derived from the referrer's key, so it can never be a",
        "program, a reserved account, or anything whose lamport balance the runtime",
        "refuses to change. Settle is the only instruction that can close a",
        "campaign, and a referrer address travels in through a referral link the",
        "creator did not author — without this indirection, a poisoned link would",
        "freeze a campaign whose creator did nothing wrong.",
        "2. Because the vault is rent-exempt once and then reused, individual cuts are",
        "no longer gated on leaving a wallet rent-exempt. Small commissions",
        "accumulate instead of being dropped.",
        "",
        "The referrer sweeps the balance with `claim_referral_fees`, signing for",
        "themselves and naming their own destination. That claim step is deliberate:",
        "the cut is a meaningful share of a whole raise and is earned rarely, so one",
        "extra transaction is a fair price for the two guarantees above."
      ],
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "referrer",
            "docs": [
              "The wallet this vault accrues for. Written once at creation from the same",
              "key used as the PDA seed, so the stored value and the derivation can never",
              "disagree."
            ],
            "type": "pubkey"
          },
          {
            "name": "bump",
            "type": "u8"
          }
        ]
      }
    },
    {
      "name": "RevenueClaimed",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "campaign",
            "type": "pubkey"
          },
          {
            "name": "user",
            "type": "pubkey"
          },
          {
            "name": "amount",
            "type": "u64"
          },
          {
            "name": "staked_amount",
            "docs": [
              "The claimer's `StakePosition` after settling and paying out. Emitted so",
              "an indexer can serve a wallet's positions without reading every",
              "StakePosition account back, which needs a getProgramAccounts scan."
            ],
            "type": "u64"
          },
          {
            "name": "pending_rewards",
            "type": "u64"
          },
          {
            "name": "reward_checkpoint",
            "type": "u128"
          }
        ]
      }
    },
    {
      "name": "RevenueDeposited",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "campaign",
            "type": "pubkey"
          },
          {
            "name": "depositor",
            "type": "pubkey"
          },
          {
            "name": "amount",
            "type": "u64"
          },
          {
            "name": "total_staked",
            "docs": [
              "`total_staked` used as the distribution denominator for this deposit."
            ],
            "type": "u64"
          },
          {
            "name": "new_accumulator",
            "type": "u128"
          },
          {
            "name": "carry_scaled_after",
            "docs": [
              "Rounding-dust carry after this deposit, in the REWARD_SCALE domain",
              "(matches `Campaign.carry_revenue_scaled`, not lamports). Strictly less",
              "than `total_staked`, in both phases: `deposit_revenue` accrues on",
              "arrival whether or not the campaign is settled, and refuses a deposit",
              "with nobody staked, so every deposit reaching this field went through",
              "the accrue."
            ],
            "type": "u128"
          }
        ]
      }
    },
    {
      "name": "RevenueVault",
      "docs": [
        "Per-campaign revenue pool. Holds SOL beyond its rent-exempt minimum; the",
        "excess is what stakers are collectively owed.",
        "",
        "Money reaches it from two places and both behave the same way: the holder",
        "share of a sell, and a `deposit_revenue`. In each case the lamports arrive",
        "and `reward_per_token_accumulator` moves in the same instruction, so the",
        "balance and the entitlements it backs never drift apart, which is what lets",
        "`claim_revenue` run in either phase.",
        "",
        "`settle` neither credits nor drains it. Nothing about revenue is decided at",
        "settlement; every share was fixed when the money arrived.",
        "",
        "`total_deposited` and `total_claimed` are monotonic counters, maintained for",
        "indexers and transparency. Nothing resets them. The live distributable",
        "balance is derived from `lamports - rent_exempt_minimum`, never from these",
        "fields."
      ],
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "campaign",
            "type": "pubkey"
          },
          {
            "name": "total_deposited",
            "type": "u64"
          },
          {
            "name": "total_claimed",
            "type": "u64"
          },
          {
            "name": "bump",
            "type": "u8"
          }
        ]
      }
    },
    {
      "name": "StakePosition",
      "docs": [
        "Per-(campaign, owner) staking position. `staked_amount` is what the owner has",
        "explicitly deposited into the campaign stake vault — it does not mirror an ATA",
        "balance. Because staked tokens are custodied by the program, the amount can",
        "only change via `stake`/`unstake` (never a silent burn or an outside transfer),",
        "so reward settling is always exact — no burn-aware variant is needed.",
        "",
        "The position carries no timestamp: rewards are a pure function of",
        "`staked_amount` and the accumulator delta since `reward_checkpoint`, with no",
        "weighting for how long the tokens sat here."
      ],
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "campaign",
            "type": "pubkey"
          },
          {
            "name": "owner",
            "type": "pubkey"
          },
          {
            "name": "staked_amount",
            "docs": [
              "Tokens currently staked by this owner (held in the campaign stake vault)."
            ],
            "type": "u64"
          },
          {
            "name": "pending_rewards",
            "docs": [
              "Claimable lamports accrued and not yet withdrawn."
            ],
            "type": "u64"
          },
          {
            "name": "reward_checkpoint",
            "docs": [
              "The per-token accumulator value this position last settled against. The",
              "reward owed since then is `staked_amount × (accumulator − reward_checkpoint)`,",
              "floored to lamports once at credit time. Storing the checkpoint (which always",
              "fits u128) instead of `staked × accumulator` keeps settle overflow-free even",
              "if the accumulator was inflated by a deposit made against a tiny",
              "`total_staked`. See `rewards::settle_core`."
            ],
            "type": "u128"
          },
          {
            "name": "bump",
            "type": "u8"
          }
        ]
      }
    },
    {
      "name": "Staked",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "campaign",
            "type": "pubkey"
          },
          {
            "name": "owner",
            "type": "pubkey"
          },
          {
            "name": "amount",
            "type": "u64"
          },
          {
            "name": "total_staked",
            "docs": [
              "Campaign-wide total, not this owner's stake."
            ],
            "type": "u64"
          },
          {
            "name": "staked_amount",
            "docs": [
              "This owner's `StakePosition` after the stake was applied. `amount` is a",
              "delta and `total_staked` belongs to the campaign, so neither yields the",
              "owner's own position; emitting it removes the account read."
            ],
            "type": "u64"
          },
          {
            "name": "pending_rewards",
            "type": "u64"
          },
          {
            "name": "reward_checkpoint",
            "type": "u128"
          }
        ]
      }
    },
    {
      "name": "Unstaked",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "campaign",
            "type": "pubkey"
          },
          {
            "name": "owner",
            "type": "pubkey"
          },
          {
            "name": "amount",
            "type": "u64"
          },
          {
            "name": "total_staked",
            "docs": [
              "Campaign-wide total, not this owner's stake."
            ],
            "type": "u64"
          },
          {
            "name": "staked_amount",
            "docs": [
              "This owner's `StakePosition` after the unstake was applied. Same",
              "reasoning as `Staked`."
            ],
            "type": "u64"
          },
          {
            "name": "pending_rewards",
            "type": "u64"
          },
          {
            "name": "reward_checkpoint",
            "type": "u128"
          }
        ]
      }
    }
  ]
}