@everstake/wallet-sdk-hysp-solana 1.3.1 → 1.4.1

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/index.d.mts CHANGED
@@ -88,6 +88,7 @@ declare const ERROR_MESSAGES: {
88
88
  GET_BALANCE_ERROR: string;
89
89
  VAULT_LOAD_ERROR: string;
90
90
  VAULT_NOT_FOUND_ERROR: string;
91
+ TX_TOO_LARGE: string;
91
92
  };
92
93
 
93
94
  /**
@@ -106,6 +107,7 @@ type VaultsMap = {
106
107
  [K in SupportedToken]: VaultInfo;
107
108
  };
108
109
  declare const VAULTS: VaultsMap;
110
+ declare const MAX_TRANSACTION_SIZE = 1232;
109
111
 
110
112
  /**
111
113
  * Copyright (c) 2025, Everstake.
@@ -170,6 +172,7 @@ declare class HyspSolana extends Blockchain {
170
172
  GET_BALANCE_ERROR: string;
171
173
  VAULT_LOAD_ERROR: string;
172
174
  VAULT_NOT_FOUND_ERROR: string;
175
+ TX_TOO_LARGE: string;
173
176
  };
174
177
  protected ORIGINAL_ERROR_MESSAGES: {
175
178
  INITIALIZATION_ERROR: string;
@@ -179,6 +182,7 @@ declare class HyspSolana extends Blockchain {
179
182
  GET_BALANCE_ERROR: string;
180
183
  VAULT_LOAD_ERROR: string;
181
184
  VAULT_NOT_FOUND_ERROR: string;
185
+ TX_TOO_LARGE: string;
182
186
  };
183
187
  private connection;
184
188
  private vault;
@@ -282,4 +286,4 @@ declare class HyspSolana extends Blockchain {
282
286
  private buildTx;
283
287
  }
284
288
 
285
- export { type ApiResponse, Blockchain, ERROR_MESSAGES, HyspSolana, type Params, type ShareToken, type SupportedToken, VAULTS, type VaultContracts, type VaultInfo, type VaultMeta, type VaultsMap, WalletSDKError };
289
+ export { type ApiResponse, Blockchain, ERROR_MESSAGES, HyspSolana, MAX_TRANSACTION_SIZE, type Params, type ShareToken, type SupportedToken, VAULTS, type VaultContracts, type VaultInfo, type VaultMeta, type VaultsMap, WalletSDKError };
package/dist/index.d.ts CHANGED
@@ -88,6 +88,7 @@ declare const ERROR_MESSAGES: {
88
88
  GET_BALANCE_ERROR: string;
89
89
  VAULT_LOAD_ERROR: string;
90
90
  VAULT_NOT_FOUND_ERROR: string;
91
+ TX_TOO_LARGE: string;
91
92
  };
92
93
 
93
94
  /**
@@ -106,6 +107,7 @@ type VaultsMap = {
106
107
  [K in SupportedToken]: VaultInfo;
107
108
  };
108
109
  declare const VAULTS: VaultsMap;
110
+ declare const MAX_TRANSACTION_SIZE = 1232;
109
111
 
110
112
  /**
111
113
  * Copyright (c) 2025, Everstake.
@@ -170,6 +172,7 @@ declare class HyspSolana extends Blockchain {
170
172
  GET_BALANCE_ERROR: string;
171
173
  VAULT_LOAD_ERROR: string;
172
174
  VAULT_NOT_FOUND_ERROR: string;
175
+ TX_TOO_LARGE: string;
173
176
  };
174
177
  protected ORIGINAL_ERROR_MESSAGES: {
175
178
  INITIALIZATION_ERROR: string;
@@ -179,6 +182,7 @@ declare class HyspSolana extends Blockchain {
179
182
  GET_BALANCE_ERROR: string;
180
183
  VAULT_LOAD_ERROR: string;
181
184
  VAULT_NOT_FOUND_ERROR: string;
185
+ TX_TOO_LARGE: string;
182
186
  };
183
187
  private connection;
184
188
  private vault;
@@ -282,4 +286,4 @@ declare class HyspSolana extends Blockchain {
282
286
  private buildTx;
283
287
  }
284
288
 
285
- export { type ApiResponse, Blockchain, ERROR_MESSAGES, HyspSolana, type Params, type ShareToken, type SupportedToken, VAULTS, type VaultContracts, type VaultInfo, type VaultMeta, type VaultsMap, WalletSDKError };
289
+ export { type ApiResponse, Blockchain, ERROR_MESSAGES, HyspSolana, MAX_TRANSACTION_SIZE, type Params, type ShareToken, type SupportedToken, VAULTS, type VaultContracts, type VaultInfo, type VaultMeta, type VaultsMap, WalletSDKError };
package/dist/index.js CHANGED
@@ -23,6 +23,7 @@ __export(index_exports, {
23
23
  Blockchain: () => Blockchain,
24
24
  ERROR_MESSAGES: () => ERROR_MESSAGES,
25
25
  HyspSolana: () => HyspSolana,
26
+ MAX_TRANSACTION_SIZE: () => MAX_TRANSACTION_SIZE,
26
27
  VAULTS: () => VAULTS,
27
28
  WalletSDKError: () => WalletSDKError
28
29
  });
@@ -126,7 +127,8 @@ var ERROR_MESSAGES = {
126
127
  GET_SHARES_ERROR: "An error occurred while fetching vault balance",
127
128
  GET_BALANCE_ERROR: "An error occurred while fetching user token balance",
128
129
  VAULT_LOAD_ERROR: "An error occurred while loading vault info",
129
- VAULT_NOT_FOUND_ERROR: "Vault not found for token: {0}"
130
+ VAULT_NOT_FOUND_ERROR: "Vault not found for token: {0}",
131
+ TX_TOO_LARGE: "Transaction exceeds the maximum size limit of 1232 bytes"
130
132
  };
131
133
 
132
134
  // src/constants/index.ts
@@ -134,12 +136,13 @@ var import_kit = require("@solana/kit");
134
136
  var VAULTS = {
135
137
  // Gauntlet USDC Prime
136
138
  USDC: {
137
- address: (0, import_kit.address)("9E69U4GzWhryRaPe8DYpco6Z9vTZY6gg8w6W2QsBACEj"),
139
+ address: (0, import_kit.address)("HptboyAsrs3xPQUMDT31gHLW3tzrq6p6As56EK7VXMcL"),
138
140
  shareTokenAddress: (0, import_kit.address)("32XLsweyeQwWgLKRVAzS72nxHGU1JmmNQQZ3C3q6fBjJ"),
139
141
  shareTokenSymbol: "Kamino Reserve Collateral (USDC) Token",
140
142
  shareTokenDecimals: 6
141
143
  }
142
144
  };
145
+ var MAX_TRANSACTION_SIZE = 1232;
143
146
 
144
147
  // src/hysp.ts
145
148
  var HyspSolana = class extends Blockchain {
@@ -427,10 +430,9 @@ var HyspSolana = class extends Blockchain {
427
430
  return (0, import_memo.getAddMemoInstruction)({ memo: processedMemo });
428
431
  }
429
432
  async buildTx(sender, instructions, params, lookupTableAddresses) {
430
- let transactionMessage = (0, import_kit2.pipe)(
431
- (0, import_kit2.createTransactionMessage)({ version: 0 }),
432
- (tx) => (0, import_kit2.setTransactionMessageFeePayer)((0, import_kit2.address)(sender), tx)
433
- );
433
+ let transactionMessage = (0, import_kit2.createTransactionMessage)({
434
+ version: 0
435
+ });
434
436
  if (params?.computeUnitLimit !== void 0 && params?.computeUnitLimit > 0) {
435
437
  const unitLimitInstruction = (0, import_compute_budget.getSetComputeUnitLimitInstruction)({
436
438
  /** Transaction compute unit limit used for prioritization fees. */
@@ -482,11 +484,21 @@ var HyspSolana = class extends Blockchain {
482
484
  fetchedTables
483
485
  );
484
486
  }
487
+ const txWithFeePayer = (0, import_kit2.setTransactionMessageFeePayer)(
488
+ (0, import_kit2.address)(sender),
489
+ transactionMessage
490
+ );
485
491
  const finalLatestBlockhash = params?.finalLatestBlockhash || (await this.connection.getLatestBlockhash().send()).value;
486
492
  const txMessageWithBlockhashLifetime = (0, import_kit2.setTransactionMessageLifetimeUsingBlockhash)(
487
493
  finalLatestBlockhash,
488
- transactionMessage
494
+ txWithFeePayer
489
495
  );
496
+ const compiledTx = (0, import_kit2.compileTransaction)(txMessageWithBlockhashLifetime);
497
+ const serializedTx = (0, import_kit2.getTransactionEncoder)().encode(compiledTx);
498
+ const txSize = serializedTx.length;
499
+ if (txSize > MAX_TRANSACTION_SIZE) {
500
+ throw this.throwError("TX_TOO_LARGE");
501
+ }
490
502
  return txMessageWithBlockhashLifetime;
491
503
  }
492
504
  };
@@ -495,6 +507,7 @@ var HyspSolana = class extends Blockchain {
495
507
  Blockchain,
496
508
  ERROR_MESSAGES,
497
509
  HyspSolana,
510
+ MAX_TRANSACTION_SIZE,
498
511
  VAULTS,
499
512
  WalletSDKError
500
513
  });
package/dist/index.mjs CHANGED
@@ -3,14 +3,15 @@ import {
3
3
  createSolanaRpc,
4
4
  createNoopSigner,
5
5
  address as address2,
6
- pipe,
7
6
  createTransactionMessage,
8
7
  setTransactionMessageFeePayer,
9
8
  setTransactionMessageLifetimeUsingBlockhash,
10
9
  appendTransactionMessageInstruction,
11
10
  prependTransactionMessageInstruction,
12
11
  compressTransactionMessageUsingAddressLookupTables,
13
- fetchAddressesForLookupTables
12
+ fetchAddressesForLookupTables,
13
+ compileTransaction,
14
+ getTransactionEncoder
14
15
  } from "@solana/kit";
15
16
  import {
16
17
  getSetComputeUnitLimitInstruction,
@@ -111,7 +112,8 @@ var ERROR_MESSAGES = {
111
112
  GET_SHARES_ERROR: "An error occurred while fetching vault balance",
112
113
  GET_BALANCE_ERROR: "An error occurred while fetching user token balance",
113
114
  VAULT_LOAD_ERROR: "An error occurred while loading vault info",
114
- VAULT_NOT_FOUND_ERROR: "Vault not found for token: {0}"
115
+ VAULT_NOT_FOUND_ERROR: "Vault not found for token: {0}",
116
+ TX_TOO_LARGE: "Transaction exceeds the maximum size limit of 1232 bytes"
115
117
  };
116
118
 
117
119
  // src/constants/index.ts
@@ -119,12 +121,13 @@ import { address } from "@solana/kit";
119
121
  var VAULTS = {
120
122
  // Gauntlet USDC Prime
121
123
  USDC: {
122
- address: address("9E69U4GzWhryRaPe8DYpco6Z9vTZY6gg8w6W2QsBACEj"),
124
+ address: address("HptboyAsrs3xPQUMDT31gHLW3tzrq6p6As56EK7VXMcL"),
123
125
  shareTokenAddress: address("32XLsweyeQwWgLKRVAzS72nxHGU1JmmNQQZ3C3q6fBjJ"),
124
126
  shareTokenSymbol: "Kamino Reserve Collateral (USDC) Token",
125
127
  shareTokenDecimals: 6
126
128
  }
127
129
  };
130
+ var MAX_TRANSACTION_SIZE = 1232;
128
131
 
129
132
  // src/hysp.ts
130
133
  var HyspSolana = class extends Blockchain {
@@ -412,10 +415,9 @@ var HyspSolana = class extends Blockchain {
412
415
  return getAddMemoInstruction({ memo: processedMemo });
413
416
  }
414
417
  async buildTx(sender, instructions, params, lookupTableAddresses) {
415
- let transactionMessage = pipe(
416
- createTransactionMessage({ version: 0 }),
417
- (tx) => setTransactionMessageFeePayer(address2(sender), tx)
418
- );
418
+ let transactionMessage = createTransactionMessage({
419
+ version: 0
420
+ });
419
421
  if (params?.computeUnitLimit !== void 0 && params?.computeUnitLimit > 0) {
420
422
  const unitLimitInstruction = getSetComputeUnitLimitInstruction({
421
423
  /** Transaction compute unit limit used for prioritization fees. */
@@ -467,11 +469,21 @@ var HyspSolana = class extends Blockchain {
467
469
  fetchedTables
468
470
  );
469
471
  }
472
+ const txWithFeePayer = setTransactionMessageFeePayer(
473
+ address2(sender),
474
+ transactionMessage
475
+ );
470
476
  const finalLatestBlockhash = params?.finalLatestBlockhash || (await this.connection.getLatestBlockhash().send()).value;
471
477
  const txMessageWithBlockhashLifetime = setTransactionMessageLifetimeUsingBlockhash(
472
478
  finalLatestBlockhash,
473
- transactionMessage
479
+ txWithFeePayer
474
480
  );
481
+ const compiledTx = compileTransaction(txMessageWithBlockhashLifetime);
482
+ const serializedTx = getTransactionEncoder().encode(compiledTx);
483
+ const txSize = serializedTx.length;
484
+ if (txSize > MAX_TRANSACTION_SIZE) {
485
+ throw this.throwError("TX_TOO_LARGE");
486
+ }
475
487
  return txMessageWithBlockhashLifetime;
476
488
  }
477
489
  };
@@ -479,6 +491,7 @@ export {
479
491
  Blockchain,
480
492
  ERROR_MESSAGES,
481
493
  HyspSolana,
494
+ MAX_TRANSACTION_SIZE,
482
495
  VAULTS,
483
496
  WalletSDKError
484
497
  };
package/jest.config.ts CHANGED
@@ -9,10 +9,11 @@ const config: Config = {
9
9
  collectCoverageFrom: [
10
10
  'src/**/*.ts',
11
11
  '!src/**/*.d.ts',
12
- '!src/**/index.ts',
12
+ '!src/index.ts',
13
13
  ],
14
14
  coverageDirectory: 'coverage',
15
15
  coverageReporters: ['text', 'lcov', 'html'],
16
+ testTimeout: 60000,
16
17
  };
17
18
 
18
19
  export default config;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@everstake/wallet-sdk-hysp-solana",
3
- "version": "1.3.1",
3
+ "version": "1.4.1",
4
4
  "description": "HYSP Solana - Everstake Wallet SDK",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Copyright (c) 2025, Everstake.
3
+ * Licensed under the BSD-3-Clause License. See LICENSE file for details.
4
+ */
5
+
6
+ import { address, Instruction } from '@solana/kit';
7
+ import { Decimal } from 'decimal.js';
8
+ import { HyspSolana } from '../hysp';
9
+
10
+ declare global {
11
+ interface BigInt {
12
+ toJSON(): number;
13
+ }
14
+ }
15
+
16
+ BigInt.prototype.toJSON = function () {
17
+ return Number(this);
18
+ };
19
+
20
+ const PLACEHOLDER_USER_ADDRESS = address(
21
+ 'Crc3qfV8QqdmGXNWSQnc8REsrDjViiSZMyjn6jsE51kj',
22
+ );
23
+ const PLACEHOLDER_TARGET_ADDRESS = address('11111111111111111111111111111113');
24
+ const PLACEHOLDER_SHARES_AMOUNT = new Decimal('0.1');
25
+
26
+ function createAdditionalInstruction(): Instruction {
27
+ return {
28
+ programAddress: address('11111111111111111111111111111112'),
29
+ accounts: [
30
+ { address: PLACEHOLDER_USER_ADDRESS, role: 0 },
31
+ { address: PLACEHOLDER_TARGET_ADDRESS, role: 0 },
32
+ ],
33
+ data: new Uint8Array(
34
+ Array.from({ length: 12 }, () => Math.floor(Math.random() * 256)),
35
+ ),
36
+ } as unknown as Instruction;
37
+ }
38
+
39
+ describe('HyspSolana Transaction Size Tests', () => {
40
+ let hyspSolana: HyspSolana;
41
+
42
+ beforeAll(() => {
43
+ hyspSolana = new HyspSolana('USDC');
44
+ });
45
+
46
+ describe('Transaction Size Limits', () => {
47
+ it('should check balance and error if insufficient shares', async () => {
48
+ const userShares = await hyspSolana.getUserShares(
49
+ PLACEHOLDER_USER_ADDRESS,
50
+ );
51
+
52
+ console.log(`User shares: ${userShares.result.toString()}`);
53
+
54
+ if (userShares.result.lt(PLACEHOLDER_SHARES_AMOUNT)) {
55
+ console.warn('Insufficient shares for tests.');
56
+ fail(
57
+ 'Insufficient shares for tests. Cannot proceed with transaction size tests.',
58
+ );
59
+ }
60
+ }, 30000);
61
+
62
+ it('should create a normal withdraw transaction within size limits', async () => {
63
+ const result = await hyspSolana.withdraw(
64
+ PLACEHOLDER_USER_ADDRESS,
65
+ PLACEHOLDER_SHARES_AMOUNT,
66
+ );
67
+
68
+ expect(result.result).toBeDefined();
69
+ }, 30000);
70
+
71
+ it('should fail when transaction exceeds size limits with too many instructions', async () => {
72
+ const additionalInstructions = [];
73
+
74
+ for (let i = 0; i < 100; i++) {
75
+ additionalInstructions.push(createAdditionalInstruction());
76
+ }
77
+
78
+ await expect(
79
+ hyspSolana.withdraw(
80
+ PLACEHOLDER_USER_ADDRESS,
81
+ PLACEHOLDER_SHARES_AMOUNT,
82
+ {
83
+ afterInstructions: additionalInstructions,
84
+ },
85
+ ),
86
+ ).rejects.toThrow(
87
+ 'Transaction exceeds the maximum size limit of 1232 bytes',
88
+ );
89
+ }, 30000);
90
+
91
+ it('should handle edge case with some additional instructions', async () => {
92
+ const moderateInstructions = [];
93
+
94
+ for (let i = 0; i < 10; i++) {
95
+ moderateInstructions.push(createAdditionalInstruction());
96
+ }
97
+
98
+ try {
99
+ const result = await hyspSolana.withdraw(
100
+ PLACEHOLDER_USER_ADDRESS,
101
+ PLACEHOLDER_SHARES_AMOUNT,
102
+ {
103
+ afterInstructions: moderateInstructions,
104
+ },
105
+ );
106
+
107
+ expect(result.result).toBeDefined();
108
+ } catch (error: unknown) {
109
+ const errorMessage = (error as Error).message;
110
+ expect(errorMessage).toContain(
111
+ 'Transaction exceeds the maximum size limit',
112
+ );
113
+ }
114
+ }, 30000);
115
+ });
116
+ });
@@ -11,4 +11,5 @@ export const ERROR_MESSAGES = {
11
11
  GET_BALANCE_ERROR: 'An error occurred while fetching user token balance',
12
12
  VAULT_LOAD_ERROR: 'An error occurred while loading vault info',
13
13
  VAULT_NOT_FOUND_ERROR: 'Vault not found for token: {0}',
14
+ TX_TOO_LARGE: 'Transaction exceeds the maximum size limit of 1232 bytes',
14
15
  };
@@ -21,11 +21,13 @@ export type VaultsMap = {
21
21
  export const VAULTS: VaultsMap = {
22
22
  // Gauntlet USDC Prime
23
23
  USDC: {
24
- address: address('9E69U4GzWhryRaPe8DYpco6Z9vTZY6gg8w6W2QsBACEj'),
24
+ address: address('HptboyAsrs3xPQUMDT31gHLW3tzrq6p6As56EK7VXMcL'),
25
25
  shareTokenAddress: address('32XLsweyeQwWgLKRVAzS72nxHGU1JmmNQQZ3C3q6fBjJ'),
26
26
  shareTokenSymbol: 'Kamino Reserve Collateral (USDC) Token',
27
27
  shareTokenDecimals: 6,
28
28
  },
29
29
  };
30
30
 
31
+ export const MAX_TRANSACTION_SIZE = 1232;
32
+
31
33
  export * from './errors';
package/src/hysp.ts CHANGED
@@ -8,7 +8,6 @@ import {
8
8
  Address,
9
9
  createNoopSigner,
10
10
  address,
11
- pipe,
12
11
  createTransactionMessage,
13
12
  setTransactionMessageFeePayer,
14
13
  setTransactionMessageLifetimeUsingBlockhash,
@@ -21,6 +20,8 @@ import {
21
20
  Rpc,
22
21
  SolanaRpcApi,
23
22
  Instruction,
23
+ compileTransaction,
24
+ getTransactionEncoder,
24
25
  } from '@solana/kit';
25
26
 
26
27
  import {
@@ -35,6 +36,7 @@ import { KaminoVault, VaultHoldings, APY } from '@kamino-finance/klend-sdk';
35
36
  import { Decimal } from 'decimal.js';
36
37
  import { Blockchain } from '../../utils';
37
38
  import { ERROR_MESSAGES } from './constants/errors';
39
+ import { MAX_TRANSACTION_SIZE } from './constants';
38
40
  import { VAULTS, SupportedToken, VaultInfo } from './constants';
39
41
  import { ApiResponse, Params, VaultMeta } from './types';
40
42
 
@@ -387,10 +389,9 @@ export class HyspSolana extends Blockchain {
387
389
  params?: Params,
388
390
  lookupTableAddresses?: Address[],
389
391
  ): Promise<TransactionMessageWithLifetime> {
390
- let transactionMessage: TransactionMessage = pipe(
391
- createTransactionMessage({ version: 0 }),
392
- (tx) => setTransactionMessageFeePayer(address(sender), tx),
393
- );
392
+ let transactionMessage: TransactionMessage = createTransactionMessage({
393
+ version: 0,
394
+ });
394
395
 
395
396
  if (
396
397
  params?.computeUnitLimit !== undefined &&
@@ -457,6 +458,11 @@ export class HyspSolana extends Blockchain {
457
458
  );
458
459
  }
459
460
 
461
+ const txWithFeePayer = setTransactionMessageFeePayer(
462
+ address(sender),
463
+ transactionMessage,
464
+ );
465
+
460
466
  const finalLatestBlockhash =
461
467
  params?.finalLatestBlockhash ||
462
468
  (await this.connection.getLatestBlockhash().send()).value;
@@ -464,9 +470,17 @@ export class HyspSolana extends Blockchain {
464
470
  const txMessageWithBlockhashLifetime =
465
471
  setTransactionMessageLifetimeUsingBlockhash(
466
472
  finalLatestBlockhash,
467
- transactionMessage,
473
+ txWithFeePayer,
468
474
  );
469
475
 
476
+ const compiledTx = compileTransaction(txMessageWithBlockhashLifetime);
477
+ const serializedTx = getTransactionEncoder().encode(compiledTx);
478
+ const txSize = serializedTx.length;
479
+
480
+ if (txSize > MAX_TRANSACTION_SIZE) {
481
+ throw this.throwError('TX_TOO_LARGE');
482
+ }
483
+
470
484
  return txMessageWithBlockhashLifetime;
471
485
  }
472
486
  }