@elemental-stv-core/sdk 0.7.0 → 0.9.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.
Files changed (35) hide show
  1. package/dist/common/ata.d.ts +13 -1
  2. package/dist/common/ata.js +27 -0
  3. package/dist/common/index.d.ts +1 -1
  4. package/dist/common/index.js +2 -1
  5. package/dist/elemental-lend-v2/accounts.d.ts +14 -0
  6. package/dist/elemental-lend-v2/accounts.js +136 -0
  7. package/dist/elemental-lend-v2/adapters.d.ts +22 -0
  8. package/dist/elemental-lend-v2/adapters.js +50 -0
  9. package/dist/elemental-lend-v2/constants.d.ts +48 -0
  10. package/dist/elemental-lend-v2/constants.js +104 -0
  11. package/dist/elemental-lend-v2/index.d.ts +8 -0
  12. package/dist/elemental-lend-v2/index.js +24 -0
  13. package/dist/elemental-lend-v2/instructions.d.ts +96 -0
  14. package/dist/elemental-lend-v2/instructions.js +190 -0
  15. package/dist/elemental-lend-v2/lut.d.ts +20 -0
  16. package/dist/elemental-lend-v2/lut.js +65 -0
  17. package/dist/elemental-lend-v2/pda.d.ts +9 -0
  18. package/dist/elemental-lend-v2/pda.js +27 -0
  19. package/dist/elemental-lend-v2/types.d.ts +105 -0
  20. package/dist/elemental-lend-v2/types.js +2 -0
  21. package/dist/elemental-lend-v2/update-aum.d.ts +29 -0
  22. package/dist/elemental-lend-v2/update-aum.js +82 -0
  23. package/dist/index.d.ts +1 -0
  24. package/dist/index.js +2 -1
  25. package/dist/jlpd-strategy/jlp-data.d.ts +72 -0
  26. package/dist/jlpd-strategy/jlp-data.js +154 -0
  27. package/dist/p-stv-core/accounts.d.ts +1 -1
  28. package/dist/p-stv-core/accounts.js +2 -2
  29. package/dist/p-stv-core/index.d.ts +1 -0
  30. package/dist/p-stv-core/index.js +1 -0
  31. package/dist/p-stv-core/lut.d.ts +41 -0
  32. package/dist/p-stv-core/lut.js +81 -0
  33. package/dist/p-stv-core/sol-wrap.js +1 -21
  34. package/dist/p-stv-core/types.d.ts +3 -1
  35. package/package.json +7 -1
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.fetchJlpPoolDetails = fetchJlpPoolDetails;
4
4
  exports.computeAddLiquidityFee = computeAddLiquidityFee;
5
5
  exports.fetchJlpCustodyData = fetchJlpCustodyData;
6
+ exports.computeEffectiveUsd = computeEffectiveUsd;
7
+ exports.fetchJlpEffectiveWeights = fetchJlpEffectiveWeights;
6
8
  const web3_js_1 = require("@solana/web3.js");
7
9
  const constants_1 = require("./constants");
8
10
  const CUSTODIES = [
@@ -403,3 +405,155 @@ async function fetchJlpCustodyData(connection) {
403
405
  custodies: results,
404
406
  };
405
407
  }
408
+ /** Map JLP custody internal name to public symbol used by effective-weights API. */
409
+ function toEffSymbol(name) {
410
+ return name === "WBTC" ? "BTC" : name;
411
+ }
412
+ /** Convert a float USD price to an 8-decimal-scaled bigint.
413
+ *
414
+ * Uses 12-decimal intermediate to preserve sub-1¢ precision before truncation. */
415
+ function priceToScaled8(priceFloat) {
416
+ if (!isFinite(priceFloat) || priceFloat <= 0)
417
+ return 0n;
418
+ // Round to 12 decimals first to avoid float artifacts, then scale to 8.
419
+ const scaled12 = BigInt(Math.round(priceFloat * 1e12));
420
+ return scaled12 / 10000n; // 12 → 8 decimals
421
+ }
422
+ /** Compute effective USD (price-sensitivity-weighted) for a single custody.
423
+ *
424
+ * Formula (in 8-decimal USD):
425
+ * spot = (owned − locked) × price_8dec / 10^decimals
426
+ * short = shortSize_6dec × price_8dec / avgShortPrice_6dec (zeroed if either operand is 0)
427
+ * effUsd = max(spot, 0) + short
428
+ *
429
+ * Algebra for unit normalization:
430
+ * - owned/locked is in 10^decimals base units; price is 10^8 USD.
431
+ * spot = (owned − locked) × price_8dec / 10^decimals → 10^8 USD ✓
432
+ * - shortSize and avgShortPrice are both 10^6; ratio is dimensionless.
433
+ * short = shortSize × price_8dec / avgShortPrice → 10^8 USD ✓
434
+ */
435
+ function computeEffectiveUsd(input) {
436
+ const { owned, locked, shortSizeUsd, avgShortPriceUsd, decimals, priceScaled8 } = input;
437
+ const tokScale = 10n ** BigInt(decimals);
438
+ // Spot term: (owned − locked) × price / 10^decimals
439
+ // Use signed bigint subtraction; clamp to 0 if owned < locked (defensive).
440
+ const netTokens = owned - locked; // bigint — can go negative
441
+ let spotEffUsd;
442
+ let spotClamped = false;
443
+ if (netTokens <= 0n) {
444
+ spotEffUsd = 0n;
445
+ if (netTokens < 0n)
446
+ spotClamped = true;
447
+ }
448
+ else {
449
+ spotEffUsd = (netTokens * priceScaled8) / tokScale;
450
+ }
451
+ // Short term: only contributes when both shortSize and avgShortPrice > 0.
452
+ // Numerator stays in u128 range comfortably (shortSize_6dec × price_8dec).
453
+ let shortEffUsd = 0n;
454
+ if (shortSizeUsd > 0n && avgShortPriceUsd > 0n && priceScaled8 > 0n) {
455
+ shortEffUsd = (shortSizeUsd * priceScaled8) / avgShortPriceUsd;
456
+ }
457
+ return {
458
+ spotEffUsd,
459
+ shortEffUsd,
460
+ effUsd: spotEffUsd + shortEffUsd,
461
+ spotClamped,
462
+ };
463
+ }
464
+ /** Compute basis-point shares for each effective USD value, summing to 10000.
465
+ *
466
+ * Uses largest-remainder allocation to guarantee the bps sum equals exactly 10000
467
+ * even with rounding. (Naive `round(eff_i / total × 10000)` per-asset can drift
468
+ * by up to `n` bps cumulatively.) Returns 0s for all assets if total is 0.
469
+ */
470
+ function computeBpsShares(effs) {
471
+ const total = effs.reduce((s, e) => s + e, 0n);
472
+ if (total === 0n)
473
+ return effs.map(() => 0);
474
+ // Floor allocation
475
+ const exact = effs.map((e) => Number((e * 10000n) / total));
476
+ const allocated = exact.reduce((s, b) => s + b, 0);
477
+ let remaining = 10000 - allocated;
478
+ if (remaining <= 0)
479
+ return exact;
480
+ // Distribute remaining bps to the assets with largest fractional remainders.
481
+ // Compute remainder = (e × 10000) mod total, ranked descending.
482
+ const remainders = effs.map((e, i) => ({
483
+ i,
484
+ rem: (e * 10000n) % total,
485
+ }));
486
+ remainders.sort((a, b) => (a.rem === b.rem ? 0 : a.rem > b.rem ? -1 : 1));
487
+ const result = exact.slice();
488
+ for (let k = 0; k < remainders.length && remaining > 0; k++) {
489
+ result[remainders[k].i]++;
490
+ remaining--;
491
+ }
492
+ return result;
493
+ }
494
+ /**
495
+ * Fetch JLP pool effective-weight composition.
496
+ *
497
+ * Returns price-sensitivity-weighted shares per asset, dropping `guaranteed_usd`
498
+ * from the per-asset weight calculation. Suitable for rebalance planners that
499
+ * want to track the pool's true delta-1 composition rather than reported aumUsd.
500
+ *
501
+ * Reuses the same on-chain custody parser and Jupiter Price API source as
502
+ * `fetchJlpCustodyData` to keep numbers consistent across callers.
503
+ *
504
+ * @returns assets in fixed order: BTC, ETH, SOL, USDC, USDT.
505
+ */
506
+ async function fetchJlpEffectiveWeights(connection) {
507
+ const [custodies, pricesByMint] = await Promise.all([
508
+ fetchAllCustodies(connection),
509
+ fetchPrices(),
510
+ ]);
511
+ // Resolve price per custody (stables fall back to $1.00 when API is missing them).
512
+ const priceFloat = {};
513
+ for (const cfg of CUSTODIES) {
514
+ const p = pricesByMint[cfg.mintAddress];
515
+ if (p === undefined || p === null) {
516
+ if (cfg.isStable) {
517
+ priceFloat[cfg.name] = 1;
518
+ }
519
+ else {
520
+ throw new Error(`Missing price for non-stable asset ${cfg.name} (mint: ${cfg.mintAddress})`);
521
+ }
522
+ }
523
+ else {
524
+ priceFloat[cfg.name] = p;
525
+ }
526
+ }
527
+ // Compute effective USD per custody.
528
+ const computed = custodies.map((raw) => {
529
+ const effInput = {
530
+ owned: raw.owned,
531
+ locked: raw.locked,
532
+ shortSizeUsd: raw.globalShortSizes,
533
+ avgShortPriceUsd: raw.globalShortAveragePrices,
534
+ guaranteedUsd: raw.guaranteedUsd,
535
+ decimals: raw.cfg.decimals,
536
+ priceScaled8: priceToScaled8(priceFloat[raw.cfg.name]),
537
+ };
538
+ return { raw, out: computeEffectiveUsd(effInput) };
539
+ });
540
+ const effs = computed.map((c) => c.out.effUsd);
541
+ const bpsShares = computeBpsShares(effs);
542
+ const assets = computed.map((c, i) => ({
543
+ mint: new web3_js_1.PublicKey(c.raw.cfg.mintAddress),
544
+ symbol: toEffSymbol(c.raw.cfg.name),
545
+ effUsd: c.out.effUsd,
546
+ effShareBps: bpsShares[i],
547
+ spotClamped: c.out.spotClamped,
548
+ }));
549
+ const totalEffUsd = effs.reduce((s, e) => s + e, 0n);
550
+ // Total pool aumUsd in 8-decimal USD = aumUsd from `calculateCustodyAum` (float)
551
+ // re-aggregated. We reuse the existing path but normalize to bigint 8-decimals.
552
+ // Each calculateCustodyAum return is a float USD; multiply by 1e8 and round.
553
+ const totalAumFloat = custodies.reduce((sum, raw) => {
554
+ const a = calculateCustodyAum(raw, priceFloat[raw.cfg.name] ?? 1);
555
+ return sum + a.aumUsd;
556
+ }, 0);
557
+ const totalAumUsd = BigInt(Math.round(totalAumFloat * 1e8));
558
+ return { assets, totalEffUsd, totalAumUsd };
559
+ }
@@ -28,7 +28,7 @@ export declare function deserializeGlobalConfig(data: Buffer): GlobalConfig;
28
28
  * [168..248] childVaults[10] [u64; 10] (allocator child vault IDs)
29
29
  * [248..256] vaultId u64
30
30
  * [256..264] reservedBase u64 (base reserved for pending claims)
31
- * [264..272] requestedBase u64 (base requested via request_withdraw)
31
+ * [264..272] requestedShares u64 (shares pending in escrow — multiply × PPS to estimate base)
32
32
  * [272..280] vaultCapacity u64 (0 = uncapped)
33
33
  * [280..288] minDeposit u64
34
34
  * [288..296] hwm u64 (high-water mark for perf fees)
@@ -66,7 +66,7 @@ function deserializeGlobalConfig(data) {
66
66
  * [168..248] childVaults[10] [u64; 10] (allocator child vault IDs)
67
67
  * [248..256] vaultId u64
68
68
  * [256..264] reservedBase u64 (base reserved for pending claims)
69
- * [264..272] requestedBase u64 (base requested via request_withdraw)
69
+ * [264..272] requestedShares u64 (shares pending in escrow — multiply × PPS to estimate base)
70
70
  * [272..280] vaultCapacity u64 (0 = uncapped)
71
71
  * [280..288] minDeposit u64
72
72
  * [288..296] hwm u64 (high-water mark for perf fees)
@@ -110,7 +110,7 @@ function deserializeStv(data) {
110
110
  childVaults,
111
111
  vaultId: (0, buffer_1.readU64)(data, 248),
112
112
  reservedBase: (0, buffer_1.readU64)(data, 256),
113
- requestedBase: (0, buffer_1.readU64)(data, 264),
113
+ requestedShares: (0, buffer_1.readU64)(data, 264),
114
114
  vaultCapacity: (0, buffer_1.readU64)(data, 272),
115
115
  minDeposit: (0, buffer_1.readU64)(data, 280),
116
116
  hwm: (0, buffer_1.readU64)(data, 288),
@@ -8,3 +8,4 @@ export * from "./remaining-accounts";
8
8
  export * from "./send-tx";
9
9
  export * from "./sol-wrap";
10
10
  export * from "./prices";
11
+ export * from "./lut";
@@ -24,3 +24,4 @@ __exportStar(require("./remaining-accounts"), exports);
24
24
  __exportStar(require("./send-tx"), exports);
25
25
  __exportStar(require("./sol-wrap"), exports);
26
26
  __exportStar(require("./prices"), exports);
27
+ __exportStar(require("./lut"), exports);
@@ -0,0 +1,41 @@
1
+ /**
2
+ * p-STV Core Address Lookup Table helpers.
3
+ *
4
+ * Packages the STATIC (per-program, not per-tx) p-stv-core accounts into a LUT
5
+ * so versioned transactions can compress them into a single 1-byte index.
6
+ *
7
+ * Usage:
8
+ * // Owner flow (one-time):
9
+ * const [createIx, lutAddress] = AddressLookupTableProgram.createLookupTable({...});
10
+ * const extendIxs = buildPstvCoreLutExtendIxs(payer, lutAddress);
11
+ * // send createIx + extendIxs
12
+ *
13
+ * // Consumer flow (every tx):
14
+ * const lutAccount = await resolvePstvCoreLut(connection, lutAddress);
15
+ * const msg = new TransactionMessage({...}).compileToV0Message([lutAccount]);
16
+ *
17
+ * NOTE: Only program IDs, the GlobalConfig PDA, and token/ATA/compute-budget
18
+ * program IDs. Per-vault PDAs (stv, evMint, vaultAta, withdrawRequest,
19
+ * managerRole) and strategy/lend state live in separate LUTs.
20
+ */
21
+ import { AddressLookupTableAccount, Connection, PublicKey, TransactionInstruction } from "@solana/web3.js";
22
+ /**
23
+ * Static p-stv-core accounts for the shared LUT. Order is deterministic so
24
+ * callers can cross-check against an on-chain LUT.
25
+ */
26
+ export declare function getPstvCoreLutAddresses(programId?: PublicKey): PublicKey[];
27
+ /**
28
+ * Build `extendLookupTable` ixs pushing every static p-stv-core account
29
+ * into `lutAddress`. Chunks at `MAX_ADDRS_PER_EXTEND` for safety.
30
+ *
31
+ * @param payer Wallet funding + authority of the LUT.
32
+ * @param lutAddress LUT to extend (must be created via
33
+ * `AddressLookupTableProgram.createLookupTable` first).
34
+ * @param programId Override for p-stv-core program ID (defaults to mainnet).
35
+ */
36
+ export declare function buildPstvCoreLutExtendIxs(payer: PublicKey, lutAddress: PublicKey, programId?: PublicKey): TransactionInstruction[];
37
+ /**
38
+ * Fetch an `AddressLookupTableAccount` by address for use in
39
+ * `TransactionMessage.compileToV0Message([lutAccount])`.
40
+ */
41
+ export declare function resolvePstvCoreLut(connection: Pick<Connection, "getAddressLookupTable">, lutAddress: PublicKey): Promise<AddressLookupTableAccount>;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ /**
3
+ * p-STV Core Address Lookup Table helpers.
4
+ *
5
+ * Packages the STATIC (per-program, not per-tx) p-stv-core accounts into a LUT
6
+ * so versioned transactions can compress them into a single 1-byte index.
7
+ *
8
+ * Usage:
9
+ * // Owner flow (one-time):
10
+ * const [createIx, lutAddress] = AddressLookupTableProgram.createLookupTable({...});
11
+ * const extendIxs = buildPstvCoreLutExtendIxs(payer, lutAddress);
12
+ * // send createIx + extendIxs
13
+ *
14
+ * // Consumer flow (every tx):
15
+ * const lutAccount = await resolvePstvCoreLut(connection, lutAddress);
16
+ * const msg = new TransactionMessage({...}).compileToV0Message([lutAccount]);
17
+ *
18
+ * NOTE: Only program IDs, the GlobalConfig PDA, and token/ATA/compute-budget
19
+ * program IDs. Per-vault PDAs (stv, evMint, vaultAta, withdrawRequest,
20
+ * managerRole) and strategy/lend state live in separate LUTs.
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.getPstvCoreLutAddresses = getPstvCoreLutAddresses;
24
+ exports.buildPstvCoreLutExtendIxs = buildPstvCoreLutExtendIxs;
25
+ exports.resolvePstvCoreLut = resolvePstvCoreLut;
26
+ const web3_js_1 = require("@solana/web3.js");
27
+ const spl_token_1 = require("@solana/spl-token");
28
+ const constants_1 = require("./constants");
29
+ const pda_1 = require("./pda");
30
+ /** Max addresses per `extendLookupTable` ix (Solana runtime limit). */
31
+ const MAX_ADDRS_PER_EXTEND = 20;
32
+ /**
33
+ * Static p-stv-core accounts for the shared LUT. Order is deterministic so
34
+ * callers can cross-check against an on-chain LUT.
35
+ */
36
+ function getPstvCoreLutAddresses(programId = constants_1.PROGRAM_ID) {
37
+ const [configPda] = (0, pda_1.findConfigPda)(programId);
38
+ return [
39
+ programId,
40
+ web3_js_1.SystemProgram.programId,
41
+ spl_token_1.TOKEN_PROGRAM_ID,
42
+ spl_token_1.TOKEN_2022_PROGRAM_ID,
43
+ spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID,
44
+ web3_js_1.ComputeBudgetProgram.programId,
45
+ configPda,
46
+ ];
47
+ }
48
+ /**
49
+ * Build `extendLookupTable` ixs pushing every static p-stv-core account
50
+ * into `lutAddress`. Chunks at `MAX_ADDRS_PER_EXTEND` for safety.
51
+ *
52
+ * @param payer Wallet funding + authority of the LUT.
53
+ * @param lutAddress LUT to extend (must be created via
54
+ * `AddressLookupTableProgram.createLookupTable` first).
55
+ * @param programId Override for p-stv-core program ID (defaults to mainnet).
56
+ */
57
+ function buildPstvCoreLutExtendIxs(payer, lutAddress, programId = constants_1.PROGRAM_ID) {
58
+ const addresses = getPstvCoreLutAddresses(programId);
59
+ const ixs = [];
60
+ for (let i = 0; i < addresses.length; i += MAX_ADDRS_PER_EXTEND) {
61
+ const chunk = addresses.slice(i, i + MAX_ADDRS_PER_EXTEND);
62
+ ixs.push(web3_js_1.AddressLookupTableProgram.extendLookupTable({
63
+ payer,
64
+ authority: payer,
65
+ lookupTable: lutAddress,
66
+ addresses: chunk,
67
+ }));
68
+ }
69
+ return ixs;
70
+ }
71
+ /**
72
+ * Fetch an `AddressLookupTableAccount` by address for use in
73
+ * `TransactionMessage.compileToV0Message([lutAccount])`.
74
+ */
75
+ async function resolvePstvCoreLut(connection, lutAddress) {
76
+ const { value } = await connection.getAddressLookupTable(lutAddress);
77
+ if (!value) {
78
+ throw new Error(`p-stv-core LUT not found at ${lutAddress.toBase58()} — create it first with buildPstvCoreLutExtendIxs`);
79
+ }
80
+ return value;
81
+ }
@@ -12,7 +12,6 @@ exports.findWsolAta = findWsolAta;
12
12
  exports.buildWrapSolIxs = buildWrapSolIxs;
13
13
  exports.buildUnwrapSolIx = buildUnwrapSolIx;
14
14
  const web3_js_1 = require("@solana/web3.js");
15
- const spl_token_1 = require("@solana/spl-token");
16
15
  const ata_1 = require("../common/ata");
17
16
  /** Native SOL mint (wrapped SOL) */
18
17
  exports.NATIVE_SOL_MINT = new web3_js_1.PublicKey("So11111111111111111111111111111111111111112");
@@ -39,15 +38,12 @@ function findWsolAta(owner) {
39
38
  function buildWrapSolIxs(payer, lamports) {
40
39
  const wsolAta = findWsolAta(payer);
41
40
  return [
42
- // Create wSOL ATA (idempotent)
43
- createAtaIxInternal(payer, exports.NATIVE_SOL_MINT, payer),
44
- // Transfer SOL to wSOL ATA
41
+ (0, ata_1.createIdempotentAtaIx)(payer, exports.NATIVE_SOL_MINT, payer, SPL_TOKEN_PROGRAM),
45
42
  web3_js_1.SystemProgram.transfer({
46
43
  fromPubkey: payer,
47
44
  toPubkey: wsolAta,
48
45
  lamports: BigInt(lamports),
49
46
  }),
50
- // Sync native balance
51
47
  new web3_js_1.TransactionInstruction({
52
48
  programId: SPL_TOKEN_PROGRAM,
53
49
  keys: [{ pubkey: wsolAta, isSigner: false, isWritable: true }],
@@ -76,19 +72,3 @@ function buildUnwrapSolIx(owner) {
76
72
  data: Buffer.from([9]),
77
73
  });
78
74
  }
79
- /** Internal: create ATA (idempotent) */
80
- function createAtaIxInternal(payer, mint, owner) {
81
- const ata = (0, ata_1.findAta)(mint, owner, SPL_TOKEN_PROGRAM);
82
- return new web3_js_1.TransactionInstruction({
83
- keys: [
84
- { pubkey: payer, isSigner: true, isWritable: true },
85
- { pubkey: ata, isSigner: false, isWritable: true },
86
- { pubkey: owner, isSigner: false, isWritable: false },
87
- { pubkey: mint, isSigner: false, isWritable: false },
88
- { pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
89
- { pubkey: SPL_TOKEN_PROGRAM, isSigner: false, isWritable: false },
90
- ],
91
- programId: spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID,
92
- data: Buffer.from([1]), // CreateIdempotent
93
- });
94
- }
@@ -16,7 +16,9 @@ export interface Stv {
16
16
  childVaults: BN[];
17
17
  vaultId: BN;
18
18
  reservedBase: BN;
19
- requestedBase: BN;
19
+ /** Pending withdrawal shares (sum across unprocessed WithdrawRequests).
20
+ * Display value: requestedShares × currentPps / PPS_DECIMALS. */
21
+ requestedShares: BN;
20
22
  vaultCapacity: BN;
21
23
  minDeposit: BN;
22
24
  hwm: BN;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elemental-stv-core/sdk",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "description": "TypeScript SDK for Elemental Vaults — p-STV Core, Elemental Lend, JLPD Strategy",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
@@ -46,6 +46,7 @@
46
46
  "scripts": {
47
47
  "build": "tsc",
48
48
  "clean": "rm -rf dist",
49
+ "test": "TS_NODE_TRANSPILE_ONLY=true mocha --require ts-node/register --extensions ts \"src/**/__tests__/**/*.test.ts\"",
49
50
  "prepublishOnly": "npm run clean && npm run build"
50
51
  },
51
52
  "dependencies": {
@@ -55,6 +56,11 @@
55
56
  "@solana/spl-token": "^0.4.0",
56
57
  "@solana/web3.js": "^1.95.0",
57
58
  "@types/bn.js": "^5.2.0",
59
+ "@types/chai": "^4.3.20",
60
+ "@types/mocha": "^10.0.10",
61
+ "chai": "^4.5.0",
62
+ "mocha": "^10.8.2",
63
+ "ts-node": "^10.9.2",
58
64
  "typescript": "^5.3.3"
59
65
  },
60
66
  "peerDependencies": {