@everstake/wallet-sdk-hysp-solana 1.0.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.
package/dist/index.js ADDED
@@ -0,0 +1,390 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Blockchain: () => Blockchain,
24
+ ERROR_MESSAGES: () => ERROR_MESSAGES,
25
+ HyspSolana: () => HyspSolana,
26
+ VAULTS: () => VAULTS,
27
+ WalletSDKError: () => WalletSDKError
28
+ });
29
+ module.exports = __toCommonJS(index_exports);
30
+
31
+ // src/hysp.ts
32
+ var import_kit2 = require("@solana/kit");
33
+ var import_compute_budget = require("@solana-program/compute-budget");
34
+ var import_klend_sdk = require("@kamino-finance/klend-sdk");
35
+ var import_decimal = require("decimal.js");
36
+
37
+ // ../utils/constants/errors.ts
38
+ var COMMON_ERROR_MESSAGES = {
39
+ UNKNOWN_ERROR: "An unknown error occurred",
40
+ TOKEN_ERROR: "Please create or use correct token"
41
+ };
42
+
43
+ // ../utils/index.ts
44
+ var WalletSDKError = class extends Error {
45
+ constructor(message, code, originalError) {
46
+ super(message);
47
+ this.code = code;
48
+ this.originalError = originalError;
49
+ Object.setPrototypeOf(this, new.target.prototype);
50
+ }
51
+ };
52
+ var Blockchain = class {
53
+ /**
54
+ * Handles errors that occur within the Ethereum class.
55
+ *
56
+ * @param {keyof typeof ERROR_MESSAGES} code - The error code associated with the error.
57
+ * @param {Error | WalletSDKError | unknown} originalError - The original error that was thrown.
58
+ *
59
+ * If the original error is an instance of WalletSDKError, it is thrown as is.
60
+ * If the original error is an instance of the built-in Error class, a new WalletSDKError is thrown with the original error as the cause.
61
+ * If the original error is not an instance of WalletSDKError or Error, a new WalletSDKError is thrown with a generic message and code.
62
+ */
63
+ handleError(code, originalError) {
64
+ const message = this.ERROR_MESSAGES[code];
65
+ if (originalError instanceof WalletSDKError || !message || !code) {
66
+ throw originalError;
67
+ }
68
+ if (originalError instanceof Error) {
69
+ const newMessage = Object.entries(this.ORIGINAL_ERROR_MESSAGES).find(
70
+ ([originalMessage]) => originalError.message.includes(originalMessage)
71
+ )?.[1];
72
+ const errorMessage = newMessage || this.ERROR_MESSAGES[code] || COMMON_ERROR_MESSAGES["UNKNOWN_ERROR"];
73
+ throw new WalletSDKError(errorMessage, String(code), originalError);
74
+ }
75
+ throw new WalletSDKError(
76
+ COMMON_ERROR_MESSAGES["UNKNOWN_ERROR"],
77
+ "UNKNOWN_ERROR"
78
+ );
79
+ }
80
+ /**
81
+ * Throws a WalletSDKError with a specified error code and message.
82
+ *
83
+ * @param {keyof typeof ERROR_MESSAGES} code - The error code associated with the error.
84
+ * @param {...string[]} values - The values to be inserted into the error message.
85
+ *
86
+ * The method retrieves the error message template associated with the provided code from the ERROR_MESSAGES object.
87
+ * It then replaces placeholders in the message template with provided values and throws a WalletSDKError with the final message and the provided code.
88
+ */
89
+ throwError(code, ...values) {
90
+ let message = this.ERROR_MESSAGES[code];
91
+ values.forEach((value, index) => {
92
+ message = message?.replace(`{${index}}`, value);
93
+ });
94
+ if (!message) {
95
+ throw new WalletSDKError(
96
+ COMMON_ERROR_MESSAGES["UNKNOWN_ERROR"],
97
+ "UNKNOWN_ERROR"
98
+ );
99
+ }
100
+ throw new WalletSDKError(message, String(code));
101
+ }
102
+ /**
103
+ * Check if the URL is valid
104
+ *
105
+ * @param {string} url - URL
106
+ * @returns a bool type result.
107
+ *
108
+ */
109
+ isValidURL(url) {
110
+ let urlClass;
111
+ try {
112
+ urlClass = new URL(url);
113
+ } catch (_) {
114
+ return false;
115
+ }
116
+ return urlClass.protocol === "http:" || urlClass.protocol === "https:";
117
+ }
118
+ };
119
+
120
+ // src/constants/errors.ts
121
+ var ERROR_MESSAGES = {
122
+ INITIALIZATION_ERROR: "An error occurred while initializingSDK",
123
+ DEPOSIT_ERROR: "An error occurred while creating vault deposit transaction",
124
+ WITHDRAW_ERROR: "An error occurred while creating vault withdraw transaction",
125
+ GET_SHARES_ERROR: "An error occurred while fetching vault balance",
126
+ GET_BALANCE_ERROR: "An error occurred while fetching user token balance",
127
+ VAULT_LOAD_ERROR: "An error occurred while loading vault info",
128
+ VAULT_NOT_FOUND_ERROR: "Vault not found for token: {0}"
129
+ };
130
+
131
+ // src/constants/index.ts
132
+ var import_kit = require("@solana/kit");
133
+ var VAULTS = {
134
+ USDC: (0, import_kit.address)("HDsayqAsDWy3QvANGqh2yNraqcD8Fnjgh73Mhb3WRS5E")
135
+ };
136
+
137
+ // src/hysp.ts
138
+ var HyspSolana = class extends Blockchain {
139
+ ERROR_MESSAGES = ERROR_MESSAGES;
140
+ ORIGINAL_ERROR_MESSAGES = ERROR_MESSAGES;
141
+ connection;
142
+ vault;
143
+ /**
144
+ * Creates a new instance of the KaminoSDK.
145
+ *
146
+ * @param rpcUrl - Optional custom RPC URL. If not provided, uses the default Solana mainnet RPC.
147
+ *
148
+ * @throws Throws an error if the token symbol is not supported.
149
+ * @throws Throws an error if there's an issue during SDK initialization.
150
+ */
151
+ constructor(tokenSymbol, rpcUrl) {
152
+ super();
153
+ const vaultAddress = this.getVaultAddress(tokenSymbol);
154
+ try {
155
+ const connectionUrl = rpcUrl || "https://api.mainnet-beta.solana.com";
156
+ this.connection = (0, import_kit2.createSolanaRpc)(connectionUrl);
157
+ this.vault = new import_klend_sdk.KaminoVault(this.connection, vaultAddress);
158
+ } catch (error) {
159
+ throw this.handleError("INITIALIZATION_ERROR", error);
160
+ }
161
+ }
162
+ getVaultAddress(tokenSymbol) {
163
+ const vaultAddress = VAULTS[tokenSymbol];
164
+ if (!vaultAddress) {
165
+ throw this.throwError("VAULT_NOT_FOUND_ERROR", tokenSymbol);
166
+ }
167
+ return vaultAddress;
168
+ }
169
+ convertToDecimal(amount) {
170
+ return new import_decimal.Decimal(amount.toString());
171
+ }
172
+ /**
173
+ * Fetches the vault holdings data.
174
+ *
175
+ * @throws Throws an error if there's an issue loading vault holdings.
176
+ *
177
+ * @returns Returns a promise that resolves with the vault holdings.
178
+ */
179
+ async getVaultHoldings() {
180
+ try {
181
+ const holdings = await this.vault.getVaultHoldings();
182
+ return { result: holdings };
183
+ } catch (error) {
184
+ throw this.handleError("VAULT_LOAD_ERROR", error);
185
+ }
186
+ }
187
+ /**
188
+ * Fetches the vault APY data.
189
+ *
190
+ * @throws Throws an error if there's an issue loading vault APYs.
191
+ *
192
+ * @returns Returns a promise that resolves with the vault actual APY information.
193
+ */
194
+ async getVaultAPYs() {
195
+ try {
196
+ const apys = await this.vault.getAPYs();
197
+ return { result: apys.actualAPY };
198
+ } catch (error) {
199
+ throw this.handleError("VAULT_LOAD_ERROR", error);
200
+ }
201
+ }
202
+ /**
203
+ * Fetches the current vault exchange rate (tokens per share).
204
+ *
205
+ * @throws Throws an error if there's an issue loading exchange rate.
206
+ *
207
+ * @returns Returns a promise that resolves with the exchange rate as Decimal.
208
+ */
209
+ async getExchangeRate() {
210
+ try {
211
+ const rate = await this.vault.getExchangeRate();
212
+ return { result: rate };
213
+ } catch (error) {
214
+ throw this.handleError("VAULT_LOAD_ERROR", error);
215
+ }
216
+ }
217
+ /**
218
+ * Fetches a user's raw share balance in the current vault.
219
+ *
220
+ * @param userAddress - The public key of the user account.
221
+ * @throws Throws an error if there's an issue fetching user shares.
222
+ * @returns Returns a promise that resolves with the user's shares amount.
223
+ */
224
+ async getUserShares(userAddress) {
225
+ try {
226
+ const shares = await this.vault.getUserShares(userAddress);
227
+ return {
228
+ result: shares.totalShares
229
+ };
230
+ } catch (error) {
231
+ throw this.handleError("GET_SHARES_ERROR", error);
232
+ }
233
+ }
234
+ /**
235
+ * Fetches a user's token balance in the current vault: shares * exchange rate.
236
+ *
237
+ * @param userAddress - The public key of the user account.
238
+ * @throws Throws an error if there's an issue fetching user balance.
239
+ * @returns Returns a promise that resolves with the user's token balance amount.
240
+ */
241
+ async getUserBalance(userAddress) {
242
+ try {
243
+ const balance = await this.vault.getUserShares(userAddress);
244
+ const exchangeRate = await this.vault.getExchangeRate();
245
+ const tokenBalance = balance.totalShares.mul(exchangeRate);
246
+ return {
247
+ result: tokenBalance
248
+ };
249
+ } catch (error) {
250
+ throw this.handleError("GET_BALANCE_ERROR", error);
251
+ }
252
+ }
253
+ /**
254
+ * Creates a deposit transaction to the vault.
255
+ *
256
+ * @param userAddress - The public key of the user account.
257
+ * @param amount - The amount to deposit.
258
+ * @param params - Optional transaction parameters.
259
+ *
260
+ * @throws Throws an error if there's an issue creating the deposit transaction.
261
+ *
262
+ * @returns Returns a promise that resolves with the deposit transaction response.
263
+ */
264
+ async deposit(userAddress, amount, params) {
265
+ try {
266
+ const signer = (0, import_kit2.createNoopSigner)(userAddress);
267
+ let decimalAmount;
268
+ if (amount instanceof import_decimal.Decimal) {
269
+ decimalAmount = amount;
270
+ } else {
271
+ decimalAmount = this.convertToDecimal(amount);
272
+ }
273
+ const depositIxs = await this.vault.depositIxs(signer, decimalAmount);
274
+ const mergedDepositIxs = [];
275
+ depositIxs.depositIxs.forEach((instruction) => {
276
+ mergedDepositIxs.push(instruction);
277
+ });
278
+ depositIxs.stakeInFarmIfNeededIxs.forEach((instruction) => {
279
+ mergedDepositIxs.push(instruction);
280
+ });
281
+ const transactionMessage = await this.buildTx(
282
+ userAddress.toString(),
283
+ mergedDepositIxs,
284
+ params
285
+ );
286
+ return {
287
+ result: transactionMessage
288
+ };
289
+ } catch (error) {
290
+ throw this.handleError("DEPOSIT_ERROR", error);
291
+ }
292
+ }
293
+ /**
294
+ * Creates a withdraw transaction from the vault.
295
+ *
296
+ * @param userAddress - The public key of the user account.
297
+ * @param sharesAmount - The amount of shares to withdraw.
298
+ * @param params - Optional transaction parameters.
299
+ *
300
+ * @throws Throws an error if there's issue creating the withdraw transaction.
301
+ *
302
+ * @returns Returns a promise that resolves with the withdraw transaction response.
303
+ */
304
+ async withdraw(userAddress, sharesAmount, params) {
305
+ try {
306
+ const signer = (0, import_kit2.createNoopSigner)(userAddress);
307
+ let sharesDecimal;
308
+ if (sharesAmount instanceof import_decimal.Decimal) {
309
+ sharesDecimal = sharesAmount;
310
+ } else {
311
+ sharesDecimal = this.convertToDecimal(sharesAmount);
312
+ }
313
+ const withdrawIxs = await this.vault.withdrawIxs(signer, sharesDecimal);
314
+ const mergedWithdrawIxs = [];
315
+ withdrawIxs.unstakeFromFarmIfNeededIxs.forEach((instruction) => {
316
+ mergedWithdrawIxs.push(instruction);
317
+ });
318
+ withdrawIxs.withdrawIxs.forEach((instruction) => {
319
+ mergedWithdrawIxs.push(instruction);
320
+ });
321
+ withdrawIxs.postWithdrawIxs.forEach((instruction) => {
322
+ mergedWithdrawIxs.push(instruction);
323
+ });
324
+ const transactionMessage = await this.buildTx(
325
+ userAddress.toString(),
326
+ mergedWithdrawIxs,
327
+ params
328
+ );
329
+ return {
330
+ result: transactionMessage
331
+ };
332
+ } catch (error) {
333
+ throw this.handleError("WITHDRAW_ERROR", error);
334
+ }
335
+ }
336
+ async buildTx(sender, instructions, params) {
337
+ let transactionMessage = (0, import_kit2.pipe)(
338
+ (0, import_kit2.createTransactionMessage)({ version: 0 }),
339
+ (tx) => (0, import_kit2.setTransactionMessageFeePayer)((0, import_kit2.address)(sender), tx)
340
+ );
341
+ if (params?.computeUnitLimit !== void 0 && params?.computeUnitLimit > 0) {
342
+ const unitLimitInstruction = (0, import_compute_budget.getSetComputeUnitLimitInstruction)({
343
+ /** Transaction compute unit limit used for prioritization fees. */
344
+ units: params?.computeUnitLimit
345
+ });
346
+ transactionMessage = (0, import_kit2.prependTransactionMessageInstruction)(
347
+ unitLimitInstruction,
348
+ transactionMessage
349
+ );
350
+ }
351
+ if (params?.\u0441omputeUnitPrice !== void 0 && params?.\u0441omputeUnitPrice > 0) {
352
+ const unitPriceInstruction = (0, import_compute_budget.getSetComputeUnitPriceInstruction)({
353
+ /** Transaction compute unit price used for prioritization fees. */
354
+ microLamports: params?.\u0441omputeUnitPrice
355
+ });
356
+ transactionMessage = (0, import_kit2.prependTransactionMessageInstruction)(
357
+ unitPriceInstruction,
358
+ transactionMessage
359
+ );
360
+ }
361
+ for (const instruction of instructions) {
362
+ transactionMessage = (0, import_kit2.appendTransactionMessageInstruction)(
363
+ instruction,
364
+ transactionMessage
365
+ );
366
+ }
367
+ if (params?.afterInstructions) {
368
+ for (const instruction of params.afterInstructions) {
369
+ transactionMessage = (0, import_kit2.appendTransactionMessageInstruction)(
370
+ instruction,
371
+ transactionMessage
372
+ );
373
+ }
374
+ }
375
+ const finalLatestBlockhash = params?.finalLatestBlockhash || (await this.connection.getLatestBlockhash().send()).value;
376
+ const txMessageWithBlockhashLifetime = (0, import_kit2.setTransactionMessageLifetimeUsingBlockhash)(
377
+ finalLatestBlockhash,
378
+ transactionMessage
379
+ );
380
+ return txMessageWithBlockhashLifetime;
381
+ }
382
+ };
383
+ // Annotate the CommonJS export names for ESM import in node:
384
+ 0 && (module.exports = {
385
+ Blockchain,
386
+ ERROR_MESSAGES,
387
+ HyspSolana,
388
+ VAULTS,
389
+ WalletSDKError
390
+ });