@elmntl/jlpd-sdk 0.1.0 → 1.0.9
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/README.md +20 -0
- package/dist/index.d.mts +27 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +148 -76
- package/dist/index.mjs +148 -76
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -108,6 +108,26 @@ console.log("Exchange rate:", rate.rate); // e.g., 1.05 means 5% yield
|
|
|
108
108
|
console.log("Is fresh:", rate.isFresh);
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
+
### Calculate APY
|
|
112
|
+
|
|
113
|
+
Calculate annualized return based on PPS (price per share) growth over time.
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
// You need a starting PPS and timestamp (e.g., from when user deposited)
|
|
117
|
+
const startPps = new BN("1000000000"); // 1.0 (9 decimals)
|
|
118
|
+
const startTime = 1706140800; // Unix timestamp when PPS was recorded
|
|
119
|
+
|
|
120
|
+
// Calculate compound APY
|
|
121
|
+
const apy = await client.calculateApy("SOL", startPps, startTime);
|
|
122
|
+
console.log(`APY: ${(apy * 100).toFixed(2)}%`); // e.g., "APY: 12.50%"
|
|
123
|
+
|
|
124
|
+
// Or calculate simple APY (non-compounded)
|
|
125
|
+
const simpleApy = await client.calculateSimpleApy("SOL", startPps, startTime);
|
|
126
|
+
console.log(`Simple APY: ${(simpleApy * 100).toFixed(2)}%`);
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Note:** Store the user's PPS and timestamp when they deposit to calculate their personal returns later.
|
|
130
|
+
|
|
111
131
|
---
|
|
112
132
|
|
|
113
133
|
## Manager Operations
|
package/dist/index.d.mts
CHANGED
|
@@ -233,6 +233,33 @@ declare class JlpdClient {
|
|
|
233
233
|
fetchVault(): Promise<JLPVault | null>;
|
|
234
234
|
fetchStv(baseMint: PublicKey): Promise<STV | null>;
|
|
235
235
|
fetchExchangeRate(poolName: PoolName): Promise<ExchangeRateResult>;
|
|
236
|
+
/**
|
|
237
|
+
* Calculate APY based on PPS growth over time
|
|
238
|
+
*
|
|
239
|
+
* @param poolName Pool to calculate APY for
|
|
240
|
+
* @param startPps PPS at the start of the period (as BN with 9 decimals)
|
|
241
|
+
* @param startTime Unix timestamp (seconds) when startPps was recorded
|
|
242
|
+
* @returns APY as a decimal (e.g., 0.12 = 12% APY)
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```typescript
|
|
246
|
+
* // Calculate APY from a week ago
|
|
247
|
+
* const startPps = new BN("1050000000"); // 1.05 (9 decimals)
|
|
248
|
+
* const startTime = Math.floor(Date.now() / 1000) - 7 * 24 * 60 * 60;
|
|
249
|
+
* const apy = await client.calculateApy("SOL", startPps, startTime);
|
|
250
|
+
* console.log(`APY: ${(apy * 100).toFixed(2)}%`);
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
calculateApy(poolName: PoolName, startPps: BN, startTime: number): Promise<number>;
|
|
254
|
+
/**
|
|
255
|
+
* Calculate simple APY (non-compounded) based on PPS growth
|
|
256
|
+
*
|
|
257
|
+
* @param poolName Pool to calculate APY for
|
|
258
|
+
* @param startPps PPS at the start of the period
|
|
259
|
+
* @param startTime Unix timestamp when startPps was recorded
|
|
260
|
+
* @returns Simple APY as a decimal
|
|
261
|
+
*/
|
|
262
|
+
calculateSimpleApy(poolName: PoolName, startPps: BN, startTime: number): Promise<number>;
|
|
236
263
|
pool(poolNameOrMint: PoolName | PublicKey): PoolContext;
|
|
237
264
|
swap(): SwapContext;
|
|
238
265
|
admin(): AdminContext;
|
package/dist/index.d.ts
CHANGED
|
@@ -233,6 +233,33 @@ declare class JlpdClient {
|
|
|
233
233
|
fetchVault(): Promise<JLPVault | null>;
|
|
234
234
|
fetchStv(baseMint: PublicKey): Promise<STV | null>;
|
|
235
235
|
fetchExchangeRate(poolName: PoolName): Promise<ExchangeRateResult>;
|
|
236
|
+
/**
|
|
237
|
+
* Calculate APY based on PPS growth over time
|
|
238
|
+
*
|
|
239
|
+
* @param poolName Pool to calculate APY for
|
|
240
|
+
* @param startPps PPS at the start of the period (as BN with 9 decimals)
|
|
241
|
+
* @param startTime Unix timestamp (seconds) when startPps was recorded
|
|
242
|
+
* @returns APY as a decimal (e.g., 0.12 = 12% APY)
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```typescript
|
|
246
|
+
* // Calculate APY from a week ago
|
|
247
|
+
* const startPps = new BN("1050000000"); // 1.05 (9 decimals)
|
|
248
|
+
* const startTime = Math.floor(Date.now() / 1000) - 7 * 24 * 60 * 60;
|
|
249
|
+
* const apy = await client.calculateApy("SOL", startPps, startTime);
|
|
250
|
+
* console.log(`APY: ${(apy * 100).toFixed(2)}%`);
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
calculateApy(poolName: PoolName, startPps: BN, startTime: number): Promise<number>;
|
|
254
|
+
/**
|
|
255
|
+
* Calculate simple APY (non-compounded) based on PPS growth
|
|
256
|
+
*
|
|
257
|
+
* @param poolName Pool to calculate APY for
|
|
258
|
+
* @param startPps PPS at the start of the period
|
|
259
|
+
* @param startTime Unix timestamp when startPps was recorded
|
|
260
|
+
* @returns Simple APY as a decimal
|
|
261
|
+
*/
|
|
262
|
+
calculateSimpleApy(poolName: PoolName, startPps: BN, startTime: number): Promise<number>;
|
|
236
263
|
pool(poolNameOrMint: PoolName | PublicKey): PoolContext;
|
|
237
264
|
swap(): SwapContext;
|
|
238
265
|
admin(): AdminContext;
|
package/dist/index.js
CHANGED
|
@@ -791,34 +791,34 @@ async function fetchJlpRate(jlpMint, fallbackPrice = 4.6, apiKey = DEFAULT_API_K
|
|
|
791
791
|
// src/instructions/admin.ts
|
|
792
792
|
var import_web38 = require("@solana/web3.js");
|
|
793
793
|
var INIT_OR_UPDATE_VAULT_DISCRIMINATOR = Buffer.from([
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
794
|
+
234,
|
|
795
|
+
24,
|
|
796
|
+
218,
|
|
797
|
+
120,
|
|
798
|
+
213,
|
|
799
|
+
149,
|
|
800
|
+
245,
|
|
801
|
+
213
|
|
802
802
|
]);
|
|
803
803
|
var INITIALIZE_STV_DISCRIMINATOR = Buffer.from([
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
804
|
+
136,
|
|
805
|
+
8,
|
|
806
|
+
178,
|
|
807
|
+
176,
|
|
808
|
+
57,
|
|
809
|
+
33,
|
|
810
|
+
1,
|
|
811
|
+
106
|
|
812
812
|
]);
|
|
813
813
|
var UPDATE_STV_DISCRIMINATOR = Buffer.from([
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
814
|
+
72,
|
|
815
|
+
173,
|
|
816
|
+
200,
|
|
817
|
+
203,
|
|
818
|
+
74,
|
|
819
|
+
83,
|
|
820
|
+
242,
|
|
821
|
+
43
|
|
822
822
|
]);
|
|
823
823
|
function serializeOptionPubkey(value) {
|
|
824
824
|
if (value === null) {
|
|
@@ -910,14 +910,14 @@ function createUpdateStvInstruction(params, accounts, programId = JLPD_PROGRAM_I
|
|
|
910
910
|
// src/instructions/user.ts
|
|
911
911
|
var import_web39 = require("@solana/web3.js");
|
|
912
912
|
var DEPOSIT_DISCRIMINATOR = Buffer.from([
|
|
913
|
-
|
|
913
|
+
242,
|
|
914
|
+
35,
|
|
914
915
|
198,
|
|
915
|
-
|
|
916
|
-
|
|
916
|
+
137,
|
|
917
|
+
82,
|
|
917
918
|
225,
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
200
|
|
919
|
+
242,
|
|
920
|
+
182
|
|
921
921
|
]);
|
|
922
922
|
var WITHDRAW_DISCRIMINATOR = Buffer.from([
|
|
923
923
|
183,
|
|
@@ -974,54 +974,54 @@ function createWithdrawInstruction(sharesToBurn, accounts, remainingAccounts = [
|
|
|
974
974
|
// src/instructions/manager.ts
|
|
975
975
|
var import_web310 = require("@solana/web3.js");
|
|
976
976
|
var JUP_EARN_DISCRIMINATOR = Buffer.from([
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
977
|
+
124,
|
|
978
|
+
60,
|
|
979
|
+
71,
|
|
980
|
+
122,
|
|
981
|
+
162,
|
|
980
982
|
212,
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
7,
|
|
984
|
-
24
|
|
983
|
+
164,
|
|
984
|
+
191
|
|
985
985
|
]);
|
|
986
986
|
var MOVE_STV_DISCRIMINATOR = Buffer.from([
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
92,
|
|
991
|
-
109,
|
|
987
|
+
60,
|
|
988
|
+
104,
|
|
989
|
+
8,
|
|
992
990
|
126,
|
|
993
|
-
|
|
994
|
-
|
|
991
|
+
254,
|
|
992
|
+
244,
|
|
993
|
+
95,
|
|
994
|
+
221
|
|
995
995
|
]);
|
|
996
996
|
var SWAP_JLX_JLX_DISCRIMINATOR = Buffer.from([
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
997
|
+
24,
|
|
998
|
+
52,
|
|
999
|
+
70,
|
|
1000
|
+
107,
|
|
1001
|
+
160,
|
|
1002
|
+
96,
|
|
1003
|
+
155,
|
|
1004
|
+
62
|
|
1005
1005
|
]);
|
|
1006
1006
|
var SWAP_JLX_JLP_DISCRIMINATOR = Buffer.from([
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1007
|
+
229,
|
|
1008
|
+
185,
|
|
1009
|
+
136,
|
|
1010
|
+
170,
|
|
1011
|
+
210,
|
|
1012
|
+
189,
|
|
1013
|
+
172,
|
|
1014
|
+
241
|
|
1015
1015
|
]);
|
|
1016
1016
|
var SETTLE_YIELD_DISCRIMINATOR = Buffer.from([
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1017
|
+
64,
|
|
1018
|
+
28,
|
|
1019
|
+
44,
|
|
1020
|
+
24,
|
|
1021
|
+
43,
|
|
1022
|
+
204,
|
|
1023
|
+
58,
|
|
1024
|
+
215
|
|
1025
1025
|
]);
|
|
1026
1026
|
function serializeU8(value) {
|
|
1027
1027
|
const buf = Buffer.alloc(1);
|
|
@@ -1155,14 +1155,14 @@ function createSettleYieldInstruction(params, accounts, remainingAccounts = [],
|
|
|
1155
1155
|
// src/instructions/fees.ts
|
|
1156
1156
|
var import_web311 = require("@solana/web3.js");
|
|
1157
1157
|
var CLAIM_FEES_DISCRIMINATOR = Buffer.from([
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1158
|
+
82,
|
|
1159
|
+
251,
|
|
1160
|
+
233,
|
|
1161
|
+
156,
|
|
1162
|
+
12,
|
|
1163
|
+
52,
|
|
1164
|
+
184,
|
|
1165
|
+
202
|
|
1166
1166
|
]);
|
|
1167
1167
|
function createClaimFeesInstruction(accounts, remainingAccounts = [], programId = JLPD_PROGRAM_ID) {
|
|
1168
1168
|
const data = CLAIM_FEES_DISCRIMINATOR;
|
|
@@ -1267,6 +1267,78 @@ var JlpdClient = class _JlpdClient {
|
|
|
1267
1267
|
isFresh: staleness < 300
|
|
1268
1268
|
};
|
|
1269
1269
|
}
|
|
1270
|
+
/**
|
|
1271
|
+
* Calculate APY based on PPS growth over time
|
|
1272
|
+
*
|
|
1273
|
+
* @param poolName Pool to calculate APY for
|
|
1274
|
+
* @param startPps PPS at the start of the period (as BN with 9 decimals)
|
|
1275
|
+
* @param startTime Unix timestamp (seconds) when startPps was recorded
|
|
1276
|
+
* @returns APY as a decimal (e.g., 0.12 = 12% APY)
|
|
1277
|
+
*
|
|
1278
|
+
* @example
|
|
1279
|
+
* ```typescript
|
|
1280
|
+
* // Calculate APY from a week ago
|
|
1281
|
+
* const startPps = new BN("1050000000"); // 1.05 (9 decimals)
|
|
1282
|
+
* const startTime = Math.floor(Date.now() / 1000) - 7 * 24 * 60 * 60;
|
|
1283
|
+
* const apy = await client.calculateApy("SOL", startPps, startTime);
|
|
1284
|
+
* console.log(`APY: ${(apy * 100).toFixed(2)}%`);
|
|
1285
|
+
* ```
|
|
1286
|
+
*/
|
|
1287
|
+
async calculateApy(poolName, startPps, startTime) {
|
|
1288
|
+
const pool = getPoolByName(poolName);
|
|
1289
|
+
if (!pool) throw new JlpdClientError(`Unknown pool: ${poolName}`);
|
|
1290
|
+
const [stv, slot] = await Promise.all([
|
|
1291
|
+
this.fetchStv(pool.mint),
|
|
1292
|
+
this.connection.getSlot()
|
|
1293
|
+
]);
|
|
1294
|
+
if (!stv) throw new JlpdClientError(`STV not found for pool: ${poolName}`);
|
|
1295
|
+
const currentTime = await this.connection.getBlockTime(slot);
|
|
1296
|
+
if (!currentTime) throw new JlpdClientError("Failed to get block time");
|
|
1297
|
+
const currentPps = stv.pps;
|
|
1298
|
+
const startPpsNum = Number(startPps.toString()) / PPS_DECIMALS;
|
|
1299
|
+
const currentPpsNum = Number(currentPps.toString()) / PPS_DECIMALS;
|
|
1300
|
+
const timeElapsed = currentTime - startTime;
|
|
1301
|
+
if (timeElapsed <= 0) {
|
|
1302
|
+
throw new JlpdClientError("Start time must be in the past");
|
|
1303
|
+
}
|
|
1304
|
+
const SECONDS_PER_YEAR2 = 365.25 * 24 * 60 * 60;
|
|
1305
|
+
const ppsGrowthRatio = currentPpsNum / startPpsNum;
|
|
1306
|
+
if (ppsGrowthRatio <= 0) {
|
|
1307
|
+
return -1;
|
|
1308
|
+
}
|
|
1309
|
+
const annualizationFactor = SECONDS_PER_YEAR2 / timeElapsed;
|
|
1310
|
+
const apy = Math.pow(ppsGrowthRatio, annualizationFactor) - 1;
|
|
1311
|
+
return apy;
|
|
1312
|
+
}
|
|
1313
|
+
/**
|
|
1314
|
+
* Calculate simple APY (non-compounded) based on PPS growth
|
|
1315
|
+
*
|
|
1316
|
+
* @param poolName Pool to calculate APY for
|
|
1317
|
+
* @param startPps PPS at the start of the period
|
|
1318
|
+
* @param startTime Unix timestamp when startPps was recorded
|
|
1319
|
+
* @returns Simple APY as a decimal
|
|
1320
|
+
*/
|
|
1321
|
+
async calculateSimpleApy(poolName, startPps, startTime) {
|
|
1322
|
+
const pool = getPoolByName(poolName);
|
|
1323
|
+
if (!pool) throw new JlpdClientError(`Unknown pool: ${poolName}`);
|
|
1324
|
+
const [stv, slot] = await Promise.all([
|
|
1325
|
+
this.fetchStv(pool.mint),
|
|
1326
|
+
this.connection.getSlot()
|
|
1327
|
+
]);
|
|
1328
|
+
if (!stv) throw new JlpdClientError(`STV not found for pool: ${poolName}`);
|
|
1329
|
+
const currentTime = await this.connection.getBlockTime(slot);
|
|
1330
|
+
if (!currentTime) throw new JlpdClientError("Failed to get block time");
|
|
1331
|
+
const startPpsNum = Number(startPps.toString()) / PPS_DECIMALS;
|
|
1332
|
+
const currentPpsNum = Number(stv.pps.toString()) / PPS_DECIMALS;
|
|
1333
|
+
const timeElapsed = currentTime - startTime;
|
|
1334
|
+
if (timeElapsed <= 0) {
|
|
1335
|
+
throw new JlpdClientError("Start time must be in the past");
|
|
1336
|
+
}
|
|
1337
|
+
const SECONDS_PER_YEAR2 = 365.25 * 24 * 60 * 60;
|
|
1338
|
+
const growthRate = (currentPpsNum - startPpsNum) / startPpsNum;
|
|
1339
|
+
const simpleApy = growthRate * (SECONDS_PER_YEAR2 / timeElapsed);
|
|
1340
|
+
return simpleApy;
|
|
1341
|
+
}
|
|
1270
1342
|
// Get pool context for pool-specific operations (cached)
|
|
1271
1343
|
pool(poolNameOrMint) {
|
|
1272
1344
|
const key = typeof poolNameOrMint === "string" ? poolNameOrMint : poolNameOrMint.toBase58();
|
package/dist/index.mjs
CHANGED
|
@@ -702,34 +702,34 @@ async function fetchJlpRate(jlpMint, fallbackPrice = 4.6, apiKey = DEFAULT_API_K
|
|
|
702
702
|
// src/instructions/admin.ts
|
|
703
703
|
import { TransactionInstruction } from "@solana/web3.js";
|
|
704
704
|
var INIT_OR_UPDATE_VAULT_DISCRIMINATOR = Buffer.from([
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
705
|
+
234,
|
|
706
|
+
24,
|
|
707
|
+
218,
|
|
708
|
+
120,
|
|
709
|
+
213,
|
|
710
|
+
149,
|
|
711
|
+
245,
|
|
712
|
+
213
|
|
713
713
|
]);
|
|
714
714
|
var INITIALIZE_STV_DISCRIMINATOR = Buffer.from([
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
715
|
+
136,
|
|
716
|
+
8,
|
|
717
|
+
178,
|
|
718
|
+
176,
|
|
719
|
+
57,
|
|
720
|
+
33,
|
|
721
|
+
1,
|
|
722
|
+
106
|
|
723
723
|
]);
|
|
724
724
|
var UPDATE_STV_DISCRIMINATOR = Buffer.from([
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
725
|
+
72,
|
|
726
|
+
173,
|
|
727
|
+
200,
|
|
728
|
+
203,
|
|
729
|
+
74,
|
|
730
|
+
83,
|
|
731
|
+
242,
|
|
732
|
+
43
|
|
733
733
|
]);
|
|
734
734
|
function serializeOptionPubkey(value) {
|
|
735
735
|
if (value === null) {
|
|
@@ -821,14 +821,14 @@ function createUpdateStvInstruction(params, accounts, programId = JLPD_PROGRAM_I
|
|
|
821
821
|
// src/instructions/user.ts
|
|
822
822
|
import { TransactionInstruction as TransactionInstruction2 } from "@solana/web3.js";
|
|
823
823
|
var DEPOSIT_DISCRIMINATOR = Buffer.from([
|
|
824
|
-
|
|
824
|
+
242,
|
|
825
|
+
35,
|
|
825
826
|
198,
|
|
826
|
-
|
|
827
|
-
|
|
827
|
+
137,
|
|
828
|
+
82,
|
|
828
829
|
225,
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
200
|
|
830
|
+
242,
|
|
831
|
+
182
|
|
832
832
|
]);
|
|
833
833
|
var WITHDRAW_DISCRIMINATOR = Buffer.from([
|
|
834
834
|
183,
|
|
@@ -885,54 +885,54 @@ function createWithdrawInstruction(sharesToBurn, accounts, remainingAccounts = [
|
|
|
885
885
|
// src/instructions/manager.ts
|
|
886
886
|
import { TransactionInstruction as TransactionInstruction3 } from "@solana/web3.js";
|
|
887
887
|
var JUP_EARN_DISCRIMINATOR = Buffer.from([
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
888
|
+
124,
|
|
889
|
+
60,
|
|
890
|
+
71,
|
|
891
|
+
122,
|
|
892
|
+
162,
|
|
891
893
|
212,
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
7,
|
|
895
|
-
24
|
|
894
|
+
164,
|
|
895
|
+
191
|
|
896
896
|
]);
|
|
897
897
|
var MOVE_STV_DISCRIMINATOR = Buffer.from([
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
92,
|
|
902
|
-
109,
|
|
898
|
+
60,
|
|
899
|
+
104,
|
|
900
|
+
8,
|
|
903
901
|
126,
|
|
904
|
-
|
|
905
|
-
|
|
902
|
+
254,
|
|
903
|
+
244,
|
|
904
|
+
95,
|
|
905
|
+
221
|
|
906
906
|
]);
|
|
907
907
|
var SWAP_JLX_JLX_DISCRIMINATOR = Buffer.from([
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
908
|
+
24,
|
|
909
|
+
52,
|
|
910
|
+
70,
|
|
911
|
+
107,
|
|
912
|
+
160,
|
|
913
|
+
96,
|
|
914
|
+
155,
|
|
915
|
+
62
|
|
916
916
|
]);
|
|
917
917
|
var SWAP_JLX_JLP_DISCRIMINATOR = Buffer.from([
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
918
|
+
229,
|
|
919
|
+
185,
|
|
920
|
+
136,
|
|
921
|
+
170,
|
|
922
|
+
210,
|
|
923
|
+
189,
|
|
924
|
+
172,
|
|
925
|
+
241
|
|
926
926
|
]);
|
|
927
927
|
var SETTLE_YIELD_DISCRIMINATOR = Buffer.from([
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
928
|
+
64,
|
|
929
|
+
28,
|
|
930
|
+
44,
|
|
931
|
+
24,
|
|
932
|
+
43,
|
|
933
|
+
204,
|
|
934
|
+
58,
|
|
935
|
+
215
|
|
936
936
|
]);
|
|
937
937
|
function serializeU8(value) {
|
|
938
938
|
const buf = Buffer.alloc(1);
|
|
@@ -1066,14 +1066,14 @@ function createSettleYieldInstruction(params, accounts, remainingAccounts = [],
|
|
|
1066
1066
|
// src/instructions/fees.ts
|
|
1067
1067
|
import { TransactionInstruction as TransactionInstruction4 } from "@solana/web3.js";
|
|
1068
1068
|
var CLAIM_FEES_DISCRIMINATOR = Buffer.from([
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1069
|
+
82,
|
|
1070
|
+
251,
|
|
1071
|
+
233,
|
|
1072
|
+
156,
|
|
1073
|
+
12,
|
|
1074
|
+
52,
|
|
1075
|
+
184,
|
|
1076
|
+
202
|
|
1077
1077
|
]);
|
|
1078
1078
|
function createClaimFeesInstruction(accounts, remainingAccounts = [], programId = JLPD_PROGRAM_ID) {
|
|
1079
1079
|
const data = CLAIM_FEES_DISCRIMINATOR;
|
|
@@ -1178,6 +1178,78 @@ var JlpdClient = class _JlpdClient {
|
|
|
1178
1178
|
isFresh: staleness < 300
|
|
1179
1179
|
};
|
|
1180
1180
|
}
|
|
1181
|
+
/**
|
|
1182
|
+
* Calculate APY based on PPS growth over time
|
|
1183
|
+
*
|
|
1184
|
+
* @param poolName Pool to calculate APY for
|
|
1185
|
+
* @param startPps PPS at the start of the period (as BN with 9 decimals)
|
|
1186
|
+
* @param startTime Unix timestamp (seconds) when startPps was recorded
|
|
1187
|
+
* @returns APY as a decimal (e.g., 0.12 = 12% APY)
|
|
1188
|
+
*
|
|
1189
|
+
* @example
|
|
1190
|
+
* ```typescript
|
|
1191
|
+
* // Calculate APY from a week ago
|
|
1192
|
+
* const startPps = new BN("1050000000"); // 1.05 (9 decimals)
|
|
1193
|
+
* const startTime = Math.floor(Date.now() / 1000) - 7 * 24 * 60 * 60;
|
|
1194
|
+
* const apy = await client.calculateApy("SOL", startPps, startTime);
|
|
1195
|
+
* console.log(`APY: ${(apy * 100).toFixed(2)}%`);
|
|
1196
|
+
* ```
|
|
1197
|
+
*/
|
|
1198
|
+
async calculateApy(poolName, startPps, startTime) {
|
|
1199
|
+
const pool = getPoolByName(poolName);
|
|
1200
|
+
if (!pool) throw new JlpdClientError(`Unknown pool: ${poolName}`);
|
|
1201
|
+
const [stv, slot] = await Promise.all([
|
|
1202
|
+
this.fetchStv(pool.mint),
|
|
1203
|
+
this.connection.getSlot()
|
|
1204
|
+
]);
|
|
1205
|
+
if (!stv) throw new JlpdClientError(`STV not found for pool: ${poolName}`);
|
|
1206
|
+
const currentTime = await this.connection.getBlockTime(slot);
|
|
1207
|
+
if (!currentTime) throw new JlpdClientError("Failed to get block time");
|
|
1208
|
+
const currentPps = stv.pps;
|
|
1209
|
+
const startPpsNum = Number(startPps.toString()) / PPS_DECIMALS;
|
|
1210
|
+
const currentPpsNum = Number(currentPps.toString()) / PPS_DECIMALS;
|
|
1211
|
+
const timeElapsed = currentTime - startTime;
|
|
1212
|
+
if (timeElapsed <= 0) {
|
|
1213
|
+
throw new JlpdClientError("Start time must be in the past");
|
|
1214
|
+
}
|
|
1215
|
+
const SECONDS_PER_YEAR2 = 365.25 * 24 * 60 * 60;
|
|
1216
|
+
const ppsGrowthRatio = currentPpsNum / startPpsNum;
|
|
1217
|
+
if (ppsGrowthRatio <= 0) {
|
|
1218
|
+
return -1;
|
|
1219
|
+
}
|
|
1220
|
+
const annualizationFactor = SECONDS_PER_YEAR2 / timeElapsed;
|
|
1221
|
+
const apy = Math.pow(ppsGrowthRatio, annualizationFactor) - 1;
|
|
1222
|
+
return apy;
|
|
1223
|
+
}
|
|
1224
|
+
/**
|
|
1225
|
+
* Calculate simple APY (non-compounded) based on PPS growth
|
|
1226
|
+
*
|
|
1227
|
+
* @param poolName Pool to calculate APY for
|
|
1228
|
+
* @param startPps PPS at the start of the period
|
|
1229
|
+
* @param startTime Unix timestamp when startPps was recorded
|
|
1230
|
+
* @returns Simple APY as a decimal
|
|
1231
|
+
*/
|
|
1232
|
+
async calculateSimpleApy(poolName, startPps, startTime) {
|
|
1233
|
+
const pool = getPoolByName(poolName);
|
|
1234
|
+
if (!pool) throw new JlpdClientError(`Unknown pool: ${poolName}`);
|
|
1235
|
+
const [stv, slot] = await Promise.all([
|
|
1236
|
+
this.fetchStv(pool.mint),
|
|
1237
|
+
this.connection.getSlot()
|
|
1238
|
+
]);
|
|
1239
|
+
if (!stv) throw new JlpdClientError(`STV not found for pool: ${poolName}`);
|
|
1240
|
+
const currentTime = await this.connection.getBlockTime(slot);
|
|
1241
|
+
if (!currentTime) throw new JlpdClientError("Failed to get block time");
|
|
1242
|
+
const startPpsNum = Number(startPps.toString()) / PPS_DECIMALS;
|
|
1243
|
+
const currentPpsNum = Number(stv.pps.toString()) / PPS_DECIMALS;
|
|
1244
|
+
const timeElapsed = currentTime - startTime;
|
|
1245
|
+
if (timeElapsed <= 0) {
|
|
1246
|
+
throw new JlpdClientError("Start time must be in the past");
|
|
1247
|
+
}
|
|
1248
|
+
const SECONDS_PER_YEAR2 = 365.25 * 24 * 60 * 60;
|
|
1249
|
+
const growthRate = (currentPpsNum - startPpsNum) / startPpsNum;
|
|
1250
|
+
const simpleApy = growthRate * (SECONDS_PER_YEAR2 / timeElapsed);
|
|
1251
|
+
return simpleApy;
|
|
1252
|
+
}
|
|
1181
1253
|
// Get pool context for pool-specific operations (cached)
|
|
1182
1254
|
pool(poolNameOrMint) {
|
|
1183
1255
|
const key = typeof poolNameOrMint === "string" ? poolNameOrMint : poolNameOrMint.toBase58();
|