@exponent-labs/kamino-vault-idl 0.9.29 → 0.9.30

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 (41) hide show
  1. package/README.md +77 -0
  2. package/build/accounts/fetchVaultReserves.d.ts +13 -0
  3. package/build/accounts/fetchVaultReserves.js +40 -0
  4. package/build/accounts/fetchVaultReserves.js.map +1 -0
  5. package/build/accounts/index.d.ts +2 -0
  6. package/build/accounts/index.js +6 -0
  7. package/build/accounts/index.js.map +1 -0
  8. package/build/index.d.ts +10 -6
  9. package/build/index.js +26 -8
  10. package/build/index.js.map +1 -1
  11. package/build/instructions/deposit.d.ts +28 -0
  12. package/build/instructions/deposit.js +31 -0
  13. package/build/instructions/deposit.js.map +1 -0
  14. package/build/instructions/encodeInstruction.d.ts +3 -0
  15. package/build/instructions/encodeInstruction.js +20 -0
  16. package/build/instructions/encodeInstruction.js.map +1 -0
  17. package/build/instructions/getVaultReserveAccounts.d.ts +7 -0
  18. package/build/instructions/getVaultReserveAccounts.js +11 -0
  19. package/build/instructions/getVaultReserveAccounts.js.map +1 -0
  20. package/build/instructions/index.d.ts +6 -0
  21. package/build/instructions/index.js +10 -0
  22. package/build/instructions/index.js.map +1 -0
  23. package/build/instructions/withdraw.d.ts +44 -0
  24. package/build/instructions/withdraw.js +45 -0
  25. package/build/instructions/withdraw.js.map +1 -0
  26. package/build/kaminovault.json +6 -2
  27. package/build/programId.d.ts +2 -0
  28. package/build/programId.js +10 -0
  29. package/build/programId.js.map +1 -0
  30. package/package.json +37 -3
  31. package/src/accounts/fetchVaultReserves.ts +52 -0
  32. package/src/accounts/index.ts +2 -0
  33. package/src/index.ts +8 -0
  34. package/src/instructions/deposit.ts +57 -0
  35. package/src/instructions/encodeInstruction.ts +16 -0
  36. package/src/instructions/getVaultReserveAccounts.ts +14 -0
  37. package/src/instructions/index.ts +6 -0
  38. package/src/instructions/withdraw.ts +87 -0
  39. package/src/kaminovault.json +6 -2
  40. package/src/programId.ts +5 -0
  41. package/tsconfig.json +0 -17
package/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # Kamino Vault instructions
2
+
3
+ The package exposes the same `args, accounts, programId?` instruction builder
4
+ structure as `@exponent-labs/klend-idl`. Existing root exports (`IDL`, the string
5
+ `PROGRAM_ID`, and `decodeVault`) are preserved.
6
+
7
+ - `@exponent-labs/kamino-vault-idl/instructions`: `deposit`, `withdraw`, and
8
+ `getVaultReserveAccounts`, with their argument/account types.
9
+ - `@exponent-labs/kamino-vault-idl/accounts`: `fetchVaultReserves`.
10
+
11
+ The deposit and withdrawal account layouts match the
12
+ [upstream v2.2.2 IDL](https://github.com/Kamino-Finance/klend-sdk/blob/master/src/idl/kvault.json)
13
+ and the mainnet program's on-chain IDL, checked on 2026-10-06. The bundled IDL's
14
+ withdrawal entries include the required `global_config` account. The rest of the
15
+ bundled IDL retains its existing layout.
16
+
17
+ ## Refresh and build instructions
18
+
19
+ ```typescript
20
+ import BN from "bn.js"
21
+
22
+ import { fetchVaultReserves } from "@exponent-labs/kamino-vault-idl/accounts"
23
+ import {
24
+ type DepositAccounts,
25
+ type WithdrawAccounts,
26
+ deposit,
27
+ getVaultReserveAccounts,
28
+ withdraw,
29
+ } from "@exponent-labs/kamino-vault-idl/instructions"
30
+ import { refreshReservesBatch } from "@exponent-labs/klend-idl/instructions"
31
+
32
+ // connection, vaultAddress, depositAccounts, and withdrawAccounts are caller inputs.
33
+ const reserves = await fetchVaultReserves(connection, vaultAddress)
34
+ const refreshIx = refreshReservesBatch({ skipPriceUpdates: true })
35
+ refreshIx.keys.push(
36
+ ...reserves.flatMap(({ reserveAddress, marketAddress }) => [
37
+ { pubkey: reserveAddress, isSigner: false, isWritable: true },
38
+ { pubkey: marketAddress, isSigner: false, isWritable: false },
39
+ ]),
40
+ )
41
+
42
+ const remainingAccounts = getVaultReserveAccounts(reserves)
43
+ const depositIx = deposit(
44
+ { maxAmount: new BN("1000000") }, // 1 USDC, including crank fees
45
+ { ...depositAccounts, remainingAccounts } satisfies DepositAccounts,
46
+ )
47
+ const withdrawIx = withdraw(
48
+ { sharesAmount: new BN("936761") }, // Raw vault shares, not a USDC amount
49
+ { ...withdrawAccounts, remainingAccounts } satisfies WithdrawAccounts,
50
+ )
51
+ ```
52
+
53
+ Send `[refreshIx, depositIx]` or `[refreshIx, withdrawIx]` in one transaction,
54
+ after any needed token account creation instructions. Refresh and the vault
55
+ instruction need to execute in the same slot. `skipPriceUpdates: true` accrues
56
+ reserve interest without fetching oracle updates.
57
+
58
+ KLend refresh accounts alternate **reserve, market**. KVault's remaining accounts
59
+ contain **all reserves, then all markets**, in allocation order. Repeated markets
60
+ must be retained.
61
+
62
+ `fetchVaultReserves` validates account ownership and discriminators and returns
63
+ `reserveAddress`, `marketAddress`, `ctokenVault`, and the decoded KLend `account`.
64
+ It skips unused allocation slots and throws if an active reserve is missing.
65
+
66
+ Withdrawal takes the IDL's nested `withdrawFromAvailable` and
67
+ `withdrawFromReserveAccounts` account groups. Select a reserve with sufficient
68
+ withdrawable liquidity; the decoded reserve exposes its collateral mint and
69
+ liquidity supply. Derive the lending market authority with seeds
70
+ `[Buffer.from("lma"), marketAddress.toBuffer()]` under the KLend program. Derive
71
+ `globalConfig` with `[Buffer.from("global_config")]` under the KVault program.
72
+ These builders return individual instructions; reserve selection, ATA creation,
73
+ and any farm unstaking are handled by the caller. If a vault requires a
74
+ permissioning authority, append its signer meta after the reserve/market blocks.
75
+
76
+ Run `yarn workspace @exponent-labs/kamino-vault-idl build` and
77
+ `yarn workspace @exponent-labs/kamino-vault-idl test` to validate the bindings.
@@ -0,0 +1,13 @@
1
+ import { Connection, PublicKey } from "@solana/web3.js";
2
+ import { Reserve } from "@exponent-labs/klend-idl/accounts";
3
+ export type VaultReserve = {
4
+ reserveAddress: PublicKey;
5
+ marketAddress: PublicKey;
6
+ ctokenVault: PublicKey;
7
+ account: Reserve;
8
+ };
9
+ /**
10
+ * Fetches every active reserve in vault allocation order, including its market and cToken vault.
11
+ * Verifies vault/reserve ownership and discriminators; throws for missing accounts.
12
+ */
13
+ export declare function fetchVaultReserves(connection: Connection, vaultAddress: PublicKey, programId?: PublicKey): Promise<VaultReserve[]>;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.fetchVaultReserves = fetchVaultReserves;
7
+ const anchor_1 = require("@coral-xyz/anchor");
8
+ const web3_js_1 = require("@solana/web3.js");
9
+ const accounts_1 = require("@exponent-labs/klend-idl/accounts");
10
+ const kaminovault_json_1 = __importDefault(require("../kaminovault.json"));
11
+ const programId_1 = require("../programId");
12
+ const ACCOUNT_CODER = new anchor_1.BorshAccountsCoder(kaminovault_json_1.default);
13
+ /**
14
+ * Fetches every active reserve in vault allocation order, including its market and cToken vault.
15
+ * Verifies vault/reserve ownership and discriminators; throws for missing accounts.
16
+ */
17
+ async function fetchVaultReserves(connection, vaultAddress, programId = programId_1.PROGRAM_ID) {
18
+ const info = await connection.getAccountInfo(vaultAddress);
19
+ if (!info)
20
+ throw new Error(`Kamino Vault not found: ${vaultAddress.toBase58()}`);
21
+ if (!info.owner.equals(programId))
22
+ throw new Error(`Account is not a Kamino Vault: ${vaultAddress.toBase58()}`);
23
+ const vault = ACCOUNT_CODER.decode("VaultState", info.data);
24
+ const allocations = vault.vault_allocation_strategy.filter(({ reserve }) => !reserve.equals(web3_js_1.PublicKey.default));
25
+ if (allocations.length === 0)
26
+ return [];
27
+ const reserves = await accounts_1.Reserve.fetchMultiple(connection, allocations.map(({ reserve }) => reserve));
28
+ return allocations.map((allocation, index) => {
29
+ const account = reserves[index];
30
+ if (!account)
31
+ throw new Error(`Kamino reserve not found: ${allocation.reserve.toBase58()}`);
32
+ return {
33
+ reserveAddress: allocation.reserve,
34
+ marketAddress: account.lendingMarket,
35
+ ctokenVault: allocation.ctoken_vault,
36
+ account,
37
+ };
38
+ });
39
+ }
40
+ //# sourceMappingURL=fetchVaultReserves.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetchVaultReserves.js","sourceRoot":"","sources":["../../src/accounts/fetchVaultReserves.ts"],"names":[],"mappings":";;;;;AAyBA,gDA0BC;AAnDD,8CAAgE;AAChE,6CAAuD;AAEvD,gEAA2D;AAE3D,2EAAqC;AACrC,4CAAyC;AAEzC,MAAM,aAAa,GAAG,IAAI,2BAAkB,CAAC,0BAAU,CAAC,CAAA;AAaxD;;;GAGG;AACI,KAAK,UAAU,kBAAkB,CACtC,UAAsB,EACtB,YAAuB,EACvB,YAAuB,sBAAU;IAEjC,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,cAAc,CAAC,YAAY,CAAC,CAAA;IAC1D,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;IAChF,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;IAC/G,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAmB,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;IAC7E,MAAM,WAAW,GAAG,KAAK,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,mBAAS,CAAC,OAAO,CAAC,CAAC,CAAA;IAC/G,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAA;IAEvC,MAAM,QAAQ,GAAG,MAAM,kBAAO,CAAC,aAAa,CAC1C,UAAU,EACV,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,CAC1C,CAAA;IACD,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,EAAE;QAC3C,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;QAC/B,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;QAC3F,OAAO;YACL,cAAc,EAAE,UAAU,CAAC,OAAO;YAClC,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,WAAW,EAAE,UAAU,CAAC,YAAY;YACpC,OAAO;SACR,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { fetchVaultReserves } from "./fetchVaultReserves";
2
+ export type { VaultReserve } from "./fetchVaultReserves";
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetchVaultReserves = void 0;
4
+ var fetchVaultReserves_1 = require("./fetchVaultReserves");
5
+ Object.defineProperty(exports, "fetchVaultReserves", { enumerable: true, get: function () { return fetchVaultReserves_1.fetchVaultReserves; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/accounts/index.ts"],"names":[],"mappings":";;;AAAA,2DAAyD;AAAhD,wHAAA,kBAAkB,OAAA"}
package/build/index.d.ts CHANGED
@@ -1,5 +1,9 @@
1
- /// <reference types="node" />
2
- /// <reference types="node" />
1
+ export * as accounts from "./accounts";
2
+ export * as instructions from "./instructions";
3
+ export { fetchVaultReserves } from "./accounts";
4
+ export type { VaultReserve } from "./accounts";
5
+ export { deposit, getVaultReserveAccounts, withdraw } from "./instructions";
6
+ export type { DepositArgs, DepositAccounts, WithdrawArgs, WithdrawAccounts, VaultReserveAccounts } from "./instructions";
3
7
  export declare const IDL: {
4
8
  address: string;
5
9
  metadata: {
@@ -34,16 +38,16 @@ export declare const IDL: {
34
38
  name: string;
35
39
  accounts: ({
36
40
  name: string;
37
- writable: boolean;
38
41
  signer: boolean;
42
+ writable?: undefined;
39
43
  } | {
40
44
  name: string;
41
45
  writable: boolean;
42
46
  signer?: undefined;
43
47
  } | {
44
48
  name: string;
45
- writable?: undefined;
46
49
  signer?: undefined;
50
+ writable?: undefined;
47
51
  })[];
48
52
  } | {
49
53
  name: string;
@@ -77,7 +81,7 @@ export declare const IDL: {
77
81
  signer?: undefined;
78
82
  docs?: undefined;
79
83
  })[];
80
- args: any[];
84
+ args: never[];
81
85
  } | {
82
86
  name: string;
83
87
  discriminator: number[];
@@ -129,7 +133,7 @@ export declare const IDL: {
129
133
  signer?: undefined;
130
134
  docs?: undefined;
131
135
  })[];
132
- args: any[];
136
+ args: never[];
133
137
  })[];
134
138
  accounts: {
135
139
  name: string;
package/build/index.js CHANGED
@@ -15,17 +15,35 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
25
35
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.decodeVault = exports.PROGRAM_ID = exports.IDL = void 0;
36
+ exports.decodeVault = exports.PROGRAM_ID = exports.IDL = exports.withdraw = exports.getVaultReserveAccounts = exports.deposit = exports.fetchVaultReserves = exports.instructions = exports.accounts = void 0;
27
37
  const anchor_1 = require("@coral-xyz/anchor");
28
38
  const idl = __importStar(require("./kaminovault.json"));
39
+ exports.accounts = __importStar(require("./accounts"));
40
+ exports.instructions = __importStar(require("./instructions"));
41
+ var accounts_1 = require("./accounts");
42
+ Object.defineProperty(exports, "fetchVaultReserves", { enumerable: true, get: function () { return accounts_1.fetchVaultReserves; } });
43
+ var instructions_1 = require("./instructions");
44
+ Object.defineProperty(exports, "deposit", { enumerable: true, get: function () { return instructions_1.deposit; } });
45
+ Object.defineProperty(exports, "getVaultReserveAccounts", { enumerable: true, get: function () { return instructions_1.getVaultReserveAccounts; } });
46
+ Object.defineProperty(exports, "withdraw", { enumerable: true, get: function () { return instructions_1.withdraw; } });
29
47
  exports.IDL = idl;
30
48
  exports.PROGRAM_ID = idl.address;
31
49
  const decodeVault = (data) => {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,8CAAmD;AACnD,wDAAyC;AAC5B,QAAA,GAAG,GAAG,GAAG,CAAA;AACT,QAAA,UAAU,GAAW,GAAG,CAAC,OAAO,CAAA;AAEtC,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,EAAE;IAC1C,MAAM,KAAK,GAAG,IAAI,mBAAU,CAAC,WAAU,CAAC,CAAA;IAExC,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,CAAA;IAEvD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AANY,QAAA,WAAW,eAMvB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,8CAAmD;AAEnD,wDAAyC;AAEzC,uDAAsC;AACtC,+DAA8C;AAC9C,uCAA+C;AAAtC,8GAAA,kBAAkB,OAAA;AAE3B,+CAA2E;AAAlE,uGAAA,OAAO,OAAA;AAAE,uHAAA,uBAAuB,OAAA;AAAE,wGAAA,QAAQ,OAAA;AAEtC,QAAA,GAAG,GAAG,GAAG,CAAA;AACT,QAAA,UAAU,GAAW,GAAG,CAAC,OAAO,CAAA;AAEtC,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,EAAE;IAC1C,MAAM,KAAK,GAAG,IAAI,mBAAU,CAAC,WAAU,CAAC,CAAA;IAExC,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,CAAA;IAEvD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AANY,QAAA,WAAW,eAMvB"}
@@ -0,0 +1,28 @@
1
+ import { type AccountMeta, PublicKey, TransactionInstruction } from "@solana/web3.js";
2
+ import type BN from "bn.js";
3
+ export type DepositArgs = {
4
+ /** Maximum deposit in raw underlying token units, including Kamino crank fees. */
5
+ maxAmount: BN;
6
+ };
7
+ export type DepositAccounts = {
8
+ user: PublicKey;
9
+ vaultState: PublicKey;
10
+ tokenVault: PublicKey;
11
+ tokenMint: PublicKey;
12
+ baseVaultAuthority: PublicKey;
13
+ sharesMint: PublicKey;
14
+ userTokenAta: PublicKey;
15
+ userSharesAta: PublicKey;
16
+ klendProgram: PublicKey;
17
+ tokenProgram: PublicKey;
18
+ sharesTokenProgram: PublicKey;
19
+ eventAuthority: PublicKey;
20
+ program: PublicKey;
21
+ /** All active reserves followed by their lending markets; use getVaultReserveAccounts. */
22
+ remainingAccounts?: readonly AccountMeta[];
23
+ };
24
+ /**
25
+ * Builds the Kamino Vault deposit instruction from its IDL.
26
+ * Token accounts must already exist, and reserves must be refreshed before execution.
27
+ */
28
+ export declare function deposit(args: DepositArgs, accounts: DepositAccounts, programId?: PublicKey): TransactionInstruction;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deposit = deposit;
4
+ const web3_js_1 = require("@solana/web3.js");
5
+ const programId_1 = require("../programId");
6
+ const encodeInstruction_1 = require("./encodeInstruction");
7
+ /**
8
+ * Builds the Kamino Vault deposit instruction from its IDL.
9
+ * Token accounts must already exist, and reserves must be refreshed before execution.
10
+ */
11
+ function deposit(args, accounts, programId = programId_1.PROGRAM_ID) {
12
+ const keys = [
13
+ { pubkey: accounts.user, isSigner: true, isWritable: true },
14
+ { pubkey: accounts.vaultState, isSigner: false, isWritable: true },
15
+ { pubkey: accounts.tokenVault, isSigner: false, isWritable: true },
16
+ { pubkey: accounts.tokenMint, isSigner: false, isWritable: false },
17
+ { pubkey: accounts.baseVaultAuthority, isSigner: false, isWritable: false },
18
+ { pubkey: accounts.sharesMint, isSigner: false, isWritable: true },
19
+ { pubkey: accounts.userTokenAta, isSigner: false, isWritable: true },
20
+ { pubkey: accounts.userSharesAta, isSigner: false, isWritable: true },
21
+ { pubkey: accounts.klendProgram, isSigner: false, isWritable: false },
22
+ { pubkey: accounts.tokenProgram, isSigner: false, isWritable: false },
23
+ { pubkey: accounts.sharesTokenProgram, isSigner: false, isWritable: false },
24
+ { pubkey: accounts.eventAuthority, isSigner: false, isWritable: false },
25
+ { pubkey: accounts.program, isSigner: false, isWritable: false },
26
+ ...(accounts.remainingAccounts ?? []).map((account) => ({ ...account })),
27
+ ];
28
+ const data = (0, encodeInstruction_1.encodeInstruction)("deposit", { max_amount: args.maxAmount });
29
+ return new web3_js_1.TransactionInstruction({ keys, programId, data });
30
+ }
31
+ //# sourceMappingURL=deposit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deposit.js","sourceRoot":"","sources":["../../src/instructions/deposit.ts"],"names":[],"mappings":";;AAiCA,0BAuBC;AAxDD,6CAAqF;AAGrF,4CAAyC;AACzC,2DAAuD;AAyBvD;;;GAGG;AACH,SAAgB,OAAO,CACrB,IAAiB,EACjB,QAAyB,EACzB,YAAuB,sBAAU;IAEjC,MAAM,IAAI,GAAkB;QAC1B,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;QAC3D,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE;QAClE,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE;QAClE,EAAE,MAAM,EAAE,QAAQ,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE;QAClE,EAAE,MAAM,EAAE,QAAQ,CAAC,kBAAkB,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE;QAC3E,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE;QAClE,EAAE,MAAM,EAAE,QAAQ,CAAC,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE;QACpE,EAAE,MAAM,EAAE,QAAQ,CAAC,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE;QACrE,EAAE,MAAM,EAAE,QAAQ,CAAC,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE;QACrE,EAAE,MAAM,EAAE,QAAQ,CAAC,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE;QACrE,EAAE,MAAM,EAAE,QAAQ,CAAC,kBAAkB,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE;QAC3E,EAAE,MAAM,EAAE,QAAQ,CAAC,cAAc,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE;QACvE,EAAE,MAAM,EAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE;QAChE,GAAG,CAAC,QAAQ,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;KACzE,CAAA;IACD,MAAM,IAAI,GAAG,IAAA,qCAAiB,EAAC,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAA;IACzE,OAAO,IAAI,gCAAsB,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;AAC9D,CAAC"}
@@ -0,0 +1,3 @@
1
+ import BN from "bn.js";
2
+ /** Encodes the vault's u64 arguments using the bundled IDL, rejecting values outside the wire format. */
3
+ export declare function encodeInstruction(name: "deposit" | "withdraw", args: Record<string, BN>): Buffer;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.encodeInstruction = encodeInstruction;
7
+ const anchor_1 = require("@coral-xyz/anchor");
8
+ const bn_js_1 = __importDefault(require("bn.js"));
9
+ const kaminovault_json_1 = __importDefault(require("../kaminovault.json"));
10
+ const INSTRUCTION_CODER = new anchor_1.BorshInstructionCoder(kaminovault_json_1.default);
11
+ /** Encodes the vault's u64 arguments using the bundled IDL, rejecting values outside the wire format. */
12
+ function encodeInstruction(name, args) {
13
+ for (const [field, value] of Object.entries(args)) {
14
+ if (!bn_js_1.default.isBN(value) || value.isNeg() || value.bitLength() > 64) {
15
+ throw new Error(`${field} must be an unsigned 64-bit integer`);
16
+ }
17
+ }
18
+ return INSTRUCTION_CODER.encode(name, args);
19
+ }
20
+ //# sourceMappingURL=encodeInstruction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encodeInstruction.js","sourceRoot":"","sources":["../../src/instructions/encodeInstruction.ts"],"names":[],"mappings":";;;;;AAQA,8CAOC;AAfD,8CAAmE;AACnE,kDAAsB;AAEtB,2EAAqC;AAErC,MAAM,iBAAiB,GAAG,IAAI,8BAAqB,CAAC,0BAAU,CAAC,CAAA;AAE/D,yGAAyG;AACzG,SAAgB,iBAAiB,CAAC,IAA4B,EAAE,IAAwB;IACtF,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAClD,IAAI,CAAC,eAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,IAAI,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,CAAC;YAC/D,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,qCAAqC,CAAC,CAAA;QAChE,CAAC;IACH,CAAC;IACD,OAAO,iBAAiB,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;AAC7C,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { AccountMeta, PublicKey } from "@solana/web3.js";
2
+ export type VaultReserveAccounts = {
3
+ reserveAddress: PublicKey;
4
+ marketAddress: PublicKey;
5
+ };
6
+ /** Builds KVault remaining accounts as an allocation-ordered reserve block followed by its market block. */
7
+ export declare function getVaultReserveAccounts(reserves: readonly VaultReserveAccounts[]): AccountMeta[];
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getVaultReserveAccounts = getVaultReserveAccounts;
4
+ /** Builds KVault remaining accounts as an allocation-ordered reserve block followed by its market block. */
5
+ function getVaultReserveAccounts(reserves) {
6
+ return [
7
+ ...reserves.map(({ reserveAddress }) => ({ pubkey: reserveAddress, isSigner: false, isWritable: true })),
8
+ ...reserves.map(({ marketAddress }) => ({ pubkey: marketAddress, isSigner: false, isWritable: false })),
9
+ ];
10
+ }
11
+ //# sourceMappingURL=getVaultReserveAccounts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getVaultReserveAccounts.js","sourceRoot":"","sources":["../../src/instructions/getVaultReserveAccounts.ts"],"names":[],"mappings":";;AAQA,0DAKC;AAND,4GAA4G;AAC5G,SAAgB,uBAAuB,CAAC,QAAyC;IAC/E,OAAO;QACL,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QACxG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;KACxG,CAAA;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { deposit } from "./deposit";
2
+ export type { DepositArgs, DepositAccounts } from "./deposit";
3
+ export { withdraw } from "./withdraw";
4
+ export type { WithdrawArgs, WithdrawAccounts } from "./withdraw";
5
+ export { getVaultReserveAccounts } from "./getVaultReserveAccounts";
6
+ export type { VaultReserveAccounts } from "./getVaultReserveAccounts";
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getVaultReserveAccounts = exports.withdraw = exports.deposit = void 0;
4
+ var deposit_1 = require("./deposit");
5
+ Object.defineProperty(exports, "deposit", { enumerable: true, get: function () { return deposit_1.deposit; } });
6
+ var withdraw_1 = require("./withdraw");
7
+ Object.defineProperty(exports, "withdraw", { enumerable: true, get: function () { return withdraw_1.withdraw; } });
8
+ var getVaultReserveAccounts_1 = require("./getVaultReserveAccounts");
9
+ Object.defineProperty(exports, "getVaultReserveAccounts", { enumerable: true, get: function () { return getVaultReserveAccounts_1.getVaultReserveAccounts; } });
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/instructions/index.ts"],"names":[],"mappings":";;;AAAA,qCAAmC;AAA1B,kGAAA,OAAO,OAAA;AAEhB,uCAAqC;AAA5B,oGAAA,QAAQ,OAAA;AAEjB,qEAAmE;AAA1D,kIAAA,uBAAuB,OAAA"}
@@ -0,0 +1,44 @@
1
+ import { type AccountMeta, PublicKey, TransactionInstruction } from "@solana/web3.js";
2
+ import type BN from "bn.js";
3
+ export type WithdrawArgs = {
4
+ /** Vault shares to burn in raw share token units. */
5
+ sharesAmount: BN;
6
+ };
7
+ export type WithdrawAccounts = {
8
+ withdrawFromAvailable: {
9
+ user: PublicKey;
10
+ vaultState: PublicKey;
11
+ globalConfig: PublicKey;
12
+ tokenVault: PublicKey;
13
+ baseVaultAuthority: PublicKey;
14
+ userTokenAta: PublicKey;
15
+ tokenMint: PublicKey;
16
+ userSharesAta: PublicKey;
17
+ sharesMint: PublicKey;
18
+ tokenProgram: PublicKey;
19
+ sharesTokenProgram: PublicKey;
20
+ klendProgram: PublicKey;
21
+ eventAuthority: PublicKey;
22
+ program: PublicKey;
23
+ };
24
+ withdrawFromReserveAccounts: {
25
+ vaultState: PublicKey;
26
+ reserve: PublicKey;
27
+ ctokenVault: PublicKey;
28
+ lendingMarket: PublicKey;
29
+ lendingMarketAuthority: PublicKey;
30
+ reserveLiquiditySupply: PublicKey;
31
+ reserveCollateralMint: PublicKey;
32
+ reserveCollateralTokenProgram: PublicKey;
33
+ instructionSysvarAccount: PublicKey;
34
+ };
35
+ eventAuthority: PublicKey;
36
+ program: PublicKey;
37
+ /** All active reserves followed by their lending markets; use getVaultReserveAccounts. */
38
+ remainingAccounts?: readonly AccountMeta[];
39
+ };
40
+ /**
41
+ * Builds a reserve-specific Kamino Vault withdrawal using raw share units.
42
+ * Callers select a reserve with sufficient liquidity and refresh all active reserves before execution.
43
+ */
44
+ export declare function withdraw(args: WithdrawArgs, accounts: WithdrawAccounts, programId?: PublicKey): TransactionInstruction;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withdraw = withdraw;
4
+ const web3_js_1 = require("@solana/web3.js");
5
+ const programId_1 = require("../programId");
6
+ const encodeInstruction_1 = require("./encodeInstruction");
7
+ /**
8
+ * Builds a reserve-specific Kamino Vault withdrawal using raw share units.
9
+ * Callers select a reserve with sufficient liquidity and refresh all active reserves before execution.
10
+ */
11
+ function withdraw(args, accounts, programId = programId_1.PROGRAM_ID) {
12
+ const available = accounts.withdrawFromAvailable;
13
+ const reserve = accounts.withdrawFromReserveAccounts;
14
+ const keys = [
15
+ { pubkey: available.user, isSigner: true, isWritable: false },
16
+ { pubkey: available.vaultState, isSigner: false, isWritable: true },
17
+ { pubkey: available.globalConfig, isSigner: false, isWritable: false },
18
+ { pubkey: available.tokenVault, isSigner: false, isWritable: true },
19
+ { pubkey: available.baseVaultAuthority, isSigner: false, isWritable: false },
20
+ { pubkey: available.userTokenAta, isSigner: false, isWritable: true },
21
+ { pubkey: available.tokenMint, isSigner: false, isWritable: true },
22
+ { pubkey: available.userSharesAta, isSigner: false, isWritable: true },
23
+ { pubkey: available.sharesMint, isSigner: false, isWritable: true },
24
+ { pubkey: available.tokenProgram, isSigner: false, isWritable: false },
25
+ { pubkey: available.sharesTokenProgram, isSigner: false, isWritable: false },
26
+ { pubkey: available.klendProgram, isSigner: false, isWritable: false },
27
+ { pubkey: available.eventAuthority, isSigner: false, isWritable: false },
28
+ { pubkey: available.program, isSigner: false, isWritable: false },
29
+ { pubkey: reserve.vaultState, isSigner: false, isWritable: true },
30
+ { pubkey: reserve.reserve, isSigner: false, isWritable: true },
31
+ { pubkey: reserve.ctokenVault, isSigner: false, isWritable: true },
32
+ { pubkey: reserve.lendingMarket, isSigner: false, isWritable: false },
33
+ { pubkey: reserve.lendingMarketAuthority, isSigner: false, isWritable: false },
34
+ { pubkey: reserve.reserveLiquiditySupply, isSigner: false, isWritable: true },
35
+ { pubkey: reserve.reserveCollateralMint, isSigner: false, isWritable: true },
36
+ { pubkey: reserve.reserveCollateralTokenProgram, isSigner: false, isWritable: false },
37
+ { pubkey: reserve.instructionSysvarAccount, isSigner: false, isWritable: false },
38
+ { pubkey: accounts.eventAuthority, isSigner: false, isWritable: false },
39
+ { pubkey: accounts.program, isSigner: false, isWritable: false },
40
+ ...(accounts.remainingAccounts ?? []).map((account) => ({ ...account })),
41
+ ];
42
+ const data = (0, encodeInstruction_1.encodeInstruction)("withdraw", { shares_amount: args.sharesAmount });
43
+ return new web3_js_1.TransactionInstruction({ keys, programId, data });
44
+ }
45
+ //# sourceMappingURL=withdraw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"withdraw.js","sourceRoot":"","sources":["../../src/instructions/withdraw.ts"],"names":[],"mappings":"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"}
@@ -167,13 +167,15 @@
167
167
  "accounts": [
168
168
  {
169
169
  "name": "user",
170
- "writable": true,
171
170
  "signer": true
172
171
  },
173
172
  {
174
173
  "name": "vault_state",
175
174
  "writable": true
176
175
  },
176
+ {
177
+ "name": "global_config"
178
+ },
177
179
  {
178
180
  "name": "token_vault",
179
181
  "writable": true
@@ -561,13 +563,15 @@
561
563
  "accounts": [
562
564
  {
563
565
  "name": "user",
564
- "writable": true,
565
566
  "signer": true
566
567
  },
567
568
  {
568
569
  "name": "vault_state",
569
570
  "writable": true
570
571
  },
572
+ {
573
+ "name": "global_config"
574
+ },
571
575
  {
572
576
  "name": "token_vault",
573
577
  "writable": true
@@ -0,0 +1,2 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ export declare const PROGRAM_ID: PublicKey;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PROGRAM_ID = void 0;
7
+ const web3_js_1 = require("@solana/web3.js");
8
+ const kaminovault_json_1 = __importDefault(require("./kaminovault.json"));
9
+ exports.PROGRAM_ID = new web3_js_1.PublicKey(kaminovault_json_1.default.address);
10
+ //# sourceMappingURL=programId.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"programId.js","sourceRoot":"","sources":["../src/programId.ts"],"names":[],"mappings":";;;;;;AAAA,6CAA2C;AAE3C,0EAAoC;AAEvB,QAAA,UAAU,GAAG,IAAI,mBAAS,CAAC,0BAAG,CAAC,OAAO,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,16 +1,50 @@
1
1
  {
2
2
  "name": "@exponent-labs/kamino-vault-idl",
3
- "version": "0.9.29",
3
+ "version": "0.9.30",
4
4
  "main": "build/index.js",
5
5
  "types": "build/index.d.ts",
6
+ "files": [
7
+ "build",
8
+ "src"
9
+ ],
10
+ "exports": {
11
+ ".": {
12
+ "types": "./build/index.d.ts",
13
+ "default": "./build/index.js"
14
+ },
15
+ "./instructions": {
16
+ "types": "./build/instructions/index.d.ts",
17
+ "default": "./build/instructions/index.js"
18
+ },
19
+ "./accounts": {
20
+ "types": "./build/accounts/index.d.ts",
21
+ "default": "./build/accounts/index.js"
22
+ }
23
+ },
24
+ "typesVersions": {
25
+ "*": {
26
+ "instructions": [
27
+ "./build/instructions/index.d.ts"
28
+ ],
29
+ "accounts": [
30
+ "./build/accounts/index.d.ts"
31
+ ]
32
+ }
33
+ },
6
34
  "license": "AGPL-3.0",
7
35
  "scripts": {
8
- "build": "tsc --build"
36
+ "build": "tsc --build",
37
+ "test": "node --import tsx --test test/*.test.ts"
9
38
  },
10
39
  "dependencies": {
11
- "@coral-xyz/anchor": "0.31.1"
40
+ "@coral-xyz/anchor": "0.31.1",
41
+ "@exponent-labs/klend-idl": "0.9.30",
42
+ "@solana/web3.js": "1.98.4",
43
+ "bn.js": "5.2.2"
12
44
  },
13
45
  "devDependencies": {
46
+ "@types/bn.js": "^5.1.0",
47
+ "tsx": "^4.19.4",
14
48
  "typescript": "5.4.5"
15
49
  }
16
50
  }
@@ -0,0 +1,52 @@
1
+ import { BorshAccountsCoder, type Idl } from "@coral-xyz/anchor"
2
+ import { Connection, PublicKey } from "@solana/web3.js"
3
+
4
+ import { Reserve } from "@exponent-labs/klend-idl/accounts"
5
+
6
+ import idl from "../kaminovault.json"
7
+ import { PROGRAM_ID } from "../programId"
8
+
9
+ const ACCOUNT_CODER = new BorshAccountsCoder(idl as Idl)
10
+
11
+ type VaultAllocations = {
12
+ vault_allocation_strategy: { reserve: PublicKey; ctoken_vault: PublicKey }[]
13
+ }
14
+
15
+ export type VaultReserve = {
16
+ reserveAddress: PublicKey
17
+ marketAddress: PublicKey
18
+ ctokenVault: PublicKey
19
+ account: Reserve
20
+ }
21
+
22
+ /**
23
+ * Fetches every active reserve in vault allocation order, including its market and cToken vault.
24
+ * Verifies vault/reserve ownership and discriminators; throws for missing accounts.
25
+ */
26
+ export async function fetchVaultReserves(
27
+ connection: Connection,
28
+ vaultAddress: PublicKey,
29
+ programId: PublicKey = PROGRAM_ID,
30
+ ): Promise<VaultReserve[]> {
31
+ const info = await connection.getAccountInfo(vaultAddress)
32
+ if (!info) throw new Error(`Kamino Vault not found: ${vaultAddress.toBase58()}`)
33
+ if (!info.owner.equals(programId)) throw new Error(`Account is not a Kamino Vault: ${vaultAddress.toBase58()}`)
34
+ const vault = ACCOUNT_CODER.decode<VaultAllocations>("VaultState", info.data)
35
+ const allocations = vault.vault_allocation_strategy.filter(({ reserve }) => !reserve.equals(PublicKey.default))
36
+ if (allocations.length === 0) return []
37
+
38
+ const reserves = await Reserve.fetchMultiple(
39
+ connection,
40
+ allocations.map(({ reserve }) => reserve),
41
+ )
42
+ return allocations.map((allocation, index) => {
43
+ const account = reserves[index]
44
+ if (!account) throw new Error(`Kamino reserve not found: ${allocation.reserve.toBase58()}`)
45
+ return {
46
+ reserveAddress: allocation.reserve,
47
+ marketAddress: account.lendingMarket,
48
+ ctokenVault: allocation.ctoken_vault,
49
+ account,
50
+ }
51
+ })
52
+ }
@@ -0,0 +1,2 @@
1
+ export { fetchVaultReserves } from "./fetchVaultReserves"
2
+ export type { VaultReserve } from "./fetchVaultReserves"
package/src/index.ts CHANGED
@@ -1,5 +1,13 @@
1
1
  import { BorshCoder, Idl } from "@coral-xyz/anchor"
2
+
2
3
  import * as idl from "./kaminovault.json"
4
+
5
+ export * as accounts from "./accounts"
6
+ export * as instructions from "./instructions"
7
+ export { fetchVaultReserves } from "./accounts"
8
+ export type { VaultReserve } from "./accounts"
9
+ export { deposit, getVaultReserveAccounts, withdraw } from "./instructions"
10
+ export type { DepositArgs, DepositAccounts, WithdrawArgs, WithdrawAccounts, VaultReserveAccounts } from "./instructions"
3
11
  export const IDL = idl
4
12
  export const PROGRAM_ID: string = idl.address
5
13
 
@@ -0,0 +1,57 @@
1
+ import { type AccountMeta, PublicKey, TransactionInstruction } from "@solana/web3.js"
2
+ import type BN from "bn.js"
3
+
4
+ import { PROGRAM_ID } from "../programId"
5
+ import { encodeInstruction } from "./encodeInstruction"
6
+
7
+ export type DepositArgs = {
8
+ /** Maximum deposit in raw underlying token units, including Kamino crank fees. */
9
+ maxAmount: BN
10
+ }
11
+
12
+ export type DepositAccounts = {
13
+ user: PublicKey
14
+ vaultState: PublicKey
15
+ tokenVault: PublicKey
16
+ tokenMint: PublicKey
17
+ baseVaultAuthority: PublicKey
18
+ sharesMint: PublicKey
19
+ userTokenAta: PublicKey
20
+ userSharesAta: PublicKey
21
+ klendProgram: PublicKey
22
+ tokenProgram: PublicKey
23
+ sharesTokenProgram: PublicKey
24
+ eventAuthority: PublicKey
25
+ program: PublicKey
26
+ /** All active reserves followed by their lending markets; use getVaultReserveAccounts. */
27
+ remainingAccounts?: readonly AccountMeta[]
28
+ }
29
+
30
+ /**
31
+ * Builds the Kamino Vault deposit instruction from its IDL.
32
+ * Token accounts must already exist, and reserves must be refreshed before execution.
33
+ */
34
+ export function deposit(
35
+ args: DepositArgs,
36
+ accounts: DepositAccounts,
37
+ programId: PublicKey = PROGRAM_ID,
38
+ ): TransactionInstruction {
39
+ const keys: AccountMeta[] = [
40
+ { pubkey: accounts.user, isSigner: true, isWritable: true },
41
+ { pubkey: accounts.vaultState, isSigner: false, isWritable: true },
42
+ { pubkey: accounts.tokenVault, isSigner: false, isWritable: true },
43
+ { pubkey: accounts.tokenMint, isSigner: false, isWritable: false },
44
+ { pubkey: accounts.baseVaultAuthority, isSigner: false, isWritable: false },
45
+ { pubkey: accounts.sharesMint, isSigner: false, isWritable: true },
46
+ { pubkey: accounts.userTokenAta, isSigner: false, isWritable: true },
47
+ { pubkey: accounts.userSharesAta, isSigner: false, isWritable: true },
48
+ { pubkey: accounts.klendProgram, isSigner: false, isWritable: false },
49
+ { pubkey: accounts.tokenProgram, isSigner: false, isWritable: false },
50
+ { pubkey: accounts.sharesTokenProgram, isSigner: false, isWritable: false },
51
+ { pubkey: accounts.eventAuthority, isSigner: false, isWritable: false },
52
+ { pubkey: accounts.program, isSigner: false, isWritable: false },
53
+ ...(accounts.remainingAccounts ?? []).map((account) => ({ ...account })),
54
+ ]
55
+ const data = encodeInstruction("deposit", { max_amount: args.maxAmount })
56
+ return new TransactionInstruction({ keys, programId, data })
57
+ }
@@ -0,0 +1,16 @@
1
+ import { BorshInstructionCoder, type Idl } from "@coral-xyz/anchor"
2
+ import BN from "bn.js"
3
+
4
+ import idl from "../kaminovault.json"
5
+
6
+ const INSTRUCTION_CODER = new BorshInstructionCoder(idl as Idl)
7
+
8
+ /** Encodes the vault's u64 arguments using the bundled IDL, rejecting values outside the wire format. */
9
+ export function encodeInstruction(name: "deposit" | "withdraw", args: Record<string, BN>): Buffer {
10
+ for (const [field, value] of Object.entries(args)) {
11
+ if (!BN.isBN(value) || value.isNeg() || value.bitLength() > 64) {
12
+ throw new Error(`${field} must be an unsigned 64-bit integer`)
13
+ }
14
+ }
15
+ return INSTRUCTION_CODER.encode(name, args)
16
+ }
@@ -0,0 +1,14 @@
1
+ import type { AccountMeta, PublicKey } from "@solana/web3.js"
2
+
3
+ export type VaultReserveAccounts = {
4
+ reserveAddress: PublicKey
5
+ marketAddress: PublicKey
6
+ }
7
+
8
+ /** Builds KVault remaining accounts as an allocation-ordered reserve block followed by its market block. */
9
+ export function getVaultReserveAccounts(reserves: readonly VaultReserveAccounts[]): AccountMeta[] {
10
+ return [
11
+ ...reserves.map(({ reserveAddress }) => ({ pubkey: reserveAddress, isSigner: false, isWritable: true })),
12
+ ...reserves.map(({ marketAddress }) => ({ pubkey: marketAddress, isSigner: false, isWritable: false })),
13
+ ]
14
+ }
@@ -0,0 +1,6 @@
1
+ export { deposit } from "./deposit"
2
+ export type { DepositArgs, DepositAccounts } from "./deposit"
3
+ export { withdraw } from "./withdraw"
4
+ export type { WithdrawArgs, WithdrawAccounts } from "./withdraw"
5
+ export { getVaultReserveAccounts } from "./getVaultReserveAccounts"
6
+ export type { VaultReserveAccounts } from "./getVaultReserveAccounts"
@@ -0,0 +1,87 @@
1
+ import { type AccountMeta, PublicKey, TransactionInstruction } from "@solana/web3.js"
2
+ import type BN from "bn.js"
3
+
4
+ import { PROGRAM_ID } from "../programId"
5
+ import { encodeInstruction } from "./encodeInstruction"
6
+
7
+ export type WithdrawArgs = {
8
+ /** Vault shares to burn in raw share token units. */
9
+ sharesAmount: BN
10
+ }
11
+
12
+ export type WithdrawAccounts = {
13
+ withdrawFromAvailable: {
14
+ user: PublicKey
15
+ vaultState: PublicKey
16
+ globalConfig: PublicKey
17
+ tokenVault: PublicKey
18
+ baseVaultAuthority: PublicKey
19
+ userTokenAta: PublicKey
20
+ tokenMint: PublicKey
21
+ userSharesAta: PublicKey
22
+ sharesMint: PublicKey
23
+ tokenProgram: PublicKey
24
+ sharesTokenProgram: PublicKey
25
+ klendProgram: PublicKey
26
+ eventAuthority: PublicKey
27
+ program: PublicKey
28
+ }
29
+ withdrawFromReserveAccounts: {
30
+ vaultState: PublicKey
31
+ reserve: PublicKey
32
+ ctokenVault: PublicKey
33
+ lendingMarket: PublicKey
34
+ lendingMarketAuthority: PublicKey
35
+ reserveLiquiditySupply: PublicKey
36
+ reserveCollateralMint: PublicKey
37
+ reserveCollateralTokenProgram: PublicKey
38
+ instructionSysvarAccount: PublicKey
39
+ }
40
+ eventAuthority: PublicKey
41
+ program: PublicKey
42
+ /** All active reserves followed by their lending markets; use getVaultReserveAccounts. */
43
+ remainingAccounts?: readonly AccountMeta[]
44
+ }
45
+
46
+ /**
47
+ * Builds a reserve-specific Kamino Vault withdrawal using raw share units.
48
+ * Callers select a reserve with sufficient liquidity and refresh all active reserves before execution.
49
+ */
50
+ export function withdraw(
51
+ args: WithdrawArgs,
52
+ accounts: WithdrawAccounts,
53
+ programId: PublicKey = PROGRAM_ID,
54
+ ): TransactionInstruction {
55
+ const available = accounts.withdrawFromAvailable
56
+ const reserve = accounts.withdrawFromReserveAccounts
57
+ const keys: AccountMeta[] = [
58
+ { pubkey: available.user, isSigner: true, isWritable: false },
59
+ { pubkey: available.vaultState, isSigner: false, isWritable: true },
60
+ { pubkey: available.globalConfig, isSigner: false, isWritable: false },
61
+ { pubkey: available.tokenVault, isSigner: false, isWritable: true },
62
+ { pubkey: available.baseVaultAuthority, isSigner: false, isWritable: false },
63
+ { pubkey: available.userTokenAta, isSigner: false, isWritable: true },
64
+ { pubkey: available.tokenMint, isSigner: false, isWritable: true },
65
+ { pubkey: available.userSharesAta, isSigner: false, isWritable: true },
66
+ { pubkey: available.sharesMint, isSigner: false, isWritable: true },
67
+ { pubkey: available.tokenProgram, isSigner: false, isWritable: false },
68
+ { pubkey: available.sharesTokenProgram, isSigner: false, isWritable: false },
69
+ { pubkey: available.klendProgram, isSigner: false, isWritable: false },
70
+ { pubkey: available.eventAuthority, isSigner: false, isWritable: false },
71
+ { pubkey: available.program, isSigner: false, isWritable: false },
72
+ { pubkey: reserve.vaultState, isSigner: false, isWritable: true },
73
+ { pubkey: reserve.reserve, isSigner: false, isWritable: true },
74
+ { pubkey: reserve.ctokenVault, isSigner: false, isWritable: true },
75
+ { pubkey: reserve.lendingMarket, isSigner: false, isWritable: false },
76
+ { pubkey: reserve.lendingMarketAuthority, isSigner: false, isWritable: false },
77
+ { pubkey: reserve.reserveLiquiditySupply, isSigner: false, isWritable: true },
78
+ { pubkey: reserve.reserveCollateralMint, isSigner: false, isWritable: true },
79
+ { pubkey: reserve.reserveCollateralTokenProgram, isSigner: false, isWritable: false },
80
+ { pubkey: reserve.instructionSysvarAccount, isSigner: false, isWritable: false },
81
+ { pubkey: accounts.eventAuthority, isSigner: false, isWritable: false },
82
+ { pubkey: accounts.program, isSigner: false, isWritable: false },
83
+ ...(accounts.remainingAccounts ?? []).map((account) => ({ ...account })),
84
+ ]
85
+ const data = encodeInstruction("withdraw", { shares_amount: args.sharesAmount })
86
+ return new TransactionInstruction({ keys, programId, data })
87
+ }
@@ -167,13 +167,15 @@
167
167
  "accounts": [
168
168
  {
169
169
  "name": "user",
170
- "writable": true,
171
170
  "signer": true
172
171
  },
173
172
  {
174
173
  "name": "vault_state",
175
174
  "writable": true
176
175
  },
176
+ {
177
+ "name": "global_config"
178
+ },
177
179
  {
178
180
  "name": "token_vault",
179
181
  "writable": true
@@ -561,13 +563,15 @@
561
563
  "accounts": [
562
564
  {
563
565
  "name": "user",
564
- "writable": true,
565
566
  "signer": true
566
567
  },
567
568
  {
568
569
  "name": "vault_state",
569
570
  "writable": true
570
571
  },
572
+ {
573
+ "name": "global_config"
574
+ },
571
575
  {
572
576
  "name": "token_vault",
573
577
  "writable": true
@@ -0,0 +1,5 @@
1
+ import { PublicKey } from "@solana/web3.js"
2
+
3
+ import idl from "./kaminovault.json"
4
+
5
+ export const PROGRAM_ID = new PublicKey(idl.address)
package/tsconfig.json DELETED
@@ -1,17 +0,0 @@
1
- {
2
- "files": ["src/index.ts", "src/kaminovault.json"],
3
- "compilerOptions": {
4
- "rootDir": "src",
5
- "sourceMap": true,
6
- "incremental": true /* Save .tsbuildinfo files to allow for incremental compilation of projects. */,
7
- "composite": true /* Enable constraints that allow a TypeScript project to be used with project references. */,
8
- "target": "ESNext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
9
- "module": "CommonJS" /* Specify what module code is generated. */,
10
- "declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */,
11
- "outDir": "./build" /* Specify an output folder for all emitted files. */,
12
- "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
13
- "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
14
- "skipLibCheck": true /* Skip type checking all .d.ts files. */,
15
- "resolveJsonModule": true
16
- }
17
- }