@kamino-finance/klend-sdk 6.0.0 → 6.0.2-beta.0

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 (36) hide show
  1. package/dist/classes/manager.d.ts +20 -2
  2. package/dist/classes/manager.d.ts.map +1 -1
  3. package/dist/classes/manager.js +63 -3
  4. package/dist/classes/manager.js.map +1 -1
  5. package/dist/classes/market.d.ts +2 -4
  6. package/dist/classes/market.d.ts.map +1 -1
  7. package/dist/classes/market.js +10 -19
  8. package/dist/classes/market.js.map +1 -1
  9. package/dist/classes/vault.d.ts +12 -1
  10. package/dist/classes/vault.d.ts.map +1 -1
  11. package/dist/classes/vault.js +28 -3
  12. package/dist/classes/vault.js.map +1 -1
  13. package/dist/client/tx/multisig.d.ts.map +1 -1
  14. package/dist/client/tx/multisig.js +2 -5
  15. package/dist/client/tx/multisig.js.map +1 -1
  16. package/dist/manager/client_kamino_manager.js +25 -0
  17. package/dist/manager/client_kamino_manager.js.map +1 -1
  18. package/dist/manager/tx/multisig.d.ts.map +1 -1
  19. package/dist/manager/tx/multisig.js +2 -5
  20. package/dist/manager/tx/multisig.js.map +1 -1
  21. package/dist/utils/accountListing.d.ts.map +1 -1
  22. package/dist/utils/accountListing.js +6 -8
  23. package/dist/utils/accountListing.js.map +1 -1
  24. package/dist/utils/managerTypes.d.ts +1 -0
  25. package/dist/utils/managerTypes.d.ts.map +1 -1
  26. package/dist/utils/managerTypes.js +2 -1
  27. package/dist/utils/managerTypes.js.map +1 -1
  28. package/package.json +1 -4
  29. package/src/classes/manager.ts +89 -4
  30. package/src/classes/market.ts +11 -22
  31. package/src/classes/vault.ts +33 -4
  32. package/src/client/tx/multisig.ts +4 -2
  33. package/src/manager/client_kamino_manager.ts +31 -0
  34. package/src/manager/tx/multisig.ts +4 -2
  35. package/src/utils/accountListing.ts +7 -6
  36. package/src/utils/managerTypes.ts +3 -1
@@ -12,6 +12,7 @@ import {
12
12
  GetProgramAccountsMemcmpFilter,
13
13
  ProgramDerivedAddress,
14
14
  Base58EncodedBytes,
15
+ getBase58Decoder,
15
16
  } from '@solana/kit';
16
17
  import {
17
18
  KaminoVault,
@@ -70,7 +71,6 @@ import BN from 'bn.js';
70
71
  import { ReserveConfig, UpdateLendingMarketMode, UpdateLendingMarketModeKind } from '../@codegen/klend/types';
71
72
  import Decimal from 'decimal.js';
72
73
  import { VaultState } from '../@codegen/kvault/accounts';
73
- import bs58 from 'bs58';
74
74
  import { getProgramAccounts } from '../utils/rpc';
75
75
  import { VaultConfigField, VaultConfigFieldKind } from '../@codegen/kvault/types';
76
76
  import {
@@ -86,7 +86,7 @@ import {
86
86
  WithdrawAndBlockReserveIxs,
87
87
  WithdrawIxs,
88
88
  } from './vault_types';
89
- import { FarmState } from '@kamino-finance/farms-sdk/dist';
89
+ import { FarmIncentives, Farms, FarmState } from '@kamino-finance/farms-sdk/dist';
90
90
  import { getSquadsMultisigAdminsAndThreshold, walletIsSquadsMultisig, WalletType } from '../utils/multisig';
91
91
  import { decodeVaultState } from '../utils/vault';
92
92
  import { noopSigner } from '../utils/signer';
@@ -95,6 +95,9 @@ import { SYSVAR_RENT_ADDRESS } from '@solana/sysvars';
95
95
  import { TOKEN_PROGRAM_ADDRESS } from '@solana-program/token';
96
96
  import type { AccountInfoBase, AccountInfoWithJsonData, AccountInfoWithPubkey } from '@solana/rpc-types';
97
97
  import { arrayElementConfigItems, ConfigUpdater } from './configItems';
98
+ import { getFarmIncentives, ReserveIncentives } from '@kamino-finance/farms-sdk/dist/utils/apy';
99
+
100
+ const base58Decoder = getBase58Decoder();
98
101
 
99
102
  /**
100
103
  * KaminoManager is a class that provides a high-level interface to interact with the Kamino Lend and Kamino Vault programs, in order to create and manage a market, as well as vaults
@@ -768,7 +771,7 @@ export class KaminoManager {
768
771
  {
769
772
  memcmp: {
770
773
  offset: 0n,
771
- bytes: bs58.encode(VaultState.discriminator) as Base58EncodedBytes,
774
+ bytes: base58Decoder.decode(VaultState.discriminator) as Base58EncodedBytes,
772
775
  encoding: 'base58',
773
776
  },
774
777
  },
@@ -1065,7 +1068,7 @@ export class KaminoManager {
1065
1068
  }
1066
1069
 
1067
1070
  /**
1068
- * This will compute the PDA that is used as delegatee in Farms program to compute the user state PDA
1071
+ * This will compute the PDA that is used as delegatee in Farms program to compute the user state PDA for vault depositor investing in vault with reserve having a supply farm
1069
1072
  */
1070
1073
  computeUserFarmStateForUserInVault(
1071
1074
  farmsProgramId: Address,
@@ -1076,6 +1079,88 @@ export class KaminoManager {
1076
1079
  return this._vaultClient.computeUserFarmStateDelegateePDAForUserInVault(farmsProgramId, reserve, vault, user);
1077
1080
  }
1078
1081
 
1082
+ /**
1083
+ * Read the APY of the farm built on top of the vault (farm in vaultState.vaultFarm)
1084
+ * @param vault - the vault to read the farm APY for
1085
+ * @param vaultTokenPrice - the price of the vault token in USD (e.g. 1.0 for USDC)
1086
+ * @param [slot] - the slot to read the farm APY for. Optional. If not provided, the function will read the current slot
1087
+ * @returns the APY of the farm built on top of the vault
1088
+ */
1089
+ async getVaultFarmRewardsAPY(vault: KaminoVault, vaultTokenPrice: Decimal, slot?: Slot): Promise<FarmIncentives> {
1090
+ return this._vaultClient.getVaultRewardsAPY(vault, vaultTokenPrice, slot);
1091
+ }
1092
+
1093
+ /**
1094
+ * This will return the APY of the reserve farms (debt and supply)
1095
+ * @param reserve - the reserve to get the farms APY for
1096
+ * @param reserveTokenPrice - the price of the reserve token in USD (e.g. 1.0 for USDC)
1097
+ * @param [reserveState] - the reserve state. Optional. If not provided, the function will fetch the reserve state
1098
+ * @param [kaminoMarket] - the kamino market. Optional. If not provided, the function will fetch the kamino market
1099
+ * @returns the APY of the farm built on top of the reserve
1100
+ */
1101
+ async getReserveFarmRewardsAPY(
1102
+ reserve: Address,
1103
+ reserveTokenPrice: Decimal,
1104
+ reserveState?: Reserve,
1105
+ kaminoMarket?: KaminoMarket
1106
+ ): Promise<ReserveIncentives> {
1107
+ const reserveIncentives: ReserveIncentives = {
1108
+ collateralFarmIncentives: null,
1109
+ debtFarmIncentives: null,
1110
+ };
1111
+
1112
+ console.log("this._kaminoLendProgramId", this._kaminoLendProgramId.toString());
1113
+ const reserveAccount = reserveState
1114
+ ? reserveState
1115
+ : await Reserve.fetch(this._rpc, reserve, this._kaminoLendProgramId);
1116
+ if (!reserveAccount) {
1117
+ throw new Error(`Reserve ${reserve} not found`);
1118
+ }
1119
+
1120
+ let market = kaminoMarket;
1121
+ if (!market) {
1122
+ const fetckedMarket = await KaminoMarket.load(this._rpc, reserveAccount.lendingMarket, 450);
1123
+ if (!fetckedMarket) {
1124
+ throw new Error(`Market ${reserveAccount.lendingMarket} not found`);
1125
+ }
1126
+ market = fetckedMarket;
1127
+ }
1128
+
1129
+ const kaminoReserve = market.getReserveByAddress(reserve);
1130
+ if (!kaminoReserve) {
1131
+ throw new Error(`Strategy state not found for strategy: ${reserve}`);
1132
+ }
1133
+
1134
+ const farmCollateral = kaminoReserve.state.farmCollateral;
1135
+ const farmDebt = kaminoReserve.state.farmDebt;
1136
+
1137
+ const stakedTokenMintDecimals = kaminoReserve.getMintDecimals();
1138
+ const reserveCtokenPrice = reserveTokenPrice.div(kaminoReserve.getCollateralExchangeRate());
1139
+
1140
+ const farmsClient = new Farms(this._rpc);
1141
+ if (farmCollateral !== DEFAULT_PUBLIC_KEY) {
1142
+ const farmIncentivesCollateral = await getFarmIncentives(
1143
+ farmsClient,
1144
+ farmCollateral,
1145
+ reserveCtokenPrice,
1146
+ 6 // all cTokens have 6 decimals
1147
+ );
1148
+ reserveIncentives.collateralFarmIncentives = farmIncentivesCollateral;
1149
+ }
1150
+
1151
+ if (farmDebt !== DEFAULT_PUBLIC_KEY) {
1152
+ const farmIncentivesDebt = await getFarmIncentives(
1153
+ farmsClient,
1154
+ farmDebt,
1155
+ reserveTokenPrice,
1156
+ stakedTokenMintDecimals
1157
+ );
1158
+ reserveIncentives.debtFarmIncentives = farmIncentivesDebt;
1159
+ }
1160
+
1161
+ return reserveIncentives;
1162
+ }
1163
+
1079
1164
  /**
1080
1165
  * This will load the onchain state for all the reserves that the vault has allocations for
1081
1166
  * @param vaultState - the vault state to load reserves for
@@ -4,8 +4,8 @@ import {
4
4
  Base58EncodedBytes,
5
5
  Commitment,
6
6
  GetAccountInfoApi,
7
- getAddressEncoder,
8
7
  GetBalanceApi,
8
+ getBase58Decoder,
9
9
  GetMinimumBalanceForRentExemptionApi,
10
10
  GetMultipleAccountsApi,
11
11
  GetProgramAccountsApi,
@@ -40,8 +40,6 @@ import {
40
40
  userMetadataPda,
41
41
  VanillaObligation,
42
42
  } from '../utils';
43
- import base58 from 'bs58';
44
- import bs58 from 'bs58';
45
43
  import BN from 'bn.js';
46
44
  import Decimal from 'decimal.js';
47
45
  import { FarmState } from '@kamino-finance/farms-sdk';
@@ -63,7 +61,7 @@ export type KaminoMarketRpcApi = GetAccountInfoApi &
63
61
  GetTokenAccountBalanceApi &
64
62
  GetBalanceApi;
65
63
 
66
- const addressEncoder = getAddressEncoder();
64
+ const base58Decoder = getBase58Decoder();
67
65
 
68
66
  export interface ReserveRewardInfo {
69
67
  rewardsPerSecond: Decimal; // not lamport
@@ -614,7 +612,7 @@ export class KaminoMarket {
614
612
  filters.push({
615
613
  memcmp: {
616
614
  offset: 8n,
617
- bytes: base58.encode(new BN(tag).toBuffer()) as Base58EncodedBytes,
615
+ bytes: base58Decoder.decode(new BN(tag).toBuffer()) as Base58EncodedBytes,
618
616
  encoding: 'base58',
619
617
  },
620
618
  });
@@ -688,7 +686,7 @@ export class KaminoMarket {
688
686
  filters.push({
689
687
  memcmp: {
690
688
  offset: 8n,
691
- bytes: base58.encode(new BN(tag).toBuffer()) as Base58EncodedBytes,
689
+ bytes: base58Decoder.decode(new BN(tag).toBuffer()) as Base58EncodedBytes,
692
690
  encoding: 'base58',
693
691
  },
694
692
  });
@@ -754,7 +752,7 @@ export class KaminoMarket {
754
752
  {
755
753
  memcmp: {
756
754
  offset: 8n,
757
- bytes: base58.encode(new BN(tag).toBuffer()) as Base58EncodedBytes,
755
+ bytes: base58Decoder.decode(new BN(tag).toBuffer()) as Base58EncodedBytes,
758
756
  encoding: 'base58',
759
757
  },
760
758
  },
@@ -886,7 +884,7 @@ export class KaminoMarket {
886
884
  {
887
885
  memcmp: {
888
886
  offset: 0n,
889
- bytes: bs58.encode(Obligation.discriminator) as Base58EncodedBytes,
887
+ bytes: base58Decoder.decode(Obligation.discriminator) as Base58EncodedBytes,
890
888
  encoding: 'base58',
891
889
  },
892
890
  },
@@ -1046,7 +1044,7 @@ export class KaminoMarket {
1046
1044
  {
1047
1045
  memcmp: {
1048
1046
  offset: 8n,
1049
- bytes: base58.encode(new BN(tag).toBuffer()) as Base58EncodedBytes,
1047
+ bytes: base58Decoder.decode(new BN(tag).toBuffer()) as Base58EncodedBytes,
1050
1048
  encoding: 'base58',
1051
1049
  },
1052
1050
  },
@@ -1215,21 +1213,12 @@ export class KaminoMarket {
1215
1213
  return referrerFeesCumulativeForMints;
1216
1214
  }
1217
1215
 
1218
- async getReferrerUrl(baseUrl: string, referrer: Address) {
1219
- return baseUrl + this.encodeReferrer(referrer);
1216
+ getReferrerUrl(baseUrl: string, referrer: Address) {
1217
+ return `${baseUrl}${referrer.toString()}`;
1220
1218
  }
1221
1219
 
1222
- async getReferrerFromUrl(baseUrl: string, url: string) {
1223
- return this.decodeReferrer(url.split(baseUrl)[1]);
1224
- }
1225
-
1226
- async encodeReferrer(referrer: Address) {
1227
- return bs58.encode(Buffer.from(addressEncoder.encode(referrer)));
1228
- }
1229
-
1230
- async decodeReferrer(encoded_referrer: string) {
1231
- const referrer_buffer = bs58.decode(encoded_referrer);
1232
- return address(referrer_buffer.toString());
1220
+ getReferrerFromUrl(baseUrl: string, url: string) {
1221
+ return address(url.split(baseUrl)[1]);
1233
1222
  }
1234
1223
 
1235
1224
  /**
@@ -9,6 +9,7 @@ import {
9
9
  generateKeyPairSigner,
10
10
  GetAccountInfoApi,
11
11
  getAddressEncoder,
12
+ getBase58Decoder,
12
13
  GetProgramAccountsDatasizeFilter,
13
14
  GetProgramAccountsMemcmpFilter,
14
15
  getProgramDerivedAddress,
@@ -81,7 +82,6 @@ import {
81
82
  U64_MAX,
82
83
  VAULT_INITIAL_DEPOSIT,
83
84
  } from '../utils';
84
- import bs58 from 'bs58';
85
85
  import { getAccountOwner, getProgramAccounts } from '../utils/rpc';
86
86
  import {
87
87
  AcceptVaultOwnershipIxs,
@@ -98,7 +98,7 @@ import {
98
98
  } from './vault_types';
99
99
  import { batchFetch, collToLamportsDecimal, ZERO } from '@kamino-finance/kliquidity-sdk';
100
100
  import { FullBPSDecimal } from '@kamino-finance/kliquidity-sdk/dist/utils/CreationParameters';
101
- import { FarmState } from '@kamino-finance/farms-sdk/dist';
101
+ import { FarmIncentives, FarmState } from '@kamino-finance/farms-sdk/dist';
102
102
  import { getAccountsInLut, initLookupTableIx } from '../utils/lookupTable';
103
103
  import {
104
104
  getFarmStakeIxs,
@@ -120,6 +120,7 @@ import { SYSVAR_INSTRUCTIONS_ADDRESS, SYSVAR_RENT_ADDRESS } from '@solana/sysvar
120
120
  import { noopSigner } from '../utils/signer';
121
121
  import { getExtendLookupTableInstruction } from '@solana-program/address-lookup-table';
122
122
  import { Farms } from '@kamino-finance/farms-sdk';
123
+ import { getFarmIncentives } from '@kamino-finance/farms-sdk/dist/utils/apy';
123
124
 
124
125
  export const kaminoVaultId = address('KvauGMspG5k6rtzrqqn7WNn3oZdyKqLKwK2XWQ8FLjd');
125
126
  export const kaminoVaultStagingId = address('stKvQfwRsQiKnLtMNVLHKS3exFJmZFsgfzBPWHECUYK');
@@ -136,6 +137,7 @@ export const METADATA_PROGRAM_ID: Address = address('metaqbxxUerdq28cj1RbAWkYQm3
136
137
  export const INITIAL_DEPOSIT_LAMPORTS = 1000;
137
138
 
138
139
  const addressEncoder = getAddressEncoder();
140
+ const base58Decoder = getBase58Decoder();
139
141
 
140
142
  /**
141
143
  * KaminoVaultClient is a class that provides a high-level interface to interact with the Kamino Vault program.
@@ -2043,7 +2045,7 @@ export class KaminoVaultClient {
2043
2045
  {
2044
2046
  memcmp: {
2045
2047
  offset: 0n,
2046
- bytes: bs58.encode(VaultState.discriminator) as Base58EncodedBytes,
2048
+ bytes: base58Decoder.decode(VaultState.discriminator) as Base58EncodedBytes,
2047
2049
  encoding: 'base58',
2048
2050
  },
2049
2051
  },
@@ -2065,7 +2067,7 @@ export class KaminoVaultClient {
2065
2067
  {
2066
2068
  memcmp: {
2067
2069
  offset: 0n,
2068
- bytes: bs58.encode(VaultState.discriminator) as Base58EncodedBytes,
2070
+ bytes: base58Decoder.decode(VaultState.discriminator) as Base58EncodedBytes,
2069
2071
  encoding: 'base58',
2070
2072
  },
2071
2073
  },
@@ -2917,6 +2919,9 @@ export class KaminoVaultClient {
2917
2919
  };
2918
2920
  }
2919
2921
 
2922
+ /**
2923
+ * This will compute the PDA that is used as delegatee in Farms program to compute the user state PDA for vault depositor investing in vault with reserve having a supply farm
2924
+ */
2920
2925
  computeUserFarmStateDelegateePDAForUserInVault(
2921
2926
  farmsProgramId: Address,
2922
2927
  vault: Address,
@@ -2929,6 +2934,30 @@ export class KaminoVaultClient {
2929
2934
  });
2930
2935
  }
2931
2936
 
2937
+ /**
2938
+ * Read the APY of the farm built on top of the vault (farm in vaultState.vaultFarm)
2939
+ * @param vault - the vault to read the farm APY for
2940
+ * @param vaultTokenPrice - the price of the vault token in USD (e.g. 1.0 for USDC)
2941
+ * @param [slot] - the slot to read the farm APY for. Optional. If not provided, the function will read the current slot
2942
+ * @returns the APY of the farm built on top of the vault
2943
+ */
2944
+ async getVaultRewardsAPY(vault: KaminoVault, vaultTokenPrice: Decimal, slot?: Slot): Promise<FarmIncentives> {
2945
+ const vaultState = await vault.getState(this.getConnection());
2946
+ if (vaultState.vaultFarm === DEFAULT_PUBLIC_KEY) {
2947
+ return {
2948
+ incentivesStats: [],
2949
+ totalIncentivesApy: 0,
2950
+ };
2951
+ }
2952
+
2953
+ const tokensPerShare = await this.getTokensPerShareSingleVault(vault, slot);
2954
+ const sharePrice = tokensPerShare.mul(vaultTokenPrice);
2955
+ const stakedTokenMintDecimals = vaultState.sharesMintDecimals.toNumber();
2956
+
2957
+ const farmsClient = new Farms(this.getConnection());
2958
+ return getFarmIncentives(farmsClient, vaultState.vaultFarm, sharePrice, stakedTokenMintDecimals);
2959
+ }
2960
+
2932
2961
  private appendRemainingAccountsForVaultReserves(
2933
2962
  ix: IInstruction,
2934
2963
  vaultReserves: Address[],
@@ -4,6 +4,7 @@ import {
4
4
  appendTransactionMessageInstructions,
5
5
  compileTransactionMessage,
6
6
  createTransactionMessage,
7
+ getBase58Decoder,
7
8
  getCompiledTransactionMessageEncoder,
8
9
  IInstruction,
9
10
  pipe,
@@ -13,9 +14,10 @@ import {
13
14
  } from '@solana/kit';
14
15
  import { INVALID_BUT_SUFFICIENT_FOR_COMPILATION_BLOCKHASH } from './simulate';
15
16
  import { AddressLookupTable } from '@solana-program/address-lookup-table';
16
- import bs58 from 'bs58';
17
17
  import { removeComputeBudgetProgramInstructions } from './priorityFee';
18
18
 
19
+ const base58Decoder = getBase58Decoder();
20
+
19
21
  export async function printMultisigTx(
20
22
  payer: TransactionSigner,
21
23
  ixs: IInstruction[],
@@ -40,6 +42,6 @@ export async function printMultisigTx(
40
42
  const compiled = compileTransactionMessage(transactionMessage);
41
43
  const encodedMessageBytes = getCompiledTransactionMessageEncoder().encode(compiled);
42
44
 
43
- const base58EncodedMessage = bs58.encode(Uint8Array.from(encodedMessageBytes));
45
+ const base58EncodedMessage = base58Decoder.decode(encodedMessageBytes);
44
46
  console.log('Base58 encoded tx:', base58EncodedMessage);
45
47
  }
@@ -1310,6 +1310,37 @@ async function main() {
1310
1310
  console.log('vaultOverview', vaultOverview);
1311
1311
  });
1312
1312
 
1313
+ commands
1314
+ .command('get-vault-farm-apy')
1315
+ .requiredOption('--vault <string>', 'Vault address')
1316
+ .requiredOption('--token-price <number>', 'Vault token price in USD')
1317
+ .option(`--staging`, 'If true, will use the staging programs')
1318
+ .action(async ({ vault, tokenPrice, staging }) => {
1319
+ const env = await initEnv(staging);
1320
+ const slotDuration = await getMedianSlotDurationInMsFromLastEpochs();
1321
+
1322
+ const kaminoManager = new KaminoManager(env.c.rpc, slotDuration, env.klendProgramId, env.kvaultProgramId);
1323
+
1324
+ const kaminoVault = new KaminoVault(address(vault));
1325
+ const farmAPY = await kaminoManager.getVaultFarmRewardsAPY(kaminoVault, new Decimal(tokenPrice));
1326
+ console.log('farmAPY', farmAPY);
1327
+ });
1328
+
1329
+ commands
1330
+ .command('get-reserve-farms-apy')
1331
+ .requiredOption('--reserve <string>', 'Reserve address')
1332
+ .requiredOption('--token-price <number>', 'Reserve token price in USD')
1333
+ .option(`--staging`, 'If true, will use the staging programs')
1334
+ .action(async ({ reserve, tokenPrice, staging }) => {
1335
+ const env = await initEnv(staging);
1336
+ const slotDuration = await getMedianSlotDurationInMsFromLastEpochs();
1337
+
1338
+ const kaminoManager = new KaminoManager(env.c.rpc, slotDuration, address("KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD"), env.kvaultProgramId);
1339
+
1340
+ const farmAPY = await kaminoManager.getReserveFarmRewardsAPY(address(reserve), new Decimal(tokenPrice));
1341
+ console.log('farmAPY', farmAPY);
1342
+ });
1343
+
1313
1344
  commands
1314
1345
  .command('get-vault-allocation-distribution')
1315
1346
  .requiredOption('--vault <string>', 'Vault address')
@@ -4,6 +4,7 @@ import {
4
4
  appendTransactionMessageInstructions,
5
5
  compileTransactionMessage,
6
6
  createTransactionMessage,
7
+ getBase58Decoder,
7
8
  getCompiledTransactionMessageEncoder,
8
9
  IInstruction,
9
10
  pipe,
@@ -13,9 +14,10 @@ import {
13
14
  } from '@solana/kit';
14
15
  import { INVALID_BUT_SUFFICIENT_FOR_COMPILATION_BLOCKHASH } from './simulate';
15
16
  import { AddressLookupTable } from '@solana-program/address-lookup-table';
16
- import bs58 from 'bs58';
17
17
  import { removeComputeBudgetProgramInstructions } from './priorityFee';
18
18
 
19
+ const base58Decoder = getBase58Decoder();
20
+
19
21
  export async function printMultisigTx(
20
22
  payer: TransactionSigner,
21
23
  ixs: IInstruction[],
@@ -40,6 +42,6 @@ export async function printMultisigTx(
40
42
  const compiled = compileTransactionMessage(transactionMessage);
41
43
  const encodedMessageBytes = getCompiledTransactionMessageEncoder().encode(compiled);
42
44
 
43
- const base58EncodedMessage = bs58.encode(Uint8Array.from(encodedMessageBytes));
45
+ const base58EncodedMessage = base58Decoder.decode(encodedMessageBytes);
44
46
  console.log('Base58 encoded tx:', base58EncodedMessage);
45
47
  }
@@ -1,7 +1,8 @@
1
- import { Address, Base58EncodedBytes, GetProgramAccountsApi, Rpc } from '@solana/kit';
1
+ import { Address, Base58EncodedBytes, getBase58Decoder, GetProgramAccountsApi, Rpc } from '@solana/kit';
2
2
  import { LendingMarket, Obligation, Reserve } from '../@codegen/klend/accounts';
3
3
  import { PROGRAM_ID } from '../@codegen/klend/programId';
4
- import bs58 from 'bs58';
4
+
5
+ const base58Decoder = getBase58Decoder();
5
6
 
6
7
  export async function* getAllObligationAccounts(
7
8
  connection: Rpc<GetProgramAccountsApi>
@@ -17,14 +18,14 @@ export async function* getAllObligationAccounts(
17
18
  {
18
19
  memcmp: {
19
20
  offset: 0n,
20
- bytes: bs58.encode(Obligation.discriminator) as Base58EncodedBytes,
21
+ bytes: base58Decoder.decode(Obligation.discriminator) as Base58EncodedBytes,
21
22
  encoding: 'base58',
22
23
  },
23
24
  },
24
25
  {
25
26
  memcmp: {
26
27
  offset: 64n,
27
- bytes: bs58.encode([i]) as Base58EncodedBytes, // ...via sharding by userId's first byte (just as a source of randomness)
28
+ bytes: base58Decoder.decode(Buffer.from([i])) as Base58EncodedBytes, // ...via sharding by userId's first byte (just as a source of randomness)
28
29
  encoding: 'base58',
29
30
  },
30
31
  },
@@ -51,7 +52,7 @@ export async function* getAllReserveAccounts(
51
52
  {
52
53
  memcmp: {
53
54
  offset: 0n,
54
- bytes: bs58.encode(Reserve.discriminator) as Base58EncodedBytes,
55
+ bytes: base58Decoder.decode(Reserve.discriminator) as Base58EncodedBytes,
55
56
  encoding: 'base58',
56
57
  },
57
58
  },
@@ -78,7 +79,7 @@ export async function* getAllLendingMarketAccounts(
78
79
  {
79
80
  memcmp: {
80
81
  offset: 0n,
81
- bytes: bs58.encode(LendingMarket.discriminator) as Base58EncodedBytes,
82
+ bytes: base58Decoder.decode(LendingMarket.discriminator) as Base58EncodedBytes,
82
83
  encoding: 'base58',
83
84
  },
84
85
  },
@@ -252,6 +252,7 @@ export type AssetReserveConfigParams = {
252
252
  maxAgePriceSeconds: number;
253
253
  maxAgeTwapSeconds: number;
254
254
  borrowRateCurve: BorrowRateCurve;
255
+ hostFixedInterestRateBps: number;
255
256
  };
256
257
 
257
258
  export const DefaultConfigParams: AssetReserveConfigParams = {
@@ -276,6 +277,7 @@ export const DefaultConfigParams: AssetReserveConfigParams = {
276
277
  } as BorrowRateCurveFields),
277
278
  maxAgePriceSeconds: 180,
278
279
  maxAgeTwapSeconds: 240,
280
+ hostFixedInterestRateBps: 0,
279
281
  };
280
282
 
281
283
  export const encodeTokenName = (tokenName: string): number[] => {
@@ -359,7 +361,7 @@ function buildReserveConfig(fields: {
359
361
  deleveragingThresholdDecreaseBpsPerDay: new BN(24),
360
362
  disableUsageAsCollOutsideEmode: 0,
361
363
  utilizationLimitBlockBorrowingAbovePct: 0,
362
- hostFixedInterestRateBps: 0,
364
+ hostFixedInterestRateBps: fields.configParams.hostFixedInterestRateBps,
363
365
  autodeleverageEnabled: 0,
364
366
  borrowLimitOutsideElevationGroup: new BN(
365
367
  numberToLamportsDecimal(fields.borrowLimitOutsideElevationGroup ?? new Decimal(0), fields.mintDecimals)