@quartz-labs/sdk 0.0.2 → 0.0.3

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 (36) hide show
  1. package/{build → dist}/client.d.ts +1 -1
  2. package/{build → dist}/client.js +5 -5
  3. package/{build → dist}/config/constants.d.ts +2 -0
  4. package/{src/config/constants.ts → dist/config/constants.js} +1 -5
  5. package/{src/index.ts → dist/index.d.ts} +1 -2
  6. package/{build → dist}/index.js +1 -1
  7. package/{build → dist}/model/driftUser.d.ts +3 -0
  8. package/{build → dist}/model/driftUser.js +9 -2
  9. package/dist/user.d.ts +25 -0
  10. package/dist/user.js +158 -0
  11. package/dist/utils/helpers.d.ts +12 -0
  12. package/{build → dist/utils}/helpers.js +8 -8
  13. package/dist/utils/jupiter.d.ts +7 -0
  14. package/dist/utils/jupiter.js +48 -0
  15. package/package.json +6 -3
  16. package/build/config/constants.js +0 -7
  17. package/build/helpers.d.ts +0 -12
  18. package/build/index.d.ts +0 -4
  19. package/build/user.d.ts +0 -16
  20. package/build/user.js +0 -47
  21. package/jest.config.js +0 -4
  22. package/src/client.ts +0 -119
  23. package/src/idl/quartz.json +0 -646
  24. package/src/model/driftUser.ts +0 -1066
  25. package/src/services/driftClientService.ts +0 -37
  26. package/src/tests/helpers.test.ts +0 -48
  27. package/src/types/quartz.ts +0 -1293
  28. package/src/user.ts +0 -227
  29. package/src/utils/helpers.ts +0 -68
  30. package/src/utils/jupiter.ts +0 -73
  31. package/tsconfig.json +0 -17
  32. /package/{build → dist}/idl/quartz.json +0 -0
  33. /package/{build → dist}/services/driftClientService.d.ts +0 -0
  34. /package/{build → dist}/services/driftClientService.js +0 -0
  35. /package/{build → dist}/types/quartz.d.ts +0 -0
  36. /package/{build → dist}/types/quartz.js +0 -0
package/src/user.ts DELETED
@@ -1,227 +0,0 @@
1
- import { AddressLookupTableAccount, PublicKey, SystemProgram, SYSVAR_INSTRUCTIONS_PUBKEY, TransactionInstruction } from "@solana/web3.js";
2
- import { DriftUser } from "./model/driftUser";
3
- import { BN, DRIFT_PROGRAM_ID, DriftClient, getSpotMarketPublicKey, QuoteResponse, UserAccount } from "@drift-labs/sdk";
4
- import { getDriftSpotMarketPublicKey, getDriftStatePublicKey, getVaultPublicKey, getVaultSplPublicKey, toRemainingAccount } from "./utils/helpers";
5
- import { Connection } from "@solana/web3.js";
6
- import { DRIFT_MARKET_INDEX_SOL, DRIFT_MARKET_INDEX_USDC, QUARTZ_HEALTH_BUFFER, USDC_MINT, WSOL_MINT } from "./config/constants";
7
- import { Quartz } from "./types/quartz";
8
- import { Program } from "@coral-xyz/anchor";
9
- import { TOKEN_PROGRAM_ID } from "@coral-xyz/anchor/dist/cjs/utils/token";
10
- import { ASSOCIATED_TOKEN_PROGRAM_ID } from "@solana/spl-token";
11
- import { SwapMode } from "@jup-ag/api";
12
- import { getJupiterSwapIx } from "./utils/jupiter";
13
-
14
- export class QuartzUser {
15
- private pubkey: PublicKey;
16
- private vaultPubkey: PublicKey;
17
-
18
- private connection: Connection;
19
- private program: Program<Quartz>;
20
- private quartzLookupTable: AddressLookupTableAccount;
21
- private oracles: Map<string, PublicKey>;
22
-
23
- private driftClient: DriftClient;
24
- private driftUser: DriftUser;
25
-
26
- constructor(
27
- pubkey: PublicKey,
28
- connection: Connection,
29
- program: Program<Quartz>,
30
- quartzLookupTable: AddressLookupTableAccount,
31
- oracles: Map<string, PublicKey>,
32
- driftClient: DriftClient,
33
- driftUserAccount?: UserAccount
34
- ) {
35
- this.pubkey = pubkey;
36
- this.vaultPubkey = getVaultPublicKey(pubkey);
37
- this.connection = connection;
38
- this.program = program;
39
- this.quartzLookupTable = quartzLookupTable;
40
- this.oracles = oracles;
41
- this.driftClient = driftClient;
42
- this.driftUser = new DriftUser(this.vaultPubkey, connection, driftClient, driftUserAccount);
43
- }
44
-
45
- private convertToQuartzHealth(protocolHealth: number): number {
46
- if (protocolHealth <= 0) return 0;
47
- if (protocolHealth >= 100) return 100;
48
-
49
- return Math.floor(
50
- Math.min(
51
- 100,
52
- Math.max(
53
- 0,
54
- (protocolHealth - QUARTZ_HEALTH_BUFFER) / (1 - QUARTZ_HEALTH_BUFFER)
55
- )
56
- )
57
- );
58
- }
59
-
60
- public getHealth(): number {
61
- const driftHealth = this.driftUser.getHealth();
62
- return this.convertToQuartzHealth(driftHealth);
63
- }
64
-
65
- public getRepayAmountForTargetHealth(
66
- targetHealth: number,
67
- repayCollateralWeight: number
68
- ): number {
69
- // New Quartz health after repayment is given as:
70
- //
71
- // loanValue - repayAmount
72
- // 1 - ----------------------------------------------------------------- - quartzHealthBuffer
73
- // currentWeightedCollateral - (repayAmount * repayCollateralWeight)
74
- // targetHealth = -------------------------------------------------------------------------------------------
75
- // 1 - quartzHealthBuffer
76
- //
77
- // The following is an algebraicly simplified expression of the above formula, in terms of repayAmount
78
-
79
- if (targetHealth <= 0 || targetHealth >= 100) throw Error(`Target health must be between 0 and 100`);
80
- if (targetHealth <= this.getHealth()) throw Error(`Target health must be greater than current health`);
81
-
82
- const currentWeightedCollateral = this.getTotalWeightedCollateral();
83
- const loanValue = this.getMaintenanceMarginRequirement();
84
-
85
- return Math.round(
86
- (
87
- loanValue - currentWeightedCollateral * (1 - QUARTZ_HEALTH_BUFFER) * (1 - targetHealth)
88
- ) / (
89
- 1 - repayCollateralWeight * (1 - QUARTZ_HEALTH_BUFFER) * (1 - targetHealth)
90
- )
91
- );
92
- }
93
-
94
- public getTotalWeightedCollateral(): number {
95
- return this.driftUser.getTotalCollateral('Maintenance').toNumber();
96
- }
97
-
98
- public getMaintenanceMarginRequirement(): number {
99
- return this.driftUser.getMaintenanceMarginRequirement().toNumber();
100
- }
101
-
102
- public async makeCollateralRepayIxs(
103
- caller: PublicKey,
104
- callerDepositSpl: PublicKey,
105
- callerWithdrawSpl: PublicKey,
106
- callerStartingDepositBalance: number,
107
- jupiterExactOutRouteQuote: QuoteResponse
108
- ): Promise<{
109
- ixs: TransactionInstruction[]
110
- lookupTables: AddressLookupTableAccount[],
111
- }> {
112
- const depositMint = USDC_MINT;
113
- const depositMarketIndex = DRIFT_MARKET_INDEX_USDC;
114
- const withdrawMint = WSOL_MINT;
115
- const withdrawMarketIndex = DRIFT_MARKET_INDEX_SOL;
116
-
117
- if (jupiterExactOutRouteQuote.swapMode !== SwapMode.ExactOut) throw Error("Jupiter quote must be ExactOutRoute");
118
- if (jupiterExactOutRouteQuote.inputMint !== withdrawMint.toBase58()) throw Error("Jupiter quote inputMint does not match withdrawMint");
119
- if (jupiterExactOutRouteQuote.outputMint !== depositMint.toBase58()) throw Error("Jupiter quote outputMint does not match depositMint");
120
-
121
- const driftState = getDriftStatePublicKey();
122
- const driftSpotMarketDeposit = getDriftSpotMarketPublicKey(depositMarketIndex);
123
- const driftSpotMarketWithdraw = getDriftSpotMarketPublicKey(withdrawMarketIndex);
124
-
125
- const autoRepayStartPromise = this.program.methods
126
- .autoRepayStart(new BN(callerStartingDepositBalance))
127
- .accounts({
128
- caller: caller,
129
- callerWithdrawSpl: callerWithdrawSpl,
130
- withdrawMint: withdrawMint,
131
- vault: this.vaultPubkey,
132
- vaultWithdrawSpl: getVaultSplPublicKey(this.vaultPubkey, withdrawMint),
133
- owner: this.pubkey,
134
- tokenProgram: TOKEN_PROGRAM_ID,
135
- associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
136
- systemProgram: SystemProgram.programId,
137
- instructions: SYSVAR_INSTRUCTIONS_PUBKEY,
138
- })
139
- .instruction();
140
-
141
- const jupiterSwapPromise = getJupiterSwapIx(caller, this.connection, jupiterExactOutRouteQuote);
142
-
143
- const autoRepayDepositPromise = this.program.methods
144
- .autoRepayDeposit(depositMarketIndex)
145
- .accounts({
146
- vault: this.vaultPubkey,
147
- vaultSpl: getVaultSplPublicKey(this.vaultPubkey, depositMint),
148
- owner: this.pubkey,
149
- caller: caller,
150
- callerSpl: callerDepositSpl,
151
- splMint: depositMint,
152
- driftUser: this.driftUser.pubkey,
153
- driftUserStats: this.driftUser.statsPubkey,
154
- driftState: driftState,
155
- spotMarketVault: driftSpotMarketDeposit,
156
- tokenProgram: TOKEN_PROGRAM_ID,
157
- associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
158
- driftProgram: new PublicKey(DRIFT_PROGRAM_ID),
159
- systemProgram: SystemProgram.programId,
160
- instructions: SYSVAR_INSTRUCTIONS_PUBKEY,
161
- })
162
- .remainingAccounts(
163
- this.driftClient.getRemainingAccounts({
164
- userAccounts: [this.driftUser.getDriftUserAccount()],
165
- useMarketLastSlotCache: true,
166
- writableSpotMarketIndexes: [depositMarketIndex],
167
- })
168
- )
169
- .instruction();
170
-
171
- const autoRepayWithdrawPromise = this.program.methods
172
- .autoRepayWithdraw(withdrawMarketIndex)
173
- .accounts({
174
- vault: this.vaultPubkey,
175
- vaultSpl: getVaultSplPublicKey(this.vaultPubkey, withdrawMint),
176
- owner: this.pubkey,
177
- caller: caller,
178
- callerSpl: callerWithdrawSpl,
179
- splMint: withdrawMint,
180
- driftUser: this.driftUser.pubkey,
181
- driftUserStats: this.driftUser.statsPubkey,
182
- driftState: driftState,
183
- spotMarketVault: driftSpotMarketWithdraw,
184
- driftSigner: this.driftClient.getSignerPublicKey(),
185
- tokenProgram: TOKEN_PROGRAM_ID,
186
- driftProgram: DRIFT_PROGRAM_ID,
187
- systemProgram: SystemProgram.programId,
188
- depositPriceUpdate: this.oracles.get("USDC/USD"),
189
- withdrawPriceUpdate: this.oracles.get("SOL/USD"),
190
- instructions: SYSVAR_INSTRUCTIONS_PUBKEY,
191
- })
192
- .remainingAccounts(
193
- this.driftClient.getRemainingAccounts({
194
- userAccounts: [this.driftUser.getDriftUserAccount()],
195
- useMarketLastSlotCache: true,
196
- writableSpotMarketIndexes: [withdrawMarketIndex],
197
- readableSpotMarketIndexes: [DRIFT_MARKET_INDEX_USDC], // Quote is in USDC
198
- })
199
- )
200
- .instruction();
201
-
202
- const [
203
- ix_autoRepayStart,
204
- { ix_jupiterSwap, jupiterLookupTables },
205
- ix_autoRepayDeposit,
206
- ix_autoRepayWithdraw
207
- ] = await Promise.all([
208
- autoRepayStartPromise,
209
- jupiterSwapPromise,
210
- autoRepayDepositPromise,
211
- autoRepayWithdrawPromise
212
- ]);
213
-
214
- return {
215
- ixs: [
216
- ix_autoRepayStart,
217
- ix_jupiterSwap,
218
- ix_autoRepayDeposit,
219
- ix_autoRepayWithdraw
220
- ],
221
- lookupTables: [
222
- this.quartzLookupTable,
223
- ...jupiterLookupTables
224
- ],
225
- };
226
- }
227
- }
@@ -1,68 +0,0 @@
1
- import { PublicKey } from "@solana/web3.js";
2
- import { QUARTZ_PROGRAM_ID } from "../config/constants";
3
- import { BN } from "@coral-xyz/anchor";
4
- import { DRIFT_PROGRAM_ID } from "@drift-labs/sdk";
5
-
6
- export const getVaultPublicKey = (user: PublicKey) => {
7
- const [vaultPda] = PublicKey.findProgramAddressSync(
8
- [Buffer.from("vault"), user.toBuffer()],
9
- QUARTZ_PROGRAM_ID
10
- )
11
- return vaultPda;
12
- }
13
-
14
- export const getVaultSplPublicKey = (user: PublicKey, mint: PublicKey) => {
15
- const vaultPda = getVaultPublicKey(user);
16
- const [vaultSplPda] = PublicKey.findProgramAddressSync(
17
- [vaultPda.toBuffer(), mint.toBuffer()],
18
- QUARTZ_PROGRAM_ID
19
- );
20
- return vaultSplPda;
21
- }
22
-
23
- export const getDriftUserPublicKey = (vaultPda: PublicKey) => {
24
- const [userPda] = PublicKey.findProgramAddressSync(
25
- [
26
- Buffer.from("user"),
27
- vaultPda.toBuffer(),
28
- new BN(0).toArrayLike(Buffer, 'le', 2),
29
- ],
30
- new PublicKey(DRIFT_PROGRAM_ID)
31
- );
32
- return userPda;
33
- }
34
-
35
- export const getDriftUserStatsPublicKey = (vaultPda: PublicKey) => {
36
- const [userStatsPda] = PublicKey.findProgramAddressSync(
37
- [Buffer.from("user_stats"), vaultPda.toBuffer()],
38
- new PublicKey(DRIFT_PROGRAM_ID)
39
- );
40
- return userStatsPda;
41
- }
42
-
43
- export const getDriftStatePublicKey = () => {
44
- const [statePda] = PublicKey.findProgramAddressSync(
45
- [Buffer.from("drift_state")],
46
- new PublicKey(DRIFT_PROGRAM_ID)
47
- );
48
- return statePda;
49
- }
50
-
51
- export const getDriftSpotMarketPublicKey = (marketIndex: number) => {
52
- const [spotMarketVaultPda] = PublicKey.findProgramAddressSync(
53
- [
54
- Buffer.from("spot_market_vault"),
55
- new BN(marketIndex).toArrayLike(Buffer, 'le', 2)
56
- ],
57
- new PublicKey(DRIFT_PROGRAM_ID)
58
- );
59
- return spotMarketVaultPda;
60
- }
61
-
62
- export const toRemainingAccount = (
63
- pubkey: PublicKey,
64
- isWritable: boolean,
65
- isSigner: boolean
66
- ) => {
67
- return { pubkey, isWritable, isSigner }
68
- }
@@ -1,73 +0,0 @@
1
- import { PublicKey, Connection, TransactionInstruction } from "@solana/web3.js";
2
- import { QuoteResponse } from "@jup-ag/api";
3
- import { AddressLookupTableAccount } from "@solana/web3.js";
4
-
5
- export async function getJupiterSwapIx(
6
- walletPubkey: PublicKey,
7
- connection: Connection,
8
- quoteResponse: QuoteResponse
9
- ): Promise<{
10
- ix_jupiterSwap: TransactionInstruction,
11
- jupiterLookupTables: AddressLookupTableAccount[]
12
- }> {
13
- const instructions = await (
14
- await fetch('https://quote-api.jup.ag/v6/swap-instructions', {
15
- method: 'POST',
16
- headers: {
17
- 'Content-Type': 'application/json'
18
- },
19
- body: JSON.stringify({
20
- quoteResponse,
21
- userPublicKey: walletPubkey.toBase58(),
22
- useCompression: true,
23
- })
24
- })
25
- ).json();
26
-
27
- if (instructions.error) {
28
- throw new Error("Failed to get swap instructions: " + instructions.error);
29
- }
30
- const { swapInstruction, addressLookupTableAddresses } = instructions;
31
-
32
- const getAddressLookupTableAccounts = async (
33
- keys: string[]
34
- ): Promise<AddressLookupTableAccount[]> => {
35
- const addressLookupTableAccountInfos =
36
- await connection.getMultipleAccountsInfo(
37
- keys.map((key) => new PublicKey(key))
38
- );
39
-
40
- return addressLookupTableAccountInfos.reduce((acc: any, accountInfo: any, index: any) => {
41
- const addressLookupTableAddress = keys[index];
42
- if (accountInfo) {
43
- const addressLookupTableAccount = new AddressLookupTableAccount({
44
- key: new PublicKey(addressLookupTableAddress),
45
- state: AddressLookupTableAccount.deserialize(accountInfo.data),
46
- });
47
- acc.push(addressLookupTableAccount);
48
- }
49
-
50
- return acc;
51
- }, new Array<AddressLookupTableAccount>());
52
- };
53
-
54
- const addressLookupTableAccounts: AddressLookupTableAccount[] = [];
55
- addressLookupTableAccounts.push(
56
- ...(await getAddressLookupTableAccounts(addressLookupTableAddresses))
57
- );
58
-
59
- const ix_jupiterSwap = new TransactionInstruction({
60
- programId: new PublicKey(swapInstruction.programId),
61
- keys: swapInstruction.accounts.map((key: any) => ({
62
- pubkey: new PublicKey(key.pubkey),
63
- isSigner: key.isSigner,
64
- isWritable: key.isWritable,
65
- })),
66
- data: Buffer.from(swapInstruction.data, "base64"),
67
- });
68
-
69
- return {
70
- ix_jupiterSwap,
71
- jupiterLookupTables: addressLookupTableAccounts,
72
- };
73
- }
package/tsconfig.json DELETED
@@ -1,17 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "es2020",
4
- "module": "es2015",
5
- "rootDir": "./src",
6
- "outDir": "./build",
7
- "declaration": true,
8
- "strict": true,
9
- "esModuleInterop": true,
10
- "skipLibCheck": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "moduleResolution": "node",
13
- "resolveJsonModule": true
14
- },
15
- "include": ["src/**/*"],
16
- "exclude": ["node_modules", "build", "**/*.test.ts"]
17
- }
File without changes
File without changes
File without changes
File without changes