@kamino-finance/klend-sdk 7.1.1 → 7.1.2
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.
- package/dist/@codegen/unstaking_pool/accounts/PoolState.d.ts +53 -0
- package/dist/@codegen/unstaking_pool/accounts/PoolState.d.ts.map +1 -0
- package/dist/@codegen/unstaking_pool/accounts/PoolState.js +167 -0
- package/dist/@codegen/unstaking_pool/accounts/PoolState.js.map +1 -0
- package/dist/@codegen/unstaking_pool/accounts/UnstakeTicket.d.ts +41 -0
- package/dist/@codegen/unstaking_pool/accounts/UnstakeTicket.d.ts.map +1 -0
- package/dist/@codegen/unstaking_pool/accounts/UnstakeTicket.js +143 -0
- package/dist/@codegen/unstaking_pool/accounts/UnstakeTicket.js.map +1 -0
- package/dist/@codegen/unstaking_pool/accounts/index.d.ts +5 -0
- package/dist/@codegen/unstaking_pool/accounts/index.d.ts.map +1 -0
- package/dist/@codegen/unstaking_pool/accounts/index.js +8 -0
- package/dist/@codegen/unstaking_pool/accounts/index.js.map +1 -0
- package/dist/@codegen/unstaking_pool/errors/anchor.d.ts +435 -0
- package/dist/@codegen/unstaking_pool/errors/anchor.d.ts.map +1 -0
- package/dist/@codegen/unstaking_pool/errors/anchor.js +767 -0
- package/dist/@codegen/unstaking_pool/errors/anchor.js.map +1 -0
- package/dist/@codegen/unstaking_pool/errors/custom.d.ts +259 -0
- package/dist/@codegen/unstaking_pool/errors/custom.d.ts.map +1 -0
- package/dist/@codegen/unstaking_pool/errors/custom.js +458 -0
- package/dist/@codegen/unstaking_pool/errors/custom.js.map +1 -0
- package/dist/@codegen/unstaking_pool/errors/index.d.ts +6 -0
- package/dist/@codegen/unstaking_pool/errors/index.d.ts.map +1 -0
- package/dist/@codegen/unstaking_pool/errors/index.js +86 -0
- package/dist/@codegen/unstaking_pool/errors/index.js.map +1 -0
- package/dist/@codegen/unstaking_pool/instructions/burn.d.ts +21 -0
- package/dist/@codegen/unstaking_pool/instructions/burn.d.ts.map +1 -0
- package/dist/@codegen/unstaking_pool/instructions/burn.js +67 -0
- package/dist/@codegen/unstaking_pool/instructions/burn.js.map +1 -0
- package/dist/@codegen/unstaking_pool/instructions/changeTicketAuthority.d.ts +8 -0
- package/dist/@codegen/unstaking_pool/instructions/changeTicketAuthority.d.ts.map +1 -0
- package/dist/@codegen/unstaking_pool/instructions/changeTicketAuthority.js +16 -0
- package/dist/@codegen/unstaking_pool/instructions/changeTicketAuthority.js.map +1 -0
- package/dist/@codegen/unstaking_pool/instructions/collect.d.ts +16 -0
- package/dist/@codegen/unstaking_pool/instructions/collect.d.ts.map +1 -0
- package/dist/@codegen/unstaking_pool/instructions/collect.js +24 -0
- package/dist/@codegen/unstaking_pool/instructions/collect.js.map +1 -0
- package/dist/@codegen/unstaking_pool/instructions/index.d.ts +17 -0
- package/dist/@codegen/unstaking_pool/instructions/index.d.ts.map +1 -0
- package/dist/@codegen/unstaking_pool/instructions/index.js +20 -0
- package/dist/@codegen/unstaking_pool/instructions/index.js.map +1 -0
- package/dist/@codegen/unstaking_pool/instructions/initializePool.d.ts +14 -0
- package/dist/@codegen/unstaking_pool/instructions/initializePool.d.ts.map +1 -0
- package/dist/@codegen/unstaking_pool/instructions/initializePool.js +22 -0
- package/dist/@codegen/unstaking_pool/instructions/initializePool.js.map +1 -0
- package/dist/@codegen/unstaking_pool/instructions/mint.d.ts +24 -0
- package/dist/@codegen/unstaking_pool/instructions/mint.d.ts.map +1 -0
- package/dist/@codegen/unstaking_pool/instructions/mint.js +74 -0
- package/dist/@codegen/unstaking_pool/instructions/mint.js.map +1 -0
- package/dist/@codegen/unstaking_pool/instructions/splitTicket.d.ts +15 -0
- package/dist/@codegen/unstaking_pool/instructions/splitTicket.d.ts.map +1 -0
- package/dist/@codegen/unstaking_pool/instructions/splitTicket.js +62 -0
- package/dist/@codegen/unstaking_pool/instructions/splitTicket.js.map +1 -0
- package/dist/@codegen/unstaking_pool/instructions/updateAdmin.d.ts +7 -0
- package/dist/@codegen/unstaking_pool/instructions/updateAdmin.d.ts.map +1 -0
- package/dist/@codegen/unstaking_pool/instructions/updateAdmin.js +19 -0
- package/dist/@codegen/unstaking_pool/instructions/updateAdmin.js.map +1 -0
- package/dist/@codegen/unstaking_pool/instructions/updatePoolConfig.d.ts +13 -0
- package/dist/@codegen/unstaking_pool/instructions/updatePoolConfig.d.ts.map +1 -0
- package/dist/@codegen/unstaking_pool/instructions/updatePoolConfig.js +60 -0
- package/dist/@codegen/unstaking_pool/instructions/updatePoolConfig.js.map +1 -0
- package/dist/@codegen/unstaking_pool/programId.d.ts +4 -0
- package/dist/@codegen/unstaking_pool/programId.d.ts.map +1 -0
- package/dist/@codegen/unstaking_pool/programId.js +9 -0
- package/dist/@codegen/unstaking_pool/programId.js.map +1 -0
- package/dist/@codegen/unstaking_pool/types/PoolConfigField.d.ts +45 -0
- package/dist/@codegen/unstaking_pool/types/PoolConfigField.d.ts.map +1 -0
- package/dist/@codegen/unstaking_pool/types/PoolConfigField.js +132 -0
- package/dist/@codegen/unstaking_pool/types/PoolConfigField.js.map +1 -0
- package/dist/@codegen/unstaking_pool/types/index.d.ts +5 -0
- package/dist/@codegen/unstaking_pool/types/index.d.ts.map +1 -0
- package/dist/@codegen/unstaking_pool/types/index.js +39 -0
- package/dist/@codegen/unstaking_pool/types/index.js.map +1 -0
- package/dist/@codegen/unstaking_pool/utils/borshAddress.d.ts +4 -0
- package/dist/@codegen/unstaking_pool/utils/borshAddress.d.ts.map +1 -0
- package/dist/@codegen/unstaking_pool/utils/borshAddress.js +30 -0
- package/dist/@codegen/unstaking_pool/utils/borshAddress.js.map +1 -0
- package/dist/@codegen/unstaking_pool/utils/index.d.ts +2 -0
- package/dist/@codegen/unstaking_pool/utils/index.d.ts.map +1 -0
- package/dist/@codegen/unstaking_pool/utils/index.js +18 -0
- package/dist/@codegen/unstaking_pool/utils/index.js.map +1 -0
- package/dist/classes/action.d.ts.map +1 -1
- package/dist/classes/action.js +5 -5
- package/dist/classes/action.js.map +1 -1
- package/dist/classes/index.d.ts +5 -0
- package/dist/classes/index.d.ts.map +1 -1
- package/dist/classes/index.js +5 -0
- package/dist/classes/index.js.map +1 -1
- package/dist/classes/manager.d.ts.map +1 -1
- package/dist/classes/manager.js +2 -3
- package/dist/classes/manager.js.map +1 -1
- package/dist/classes/stakePool.d.ts +8 -0
- package/dist/classes/stakePool.d.ts.map +1 -0
- package/dist/classes/stakePool.js +18 -0
- package/dist/classes/stakePool.js.map +1 -0
- package/dist/classes/standardStakePool.d.ts +76 -0
- package/dist/classes/standardStakePool.d.ts.map +1 -0
- package/dist/classes/standardStakePool.js +400 -0
- package/dist/classes/standardStakePool.js.map +1 -0
- package/dist/classes/unstakingPool.d.ts +115 -0
- package/dist/classes/unstakingPool.d.ts.map +1 -0
- package/dist/classes/unstakingPool.js +372 -0
- package/dist/classes/unstakingPool.js.map +1 -0
- package/dist/classes/unstakingPoolTypes.d.ts +10 -0
- package/dist/classes/unstakingPoolTypes.d.ts.map +1 -0
- package/dist/classes/unstakingPoolTypes.js +3 -0
- package/dist/classes/unstakingPoolTypes.js.map +1 -0
- package/dist/classes/vault.d.ts +0 -9
- package/dist/classes/vault.d.ts.map +1 -1
- package/dist/classes/vault.js +6 -41
- package/dist/classes/vault.js.map +1 -1
- package/dist/lib.d.ts +1 -0
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +3 -1
- package/dist/lib.js.map +1 -1
- package/dist/utils/lookupTable.d.ts +9 -0
- package/dist/utils/lookupTable.d.ts.map +1 -1
- package/dist/utils/lookupTable.js +37 -0
- package/dist/utils/lookupTable.js.map +1 -1
- package/package.json +3 -1
- package/src/@codegen/unstaking_pool/accounts/PoolState.ts +188 -0
- package/src/@codegen/unstaking_pool/accounts/UnstakeTicket.ts +156 -0
- package/src/@codegen/unstaking_pool/accounts/index.ts +4 -0
- package/src/@codegen/unstaking_pool/errors/anchor.ts +773 -0
- package/src/@codegen/unstaking_pool/errors/custom.ts +477 -0
- package/src/@codegen/unstaking_pool/errors/index.ts +68 -0
- package/src/@codegen/unstaking_pool/instructions/burn.ts +70 -0
- package/src/@codegen/unstaking_pool/instructions/changeTicketAuthority.ts +37 -0
- package/src/@codegen/unstaking_pool/instructions/collect.ts +53 -0
- package/src/@codegen/unstaking_pool/instructions/index.ts +19 -0
- package/src/@codegen/unstaking_pool/instructions/initializePool.ts +49 -0
- package/src/@codegen/unstaking_pool/instructions/mint.ts +80 -0
- package/src/@codegen/unstaking_pool/instructions/splitTicket.ts +59 -0
- package/src/@codegen/unstaking_pool/instructions/updateAdmin.ts +39 -0
- package/src/@codegen/unstaking_pool/instructions/updatePoolConfig.ts +58 -0
- package/src/@codegen/unstaking_pool/programId.ts +9 -0
- package/src/@codegen/unstaking_pool/types/PoolConfigField.ts +121 -0
- package/src/@codegen/unstaking_pool/types/index.ts +12 -0
- package/src/@codegen/unstaking_pool/utils/borshAddress.ts +43 -0
- package/src/@codegen/unstaking_pool/utils/index.ts +1 -0
- package/src/classes/action.ts +10 -5
- package/src/classes/index.ts +5 -0
- package/src/classes/manager.ts +3 -4
- package/src/classes/stakePool.ts +21 -0
- package/src/classes/standardStakePool.ts +487 -0
- package/src/classes/unstakingPool.ts +504 -0
- package/src/classes/unstakingPoolTypes.ts +12 -0
- package/src/classes/vault.ts +43 -56
- package/src/idl/unstaking_pool.json +662 -0
- package/src/lib.ts +1 -0
- package/src/utils/lookupTable.ts +48 -0
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
import {
|
|
2
|
+
initializePool,
|
|
3
|
+
InitializePoolAccounts,
|
|
4
|
+
updatePoolConfig,
|
|
5
|
+
UpdatePoolConfigAccounts,
|
|
6
|
+
UpdatePoolConfigArgs,
|
|
7
|
+
collect,
|
|
8
|
+
CollectAccounts,
|
|
9
|
+
burn,
|
|
10
|
+
BurnAccounts,
|
|
11
|
+
BurnArgs,
|
|
12
|
+
mint,
|
|
13
|
+
MintAccounts,
|
|
14
|
+
MintArgs,
|
|
15
|
+
} from '../@codegen/unstaking_pool/instructions';
|
|
16
|
+
import { TOKEN_2022_PROGRAM_ADDRESS } from '@solana-program/token-2022';
|
|
17
|
+
import { getAssociatedTokenAddress } from '../lib';
|
|
18
|
+
import { PoolState, UnstakeTicket } from '../@codegen/unstaking_pool/accounts';
|
|
19
|
+
import {
|
|
20
|
+
createLookupTableIx,
|
|
21
|
+
DEFAULT_PUBLIC_KEY,
|
|
22
|
+
extendLookupTableIxs,
|
|
23
|
+
insertIntoLookupTableIxs,
|
|
24
|
+
WRAPPED_SOL_MINT,
|
|
25
|
+
} from '../utils';
|
|
26
|
+
import bs58 from 'bs58';
|
|
27
|
+
import { getProgramAccounts } from '../utils/rpc';
|
|
28
|
+
import { InitPoolIxs, MintIxs } from './unstakingPoolTypes';
|
|
29
|
+
import { PoolConfigField, PoolConfigFieldKind } from '../@codegen/unstaking_pool/types';
|
|
30
|
+
import BN from 'bn.js';
|
|
31
|
+
import { mapStakedSolMintToPool, StakePoolType } from './stakePool';
|
|
32
|
+
import { getStandardPoolMintRemainingAccounts, STAKE_POOL_PROGRAM_ID, StakeAccount } from './standardStakePool';
|
|
33
|
+
import {
|
|
34
|
+
Address,
|
|
35
|
+
address,
|
|
36
|
+
Base58EncodedBytes,
|
|
37
|
+
generateKeyPairSigner,
|
|
38
|
+
GetAccountInfoApi,
|
|
39
|
+
getAddressEncoder,
|
|
40
|
+
GetProgramAccountsApi,
|
|
41
|
+
GetProgramAccountsDatasizeFilter,
|
|
42
|
+
GetProgramAccountsMemcmpFilter,
|
|
43
|
+
getProgramDerivedAddress,
|
|
44
|
+
AccountMeta,
|
|
45
|
+
AccountSignerMeta,
|
|
46
|
+
Instruction,
|
|
47
|
+
KeyPairSigner,
|
|
48
|
+
ProgramDerivedAddress,
|
|
49
|
+
Rpc,
|
|
50
|
+
SolanaRpcApi,
|
|
51
|
+
TransactionSigner,
|
|
52
|
+
} from '@solana/kit';
|
|
53
|
+
import { getCreateAccountInstruction, SYSTEM_PROGRAM_ADDRESS } from '@solana-program/system';
|
|
54
|
+
import { SYSVAR_CLOCK_ADDRESS, SYSVAR_INSTRUCTIONS_ADDRESS, SYSVAR_RENT_ADDRESS } from '@solana/sysvars';
|
|
55
|
+
import { TOKEN_PROGRAM_ADDRESS } from '@solana-program/token';
|
|
56
|
+
import { fromLegacyPublicKey } from '@solana/compat';
|
|
57
|
+
import { PROGRAM_ID as UNSTAKING_POOL_ID } from '../@codegen/unstaking_pool/programId';
|
|
58
|
+
export const UNSTAKING_POOL_STAGING_ID: Address = address('SUPFzSvjWnK9AbQ5bQksKaDKeAZBx56Gtjx1AjJsUdj');
|
|
59
|
+
export const STAKE_PROGRAM_ID: Address = address('Stake11111111111111111111111111111111111111');
|
|
60
|
+
export const CLOCK_PROGRAM_ID: Address = address('SysvarC1ock11111111111111111111111111111111');
|
|
61
|
+
const STAKE_HISTORY_PROGRAM_ID: Address = address('SysvarStakeHistory1111111111111111111111111');
|
|
62
|
+
const STAKE_ACCOUNT_SIZE: number = 200;
|
|
63
|
+
export const STAKE_POOL_SIZE: number = 611;
|
|
64
|
+
const addressEncoder = getAddressEncoder();
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Unstaking sol mint seed
|
|
68
|
+
*/
|
|
69
|
+
export const UNSTAKING_SOL_MINT_SEED = Buffer.from('unstaking_sol_mint');
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Unstaking sol pool base authority seed
|
|
73
|
+
*/
|
|
74
|
+
export const BASE_POOL_AUTHORITY_SEED = Buffer.from('authority');
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* KaminoPoolClient is a class that provides a high-level interface to interact with the Kamino Pool program.
|
|
78
|
+
*/
|
|
79
|
+
export class UnstakingPoolClient {
|
|
80
|
+
private readonly _rpc: Rpc<SolanaRpcApi>;
|
|
81
|
+
private readonly _unstakingPoolProgramId: Address;
|
|
82
|
+
|
|
83
|
+
constructor(rpc: Rpc<SolanaRpcApi>, unstakingPoolprogramId?: Address) {
|
|
84
|
+
this._rpc = rpc;
|
|
85
|
+
this._unstakingPoolProgramId = unstakingPoolprogramId ? unstakingPoolprogramId : UNSTAKING_POOL_ID;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
getConnection() {
|
|
89
|
+
return this._rpc;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
getProgramID() {
|
|
93
|
+
return this._unstakingPoolProgramId;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* This method will create a pool with a given config. The config can be changed later on, but it is recommended to set it up correctly from the start
|
|
98
|
+
* @param poolConfig - the config object used to create a pool
|
|
99
|
+
* @returns pool - keypair, should be used to sign the transaction which creates the pool account
|
|
100
|
+
* @returns pool: the keypair of the pool, used to sign the initialization transaction; initPoolIxs: a struct with ixs to initialize the pool and its lookup table + populateLUTIxs, a list to populate the lookup table which has to be executed in a separate transaction
|
|
101
|
+
*/
|
|
102
|
+
async createPoolIxs(poolConfig: UnstakingPoolConfig): Promise<{ pool: KeyPairSigner; initPoolIxs: InitPoolIxs }> {
|
|
103
|
+
const poolState = await generateKeyPairSigner();
|
|
104
|
+
const size = PoolState.layout.span + 8;
|
|
105
|
+
|
|
106
|
+
const createPoolIx = getCreateAccountInstruction({
|
|
107
|
+
payer: poolConfig.admin,
|
|
108
|
+
newAccount: poolState,
|
|
109
|
+
lamports: await this.getConnection().getMinimumBalanceForRentExemption(BigInt(size)).send(),
|
|
110
|
+
space: size,
|
|
111
|
+
programAddress: this._unstakingPoolProgramId,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const unstakingSolMint = (await unstakingPoolMintPda(poolState.address))[0];
|
|
115
|
+
const basePoolAuthority = (await unstakingPoolAuthorityPda(poolState.address))[0];
|
|
116
|
+
const wsolVault = await getAssociatedTokenAddress(WRAPPED_SOL_MINT, basePoolAuthority);
|
|
117
|
+
|
|
118
|
+
const initPoolAccounts: InitializePoolAccounts = {
|
|
119
|
+
admin: poolConfig.admin,
|
|
120
|
+
poolState: poolState.address,
|
|
121
|
+
basePoolAuthority,
|
|
122
|
+
systemProgram: SYSTEM_PROGRAM_ADDRESS,
|
|
123
|
+
rent: SYSVAR_RENT_ADDRESS,
|
|
124
|
+
tokenProgram: TOKEN_PROGRAM_ADDRESS,
|
|
125
|
+
unstakingSolMint,
|
|
126
|
+
wsolMint: WRAPPED_SOL_MINT,
|
|
127
|
+
wsolVault,
|
|
128
|
+
};
|
|
129
|
+
const initPoolIx = initializePool(initPoolAccounts, this._unstakingPoolProgramId);
|
|
130
|
+
|
|
131
|
+
// create and set up the pool lookup table
|
|
132
|
+
const [createLUTIx, lut] = await createLookupTableIx(this.getConnection(), poolConfig.admin);
|
|
133
|
+
|
|
134
|
+
const allAccountsToBeInserted = [
|
|
135
|
+
poolState.address,
|
|
136
|
+
basePoolAuthority,
|
|
137
|
+
wsolVault,
|
|
138
|
+
unstakingSolMint,
|
|
139
|
+
poolConfig.admin.address,
|
|
140
|
+
WRAPPED_SOL_MINT,
|
|
141
|
+
this._unstakingPoolProgramId,
|
|
142
|
+
SYSTEM_PROGRAM_ADDRESS,
|
|
143
|
+
SYSVAR_RENT_ADDRESS,
|
|
144
|
+
TOKEN_PROGRAM_ADDRESS,
|
|
145
|
+
TOKEN_2022_PROGRAM_ADDRESS,
|
|
146
|
+
SYSVAR_INSTRUCTIONS_ADDRESS,
|
|
147
|
+
SYSVAR_CLOCK_ADDRESS,
|
|
148
|
+
STAKE_PROGRAM_ID,
|
|
149
|
+
STAKE_POOL_PROGRAM_ID,
|
|
150
|
+
];
|
|
151
|
+
const insertIntoLUTIxs = extendLookupTableIxs(poolConfig.admin, lut, allAccountsToBeInserted, poolConfig.admin);
|
|
152
|
+
const updateLUTIx = await this.updatePoolConfigIxs(
|
|
153
|
+
poolState.address,
|
|
154
|
+
poolConfig.admin,
|
|
155
|
+
new PoolConfigField.LookupTable(),
|
|
156
|
+
lut.toString()
|
|
157
|
+
);
|
|
158
|
+
const ixns = [createPoolIx, initPoolIx, createLUTIx, ...insertIntoLUTIxs, updateLUTIx];
|
|
159
|
+
|
|
160
|
+
if (poolConfig.actionAuthority) {
|
|
161
|
+
const updateActionAuthorityIx = await this.updatePoolConfigIxs(
|
|
162
|
+
poolState.address,
|
|
163
|
+
poolConfig.admin,
|
|
164
|
+
new PoolConfigField.ActionAuthority(),
|
|
165
|
+
poolConfig.actionAuthority.toString()
|
|
166
|
+
);
|
|
167
|
+
ixns.push(updateActionAuthorityIx);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return { pool: poolState, initPoolIxs: { initPoolIxs: ixns, populateLUTIxs: [] } };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Update pool configuration such as admin authority (or fees/minimum depositable in the future)
|
|
175
|
+
* @param poolState - the pool to update and set the LUT for if needed or only the pool pubkey if updating LUT is not needed
|
|
176
|
+
* @param admin - admin of the specified pool
|
|
177
|
+
* @param mode - what field to update for pool
|
|
178
|
+
* @param value - new value that is converted .toString()
|
|
179
|
+
* @returns a struct that contains a list of ix to update the pool config
|
|
180
|
+
*/
|
|
181
|
+
async updatePoolConfigIxs(
|
|
182
|
+
poolState: UnstakingPool | Address,
|
|
183
|
+
admin: TransactionSigner,
|
|
184
|
+
mode: PoolConfigFieldKind,
|
|
185
|
+
value: string
|
|
186
|
+
): Promise<Instruction> {
|
|
187
|
+
const updatePoolConfigAccounts: UpdatePoolConfigAccounts = {
|
|
188
|
+
admin,
|
|
189
|
+
poolState: poolState instanceof UnstakingPool ? poolState.address : poolState,
|
|
190
|
+
};
|
|
191
|
+
const args: UpdatePoolConfigArgs = {
|
|
192
|
+
entry: mode,
|
|
193
|
+
data: Buffer.from([0]),
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
if (isNaN(+value)) {
|
|
197
|
+
const data = address(value);
|
|
198
|
+
args.data = Buffer.from(addressEncoder.encode(data));
|
|
199
|
+
} else {
|
|
200
|
+
const buffer = Buffer.alloc(8);
|
|
201
|
+
buffer.writeBigUInt64LE(BigInt(value.toString()));
|
|
202
|
+
args.data = buffer;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const updatePoolConfigIx = updatePoolConfig(args, updatePoolConfigAccounts, this._unstakingPoolProgramId);
|
|
206
|
+
|
|
207
|
+
return updatePoolConfigIx;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Collect a stake account SOL if the needed epoch was reached
|
|
212
|
+
* @param poolState - the pool to collect SOL into
|
|
213
|
+
* @param payer - payer for the operation (ix is permissionless)
|
|
214
|
+
* @param stakeAccount - stake account that was deactivated this epoch and has base pool authority as owner
|
|
215
|
+
* @returns collect instruction
|
|
216
|
+
*/
|
|
217
|
+
async collectIx(poolState: UnstakingPool, payer: TransactionSigner, stakeAccount: Address): Promise<Instruction> {
|
|
218
|
+
const pool = await poolState.getState(this.getConnection());
|
|
219
|
+
const accounts: CollectAccounts = {
|
|
220
|
+
poolState: poolState.address,
|
|
221
|
+
payer,
|
|
222
|
+
stakeAccount,
|
|
223
|
+
basePoolAuthority: pool.basePoolAuthority,
|
|
224
|
+
wsolVault: pool.wsolVault,
|
|
225
|
+
wsolMint: WRAPPED_SOL_MINT,
|
|
226
|
+
tokenProgram: TOKEN_PROGRAM_ADDRESS,
|
|
227
|
+
systemProgram: SYSTEM_PROGRAM_ADDRESS,
|
|
228
|
+
clockProgramId: SYSVAR_CLOCK_ADDRESS,
|
|
229
|
+
stakeProgramId: STAKE_PROGRAM_ID,
|
|
230
|
+
stakeHistoryProgramId: STAKE_HISTORY_PROGRAM_ID,
|
|
231
|
+
};
|
|
232
|
+
return collect(accounts, this._unstakingPoolProgramId);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Burn a number of shares (USOL) in exchange for SOL
|
|
237
|
+
* @param poolState - the pool to burn USOL from
|
|
238
|
+
* @param user - user that burns (ix is not gated by action authority)
|
|
239
|
+
* @param unstakeTicket - ticket where to burn the shares from
|
|
240
|
+
* @param sharesToBurn - number of shares that are equivalent 1:1 with SOL
|
|
241
|
+
* @returns burn instruction
|
|
242
|
+
*/
|
|
243
|
+
async burnIx(
|
|
244
|
+
poolState: UnstakingPool,
|
|
245
|
+
user: TransactionSigner,
|
|
246
|
+
unstakeTicket: Address,
|
|
247
|
+
sharesToBurn: BN
|
|
248
|
+
): Promise<Instruction> {
|
|
249
|
+
const pool = await poolState.getState(this.getConnection());
|
|
250
|
+
const accounts: BurnAccounts = {
|
|
251
|
+
poolState: poolState.address,
|
|
252
|
+
basePoolAuthority: pool.basePoolAuthority,
|
|
253
|
+
wsolVault: pool.wsolVault,
|
|
254
|
+
wsolMint: WRAPPED_SOL_MINT,
|
|
255
|
+
user,
|
|
256
|
+
userWsolToken: await getAssociatedTokenAddress(WRAPPED_SOL_MINT, user.address),
|
|
257
|
+
userUnstakingSolToken: await getAssociatedTokenAddress(pool.unstakingSolMint, user.address),
|
|
258
|
+
unstakingSolMint: pool.unstakingSolMint,
|
|
259
|
+
tokenProgram: TOKEN_PROGRAM_ADDRESS,
|
|
260
|
+
unstakeTicket,
|
|
261
|
+
};
|
|
262
|
+
const args: BurnArgs = {
|
|
263
|
+
sharesToBurn,
|
|
264
|
+
minWsolToReceive: sharesToBurn,
|
|
265
|
+
};
|
|
266
|
+
return burn(args, accounts, this._unstakingPoolProgramId);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Mints a number of unstaking sol (USOL) in exchange for staked SOL
|
|
271
|
+
* NOTE: this ix is permissioned by action authority
|
|
272
|
+
* @param poolState - the pool to mint USOL from
|
|
273
|
+
* @param user - user that mints
|
|
274
|
+
* @param actionAuthority - user that has authority to mint in that pool (== poolState.actionAuthority)
|
|
275
|
+
* @param unstakeTicket - empty keypair where unstake ticket will be stored
|
|
276
|
+
* @param stakedSolMint - staked sol mint
|
|
277
|
+
* @param stakedSolToDeposit - staked sol to convert to USOL (at the pool ratio)
|
|
278
|
+
* @param minSharesToReceive - parameter to control slippage
|
|
279
|
+
* @returns burn instruction
|
|
280
|
+
*/
|
|
281
|
+
async mintIx(
|
|
282
|
+
poolState: UnstakingPool,
|
|
283
|
+
user: TransactionSigner,
|
|
284
|
+
actionAuthority: TransactionSigner,
|
|
285
|
+
unstakeTicket: TransactionSigner,
|
|
286
|
+
stakedSolMint: Address,
|
|
287
|
+
stakedSolToDeposit: BN,
|
|
288
|
+
minSharesToReceive: BN
|
|
289
|
+
): Promise<MintIxs> {
|
|
290
|
+
const pool = await poolState.getState(this.getConnection());
|
|
291
|
+
// Create unstake ticket ix
|
|
292
|
+
const size = UnstakeTicket.layout.span + 8;
|
|
293
|
+
const createUnstakeTicketIx = getCreateAccountInstruction({
|
|
294
|
+
payer: user,
|
|
295
|
+
newAccount: unstakeTicket,
|
|
296
|
+
lamports: await this.getConnection().getMinimumBalanceForRentExemption(BigInt(size)).send(),
|
|
297
|
+
space: size,
|
|
298
|
+
programAddress: this._unstakingPoolProgramId,
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
// Actual mint ix
|
|
302
|
+
const [stakedSolPool, stakedSolPoolPk, stakePoolType] = await mapStakedSolMintToPool(
|
|
303
|
+
this.getConnection(),
|
|
304
|
+
stakedSolMint
|
|
305
|
+
);
|
|
306
|
+
const accounts: MintAccounts = {
|
|
307
|
+
poolState: poolState.address,
|
|
308
|
+
basePoolAuthority: pool.basePoolAuthority,
|
|
309
|
+
systemProgram: SYSTEM_PROGRAM_ADDRESS,
|
|
310
|
+
unstakingSolMint: pool.unstakingSolMint,
|
|
311
|
+
unstakingSolTokenProgram: TOKEN_PROGRAM_ADDRESS,
|
|
312
|
+
user,
|
|
313
|
+
actionAuthority,
|
|
314
|
+
userStakedSolToken: await getAssociatedTokenAddress(stakedSolMint, user.address),
|
|
315
|
+
userUnstakingSolToken: await getAssociatedTokenAddress(pool.unstakingSolMint, user.address),
|
|
316
|
+
stakedSolMint,
|
|
317
|
+
stakedSolTokenProgram: fromLegacyPublicKey(stakedSolPool.tokenProgramId),
|
|
318
|
+
unstakingTicketAuthority: user.address,
|
|
319
|
+
unstakeTicket: unstakeTicket.address,
|
|
320
|
+
};
|
|
321
|
+
const args: MintArgs = {
|
|
322
|
+
stakedSolToDeposit,
|
|
323
|
+
minSharesToReceive,
|
|
324
|
+
};
|
|
325
|
+
const ix = mint(args, accounts, this._unstakingPoolProgramId);
|
|
326
|
+
let remainingAccounts: (AccountMeta | AccountSignerMeta)[] = [];
|
|
327
|
+
let remainingSigners: KeyPairSigner[] = [];
|
|
328
|
+
switch (stakePoolType) {
|
|
329
|
+
case StakePoolType.Standard:
|
|
330
|
+
[remainingAccounts, remainingSigners] = await getStandardPoolMintRemainingAccounts(
|
|
331
|
+
this.getConnection(),
|
|
332
|
+
stakedSolPool,
|
|
333
|
+
stakedSolPoolPk,
|
|
334
|
+
stakedSolToDeposit
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
const ixAccounts = ix.accounts || [];
|
|
338
|
+
const mintIx: Instruction = {
|
|
339
|
+
programAddress: ix.programAddress,
|
|
340
|
+
accounts: ixAccounts.concat(remainingAccounts),
|
|
341
|
+
data: ix.data,
|
|
342
|
+
};
|
|
343
|
+
return { mintIxs: [createUnstakeTicketIx, mintIx], additionalSigners: remainingSigners };
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Sync a pool for lookup table;
|
|
348
|
+
* @param pool the pool to sync the LUT for
|
|
349
|
+
* @param owner the pool lut owner
|
|
350
|
+
* @returns a struct that contains a list of ix to create the LUT and assign it to the pool if needed + a list of ixs to insert all the accounts in the LUT
|
|
351
|
+
*/
|
|
352
|
+
async syncPoolLookupTable(pool: UnstakingPool, owner: TransactionSigner): Promise<Instruction[]> {
|
|
353
|
+
const poolState = await pool.getState(this.getConnection());
|
|
354
|
+
if (poolState.poolLookupTable == DEFAULT_PUBLIC_KEY) {
|
|
355
|
+
throw new Error(`Pool ${pool.address} has no lut set`);
|
|
356
|
+
}
|
|
357
|
+
const allAccountsToBeInserted = [
|
|
358
|
+
pool.address,
|
|
359
|
+
poolState.basePoolAuthority,
|
|
360
|
+
poolState.wsolVault,
|
|
361
|
+
poolState.unstakingSolMint,
|
|
362
|
+
poolState.actionAuthority,
|
|
363
|
+
poolState.admin,
|
|
364
|
+
this._unstakingPoolProgramId,
|
|
365
|
+
SYSTEM_PROGRAM_ADDRESS,
|
|
366
|
+
SYSVAR_RENT_ADDRESS,
|
|
367
|
+
TOKEN_PROGRAM_ADDRESS,
|
|
368
|
+
TOKEN_2022_PROGRAM_ADDRESS,
|
|
369
|
+
SYSVAR_INSTRUCTIONS_ADDRESS,
|
|
370
|
+
SYSVAR_CLOCK_ADDRESS,
|
|
371
|
+
STAKE_PROGRAM_ID,
|
|
372
|
+
STAKE_POOL_PROGRAM_ID,
|
|
373
|
+
];
|
|
374
|
+
|
|
375
|
+
// Passing [] as accountsInLut will not fetch anything
|
|
376
|
+
const syncIxs = insertIntoLookupTableIxs(
|
|
377
|
+
this.getConnection(),
|
|
378
|
+
owner,
|
|
379
|
+
poolState.poolLookupTable,
|
|
380
|
+
allAccountsToBeInserted,
|
|
381
|
+
[]
|
|
382
|
+
);
|
|
383
|
+
return syncIxs;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Get all pools
|
|
388
|
+
* @returns an array of all pools
|
|
389
|
+
*/
|
|
390
|
+
async getAllPools(): Promise<UnstakingPool[]> {
|
|
391
|
+
const filters: (GetProgramAccountsDatasizeFilter | GetProgramAccountsMemcmpFilter)[] = [
|
|
392
|
+
{
|
|
393
|
+
dataSize: BigInt(PoolState.layout.span + 8),
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
memcmp: {
|
|
397
|
+
offset: 0n,
|
|
398
|
+
bytes: bs58.encode(PoolState.discriminator) as Base58EncodedBytes,
|
|
399
|
+
encoding: 'base58',
|
|
400
|
+
},
|
|
401
|
+
},
|
|
402
|
+
];
|
|
403
|
+
|
|
404
|
+
const unstakingPools = await getProgramAccounts(
|
|
405
|
+
this.getConnection(),
|
|
406
|
+
this._unstakingPoolProgramId,
|
|
407
|
+
PoolState.layout.span + 8,
|
|
408
|
+
filters
|
|
409
|
+
);
|
|
410
|
+
|
|
411
|
+
return unstakingPools.map((unstakingPool) => {
|
|
412
|
+
const unstakingPoolAccount = PoolState.decode(unstakingPool.data);
|
|
413
|
+
if (!unstakingPoolAccount) {
|
|
414
|
+
throw Error(`unstakingPool with pubkey ${unstakingPool.address.toString()} could not be decoded`);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
return new UnstakingPool(unstakingPool.address, unstakingPoolAccount, this._unstakingPoolProgramId);
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
} // UnstakingPoolClient
|
|
421
|
+
|
|
422
|
+
export class UnstakingPool {
|
|
423
|
+
readonly address: Address;
|
|
424
|
+
state: PoolState | undefined | null;
|
|
425
|
+
programId: Address;
|
|
426
|
+
|
|
427
|
+
constructor(poolAddress: Address, state?: PoolState, programId: Address = UNSTAKING_POOL_ID) {
|
|
428
|
+
this.address = poolAddress;
|
|
429
|
+
this.state = state;
|
|
430
|
+
this.programId = programId;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
async getState(rpc: Rpc<GetAccountInfoApi>): Promise<PoolState> {
|
|
434
|
+
if (!this.state) {
|
|
435
|
+
this.state = await this.reloadState(rpc);
|
|
436
|
+
}
|
|
437
|
+
return this.state;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
async reloadState(rpc: Rpc<GetAccountInfoApi>): Promise<PoolState> {
|
|
441
|
+
this.state = await PoolState.fetch(rpc, this.address, this.programId);
|
|
442
|
+
if (!this.state) {
|
|
443
|
+
throw new Error(`Could not fetch pool ${this.address.toString()}`);
|
|
444
|
+
}
|
|
445
|
+
return this.state;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
async getStakeAccountsForPool(rpc: Rpc<GetProgramAccountsApi>): Promise<Array<StakeAccountInfo>> {
|
|
449
|
+
if (!this.state) {
|
|
450
|
+
throw new Error('Need to have pool state to fetch stake accounts');
|
|
451
|
+
}
|
|
452
|
+
// Filter only accounts that have withdraw authority the base pool authority
|
|
453
|
+
// and are delegating
|
|
454
|
+
const results = await getProgramAccounts(rpc, STAKE_PROGRAM_ID, STAKE_ACCOUNT_SIZE, [
|
|
455
|
+
{ memcmp: { offset: 0n, bytes: bs58.encode([2]) as Base58EncodedBytes, encoding: 'base58' } },
|
|
456
|
+
{
|
|
457
|
+
memcmp: {
|
|
458
|
+
offset: 44n,
|
|
459
|
+
bytes: this.state.basePoolAuthority.toString() as Base58EncodedBytes,
|
|
460
|
+
encoding: 'base58',
|
|
461
|
+
},
|
|
462
|
+
},
|
|
463
|
+
]);
|
|
464
|
+
return results.map((result) => {
|
|
465
|
+
return { stakeAccount: StakeAccount.decode(result.data), pk: result.address, lamports: new BN(result.lamports) };
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
export type StakeAccountInfo = {
|
|
471
|
+
pk: Address;
|
|
472
|
+
stakeAccount: StakeAccount;
|
|
473
|
+
lamports: BN;
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Used to initialize a Kamino Pool
|
|
478
|
+
*/
|
|
479
|
+
export type UnstakingPoolConfig = {
|
|
480
|
+
/** The admin of the pool */
|
|
481
|
+
admin: TransactionSigner;
|
|
482
|
+
/** Pubkey that can mint new tokens */
|
|
483
|
+
actionAuthority: Address | null;
|
|
484
|
+
};
|
|
485
|
+
|
|
486
|
+
export function unstakingPoolMintPda(
|
|
487
|
+
pool: Address,
|
|
488
|
+
programId: Address = UNSTAKING_POOL_ID
|
|
489
|
+
): Promise<ProgramDerivedAddress> {
|
|
490
|
+
return getProgramDerivedAddress({
|
|
491
|
+
seeds: [UNSTAKING_SOL_MINT_SEED, addressEncoder.encode(pool)],
|
|
492
|
+
programAddress: programId,
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
export function unstakingPoolAuthorityPda(
|
|
497
|
+
pool: Address,
|
|
498
|
+
programId: Address = UNSTAKING_POOL_ID
|
|
499
|
+
): Promise<ProgramDerivedAddress> {
|
|
500
|
+
return getProgramDerivedAddress({
|
|
501
|
+
seeds: [BASE_POOL_AUTHORITY_SEED, addressEncoder.encode(pool)],
|
|
502
|
+
programAddress: programId,
|
|
503
|
+
});
|
|
504
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Instruction, KeyPairSigner } from '@solana/kit';
|
|
2
|
+
|
|
3
|
+
export type InitPoolIxs = {
|
|
4
|
+
initPoolIxs: Instruction[];
|
|
5
|
+
populateLUTIxs: Instruction[];
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type MintIxs = {
|
|
9
|
+
// Should return unstake ticket creation ix + mint ix
|
|
10
|
+
mintIxs: Instruction[];
|
|
11
|
+
additionalSigners: KeyPairSigner[];
|
|
12
|
+
};
|
package/src/classes/vault.ts
CHANGED
|
@@ -102,7 +102,7 @@ import {
|
|
|
102
102
|
import { batchFetch, collToLamportsDecimal, ZERO } from '@kamino-finance/kliquidity-sdk';
|
|
103
103
|
import { FullBPSDecimal } from '@kamino-finance/kliquidity-sdk/dist/utils/CreationParameters';
|
|
104
104
|
import { FarmIncentives, FarmState } from '@kamino-finance/farms-sdk/dist';
|
|
105
|
-
import { getAccountsInLut, initLookupTableIx } from '../utils/lookupTable';
|
|
105
|
+
import { getAccountsInLut, initLookupTableIx, insertIntoLookupTableIxs } from '../utils/lookupTable';
|
|
106
106
|
import {
|
|
107
107
|
getFarmStakeIxs,
|
|
108
108
|
getFarmUnstakeAndWithdrawIxs,
|
|
@@ -121,7 +121,6 @@ import {
|
|
|
121
121
|
import { TOKEN_PROGRAM_ADDRESS } from '@solana-program/token';
|
|
122
122
|
import { SYSVAR_INSTRUCTIONS_ADDRESS, SYSVAR_RENT_ADDRESS } from '@solana/sysvars';
|
|
123
123
|
import { noopSigner } from '../utils/signer';
|
|
124
|
-
import { getExtendLookupTableInstruction } from '@solana-program/address-lookup-table';
|
|
125
124
|
import { Farms } from '@kamino-finance/farms-sdk';
|
|
126
125
|
import { getFarmIncentives } from '@kamino-finance/farms-sdk/dist/utils/apy';
|
|
127
126
|
import { computeReservesAllocation } from '../utils/vaultAllocation';
|
|
@@ -296,7 +295,13 @@ export class KaminoVaultClient {
|
|
|
296
295
|
this._kaminoLendProgramId,
|
|
297
296
|
SYSVAR_INSTRUCTIONS_ADDRESS,
|
|
298
297
|
];
|
|
299
|
-
const insertIntoLUTIxs = await
|
|
298
|
+
const insertIntoLUTIxs = await insertIntoLookupTableIxs(
|
|
299
|
+
this.getConnection(),
|
|
300
|
+
vaultConfig.admin,
|
|
301
|
+
lut,
|
|
302
|
+
accountsToBeInserted,
|
|
303
|
+
[]
|
|
304
|
+
);
|
|
300
305
|
|
|
301
306
|
const setLUTIx = this.updateUninitialisedVaultConfigIx(
|
|
302
307
|
vaultConfig.admin,
|
|
@@ -445,7 +450,8 @@ export class KaminoVaultClient {
|
|
|
445
450
|
const [lendingMarketAuth] = await lendingMarketAuthPda(reserveState.lendingMarket, this._kaminoLendProgramId);
|
|
446
451
|
accountsToAddToLut.push(lendingMarketAuth);
|
|
447
452
|
|
|
448
|
-
const insertIntoLutIxs = await
|
|
453
|
+
const insertIntoLutIxs = await insertIntoLookupTableIxs(
|
|
454
|
+
this.getConnection(),
|
|
449
455
|
vaultAdmin,
|
|
450
456
|
vaultState.vaultLookupTable,
|
|
451
457
|
accountsToAddToLut
|
|
@@ -743,7 +749,12 @@ export class KaminoVaultClient {
|
|
|
743
749
|
|
|
744
750
|
if (mode.kind === new VaultConfigField.PendingVaultAdmin().kind) {
|
|
745
751
|
const newPubkey = address(value);
|
|
746
|
-
const insertIntoLutIxs = await
|
|
752
|
+
const insertIntoLutIxs = await insertIntoLookupTableIxs(
|
|
753
|
+
this.getConnection(),
|
|
754
|
+
admin,
|
|
755
|
+
vaultState.vaultLookupTable,
|
|
756
|
+
[newPubkey]
|
|
757
|
+
);
|
|
747
758
|
updateLUTIxs.push(...insertIntoLutIxs);
|
|
748
759
|
} else if (mode.kind === new VaultConfigField.Farm().kind) {
|
|
749
760
|
const keysToAddToLUT = [address(value)];
|
|
@@ -757,7 +768,8 @@ export class KaminoVaultClient {
|
|
|
757
768
|
farmState!.scopePrices,
|
|
758
769
|
farmState!.globalConfig
|
|
759
770
|
);
|
|
760
|
-
const insertIntoLutIxs = await
|
|
771
|
+
const insertIntoLutIxs = await insertIntoLookupTableIxs(
|
|
772
|
+
this.getConnection(),
|
|
761
773
|
admin,
|
|
762
774
|
vaultState.vaultLookupTable,
|
|
763
775
|
keysToAddToLUT
|
|
@@ -876,7 +888,13 @@ export class KaminoVaultClient {
|
|
|
876
888
|
await this.getConnection().getSlot({ commitment: 'finalized' }).send()
|
|
877
889
|
);
|
|
878
890
|
|
|
879
|
-
const insertIntoLUTIxs = await
|
|
891
|
+
const insertIntoLUTIxs = await insertIntoLookupTableIxs(
|
|
892
|
+
this.getConnection(),
|
|
893
|
+
signer,
|
|
894
|
+
newLut,
|
|
895
|
+
accountsInExistentLUT,
|
|
896
|
+
[]
|
|
897
|
+
);
|
|
880
898
|
|
|
881
899
|
lutIxs.push(...insertIntoLUTIxs);
|
|
882
900
|
|
|
@@ -1689,7 +1707,12 @@ export class KaminoVaultClient {
|
|
|
1689
1707
|
sharesAmount: new BN(shareAmountLamports.floor().toString()),
|
|
1690
1708
|
};
|
|
1691
1709
|
|
|
1692
|
-
return withdrawFromAvailable(
|
|
1710
|
+
return withdrawFromAvailable(
|
|
1711
|
+
withdrawFromAvailableArgs,
|
|
1712
|
+
withdrawFromAvailableAccounts,
|
|
1713
|
+
undefined,
|
|
1714
|
+
this._kaminoVaultProgramId
|
|
1715
|
+
);
|
|
1693
1716
|
}
|
|
1694
1717
|
|
|
1695
1718
|
private async withdrawPendingFeesIx(
|
|
@@ -1722,7 +1745,11 @@ export class KaminoVaultClient {
|
|
|
1722
1745
|
reserveCollateralTokenProgram: TOKEN_PROGRAM_ADDRESS,
|
|
1723
1746
|
};
|
|
1724
1747
|
|
|
1725
|
-
let withdrawPendingFeesIxn = withdrawPendingFees(
|
|
1748
|
+
let withdrawPendingFeesIxn = withdrawPendingFees(
|
|
1749
|
+
withdrawPendingFeesAccounts,
|
|
1750
|
+
undefined,
|
|
1751
|
+
this._kaminoVaultProgramId
|
|
1752
|
+
);
|
|
1726
1753
|
|
|
1727
1754
|
const vaultReserves = this.getVaultReserves(vaultState);
|
|
1728
1755
|
const vaultReservesState = await this.loadVaultReserves(vaultState);
|
|
@@ -1814,7 +1841,13 @@ export class KaminoVaultClient {
|
|
|
1814
1841
|
overriddenExistentAccounts = [];
|
|
1815
1842
|
}
|
|
1816
1843
|
ixs.push(
|
|
1817
|
-
...(await
|
|
1844
|
+
...(await insertIntoLookupTableIxs(
|
|
1845
|
+
this.getConnection(),
|
|
1846
|
+
authority,
|
|
1847
|
+
lut,
|
|
1848
|
+
allAccountsToBeInserted,
|
|
1849
|
+
overriddenExistentAccounts
|
|
1850
|
+
))
|
|
1818
1851
|
);
|
|
1819
1852
|
|
|
1820
1853
|
return {
|
|
@@ -1836,52 +1869,6 @@ export class KaminoVaultClient {
|
|
|
1836
1869
|
];
|
|
1837
1870
|
}
|
|
1838
1871
|
|
|
1839
|
-
/**
|
|
1840
|
-
* This method inserts the missing keys from the provided keys into an existent lookup table
|
|
1841
|
-
* @param authority - payer wallet pubkey
|
|
1842
|
-
* @param lookupTable - lookup table to insert the keys into
|
|
1843
|
-
* @param keys - keys to insert into the lookup table
|
|
1844
|
-
* @param [accountsInLut] - the existent accounts in the lookup table. Optional. If provided, the function will not fetch the accounts in the lookup table
|
|
1845
|
-
* @returns - an array of instructions to insert the missing keys into the lookup table
|
|
1846
|
-
*/
|
|
1847
|
-
async insertIntoLookupTableIxs(
|
|
1848
|
-
authority: TransactionSigner,
|
|
1849
|
-
lookupTable: Address,
|
|
1850
|
-
keys: Address[],
|
|
1851
|
-
accountsInLut?: Address[]
|
|
1852
|
-
): Promise<Instruction[]> {
|
|
1853
|
-
let lutContentsList = accountsInLut;
|
|
1854
|
-
if (!accountsInLut) {
|
|
1855
|
-
lutContentsList = await getAccountsInLut(this.getConnection(), lookupTable);
|
|
1856
|
-
} else {
|
|
1857
|
-
lutContentsList = accountsInLut;
|
|
1858
|
-
}
|
|
1859
|
-
|
|
1860
|
-
const lutContents = new Set<Address>(lutContentsList);
|
|
1861
|
-
|
|
1862
|
-
const missingAccounts = keys.filter((key) => !lutContents.has(key) && key !== DEFAULT_PUBLIC_KEY);
|
|
1863
|
-
// deduplicate missing accounts and remove default accounts and convert it back to an array
|
|
1864
|
-
const missingAccountsList = [...new Set<Address>(missingAccounts)];
|
|
1865
|
-
|
|
1866
|
-
const chunkSize = 10;
|
|
1867
|
-
const ixs: Instruction[] = [];
|
|
1868
|
-
|
|
1869
|
-
for (let i = 0; i < missingAccountsList.length; i += chunkSize) {
|
|
1870
|
-
const chunk = missingAccountsList.slice(i, i + chunkSize);
|
|
1871
|
-
ixs.push(
|
|
1872
|
-
getExtendLookupTableInstruction({
|
|
1873
|
-
payer: authority,
|
|
1874
|
-
authority,
|
|
1875
|
-
address: lookupTable,
|
|
1876
|
-
systemProgram: SYSTEM_PROGRAM_ADDRESS,
|
|
1877
|
-
addresses: chunk,
|
|
1878
|
-
})
|
|
1879
|
-
);
|
|
1880
|
-
}
|
|
1881
|
-
|
|
1882
|
-
return ixs;
|
|
1883
|
-
}
|
|
1884
|
-
|
|
1885
1872
|
/** Read the total holdings of a vault and the reserve weights and returns a map from each reserve to how many tokens should be deposited.
|
|
1886
1873
|
* @param vaultState - the vault state to calculate the allocation for
|
|
1887
1874
|
* @param [slot] - the slot for which to calculate the allocation. Optional. If not provided the function will fetch the current slot
|