@everstake/wallet-sdk-hysp-solana 1.2.0 → 1.3.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 +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +40 -0
- package/dist/index.mjs +40 -0
- package/jest.config.ts +18 -0
- package/package.json +13 -3
- package/src/__tests__/index.ts +41 -0
- package/src/hysp.ts +49 -0
- package/src/types/index.ts +2 -0
package/dist/index.d.mts
CHANGED
|
@@ -126,6 +126,8 @@ type Params = {
|
|
|
126
126
|
};
|
|
127
127
|
/** Instructions to be added after the main instructions created by SDK */
|
|
128
128
|
afterInstructions?: Instruction[];
|
|
129
|
+
/** Memo text to be included in the transaction */
|
|
130
|
+
memo?: string;
|
|
129
131
|
};
|
|
130
132
|
interface ShareToken {
|
|
131
133
|
address: string;
|
|
@@ -271,6 +273,12 @@ declare class HyspSolana extends Blockchain {
|
|
|
271
273
|
* @returns Returns a promise that resolves with the withdraw transaction response.
|
|
272
274
|
*/
|
|
273
275
|
withdraw(userAddress: Address, sharesAmount: number | string | bigint | Decimal, params?: Params): Promise<ApiResponse<TransactionMessageWithLifetime>>;
|
|
276
|
+
/**
|
|
277
|
+
* Processes and creates a memo instruction according to SDK requirements
|
|
278
|
+
* @param memo - Input memo text
|
|
279
|
+
* @returns Memo instruction
|
|
280
|
+
*/
|
|
281
|
+
protected processMemo(memo?: string): Instruction;
|
|
274
282
|
private buildTx;
|
|
275
283
|
}
|
|
276
284
|
|
package/dist/index.d.ts
CHANGED
|
@@ -126,6 +126,8 @@ type Params = {
|
|
|
126
126
|
};
|
|
127
127
|
/** Instructions to be added after the main instructions created by SDK */
|
|
128
128
|
afterInstructions?: Instruction[];
|
|
129
|
+
/** Memo text to be included in the transaction */
|
|
130
|
+
memo?: string;
|
|
129
131
|
};
|
|
130
132
|
interface ShareToken {
|
|
131
133
|
address: string;
|
|
@@ -271,6 +273,12 @@ declare class HyspSolana extends Blockchain {
|
|
|
271
273
|
* @returns Returns a promise that resolves with the withdraw transaction response.
|
|
272
274
|
*/
|
|
273
275
|
withdraw(userAddress: Address, sharesAmount: number | string | bigint | Decimal, params?: Params): Promise<ApiResponse<TransactionMessageWithLifetime>>;
|
|
276
|
+
/**
|
|
277
|
+
* Processes and creates a memo instruction according to SDK requirements
|
|
278
|
+
* @param memo - Input memo text
|
|
279
|
+
* @returns Memo instruction
|
|
280
|
+
*/
|
|
281
|
+
protected processMemo(memo?: string): Instruction;
|
|
274
282
|
private buildTx;
|
|
275
283
|
}
|
|
276
284
|
|
package/dist/index.js
CHANGED
|
@@ -31,6 +31,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
31
31
|
// src/hysp.ts
|
|
32
32
|
var import_kit2 = require("@solana/kit");
|
|
33
33
|
var import_compute_budget = require("@solana-program/compute-budget");
|
|
34
|
+
var import_memo = require("@solana-program/memo");
|
|
34
35
|
var import_klend_sdk = require("@kamino-finance/klend-sdk");
|
|
35
36
|
var import_decimal = require("decimal.js");
|
|
36
37
|
|
|
@@ -393,6 +394,38 @@ var HyspSolana = class extends Blockchain {
|
|
|
393
394
|
throw this.handleError("WITHDRAW_ERROR", error);
|
|
394
395
|
}
|
|
395
396
|
}
|
|
397
|
+
/**
|
|
398
|
+
* Processes and creates a memo instruction according to SDK requirements
|
|
399
|
+
* @param memo - Input memo text
|
|
400
|
+
* @returns Memo instruction
|
|
401
|
+
*/
|
|
402
|
+
processMemo(memo) {
|
|
403
|
+
let processedMemo;
|
|
404
|
+
if (!memo || memo.trim() === "") {
|
|
405
|
+
processedMemo = "SDK";
|
|
406
|
+
} else {
|
|
407
|
+
const trimmedMemo = memo.trim();
|
|
408
|
+
if (trimmedMemo === "SDK") {
|
|
409
|
+
processedMemo = trimmedMemo;
|
|
410
|
+
} else if (!trimmedMemo.startsWith("SDK:")) {
|
|
411
|
+
processedMemo = `SDK:${trimmedMemo}`;
|
|
412
|
+
} else {
|
|
413
|
+
processedMemo = trimmedMemo;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
if (processedMemo.length > 64) {
|
|
417
|
+
throw new Error(
|
|
418
|
+
`Invalid memo: "${processedMemo}". Must be max 64 characters`
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
const validPattern = /^[A-Za-z0-9:_-]*$/;
|
|
422
|
+
if (!validPattern.test(processedMemo)) {
|
|
423
|
+
throw new Error(
|
|
424
|
+
`Invalid memo: "${processedMemo}". Must contain only [A-Za-z0-9:_-] characters`
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
return (0, import_memo.getAddMemoInstruction)({ memo: processedMemo });
|
|
428
|
+
}
|
|
396
429
|
async buildTx(sender, instructions, params, lookupTableAddresses) {
|
|
397
430
|
let transactionMessage = (0, import_kit2.pipe)(
|
|
398
431
|
(0, import_kit2.createTransactionMessage)({ version: 0 }),
|
|
@@ -424,6 +457,13 @@ var HyspSolana = class extends Blockchain {
|
|
|
424
457
|
transactionMessage
|
|
425
458
|
);
|
|
426
459
|
}
|
|
460
|
+
if (params?.memo !== void 0) {
|
|
461
|
+
const memoInstruction = this.processMemo(params.memo);
|
|
462
|
+
transactionMessage = (0, import_kit2.appendTransactionMessageInstruction)(
|
|
463
|
+
memoInstruction,
|
|
464
|
+
transactionMessage
|
|
465
|
+
);
|
|
466
|
+
}
|
|
427
467
|
if (params?.afterInstructions) {
|
|
428
468
|
for (const instruction of params.afterInstructions) {
|
|
429
469
|
transactionMessage = (0, import_kit2.appendTransactionMessageInstruction)(
|
package/dist/index.mjs
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
getSetComputeUnitLimitInstruction,
|
|
17
17
|
getSetComputeUnitPriceInstruction
|
|
18
18
|
} from "@solana-program/compute-budget";
|
|
19
|
+
import { getAddMemoInstruction } from "@solana-program/memo";
|
|
19
20
|
import { KaminoVault } from "@kamino-finance/klend-sdk";
|
|
20
21
|
import { Decimal } from "decimal.js";
|
|
21
22
|
|
|
@@ -378,6 +379,38 @@ var HyspSolana = class extends Blockchain {
|
|
|
378
379
|
throw this.handleError("WITHDRAW_ERROR", error);
|
|
379
380
|
}
|
|
380
381
|
}
|
|
382
|
+
/**
|
|
383
|
+
* Processes and creates a memo instruction according to SDK requirements
|
|
384
|
+
* @param memo - Input memo text
|
|
385
|
+
* @returns Memo instruction
|
|
386
|
+
*/
|
|
387
|
+
processMemo(memo) {
|
|
388
|
+
let processedMemo;
|
|
389
|
+
if (!memo || memo.trim() === "") {
|
|
390
|
+
processedMemo = "SDK";
|
|
391
|
+
} else {
|
|
392
|
+
const trimmedMemo = memo.trim();
|
|
393
|
+
if (trimmedMemo === "SDK") {
|
|
394
|
+
processedMemo = trimmedMemo;
|
|
395
|
+
} else if (!trimmedMemo.startsWith("SDK:")) {
|
|
396
|
+
processedMemo = `SDK:${trimmedMemo}`;
|
|
397
|
+
} else {
|
|
398
|
+
processedMemo = trimmedMemo;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
if (processedMemo.length > 64) {
|
|
402
|
+
throw new Error(
|
|
403
|
+
`Invalid memo: "${processedMemo}". Must be max 64 characters`
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
const validPattern = /^[A-Za-z0-9:_-]*$/;
|
|
407
|
+
if (!validPattern.test(processedMemo)) {
|
|
408
|
+
throw new Error(
|
|
409
|
+
`Invalid memo: "${processedMemo}". Must contain only [A-Za-z0-9:_-] characters`
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
return getAddMemoInstruction({ memo: processedMemo });
|
|
413
|
+
}
|
|
381
414
|
async buildTx(sender, instructions, params, lookupTableAddresses) {
|
|
382
415
|
let transactionMessage = pipe(
|
|
383
416
|
createTransactionMessage({ version: 0 }),
|
|
@@ -409,6 +442,13 @@ var HyspSolana = class extends Blockchain {
|
|
|
409
442
|
transactionMessage
|
|
410
443
|
);
|
|
411
444
|
}
|
|
445
|
+
if (params?.memo !== void 0) {
|
|
446
|
+
const memoInstruction = this.processMemo(params.memo);
|
|
447
|
+
transactionMessage = appendTransactionMessageInstruction(
|
|
448
|
+
memoInstruction,
|
|
449
|
+
transactionMessage
|
|
450
|
+
);
|
|
451
|
+
}
|
|
412
452
|
if (params?.afterInstructions) {
|
|
413
453
|
for (const instruction of params.afterInstructions) {
|
|
414
454
|
transactionMessage = appendTransactionMessageInstruction(
|
package/jest.config.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Config } from 'jest';
|
|
2
|
+
|
|
3
|
+
const config: Config = {
|
|
4
|
+
preset: 'ts-jest',
|
|
5
|
+
testEnvironment: 'node',
|
|
6
|
+
verbose: true,
|
|
7
|
+
roots: ['<rootDir>/src'],
|
|
8
|
+
testMatch: ['**/__tests__/**/*.test.ts'],
|
|
9
|
+
collectCoverageFrom: [
|
|
10
|
+
'src/**/*.ts',
|
|
11
|
+
'!src/**/*.d.ts',
|
|
12
|
+
'!src/**/index.ts',
|
|
13
|
+
],
|
|
14
|
+
coverageDirectory: 'coverage',
|
|
15
|
+
coverageReporters: ['text', 'lcov', 'html'],
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
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
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "HYSP Solana - Everstake Wallet SDK",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"type-check": "tsc",
|
|
21
21
|
"lint": "eslint 'src/**/*.{ts,tsx}'",
|
|
22
22
|
"prettier": "prettier --write 'src/**/*.{ts,tsx}'",
|
|
23
|
-
"test": "jest",
|
|
24
|
-
"prebuild": "pnpm run type-check && pnpm run lint"
|
|
23
|
+
"test": "jest --passWithNoTests",
|
|
24
|
+
"prebuild": "pnpm run type-check && pnpm run lint && npm run test"
|
|
25
25
|
},
|
|
26
26
|
"keywords": [
|
|
27
27
|
"hysp",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@kamino-finance/klend-sdk": "^7.3.4",
|
|
46
46
|
"@solana-program/compute-budget": "^0.7.0",
|
|
47
|
+
"@solana-program/memo": "^0.10.0",
|
|
47
48
|
"@solana/kit": "^3.0.3",
|
|
48
49
|
"decimal.js": "^10.6.0"
|
|
49
50
|
},
|
|
@@ -65,5 +66,14 @@
|
|
|
65
66
|
"tsup": "^8.1.0",
|
|
66
67
|
"typescript": "^5.5.3",
|
|
67
68
|
"typescript-eslint": "^8.46.2"
|
|
69
|
+
},
|
|
70
|
+
"pnpm": {
|
|
71
|
+
"overrides": {
|
|
72
|
+
"js-yaml@<3.14.2": ">=3.14.2",
|
|
73
|
+
"js-yaml@>=4.0.0 <4.1.1": ">=4.1.1",
|
|
74
|
+
"glob@>=10.2.0 <10.5.0": ">=10.5.0",
|
|
75
|
+
"js-yaml": ">=4.1.1",
|
|
76
|
+
"glob": ">=10.5.0"
|
|
77
|
+
}
|
|
68
78
|
}
|
|
69
79
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025, Everstake.
|
|
3
|
+
* Licensed under the BSD-3-Clause License. See LICENSE file for details.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { HyspSolana } from '..';
|
|
7
|
+
import { SupportedToken } from '../constants';
|
|
8
|
+
|
|
9
|
+
// Create a test class to access protected methods
|
|
10
|
+
class TestableHyspSolana extends HyspSolana {
|
|
11
|
+
public testProcessMemo(memo?: string) {
|
|
12
|
+
return this.processMemo(memo);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
describe('HyspSolana processMemo method', () => {
|
|
17
|
+
const hyspSolana: TestableHyspSolana = new TestableHyspSolana(
|
|
18
|
+
'USDC' as SupportedToken,
|
|
19
|
+
'https://api.mainnet-beta.solana.com',
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
it('should return SDK when memo is empty', () => {
|
|
23
|
+
const result = hyspSolana.testProcessMemo('');
|
|
24
|
+
|
|
25
|
+
expect(new TextDecoder().decode(result.data)).toBe('SDK');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should prepend SDK: to memo without SDK prefix', () => {
|
|
29
|
+
const result = hyspSolana.testProcessMemo('acme:pilotQ1:prod:v1');
|
|
30
|
+
|
|
31
|
+
expect(new TextDecoder().decode(result.data)).toBe(
|
|
32
|
+
'SDK:acme:pilotQ1:prod:v1',
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('should keep memo unchanged when it has SDK prefix', () => {
|
|
37
|
+
const result = hyspSolana.testProcessMemo('SDK:bankxyz::prod:v1');
|
|
38
|
+
|
|
39
|
+
expect(new TextDecoder().decode(result.data)).toBe('SDK:bankxyz::prod:v1');
|
|
40
|
+
});
|
|
41
|
+
});
|
package/src/hysp.ts
CHANGED
|
@@ -28,6 +28,8 @@ import {
|
|
|
28
28
|
getSetComputeUnitPriceInstruction,
|
|
29
29
|
} from '@solana-program/compute-budget';
|
|
30
30
|
|
|
31
|
+
import { getAddMemoInstruction } from '@solana-program/memo';
|
|
32
|
+
|
|
31
33
|
import { KaminoVault, VaultHoldings, APY } from '@kamino-finance/klend-sdk';
|
|
32
34
|
|
|
33
35
|
import { Decimal } from 'decimal.js';
|
|
@@ -341,6 +343,44 @@ export class HyspSolana extends Blockchain {
|
|
|
341
343
|
}
|
|
342
344
|
}
|
|
343
345
|
|
|
346
|
+
/**
|
|
347
|
+
* Processes and creates a memo instruction according to SDK requirements
|
|
348
|
+
* @param memo - Input memo text
|
|
349
|
+
* @returns Memo instruction
|
|
350
|
+
*/
|
|
351
|
+
protected processMemo(memo?: string): Instruction {
|
|
352
|
+
// Process memo text
|
|
353
|
+
let processedMemo: string;
|
|
354
|
+
if (!memo || memo.trim() === '') {
|
|
355
|
+
processedMemo = 'SDK';
|
|
356
|
+
} else {
|
|
357
|
+
const trimmedMemo = memo.trim();
|
|
358
|
+
if (trimmedMemo === 'SDK') {
|
|
359
|
+
processedMemo = trimmedMemo;
|
|
360
|
+
} else if (!trimmedMemo.startsWith('SDK:')) {
|
|
361
|
+
processedMemo = `SDK:${trimmedMemo}`;
|
|
362
|
+
} else {
|
|
363
|
+
processedMemo = trimmedMemo;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// Validate memo
|
|
368
|
+
if (processedMemo.length > 64) {
|
|
369
|
+
throw new Error(
|
|
370
|
+
`Invalid memo: "${processedMemo}". Must be max 64 characters`,
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
const validPattern = /^[A-Za-z0-9:_-]*$/;
|
|
375
|
+
if (!validPattern.test(processedMemo)) {
|
|
376
|
+
throw new Error(
|
|
377
|
+
`Invalid memo: "${processedMemo}". Must contain only [A-Za-z0-9:_-] characters`,
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
return getAddMemoInstruction({ memo: processedMemo });
|
|
382
|
+
}
|
|
383
|
+
|
|
344
384
|
private async buildTx(
|
|
345
385
|
sender: string,
|
|
346
386
|
instructions: Instruction[],
|
|
@@ -388,6 +428,15 @@ export class HyspSolana extends Blockchain {
|
|
|
388
428
|
);
|
|
389
429
|
}
|
|
390
430
|
|
|
431
|
+
// Add memo instruction if memo is provided in params
|
|
432
|
+
if (params?.memo !== undefined) {
|
|
433
|
+
const memoInstruction = this.processMemo(params.memo);
|
|
434
|
+
transactionMessage = appendTransactionMessageInstruction(
|
|
435
|
+
memoInstruction,
|
|
436
|
+
transactionMessage,
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
|
|
391
440
|
if (params?.afterInstructions) {
|
|
392
441
|
for (const instruction of params.afterInstructions) {
|
|
393
442
|
transactionMessage = appendTransactionMessageInstruction(
|
package/src/types/index.ts
CHANGED