@quartz-labs/sdk 0.0.8 → 0.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/dist/client.d.ts +4 -4
- package/dist/client.js +4 -4
- package/dist/config/constants.d.ts +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -4
- package/dist/interfaces/remainingAccount.interface.d.ts +5 -0
- package/dist/interfaces/remainingAccount.interface.js +1 -0
- package/dist/model/driftUser.d.ts +1 -1
- package/dist/model/driftUser.js +60 -31
- package/dist/services/driftClientService.d.ts +1 -1
- package/dist/user.d.ts +3 -3
- package/dist/user.js +7 -7
- package/dist/utils/helpers.d.ts +1 -6
- package/dist/utils/helpers.js +8 -4
- package/dist/utils/jupiter.d.ts +3 -2
- package/dist/utils/jupiter.js +1 -1
- package/package.json +3 -2
package/dist/client.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { DriftClient } from "@drift-labs/sdk";
|
|
2
2
|
import type { Quartz } from "./types/quartz.js";
|
|
3
|
-
import
|
|
4
|
-
import type {
|
|
5
|
-
import type { PublicKey } from "@solana/web3.js";
|
|
6
|
-
import
|
|
3
|
+
import { Program } from "@coral-xyz/anchor";
|
|
4
|
+
import type { Wallet } from "@coral-xyz/anchor";
|
|
5
|
+
import type { PublicKey, Connection, AddressLookupTableAccount } from "@solana/web3.js";
|
|
6
|
+
import { QuartzUser } from "./user.js";
|
|
7
7
|
export declare class QuartzClient {
|
|
8
8
|
private connection;
|
|
9
9
|
private wallet;
|
package/dist/client.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { fetchUserAccountsUsingKeys as fetchDriftAccountsUsingKeys } from "@drift-labs/sdk";
|
|
2
|
-
import { QUARTZ_ADDRESS_TABLE, QUARTZ_PROGRAM_ID } from "./config/constants";
|
|
2
|
+
import { QUARTZ_ADDRESS_TABLE, QUARTZ_PROGRAM_ID } from "./config/constants.js";
|
|
3
3
|
import quartzIdl from "./idl/quartz.json";
|
|
4
4
|
import { AnchorProvider, Program, setProvider } from "@coral-xyz/anchor";
|
|
5
5
|
import { PythSolanaReceiver } from "@pythnetwork/pyth-solana-receiver";
|
|
6
|
-
import { QuartzUser } from "./user";
|
|
7
|
-
import { getDriftUserPublicKey, getVaultPublicKey } from "./utils/helpers";
|
|
8
|
-
import { DriftClientService } from "./services/driftClientService";
|
|
6
|
+
import { QuartzUser } from "./user.js";
|
|
7
|
+
import { getDriftUserPublicKey, getVaultPublicKey } from "./utils/helpers.js";
|
|
8
|
+
import { DriftClientService } from "./services/driftClientService.js";
|
|
9
9
|
export class QuartzClient {
|
|
10
10
|
constructor(connection, wallet, program, quartzAddressTable, driftClient, oracles) {
|
|
11
11
|
this.connection = connection;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { QuartzClient } from "./client";
|
|
2
|
-
import { QuartzUser } from "./user";
|
|
3
|
-
export * from "./config/constants";
|
|
4
|
-
export * from "./utils/helpers";
|
|
1
|
+
import { QuartzClient } from "./client.js";
|
|
2
|
+
import { QuartzUser } from "./user.js";
|
|
3
|
+
export * from "./config/constants.js";
|
|
4
|
+
export * from "./utils/helpers.js";
|
|
5
5
|
export { QuartzClient, QuartzUser };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { QuartzClient } from "./client";
|
|
2
|
-
import { QuartzUser } from "./user";
|
|
3
|
-
export * from "./config/constants";
|
|
4
|
-
export * from "./utils/helpers";
|
|
1
|
+
import { QuartzClient } from "./client.js";
|
|
2
|
+
import { QuartzUser } from "./user.js";
|
|
3
|
+
export * from "./config/constants.js";
|
|
4
|
+
export * from "./utils/helpers.js";
|
|
5
5
|
export { QuartzClient, QuartzUser };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { BN, type DriftClient, type MarginCategory, type UserAccount } from "@drift-labs/sdk";
|
|
2
2
|
import type { Connection, PublicKey } from "@solana/web3.js";
|
|
3
3
|
export declare class DriftUser {
|
|
4
4
|
private isInitialized;
|
package/dist/model/driftUser.js
CHANGED
|
@@ -23,7 +23,7 @@ export class DriftUser {
|
|
|
23
23
|
this.isInitialized = true;
|
|
24
24
|
}
|
|
25
25
|
getDriftUserAccount() {
|
|
26
|
-
if (!this.isInitialized)
|
|
26
|
+
if (!this.isInitialized || !this.userAccount)
|
|
27
27
|
throw new Error("DriftUser not initialized");
|
|
28
28
|
return this.userAccount;
|
|
29
29
|
}
|
|
@@ -43,18 +43,22 @@ export class DriftUser {
|
|
|
43
43
|
return Math.round(Math.min(100, Math.max(0, (1 - maintenanceMarginReq.toNumber() / totalCollateral.toNumber()) * 100)));
|
|
44
44
|
}
|
|
45
45
|
getTokenAmount(marketIndex) {
|
|
46
|
-
if (!this.isInitialized)
|
|
46
|
+
if (!this.isInitialized || !this.userAccount)
|
|
47
47
|
throw new Error("DriftUser not initialized");
|
|
48
48
|
const spotPosition = this.userAccount.spotPositions.find((position) => position.marketIndex === marketIndex);
|
|
49
49
|
if (spotPosition === undefined) {
|
|
50
50
|
return ZERO;
|
|
51
51
|
}
|
|
52
52
|
const spotMarket = this.driftClient.getSpotMarketAccount(marketIndex);
|
|
53
|
+
if (!spotMarket)
|
|
54
|
+
throw new Error("Spot market not found");
|
|
53
55
|
return getSignedTokenAmount(getTokenAmount(spotPosition.scaledBalance, spotMarket, spotPosition.balanceType), spotPosition.balanceType);
|
|
54
56
|
}
|
|
55
57
|
getWithdrawalLimit(marketIndex, reduceOnly) {
|
|
56
58
|
const nowTs = new BN(Math.floor(Date.now() / 1000));
|
|
57
59
|
const spotMarket = this.driftClient.getSpotMarketAccount(marketIndex);
|
|
60
|
+
if (!spotMarket)
|
|
61
|
+
throw new Error("Spot market not found");
|
|
58
62
|
// eslint-disable-next-line prefer-const
|
|
59
63
|
let { borrowLimit, withdrawLimit } = calculateWithdrawLimit(spotMarket, nowTs);
|
|
60
64
|
const freeCollateral = this.getFreeCollateral();
|
|
@@ -80,20 +84,18 @@ export class DriftUser {
|
|
|
80
84
|
if (reduceOnly) {
|
|
81
85
|
return BN.max(maxWithdrawValue, ZERO);
|
|
82
86
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return BN.max(maxBorrowValue, ZERO);
|
|
96
|
-
}
|
|
87
|
+
const weightedAssetValue = this.getSpotMarketAssetValue('Initial', marketIndex, false);
|
|
88
|
+
const freeCollatAfterWithdraw = userDepositAmount.gt(ZERO)
|
|
89
|
+
? freeCollateral.sub(weightedAssetValue)
|
|
90
|
+
: freeCollateral;
|
|
91
|
+
const maxLiabilityAllowed = freeCollatAfterWithdraw
|
|
92
|
+
.mul(MARGIN_PRECISION)
|
|
93
|
+
.div(new BN(spotMarket.initialLiabilityWeight))
|
|
94
|
+
.mul(PRICE_PRECISION)
|
|
95
|
+
.div(oracleData.price)
|
|
96
|
+
.mul(precisionIncrease);
|
|
97
|
+
const maxBorrowValue = BN.min(maxWithdrawValue.add(maxLiabilityAllowed), borrowLimit.abs());
|
|
98
|
+
return BN.max(maxBorrowValue, ZERO);
|
|
97
99
|
}
|
|
98
100
|
getFreeCollateral(marginCategory = 'Initial') {
|
|
99
101
|
const totalCollateral = this.getTotalCollateral(marginCategory, true);
|
|
@@ -104,7 +106,11 @@ export class DriftUser {
|
|
|
104
106
|
return freeCollateral.gte(ZERO) ? freeCollateral : ZERO;
|
|
105
107
|
}
|
|
106
108
|
canBypassWithdrawLimits(marketIndex) {
|
|
109
|
+
if (!this.isInitialized || !this.userAccount)
|
|
110
|
+
throw new Error("DriftUser not initialized");
|
|
107
111
|
const spotMarket = this.driftClient.getSpotMarketAccount(marketIndex);
|
|
112
|
+
if (!spotMarket)
|
|
113
|
+
throw new Error("Spot market not found");
|
|
108
114
|
const maxDepositAmount = spotMarket.withdrawGuardThreshold.div(new BN(10));
|
|
109
115
|
const position = this.userAccount.spotPositions.find((position) => position.marketIndex === marketIndex);
|
|
110
116
|
const netDeposits = this.userAccount.totalDeposits.sub(this.userAccount.totalWithdraws);
|
|
@@ -141,6 +147,8 @@ export class DriftUser {
|
|
|
141
147
|
};
|
|
142
148
|
}
|
|
143
149
|
isBeingLiquidated() {
|
|
150
|
+
if (!this.isInitialized || !this.userAccount)
|
|
151
|
+
throw new Error("DriftUser not initialized");
|
|
144
152
|
return ((this.userAccount.status &
|
|
145
153
|
(UserStatus.BEING_LIQUIDATED | UserStatus.BANKRUPT)) >
|
|
146
154
|
0);
|
|
@@ -154,8 +162,9 @@ export class DriftUser {
|
|
|
154
162
|
const { totalAssetValue } = this.getSpotMarketAssetAndLiabilityValue(marginCategory, marketIndex, undefined, includeOpenOrders, strict, now);
|
|
155
163
|
return totalAssetValue;
|
|
156
164
|
}
|
|
157
|
-
getSpotMarketAssetAndLiabilityValue(marginCategory, marketIndex, liquidationBuffer, includeOpenOrders, strict = false, now) {
|
|
158
|
-
|
|
165
|
+
getSpotMarketAssetAndLiabilityValue(marginCategory, marketIndex, liquidationBuffer, includeOpenOrders, strict = false, now = new BN(new Date().getTime() / 1000)) {
|
|
166
|
+
if (!this.isInitialized || !this.userAccount)
|
|
167
|
+
throw new Error("DriftUser not initialized");
|
|
159
168
|
let netQuoteValue = ZERO;
|
|
160
169
|
let totalAssetValue = ZERO;
|
|
161
170
|
let totalLiabilityValue = ZERO;
|
|
@@ -169,6 +178,8 @@ export class DriftUser {
|
|
|
169
178
|
continue;
|
|
170
179
|
}
|
|
171
180
|
const spotMarketAccount = this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
|
|
181
|
+
if (!spotMarketAccount)
|
|
182
|
+
throw new Error("Spot market not found");
|
|
172
183
|
const oraclePriceData = this.driftClient.getOracleDataForSpotMarket(spotPosition.marketIndex);
|
|
173
184
|
let twap5min;
|
|
174
185
|
if (strict) {
|
|
@@ -196,12 +207,10 @@ export class DriftUser {
|
|
|
196
207
|
totalLiabilityValue = totalLiabilityValue.add(liabilityValue);
|
|
197
208
|
continue;
|
|
198
209
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
continue;
|
|
204
|
-
}
|
|
210
|
+
const tokenAmount = getTokenAmount(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType);
|
|
211
|
+
const assetValue = this.getSpotAssetValue(tokenAmount, strictOraclePrice, spotMarketAccount, marginCategory);
|
|
212
|
+
totalAssetValue = totalAssetValue.add(assetValue);
|
|
213
|
+
continue;
|
|
205
214
|
}
|
|
206
215
|
const { tokenAmount: worstCaseTokenAmount, ordersValue: worstCaseQuoteTokenAmount, } = getWorstCaseTokenAmounts(spotPosition, spotMarketAccount, strictOraclePrice, marginCategory, this.userAccount.maxMarginRatio);
|
|
207
216
|
if (worstCaseTokenAmount.gt(ZERO) && countForBase) {
|
|
@@ -239,6 +248,8 @@ export class DriftUser {
|
|
|
239
248
|
return { totalAssetValue, totalLiabilityValue };
|
|
240
249
|
}
|
|
241
250
|
getSpotLiabilityValue(tokenAmount, strictOraclePrice, spotMarketAccount, marginCategory, liquidationBuffer) {
|
|
251
|
+
if (!this.isInitialized || !this.userAccount)
|
|
252
|
+
throw new Error("DriftUser not initialized");
|
|
242
253
|
let liabilityValue = getStrictTokenValue(tokenAmount, spotMarketAccount.decimals, strictOraclePrice);
|
|
243
254
|
if (marginCategory !== undefined) {
|
|
244
255
|
let weight = calculateLiabilityWeight(tokenAmount, spotMarketAccount, marginCategory);
|
|
@@ -256,6 +267,8 @@ export class DriftUser {
|
|
|
256
267
|
return liabilityValue;
|
|
257
268
|
}
|
|
258
269
|
getSpotAssetValue(tokenAmount, strictOraclePrice, spotMarketAccount, marginCategory) {
|
|
270
|
+
if (!this.isInitialized || !this.userAccount)
|
|
271
|
+
throw new Error("DriftUser not initialized");
|
|
259
272
|
let assetValue = getStrictTokenValue(tokenAmount, spotMarketAccount.decimals, strictOraclePrice);
|
|
260
273
|
if (marginCategory !== undefined) {
|
|
261
274
|
let weight = calculateAssetWeight(tokenAmount, strictOraclePrice.current, spotMarketAccount, marginCategory);
|
|
@@ -273,8 +286,12 @@ export class DriftUser {
|
|
|
273
286
|
.filter((pos) => marketIndex !== undefined ? pos.marketIndex === marketIndex : true)
|
|
274
287
|
.reduce((unrealizedPnl, perpPosition) => {
|
|
275
288
|
const market = this.driftClient.getPerpMarketAccount(perpPosition.marketIndex);
|
|
289
|
+
if (!market)
|
|
290
|
+
throw new Error("Perp market not found");
|
|
276
291
|
const oraclePriceData = this.driftClient.getOracleDataForPerpMarket(market.marketIndex);
|
|
277
292
|
const quoteSpotMarket = this.driftClient.getSpotMarketAccount(market.quoteSpotMarketIndex);
|
|
293
|
+
if (!quoteSpotMarket)
|
|
294
|
+
throw new Error("Quote spot market not found");
|
|
278
295
|
const quoteOraclePriceData = this.driftClient.getOracleDataForSpotMarket(market.quoteSpotMarketIndex);
|
|
279
296
|
if (perpPosition.lpShares.gt(ZERO)) {
|
|
280
297
|
perpPosition = this.getPerpPositionWithLPSettle(perpPosition.marketIndex, undefined, !!withWeightMarginCategory)[0];
|
|
@@ -304,9 +321,11 @@ export class DriftUser {
|
|
|
304
321
|
}, ZERO);
|
|
305
322
|
}
|
|
306
323
|
getActivePerpPositions() {
|
|
324
|
+
if (!this.isInitialized || !this.userAccount)
|
|
325
|
+
throw new Error("DriftUser not initialized");
|
|
307
326
|
return this.userAccount.perpPositions.filter((pos) => !pos.baseAssetAmount.eq(ZERO) ||
|
|
308
327
|
!pos.quoteAssetAmount.eq(ZERO) ||
|
|
309
|
-
!(pos.openOrders
|
|
328
|
+
!(pos.openOrders === 0) ||
|
|
310
329
|
!pos.lpShares.eq(ZERO));
|
|
311
330
|
}
|
|
312
331
|
getPerpPositionWithLPSettle(marketIndex, originalPosition, burnLpShares = false, includeRemainderInBaseAmount = false) {
|
|
@@ -319,7 +338,9 @@ export class DriftUser {
|
|
|
319
338
|
}
|
|
320
339
|
const position = this.getClonedPosition(originalPosition);
|
|
321
340
|
const market = this.driftClient.getPerpMarketAccount(position.marketIndex);
|
|
322
|
-
if (market
|
|
341
|
+
if (!market)
|
|
342
|
+
throw new Error("Perp market not found");
|
|
343
|
+
if (market.amm.perLpBase !== position.perLpBase) {
|
|
323
344
|
// perLpBase = 1 => per 10 LP shares, perLpBase = -1 => per 0.1 LP shares
|
|
324
345
|
const expoDiff = market.amm.perLpBase - position.perLpBase;
|
|
325
346
|
const marketPerLpRebaseScalar = new BN(10 ** Math.abs(expoDiff));
|
|
@@ -341,7 +362,7 @@ export class DriftUser {
|
|
|
341
362
|
// incorp unsettled funding on pre settled position
|
|
342
363
|
const quoteFundingPnl = calculateUnsettledFundingPnl(market, position);
|
|
343
364
|
let baseUnit = AMM_RESERVE_PRECISION;
|
|
344
|
-
if (market.amm.perLpBase
|
|
365
|
+
if (market.amm.perLpBase === position.perLpBase) {
|
|
345
366
|
if (position.perLpBase >= 0 &&
|
|
346
367
|
position.perLpBase <= AMM_RESERVE_PRECISION_EXP.toNumber()) {
|
|
347
368
|
const marketPerLpRebase = new BN(10 ** market.amm.perLpBase);
|
|
@@ -385,7 +406,7 @@ export class DriftUser {
|
|
|
385
406
|
position.remainderBaseAssetAmount = newRemainderBaa.toNumber();
|
|
386
407
|
}
|
|
387
408
|
let dustBaseAssetValue = ZERO;
|
|
388
|
-
if (burnLpShares && position.remainderBaseAssetAmount
|
|
409
|
+
if (burnLpShares && position.remainderBaseAssetAmount !== 0) {
|
|
389
410
|
const oraclePriceData = this.driftClient.getOracleDataForPerpMarket(position.marketIndex);
|
|
390
411
|
dustBaseAssetValue = new BN(Math.abs(position.remainderBaseAssetAmount))
|
|
391
412
|
.mul(oraclePriceData.price)
|
|
@@ -410,11 +431,11 @@ export class DriftUser {
|
|
|
410
431
|
}
|
|
411
432
|
let newQuoteEntry;
|
|
412
433
|
let pnl;
|
|
413
|
-
if (updateType
|
|
434
|
+
if (updateType === 'open' || updateType === 'increase') {
|
|
414
435
|
newQuoteEntry = position.quoteEntryAmount.add(deltaQaa);
|
|
415
436
|
pnl = ZERO;
|
|
416
437
|
}
|
|
417
|
-
else if (updateType
|
|
438
|
+
else if (updateType === 'reduce' || updateType === 'close') {
|
|
418
439
|
newQuoteEntry = position.quoteEntryAmount.sub(position.quoteEntryAmount
|
|
419
440
|
.mul(deltaBaa.abs())
|
|
420
441
|
.div(position.baseAssetAmount.abs()));
|
|
@@ -463,9 +484,11 @@ export class DriftUser {
|
|
|
463
484
|
return [position, remainderBeforeRemoval, pnl];
|
|
464
485
|
}
|
|
465
486
|
getPerpPosition(marketIndex) {
|
|
487
|
+
if (!this.isInitialized || !this.userAccount)
|
|
488
|
+
throw new Error("DriftUser not initialized");
|
|
466
489
|
const activePositions = this.userAccount.perpPositions.filter((pos) => !pos.baseAssetAmount.eq(ZERO) ||
|
|
467
490
|
!pos.quoteAssetAmount.eq(ZERO) ||
|
|
468
|
-
!(pos.openOrders
|
|
491
|
+
!(pos.openOrders === 0) ||
|
|
469
492
|
!pos.lpShares.eq(ZERO));
|
|
470
493
|
return activePositions.find((position) => position.marketIndex === marketIndex);
|
|
471
494
|
}
|
|
@@ -512,7 +535,11 @@ export class DriftUser {
|
|
|
512
535
|
}, ZERO);
|
|
513
536
|
}
|
|
514
537
|
calculateWeightedPerpPositionLiability(perpPosition, marginCategory, liquidationBuffer, includeOpenOrders, strict = false) {
|
|
538
|
+
if (!this.isInitialized || !this.userAccount)
|
|
539
|
+
throw new Error("DriftUser not initialized");
|
|
515
540
|
const market = this.driftClient.getPerpMarketAccount(perpPosition.marketIndex);
|
|
541
|
+
if (!market)
|
|
542
|
+
throw new Error("Perp market not found");
|
|
516
543
|
if (perpPosition.lpShares.gt(ZERO)) {
|
|
517
544
|
// is an lp, clone so we dont mutate the position
|
|
518
545
|
perpPosition = this.getPerpPositionWithLPSettle(market.marketIndex, this.getClonedPosition(perpPosition), !!marginCategory)[0];
|
|
@@ -541,6 +568,8 @@ export class DriftUser {
|
|
|
541
568
|
marginRatio = ZERO;
|
|
542
569
|
}
|
|
543
570
|
const quoteSpotMarket = this.driftClient.getSpotMarketAccount(market.quoteSpotMarketIndex);
|
|
571
|
+
if (!quoteSpotMarket)
|
|
572
|
+
throw new Error("Quote spot market not found");
|
|
544
573
|
const quoteOraclePriceData = this.driftClient.getOracleDataForSpotMarket(QUOTE_SPOT_MARKET_INDEX);
|
|
545
574
|
let quotePrice;
|
|
546
575
|
if (strict) {
|
package/dist/user.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { AddressLookupTableAccount, PublicKey, TransactionInstruction } from "@solana/web3.js";
|
|
2
1
|
import type { DriftClient, QuoteResponse, UserAccount } from "@drift-labs/sdk";
|
|
3
|
-
import type { Connection } from "@solana/web3.js";
|
|
4
|
-
import type { Quartz } from "./types/quartz";
|
|
2
|
+
import type { Connection, AddressLookupTableAccount, TransactionInstruction } from "@solana/web3.js";
|
|
3
|
+
import type { Quartz } from "./types/quartz.js";
|
|
5
4
|
import type { Program } from "@coral-xyz/anchor";
|
|
5
|
+
import { PublicKey } from "@solana/web3.js";
|
|
6
6
|
export declare class QuartzUser {
|
|
7
7
|
readonly pubkey: PublicKey;
|
|
8
8
|
readonly vaultPubkey: PublicKey;
|
package/dist/user.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { DriftUser } from "./model/driftUser";
|
|
1
|
+
import { DriftUser } from "./model/driftUser.js";
|
|
3
2
|
import { BN, DRIFT_PROGRAM_ID } from "@drift-labs/sdk";
|
|
4
|
-
import { getDriftSpotMarketPublicKey, getDriftStatePublicKey, getVaultPublicKey, getVaultSplPublicKey } from "./utils/helpers";
|
|
5
|
-
import { DRIFT_MARKET_INDEX_SOL, DRIFT_MARKET_INDEX_USDC, QUARTZ_HEALTH_BUFFER, USDC_MINT, WSOL_MINT } from "./config/constants";
|
|
3
|
+
import { getDriftSpotMarketPublicKey, getDriftStatePublicKey, getVaultPublicKey, getVaultSplPublicKey } from "./utils/helpers.js";
|
|
4
|
+
import { DRIFT_MARKET_INDEX_SOL, DRIFT_MARKET_INDEX_USDC, QUARTZ_HEALTH_BUFFER, USDC_MINT, WSOL_MINT } from "./config/constants.js";
|
|
6
5
|
import { TOKEN_PROGRAM_ID } from "@coral-xyz/anchor/dist/cjs/utils/token";
|
|
7
6
|
import { ASSOCIATED_TOKEN_PROGRAM_ID } from "@solana/spl-token";
|
|
8
7
|
import { SwapMode } from "@jup-ag/api";
|
|
9
|
-
import { getJupiterSwapIx } from "./utils/jupiter";
|
|
8
|
+
import { getJupiterSwapIx } from "./utils/jupiter.js";
|
|
9
|
+
import { PublicKey, SystemProgram, SYSVAR_INSTRUCTIONS_PUBKEY } from "@solana/web3.js";
|
|
10
10
|
export class QuartzUser {
|
|
11
11
|
constructor(pubkey, connection, program, quartzLookupTable, oracles, driftClient, driftUserAccount) {
|
|
12
12
|
this.pubkey = pubkey;
|
|
@@ -40,9 +40,9 @@ export class QuartzUser {
|
|
|
40
40
|
//
|
|
41
41
|
// The following is an algebraicly simplified expression of the above formula, in terms of repayAmount
|
|
42
42
|
if (targetHealth <= 0 || targetHealth >= 100)
|
|
43
|
-
throw Error(
|
|
43
|
+
throw Error("Target health must be between 0 and 100");
|
|
44
44
|
if (targetHealth <= this.getHealth())
|
|
45
|
-
throw Error(
|
|
45
|
+
throw Error("Target health must be greater than current health");
|
|
46
46
|
const currentWeightedCollateral = this.getTotalWeightedCollateral();
|
|
47
47
|
const loanValue = this.getMaintenanceMarginRequirement();
|
|
48
48
|
return Math.round((loanValue - currentWeightedCollateral * (1 - QUARTZ_HEALTH_BUFFER) * (1 - targetHealth)) / (1 - repayCollateralWeight * (1 - QUARTZ_HEALTH_BUFFER) * (1 - targetHealth)));
|
package/dist/utils/helpers.d.ts
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { PublicKey } from "@solana/web3.js";
|
|
2
2
|
export declare const getVaultPublicKey: (user: PublicKey) => PublicKey;
|
|
3
3
|
export declare const getVaultSplPublicKey: (user: PublicKey, mint: PublicKey) => PublicKey;
|
|
4
4
|
export declare const getDriftUserPublicKey: (vaultPda: PublicKey) => PublicKey;
|
|
5
5
|
export declare const getDriftUserStatsPublicKey: (vaultPda: PublicKey) => PublicKey;
|
|
6
6
|
export declare const getDriftStatePublicKey: () => PublicKey;
|
|
7
7
|
export declare const getDriftSpotMarketPublicKey: (marketIndex: number) => PublicKey;
|
|
8
|
-
export declare const toRemainingAccount: (pubkey: PublicKey, isWritable: boolean, isSigner: boolean) => {
|
|
9
|
-
pubkey: PublicKey;
|
|
10
|
-
isWritable: boolean;
|
|
11
|
-
isSigner: boolean;
|
|
12
|
-
};
|
package/dist/utils/helpers.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PublicKey } from "@solana/web3.js";
|
|
2
|
-
import { QUARTZ_PROGRAM_ID } from "../config/constants";
|
|
2
|
+
import { QUARTZ_PROGRAM_ID } from "../config/constants.js";
|
|
3
3
|
import { BN } from "@coral-xyz/anchor";
|
|
4
4
|
import { DRIFT_PROGRAM_ID } from "@drift-labs/sdk";
|
|
5
5
|
export const getVaultPublicKey = (user) => {
|
|
@@ -34,6 +34,10 @@ export const getDriftSpotMarketPublicKey = (marketIndex) => {
|
|
|
34
34
|
], new PublicKey(DRIFT_PROGRAM_ID));
|
|
35
35
|
return spotMarketVaultPda;
|
|
36
36
|
};
|
|
37
|
-
export const toRemainingAccount = (
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
// export const toRemainingAccount = (
|
|
38
|
+
// pubkey: PublicKey,
|
|
39
|
+
// isWritable: boolean,
|
|
40
|
+
// isSigner: boolean
|
|
41
|
+
// ) => {
|
|
42
|
+
// return { pubkey, isWritable, isSigner }
|
|
43
|
+
// }
|
package/dist/utils/jupiter.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Connection } from "@solana/web3.js";
|
|
2
|
+
import { PublicKey, TransactionInstruction } from "@solana/web3.js";
|
|
2
3
|
import type { QuoteResponse } from "@jup-ag/api";
|
|
3
|
-
import
|
|
4
|
+
import { AddressLookupTableAccount } from "@solana/web3.js";
|
|
4
5
|
export declare function getJupiterSwapIx(walletPubkey: PublicKey, connection: Connection, quoteResponse: QuoteResponse): Promise<{
|
|
5
6
|
ix_jupiterSwap: TransactionInstruction;
|
|
6
7
|
jupiterLookupTables: AddressLookupTableAccount[];
|
package/dist/utils/jupiter.js
CHANGED
|
@@ -13,7 +13,7 @@ export async function getJupiterSwapIx(walletPubkey, connection, quoteResponse)
|
|
|
13
13
|
})
|
|
14
14
|
})).json();
|
|
15
15
|
if (instructions.error) {
|
|
16
|
-
throw new Error(
|
|
16
|
+
throw new Error(`Failed to get swap instructions: ${instructions.error}`);
|
|
17
17
|
}
|
|
18
18
|
const { swapInstruction, addressLookupTableAddresses } = instructions;
|
|
19
19
|
const getAddressLookupTableAccounts = async (keys) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quartz-labs/sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"description": "SDK for interacting with the Quartz Protocol",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
],
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "tsc",
|
|
12
|
-
"test": "jest"
|
|
12
|
+
"test": "jest",
|
|
13
|
+
"deploy": "tsc && npm publish"
|
|
13
14
|
},
|
|
14
15
|
"repository": {
|
|
15
16
|
"type": "git",
|