@solana/web3.js. They define all instructions, accounts, types, and events.
IDL descriptions use capital provider terminology. Program identifiers and error messages retain their on-chain values.
Each code block includes a built-in copy button. Click the copy icon in the top-right corner to copy the full IDL to your clipboard.
Swap Program
Handles all swap operations between RWAs and stablecoins, asset configuration, pair management, liquidity operations, and fee collection. Program ID:HaWDr94LKJQT2fXuHJGsSGeQf6M7S68FXpEQLcE5RYs6
Swap Program IDL
Swap Program IDL
swap_program.json
{
"address": "HaWDr94LKJQT2fXuHJGsSGeQf6M7S68FXpEQLcE5RYs6",
"metadata": {
"name": "swap_program",
"version": "0.1.0",
"spec": "0.1.0",
"description": "Created with Anchor"
},
"instructions": [
{
"name": "add_liquidity",
"docs": [
"Deposits tokens from the capital provider into the vault, optionally routing through the treasury program.",
"",
"Flow:",
"- Checks the program pause state, the asset pause state and, for stable assets, the capital provider's",
"stable pause state.",
"- Transfers `amount` tokens from the capital provider's token account into the vault ATA.",
"- If treasury is enabled, CPIs into the treasury `deposit` instruction so vault tokens are",
"put to work earning yield.",
"",
"Parameters:",
"- `amount`: Number of tokens to deposit.",
"- `treasury_nav_account_count`: Number of NAV accounts in `remaining_accounts` for the treasury CPI.",
"- `treasury_apy_account_count`: Number of APY accounts in `remaining_accounts` for the treasury CPI.",
"- `amount_threshold`: Optional floor on the treasury tokens minted. The deposit is always",
"`ExactIn`, and this is ignored when there is no deposit to make."
],
"discriminator": [
181,
157,
89,
67,
143,
182,
52,
72
],
"accounts": [
{
"name": "liquidity_provider",
"docs": [
"the capital provider that provides the tokens"
],
"writable": true,
"signer": true
},
{
"name": "mint_address",
"docs": [
"the mint address of the token"
]
},
{
"name": "lp_token_account",
"docs": [
"the token account of the capital provider"
],
"writable": true
},
{
"name": "vault_token_account",
"docs": [
"the vault token account (for the program)"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "lp_vault_authority"
},
{
"kind": "account",
"path": "token_program"
},
{
"kind": "account",
"path": "mint_address"
}
],
"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": "lp_vault_authority",
"docs": [
"the capital provider's vault authority used in vault ATA constraints"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
118,
97,
117,
108,
116,
95,
97,
117,
116,
104,
111,
114,
105,
116,
121
]
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "global_config",
"docs": [
"the global config, used to check if the program is paused"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
103,
108,
111,
98,
97,
108,
95,
99,
111,
110,
102,
105,
103
]
}
]
}
},
{
"name": "lp_protocol_fee_config",
"docs": [
"Treasury toggle and protocol fee overrides for the capital provider."
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
108,
112,
95,
112,
114,
111,
116,
111,
99,
111,
108,
95,
102,
101,
101,
95,
99,
111,
110,
102,
105,
103
]
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "asset_config",
"docs": [
"the asset config of the deposited mint, used to check the per-asset pause flag"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
97,
115,
115,
101,
116
]
},
{
"kind": "account",
"path": "mint_address"
}
]
}
},
{
"name": "lp_stable_config",
"docs": [
"Capital provider stable config for the deposited mint — Some only when the mint is Stable, None for RWA"
],
"optional": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
108,
112,
95,
115,
116,
97,
98,
108,
101,
95,
99,
111,
110,
102,
105,
103
]
},
{
"kind": "account",
"path": "mint_address"
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "treasury_program",
"optional": true
},
{
"name": "treasury_global_config",
"optional": true
},
{
"name": "treasury_asset_config",
"optional": true
},
{
"name": "treasury_user_position",
"writable": true,
"optional": true
},
{
"name": "treasury_vault_authority",
"optional": true
},
{
"name": "treasury_mint",
"writable": true,
"optional": true
},
{
"name": "treasury_asset_vault",
"writable": true,
"optional": true
},
{
"name": "treasury_user_treasury_token_account",
"writable": true,
"optional": true
},
{
"name": "treasury_token_program",
"optional": true
},
{
"name": "treasury_associated_token_program",
"optional": true
},
{
"name": "treasury_system_program",
"optional": true
},
{
"name": "token_program",
"docs": [
"the token program, could be either the token2022 or the legacy token program"
]
}
],
"args": [
{
"name": "amount",
"type": "u64"
},
{
"name": "treasury_nav_account_count",
"type": "u8"
},
{
"name": "treasury_apy_account_count",
"type": "u8"
},
{
"name": "amount_threshold",
"type": {
"option": "u64"
}
}
]
},
{
"name": "claim_fees",
"docs": [
"Sweeps the entire balance from the program-level fee vault to the designated fee wallet.",
"",
"Flow:",
"- Verifies the caller-supplied `fee_wallet` matches `GlobalConfig.fee_wallet` via `has_one`.",
"- Transfers the full balance of `fee_token_account` (owned by `program_authority`) to",
"`fee_wallet_token_account`.",
"",
"Parameters:",
"- `fee_wallet`: The fee wallet public key; used as an `#[instruction]` seed for the constraint."
],
"discriminator": [
82,
251,
233,
156,
12,
52,
184,
202
],
"accounts": [
{
"name": "fee_mint",
"docs": [
"the mint address of the quote token"
]
},
{
"name": "fee_wallet_token_account",
"docs": [
"the token account of the fee wallet"
],
"writable": true
},
{
"name": "program_authority",
"docs": [
"the program authority, used to sign the CPI transfer"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
112,
114,
111,
103,
114,
97,
109,
95,
97,
117,
116,
104,
111,
114,
105,
116,
121
]
}
]
}
},
{
"name": "fee_token_account",
"docs": [
"the fee vault token account, used to transfer the tokens to the fee wallet"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "program_authority"
},
{
"kind": "account",
"path": "token_program"
},
{
"kind": "account",
"path": "fee_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": "global_config",
"docs": [
"the global config, used to check if the program is paused, and check fee wallet"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
103,
108,
111,
98,
97,
108,
95,
99,
111,
110,
102,
105,
103
]
}
]
}
},
{
"name": "token_program",
"docs": [
"the token program, could be either the token2022 or the legacy token program"
]
}
],
"args": [
{
"name": "fee_wallet",
"type": "pubkey"
}
]
},
{
"name": "close_lp_fee_account",
"docs": [
"Closes the capital provider's protocol-fee token account and returns any remaining balance to the capital provider.",
"",
"Flow:",
"- Checks that the program is not paused.",
"- If the fee account holds a non-zero balance, transfers it to `lp_destination_token_account`.",
"- Closes the fee token ATA and returns the rent lamports to `liquidity_provider`.",
"",
"This instruction should be called after all pairs have been closed via `close_pair`.",
"Closing the fee account while active pairs exist will cause future swaps for those pairs",
"to fail, as the swap instruction debits protocol fees from this account."
],
"discriminator": [
188,
218,
123,
57,
25,
51,
105,
181
],
"accounts": [
{
"name": "liquidity_provider",
"docs": [
"the capital provider; receives the remaining fee balance and reclaimed rent"
],
"writable": true,
"signer": true
},
{
"name": "lp_fee_vault_authority",
"docs": [
"the separate capital provider fee vault authority that owns the fee token account"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
108,
112,
95,
102,
101,
101,
95,
118,
97,
117,
108,
116,
95,
97,
117,
116,
104,
111,
114,
105,
116,
121
]
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "global_config",
"docs": [
"the global config, used to verify the fee token mint and check pause state;",
"placed before fee_token_mint_address so its seeds constraint is validated first"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
103,
108,
111,
98,
97,
108,
95,
99,
111,
110,
102,
105,
103
]
}
]
}
},
{
"name": "fee_token_mint_address",
"docs": [
"the mint address of the fee token; must match global config"
]
},
{
"name": "lp_fee_token_account",
"docs": [
"the capital provider's protocol-fee token account to drain and close"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "lp_fee_vault_authority"
},
{
"kind": "account",
"path": "token_program_fee"
},
{
"kind": "account",
"path": "fee_token_mint_address"
}
],
"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": "lp_destination_token_account",
"docs": [
"the capital provider token account that receives any remaining fee balance"
],
"writable": true
},
{
"name": "token_program_fee",
"docs": [
"the token program for the fee token"
]
}
],
"args": []
},
{
"name": "close_pair",
"docs": [
"Closes a trading pair and reclaims rent; returns vault tokens to the capital provider if all pairs for a mint are closed.",
"",
"Flow:",
"- Checks that the program is not paused.",
"- If treasury is enabled for this capital provider, verifies that the treasury user position has zero balance.",
"- Decrements `used` on the `UserVaultInfo` PDAs and `used_in_pairs_count` on both asset configs.",
"- If a vault's `used` count reaches zero, transfers the remaining vault balance back to the capital provider",
"and closes the vault ATA and `UserVaultInfo` PDA.",
"",
"The capital provider must call `remove_liquidity` to drain all vault and treasury balances before calling",
"this instruction. If treasury is enabled, pass the `treasury_user_position` account; it must",
"report a zero balance for the instruction to succeed. After closing all pairs, call",
"`close_lp_fee_account` to recover any remaining fee token balance."
],
"discriminator": [
45,
8,
194,
47,
65,
139,
172,
120
],
"accounts": [
{
"name": "admin",
"docs": [
"the admin, checked by has_one constraint with global config"
],
"relations": [
"global_config"
]
},
{
"name": "liquidity_provider",
"docs": [
"the capital provider, will receive tokens and reclaimed rent back if necessary"
],
"writable": true,
"signer": true
},
{
"name": "pair",
"docs": [
"the pair account, will be closed"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
112,
97,
105,
114
]
},
{
"kind": "account",
"path": "liquidity_provider"
},
{
"kind": "account",
"path": "quote_token_mint_address"
},
{
"kind": "account",
"path": "base_token_mint_address"
}
]
}
},
{
"name": "quote_token_mint_address",
"docs": [
"the mint address of the pair's quote token"
]
},
{
"name": "base_token_mint_address",
"docs": [
"the mint address of the pair's base token"
]
},
{
"name": "lp_vault_authority",
"docs": [
"the capital provider's vault authority, used to sign capital provider vault transfers"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
118,
97,
117,
108,
116,
95,
97,
117,
116,
104,
111,
114,
105,
116,
121
]
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "quote_token_vault_token_account",
"docs": [
"the vault token account for the quote token"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "lp_vault_authority"
},
{
"kind": "account",
"path": "token_program_quote"
},
{
"kind": "account",
"path": "quote_token_mint_address"
}
],
"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": "base_token_vault_token_account",
"docs": [
"the vault token account for the base token"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "lp_vault_authority"
},
{
"kind": "account",
"path": "token_program_base"
},
{
"kind": "account",
"path": "base_token_mint_address"
}
],
"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": "lp_quote_token_account",
"docs": [
"the token account of the capital provider for the quote token"
],
"writable": true
},
{
"name": "lp_base_token_account",
"docs": [
"the token account of the capital provider for the base token"
],
"writable": true
},
{
"name": "lp_vault_quote_pda",
"docs": [
"the capital provider vault info for the quote token"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
117,
115,
101,
114,
95,
118,
97,
117,
108,
116,
95,
105,
110,
102,
111
]
},
{
"kind": "account",
"path": "quote_token_mint_address"
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "lp_vault_base_pda",
"docs": [
"the capital provider vault info for the base token"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
117,
115,
101,
114,
95,
118,
97,
117,
108,
116,
95,
105,
110,
102,
111
]
},
{
"kind": "account",
"path": "base_token_mint_address"
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "quote_asset_config",
"docs": [
"the asset config for the quote token"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
97,
115,
115,
101,
116
]
},
{
"kind": "account",
"path": "quote_token_mint_address"
}
]
}
},
{
"name": "base_asset_config",
"docs": [
"the asset config for the base token"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
97,
115,
115,
101,
116
]
},
{
"kind": "account",
"path": "base_token_mint_address"
}
]
}
},
{
"name": "global_config",
"docs": [
"the global config, used to check if the program is paused, and check admin"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
103,
108,
111,
98,
97,
108,
95,
99,
111,
110,
102,
105,
103
]
}
]
}
},
{
"name": "lp_protocol_fee_config",
"docs": [
"Treasury toggle and protocol fee overrides for the capital provider."
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
108,
112,
95,
112,
114,
111,
116,
111,
99,
111,
108,
95,
102,
101,
101,
95,
99,
111,
110,
102,
105,
103
]
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "treasury_user_position",
"docs": [
"Treasury user position for the capital provider vault authority.",
"Always required; data_is_empty() means capital provider never deposited to treasury."
]
},
{
"name": "token_program_quote",
"docs": [
"the token program for the quote token, could be either the token2022 or the legacy token program"
]
},
{
"name": "token_program_base",
"docs": [
"the token program for the base token, could be either the token2022 or the legacy token program"
]
}
],
"args": []
},
{
"name": "close_treasury_position",
"docs": [
"Closes the capital provider's treasury user position and returns the reclaimed rent to the capital provider.",
"",
"Flow:",
"- Checks that the program is not paused.",
"- Pins `treasury_mint` against the treasury program's global config.",
"- Verifies `treasury_user_position` by deriving the expected treasury PDA.",
"- CPIs into the treasury `close_user_position` instruction, signing as `lp_vault_authority`.",
"- Closes the capital provider's treasury receipt account when it is already empty.",
"- Sweeps the full `lp_vault_authority` lamport balance to the capital provider.",
"",
"Treasury bills the position's rent to `lp_vault_authority` and refunds to that same PDA on",
"close, so the final sweep is the only way the capital provider gets the SOL back.",
"",
"Call this after `remove_liquidity` has drained the position. Treasury requires principal,",
"yield, and pending deposits to all be zero, and pending deposits only clear once they are",
"merge-ready, so this cannot run in the same breath as the final redeem."
],
"discriminator": [
62,
152,
253,
37,
167,
251,
8,
64
],
"accounts": [
{
"name": "liquidity_provider",
"docs": [
"the capital provider; receives the reclaimed rent"
],
"writable": true,
"signer": true
},
{
"name": "global_config",
"pda": {
"seeds": [
{
"kind": "const",
"value": [
103,
108,
111,
98,
97,
108,
95,
99,
111,
110,
102,
105,
103
]
}
]
}
},
{
"name": "treasury_global_config",
"docs": [
"the treasury program's global config; pins `treasury_mint` to the real receipt mint"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
71,
76,
79,
66,
65,
76,
95,
67,
79,
78,
70,
73,
71
]
}
],
"program": {
"kind": "const",
"value": [
225,
137,
15,
93,
135,
103,
114,
68,
124,
46,
133,
205,
18,
24,
147,
212,
92,
235,
177,
70,
28,
77,
59,
174,
183,
100,
70,
152,
13,
17,
18,
174
]
}
}
},
{
"name": "lp_vault_authority",
"docs": [
"the capital provider's vault authority; owns the treasury position and holds its rent lamports"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
118,
97,
117,
108,
116,
95,
97,
117,
116,
104,
111,
114,
105,
116,
121
]
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "treasury_user_position",
"docs": [
"the treasury user position to close"
],
"writable": true
},
{
"name": "treasury_mint",
"docs": [
"the treasury receipt mint; verified against treasury's global config in the handler.",
"Without that check any mint would do, and the receipt-account constraint below would",
"equally accept one of the capital provider's swap vault ATAs, which share the same authority."
]
},
{
"name": "treasury_user_treasury_token_account",
"docs": [
"the capital provider's treasury receipt account, closed when it is already empty"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "lp_vault_authority"
},
{
"kind": "account",
"path": "token_program_treasury"
},
{
"kind": "account",
"path": "treasury_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": "treasury_program"
},
{
"name": "token_program_treasury"
},
{
"name": "system_program",
"address": "11111111111111111111111111111111"
}
],
"args": []
},
{
"name": "confirm_new_admin",
"docs": [
"Completes an admin transfer when the pending admin signs and accepts the role.",
"",
"Flow:",
"- Verifies the signer matches `GlobalConfig.pending_admin`.",
"- Promotes pending admin to `GlobalConfig.admin` and clears the pending field."
],
"discriminator": [
3,
109,
83,
170,
106,
54,
173,
117
],
"accounts": [
{
"name": "global_config",
"docs": [
"the global config account, will be updated"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
103,
108,
111,
98,
97,
108,
95,
99,
111,
110,
102,
105,
103
]
}
]
}
},
{
"name": "new_admin",
"signer": true
}
],
"args": []
},
{
"name": "init_asset_config_account",
"docs": [
"Registers a new asset (quote or base token) with its NAV price sources.",
"",
"Flow:",
"- Validates NAV sources and the price-difference bound.",
"- Initialises the `AssetConfig` PDA storing the NAV configuration and asset type.",
"",
"Parameters:",
"- `nav_data`: Up to 5 NAV source definitions (Hardcoded, U64FixedAddress, or PythPush).",
"- `price_difference_bps`: Maximum permitted divergence between NAV sources in basis points.",
"- `asset_type`: Classification of the asset (RWA or Stable)."
],
"discriminator": [
32,
66,
21,
159,
176,
230,
59,
11
],
"accounts": [
{
"name": "asset_config",
"docs": [
"the RWA config account, will be initialized if needed"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
97,
115,
115,
101,
116
]
},
{
"kind": "account",
"path": "mint_address"
}
]
}
},
{
"name": "mint_address",
"docs": [
"the mint address of the RWA token"
]
},
{
"name": "admin",
"writable": true,
"signer": true,
"relations": [
"global_config"
]
},
{
"name": "fee_vault_token_account",
"docs": [
"the fee vault token account, used to store the fees"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "program_authority"
},
{
"kind": "account",
"path": "token_program"
},
{
"kind": "account",
"path": "mint_address"
}
],
"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": "program_authority",
"docs": [
"the program authority"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
112,
114,
111,
103,
114,
97,
109,
95,
97,
117,
116,
104,
111,
114,
105,
116,
121
]
}
]
}
},
{
"name": "global_config",
"docs": [
"the global config, used to check admin"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
103,
108,
111,
98,
97,
108,
95,
99,
111,
110,
102,
105,
103
]
}
]
}
},
{
"name": "token_program",
"docs": [
"the token program for the asset token, could be either the token2022 or the legacy token program"
]
},
{
"name": "system_program",
"docs": [
"the system program, used to initialize the account"
],
"address": "11111111111111111111111111111111"
},
{
"name": "associated_token_program",
"address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
}
],
"args": [
{
"name": "nav_data",
"type": {
"vec": {
"defined": {
"name": "NavData"
}
}
}
},
{
"name": "price_difference_bps",
"type": "u16"
},
{
"name": "asset_type",
"type": {
"defined": {
"name": "AssetType"
}
}
}
]
},
{
"name": "init_global_config",
"docs": [
"Initialises the global configuration and the program-level fee vault ATA.",
"",
"Flow:",
"- Validates that `protocol_fees_bps` and `spread_protocol_fees_bps` are within range.",
"- Stores admin, fee wallet, fee rates, and fee token mint in `GlobalConfig`.",
"- Creates the global fee vault ATA owned by `program_authority`.",
"- The program starts **paused**; call `update_global_config` to unpause.",
"",
"Parameters:",
"- `fee_wallet`: Recipient of protocol fees swept by `claim_fees`.",
"- `protocol_fees_bps`: Default issuer protocol fee rate in basis points.",
"- `spread_protocol_fees_bps`: Default spread protocol fee rate in basis points.",
"- `fee_token_mint`: Mint of the token capital providers use to pay protocol fees (e.g. USDC)."
],
"discriminator": [
140,
136,
214,
48,
87,
0,
120,
255
],
"accounts": [
{
"name": "global_config",
"docs": [
"the global config account, will be initialized"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
103,
108,
111,
98,
97,
108,
95,
99,
111,
110,
102,
105,
103
]
}
]
}
},
{
"name": "admin",
"docs": [
"the admin, will be the admin of the global config"
],
"writable": true,
"signer": true
},
{
"name": "program_data",
"pda": {
"seeds": [
{
"kind": "const",
"value": [
246,
80,
50,
201,
22,
67,
113,
95,
184,
123,
138,
8,
210,
160,
250,
182,
38,
116,
26,
34,
165,
198,
52,
1,
157,
26,
161,
36,
224,
107,
219,
21
]
}
],
"program": {
"kind": "const",
"value": [
2,
168,
246,
145,
78,
136,
161,
176,
226,
16,
21,
62,
247,
99,
174,
43,
0,
194,
185,
61,
22,
193,
36,
210,
192,
83,
122,
16,
4,
128,
0,
0
]
}
}
},
{
"name": "program_authority",
"docs": [
"the program authority PDA, will own the fee vault"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
112,
114,
111,
103,
114,
97,
109,
95,
97,
117,
116,
104,
111,
114,
105,
116,
121
]
}
]
}
},
{
"name": "fee_token_mint_address",
"docs": [
"the mint of the fee token"
]
},
{
"name": "fee_token_account",
"docs": [
"the program-level fee vault, initialized with global config"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "program_authority"
},
{
"kind": "account",
"path": "token_program_fee"
},
{
"kind": "account",
"path": "fee_token_mint_address"
}
],
"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_fee",
"docs": [
"the token program for the fee token"
]
},
{
"name": "associated_token_program",
"address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
},
{
"name": "system_program",
"docs": [
"the system program, used to initialize the account"
],
"address": "11111111111111111111111111111111"
}
],
"args": [
{
"name": "fee_wallet",
"type": "pubkey"
},
{
"name": "protocol_fees_bps",
"type": "u16"
},
{
"name": "spread_protocol_fees_bps",
"type": "u16"
},
{
"name": "fee_token_mint",
"type": "pubkey"
}
]
},
{
"name": "init_pair",
"docs": [
"Initialises a new quote/base trading pair for a capital provider.",
"",
"Flow:",
"- Validates fee rates and that the two mints are distinct.",
"- Creates or increments `UserVaultInfo` PDAs for both mints.",
"- Initialises vault ATAs (owned by `lp_vault_authority`) and the capital provider fee ATA (owned by `lp_fee_vault_authority`).",
"- Increments `used_in_pairs_count` on both asset configs.",
"- Creates `LpStableConfig` PDAs for any stable token mints in the pair.",
"",
"Parameters:",
"- `redemption_fee_bps`: Fee applied when swapping base → quote (selling RWA), in basis points.",
"- `discount_rate_bps`: Fee applied when swapping quote → base (buying RWA), in basis points."
],
"discriminator": [
210,
79,
92,
60,
153,
69,
57,
157
],
"accounts": [
{
"name": "liquidity_provider",
"docs": [
"the capital provider, must sign to initialize its own pair"
],
"writable": true,
"signer": true
},
{
"name": "pair",
"docs": [
"the pair account, will be initialized"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
112,
97,
105,
114
]
},
{
"kind": "account",
"path": "liquidity_provider"
},
{
"kind": "account",
"path": "quote_token_mint_address"
},
{
"kind": "account",
"path": "base_token_mint_address"
}
]
}
},
{
"name": "quote_token_mint_address",
"docs": [
"the mint address of the pair's quote token"
]
},
{
"name": "base_token_mint_address",
"docs": [
"the mint address of the pair's base token"
]
},
{
"name": "lp_vault_authority",
"docs": [
"the capital provider's vault authority used to own capital provider's token accounts"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
118,
97,
117,
108,
116,
95,
97,
117,
116,
104,
111,
114,
105,
116,
121
]
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "lp_fee_vault_authority",
"docs": [
"the separate capital provider fee vault authority used to own the capital provider's protocol-fee token account"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
108,
112,
95,
102,
101,
101,
95,
118,
97,
117,
108,
116,
95,
97,
117,
116,
104,
111,
114,
105,
116,
121
]
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "quote_token_vault_token_account",
"docs": [
"the vault token account for the quote token"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "lp_vault_authority"
},
{
"kind": "account",
"path": "token_program_quote"
},
{
"kind": "account",
"path": "quote_token_mint_address"
}
],
"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": "base_token_vault_token_account",
"docs": [
"the vault token account for the base token"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "lp_vault_authority"
},
{
"kind": "account",
"path": "token_program_base"
},
{
"kind": "account",
"path": "base_token_mint_address"
}
],
"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": "lp_vault_quote_pda",
"docs": [
"the capital provider vault info for the quote token"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
117,
115,
101,
114,
95,
118,
97,
117,
108,
116,
95,
105,
110,
102,
111
]
},
{
"kind": "account",
"path": "quote_token_mint_address"
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "lp_vault_base_pda",
"docs": [
"the capital provider vault info for the base token"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
117,
115,
101,
114,
95,
118,
97,
117,
108,
116,
95,
105,
110,
102,
111
]
},
{
"kind": "account",
"path": "base_token_mint_address"
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "global_config",
"docs": [
"the global config, used to check the pause state and the fee token mint"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
103,
108,
111,
98,
97,
108,
95,
99,
111,
110,
102,
105,
103
]
}
]
}
},
{
"name": "fee_token_mint_address",
"docs": [
"the mint address used by capital providers to pay protocol fees"
]
},
{
"name": "lp_fee_token_account",
"docs": [
"the capital provider's protocol-fee token account"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "lp_fee_vault_authority"
},
{
"kind": "account",
"path": "token_program_fee"
},
{
"kind": "account",
"path": "fee_token_mint_address"
}
],
"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": "lp_stable_config_quote",
"docs": [
"Capital provider stable config for the quote token — Some only when quote token is Stable, None for RWA"
],
"writable": true,
"optional": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
108,
112,
95,
115,
116,
97,
98,
108,
101,
95,
99,
111,
110,
102,
105,
103
]
},
{
"kind": "account",
"path": "quote_token_mint_address"
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "lp_stable_config_base",
"docs": [
"Capital provider stable config for the base token — Some only when base token is Stable, None for RWA"
],
"writable": true,
"optional": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
108,
112,
95,
115,
116,
97,
98,
108,
101,
95,
99,
111,
110,
102,
105,
103
]
},
{
"kind": "account",
"path": "base_token_mint_address"
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "quote_asset_config",
"docs": [
"the asset config for the quote token"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
97,
115,
115,
101,
116
]
},
{
"kind": "account",
"path": "quote_token_mint_address"
}
]
}
},
{
"name": "base_asset_config",
"docs": [
"the asset config for the base token"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
97,
115,
115,
101,
116
]
},
{
"kind": "account",
"path": "base_token_mint_address"
}
]
}
},
{
"name": "token_program_quote",
"docs": [
"the token program for the quote token, could be either the token2022 or the legacy token program"
]
},
{
"name": "token_program_base",
"docs": [
"the token program for the base token, could be either the token2022 or the legacy token program"
]
},
{
"name": "token_program_fee",
"docs": [
"the token program for the fee token, could be either the token2022 or the legacy token program"
]
},
{
"name": "associated_token_program",
"address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
},
{
"name": "system_program",
"docs": [
"the system program, used to initialize the account"
],
"address": "11111111111111111111111111111111"
}
],
"args": [
{
"name": "redemption_fee_bps",
"type": "u16"
},
{
"name": "discount_rate_bps",
"type": "u16"
}
]
},
{
"name": "remove_liquidity",
"docs": [
"Withdraws tokens from the vault back to the capital provider, optionally redeeming from the treasury program.",
"",
"Flow:",
"- Checks the program pause state. Asset and capital provider stable pause flags are deliberately not",
"checked here so a capital provider can always exit a paused asset.",
"- If treasury is enabled, CPIs into the treasury `redeem` instruction to move tokens back",
"into the vault; the actual asset amount transferred to the capital provider is the vault balance delta",
"after the CPI (relevant for `ExactIn` mode where the output depends on NAV).",
"- If treasury is disabled, verifies the vault holds sufficient balance and transfers directly.",
"- Transfers the resulting token amount from the vault to the capital provider's token account.",
"",
"Parameters:",
"- `amount`: Amount to redeem, interpreted according to `exact_mode`.",
"- `treasury_nav_account_count`: Number of NAV accounts in `remaining_accounts` for the treasury CPI.",
"- `treasury_apy_account_count`: Number of APY accounts in `remaining_accounts` for the treasury CPI.",
"- `exact_mode`: `ExactOut` — `amount` is asset tokens to receive; `ExactIn` — `amount` is",
"treasury tokens to burn (output is NAV-determined). Use `ExactIn` to fully drain a position.",
"- `amount_threshold`: A floor on the assets paid out for `ExactIn`, a ceiling on the treasury tokens burned for `ExactOut`."
],
"discriminator": [
80,
85,
209,
72,
24,
206,
177,
108
],
"accounts": [
{
"name": "liquidity_provider",
"docs": [
"the capital provider, will receive the tokens back"
],
"signer": true
},
{
"name": "mint_address",
"docs": [
"the mint address of the token"
]
},
{
"name": "lp_token_account",
"docs": [
"the token account of the capital provider"
],
"writable": true
},
{
"name": "vault_token_account",
"docs": [
"the vault token account for the token"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "lp_vault_authority"
},
{
"kind": "account",
"path": "token_program"
},
{
"kind": "account",
"path": "mint_address"
}
],
"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": "lp_vault_authority",
"docs": [
"the capital provider's vault authority, used to sign the CPI transfers"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
118,
97,
117,
108,
116,
95,
97,
117,
116,
104,
111,
114,
105,
116,
121
]
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "global_config",
"docs": [
"the global config, used to check if the program is paused"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
103,
108,
111,
98,
97,
108,
95,
99,
111,
110,
102,
105,
103
]
}
]
}
},
{
"name": "lp_protocol_fee_config",
"docs": [
"Treasury toggle and protocol fee overrides for the capital provider."
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
108,
112,
95,
112,
114,
111,
116,
111,
99,
111,
108,
95,
102,
101,
101,
95,
99,
111,
110,
102,
105,
103
]
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "treasury_program",
"optional": true
},
{
"name": "treasury_global_config",
"optional": true
},
{
"name": "treasury_asset_config",
"optional": true
},
{
"name": "treasury_user_position",
"writable": true,
"optional": true
},
{
"name": "treasury_vault_authority",
"optional": true
},
{
"name": "treasury_mint",
"writable": true,
"optional": true
},
{
"name": "treasury_user_treasury_token_account",
"writable": true,
"optional": true
},
{
"name": "treasury_asset_vault",
"writable": true,
"optional": true
},
{
"name": "treasury_latest_apy_entry",
"optional": true
},
{
"name": "treasury_token_program",
"optional": true
},
{
"name": "treasury_associated_token_program",
"optional": true
},
{
"name": "token_program",
"docs": [
"the token program for the token, could be either the token2022 or the legacy token program"
]
}
],
"args": [
{
"name": "amount",
"type": "u64"
},
{
"name": "treasury_nav_account_count",
"type": "u8"
},
{
"name": "treasury_apy_account_count",
"type": "u8"
},
{
"name": "exact_mode",
"type": {
"defined": {
"name": "ExactMode"
}
}
},
{
"name": "amount_threshold",
"type": {
"option": "u64"
}
}
]
},
{
"name": "set_lp_protocol_fee_config",
"docs": [
"Sets or updates protocol fee overrides for the capital provider.",
"",
"Flow:",
"- Only callable by the admin.",
"- Creates the `LpProtocolFeeConfig` PDA if it does not yet exist.",
"- Stores fee rates per capital provider.",
"",
"Parameters:",
"- `protocol_fees_bps`: Issuer protocol fee rate for the capital provider in basis points.",
"- `spread_protocol_fees_bps`: Spread protocol fee rate for the capital provider in basis points."
],
"discriminator": [
116,
84,
221,
0,
37,
34,
202,
205
],
"accounts": [
{
"name": "admin",
"writable": true,
"signer": true,
"relations": [
"global_config"
]
},
{
"name": "global_config",
"pda": {
"seeds": [
{
"kind": "const",
"value": [
103,
108,
111,
98,
97,
108,
95,
99,
111,
110,
102,
105,
103
]
}
]
}
},
{
"name": "lp_protocol_fee_config",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
108,
112,
95,
112,
114,
111,
116,
111,
99,
111,
108,
95,
102,
101,
101,
95,
99,
111,
110,
102,
105,
103
]
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "liquidity_provider",
"docs": [
"Capital provider whose fee overrides are being set"
]
},
{
"name": "system_program",
"address": "11111111111111111111111111111111"
}
],
"args": [
{
"name": "protocol_fees_bps",
"type": "u16"
},
{
"name": "spread_protocol_fees_bps",
"type": "u16"
}
]
},
{
"name": "set_lp_treasury_enabled",
"docs": [
"Enables or disables treasury-backed liquidity routing for the signing capital provider.",
"",
"Flow:",
"- Only callable by the capital provider themselves.",
"- If the `LpProtocolFeeConfig` PDA does not yet exist it is created with the global",
"default fee rates; the capital provider pays for the account.",
"- Writes the new `treasury_enabled` flag to the capital provider's config.",
"- When opting in, tops `lp_vault_authority` up to the rent for a `UserPosition` grown to",
"treasury's `max_pending_deposit_slots` plus the receipt ATA, so no later swap fails on a",
"realloc the PDA cannot pay for. `close_treasury_position` refunds the unused remainder.",
"",
"Parameters:",
"- `enabled`: Whether the capital provider opts in (`true`) or out (`false`) of treasury routing."
],
"discriminator": [
211,
145,
194,
69,
58,
232,
85,
175
],
"accounts": [
{
"name": "liquidity_provider",
"writable": true,
"signer": true
},
{
"name": "global_config",
"pda": {
"seeds": [
{
"kind": "const",
"value": [
103,
108,
111,
98,
97,
108,
95,
99,
111,
110,
102,
105,
103
]
}
]
}
},
{
"name": "lp_protocol_fee_config",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
108,
112,
95,
112,
114,
111,
116,
111,
99,
111,
108,
95,
102,
101,
101,
95,
99,
111,
110,
102,
105,
103
]
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "lp_vault_authority",
"docs": [
"the capital provider's vault authority"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
118,
97,
117,
108,
116,
95,
97,
117,
116,
104,
111,
114,
105,
116,
121
]
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "treasury_global_config",
"docs": [
"the treasury program's global config"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
71,
76,
79,
66,
65,
76,
95,
67,
79,
78,
70,
73,
71
]
}
],
"program": {
"kind": "const",
"value": [
225,
137,
15,
93,
135,
103,
114,
68,
124,
46,
133,
205,
18,
24,
147,
212,
92,
235,
177,
70,
28,
77,
59,
174,
183,
100,
70,
152,
13,
17,
18,
174
]
}
}
},
{
"name": "treasury_mint",
"docs": [
"the treasury receipt mint"
]
},
{
"name": "treasury_user_position",
"docs": [
"the capital provider's treasury position"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
85,
83,
69,
82,
95,
80,
79,
83,
73,
84,
73,
79,
78
]
},
{
"kind": "account",
"path": "lp_vault_authority"
}
],
"program": {
"kind": "const",
"value": [
225,
137,
15,
93,
135,
103,
114,
68,
124,
46,
133,
205,
18,
24,
147,
212,
92,
235,
177,
70,
28,
77,
59,
174,
183,
100,
70,
152,
13,
17,
18,
174
]
}
}
},
{
"name": "system_program",
"address": "11111111111111111111111111111111"
}
],
"args": [
{
"name": "enabled",
"type": "bool"
}
]
},
{
"name": "set_new_admin",
"docs": [
"Begins an admin transfer by recording a pending admin chosen by the current admin.",
"",
"Flow:",
"- Verified through the `has_one = admin` constraint on `GlobalConfig`.",
"- Stores `new_admin` as `GlobalConfig.pending_admin`.",
"- Transfer is completed by the pending admin calling `confirm_new_admin`.",
"",
"Parameters:",
"- `new_admin`: Public key of the account that will become the new admin."
],
"discriminator": [
62,
156,
4,
148,
79,
162,
148,
252
],
"accounts": [
{
"name": "global_config",
"docs": [
"the global config account, will be updated"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
103,
108,
111,
98,
97,
108,
95,
99,
111,
110,
102,
105,
103
]
}
]
}
},
{
"name": "admin",
"docs": [
"the multi liquid admin"
],
"signer": true,
"relations": [
"global_config"
]
}
],
"args": [
{
"name": "new_admin",
"type": "pubkey"
}
]
},
{
"name": "set_paused_for_asset",
"docs": [
"Pauses or unpauses all swaps involving a specific asset globally.",
"",
"Flow:",
"- Only callable by the admin.",
"- Writes the new pause flag to `AssetConfig.paused`.",
"",
"Parameters:",
"- `paused`: New pause state for this asset across all pairs."
],
"discriminator": [
116,
141,
145,
189,
67,
108,
178,
238
],
"accounts": [
{
"name": "global_config",
"docs": [
"global config account, used to check the admin"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
103,
108,
111,
98,
97,
108,
95,
99,
111,
110,
102,
105,
103
]
}
]
}
},
{
"name": "asset_config",
"docs": [
"RWA config account, used to update the paused state"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
97,
115,
115,
101,
116
]
},
{
"kind": "account",
"path": "mint_address"
}
]
}
},
{
"name": "mint_address",
"docs": [
"the mint address of the RWA token"
]
},
{
"name": "admin",
"docs": [
"the multi liquid admin"
],
"writable": true,
"signer": true,
"relations": [
"global_config"
]
}
],
"args": [
{
"name": "paused",
"type": "bool"
}
]
},
{
"name": "set_paused_for_lp_stable_config",
"docs": [
"Pauses or unpauses all swaps through this capital provider's quote token for a given stable mint.",
"",
"Flow:",
"- The capital provider signs; the `LpStableConfig` PDA is verified by seeds.",
"- Writes the new pause flag to `LpStableConfig.paused`.",
"",
"Parameters:",
"- `paused`: New pause state for this capital provider's stable mint configuration."
],
"discriminator": [
214,
35,
14,
32,
51,
46,
101,
150
],
"accounts": [
{
"name": "global_config",
"docs": [
"global config account, used to authorize the admin signer"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
103,
108,
111,
98,
97,
108,
95,
99,
111,
110,
102,
105,
103
]
}
]
}
},
{
"name": "lp_stable_config",
"docs": [
"Capital provider stable config account, used to update the paused state"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
108,
112,
95,
115,
116,
97,
98,
108,
101,
95,
99,
111,
110,
102,
105,
103
]
},
{
"kind": "account",
"path": "mint_address"
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "mint_address",
"docs": [
"the mint address of the stable coin"
]
},
{
"name": "liquidity_provider",
"docs": [
"the capital provider"
]
},
{
"name": "signer",
"docs": [
"the signer, could be either multiliquid admin, or the capital provider"
],
"signer": true
}
],
"args": [
{
"name": "paused",
"type": "bool"
}
]
},
{
"name": "swap",
"docs": [
"Executes a swap between the quote token and the base token for a given pair.",
"",
"Flow:",
"- Checks program, pair, RWA, and stable pause states.",
"- Reads NAV for the base (RWA) token and calculates swap amounts with fees.",
"- Computes the protocol fee from the capital provider's fee account and transfers it to the global fee vault.",
"- Transfers tokens between the trader and the capital provider's vault (via SPL transfer-checked).",
"- If treasury is enabled for the capital provider, routes vault movements through the treasury CPI.",
"",
"Parameters:",
"- `amount`: Exact input or output amount depending on `swap_type`.",
"- `min_amount_out`: Slippage guard for ExactIn swaps; the instruction errors if output is below this.",
"- `max_amount_in`: Slippage guard for ExactOut swaps; the instruction errors if input exceeds this.",
"- `swap_direction`: `QuoteToBase` (buy RWA) or `BaseToQuote` (sell RWA).",
"- `swap_type`: `ExactIn` (fixed input) or `ExactOut` (fixed output).",
"- `treasury_nav_account_count`: Number of NAV accounts in `remaining_accounts` for the treasury CPI.",
"- `treasury_apy_account_count`: Number of APY accounts in `remaining_accounts` for the treasury CPI."
],
"discriminator": [
248,
198,
158,
145,
225,
117,
135,
200
],
"accounts": [
{
"name": "user",
"docs": [
"the trader"
],
"writable": true,
"signer": true
},
{
"name": "pair",
"docs": [
"the pair account"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
112,
97,
105,
114
]
},
{
"kind": "account",
"path": "liquidity_provider"
},
{
"kind": "account",
"path": "quote_token_mint_address"
},
{
"kind": "account",
"path": "base_token_mint_address"
}
]
}
},
{
"name": "program_authority",
"docs": [
"the program authority, used to sign the CPI transfers"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
112,
114,
111,
103,
114,
97,
109,
95,
97,
117,
116,
104,
111,
114,
105,
116,
121
]
}
]
}
},
{
"name": "liquidity_provider",
"docs": [
"Capital provider, must be the capital provider of the pair"
]
},
{
"name": "lp_vault_authority",
"docs": [
"the capital provider's vault authority, used to sign capital provider vault transfers"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
118,
97,
117,
108,
116,
95,
97,
117,
116,
104,
111,
114,
105,
116,
121
]
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "lp_fee_vault_authority",
"docs": [
"the separate capital provider fee vault authority used to own the capital provider's protocol-fee token account"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
108,
112,
95,
102,
101,
101,
95,
118,
97,
117,
108,
116,
95,
97,
117,
116,
104,
111,
114,
105,
116,
121
]
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "quote_token_mint_address",
"docs": [
"the mint address of the quote token"
]
},
{
"name": "base_token_mint_address",
"docs": [
"the mint address of the base token"
]
},
{
"name": "base_token_user_token_account",
"docs": [
"the token account of the base token, owned by the trader"
],
"writable": true
},
{
"name": "quote_token_user_token_account",
"docs": [
"the token account of the quote token, owned by the trader"
],
"writable": true
},
{
"name": "quote_token_vault_token_account",
"docs": [
"the vault token account for the quote token"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "lp_vault_authority"
},
{
"kind": "account",
"path": "token_program_quote"
},
{
"kind": "account",
"path": "quote_token_mint_address"
}
],
"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": "base_token_vault_token_account",
"docs": [
"the vault token account for the base token"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "lp_vault_authority"
},
{
"kind": "account",
"path": "token_program_base"
},
{
"kind": "account",
"path": "base_token_mint_address"
}
],
"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": "global_config",
"docs": [
"the global config, used to check if the program is paused"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
103,
108,
111,
98,
97,
108,
95,
99,
111,
110,
102,
105,
103
]
}
]
}
},
{
"name": "fee_token_mint_address",
"docs": [
"the mint address used by capital providers to pay protocol fees"
]
},
{
"name": "lp_fee_token_account",
"docs": [
"the capital provider's protocol-fee token account"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "lp_fee_vault_authority"
},
{
"kind": "account",
"path": "token_program_fee"
},
{
"kind": "account",
"path": "fee_token_mint_address"
}
],
"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": "fee_token_account",
"docs": [
"the fee vault token account for the global fee token, initialized in init_global_config"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "program_authority"
},
{
"kind": "account",
"path": "token_program_fee"
},
{
"kind": "account",
"path": "fee_token_mint_address"
}
],
"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": "base_config",
"docs": [
"the asset config account for the base token"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
97,
115,
115,
101,
116
]
},
{
"kind": "account",
"path": "base_token_mint_address"
}
]
}
},
{
"name": "quote_config",
"docs": [
"the asset config account for the quote token"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
97,
115,
115,
101,
116
]
},
{
"kind": "account",
"path": "quote_token_mint_address"
}
]
}
},
{
"name": "fee_config",
"docs": [
"the asset config account for the global fee token"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
97,
115,
115,
101,
116
]
},
{
"kind": "account",
"path": "fee_token_mint_address"
}
]
}
},
{
"name": "lp_stable_config_quote",
"docs": [
"Capital provider stable config for the quote token — Some only when quote token is Stable, None for RWA"
],
"optional": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
108,
112,
95,
115,
116,
97,
98,
108,
101,
95,
99,
111,
110,
102,
105,
103
]
},
{
"kind": "account",
"path": "quote_token_mint_address"
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "lp_stable_config_base",
"docs": [
"Capital provider stable config for the base token — Some only when base token is Stable, None for RWA"
],
"optional": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
108,
112,
95,
115,
116,
97,
98,
108,
101,
95,
99,
111,
110,
102,
105,
103
]
},
{
"kind": "account",
"path": "base_token_mint_address"
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "lp_protocol_fee_config",
"docs": [
"Protocol fee overrides for the capital provider, if initialized"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
108,
112,
95,
112,
114,
111,
116,
111,
99,
111,
108,
95,
102,
101,
101,
95,
99,
111,
110,
102,
105,
103
]
},
{
"kind": "account",
"path": "liquidity_provider"
}
]
}
},
{
"name": "token_program_quote",
"docs": [
"the token program for the quote token, could be either the token2022 or the legacy token program"
]
},
{
"name": "token_program_base",
"docs": [
"the token program for the base token, could be either the token2022 or the legacy token program"
]
},
{
"name": "token_program_fee",
"docs": [
"the token program for the fee token, could be either the token2022 or the legacy token program"
]
}
],
"args": [
{
"name": "amount",
"type": "u64"
},
{
"name": "min_amount_out",
"type": {
"option": "u64"
}
},
{
"name": "max_amount_in",
"type": {
"option": "u64"
}
},
{
"name": "swap_direction",
"type": {
"defined": {
"name": "SwapDirection"
}
}
},
{
"name": "swap_type",
"type": {
"defined": {
"name": "SwapType"
}
}
},
{
"name": "treasury_nav_account_count",
"type": "u8"
},
{
"name": "treasury_apy_account_count",
"type": "u8"
}
]
},
{
"name": "update_asset_config_account",
"docs": [
"Updates the NAV sources or price-difference bound for an existing asset config.",
"",
"Flow:",
"- Validates updated NAV sources and price-difference bound.",
"- Overwrites the `AssetConfig` fields; the asset type cannot be changed.",
"",
"Parameters:",
"- `nav_data`: Replacement NAV source definitions (up to 5).",
"- `price_difference_bps`: Updated maximum permitted NAV divergence in basis points.",
"- `asset_type`: Must match the existing asset type (validated by the instruction)."
],
"discriminator": [
217,
201,
225,
177,
234,
99,
234,
162
],
"accounts": [
{
"name": "asset_config",
"docs": [
"the RWA config account, will be updated"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
97,
115,
115,
101,
116
]
},
{
"kind": "account",
"path": "mint_address"
}
]
}
},
{
"name": "mint_address",
"docs": [
"the mint address of the RWA token (used in seeds)"
]
},
{
"name": "admin",
"docs": [
"the multi liquid admin"
],
"signer": true,
"relations": [
"global_config"
]
},
{
"name": "global_config",
"docs": [
"the global config account, used to check the admin"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
103,
108,
111,
98,
97,
108,
95,
99,
111,
110,
102,
105,
103
]
}
]
}
}
],
"args": [
{
"name": "nav_data",
"type": {
"vec": {
"defined": {
"name": "NavData"
}
}
}
},
{
"name": "price_difference_bps",
"type": "u16"
},
{
"name": "asset_type",
"type": {
"defined": {
"name": "AssetType"
}
}
}
]
},
{
"name": "update_global_config",
"docs": [
"Updates one or more fields of the global configuration.",
"",
"Flow:",
"- Validates updated fee rates if provided.",
"- Applies each `Some(value)` field; `None` fields are left unchanged.",
"",
"Parameters:",
"- `fee_wallet`: New fee wallet recipient, or `None` to leave unchanged.",
"- `paused`: New pause state, or `None` to leave unchanged.",
"- `protocol_fees_bps`: New default issuer fee rate, or `None` to leave unchanged.",
"- `spread_protocol_fees_bps`: New default spread fee rate, or `None` to leave unchanged.",
"- `fee_token_mint`: New fee token mint, or `None` to leave unchanged."
],
"discriminator": [
164,
84,
130,
189,
111,
58,
250,
200
],
"accounts": [
{
"name": "global_config",
"docs": [
"the global config account, will be updated"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
103,
108,
111,
98,
97,
108,
95,
99,
111,
110,
102,
105,
103
]
}
]
}
},
{
"name": "admin",
"docs": [
"the multi liquid admin"
],
"signer": true,
"relations": [
"global_config"
]
}
],
"args": [
{
"name": "fee_wallet",
"type": {
"option": "pubkey"
}
},
{
"name": "paused",
"type": {
"option": "bool"
}
},
{
"name": "protocol_fees_bps",
"type": {
"option": "u16"
}
},
{
"name": "spread_protocol_fees_bps",
"type": {
"option": "u16"
}
},
{
"name": "fee_token_mint",
"type": {
"option": "pubkey"
}
}
]
},
{
"name": "update_pair",
"docs": [
"Updates the fee rates and pause state for an existing trading pair.",
"",
"Flow:",
"- Validates that the updated fee rates are within range.",
"- Writes the new fee rates and pause flag to the `Pair` account.",
"",
"Parameters:",
"- `redemption_fee_bps`: Updated base → quote fee rate in basis points.",
"- `discount_rate_bps`: Updated quote → base fee rate in basis points.",
"- `paused`: New pause state for this specific pair."
],
"discriminator": [
176,
62,
36,
215,
255,
206,
35,
12
],
"accounts": [
{
"name": "liquidity_provider",
"docs": [
"the capital provider, must be the capital provider of the pair"
],
"signer": true,
"relations": [
"pair"
]
},
{
"name": "pair",
"docs": [
"the pair account, will be updated"
],
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
112,
97,
105,
114
]
},
{
"kind": "account",
"path": "liquidity_provider"
},
{
"kind": "account",
"path": "quote_token_mint_address"
},
{
"kind": "account",
"path": "base_token_mint_address"
}
]
}
},
{
"name": "quote_token_mint_address",
"docs": [
"the mint address of the quote token (used in seeds)"
]
},
{
"name": "base_token_mint_address",
"docs": [
"the mint address of the base token (used in seeds)"
]
},
{
"name": "global_config",
"docs": [
"the global config account, used to check if the program is paused"
],
"pda": {
"seeds": [
{
"kind": "const",
"value": [
103,
108,
111,
98,
97,
108,
95,
99,
111,
110,
102,
105,
103
]
}
]
}
}
],
"args": [
{
"name": "redemption_fee_bps",
"type": "u16"
},
{
"name": "discount_rate_bps",
"type": "u16"
},
{
"name": "paused",
"type": "bool"
}
]
}
],
"accounts": [
{
"name": "AssetConfig",
"discriminator": [
57,
112,
247,
166,
247,
64,
140,
23
]
},
{
"name": "GlobalConfig",
"discriminator": [
149,
8,
156,
202,
160,
252,
176,
217
]
},
{
"name": "LpProtocolFeeConfig",
"discriminator": [
135,
75,
123,
10,
42,
109,
206,
172
]
},
{
"name": "LpStableConfig",
"discriminator": [
178,
48,
23,
140,
152,
86,
22,
226
]
},
{
"name": "Pair",
"discriminator": [
85,
72,
49,
176,
182,
228,
141,
82
]
},
{
"name": "UserVaultInfo",
"discriminator": [
100,
30,
4,
32,
178,
226,
105,
0
]
}
],
"events": [
{
"name": "AdminChanged",
"discriminator": [
232,
34,
31,
226,
62,
18,
19,
114
]
},
{
"name": "AssetConfigInitialized",
"discriminator": [
155,
228,
155,
62,
174,
164,
61,
147
]
},
{
"name": "AssetConfigUpdated",
"discriminator": [
12,
97,
64,
94,
123,
177,
111,
10
]
},
{
"name": "AssetPauseChanged",
"discriminator": [
30,
56,
152,
180,
133,
188,
179,
249
]
},
{
"name": "FeesClaimed",
"discriminator": [
22,
104,
110,
222,
38,
157,
14,
62
]
},
{
"name": "GlobalConfigInitialized",
"discriminator": [
5,
221,
172,
158,
77,
87,
157,
113
]
},
{
"name": "GlobalConfigUpdated",
"discriminator": [
232,
238,
158,
123,
210,
172,
159,
46
]
},
{
"name": "LiquidityAdded",
"discriminator": [
154,
26,
221,
108,
238,
64,
217,
161
]
},
{
"name": "LiquidityRemoved",
"discriminator": [
225,
105,
216,
39,
124,
116,
169,
189
]
},
{
"name": "LpFeeAccountClosed",
"discriminator": [
103,
159,
170,
253,
58,
140,
131,
138
]
},
{
"name": "LpProtocolFeeConfigUpdated",
"discriminator": [
58,
157,
1,
126,
238,
158,
141,
180
]
},
{
"name": "LpStableConfigPauseChanged",
"discriminator": [
127,
23,
108,
124,
24,
91,
232,
50
]
},
{
"name": "LpTreasuryEnabledChanged",
"discriminator": [
105,
98,
154,
187,
217,
205,
205,
126
]
},
{
"name": "NewAdminProposed",
"discriminator": [
28,
150,
26,
229,
207,
97,
30,
242
]
},
{
"name": "PairClosed",
"discriminator": [
44,
133,
115,
118,
95,
41,
87,
136
]
},
{
"name": "PairInitialized",
"discriminator": [
32,
143,
168,
185,
98,
225,
71,
148
]
},
{
"name": "PairUpdated",
"discriminator": [
208,
67,
143,
117,
86,
212,
167,
194
]
},
{
"name": "SwapExecuted",
"discriminator": [
150,
166,
26,
225,
28,
89,
38,
79
]
},
{
"name": "TreasuryPositionClosed",
"discriminator": [
180,
80,
87,
94,
238,
17,
237,
43
]
}
],
"errors": [
{
"code": 6000,
"name": "InvalidNav",
"msg": "Invalid NAV"
},
{
"code": 6001,
"name": "ConfidenceTooLow",
"msg": "Confidence too low"
},
{
"code": 6002,
"name": "OutOfRange",
"msg": "Out of range"
},
{
"code": 6003,
"name": "MustProvideAtLeastOneNavData",
"msg": "Must provide at least one NAV data"
},
{
"code": 6004,
"name": "MustProvideHardcodedPrice",
"msg": "Must provide hardcoded price"
},
{
"code": 6005,
"name": "ProgramPaused",
"msg": "Program paused"
},
{
"code": 6006,
"name": "AmountMustBePositive",
"msg": "Amount must be positive"
},
{
"code": 6007,
"name": "InsufficientLiquidity",
"msg": "Insufficient liquidity"
},
{
"code": 6008,
"name": "PairPaused",
"msg": "Pair paused"
},
{
"code": 6009,
"name": "RwaPaused",
"msg": "RWA paused"
},
{
"code": 6010,
"name": "StablePaused",
"msg": "Stable paused"
},
{
"code": 6011,
"name": "Max5NavData",
"msg": "Max 5 NAV data"
},
{
"code": 6012,
"name": "SwapAmountTooSmall",
"msg": "Swap amount too small"
},
{
"code": 6013,
"name": "DiscountMustBePositive",
"msg": "Discount must be positive"
},
{
"code": 6014,
"name": "AmountInMustBePositive",
"msg": "Amount in must be positive"
},
{
"code": 6015,
"name": "AmountOutMustBePositive",
"msg": "Amount out must be positive"
},
{
"code": 6016,
"name": "PriceDecimalsTooLarge",
"msg": "Price decimals too large"
},
{
"code": 6017,
"name": "Unauthorized",
"msg": "Unauthorized"
},
{
"code": 6018,
"name": "MathOverflow",
"msg": "Math Overflow"
},
{
"code": 6019,
"name": "MathUnderflow",
"msg": "Math Underflow"
},
{
"code": 6020,
"name": "InvalidAssetType",
"msg": "Invalid asset type"
},
{
"code": 6021,
"name": "NavMustBePositive",
"msg": "Nav must be positive"
},
{
"code": 6022,
"name": "FeesOutOfRange",
"msg": "Fees out of range"
},
{
"code": 6023,
"name": "AssetConfigInUse",
"msg": "Asset config in use"
},
{
"code": 6024,
"name": "InvalidNewAdmin",
"msg": "Invalid new admin"
},
{
"code": 6025,
"name": "InvalidAccountPublicKey",
"msg": "Invalid account public key"
},
{
"code": 6026,
"name": "AmountInTooHigh",
"msg": "Amount in too high"
},
{
"code": 6027,
"name": "AmountOutTooLow",
"msg": "Amount out too low"
},
{
"code": 6028,
"name": "InsufficientLpFeeBalance",
"msg": "Insufficient LP fee balance"
},
{
"code": 6029,
"name": "InvalidFeedId",
"msg": "Invalid pyth feed id"
},
{
"code": 6030,
"name": "InvalidMaxAge",
"msg": "Pyth max age must be > 0"
},
{
"code": 6031,
"name": "MaxAgeTooLarge",
"msg": "Pyth max age too high"
},
{
"code": 6032,
"name": "ConfBpsTooLarge",
"msg": "Pyth max conf too high"
},
{
"code": 6033,
"name": "MissingPythAccount",
"msg": "Pyth feed missing from remaining accounts"
},
{
"code": 6034,
"name": "FeedIdMismatch",
"msg": "Pyth feed mismatch"
},
{
"code": 6035,
"name": "MissingTreasuryAccounts",
"msg": "Missing treasury accounts"
},
{
"code": 6036,
"name": "InvalidTreasuryProgram",
"msg": "Invalid treasury program"
},
{
"code": 6037,
"name": "TreasuryBalanceNonZero",
"msg": "Treasury balance is non-zero"
},
{
"code": 6038,
"name": "MissingLpStableConfig",
"msg": "LP stable config must be provided for stable tokens"
},
{
"code": 6039,
"name": "NonCanonicalTokenOrder",
"msg": "Quote mint must be lexicographically less than base mint"
},
{
"code": 6040,
"name": "InvalidTreasuryMint",
"msg": "Invalid treasury mint"
},
{
"code": 6041,
"name": "TransferFeeNotSupported",
"msg": "Mints charging a Token-2022 transfer fee are not supported"
},
{
"code": 6042,
"name": "InvalidTokenExtensionData",
"msg": "Token-2022 extension data could not be decoded"
},
{
"code": 6043,
"name": "UnauthorizedInitializer",
"msg": "Caller must be the program upgrade authority"
},
{
"code": 6044,
"name": "LpVaultAuthorityUnderfunded",
"msg": "LP vault authority has insufficient SOL to fund the treasury position rent"
},
{
"code": 6045,
"name": "FeeAssetPaused",
"msg": "Protocol fee asset paused"
},
{
"code": 6046,
"name": "SignerInRemainingAccounts",
"msg": "Remaining accounts must not contain signers"
}
],
"types": [
{
"name": "AdminChanged",
"type": {
"kind": "struct",
"fields": [
{
"name": "old_admin",
"type": "pubkey"
},
{
"name": "new_admin",
"type": "pubkey"
}
]
}
},
{
"name": "AssetConfig",
"docs": [
"State that tracks configurations related to a specific asset (RWA or stable).",
"PDA seeds [b\"asset\", asset_mint_address]"
],
"type": {
"kind": "struct",
"fields": [
{
"name": "mint_address",
"docs": [
"asset mint address"
],
"type": "pubkey"
},
{
"name": "nav_data",
"docs": [
"NAV data"
],
"type": {
"vec": {
"defined": {
"name": "NavData"
}
}
}
},
{
"name": "price_difference_bps",
"docs": [
"the max and min prices fetched with the vec above should not have",
"a bigger difference than this BPS"
],
"type": "u16"
},
{
"name": "paused",
"docs": [
"whether this asset is paused at a program level"
],
"type": "bool"
},
{
"name": "version",
"docs": [
"version of the NavData struct"
],
"type": "u8"
},
{
"name": "asset_type",
"docs": [
"type of the asset"
],
"type": {
"defined": {
"name": "AssetType"
}
}
},
{
"name": "used_in_pairs_count",
"docs": [
"how many times this asset is set in a pair"
],
"type": "u16"
},
{
"name": "bump",
"docs": [
"bump"
],
"type": "u8"
},
{
"name": "padding",
"docs": [
"padding in case we need to add more fields in the future (128 bytes for each NavData)"
],
"type": {
"vec": {
"array": [
"u8",
128
]
}
}
}
]
}
},
{
"name": "AssetConfigInitialized",
"type": {
"kind": "struct",
"fields": [
{
"name": "asset_config",
"type": "pubkey"
},
{
"name": "mint",
"type": "pubkey"
},
{
"name": "asset_type",
"type": {
"defined": {
"name": "AssetType"
}
}
},
{
"name": "price_difference_bps",
"type": "u16"
},
{
"name": "nav_data",
"type": {
"vec": {
"defined": {
"name": "NavData"
}
}
}
}
]
}
},
{
"name": "AssetConfigUpdated",
"type": {
"kind": "struct",
"fields": [
{
"name": "asset_config",
"type": "pubkey"
},
{
"name": "mint",
"type": "pubkey"
},
{
"name": "asset_type",
"type": {
"defined": {
"name": "AssetType"
}
}
},
{
"name": "price_difference_bps",
"type": "u16"
},
{
"name": "nav_data",
"type": {
"vec": {
"defined": {
"name": "NavData"
}
}
}
}
]
}
},
{
"name": "AssetPauseChanged",
"type": {
"kind": "struct",
"fields": [
{
"name": "mint",
"type": "pubkey"
},
{
"name": "paused",
"type": "bool"
}
]
}
},
{
"name": "AssetType",
"type": {
"kind": "enum",
"variants": [
{
"name": "Rwa"
},
{
"name": "Stable"
}
]
}
},
{
"name": "ExactMode",
"type": {
"kind": "enum",
"variants": [
{
"name": "ExactIn"
},
{
"name": "ExactOut"
}
]
}
},
{
"name": "FeesClaimed",
"type": {
"kind": "struct",
"fields": [
{
"name": "fee_wallet",
"type": "pubkey"
},
{
"name": "fee_mint",
"type": "pubkey"
},
{
"name": "amount",
"type": "u64"
}
]
}
},
{
"name": "GlobalConfig",
"docs": [
"Multiliquid swap program global configration",
"PDA seeds [b\"global_config\"]"
],
"type": {
"kind": "struct",
"fields": [
{
"name": "admin",
"docs": [
"MultiLiquid admin"
],
"type": "pubkey"
},
{
"name": "fee_wallet",
"docs": [
"Wallet address that has the ability to withdraw the fees"
],
"type": "pubkey"
},
{
"name": "protocol_fees_bps",
"docs": [
"Protocol fee in basis points (0-10000)"
],
"type": "u16"
},
{
"name": "paused",
"docs": [
"whether the whole app is paused"
],
"type": "bool"
},
{
"name": "pending_new_admin",
"docs": [
"the new admin that is pending to be set"
],
"type": {
"option": "pubkey"
}
},
{
"name": "bump",
"docs": [
"bump"
],
"type": "u8"
},
{
"name": "fee_token_mint",
"docs": [
"This would be the token that every capital provider has to maintain a balance of, to pay protocol fees."
],
"type": "pubkey"
},
{
"name": "spread_protocol_fees_bps",
"docs": [
"Protocol fee in basis points charged on spread fees (0-10000)"
],
"type": "u16"
},
{
"name": "padding",
"docs": [
"add some padding"
],
"type": {
"array": [
"u8",
94
]
}
}
]
}
},
{
"name": "GlobalConfigInitialized",
"type": {
"kind": "struct",
"fields": [
{
"name": "admin",
"type": "pubkey"
},
{
"name": "fee_wallet",
"type": "pubkey"
},
{
"name": "protocol_fees_bps",
"type": "u16"
},
{
"name": "spread_protocol_fees_bps",
"type": "u16"
},
{
"name": "fee_token_mint",
"type": "pubkey"
},
{
"name": "paused",
"type": "bool"
}
]
}
},
{
"name": "GlobalConfigUpdated",
"type": {
"kind": "struct",
"fields": [
{
"name": "fee_wallet",
"type": "pubkey"
},
{
"name": "paused",
"type": "bool"
},
{
"name": "protocol_fees_bps",
"type": "u16"
},
{
"name": "spread_protocol_fees_bps",
"type": "u16"
},
{
"name": "fee_token_mint",
"type": "pubkey"
}
]
}
},
{
"name": "LiquidityAdded",
"type": {
"kind": "struct",
"fields": [
{
"name": "liquidity_provider",
"type": "pubkey"
},
{
"name": "mint_address",
"type": "pubkey"
},
{
"name": "amount",
"docs": [
"tokens pulled from the capital provider into the vault"
],
"type": "u64"
},
{
"name": "treasury_deposit_amount",
"docs": [
"vault balance swept into the treasury, 0 when no sweep happened"
],
"type": "u64"
}
]
}
},
{
"name": "LiquidityRemoved",
"type": {
"kind": "struct",
"fields": [
{
"name": "liquidity_provider",
"type": "pubkey"
},
{
"name": "mint_address",
"type": "pubkey"
},
{
"name": "amount",
"docs": [
"the raw `amount` argument, interpreted per `exact_mode`"
],
"type": "u64"
},
{
"name": "amount_transferred",
"docs": [
"asset tokens actually sent back to the capital provider"
],
"type": "u64"
},
{
"name": "treasury_backed",
"docs": [
"whether the withdrawal was served by redeeming from the treasury"
],
"type": "bool"
}
]
}
},
{
"name": "LpFeeAccountClosed",
"type": {
"kind": "struct",
"fields": [
{
"name": "liquidity_provider",
"type": "pubkey"
},
{
"name": "fee_token_mint",
"type": "pubkey"
},
{
"name": "amount_returned",
"docs": [
"remaining fee balance swept back to the capital provider before the account was closed"
],
"type": "u64"
}
]
}
},
{
"name": "LpProtocolFeeConfig",
"docs": [
"Protocol fee overrides for the capital provider.",
"PDA seeds [b\"lp_protocol_fee_config\", liquidity_provider]"
],
"type": {
"kind": "struct",
"fields": [
{
"name": "liquidity_provider",
"docs": [
"Capital provider address"
],
"type": "pubkey"
},
{
"name": "protocol_fees_bps",
"docs": [
"Protocol fee in basis points charged on the issuer fee basis"
],
"type": "u16"
},
{
"name": "spread_protocol_fees_bps",
"docs": [
"Protocol fee in basis points charged on spread fees"
],
"type": "u16"
},
{
"name": "bump",
"type": "u8"
},
{
"name": "treasury_enabled",
"type": "bool"
},
{
"name": "padding",
"type": {
"array": [
"u8",
128
]
}
}
]
}
},
{
"name": "LpProtocolFeeConfigUpdated",
"type": {
"kind": "struct",
"fields": [
{
"name": "liquidity_provider",
"type": "pubkey"
},
{
"name": "protocol_fees_bps",
"type": "u16"
},
{
"name": "spread_protocol_fees_bps",
"type": "u16"
}
]
}
},
{
"name": "LpStableConfig",
"docs": [
"State that tracks capital provider configuration for a quote token.",
"PDA seeds [b\"lp_stable_config\", quote_token, liquidity_provider]"
],
"type": {
"kind": "struct",
"fields": [
{
"name": "quote_token_mint_address",
"docs": [
"mint address of the quote token"
],
"type": "pubkey"
},
{
"name": "paused",
"docs": [
"whether this capital provider quote token is paused (for all pairs)"
],
"type": "bool"
},
{
"name": "liquidity_provider",
"docs": [
"Capital provider address"
],
"type": "pubkey"
},
{
"name": "bump",
"docs": [
"bump"
],
"type": "u8"
},
{
"name": "padding",
"docs": [
"add some padding"
],
"type": {
"array": [
"u8",
128
]
}
}
]
}
},
{
"name": "LpStableConfigPauseChanged",
"type": {
"kind": "struct",
"fields": [
{
"name": "liquidity_provider",
"type": "pubkey"
},
{
"name": "mint",
"type": "pubkey"
},
{
"name": "paused",
"type": "bool"
}
]
}
},
{
"name": "LpTreasuryEnabledChanged",
"type": {
"kind": "struct",
"fields": [
{
"name": "liquidity_provider",
"type": "pubkey"
},
{
"name": "enabled",
"type": "bool"
}
]
}
},
{
"name": "NavData",
"docs": [
"NavData is used to store info about the methods to retrieve the NAV data for a specific asset.",
"Currently we support 4 methods:",
"1. U64FixedAddress: read the price from an onchain account with a fixed address.",
"2. Hardcoded: read the price from a hardcoded value.",
"3. PythPush: read the price from a pyth push account.",
"4. RedstonePush: read the price from a Redstone PriceData account."
],
"type": {
"kind": "enum",
"variants": [
{
"name": "U64FixedAddress",
"fields": [
{
"name": "nav_account_address",
"docs": [
"fixed account address"
],
"type": "pubkey"
},
{
"name": "nav_price_offset",
"docs": [
"Byte offset of the NAV"
],
"type": "u16"
},
{
"name": "price_decimals",
"docs": [
"price decimals"
],
"type": "u8"
}
]
},
{
"name": "Hardcoded",
"fields": [
{
"name": "hardcoded_price",
"docs": [
"hardcoded price"
],
"type": "u64"
},
{
"name": "price_decimals",
"docs": [
"price decimals"
],
"type": "u8"
}
]
},
{
"name": "PythPush",
"fields": [
{
"name": "pyth_push_account_address",
"docs": [
"Pyth push account address"
],
"type": "pubkey"
},
{
"name": "feed_id",
"docs": [
"Pyth feed id"
],
"type": {
"array": [
"u8",
32
]
}
},
{
"name": "max_age_secs",
"docs": [
"Maximum accepted age for the price update"
],
"type": "u64"
},
{
"name": "max_conf_bps",
"docs": [
"Maximum accepted confidence ratio in basis points"
],
"type": "u16"
}
]
},
{
"name": "RedstonePush",
"fields": [
{
"name": "price_feed_account",
"docs": [
"Redstone PriceData account address"
],
"type": "pubkey"
},
{
"name": "feed_id",
"docs": [
"Expected feed id (32 bytes)"
],
"type": {
"array": [
"u8",
32
]
}
},
{
"name": "max_age_secs",
"docs": [
"Maximum accepted age in seconds"
],
"type": "u64"
}
]
}
]
}
},
{
"name": "NewAdminProposed",
"type": {
"kind": "struct",
"fields": [
{
"name": "current_admin",
"type": "pubkey"
},
{
"name": "pending_admin",
"type": "pubkey"
}
]
}
},
{
"name": "Pair",
"docs": [
"Account that maintains state for a given quote/base token pairing.",
"PDA seeds [b\"pair\", liquidity_provider, quote_token_mint_address, base_token_mint_address]"
],
"type": {
"kind": "struct",
"fields": [
{
"name": "redemption_fee_bps",
"docs": [
"Fee applied when swapping quote to base"
],
"type": "u16"
},
{
"name": "discount_rate_bps",
"docs": [
"Fee applied when swapping base to quote"
],
"type": "u16"
},
{
"name": "quote_token_mint_address",
"docs": [
"Mint address of the quote token"
],
"type": "pubkey"
},
{
"name": "base_token_mint_address",
"docs": [
"Mint address of the base token"
],
"type": "pubkey"
},
{
"name": "liquidity_provider",
"docs": [
"liquidiy ptovider (pair owner)"
],
"type": "pubkey"
},
{
"name": "paused",
"docs": [
"if this pair is paused"
],
"type": "bool"
},
{
"name": "bump",
"docs": [
"bump"
],
"type": "u8"
},
{
"name": "padding",
"docs": [
"add some padding"
],
"type": {
"array": [
"u8",
128
]
}
}
]
}
},
{
"name": "PairClosed",
"type": {
"kind": "struct",
"fields": [
{
"name": "pair",
"type": "pubkey"
},
{
"name": "liquidity_provider",
"type": "pubkey"
},
{
"name": "quote_token_mint_address",
"type": "pubkey"
},
{
"name": "base_token_mint_address",
"type": "pubkey"
},
{
"name": "quote_amount_returned",
"docs": [
"quote tokens sent back to the capital provider, 0 when the vault stays open for another pair"
],
"type": "u64"
},
{
"name": "base_amount_returned",
"docs": [
"base tokens sent back to the capital provider, 0 when the vault stays open for another pair"
],
"type": "u64"
}
]
}
},
{
"name": "PairInitialized",
"type": {
"kind": "struct",
"fields": [
{
"name": "pair",
"type": "pubkey"
},
{
"name": "liquidity_provider",
"type": "pubkey"
},
{
"name": "quote_token_mint_address",
"type": "pubkey"
},
{
"name": "base_token_mint_address",
"type": "pubkey"
},
{
"name": "redemption_fee_bps",
"type": "u16"
},
{
"name": "discount_rate_bps",
"type": "u16"
}
]
}
},
{
"name": "PairUpdated",
"type": {
"kind": "struct",
"fields": [
{
"name": "pair",
"type": "pubkey"
},
{
"name": "liquidity_provider",
"type": "pubkey"
},
{
"name": "redemption_fee_bps",
"type": "u16"
},
{
"name": "discount_rate_bps",
"type": "u16"
},
{
"name": "paused",
"type": "bool"
}
]
}
},
{
"name": "SwapDirection",
"type": {
"kind": "enum",
"variants": [
{
"name": "QuoteToBase"
},
{
"name": "BaseToQuote"
}
]
}
},
{
"name": "SwapExecuted",
"type": {
"kind": "struct",
"fields": [
{
"name": "requestor",
"docs": [
"the trader"
],
"type": "pubkey"
},
{
"name": "amount_in",
"docs": [
"the amount in"
],
"type": "u64"
},
{
"name": "protocol_fee_amount",
"docs": [
"the protocol fee amount"
],
"type": "u64"
},
{
"name": "discount_bps",
"docs": [
"the effective pair fee bps applied to this swap"
],
"type": "u16"
},
{
"name": "amount_out",
"docs": [
"the amount out"
],
"type": "u64"
},
{
"name": "pair",
"docs": [
"the pair pubkey"
],
"type": "pubkey"
},
{
"name": "swap_direction",
"type": {
"defined": {
"name": "SwapDirection"
}
}
},
{
"name": "swap_type",
"type": {
"defined": {
"name": "SwapType"
}
}
},
{
"name": "redemption_fee_bps",
"docs": [
"raw pair redemption fee bps"
],
"type": "u16"
},
{
"name": "discount_rate_bps",
"docs": [
"raw pair discount rate bps"
],
"type": "u16"
}
]
}
},
{
"name": "SwapType",
"type": {
"kind": "enum",
"variants": [
{
"name": "ExactIn"
},
{
"name": "ExactOut"
}
]
}
},
{
"name": "TreasuryPositionClosed",
"type": {
"kind": "struct",
"fields": [
{
"name": "liquidity_provider",
"type": "pubkey"
},
{
"name": "lp_vault_authority",
"type": "pubkey"
},
{
"name": "treasury_user_position",
"type": "pubkey"
},
{
"name": "lamports_returned",
"docs": [
"rent lamports swept from the vault authority back to the capital provider"
],
"type": "u64"
}
]
}
},
{
"name": "UserVaultInfo",
"docs": [
"Vaults are shared between multiple pairs",
"We use this state to track how many pairs include a specific vault",
"PDA seeds [b\"user_vault_info\", asset_mint_address, liquidity_provider]"
],
"type": {
"kind": "struct",
"fields": [
{
"name": "user",
"docs": [
"Capital provider wallet address"
],
"type": "pubkey"
},
{
"name": "mint_address",
"docs": [
"Mint address of the vault's token"
],
"type": "pubkey"
},
{
"name": "used",
"docs": [
"Counter for how many pairs include this vault (for the same capital provider)"
],
"type": "u16"
},
{
"name": "bump",
"docs": [
"bump"
],
"type": "u8"
},
{
"name": "padding",
"docs": [
"add some padding"
],
"type": {
"array": [
"u8",
128
]
}
}
]
}
}
],
"constants": [
{
"name": "GLOBAL_CONFIG_PREFIX",
"type": "bytes",
"value": "[103, 108, 111, 98, 97, 108, 95, 99, 111, 110, 102, 105, 103]"
}
]
}
Treasury Program
Handles asset deposits and redemptions, receipt-token minting and burning, user positions, daily APY rates, and manager configuration. Program ID:GBPx215wQtoweA8NdeLuYkJ8VotSHuGLKUZKoJMMM8of
deposit and redeem accept amount, nav_account_count, apy_account_count, exact_mode, and amount_threshold. Amounts use native token units, and the optional threshold must be serialized even when it is None.
| Instruction | Mode | amount | amount_threshold |
|---|---|---|---|
deposit | ExactIn | Asset input | Minimum Treasury tokens minted |
deposit | ExactOut | Treasury tokens to mint | Maximum asset input |
redeem | ExactIn | Value in Treasury token units | Minimum asset output |
redeem | ExactOut | Asset output | Maximum Treasury tokens actually burned |
UserPosition. Redemption consumes pending deposits newest-first, then settled principal and yield proportionally. Only consumed principal is burned from the receipt-token balance.
Stable deposits begin earning after 24 hours and merge once the earning-start day’s APY has been posted. RWA deposits accrue from the deposit timestamp and merge after 24 hours once the deposit day’s APY is available. accrue_interest settles posted yield without moving tokens; redemption can include partial-day yield using the latest posted rate, subject to max_unposted_yield_seconds.
UserPosition can grow beyond its initial 50 pending-deposit slots. The configured limit is 50–300 slots; decoders must include the reallocated tail. The SDK’s treasuryProgramClient position decoder handles this layout.
Treasury Program IDL
Treasury Program IDL
treasury.json
{
"address": "GBPx215wQtoweA8NdeLuYkJ8VotSHuGLKUZKoJMMM8of",
"metadata": {
"name": "treasury",
"version": "0.1.0",
"spec": "0.1.0",
"description": "Created with Anchor"
},
"instructions": [
{
"name": "accept_manager",
"docs": [
"Completes manager transfer when the pending manager signs and accepts the role.",
"",
"Flow:",
"- Verifies the signer matches the pending manager, promotes them to manager, clears the pending manager, and emits the accept event."
],
"discriminator": [
212,
23,
254,
58,
51,
238,
232,
67
],
"accounts": [
{
"name": "pending_manager",
"signer": true
},
{
"name": "global_config",
"writable": true
}
],
"args": []
},
{
"name": "accrue_interest",
"docs": [
"Settles a user position's matured yield and pending deposits without moving tokens.",
"",
"Flow:",
"- Checks global pause state, loads APY entries, and settles principal, accumulated yield, and pending deposits.",
"- Writes the updated user position and emits the accrue-interest event."
],
"discriminator": [
47,
40,
115,
198,
91,
12,
222,
49
],
"accounts": [
{
"name": "global_config"
},
{
"name": "treasury_mint"
},
{
"name": "user_position",
"writable": true
}
],
"args": []
},
{
"name": "admin_update_user_yield",
"docs": [
"Manager-only manual override of a user's accumulated yield. Sets users credit index to current global index.",
"",
"Parameters:",
"- `accumulated_yield`: `Some(v)` sets the position's accumulated yield to `v`; `None` keeps the",
"existing value. In both cases the credit index is refreshed to the current global index."
],
"discriminator": [
58,
30,
138,
21,
235,
52,
41,
189
],
"accounts": [
{
"name": "manager",
"signer": true,
"relations": [
"global_config"
]
},
{
"name": "global_config",
"pda": {
"seeds": [
{
"kind": "const",
"value": [
71,
76,
79,
66,
65,
76,
95,
67,
79,
78,
70,
73,
71
]
}
]
}
},
{
"name": "user_position",
"writable": true
}
],
"args": [
{
"name": "accumulated_yield",
"type": {
"option": "u64"
}
}
]
},
{
"name": "close_asset_config",
"docs": [
"Sweeps any remaining asset vault balance to the manager, closes the vault/config, and decrements supported asset count.",
"",
"Flow:",
"- Signs with the vault authority PDA and sweeps any remaining vault balance to the manager.",
"- Closes the asset vault and asset config, decrements supported-asset count, and emits the close event."
],
"discriminator": [
106,
126,
17,
11,
206,
31,
41,
151
],
"accounts": [
{
"name": "manager",
"writable": true,
"signer": true,
"relations": [
"global_config"
]
},
{
"name": "global_config",
"writable": true
},
{
"name": "asset_config",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
65,
83,
83,
69,
84,
95,
67,
79,
78,
70,
73,
71
]
},
{
"kind": "account",
"path": "asset_mint"
}
]
}
},
{
"name": "vault_authority",
"pda": {
"seeds": [
{
"kind": "const",
"value": [
86,
65,
85,
76,
84,
95,
65,
85,
84,
72,
79,
82,
73,
84,
89
]
}
]
}
},
{
"name": "asset_mint"
},
{
"name": "asset_vault",
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "vault_authority"
},
{
"kind": "account",
"path": "token_program"
},
{
"kind": "account",
"path": "asset_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": "manager_asset_token_account",
"docs": [
"We need it to pre exist for token22 hooks"
],
"writable": true
},
{
"name": "token_program"
},
{
"name": "associated_token_program",
"address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
},
{
"name": "system_program",
"address": "11111111111111111111111111111111"
}
],
"args": []
},
{
"name": "close_global_config",
"docs": [
"Closes global config once all assets are removed and treasury mint supply is zero.",
"",
"Flow:",
"- Requires no supported assets and zero treasury mint supply, then closes global config to the manager.",
"- Emits the close-global-config event."
],
"discriminator": [
16,
244,
225,
240,
253,
137,
126,
39
],
"accounts": [
{
"name": "manager",
"writable": true,
"signer": true,
"relations": [
"global_config"
]
},
{
"name": "global_config",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
71,
76,
79,
66,
65,
76,
95,
67,
79,
78,
70,
73,
71
]
}
]
}
},
{
"name": "treasury_mint"
},
{
"name": "token_program"
}
],
"args": []
},
{
"name": "close_user_position",
"docs": [
"Closes an empty user position account back to the user.",
"",
"Flow:",
"- Verifies the user owns the position, requires principal/yield/pending deposits to be zero, and emits the close event."
],
"discriminator": [
111,
105,
100,
191,
82,
118,
204,
64
],
"accounts": [
{
"name": "user",
"writable": true,
"signer": true
},
{
"name": "user_position",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
85,
83,
69,
82,
95,
80,
79,
83,
73,
84,
73,
79,
78
]
},
{
"kind": "account",
"path": "user"
}
]
}
}
],
"args": []
},
{
"name": "deposit",
"docs": [
"Deposits an asset into the vault, settles user yield state, records pending deposits, and mints treasury tokens.",
"",
"Flow:",
"- Checks global/asset pause state, initializes the user position if needed, and splits NAV/APY/hook accounts.",
"- Reads NAV, settles the user's existing principal, yield, and pending deposits against APY history.",
"- Converts the requested amount using exact mode, rejects deposits below the minimum supported value, transfers assets into the vault, and mints treasury tokens.",
"- Appends the new pending deposit to the user position and emits the deposit event.",
"- Rejects the deposit when recording it would need a slot past",
"`global_config.max_pending_deposit_slots`.",
"",
"Parameters:",
"- `amount`: Amount of the asset token to deposit.",
"- `nav_account_count`: Number of NAV accounts supplied in remaining accounts.",
"- `apy_account_count`: Number of APY accounts supplied in remaining accounts.",
"- `exact_mode`: Whether the input amount is interpreted as exact asset input or exact treasury output.",
"- `amount_threshold`: Optional bound on the side `amount` does not pin: a floor on the",
"treasury tokens minted for `ExactIn`, a ceiling on the asset tokens taken for `ExactOut`."
],
"discriminator": [
242,
35,
198,
137,
82,
225,
242,
182
],
"accounts": [
{
"name": "user",
"writable": true,
"signer": true
},
{
"name": "global_config"
},
{
"name": "asset_config",
"pda": {
"seeds": [
{
"kind": "const",
"value": [
65,
83,
83,
69,
84,
95,
67,
79,
78,
70,
73,
71
]
},
{
"kind": "account",
"path": "asset_mint"
}
]
}
},
{
"name": "user_position",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
85,
83,
69,
82,
95,
80,
79,
83,
73,
84,
73,
79,
78
]
},
{
"kind": "account",
"path": "user"
}
]
}
},
{
"name": "vault_authority",
"pda": {
"seeds": [
{
"kind": "const",
"value": [
86,
65,
85,
76,
84,
95,
65,
85,
84,
72,
79,
82,
73,
84,
89
]
}
]
}
},
{
"name": "treasury_mint",
"writable": true
},
{
"name": "asset_mint"
},
{
"name": "user_asset_token_account",
"writable": true
},
{
"name": "asset_vault",
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "vault_authority"
},
{
"kind": "account",
"path": "asset_token_program"
},
{
"kind": "account",
"path": "asset_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": "user_treasury_token_account",
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "user"
},
{
"kind": "account",
"path": "treasury_token_program"
},
{
"kind": "account",
"path": "treasury_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": "asset_token_program"
},
{
"name": "treasury_token_program"
},
{
"name": "associated_token_program",
"address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
},
{
"name": "system_program",
"address": "11111111111111111111111111111111"
}
],
"args": [
{
"name": "amount",
"type": "u64"
},
{
"name": "nav_account_count",
"type": "u8"
},
{
"name": "apy_account_count",
"type": "u8"
},
{
"name": "exact_mode",
"type": {
"defined": {
"name": "ExactMode"
}
}
},
{
"name": "amount_threshold",
"type": {
"option": "u64"
}
}
]
},
{
"name": "initialize",
"docs": [
"Initializes global treasury config, validates and takes over the treasury mint, records manager/oracle/fee settings, and starts unpaused.",
"",
"Flow:",
"- Verifies the caller is the program upgrade authority through the ProgramData account.",
"- Validates the pre-created Token-2022 treasury mint, metadata, zero supply, and supported decimals.",
"- Transfers treasury mint authority from the caller to the vault authority PDA.",
"- Validates management fee and APY retention bounds.",
"- Stores the initial manager, oracle authority, treasury mint, yield index, fee settings, and pause state.",
"- Emits the initialize event with the recorded configuration.",
"",
"Parameters:",
"- `manager`: Initial operational manager stored in global config.",
"- `oracle_authority`: Authority allowed to post treasury APY data.",
"- `apy_history_retention_duration`: Minimum age before APY history entries can be pruned.",
"- `management_fee_bps`: Management fee in basis points.",
"- `max_unposted_yield_seconds`: Cap on how long the latest posted APY keeps accruing once",
"the oracle stops posting.",
"- `max_pending_deposit_slots`: Ceiling on how many pending deposit slots one `UserPosition`",
"may hold. Must be at least `DEFAULT_PENDING_CAPACITY`, the capacity every position opens",
"with. Adjustable later through `update_global_config`."
],
"discriminator": [
175,
175,
109,
31,
13,
152,
155,
237
],
"accounts": [
{
"name": "caller",
"writable": true,
"signer": true
},
{
"name": "program_data",
"pda": {
"seeds": [
{
"kind": "const",
"value": [
225,
137,
15,
93,
135,
103,
114,
68,
124,
46,
133,
205,
18,
24,
147,
212,
92,
235,
177,
70,
28,
77,
59,
174,
183,
100,
70,
152,
13,
17,
18,
174
]
}
],
"program": {
"kind": "const",
"value": [
2,
168,
246,
145,
78,
136,
161,
176,
226,
16,
21,
62,
247,
99,
174,
43,
0,
194,
185,
61,
22,
193,
36,
210,
192,
83,
122,
16,
4,
128,
0,
0
]
}
}
},
{
"name": "global_config",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
71,
76,
79,
66,
65,
76,
95,
67,
79,
78,
70,
73,
71
]
}
]
}
},
{
"name": "vault_authority",
"pda": {
"seeds": [
{
"kind": "const",
"value": [
86,
65,
85,
76,
84,
95,
65,
85,
84,
72,
79,
82,
73,
84,
89
]
}
]
}
},
{
"name": "token_program",
"address": "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"
},
{
"name": "treasury_mint",
"writable": true
},
{
"name": "system_program",
"address": "11111111111111111111111111111111"
}
],
"args": [
{
"name": "manager",
"type": "pubkey"
},
{
"name": "oracle_authority",
"type": "pubkey"
},
{
"name": "apy_history_retention_duration",
"type": "u64"
},
{
"name": "management_fee_bps",
"type": "u16"
},
{
"name": "max_unposted_yield_seconds",
"type": "u64"
},
{
"name": "max_pending_deposit_slots",
"type": "u16"
}
]
},
{
"name": "initialize_asset_config",
"docs": [
"Adds a supported asset config, creates the vault ATA, validates NAV config, and increments supported asset count.",
"",
"Flow:",
"- Validates the price-difference bound and supplied NAV source accounts.",
"- Stores the asset config as unpaused and records the vault created by the account constraints.",
"- Increments the global supported-asset count and emits the asset-config event.",
"",
"Parameters:",
"- `asset_type`: Classification of the supported asset.",
"- `price_difference_bps`: Maximum allowed NAV price difference in basis points.",
"- `nav_data`: NAV source configuration for valuing the asset."
],
"discriminator": [
201,
180,
166,
88,
111,
8,
150,
205
],
"accounts": [
{
"name": "manager",
"writable": true,
"signer": true,
"relations": [
"global_config"
]
},
{
"name": "global_config",
"writable": true
},
{
"name": "asset_config",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
65,
83,
83,
69,
84,
95,
67,
79,
78,
70,
73,
71
]
},
{
"kind": "account",
"path": "asset_mint"
}
]
}
},
{
"name": "vault_authority",
"pda": {
"seeds": [
{
"kind": "const",
"value": [
86,
65,
85,
76,
84,
95,
65,
85,
84,
72,
79,
82,
73,
84,
89
]
}
]
}
},
{
"name": "asset_vault",
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "vault_authority"
},
{
"kind": "account",
"path": "token_program"
},
{
"kind": "account",
"path": "asset_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": "asset_mint"
},
{
"name": "token_program"
},
{
"name": "associated_token_program",
"address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
},
{
"name": "system_program",
"address": "11111111111111111111111111111111"
}
],
"args": [
{
"name": "asset_type",
"type": {
"defined": {
"name": "AssetType"
}
}
},
{
"name": "price_difference_bps",
"type": "u16"
},
{
"name": "nav_data",
"type": {
"vec": {
"defined": {
"name": "NavData"
}
}
}
}
]
},
{
"name": "manager_deposit",
"docs": [
"Lets the manager deposit asset tokens directly into the asset vault.",
"",
"Flow:",
"- Verifies the manager, checks pause state and positive amount, then transfers manager assets into the vault.",
"- Emits the manager-deposit event.",
"",
"Parameters:",
"- `amount`: Amount of the asset token to deposit."
],
"discriminator": [
73,
3,
16,
168,
143,
226,
201,
254
],
"accounts": [
{
"name": "manager",
"writable": true,
"signer": true,
"relations": [
"global_config"
]
},
{
"name": "global_config"
},
{
"name": "asset_config",
"pda": {
"seeds": [
{
"kind": "const",
"value": [
65,
83,
83,
69,
84,
95,
67,
79,
78,
70,
73,
71
]
},
{
"kind": "account",
"path": "asset_mint"
}
]
}
},
{
"name": "vault_authority",
"pda": {
"seeds": [
{
"kind": "const",
"value": [
86,
65,
85,
76,
84,
95,
65,
85,
84,
72,
79,
82,
73,
84,
89
]
}
]
}
},
{
"name": "asset_mint"
},
{
"name": "manager_asset_token_account",
"writable": true
},
{
"name": "asset_vault",
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "vault_authority"
},
{
"kind": "account",
"path": "token_program"
},
{
"kind": "account",
"path": "asset_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"
}
],
"args": [
{
"name": "amount",
"type": "u64"
}
]
},
{
"name": "manager_withdraw",
"docs": [
"Lets the manager withdraw asset tokens from the asset vault when sufficient balance exists.",
"",
"Flow:",
"- Verifies the manager, checks pause state, positive amount, and vault balance.",
"- Signs with the vault authority PDA, transfers assets to the manager, and emits the manager-withdraw event.",
"",
"Parameters:",
"- `amount`: Amount of the asset token to withdraw."
],
"discriminator": [
201,
248,
190,
143,
86,
43,
183,
254
],
"accounts": [
{
"name": "manager",
"writable": true,
"signer": true,
"relations": [
"global_config"
]
},
{
"name": "global_config"
},
{
"name": "asset_config",
"pda": {
"seeds": [
{
"kind": "const",
"value": [
65,
83,
83,
69,
84,
95,
67,
79,
78,
70,
73,
71
]
},
{
"kind": "account",
"path": "asset_mint"
}
]
}
},
{
"name": "vault_authority",
"pda": {
"seeds": [
{
"kind": "const",
"value": [
86,
65,
85,
76,
84,
95,
65,
85,
84,
72,
79,
82,
73,
84,
89
]
}
]
}
},
{
"name": "asset_mint"
},
{
"name": "asset_vault",
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "vault_authority"
},
{
"kind": "account",
"path": "token_program"
},
{
"kind": "account",
"path": "asset_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": "manager_asset_token_account",
"writable": true
},
{
"name": "token_program"
},
{
"name": "associated_token_program",
"address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
}
],
"args": [
{
"name": "amount",
"type": "u64"
}
]
},
{
"name": "post_daily_rate",
"docs": [
"Posts or updates a daily APY entry and advances the global yield index for new chronological entries.",
"",
"Flow:",
"- Verifies the oracle authority, validates the day boundary, and subtracts the management fee from APY.",
"- For a new entry, requires chronological posting, stores the entry, advances the global index, and moves the update cursor.",
"- For an existing entry, updates that day's net APY and replays the compounded index forward through every later day",
"(provided in remaining accounts, ending at the latest posted entry), keeping the whole chain consistent.",
"",
"Parameters:",
"- `day_start_ts`: Start timestamp for the APY day being posted.",
"- `apy_bps`: Daily APY value in basis points."
],
"discriminator": [
97,
148,
227,
180,
119,
174,
56,
81
],
"accounts": [
{
"name": "oracle_authority",
"writable": true,
"signer": true,
"relations": [
"global_config"
]
},
{
"name": "global_config",
"writable": true
},
{
"name": "apy_entry",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
65,
80,
89,
95,
69,
78,
84,
82,
89
]
},
{
"kind": "arg",
"path": "day_start_ts"
}
]
}
},
{
"name": "system_program",
"address": "11111111111111111111111111111111"
}
],
"args": [
{
"name": "day_start_ts",
"type": "u64"
},
{
"name": "apy_bps",
"type": "u32"
}
]
},
{
"name": "prune_apy_entry",
"docs": [
"Closes an APY history entry after the configured retention window has elapsed.",
"",
"Flow:",
"- Computes the entry's retention end timestamp, requires that the retention window has passed, and closes the entry.",
"- Emits the prune-APY-entry event.",
"",
"Parameters:",
"- `day_start_ts`: Start timestamp identifying the APY history entry."
],
"discriminator": [
124,
138,
154,
164,
142,
71,
212,
79
],
"accounts": [
{
"name": "manager",
"writable": true,
"signer": true,
"relations": [
"global_config"
]
},
{
"name": "global_config",
"writable": true
},
{
"name": "apy_entry",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
65,
80,
89,
95,
69,
78,
84,
82,
89
]
},
{
"kind": "arg",
"path": "day_start_ts"
}
]
}
}
],
"args": [
{
"name": "day_start_ts",
"type": "u64"
}
]
},
{
"name": "redeem",
"docs": [
"Burns treasury tokens and redeems the selected asset after settling yield and pending deposit state.",
"",
"Flow:",
"- Checks global/asset pause state, reads NAV, and converts the requested amount using exact mode.",
"- Extends the current yield index from the latest APY entry and settles the user position.",
"- Consumes redeemable balance from pending deposits newest-first, then from settled principal and accumulated yield proportionally to their current balances.",
"- Burns treasury tokens, transfers assets from the vault to the user, writes the updated position, and emits the redeem event.",
"",
"Parameters:",
"- `amount`: Amount to redeem according to the selected exact mode.",
"- `nav_account_count`: Number of NAV accounts supplied in remaining accounts.",
"- `apy_account_count`: Number of APY accounts supplied in remaining accounts.",
"- `exact_mode`: Whether the input amount is interpreted as exact treasury input or exact asset output.",
"- `amount_threshold`: Optional bound on the side `amount` does not pin: a floor on the",
"asset tokens paid out for `ExactIn`, a ceiling on the treasury tokens burned for `ExactOut`."
],
"discriminator": [
184,
12,
86,
149,
70,
196,
97,
225
],
"accounts": [
{
"name": "user",
"writable": true,
"signer": true
},
{
"name": "global_config"
},
{
"name": "asset_config",
"pda": {
"seeds": [
{
"kind": "const",
"value": [
65,
83,
83,
69,
84,
95,
67,
79,
78,
70,
73,
71
]
},
{
"kind": "account",
"path": "asset_mint"
}
]
}
},
{
"name": "user_position",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
85,
83,
69,
82,
95,
80,
79,
83,
73,
84,
73,
79,
78
]
},
{
"kind": "account",
"path": "user"
}
]
}
},
{
"name": "vault_authority",
"pda": {
"seeds": [
{
"kind": "const",
"value": [
86,
65,
85,
76,
84,
95,
65,
85,
84,
72,
79,
82,
73,
84,
89
]
}
]
}
},
{
"name": "treasury_mint",
"writable": true
},
{
"name": "user_treasury_token_account",
"writable": true
},
{
"name": "asset_mint"
},
{
"name": "asset_vault",
"writable": true,
"pda": {
"seeds": [
{
"kind": "account",
"path": "vault_authority"
},
{
"kind": "account",
"path": "asset_token_program"
},
{
"kind": "account",
"path": "asset_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": "user_asset_token_account",
"writable": true
},
{
"name": "latest_apy_entry"
},
{
"name": "treasury_token_program"
},
{
"name": "asset_token_program"
},
{
"name": "associated_token_program",
"address": "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
}
],
"args": [
{
"name": "amount",
"type": "u64"
},
{
"name": "nav_account_count",
"type": "u8"
},
{
"name": "apy_account_count",
"type": "u8"
},
{
"name": "exact_mode",
"type": {
"defined": {
"name": "ExactMode"
}
}
},
{
"name": "amount_threshold",
"type": {
"option": "u64"
}
}
]
},
{
"name": "set_asset_config",
"docs": [
"Updates optional asset settings such as type, pause state, NAV sources, and price-difference bounds.",
"",
"Flow:",
"- Verifies the manager and asset config through account constraints.",
"- Applies each provided asset setting, validating NAV sources and price-difference bounds before writing.",
"- Emits the asset-config update event, including whether NAV data changed.",
"",
"Parameters:",
"- `asset_type`: Optional replacement asset classification.",
"- `pause`: Optional asset pause-state update.",
"- `nav_data`: Optional replacement NAV source configuration.",
"- `price_difference_bps`: Optional replacement maximum NAV price difference in basis points."
],
"discriminator": [
110,
198,
171,
111,
60,
234,
8,
197
],
"accounts": [
{
"name": "manager",
"signer": true,
"relations": [
"global_config"
]
},
{
"name": "global_config",
"docs": [
"To verify if GlocalConfig is created and manager address is correct"
]
},
{
"name": "asset_config",
"writable": true,
"pda": {
"seeds": [
{
"kind": "const",
"value": [
65,
83,
83,
69,
84,
95,
67,
79,
78,
70,
73,
71
]
},
{
"kind": "account",
"path": "asset_mint"
}
]
}
},
{
"name": "asset_mint"
},
{
"name": "token_program"
}
],
"args": [
{
"name": "asset_type",
"type": {
"option": {
"defined": {
"name": "AssetType"
}
}
}
},
{
"name": "pause",
"type": {
"option": "bool"
}
},
{
"name": "nav_data",
"type": {
"option": {
"vec": {
"defined": {
"name": "NavData"
}
}
}
}
},
{
"name": "price_difference_bps",
"type": {
"option": "u16"
}
}
]
},
{
"name": "set_max_apy_bps",
"docs": [
"Sets the maximum gross APY (bps) the oracle may post per daily rate. Manager only."
],
"discriminator": [
175,
133,
235,
249,
117,
76,
242,
171
],
"accounts": [
{
"name": "manager",
"signer": true,
"relations": [
"global_config"
]
},
{
"name": "global_config",
"writable": true
}
],
"args": [
{
"name": "max_apy_bps",
"type": "u32"
}
]
},
{
"name": "set_pending_manager",
"docs": [
"Starts manager transfer by recording a pending manager chosen by the current manager.",
"",
"Flow:",
"- Verifies the current manager through account constraints, records the pending manager key, and emits the nomination event."
],
"discriminator": [
141,
140,
182,
240,
16,
23,
219,
99
],
"accounts": [
{
"name": "manager",
"signer": true,
"relations": [
"global_config"
]
},
{
"name": "global_config",
"writable": true
},
{
"name": "pending_manager"
}
],
"args": []
},
{
"name": "update_global_config",
"docs": [
"Updates optional global settings such as oracle authority, APY retention, management fee, and pause state.",
"",
"Flow:",
"- Verifies the manager through account constraints.",
"- Applies each provided setting, validating APY retention and management fee bounds before writing.",
"- Emits the global-config update event with the requested changes.",
"",
"Parameters:",
"- `oracle_authority`: Optional replacement oracle authority.",
"- `apy_history_retention_duration`: Optional replacement APY history retention duration.",
"- `management_fee_bps`: Optional replacement management fee in basis points.",
"- `pause`: Optional global pause-state update.",
"- `max_unposted_yield_seconds`: Optional replacement cap on how long the latest posted APY",
"keeps accruing once the oracle stops posting.",
"- `max_pending_deposit_slots`: Optional replacement ceiling on how many pending deposit",
"slots one `UserPosition` may hold."
],
"discriminator": [
164,
84,
130,
189,
111,
58,
250,
200
],
"accounts": [
{
"name": "manager",
"signer": true,
"relations": [
"global_config"
]
},
{
"name": "global_config",
"writable": true
}
],
"args": [
{
"name": "oracle_authority",
"type": {
"option": "pubkey"
}
},
{
"name": "apy_history_retention_duration",
"type": {
"option": "u64"
}
},
{
"name": "management_fee_bps",
"type": {
"option": "u16"
}
},
{
"name": "pause",
"type": {
"option": "bool"
}
},
{
"name": "max_unposted_yield_seconds",
"type": {
"option": "u64"
}
},
{
"name": "max_pending_deposit_slots",
"type": {
"option": "u16"
}
}
]
}
],
"accounts": [
{
"name": "ApyEntry",
"discriminator": [
163,
185,
43,
251,
157,
154,
19,
76
]
},
{
"name": "AssetConfig",
"discriminator": [
57,
112,
247,
166,
247,
64,
140,
23
]
},
{
"name": "GlobalConfig",
"discriminator": [
149,
8,
156,
202,
160,
252,
176,
217
]
},
{
"name": "UserPosition",
"discriminator": [
251,
248,
209,
245,
83,
234,
17,
27
]
}
],
"events": [
{
"name": "AcceptManagerEvent",
"discriminator": [
122,
8,
15,
50,
143,
7,
38,
25
]
},
{
"name": "AccrueInterestEvent",
"discriminator": [
107,
191,
252,
125,
157,
84,
71,
124
]
},
{
"name": "AdminUpdateUserYieldEvent",
"discriminator": [
154,
40,
212,
128,
128,
147,
28,
240
]
},
{
"name": "CloseAssetConfigEvent",
"discriminator": [
138,
204,
99,
145,
73,
104,
100,
196
]
},
{
"name": "CloseGlobalConfigEvent",
"discriminator": [
164,
22,
91,
45,
69,
117,
112,
79
]
},
{
"name": "CloseUserPositionEvent",
"discriminator": [
81,
161,
60,
134,
208,
247,
254,
133
]
},
{
"name": "DepositEvent",
"discriminator": [
120,
248,
61,
83,
31,
142,
107,
144
]
},
{
"name": "InitializeAssetConfigEvent",
"discriminator": [
225,
38,
141,
103,
179,
94,
191,
157
]
},
{
"name": "InitializeEvent",
"discriminator": [
206,
175,
169,
208,
241,
210,
35,
221
]
},
{
"name": "ManagerDepositEvent",
"discriminator": [
228,
210,
251,
18,
56,
69,
102,
164
]
},
{
"name": "ManagerWithdrawEvent",
"discriminator": [
189,
192,
5,
198,
128,
188,
176,
52
]
},
{
"name": "PendingDepositsMergedEvent",
"discriminator": [
60,
247,
30,
166,
55,
48,
240,
104
]
},
{
"name": "PostDailyRateEvent",
"discriminator": [
158,
44,
182,
121,
77,
49,
52,
24
]
},
{
"name": "PruneApyEntryEvent",
"discriminator": [
220,
238,
164,
146,
102,
49,
102,
233
]
},
{
"name": "RedeemEvent",
"discriminator": [
90,
114,
83,
146,
212,
26,
217,
59
]
},
{
"name": "SetAssetConfigEvent",
"discriminator": [
5,
238,
242,
68,
251,
51,
148,
157
]
},
{
"name": "SetMaxApyBpsEvent",
"discriminator": [
225,
86,
222,
30,
99,
253,
243,
202
]
},
{
"name": "SetPendingManagerEvent",
"discriminator": [
113,
146,
57,
18,
89,
66,
2,
248
]
},
{
"name": "UpdateGlobalConfigEvent",
"discriminator": [
88,
201,
118,
69,
70,
159,
190,
16
]
}
],
"errors": [
{
"code": 6000,
"name": "ArithmeticError",
"msg": "Arithmetic Error"
},
{
"code": 6001,
"name": "BpsValueOutOfRange",
"msg": "Bps value out of range"
},
{
"code": 6002,
"name": "ProgramPaused",
"msg": "Program is paused"
},
{
"code": 6003,
"name": "AssetPaused",
"msg": "Asset is paused"
},
{
"code": 6004,
"name": "AmountMustBePositive",
"msg": "Amount must be positive"
},
{
"code": 6005,
"name": "DepositValueBelowMinimum",
"msg": "Deposit value is below the minimum supported amount"
},
{
"code": 6006,
"name": "InvalidNav",
"msg": "NAV must be positive"
},
{
"code": 6007,
"name": "InvalidDayStartTs",
"msg": "Day start timestamp is invalid"
},
{
"code": 6008,
"name": "OutOfOrderApyEntry",
"msg": "APY entries must be posted in chronological order"
},
{
"code": 6009,
"name": "InvalidRemainingAccounts",
"msg": "Remaining account counts do not match the provided accounts"
},
{
"code": 6010,
"name": "ZeroBasisIndex",
"msg": "Basis index cannot be zero"
},
{
"code": 6011,
"name": "ZeroYieldIndex",
"msg": "Yield index cannot be zero"
},
{
"code": 6012,
"name": "YieldIndexRegression",
"msg": "Current yield index cannot move backwards"
},
{
"code": 6013,
"name": "PendingDepositCountTooLarge",
"msg": "Pending deposit count exceeds capacity"
},
{
"code": 6014,
"name": "MissingApyEntry",
"msg": "Missing APY entry for mergeable pending deposit"
},
{
"code": 6015,
"name": "InsufficientRedeemableBalance",
"msg": "Redeem amount exceeds the user's available balance"
},
{
"code": 6016,
"name": "UserPositionNotEmpty",
"msg": "User position must be empty before it can be closed"
},
{
"code": 6017,
"name": "SupportedAssetsRemain",
"msg": "All asset configs must be closed before the global config can be closed"
},
{
"code": 6018,
"name": "TreasuryMintSupplyNotZero",
"msg": "Treasury mint supply must be zero before the global config can be closed"
},
{
"code": 6019,
"name": "InsufficientVaultBalance",
"msg": "Insufficient vault balance"
},
{
"code": 6020,
"name": "ApyHistoryRetentionDurationTooShort",
"msg": "APY history retention duration must be greater than 7 days"
},
{
"code": 6021,
"name": "ApyEntryRetentionNotMet",
"msg": "APY entry is still within the retention window"
},
{
"code": 6022,
"name": "InvalidLatestApyEntry",
"msg": "Provided APY entry is not the latest APY entry"
},
{
"code": 6023,
"name": "UnauthorizedInitializer",
"msg": "Caller must be the program upgrade authority"
},
{
"code": 6024,
"name": "InvalidTreasuryMintTokenProgram",
"msg": "Treasury mint must use Token-2022"
},
{
"code": 6025,
"name": "TreasuryMintDecimalsTooLarge",
"msg": "Treasury mint decimals exceed supported fixed-point precision"
},
{
"code": 6026,
"name": "InvalidTreasuryMintAuthority",
"msg": "Treasury mint authority is invalid"
},
{
"code": 6027,
"name": "InvalidTreasuryMintSupply",
"msg": "Treasury mint supply must be zero"
},
{
"code": 6028,
"name": "InvalidTreasuryMintMetadata",
"msg": "Treasury mint metadata is invalid"
},
{
"code": 6029,
"name": "InvalidTreasuryMintFreezeAuthority",
"msg": "Treasury mint freeze authority must be unset"
},
{
"code": 6030,
"name": "InvalidAssetMint",
"msg": "Asset mint cannot be the treasury mint"
},
{
"code": 6031,
"name": "DayNotElapsed",
"msg": "The full day has not elapsed since the day start timestamp"
},
{
"code": 6032,
"name": "DuplicateLatestApyEntry",
"msg": "latest_apy_entry must not be duplicated in the apy remaining accounts"
},
{
"code": 6033,
"name": "CannotPruneLatestApyEntry",
"msg": "Latest Apy entry can not be pruned"
},
{
"code": 6034,
"name": "ApyExceedsMax",
"msg": "Posted APY exceeds the configured maximum"
},
{
"code": 6035,
"name": "UserIndexExceedsGlobalIndex",
"msg": "User credit index cannot exceed the current global credit index"
},
{
"code": 6036,
"name": "MaxUnpostedYieldSecondsTooLarge",
"msg": "max_unposted_yield_seconds exceeds the maximum representable value (i64::MAX)"
},
{
"code": 6037,
"name": "MaxApyBelowManagementFee",
"msg": "max_apy_bps must be greater than or equal to management_fee_bps"
},
{
"code": 6038,
"name": "FirstApyEntryNotPosted",
"msg": "deposits are disabled until the first daily APY rate has been posted"
},
{
"code": 6039,
"name": "TransferFeeNotSupported",
"msg": "Mints charging a Token-2022 transfer fee are not supported"
},
{
"code": 6040,
"name": "InvalidTokenExtensionData",
"msg": "Token-2022 extension data could not be decoded"
},
{
"code": 6041,
"name": "PendingDepositCapacityExceeded",
"msg": "Position already holds the maximum number of pending deposits"
},
{
"code": 6042,
"name": "MaxPendingDepositSlotsOutOfRange",
"msg": "max_pending_deposit_slots is outside the supported range"
},
{
"code": 6043,
"name": "InvalidUserPositionAccount",
"msg": "Account data is not a readable UserPosition"
},
{
"code": 6044,
"name": "MaxPendingDepositSlotsDecreased",
"msg": "max_pending_deposit_slots can only be raised, never lowered"
},
{
"code": 6045,
"name": "SignerInRemainingAccounts",
"msg": "Remaining accounts must not contain signers"
},
{
"code": 6046,
"name": "AmountOutTooLow",
"msg": "Output amount is below the caller's minimum"
},
{
"code": 6047,
"name": "AmountInTooHigh",
"msg": "Input amount exceeds the caller's maximum"
}
],
"types": [
{
"name": "AcceptManagerEvent",
"type": {
"kind": "struct",
"fields": [
{
"name": "global_config",
"type": "pubkey"
},
{
"name": "new_manager",
"type": "pubkey"
}
]
}
},
{
"name": "AccrueInterestEvent",
"type": {
"kind": "struct",
"fields": [
{
"name": "user_position",
"type": "pubkey"
},
{
"name": "principal_amount",
"type": "u64"
},
{
"name": "accumulated_yield",
"type": "u64"
},
{
"name": "pending_deposit_count",
"type": "u16"
},
{
"name": "global_yield_index_on_last_update",
"type": "u128"
}
]
}
},
{
"name": "AdminUpdateUserYieldEvent",
"type": {
"kind": "struct",
"fields": [
{
"name": "manager",
"type": "pubkey"
},
{
"name": "user_position",
"type": "pubkey"
},
{
"name": "accumulated_yield",
"type": "u64"
},
{
"name": "global_yield_index_on_last_update",
"type": "u128"
}
]
}
},
{
"name": "ApyEntry",
"docs": [
"Account that stores daily APY rate and the global yield index prior to that update",
"seeds: [\"APY_ENTRY\", day_start_ts]"
],
"type": {
"kind": "struct",
"fields": [
{
"name": "day_start_ts",
"docs": [
"UTC value for the day start timestamp"
],
"type": "i64"
},
{
"name": "apy_bps",
"docs": [
"APY value for this day"
],
"type": "u32"
},
{
"name": "global_yield_index_before",
"docs": [
"Stores the global_yield_index prior to the applied APY for the date"
],
"type": "u128"
},
{
"name": "bump",
"type": "u8"
}
]
}
},
{
"name": "AssetConfig",
"docs": [
"SEEDS: [”ASSET_CONFIG”, asset_mint]"
],
"type": {
"kind": "struct",
"fields": [
{
"name": "asset_mint",
"docs": [
"mint of the asset that users will deposit"
],
"type": "pubkey"
},
{
"name": "asset_type",
"docs": [
"Determines whether this asset is treated as a RWA or a Stable"
],
"type": {
"defined": {
"name": "AssetType"
}
}
},
{
"name": "paused",
"docs": [
"deposits and withdrawals if this asset paused"
],
"type": "bool"
},
{
"name": "nav_data",
"docs": [
"used to determine the price of the asset, upto 5 NAV Sources"
],
"type": {
"vec": {
"defined": {
"name": "NavData"
}
}
}
},
{
"name": "price_difference_bps",
"docs": [
"max allowed difference between min and max resolved NAV"
],
"type": "u16"
},
{
"name": "bump",
"type": "u8"
}
]
}
},
{
"name": "AssetType",
"repr": {
"kind": "rust"
},
"type": {
"kind": "enum",
"variants": [
{
"name": "Rwa"
},
{
"name": "Stable"
}
]
}
},
{
"name": "CloseAssetConfigEvent",
"type": {
"kind": "struct",
"fields": [
{
"name": "manager",
"type": "pubkey"
},
{
"name": "global_config",
"type": "pubkey"
},
{
"name": "asset_config",
"type": "pubkey"
},
{
"name": "asset_mint",
"type": "pubkey"
},
{
"name": "swept_amount",
"type": "u64"
},
{
"name": "supported_asset_count",
"type": "u16"
}
]
}
},
{
"name": "CloseGlobalConfigEvent",
"type": {
"kind": "struct",
"fields": [
{
"name": "manager",
"type": "pubkey"
},
{
"name": "global_config",
"type": "pubkey"
},
{
"name": "treasury_mint",
"type": "pubkey"
}
]
}
},
{
"name": "CloseUserPositionEvent",
"type": {
"kind": "struct",
"fields": [
{
"name": "user",
"type": "pubkey"
},
{
"name": "user_position",
"type": "pubkey"
}
]
}
},
{
"name": "DepositEvent",
"type": {
"kind": "struct",
"fields": [
{
"name": "user",
"type": "pubkey"
},
{
"name": "user_position",
"type": "pubkey"
},
{
"name": "asset_mint",
"type": "pubkey"
},
{
"name": "amount",
"type": "u64"
},
{
"name": "nav_9dec",
"type": "u64"
},
{
"name": "treasury_amount",
"type": "u64"
},
{
"name": "principal_amount",
"type": "u64"
},
{
"name": "accumulated_yield",
"type": "u64"
},
{
"name": "pending_deposit_count",
"type": "u16"
}
]
}
},
{
"name": "ExactMode",
"type": {
"kind": "enum",
"variants": [
{
"name": "ExactIn"
},
{
"name": "ExactOut"
}
]
}
},
{
"name": "GlobalConfig",
"docs": [
"Singleton global account across the entire platform",
"SEEDS: [”GLOBAL_CONFIG”]"
],
"type": {
"kind": "struct",
"fields": [
{
"name": "manager",
"docs": [
"multiliquid manager public key"
],
"type": "pubkey"
},
{
"name": "pending_manager",
"docs": [
"for manager transfer"
],
"type": {
"option": "pubkey"
}
},
{
"name": "treasury_mint",
"docs": [
"mint of the treasury token that user recieves on depositing"
],
"type": "pubkey"
},
{
"name": "oracle_authority",
"docs": [
"address that is allowed to publish updates for `current_apy_bps`"
],
"type": "pubkey"
},
{
"name": "global_yield_index_fp",
"docs": [
"instead of updating every user's yield every time the oracle updates the",
"APY value, the protocol keeps a shared global growth index.",
"user redeemable value is derived from:",
"principal_amount * global_credit_index_fp / basis_index",
"where `basis_index` is the user's weighted basis denominator for matured",
"main principal. more on this below the accounts section.",
"Default value - `FP_ONE` (10^18)"
],
"type": "u128"
},
{
"name": "last_yield_update_ts",
"docs": [
"Day-start timestamp immediately after the most recently applied APY",
"entry. On initialization this is the current day start."
],
"type": "i64"
},
{
"name": "latest_apy_entry",
"docs": [
"latest posted APY entry account used by redeem for partial-day accrual."
],
"type": "pubkey"
},
{
"name": "apy_history_retention_duration",
"docs": [
"minimum duration the APY history entry must be kept before it can be",
"closed"
],
"type": "u64"
},
{
"name": "management_fee_bps",
"docs": [
"management fee applied to newly accrued yield"
],
"type": "u16"
},
{
"name": "max_apy_bps",
"docs": [
"maximum gross APY (bps) the oracle may post in a single daily rate"
],
"type": "u32"
},
{
"name": "max_unposted_yield_seconds",
"docs": [
"caps how many seconds past `last_yield_update_ts` the latest posted APY keeps",
"accruing during redeem. Bounds yield extrapolation when the oracle stops",
"posting: beyond this window the global index is frozen at the cap."
],
"type": "u64"
},
{
"name": "supported_asset_count",
"docs": [
"number of assets that this global config supports. Added it here to",
"prevent early closing of global config without closing all asset vaults."
],
"type": "u16"
},
{
"name": "max_pending_deposit_slots",
"docs": [
"ceiling on how many pending deposit slots any one `UserPosition` may hold."
],
"type": "u16"
},
{
"name": "paused",
"docs": [
"is deposits and withdrawals paused"
],
"type": "bool"
},
{
"name": "bump",
"type": "u8"
}
]
}
},
{
"name": "InitializeAssetConfigEvent",
"type": {
"kind": "struct",
"fields": [
{
"name": "manager",
"type": "pubkey"
},
{
"name": "global_config",
"type": "pubkey"
},
{
"name": "asset_config",
"type": "pubkey"
},
{
"name": "asset_mint",
"type": "pubkey"
},
{
"name": "asset_vault",
"type": "pubkey"
},
{
"name": "asset_type",
"type": {
"defined": {
"name": "AssetType"
}
}
},
{
"name": "price_difference_bps",
"type": "u16"
},
{
"name": "supported_asset_count",
"type": "u16"
}
]
}
},
{
"name": "InitializeEvent",
"type": {
"kind": "struct",
"fields": [
{
"name": "manager",
"type": "pubkey"
},
{
"name": "global_config",
"type": "pubkey"
},
{
"name": "treasury_mint",
"type": "pubkey"
},
{
"name": "oracle_authority",
"type": "pubkey"
},
{
"name": "apy_history_retention_duration",
"type": "u64"
},
{
"name": "management_fee_bps",
"type": "u16"
},
{
"name": "max_unposted_yield_seconds",
"type": "u64"
},
{
"name": "max_pending_deposit_slots",
"type": "u16"
},
{
"name": "last_yield_update_ts",
"type": "i64"
}
]
}
},
{
"name": "ManagerDepositEvent",
"type": {
"kind": "struct",
"fields": [
{
"name": "manager",
"type": "pubkey"
},
{
"name": "asset_mint",
"type": "pubkey"
},
{
"name": "amount",
"type": "u64"
}
]
}
},
{
"name": "ManagerWithdrawEvent",
"type": {
"kind": "struct",
"fields": [
{
"name": "manager",
"type": "pubkey"
},
{
"name": "asset_mint",
"type": "pubkey"
},
{
"name": "amount",
"type": "u64"
}
]
}
},
{
"name": "NavData",
"docs": [
"NavData is used to store info about the methods to retrieve the NAV data for a specific asset.",
"Currently we support 4 methods:",
"1. U64FixedAddress: read the price from an onchain account with a fixed address.",
"2. Hardcoded: read the price from a hardcoded value.",
"3. PythPush: read the price from a pyth push account.",
"4. RedstonePush: read the price from a Redstone PriceData account."
],
"type": {
"kind": "enum",
"variants": [
{
"name": "U64FixedAddress",
"fields": [
{
"name": "nav_account_address",
"docs": [
"fixed account address"
],
"type": "pubkey"
},
{
"name": "nav_price_offset",
"docs": [
"Byte offset of the NAV"
],
"type": "u16"
},
{
"name": "price_decimals",
"docs": [
"price decimals"
],
"type": "u8"
}
]
},
{
"name": "Hardcoded",
"fields": [
{
"name": "hardcoded_price",
"docs": [
"hardcoded price"
],
"type": "u64"
},
{
"name": "price_decimals",
"docs": [
"price decimals"
],
"type": "u8"
}
]
},
{
"name": "PythPush",
"fields": [
{
"name": "pyth_push_account_address",
"docs": [
"Pyth push account address"
],
"type": "pubkey"
},
{
"name": "feed_id",
"docs": [
"Pyth feed id"
],
"type": {
"array": [
"u8",
32
]
}
},
{
"name": "max_age_secs",
"docs": [
"Maximum accepted age for the price update"
],
"type": "u64"
},
{
"name": "max_conf_bps",
"docs": [
"Maximum accepted confidence ratio in basis points"
],
"type": "u16"
}
]
},
{
"name": "RedstonePush",
"fields": [
{
"name": "price_feed_account",
"docs": [
"Redstone PriceData account address"
],
"type": "pubkey"
},
{
"name": "feed_id",
"docs": [
"Expected feed id (32 bytes)"
],
"type": {
"array": [
"u8",
32
]
}
},
{
"name": "max_age_secs",
"docs": [
"Maximum accepted age in seconds"
],
"type": "u64"
}
]
}
]
}
},
{
"name": "PendingDeposit",
"serialization": "bytemuckunsafe",
"repr": {
"kind": "c",
"packed": true
},
"type": {
"kind": "struct",
"fields": [
{
"name": "amount_deposited_fp",
"docs": [
"Amount deposited in USD terms.",
"",
"This is stored as fixed point because NAV math can produce values that",
"do not fit in treasury token decimal places."
],
"type": "u128"
},
{
"name": "deposit_ts",
"docs": [
"Original deposit timestamp."
],
"type": "i64"
},
{
"name": "asset_type",
"docs": [
"Determines pending yield timing rules."
],
"type": {
"defined": {
"name": "AssetType"
}
}
}
]
}
},
{
"name": "PendingDepositsMergedEvent",
"type": {
"kind": "struct",
"fields": [
{
"name": "user_position",
"type": "pubkey"
},
{
"name": "merged_count",
"type": "u16"
},
{
"name": "merged_principal_delta",
"type": "u64"
},
{
"name": "merged_yield_delta",
"type": "u64"
}
]
}
},
{
"name": "PostDailyRateEvent",
"type": {
"kind": "struct",
"fields": [
{
"name": "oracle_authority",
"type": "pubkey"
},
{
"name": "global_config",
"type": "pubkey"
},
{
"name": "apy_entry",
"type": "pubkey"
},
{
"name": "day_start_ts",
"type": "i64"
},
{
"name": "apy_bps",
"docs": [
"`gross_apy_bps - management_fee_bps_applied`."
],
"type": "u32"
},
{
"name": "gross_apy_bps",
"docs": [
"Gross rate the oracle posted for this day, before the management fee."
],
"type": "u32"
},
{
"name": "management_fee_bps_applied",
"type": "u32"
},
{
"name": "created",
"type": "bool"
},
{
"name": "global_yield_index_fp",
"type": "u128"
},
{
"name": "last_yield_update_ts",
"type": "i64"
}
]
}
},
{
"name": "PruneApyEntryEvent",
"type": {
"kind": "struct",
"fields": [
{
"name": "manager",
"type": "pubkey"
},
{
"name": "global_config",
"type": "pubkey"
},
{
"name": "apy_entry",
"type": "pubkey"
},
{
"name": "day_start_ts",
"type": "i64"
}
]
}
},
{
"name": "RedeemEvent",
"type": {
"kind": "struct",
"fields": [
{
"name": "user",
"type": "pubkey"
},
{
"name": "user_position",
"type": "pubkey"
},
{
"name": "asset_mint",
"type": "pubkey"
},
{
"name": "treasury_amount",
"type": "u64"
},
{
"name": "nav_9dec",
"type": "u64"
},
{
"name": "redeem_asset_amount",
"type": "u64"
},
{
"name": "principal_amount",
"type": "u64"
},
{
"name": "accumulated_yield",
"type": "u64"
},
{
"name": "pending_deposit_count",
"type": "u16"
}
]
}
},
{
"name": "SetAssetConfigEvent",
"type": {
"kind": "struct",
"fields": [
{
"name": "manager",
"type": "pubkey"
},
{
"name": "asset_config",
"type": "pubkey"
},
{
"name": "asset_mint",
"type": "pubkey"
},
{
"name": "asset_type",
"type": {
"option": {
"defined": {
"name": "AssetType"
}
}
}
},
{
"name": "pause",
"type": {
"option": "bool"
}
},
{
"name": "price_difference_bps",
"type": {
"option": "u16"
}
},
{
"name": "nav_data_updated",
"type": "bool"
}
]
}
},
{
"name": "SetMaxApyBpsEvent",
"type": {
"kind": "struct",
"fields": [
{
"name": "manager",
"type": "pubkey"
},
{
"name": "global_config",
"type": "pubkey"
},
{
"name": "max_apy_bps",
"type": "u32"
}
]
}
},
{
"name": "SetPendingManagerEvent",
"type": {
"kind": "struct",
"fields": [
{
"name": "manager",
"type": "pubkey"
},
{
"name": "global_config",
"type": "pubkey"
},
{
"name": "pending_manager",
"type": "pubkey"
}
]
}
},
{
"name": "UpdateGlobalConfigEvent",
"type": {
"kind": "struct",
"fields": [
{
"name": "manager",
"type": "pubkey"
},
{
"name": "global_config",
"type": "pubkey"
},
{
"name": "apy_history_retention_duration",
"type": {
"option": "u64"
}
},
{
"name": "management_fee_bps",
"type": {
"option": "u16"
}
},
{
"name": "pause",
"type": {
"option": "bool"
}
},
{
"name": "oracle_authority",
"type": "pubkey"
},
{
"name": "max_unposted_yield_seconds",
"type": {
"option": "u64"
}
},
{
"name": "max_pending_deposit_slots",
"type": {
"option": "u16"
}
}
]
}
},
{
"name": "UserPosition",
"docs": [
"`pending_deposits` is the last field so that realloc can extend the account with additional",
"slots beyond the base MAX_PENDING_DEPOSITS without moving any other fields."
],
"serialization": "bytemuckunsafe",
"repr": {
"kind": "c",
"packed": true
},
"type": {
"kind": "struct",
"fields": [
{
"name": "owner",
"docs": [
"User that deposits assets."
],
"type": "pubkey"
},
{
"name": "principal_amount",
"docs": [
"Deposited principal, normalized in USD and stored at 6-decimal treasury precision."
],
"type": "u64"
},
{
"name": "accumulated_yield",
"docs": [
"Yield the user has earned, normalized in USD and stored at 6-decimal treasury precision."
],
"type": "u64"
},
{
"name": "global_yield_index_on_last_update",
"docs": [
"GlobalConfig.global_yield_index when this position was last updated."
],
"type": "u128"
},
{
"name": "pending_deposit_count",
"type": "u16"
},
{
"name": "max_pending_deposits",
"docs": [
"Tracks how many pending_deposit slots have been allocated (grows in chunks via realloc)."
],
"type": "u16"
},
{
"name": "bump",
"type": "u8"
},
{
"name": "_padding",
"type": {
"array": [
"u8",
3
]
}
},
{
"name": "pending_deposits",
"docs": [
"Fixed base array; slots beyond index MAX_PENDING_DEPOSITS-1 live in realloc'd bytes."
],
"type": {
"array": [
{
"defined": {
"name": "PendingDeposit"
}
},
50
]
}
}
]
}
}
]
}
Usage
Fetch from On-Chain
The published swap IDL can be fetched directly. At verification on 2026-09-24, it still contained the earlier interface, and the Treasury IDL had not been published on-chain. The embedded IDLs above provide the current release interfaces for client construction.anchor idl fetch HaWDr94LKJQT2fXuHJGsSGeQf6M7S68FXpEQLcE5RYs6 --provider.cluster mainnet
Load from File
import { Program, AnchorProvider } from "@coral-xyz/anchor";
import idl from "./swap_program.json";
const provider = AnchorProvider.env();
const program = new Program(idl as any, provider);
Fetch Programmatically
import { Program, AnchorProvider } from "@coral-xyz/anchor";
const provider = new AnchorProvider(connection, wallet, {});
const publishedIdl = await Program.fetchIdl(
"HaWDr94LKJQT2fXuHJGsSGeQf6M7S68FXpEQLcE5RYs6",
provider
);
// Inspect the published interface; load the matching IDL above to construct a client.
Deriving PDAs
Pair derivation uses the stored quote/base mint order. New pairs require ascending mint-byte order; existing pairs retain their stored order. All program accounts are Program-Derived Addresses. Use the program ID and the appropriate seeds to derive any account address:import { PublicKey } from "@solana/web3.js";
import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from "@solana/spl-token";
const PROGRAM_ID = new PublicKey("HaWDr94LKJQT2fXuHJGsSGeQf6M7S68FXpEQLcE5RYs6");
function deriveGlobalConfig(): PublicKey {
return PublicKey.findProgramAddressSync(
[Buffer.from("global_config")],
PROGRAM_ID
)[0];
}
function deriveAssetConfig(mint: PublicKey): PublicKey {
return PublicKey.findProgramAddressSync(
[Buffer.from("asset"), mint.toBuffer()],
PROGRAM_ID
)[0];
}
function derivePair(
lp: PublicKey,
quoteMint: PublicKey,
baseMint: PublicKey
): PublicKey {
return PublicKey.findProgramAddressSync(
[Buffer.from("pair"), lp.toBuffer(), quoteMint.toBuffer(), baseMint.toBuffer()],
PROGRAM_ID
)[0];
}
function deriveAssociatedTokenAccount(
mint: PublicKey,
owner: PublicKey,
tokenProgram = TOKEN_PROGRAM_ID
): PublicKey {
return PublicKey.findProgramAddressSync(
[owner.toBuffer(), tokenProgram.toBuffer(), mint.toBuffer()],
ASSOCIATED_TOKEN_PROGRAM_ID
)[0];
}
function deriveVaultAuthority(lp: PublicKey): PublicKey {
return PublicKey.findProgramAddressSync(
[Buffer.from("vault_authority"), lp.toBuffer()],
PROGRAM_ID
)[0];
}
function deriveVault(mint: PublicKey, lp: PublicKey): PublicKey {
return deriveAssociatedTokenAccount(mint, deriveVaultAuthority(lp));
}
function deriveFeeVault(mint: PublicKey): PublicKey {
return deriveAssociatedTokenAccount(mint, deriveProgramAuthority());
}
function deriveLpStableConfig(
stableMint: PublicKey,
lp: PublicKey
): PublicKey {
return PublicKey.findProgramAddressSync(
[Buffer.from("lp_stable_config"), stableMint.toBuffer(), lp.toBuffer()],
PROGRAM_ID
)[0];
}
function deriveProgramAuthority(): PublicKey {
return PublicKey.findProgramAddressSync(
[Buffer.from("program_authority")],
PROGRAM_ID
)[0];
}
For program and account addresses, see the Deployments page.