@elmntl/jlpd-sdk 0.2.0 → 0.13.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +185 -404
  3. package/dist/common/ata.d.ts +26 -0
  4. package/dist/common/ata.js +48 -0
  5. package/dist/common/buffer.d.ts +15 -0
  6. package/dist/common/buffer.js +118 -0
  7. package/dist/common/connection.d.ts +13 -0
  8. package/dist/common/connection.js +2 -0
  9. package/dist/common/constants.d.ts +14 -0
  10. package/dist/common/constants.js +31 -0
  11. package/dist/common/index.d.ts +6 -0
  12. package/dist/common/index.js +28 -0
  13. package/dist/common/strategy-interface.d.ts +59 -0
  14. package/dist/common/strategy-interface.js +42 -0
  15. package/dist/elemental-lend/accounts.d.ts +103 -0
  16. package/dist/elemental-lend/accounts.js +354 -0
  17. package/dist/elemental-lend/constants.d.ts +25 -0
  18. package/dist/elemental-lend/constants.js +48 -0
  19. package/dist/elemental-lend/index.d.ts +8 -0
  20. package/dist/elemental-lend/index.js +24 -0
  21. package/dist/elemental-lend/instructions.d.ts +104 -0
  22. package/dist/elemental-lend/instructions.js +266 -0
  23. package/dist/elemental-lend/jupiter-lend.d.ts +91 -0
  24. package/dist/elemental-lend/jupiter-lend.js +189 -0
  25. package/dist/elemental-lend/kamino-vault.d.ts +173 -0
  26. package/dist/elemental-lend/kamino-vault.js +483 -0
  27. package/dist/elemental-lend/pda.d.ts +12 -0
  28. package/dist/elemental-lend/pda.js +24 -0
  29. package/dist/elemental-lend/protocol-actions.d.ts +56 -0
  30. package/dist/elemental-lend/protocol-actions.js +244 -0
  31. package/dist/elemental-lend/types.d.ts +113 -0
  32. package/dist/elemental-lend/types.js +2 -0
  33. package/dist/elemental-lend-v2/accounts.d.ts +14 -0
  34. package/dist/elemental-lend-v2/accounts.js +136 -0
  35. package/dist/elemental-lend-v2/adapters.d.ts +22 -0
  36. package/dist/elemental-lend-v2/adapters.js +50 -0
  37. package/dist/elemental-lend-v2/constants.d.ts +48 -0
  38. package/dist/elemental-lend-v2/constants.js +104 -0
  39. package/dist/elemental-lend-v2/index.d.ts +8 -0
  40. package/dist/elemental-lend-v2/index.js +24 -0
  41. package/dist/elemental-lend-v2/instructions.d.ts +96 -0
  42. package/dist/elemental-lend-v2/instructions.js +190 -0
  43. package/dist/elemental-lend-v2/lut.d.ts +20 -0
  44. package/dist/elemental-lend-v2/lut.js +65 -0
  45. package/dist/elemental-lend-v2/pda.d.ts +9 -0
  46. package/dist/elemental-lend-v2/pda.js +27 -0
  47. package/dist/elemental-lend-v2/types.d.ts +105 -0
  48. package/dist/elemental-lend-v2/types.js +2 -0
  49. package/dist/elemental-lend-v2/update-aum.d.ts +29 -0
  50. package/dist/elemental-lend-v2/update-aum.js +82 -0
  51. package/dist/index.d.ts +5 -4199
  52. package/dist/index.js +37 -5187
  53. package/dist/jlpd-strategy/accounts.d.ts +83 -0
  54. package/dist/jlpd-strategy/accounts.js +216 -0
  55. package/dist/jlpd-strategy/adapter.d.ts +81 -0
  56. package/dist/jlpd-strategy/adapter.js +118 -0
  57. package/dist/jlpd-strategy/base-to-base-swap.d.ts +74 -0
  58. package/dist/jlpd-strategy/base-to-base-swap.js +205 -0
  59. package/dist/jlpd-strategy/constants.d.ts +127 -0
  60. package/dist/jlpd-strategy/constants.js +174 -0
  61. package/dist/jlpd-strategy/fluid-view.d.ts +199 -0
  62. package/dist/jlpd-strategy/fluid-view.js +799 -0
  63. package/dist/jlpd-strategy/hedge-derived.d.ts +135 -0
  64. package/dist/jlpd-strategy/hedge-derived.js +231 -0
  65. package/dist/jlpd-strategy/hedge-instructions.d.ts +210 -0
  66. package/dist/jlpd-strategy/hedge-instructions.js +300 -0
  67. package/dist/jlpd-strategy/hedge-state.d.ts +88 -0
  68. package/dist/jlpd-strategy/hedge-state.js +110 -0
  69. package/dist/jlpd-strategy/index.d.ts +17 -0
  70. package/dist/jlpd-strategy/index.js +33 -0
  71. package/dist/jlpd-strategy/instructions.d.ts +159 -0
  72. package/dist/jlpd-strategy/instructions.js +234 -0
  73. package/dist/jlpd-strategy/jlp-borrow.d.ts +63 -0
  74. package/dist/jlpd-strategy/jlp-borrow.js +87 -0
  75. package/dist/jlpd-strategy/jlp-data.d.ts +166 -0
  76. package/dist/jlpd-strategy/jlp-data.js +611 -0
  77. package/dist/jlpd-strategy/jupusd-earn.d.ts +90 -0
  78. package/dist/jlpd-strategy/jupusd-earn.js +166 -0
  79. package/dist/jlpd-strategy/live-jlp-price.d.ts +46 -0
  80. package/dist/jlpd-strategy/live-jlp-price.js +267 -0
  81. package/dist/jlpd-strategy/pda.d.ts +13 -0
  82. package/dist/jlpd-strategy/pda.js +28 -0
  83. package/dist/jlpd-strategy/settle-yield.d.ts +45 -0
  84. package/dist/jlpd-strategy/settle-yield.js +113 -0
  85. package/dist/jlpd-strategy/swap-jlp.d.ts +198 -0
  86. package/dist/jlpd-strategy/swap-jlp.js +586 -0
  87. package/dist/jlpd-strategy/types.d.ts +101 -0
  88. package/dist/jlpd-strategy/types.js +29 -0
  89. package/dist/p-stv-core/accounts.d.ts +152 -0
  90. package/dist/p-stv-core/accounts.js +407 -0
  91. package/dist/p-stv-core/constants.d.ts +138 -0
  92. package/dist/p-stv-core/constants.js +181 -0
  93. package/dist/p-stv-core/events.d.ts +7 -0
  94. package/dist/p-stv-core/events.js +246 -0
  95. package/dist/p-stv-core/index.d.ts +11 -0
  96. package/dist/p-stv-core/index.js +27 -0
  97. package/dist/p-stv-core/instructions.d.ts +637 -0
  98. package/dist/p-stv-core/instructions.js +670 -0
  99. package/dist/p-stv-core/lut.d.ts +41 -0
  100. package/dist/p-stv-core/lut.js +81 -0
  101. package/dist/p-stv-core/pda.d.ts +30 -0
  102. package/dist/p-stv-core/pda.js +65 -0
  103. package/dist/p-stv-core/prices.d.ts +20 -0
  104. package/dist/p-stv-core/prices.js +77 -0
  105. package/dist/p-stv-core/remaining-accounts.d.ts +107 -0
  106. package/dist/p-stv-core/remaining-accounts.js +326 -0
  107. package/dist/p-stv-core/send-tx.d.ts +72 -0
  108. package/dist/p-stv-core/send-tx.js +290 -0
  109. package/dist/p-stv-core/sol-wrap.d.ts +34 -0
  110. package/dist/p-stv-core/sol-wrap.js +74 -0
  111. package/dist/p-stv-core/types.d.ts +361 -0
  112. package/dist/p-stv-core/types.js +2 -0
  113. package/package.json +56 -15
  114. package/dist/index.d.mts +0 -4199
  115. package/dist/index.mjs +0 -5090
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Kamino kVault account builders for deposit/withdraw.
3
+ *
4
+ * Builds the remaining_accounts arrays needed by elemental-lend's
5
+ * kvault_deposit and kvault_withdraw instructions.
6
+ *
7
+ * For deposit: 11 fixed accounts derived from vault_state PDAs.
8
+ * For withdraw: 21 fixed accounts — first 12 derivable, then 9 KLend-specific
9
+ * accounts read from vault_state and reserve on-chain data.
10
+ */
11
+ import { AccountMeta, PublicKey, TransactionInstruction } from "@solana/web3.js";
12
+ import { KLEND_PROGRAM } from "./constants";
13
+ import type { SolanaConnection } from "../common/connection";
14
+ export { KLEND_PROGRAM };
15
+ /** Kamino Vault global config (singleton, mainnet) */
16
+ export declare const KAMINO_GLOBAL_CONFIG: PublicKey;
17
+ /** Derive token_vault PDA: ["token_vault", vault_state] under Kamino Vault */
18
+ export declare function findKvaultTokenVault(vaultState: PublicKey): [PublicKey, number];
19
+ /** Derive base_vault_authority PDA: ["authority", vault_state] under Kamino Vault */
20
+ export declare function findKvaultAuthority(vaultState: PublicKey): [PublicKey, number];
21
+ /** Derive shares_mint PDA: ["shares", vault_state] under Kamino Vault */
22
+ export declare function findKvaultSharesMint(vaultState: PublicKey): [PublicKey, number];
23
+ /** Derive event_authority PDA: ["__event_authority"] under Kamino Vault */
24
+ export declare function findKvaultEventAuthority(): [PublicKey, number];
25
+ /** Derive lending_market_authority PDA: ["lma", lending_market] under KLend */
26
+ export declare function findLendingMarketAuthority(lendingMarket: PublicKey): [PublicKey, number];
27
+ /**
28
+ * Read the first VaultAllocation's reserve and ctokenVault from VaultState data.
29
+ *
30
+ * @param vaultStateData - Raw account data (including 8-byte discriminator)
31
+ * @param allocationIndex - Which allocation slot to read (default 0)
32
+ */
33
+ export declare function readVaultAllocation(vaultStateData: Buffer | Uint8Array, allocationIndex?: number): {
34
+ reserve: PublicKey;
35
+ ctokenVault: PublicKey;
36
+ };
37
+ /**
38
+ * Read KLend-specific accounts from a Reserve account's raw data.
39
+ *
40
+ * @param reserveData - Raw KLend Reserve account data (including 8-byte discriminator)
41
+ */
42
+ export declare function readReserveAccounts(reserveData: Buffer | Uint8Array): {
43
+ lendingMarket: PublicKey;
44
+ reserveLiquiditySupply: PublicKey;
45
+ reserveCollateralMint: PublicKey;
46
+ reserveCollateralTokenProgram: PublicKey;
47
+ };
48
+ /**
49
+ * Build the 11 remaining_accounts for elemental-lend's kvault_deposit instruction.
50
+ *
51
+ * Account order matches kamino_vault::deposit_accounts:
52
+ * 0. strategy_state PDA (signer, mut)
53
+ * 1. vault_state (mut)
54
+ * 2. token_vault (mut) — PDA ["token_vault", vault_state]
55
+ * 3. token_mint — base token mint
56
+ * 4. base_vault_authority — PDA ["authority", vault_state]
57
+ * 5. shares_mint (mut) — PDA ["shares", vault_state]
58
+ * 6. user_token_ata (mut) — strategy's base ATA
59
+ * 7. user_shares_ata (mut) — strategy's kvToken ATA
60
+ * 8. klend_program
61
+ * 9. token_program — SPL Token
62
+ * 10. shares_token_program — SPL Token
63
+ *
64
+ * After the 11 fixed accounts, callers should append reserve accounts for refresh.
65
+ */
66
+ export declare function buildKvaultDepositAccounts(vaultState: PublicKey, strategyStatePda: PublicKey, strategyBaseAta: PublicKey, strategySharesAta: PublicKey, baseMint: PublicKey, reserves?: {
67
+ reserve: PublicKey;
68
+ lendingMarket: PublicKey;
69
+ }[]): AccountMeta[];
70
+ /**
71
+ * KLend reserve accounts needed for kvault_withdraw.
72
+ * Read from vault_state and reserve on-chain data using
73
+ * readVaultAllocation() and readReserveAccounts().
74
+ */
75
+ export interface KvaultWithdrawReserveConfig {
76
+ reserve: PublicKey;
77
+ ctokenVault: PublicKey;
78
+ lendingMarket: PublicKey;
79
+ lendingMarketAuthority: PublicKey;
80
+ reserveLiquiditySupply: PublicKey;
81
+ reserveCollateralMint: PublicKey;
82
+ reserveCollateralTokenProgram: PublicKey;
83
+ }
84
+ /**
85
+ * Build the KvaultWithdrawReserveConfig from raw on-chain data.
86
+ *
87
+ * @param vaultStateData - Raw Kamino VaultState account data
88
+ * @param reserveData - Raw KLend Reserve account data
89
+ * @param allocationIndex - VaultAllocation index (default 0)
90
+ */
91
+ export declare function buildKvaultWithdrawReserveConfig(vaultStateData: Buffer | Uint8Array, reserveData: Buffer | Uint8Array, allocationIndex?: number): KvaultWithdrawReserveConfig;
92
+ /**
93
+ * Build the 21 remaining_accounts for elemental-lend's kvault_withdraw instruction.
94
+ *
95
+ * Account order matches kamino_vault::withdraw_accounts:
96
+ * WithdrawFromAvailable (0-11):
97
+ * 0. strategy_state PDA (signer, mut)
98
+ * 1. vault_state (mut)
99
+ * 2. global_config
100
+ * 3. token_vault (mut)
101
+ * 4. base_vault_authority
102
+ * 5. user_token_ata (mut) — strategy's base ATA
103
+ * 6. token_mint (mut)
104
+ * 7. user_shares_ata (mut) — strategy's kvToken ATA
105
+ * 8. shares_mint (mut)
106
+ * 9. token_program
107
+ * 10. shares_token_program
108
+ * 11. klend_program
109
+ * WithdrawFromInvested (12-20):
110
+ * 12. vault_state (mut, dup)
111
+ * 13. reserve (mut)
112
+ * 14. ctoken_vault (mut)
113
+ * 15. lending_market
114
+ * 16. lending_market_authority
115
+ * 17. reserve_liquidity_supply (mut)
116
+ * 18. reserve_collateral_mint (mut)
117
+ * 19. reserve_collateral_token_program
118
+ * 20. instruction_sysvar_account
119
+ *
120
+ * After the 21 fixed accounts, callers should append reserve accounts for refresh.
121
+ */
122
+ export declare function buildKvaultWithdrawAccounts(vaultState: PublicKey, strategyStatePda: PublicKey, strategyBaseAta: PublicKey, strategySharesAta: PublicKey, baseMint: PublicKey, reserveConfig: KvaultWithdrawReserveConfig, globalConfig?: PublicKey): AccountMeta[];
123
+ /** Staleness threshold in seconds (matches elemental-lend KVAULT_STALENESS_THRESHOLD) */
124
+ export declare const KVAULT_STALENESS_THRESHOLD = 120;
125
+ /**
126
+ * Read `last_fee_charge_timestamp` from raw Kamino VaultState account data.
127
+ * Returns undefined if data is too short.
128
+ */
129
+ export declare function readKvaultLastFeeChargeTs(data: Buffer | Uint8Array): number | undefined;
130
+ /**
131
+ * Check if a Kamino kVault is stale (needs an `invest` call to refresh).
132
+ *
133
+ * @param vaultStateData - Raw account data for the Kamino VaultState
134
+ * @param currentSlotTimestamp - Current cluster timestamp (seconds)
135
+ * @returns true if the vault is stale (last_fee_charge_timestamp is older than threshold)
136
+ */
137
+ export declare function isKvaultStale(vaultStateData: Buffer | Uint8Array, currentSlotTimestamp: number): boolean;
138
+ /**
139
+ * Check if any registered kVault protocol is stale and return the stale vault states.
140
+ *
141
+ * @param connection - Solana connection
142
+ * @param protocols - Protocol pubkeys from the lend strategy state
143
+ * @returns Array of stale kVault state pubkeys
144
+ */
145
+ export declare function findStaleKvaults(connection: SolanaConnection, protocols: PublicKey[]): Promise<PublicKey[]>;
146
+ /**
147
+ * Build a Kamino `invest` instruction to refresh a stale kVault.
148
+ *
149
+ * `invest` is permissionless — anyone can call it. It refreshes the vault's
150
+ * `last_fee_charge_timestamp` which is required for elemental-lend's update_aum
151
+ * staleness check (120s threshold).
152
+ *
153
+ * @param payer - Transaction signer (pays for any crank fee, usually 0)
154
+ * @param payerTokenAccount - Payer's base token ATA (for crank fee)
155
+ * @param vaultState - Kamino vault_state pubkey
156
+ * @param baseMint - Base token mint (e.g., USDC)
157
+ * @param vaultStateData - Raw vault_state account data (for reading allocation)
158
+ * @param reserveData - Raw KLend reserve account data (for reading lending_market, etc.)
159
+ * @param allocationIndex - Which vault allocation to invest (default 0)
160
+ */
161
+ export declare function buildKaminoInvestIx(payer: PublicKey, payerTokenAccount: PublicKey, vaultState: PublicKey, baseMint: PublicKey, vaultStateData: Buffer | Uint8Array, reserveData: Buffer | Uint8Array, allocationIndex?: number): TransactionInstruction;
162
+ /**
163
+ * Build Kamino `invest` instructions for all stale kVaults in a lend strategy.
164
+ *
165
+ * Checks each registered protocol for staleness and returns invest instructions
166
+ * for any that are stale.
167
+ *
168
+ * @param connection - Solana connection
169
+ * @param payer - Transaction signer
170
+ * @param baseMint - Base token mint
171
+ * @param protocols - Registered protocol pubkeys from lend strategy state
172
+ */
173
+ export declare function buildKaminoInvestIxsIfStale(connection: SolanaConnection, payer: PublicKey, baseMint: PublicKey, protocols: PublicKey[]): Promise<TransactionInstruction[]>;
@@ -0,0 +1,483 @@
1
+ "use strict";
2
+ /**
3
+ * Kamino kVault account builders for deposit/withdraw.
4
+ *
5
+ * Builds the remaining_accounts arrays needed by elemental-lend's
6
+ * kvault_deposit and kvault_withdraw instructions.
7
+ *
8
+ * For deposit: 11 fixed accounts derived from vault_state PDAs.
9
+ * For withdraw: 21 fixed accounts — first 12 derivable, then 9 KLend-specific
10
+ * accounts read from vault_state and reserve on-chain data.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.KVAULT_STALENESS_THRESHOLD = exports.KAMINO_GLOBAL_CONFIG = exports.KLEND_PROGRAM = void 0;
14
+ exports.findKvaultTokenVault = findKvaultTokenVault;
15
+ exports.findKvaultAuthority = findKvaultAuthority;
16
+ exports.findKvaultSharesMint = findKvaultSharesMint;
17
+ exports.findKvaultEventAuthority = findKvaultEventAuthority;
18
+ exports.findLendingMarketAuthority = findLendingMarketAuthority;
19
+ exports.readVaultAllocation = readVaultAllocation;
20
+ exports.readReserveAccounts = readReserveAccounts;
21
+ exports.buildKvaultDepositAccounts = buildKvaultDepositAccounts;
22
+ exports.buildKvaultWithdrawReserveConfig = buildKvaultWithdrawReserveConfig;
23
+ exports.buildKvaultWithdrawAccounts = buildKvaultWithdrawAccounts;
24
+ exports.readKvaultLastFeeChargeTs = readKvaultLastFeeChargeTs;
25
+ exports.isKvaultStale = isKvaultStale;
26
+ exports.findStaleKvaults = findStaleKvaults;
27
+ exports.buildKaminoInvestIx = buildKaminoInvestIx;
28
+ exports.buildKaminoInvestIxsIfStale = buildKaminoInvestIxsIfStale;
29
+ const web3_js_1 = require("@solana/web3.js");
30
+ const constants_1 = require("./constants");
31
+ Object.defineProperty(exports, "KLEND_PROGRAM", { enumerable: true, get: function () { return constants_1.KLEND_PROGRAM; } });
32
+ // ---------------------------------------------------------------------------
33
+ // Constants
34
+ // ---------------------------------------------------------------------------
35
+ /** Kamino Vault global config (singleton, mainnet) */
36
+ exports.KAMINO_GLOBAL_CONFIG = new web3_js_1.PublicKey("BKyTcUe6daNG8HbgBix2ugdRHbykG2dK9hPBBqhUyoEX");
37
+ /** SPL Token program */
38
+ const SPL_TOKEN_PROGRAM = new web3_js_1.PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
39
+ /** Sysvar Instructions */
40
+ const SYSVAR_INSTRUCTIONS = new web3_js_1.PublicKey("Sysvar1nstructions1111111111111111111111111");
41
+ // ---------------------------------------------------------------------------
42
+ // PDA Derivation Helpers
43
+ // ---------------------------------------------------------------------------
44
+ /** Derive token_vault PDA: ["token_vault", vault_state] under Kamino Vault */
45
+ function findKvaultTokenVault(vaultState) {
46
+ return web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("token_vault"), vaultState.toBuffer()], constants_1.KAMINO_VAULT_PROGRAM);
47
+ }
48
+ /** Derive base_vault_authority PDA: ["authority", vault_state] under Kamino Vault */
49
+ function findKvaultAuthority(vaultState) {
50
+ return web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("authority"), vaultState.toBuffer()], constants_1.KAMINO_VAULT_PROGRAM);
51
+ }
52
+ /** Derive shares_mint PDA: ["shares", vault_state] under Kamino Vault */
53
+ function findKvaultSharesMint(vaultState) {
54
+ return web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("shares"), vaultState.toBuffer()], constants_1.KAMINO_VAULT_PROGRAM);
55
+ }
56
+ /** Derive event_authority PDA: ["__event_authority"] under Kamino Vault */
57
+ function findKvaultEventAuthority() {
58
+ return web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("__event_authority")], constants_1.KAMINO_VAULT_PROGRAM);
59
+ }
60
+ /** Derive lending_market_authority PDA: ["lma", lending_market] under KLend */
61
+ function findLendingMarketAuthority(lendingMarket) {
62
+ return web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("lma"), lendingMarket.toBuffer()], constants_1.KLEND_PROGRAM);
63
+ }
64
+ // ---------------------------------------------------------------------------
65
+ // VaultState / Reserve Data Readers
66
+ // ---------------------------------------------------------------------------
67
+ /**
68
+ * Kamino VaultState layout offsets (from account data start, including 8-byte discriminator).
69
+ *
70
+ * VaultAllocation[0] starts at offset 312:
71
+ * [312..344] reserve (Pubkey)
72
+ * [344..376] ctokenVault (Pubkey)
73
+ * Each VaultAllocation is 2160 bytes. Index N starts at 312 + N*2160.
74
+ */
75
+ const VAULT_ALLOCATION_OFFSET = 312; // 8 disc + 304 struct offset
76
+ const VAULT_ALLOCATION_SIZE = 2160;
77
+ /**
78
+ * KLend Reserve layout offsets (from account data start, including 8-byte discriminator).
79
+ * [32..64] lendingMarket (Pubkey)
80
+ * [160..192] liquidity.supplyVault (Pubkey)
81
+ * [408..440] liquidity.tokenProgram (Pubkey)
82
+ * [2560..2592] collateral.mintPubkey (Pubkey)
83
+ */
84
+ const RESERVE_LENDING_MARKET_OFFSET = 32;
85
+ const RESERVE_LIQUIDITY_SUPPLY_OFFSET = 160;
86
+ const RESERVE_LIQUIDITY_TOKEN_PROGRAM_OFFSET = 408;
87
+ const RESERVE_COLLATERAL_MINT_OFFSET = 2560;
88
+ /** Read a Pubkey from a Buffer at a given offset */
89
+ function readPubkey(data, offset) {
90
+ return new web3_js_1.PublicKey(data.slice(offset, offset + 32));
91
+ }
92
+ /**
93
+ * Read the first VaultAllocation's reserve and ctokenVault from VaultState data.
94
+ *
95
+ * @param vaultStateData - Raw account data (including 8-byte discriminator)
96
+ * @param allocationIndex - Which allocation slot to read (default 0)
97
+ */
98
+ function readVaultAllocation(vaultStateData, allocationIndex = 0) {
99
+ const base = VAULT_ALLOCATION_OFFSET + allocationIndex * VAULT_ALLOCATION_SIZE;
100
+ if (vaultStateData.length < base + 64) {
101
+ throw new Error(`VaultState data too short for allocation ${allocationIndex}: need ${base + 64}, got ${vaultStateData.length}`);
102
+ }
103
+ return {
104
+ reserve: readPubkey(vaultStateData, base),
105
+ ctokenVault: readPubkey(vaultStateData, base + 32),
106
+ };
107
+ }
108
+ /**
109
+ * Read KLend-specific accounts from a Reserve account's raw data.
110
+ *
111
+ * @param reserveData - Raw KLend Reserve account data (including 8-byte discriminator)
112
+ */
113
+ function readReserveAccounts(reserveData) {
114
+ if (reserveData.length < RESERVE_COLLATERAL_MINT_OFFSET + 32) {
115
+ throw new Error(`Reserve data too short: need ${RESERVE_COLLATERAL_MINT_OFFSET + 32}, got ${reserveData.length}`);
116
+ }
117
+ return {
118
+ lendingMarket: readPubkey(reserveData, RESERVE_LENDING_MARKET_OFFSET),
119
+ reserveLiquiditySupply: readPubkey(reserveData, RESERVE_LIQUIDITY_SUPPLY_OFFSET),
120
+ reserveCollateralMint: readPubkey(reserveData, RESERVE_COLLATERAL_MINT_OFFSET),
121
+ reserveCollateralTokenProgram: readPubkey(reserveData, RESERVE_LIQUIDITY_TOKEN_PROGRAM_OFFSET),
122
+ };
123
+ }
124
+ // ---------------------------------------------------------------------------
125
+ // Deposit Account Builder (11 fixed accounts)
126
+ // ---------------------------------------------------------------------------
127
+ /**
128
+ * Build the 11 remaining_accounts for elemental-lend's kvault_deposit instruction.
129
+ *
130
+ * Account order matches kamino_vault::deposit_accounts:
131
+ * 0. strategy_state PDA (signer, mut)
132
+ * 1. vault_state (mut)
133
+ * 2. token_vault (mut) — PDA ["token_vault", vault_state]
134
+ * 3. token_mint — base token mint
135
+ * 4. base_vault_authority — PDA ["authority", vault_state]
136
+ * 5. shares_mint (mut) — PDA ["shares", vault_state]
137
+ * 6. user_token_ata (mut) — strategy's base ATA
138
+ * 7. user_shares_ata (mut) — strategy's kvToken ATA
139
+ * 8. klend_program
140
+ * 9. token_program — SPL Token
141
+ * 10. shares_token_program — SPL Token
142
+ *
143
+ * After the 11 fixed accounts, callers should append reserve accounts for refresh.
144
+ */
145
+ function buildKvaultDepositAccounts(vaultState, strategyStatePda, strategyBaseAta, strategySharesAta, baseMint, reserves = []) {
146
+ const [tokenVault] = findKvaultTokenVault(vaultState);
147
+ const [authority] = findKvaultAuthority(vaultState);
148
+ const [sharesMint] = findKvaultSharesMint(vaultState);
149
+ const [eventAuthority] = findKvaultEventAuthority();
150
+ const accounts = [
151
+ { pubkey: strategyStatePda, isSigner: true, isWritable: true }, // 0
152
+ { pubkey: vaultState, isSigner: false, isWritable: true }, // 1
153
+ { pubkey: tokenVault, isSigner: false, isWritable: true }, // 2
154
+ { pubkey: baseMint, isSigner: false, isWritable: false }, // 3
155
+ { pubkey: authority, isSigner: false, isWritable: false }, // 4
156
+ { pubkey: sharesMint, isSigner: false, isWritable: true }, // 5
157
+ { pubkey: strategyBaseAta, isSigner: false, isWritable: true }, // 6
158
+ { pubkey: strategySharesAta, isSigner: false, isWritable: true }, // 7
159
+ { pubkey: constants_1.KLEND_PROGRAM, isSigner: false, isWritable: false }, // 8
160
+ { pubkey: SPL_TOKEN_PROGRAM, isSigner: false, isWritable: false }, // 9
161
+ { pubkey: SPL_TOKEN_PROGRAM, isSigner: false, isWritable: false }, // 10
162
+ { pubkey: eventAuthority, isSigner: false, isWritable: false }, // 11 (Anchor event CPI)
163
+ { pubkey: constants_1.KAMINO_VAULT_PROGRAM, isSigner: false, isWritable: false }, // 12 (program self-ref)
164
+ ];
165
+ // Append reserve accounts for KLend batch refresh (writable), then unique lending markets (readonly).
166
+ // Kamino's cpi_refresh_reserves uses .take(reserves_count) to get just the reserves,
167
+ // then reads lending_market from each reserve's data for the CPI. The lending_market
168
+ // AccountInfo must be in the transaction but after the reserves.
169
+ const seenMarkets = new Set();
170
+ for (const { reserve } of reserves) {
171
+ accounts.push({ pubkey: reserve, isSigner: false, isWritable: true });
172
+ }
173
+ for (const { lendingMarket } of reserves) {
174
+ const key = lendingMarket.toBase58();
175
+ if (!seenMarkets.has(key)) {
176
+ seenMarkets.add(key);
177
+ accounts.push({ pubkey: lendingMarket, isSigner: false, isWritable: false });
178
+ }
179
+ }
180
+ return accounts;
181
+ }
182
+ /**
183
+ * Build the KvaultWithdrawReserveConfig from raw on-chain data.
184
+ *
185
+ * @param vaultStateData - Raw Kamino VaultState account data
186
+ * @param reserveData - Raw KLend Reserve account data
187
+ * @param allocationIndex - VaultAllocation index (default 0)
188
+ */
189
+ function buildKvaultWithdrawReserveConfig(vaultStateData, reserveData, allocationIndex = 0) {
190
+ const alloc = readVaultAllocation(vaultStateData, allocationIndex);
191
+ const res = readReserveAccounts(reserveData);
192
+ const [lendingMarketAuthority] = findLendingMarketAuthority(res.lendingMarket);
193
+ return {
194
+ reserve: alloc.reserve,
195
+ ctokenVault: alloc.ctokenVault,
196
+ lendingMarket: res.lendingMarket,
197
+ lendingMarketAuthority,
198
+ reserveLiquiditySupply: res.reserveLiquiditySupply,
199
+ reserveCollateralMint: res.reserveCollateralMint,
200
+ reserveCollateralTokenProgram: res.reserveCollateralTokenProgram,
201
+ };
202
+ }
203
+ /**
204
+ * Build the 21 remaining_accounts for elemental-lend's kvault_withdraw instruction.
205
+ *
206
+ * Account order matches kamino_vault::withdraw_accounts:
207
+ * WithdrawFromAvailable (0-11):
208
+ * 0. strategy_state PDA (signer, mut)
209
+ * 1. vault_state (mut)
210
+ * 2. global_config
211
+ * 3. token_vault (mut)
212
+ * 4. base_vault_authority
213
+ * 5. user_token_ata (mut) — strategy's base ATA
214
+ * 6. token_mint (mut)
215
+ * 7. user_shares_ata (mut) — strategy's kvToken ATA
216
+ * 8. shares_mint (mut)
217
+ * 9. token_program
218
+ * 10. shares_token_program
219
+ * 11. klend_program
220
+ * WithdrawFromInvested (12-20):
221
+ * 12. vault_state (mut, dup)
222
+ * 13. reserve (mut)
223
+ * 14. ctoken_vault (mut)
224
+ * 15. lending_market
225
+ * 16. lending_market_authority
226
+ * 17. reserve_liquidity_supply (mut)
227
+ * 18. reserve_collateral_mint (mut)
228
+ * 19. reserve_collateral_token_program
229
+ * 20. instruction_sysvar_account
230
+ *
231
+ * After the 21 fixed accounts, callers should append reserve accounts for refresh.
232
+ */
233
+ function buildKvaultWithdrawAccounts(vaultState, strategyStatePda, strategyBaseAta, strategySharesAta, baseMint, reserveConfig, globalConfig = exports.KAMINO_GLOBAL_CONFIG) {
234
+ const [tokenVault] = findKvaultTokenVault(vaultState);
235
+ const [authority] = findKvaultAuthority(vaultState);
236
+ const [sharesMint] = findKvaultSharesMint(vaultState);
237
+ const [eventAuthority] = findKvaultEventAuthority();
238
+ return [
239
+ // WithdrawFromAvailable (0-11)
240
+ { pubkey: strategyStatePda, isSigner: true, isWritable: true }, // 0
241
+ { pubkey: vaultState, isSigner: false, isWritable: true }, // 1
242
+ { pubkey: globalConfig, isSigner: false, isWritable: false }, // 2
243
+ { pubkey: tokenVault, isSigner: false, isWritable: true }, // 3
244
+ { pubkey: authority, isSigner: false, isWritable: false }, // 4
245
+ { pubkey: strategyBaseAta, isSigner: false, isWritable: true }, // 5
246
+ { pubkey: baseMint, isSigner: false, isWritable: true }, // 6
247
+ { pubkey: strategySharesAta, isSigner: false, isWritable: true }, // 7
248
+ { pubkey: sharesMint, isSigner: false, isWritable: true }, // 8
249
+ { pubkey: SPL_TOKEN_PROGRAM, isSigner: false, isWritable: false }, // 9
250
+ { pubkey: SPL_TOKEN_PROGRAM, isSigner: false, isWritable: false }, // 10
251
+ { pubkey: constants_1.KLEND_PROGRAM, isSigner: false, isWritable: false }, // 11
252
+ // WithdrawFromAvailable event CPI (12-13)
253
+ { pubkey: eventAuthority, isSigner: false, isWritable: false }, // 12
254
+ { pubkey: constants_1.KAMINO_VAULT_PROGRAM, isSigner: false, isWritable: false }, // 13
255
+ // WithdrawFromInvested (14-22)
256
+ { pubkey: vaultState, isSigner: false, isWritable: true }, // 14 (dup)
257
+ { pubkey: reserveConfig.reserve, isSigner: false, isWritable: true }, // 15
258
+ { pubkey: reserveConfig.ctokenVault, isSigner: false, isWritable: true }, // 16
259
+ { pubkey: reserveConfig.lendingMarket, isSigner: false, isWritable: false }, // 17
260
+ { pubkey: reserveConfig.lendingMarketAuthority, isSigner: false, isWritable: false }, // 18
261
+ { pubkey: reserveConfig.reserveLiquiditySupply, isSigner: false, isWritable: true }, // 19
262
+ { pubkey: reserveConfig.reserveCollateralMint, isSigner: false, isWritable: true }, // 20
263
+ { pubkey: reserveConfig.reserveCollateralTokenProgram, isSigner: false, isWritable: false }, // 21
264
+ { pubkey: SYSVAR_INSTRUCTIONS, isSigner: false, isWritable: false }, // 22
265
+ // Withdraw event CPI (23-24)
266
+ { pubkey: eventAuthority, isSigner: false, isWritable: false }, // 23
267
+ { pubkey: constants_1.KAMINO_VAULT_PROGRAM, isSigner: false, isWritable: false }, // 24
268
+ ];
269
+ }
270
+ // ---------------------------------------------------------------------------
271
+ // Kamino kVault Staleness Check
272
+ // ---------------------------------------------------------------------------
273
+ /** Offset of `last_fee_charge_timestamp` (u64) in Kamino VaultState account data */
274
+ const KVAULT_LAST_FEE_CHARGE_TS_OFFSET = 272; // 8 disc + 264
275
+ /** Minimum data length to read `last_fee_charge_timestamp` */
276
+ const KVAULT_MIN_READ_SIZE = KVAULT_LAST_FEE_CHARGE_TS_OFFSET + 8;
277
+ /** Staleness threshold in seconds (matches elemental-lend KVAULT_STALENESS_THRESHOLD) */
278
+ exports.KVAULT_STALENESS_THRESHOLD = 120;
279
+ /**
280
+ * Read `last_fee_charge_timestamp` from raw Kamino VaultState account data.
281
+ * Returns undefined if data is too short.
282
+ */
283
+ function readKvaultLastFeeChargeTs(data) {
284
+ if (data.length < KVAULT_MIN_READ_SIZE)
285
+ return undefined;
286
+ const buf = Buffer.from(data);
287
+ // Read as u64 LE — timestamp fits in a regular number
288
+ return Number(buf.readBigUInt64LE(KVAULT_LAST_FEE_CHARGE_TS_OFFSET));
289
+ }
290
+ /**
291
+ * Check if a Kamino kVault is stale (needs an `invest` call to refresh).
292
+ *
293
+ * @param vaultStateData - Raw account data for the Kamino VaultState
294
+ * @param currentSlotTimestamp - Current cluster timestamp (seconds)
295
+ * @returns true if the vault is stale (last_fee_charge_timestamp is older than threshold)
296
+ */
297
+ function isKvaultStale(vaultStateData, currentSlotTimestamp) {
298
+ const ts = readKvaultLastFeeChargeTs(vaultStateData);
299
+ if (ts === undefined)
300
+ return true; // can't read — assume stale
301
+ return (currentSlotTimestamp - ts) > exports.KVAULT_STALENESS_THRESHOLD;
302
+ }
303
+ /**
304
+ * Check if any registered kVault protocol is stale and return the stale vault states.
305
+ *
306
+ * @param connection - Solana connection
307
+ * @param protocols - Protocol pubkeys from the lend strategy state
308
+ * @returns Array of stale kVault state pubkeys
309
+ */
310
+ async function findStaleKvaults(connection, protocols) {
311
+ if (protocols.length === 0)
312
+ return [];
313
+ const [accountInfos, slot] = await Promise.all([
314
+ connection.getMultipleAccountsInfo(protocols),
315
+ connection.getSlot("confirmed"),
316
+ ]);
317
+ // Approximate current timestamp via the slot's block time. If the RPC has
318
+ // no block time available, fall back to wall-clock — close enough for the
319
+ // 120s staleness check.
320
+ const blockTime = await connection.getBlockTime(slot);
321
+ const currentTs = blockTime ?? Math.floor(Date.now() / 1000);
322
+ const stale = [];
323
+ for (let i = 0; i < protocols.length; i++) {
324
+ const info = accountInfos[i];
325
+ if (!info)
326
+ continue;
327
+ // Only check accounts owned by Kamino Vault program
328
+ if (!info.owner.equals(constants_1.KAMINO_VAULT_PROGRAM))
329
+ continue;
330
+ if (isKvaultStale(info.data, currentTs)) {
331
+ stale.push(protocols[i]);
332
+ }
333
+ }
334
+ return stale;
335
+ }
336
+ // ---------------------------------------------------------------------------
337
+ // Kamino Invest Instruction Builder
338
+ // ---------------------------------------------------------------------------
339
+ /** Anchor discriminator: sha256("global:invest")[..8] */
340
+ const IX_INVEST = Buffer.from([13, 245, 180, 103, 254, 182, 121, 4]);
341
+ /** PDA seed for ctoken_vault: ["ctoken_vault", vault_state, reserve] */
342
+ const CTOKEN_VAULT_SEED = Buffer.from("ctoken_vault");
343
+ /** PDA seed for whitelisted_reserves: ["whitelisted_reserves", reserve] */
344
+ const WHITELISTED_RESERVES_SEED = Buffer.from("whitelisted_reserves");
345
+ /**
346
+ * Build a Kamino `invest` instruction to refresh a stale kVault.
347
+ *
348
+ * `invest` is permissionless — anyone can call it. It refreshes the vault's
349
+ * `last_fee_charge_timestamp` which is required for elemental-lend's update_aum
350
+ * staleness check (120s threshold).
351
+ *
352
+ * @param payer - Transaction signer (pays for any crank fee, usually 0)
353
+ * @param payerTokenAccount - Payer's base token ATA (for crank fee)
354
+ * @param vaultState - Kamino vault_state pubkey
355
+ * @param baseMint - Base token mint (e.g., USDC)
356
+ * @param vaultStateData - Raw vault_state account data (for reading allocation)
357
+ * @param reserveData - Raw KLend reserve account data (for reading lending_market, etc.)
358
+ * @param allocationIndex - Which vault allocation to invest (default 0)
359
+ */
360
+ function buildKaminoInvestIx(payer, payerTokenAccount, vaultState, baseMint, vaultStateData, reserveData, allocationIndex = 0) {
361
+ const alloc = readVaultAllocation(vaultStateData, allocationIndex);
362
+ const res = readReserveAccounts(reserveData);
363
+ const [lendingMarketAuthority] = findLendingMarketAuthority(res.lendingMarket);
364
+ const [tokenVault] = findKvaultTokenVault(vaultState);
365
+ const [authority] = findKvaultAuthority(vaultState);
366
+ // ctoken_vault PDA: ["ctoken_vault", vault_state, reserve] under Kamino
367
+ const [ctokenVault] = web3_js_1.PublicKey.findProgramAddressSync([CTOKEN_VAULT_SEED, vaultState.toBuffer(), alloc.reserve.toBuffer()], constants_1.KAMINO_VAULT_PROGRAM);
368
+ // reserve_whitelist_entry PDA: ["whitelisted_reserves", reserve] under Kamino (optional)
369
+ const [reserveWhitelist] = web3_js_1.PublicKey.findProgramAddressSync([WHITELISTED_RESERVES_SEED, alloc.reserve.toBuffer()], constants_1.KAMINO_VAULT_PROGRAM);
370
+ const keys = [
371
+ { pubkey: payer, isSigner: true, isWritable: true }, // 0: payer
372
+ { pubkey: payerTokenAccount, isSigner: false, isWritable: true }, // 1: payer_token_account
373
+ { pubkey: vaultState, isSigner: false, isWritable: true }, // 2: vault_state
374
+ { pubkey: tokenVault, isSigner: false, isWritable: true }, // 3: token_vault
375
+ { pubkey: baseMint, isSigner: false, isWritable: true }, // 4: token_mint
376
+ { pubkey: authority, isSigner: false, isWritable: true }, // 5: base_vault_authority
377
+ { pubkey: ctokenVault, isSigner: false, isWritable: true }, // 6: ctoken_vault
378
+ { pubkey: alloc.reserve, isSigner: false, isWritable: true }, // 7: reserve
379
+ { pubkey: res.lendingMarket, isSigner: false, isWritable: false }, // 8: lending_market
380
+ { pubkey: lendingMarketAuthority, isSigner: false, isWritable: false }, // 9: lending_market_authority
381
+ { pubkey: res.reserveLiquiditySupply, isSigner: false, isWritable: true }, // 10: reserve_liquidity_supply
382
+ { pubkey: res.reserveCollateralMint, isSigner: false, isWritable: true }, // 11: reserve_collateral_mint
383
+ { pubkey: reserveWhitelist, isSigner: false, isWritable: false }, // 12: reserve_whitelist_entry (optional)
384
+ { pubkey: constants_1.KLEND_PROGRAM, isSigner: false, isWritable: false }, // 13: klend_program
385
+ { pubkey: SPL_TOKEN_PROGRAM, isSigner: false, isWritable: false }, // 14: reserve_collateral_token_program
386
+ { pubkey: SPL_TOKEN_PROGRAM, isSigner: false, isWritable: false }, // 15: token_program
387
+ { pubkey: SYSVAR_INSTRUCTIONS, isSigner: false, isWritable: false }, // 16: instruction_sysvar_account
388
+ ];
389
+ // Append ALL reserves for batch refresh, then lending_market at the end.
390
+ // cpi_refresh_reserves uses .take(reserves_count) to get just reserves.
391
+ // The lending_market must be in the transaction but AFTER reserves.
392
+ const allReserves = [];
393
+ for (let ai = 0; ai < 10; ai++) {
394
+ try {
395
+ const a = readVaultAllocation(vaultStateData, ai);
396
+ if (a.reserve.equals(web3_js_1.PublicKey.default))
397
+ break;
398
+ allReserves.push(a.reserve);
399
+ }
400
+ catch {
401
+ break;
402
+ }
403
+ }
404
+ for (const r of allReserves) {
405
+ keys.push({ pubkey: r, isSigner: false, isWritable: true });
406
+ }
407
+ // Lending market after reserves (for CPI resolution, not counted as a reserve)
408
+ keys.push({ pubkey: res.lendingMarket, isSigner: false, isWritable: false });
409
+ return new web3_js_1.TransactionInstruction({
410
+ programId: constants_1.KAMINO_VAULT_PROGRAM,
411
+ keys,
412
+ data: IX_INVEST,
413
+ });
414
+ }
415
+ /**
416
+ * Build Kamino `invest` instructions for all stale kVaults in a lend strategy.
417
+ *
418
+ * Checks each registered protocol for staleness and returns invest instructions
419
+ * for any that are stale.
420
+ *
421
+ * @param connection - Solana connection
422
+ * @param payer - Transaction signer
423
+ * @param baseMint - Base token mint
424
+ * @param protocols - Registered protocol pubkeys from lend strategy state
425
+ */
426
+ async function buildKaminoInvestIxsIfStale(connection, payer, baseMint, protocols) {
427
+ const staleVaults = await findStaleKvaults(connection, protocols);
428
+ if (staleVaults.length === 0)
429
+ return [];
430
+ const TOKEN_PROG = new web3_js_1.PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
431
+ const ATA_PROG = new web3_js_1.PublicKey("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL");
432
+ // Payer's base ATA (for crank fee — usually 0)
433
+ const [payerAta] = web3_js_1.PublicKey.findProgramAddressSync([payer.toBuffer(), TOKEN_PROG.toBuffer(), baseMint.toBuffer()], ATA_PROG);
434
+ // Batch-fetch all vault states in one round-trip, then derive the reserve
435
+ // pubkeys from the returned buffers, then batch-fetch all reserves. Total:
436
+ // 2 RPC calls regardless of how many vaults are stale (previous loop did
437
+ // 2N sequential calls).
438
+ const vaultInfos = await connection.getMultipleAccountsInfo(staleVaults, "confirmed");
439
+ const reserveKeys = vaultInfos.map((info) => {
440
+ if (!info)
441
+ return null;
442
+ try {
443
+ const alloc = readVaultAllocation(info.data, 0);
444
+ return alloc.reserve.equals(web3_js_1.PublicKey.default) ? null : alloc.reserve;
445
+ }
446
+ catch {
447
+ return null;
448
+ }
449
+ });
450
+ // Reserves to fetch: only the non-null ones, but remember which original
451
+ // index each corresponds to so we can line them back up.
452
+ const reserveFetchList = [];
453
+ const reserveIdx = [];
454
+ for (let i = 0; i < reserveKeys.length; i++) {
455
+ const r = reserveKeys[i];
456
+ if (r) {
457
+ reserveIdx.push(i);
458
+ reserveFetchList.push(r);
459
+ }
460
+ }
461
+ const reserveInfos = reserveFetchList.length > 0
462
+ ? await connection.getMultipleAccountsInfo(reserveFetchList, "confirmed")
463
+ : [];
464
+ const ixs = [];
465
+ for (let j = 0; j < reserveFetchList.length; j++) {
466
+ const origIdx = reserveIdx[j];
467
+ const vaultInfo = vaultInfos[origIdx];
468
+ const reserveInfo = reserveInfos[j];
469
+ if (!reserveInfo)
470
+ continue;
471
+ // Validate reserve is owned by KLend (skip if migrated/closed)
472
+ if (!reserveInfo.owner.equals(constants_1.KLEND_PROGRAM))
473
+ continue;
474
+ try {
475
+ ixs.push(buildKaminoInvestIx(payer, payerAta, staleVaults[origIdx], baseMint, vaultInfo.data, reserveInfo.data, 0));
476
+ }
477
+ catch {
478
+ // Skip if ix builder can't parse the data
479
+ continue;
480
+ }
481
+ }
482
+ return ixs;
483
+ }
@@ -0,0 +1,12 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ export declare function findStrategyStatePda(baseMint: PublicKey, programId?: PublicKey): [PublicKey, number];
3
+ export declare function findStvPositionPda(stv: PublicKey, programId?: PublicKey): [PublicKey, number];
4
+ /**
5
+ * Derive the per-strategy_state `ManagerRole` PDA for Elemental Lend.
6
+ * Seeds: `["manager", strategy_state, manager]`.
7
+ *
8
+ * Note the per-program prefix on the name: each Elemental program has its
9
+ * own `ManagerRole` PDA scoped to a different anchor account (`p-stv-core`
10
+ * → STV, `jlpd-strategy` → JlpdConfig).
11
+ */
12
+ export declare function findLendManagerRolePda(strategyState: PublicKey, manager: PublicKey, programId?: PublicKey): [PublicKey, number];