@lavarage/sdk 6.4.7 → 6.6.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.
- package/abi/borrowerOperations.ts +248 -0
- package/abi/tokenHolderAbi.ts +443 -0
- package/dist/index.d.mts +135 -1
- package/dist/index.d.ts +135 -1
- package/dist/index.js +1414 -172
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1428 -174
- package/dist/index.mjs.map +1 -1
- package/evm.ts +350 -0
- package/index.ts +1210 -669
- package/interfaces/evm.ts +42 -0
- package/package.json +4 -3
package/index.ts
CHANGED
|
@@ -1,23 +1,67 @@
|
|
|
1
|
-
import { BN, Program, ProgramAccount } from
|
|
2
|
-
import { Lavarage } from
|
|
3
|
-
import { Lavarage as LavarageV2 } from
|
|
4
|
-
import bs58 from
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { BN, Program, ProgramAccount } from "@coral-xyz/anchor";
|
|
2
|
+
import { Lavarage } from "./idl/lavarage";
|
|
3
|
+
import { Lavarage as LavarageV2 } from "./idl/lavaragev2";
|
|
4
|
+
import bs58 from "bs58";
|
|
5
|
+
import {
|
|
6
|
+
AddressLookupTableAccount,
|
|
7
|
+
ComputeBudgetProgram,
|
|
8
|
+
Keypair,
|
|
9
|
+
PublicKey,
|
|
10
|
+
SystemProgram,
|
|
11
|
+
SYSVAR_CLOCK_PUBKEY,
|
|
12
|
+
SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
13
|
+
Transaction,
|
|
14
|
+
TransactionInstruction,
|
|
15
|
+
TransactionMessage,
|
|
16
|
+
VersionedTransaction,
|
|
17
|
+
} from "@solana/web3.js";
|
|
18
|
+
import {
|
|
19
|
+
ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
20
|
+
createAssociatedTokenAccountIdempotentInstruction,
|
|
21
|
+
createAssociatedTokenAccountInstruction,
|
|
22
|
+
createTransferInstruction,
|
|
23
|
+
getAccount,
|
|
24
|
+
getAssociatedTokenAddressSync,
|
|
25
|
+
TOKEN_PROGRAM_ID,
|
|
26
|
+
TokenAccountNotFoundError,
|
|
27
|
+
TokenInvalidAccountOwnerError,
|
|
28
|
+
} from "@solana/spl-token";
|
|
8
29
|
|
|
9
30
|
export function getPda(seed: Buffer | Buffer[], programId: PublicKey) {
|
|
10
|
-
const seedsBuffer = Array.isArray(seed) ? seed : [seed]
|
|
31
|
+
const seedsBuffer = Array.isArray(seed) ? seed : [seed];
|
|
11
32
|
|
|
12
|
-
return PublicKey.findProgramAddressSync(seedsBuffer, programId)[0]
|
|
33
|
+
return PublicKey.findProgramAddressSync(seedsBuffer, programId)[0];
|
|
13
34
|
}
|
|
14
35
|
|
|
15
|
-
export function getPositionAccountPDA(
|
|
16
|
-
|
|
36
|
+
export function getPositionAccountPDA(
|
|
37
|
+
lavarageProgram: Program<Lavarage> | Program<LavarageV2>,
|
|
38
|
+
offer: ProgramAccount,
|
|
39
|
+
seed: PublicKey
|
|
40
|
+
) {
|
|
41
|
+
return getPda(
|
|
42
|
+
[
|
|
43
|
+
Buffer.from("position"),
|
|
44
|
+
lavarageProgram.provider.publicKey!.toBuffer(),
|
|
45
|
+
offer.publicKey.toBuffer(),
|
|
46
|
+
seed.toBuffer(),
|
|
47
|
+
],
|
|
48
|
+
lavarageProgram.programId
|
|
49
|
+
);
|
|
17
50
|
}
|
|
18
51
|
|
|
19
|
-
async function getTokenAccountOrCreateIfNotExists(
|
|
20
|
-
|
|
52
|
+
async function getTokenAccountOrCreateIfNotExists(
|
|
53
|
+
lavarageProgram: Program<Lavarage> | Program<LavarageV2>,
|
|
54
|
+
ownerPublicKey: PublicKey,
|
|
55
|
+
tokenAddress: PublicKey,
|
|
56
|
+
tokenProgram?: PublicKey
|
|
57
|
+
) {
|
|
58
|
+
const associatedTokenAddress = getAssociatedTokenAddressSync(
|
|
59
|
+
tokenAddress,
|
|
60
|
+
ownerPublicKey,
|
|
61
|
+
true,
|
|
62
|
+
tokenProgram,
|
|
63
|
+
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
64
|
+
);
|
|
21
65
|
|
|
22
66
|
const instruction = createAssociatedTokenAccountIdempotentInstruction(
|
|
23
67
|
lavarageProgram.provider.publicKey!,
|
|
@@ -25,126 +69,181 @@ async function getTokenAccountOrCreateIfNotExists(lavarageProgram: Program<Lavar
|
|
|
25
69
|
ownerPublicKey,
|
|
26
70
|
tokenAddress,
|
|
27
71
|
tokenProgram,
|
|
28
|
-
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
29
|
-
)
|
|
72
|
+
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
73
|
+
);
|
|
30
74
|
|
|
31
75
|
return {
|
|
32
76
|
account: {
|
|
33
77
|
address: associatedTokenAddress,
|
|
34
78
|
},
|
|
35
79
|
instruction,
|
|
36
|
-
}
|
|
80
|
+
};
|
|
37
81
|
}
|
|
38
82
|
|
|
39
|
-
export * from
|
|
40
|
-
export * as IDLV2 from
|
|
41
|
-
|
|
42
|
-
export const getOffers = (lavarageProgram: Program<Lavarage> | Program<LavarageV2>) => {
|
|
43
|
-
return lavarageProgram.account.pool.all()
|
|
44
|
-
}
|
|
83
|
+
export * from "./idl/lavarage";
|
|
84
|
+
export * as IDLV2 from "./idl/lavaragev2";
|
|
45
85
|
|
|
46
|
-
export const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
bytes: bs58.encode(new Uint8Array(8)),
|
|
52
|
-
},
|
|
53
|
-
},])
|
|
54
|
-
}
|
|
86
|
+
export const getOffers = (
|
|
87
|
+
lavarageProgram: Program<Lavarage> | Program<LavarageV2>
|
|
88
|
+
) => {
|
|
89
|
+
return lavarageProgram.account.pool.all();
|
|
90
|
+
};
|
|
55
91
|
|
|
56
|
-
export const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return (await lavarageProgram.account.position.all([{ dataSize: 178 },
|
|
67
|
-
{
|
|
68
|
-
memcmp: {
|
|
69
|
-
offset: 40,
|
|
70
|
-
bytes: bs58.encode(Uint8Array.from(valueBuffer)),
|
|
71
|
-
},
|
|
72
|
-
},])).concat(await lavarageProgram.account.position.all([{ dataSize: 178 },
|
|
73
|
-
{
|
|
74
|
-
memcmp: {
|
|
75
|
-
offset: 40,
|
|
76
|
-
bytes: bs58.encode(Uint8Array.from(valueBuffer2)),
|
|
92
|
+
export const getOpenPositions = (
|
|
93
|
+
lavarageProgram: Program<Lavarage> | Program<LavarageV2>
|
|
94
|
+
) => {
|
|
95
|
+
return lavarageProgram.account.position.all([
|
|
96
|
+
{ dataSize: 178 },
|
|
97
|
+
{
|
|
98
|
+
memcmp: {
|
|
99
|
+
offset: 40,
|
|
100
|
+
bytes: bs58.encode(new Uint8Array(8)),
|
|
101
|
+
},
|
|
77
102
|
},
|
|
78
|
-
|
|
79
|
-
|
|
103
|
+
]);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export const getClosedPositions = async (
|
|
107
|
+
lavarageProgram: Program<Lavarage> | Program<LavarageV2>
|
|
108
|
+
) => {
|
|
109
|
+
const value = BigInt(9997);
|
|
110
|
+
const valueBuffer = Buffer.alloc(8);
|
|
111
|
+
valueBuffer.writeBigUInt64LE(value);
|
|
112
|
+
const value2 = BigInt(9998);
|
|
113
|
+
const valueBuffer2 = Buffer.alloc(8);
|
|
114
|
+
valueBuffer2.writeBigUInt64LE(value2);
|
|
115
|
+
const value3 = BigInt(9996);
|
|
116
|
+
const valueBuffer3 = Buffer.alloc(8);
|
|
117
|
+
valueBuffer3.writeBigUInt64LE(value3);
|
|
118
|
+
return (
|
|
119
|
+
await lavarageProgram.account.position.all([
|
|
120
|
+
{ dataSize: 178 },
|
|
121
|
+
{
|
|
122
|
+
memcmp: {
|
|
123
|
+
offset: 40,
|
|
124
|
+
bytes: bs58.encode(Uint8Array.from(valueBuffer)),
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
])
|
|
128
|
+
)
|
|
129
|
+
.concat(
|
|
130
|
+
await lavarageProgram.account.position.all([
|
|
131
|
+
{ dataSize: 178 },
|
|
132
|
+
{
|
|
133
|
+
memcmp: {
|
|
134
|
+
offset: 40,
|
|
135
|
+
bytes: bs58.encode(Uint8Array.from(valueBuffer2)),
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
])
|
|
139
|
+
)
|
|
140
|
+
.concat(
|
|
141
|
+
await lavarageProgram.account.position.all([
|
|
142
|
+
{ dataSize: 178 },
|
|
143
|
+
{
|
|
144
|
+
memcmp: {
|
|
145
|
+
offset: 40,
|
|
146
|
+
bytes: bs58.encode(Uint8Array.from(valueBuffer3)),
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
])
|
|
150
|
+
);
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
export const getLiquidatedPositions = (
|
|
154
|
+
lavarageProgram: Program<Lavarage> | Program<LavarageV2>
|
|
155
|
+
) => {
|
|
156
|
+
const value = BigInt(9999);
|
|
157
|
+
const valueBuffer = Buffer.alloc(8);
|
|
158
|
+
valueBuffer.writeBigUInt64LE(value);
|
|
159
|
+
return lavarageProgram.account.position.all([
|
|
160
|
+
{ dataSize: 178 },
|
|
80
161
|
{
|
|
81
162
|
memcmp: {
|
|
82
163
|
offset: 40,
|
|
83
|
-
bytes: bs58.encode(Uint8Array.from(
|
|
164
|
+
bytes: bs58.encode(Uint8Array.from(valueBuffer)),
|
|
84
165
|
},
|
|
85
|
-
},]))
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export const getLiquidatedPositions = (lavarageProgram: Program<Lavarage> | Program<LavarageV2>) => {
|
|
89
|
-
const value = BigInt(9999)
|
|
90
|
-
const valueBuffer = Buffer.alloc(8)
|
|
91
|
-
valueBuffer.writeBigUInt64LE(value)
|
|
92
|
-
return lavarageProgram.account.position.all([{ dataSize: 178 },
|
|
93
|
-
{
|
|
94
|
-
memcmp: {
|
|
95
|
-
offset: 40,
|
|
96
|
-
bytes: bs58.encode(Uint8Array.from(valueBuffer)),
|
|
97
166
|
},
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export const getAllPositions = (
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
167
|
+
]);
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
export const getAllPositions = (
|
|
171
|
+
lavarageProgram: Program<Lavarage> | Program<LavarageV2>
|
|
172
|
+
) => {
|
|
173
|
+
return lavarageProgram.account.position.all([{ dataSize: 178 }]);
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
export const openTradeV1 = async (
|
|
177
|
+
lavarageProgram: Program<Lavarage>,
|
|
178
|
+
offer: ProgramAccount<{
|
|
179
|
+
nodeWallet: PublicKey;
|
|
180
|
+
interestRate: number;
|
|
181
|
+
collateralType: PublicKey;
|
|
182
|
+
}>,
|
|
183
|
+
jupInstruction: {
|
|
184
|
+
instructions: {
|
|
185
|
+
setupInstructions: Record<string, unknown>[];
|
|
186
|
+
swapInstruction: Record<string, unknown>;
|
|
187
|
+
addressLookupTableAddresses: string[];
|
|
188
|
+
};
|
|
189
|
+
},
|
|
190
|
+
marginSOL: BN,
|
|
191
|
+
leverage: number,
|
|
192
|
+
randomSeed: Keypair,
|
|
193
|
+
partnerFeeRecipient?: PublicKey,
|
|
194
|
+
partnerFeeMarkup?: number
|
|
195
|
+
) => {
|
|
196
|
+
let partnerFeeMarkupAsPkey;
|
|
118
197
|
if (partnerFeeMarkup) {
|
|
119
|
-
const feeBuffer = Buffer.alloc(8)
|
|
120
|
-
feeBuffer.writeBigUInt64LE(BigInt(partnerFeeMarkup))
|
|
121
|
-
const feeBuffer32 = Buffer.alloc(32)
|
|
122
|
-
feeBuffer32.set(feeBuffer, 0)
|
|
123
|
-
partnerFeeMarkupAsPkey = new PublicKey(feeBuffer32)
|
|
198
|
+
const feeBuffer = Buffer.alloc(8);
|
|
199
|
+
feeBuffer.writeBigUInt64LE(BigInt(partnerFeeMarkup));
|
|
200
|
+
const feeBuffer32 = Buffer.alloc(32);
|
|
201
|
+
feeBuffer32.set(feeBuffer, 0);
|
|
202
|
+
partnerFeeMarkupAsPkey = new PublicKey(feeBuffer32);
|
|
124
203
|
}
|
|
125
204
|
// assuming all token accounts are created prior
|
|
126
|
-
const positionAccount = getPositionAccountPDA(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
205
|
+
const positionAccount = getPositionAccountPDA(
|
|
206
|
+
lavarageProgram,
|
|
207
|
+
offer,
|
|
208
|
+
randomSeed.publicKey
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
const mintAccount = await lavarageProgram.provider.connection.getAccountInfo(
|
|
212
|
+
offer.account.collateralType
|
|
213
|
+
);
|
|
214
|
+
const tokenProgram = mintAccount?.owner;
|
|
215
|
+
|
|
216
|
+
const fromTokenAccount = await getTokenAccountOrCreateIfNotExists(
|
|
217
|
+
lavarageProgram,
|
|
218
|
+
lavarageProgram.provider.publicKey!,
|
|
219
|
+
offer.account.collateralType,
|
|
220
|
+
tokenProgram
|
|
221
|
+
);
|
|
132
222
|
|
|
133
|
-
const toTokenAccount = await getTokenAccountOrCreateIfNotExists(
|
|
223
|
+
const toTokenAccount = await getTokenAccountOrCreateIfNotExists(
|
|
224
|
+
lavarageProgram,
|
|
225
|
+
positionAccount,
|
|
226
|
+
offer.account.collateralType,
|
|
227
|
+
tokenProgram
|
|
228
|
+
);
|
|
134
229
|
|
|
135
|
-
const tokenAccountCreationTx = new Transaction()
|
|
230
|
+
const tokenAccountCreationTx = new Transaction();
|
|
136
231
|
|
|
137
232
|
if (fromTokenAccount.instruction) {
|
|
138
|
-
tokenAccountCreationTx.add(fromTokenAccount.instruction)
|
|
233
|
+
tokenAccountCreationTx.add(fromTokenAccount.instruction);
|
|
139
234
|
}
|
|
140
235
|
|
|
141
236
|
if (toTokenAccount.instruction) {
|
|
142
|
-
tokenAccountCreationTx.add(toTokenAccount.instruction)
|
|
237
|
+
tokenAccountCreationTx.add(toTokenAccount.instruction);
|
|
143
238
|
}
|
|
144
239
|
|
|
145
|
-
const instructionsJup = jupInstruction.instructions
|
|
240
|
+
const instructionsJup = jupInstruction.instructions;
|
|
146
241
|
|
|
147
|
-
const {
|
|
242
|
+
const {
|
|
243
|
+
setupInstructions,
|
|
244
|
+
swapInstruction: swapInstructionPayload,
|
|
245
|
+
addressLookupTableAddresses,
|
|
246
|
+
} = instructionsJup;
|
|
148
247
|
|
|
149
248
|
const deserializeInstruction = (instruction: any) => {
|
|
150
249
|
return new TransactionInstruction({
|
|
@@ -155,35 +254,51 @@ export const openTradeV1 = async (lavarageProgram: Program<Lavarage>, offer: Pro
|
|
|
155
254
|
isSigner: key.isSigner,
|
|
156
255
|
isWritable: key.isWritable,
|
|
157
256
|
})),
|
|
158
|
-
data: Buffer.from(instruction.data,
|
|
159
|
-
})
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const getAddressLookupTableAccounts = async (
|
|
163
|
-
|
|
257
|
+
data: Buffer.from(instruction.data, "base64"),
|
|
258
|
+
});
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
const getAddressLookupTableAccounts = async (
|
|
262
|
+
keys: string[]
|
|
263
|
+
): Promise<AddressLookupTableAccount[]> => {
|
|
264
|
+
const addressLookupTableAccountInfos =
|
|
265
|
+
await lavarageProgram.provider.connection.getMultipleAccountsInfo(
|
|
266
|
+
keys.map((key) => new PublicKey(key))
|
|
267
|
+
);
|
|
164
268
|
|
|
165
269
|
return addressLookupTableAccountInfos.reduce((acc, accountInfo, index) => {
|
|
166
|
-
const addressLookupTableAddress = keys[index]
|
|
270
|
+
const addressLookupTableAddress = keys[index];
|
|
167
271
|
if (accountInfo) {
|
|
168
272
|
const addressLookupTableAccount = new AddressLookupTableAccount({
|
|
169
273
|
key: new PublicKey(addressLookupTableAddress),
|
|
170
|
-
state: AddressLookupTableAccount.deserialize(
|
|
171
|
-
|
|
172
|
-
|
|
274
|
+
state: AddressLookupTableAccount.deserialize(
|
|
275
|
+
Uint8Array.from(accountInfo.data)
|
|
276
|
+
),
|
|
277
|
+
});
|
|
278
|
+
acc.push(addressLookupTableAccount);
|
|
173
279
|
}
|
|
174
280
|
|
|
175
|
-
return acc
|
|
176
|
-
}, new Array<AddressLookupTableAccount>())
|
|
177
|
-
}
|
|
281
|
+
return acc;
|
|
282
|
+
}, new Array<AddressLookupTableAccount>());
|
|
283
|
+
};
|
|
178
284
|
|
|
179
|
-
const addressLookupTableAccounts: AddressLookupTableAccount[] = []
|
|
285
|
+
const addressLookupTableAccounts: AddressLookupTableAccount[] = [];
|
|
180
286
|
|
|
181
|
-
addressLookupTableAccounts.push(
|
|
287
|
+
addressLookupTableAccounts.push(
|
|
288
|
+
...(await getAddressLookupTableAccounts([
|
|
289
|
+
"5LEAB3owNUSKvECm7vkr58tDtQpzbngQ2NYpc7qmRFdi",
|
|
290
|
+
...addressLookupTableAddresses,
|
|
291
|
+
]))
|
|
292
|
+
);
|
|
182
293
|
|
|
183
|
-
const { blockhash } =
|
|
294
|
+
const { blockhash } =
|
|
295
|
+
await lavarageProgram.provider.connection.getLatestBlockhash("finalized");
|
|
184
296
|
|
|
185
297
|
const tradingOpenBorrowInstruction = await lavarageProgram.methods
|
|
186
|
-
.tradingOpenBorrow(
|
|
298
|
+
.tradingOpenBorrow(
|
|
299
|
+
new BN((marginSOL.toNumber() * leverage).toFixed(0)),
|
|
300
|
+
marginSOL
|
|
301
|
+
)
|
|
187
302
|
.accountsStrict({
|
|
188
303
|
nodeWallet: offer.account.nodeWallet,
|
|
189
304
|
instructions: SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
@@ -193,18 +308,25 @@ export const openTradeV1 = async (lavarageProgram: Program<Lavarage>, offer: Pro
|
|
|
193
308
|
systemProgram: SystemProgram.programId,
|
|
194
309
|
clock: SYSVAR_CLOCK_PUBKEY,
|
|
195
310
|
randomAccountAsId: randomSeed.publicKey.toBase58(),
|
|
196
|
-
feeReceipient:
|
|
311
|
+
feeReceipient: "6JfTobDvwuwZxZP6FR5JPmjdvQ4h4MovkEVH2FPsMSrF",
|
|
197
312
|
})
|
|
198
|
-
.remainingAccounts(
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
313
|
+
.remainingAccounts(
|
|
314
|
+
partnerFeeRecipient && partnerFeeMarkupAsPkey
|
|
315
|
+
? [
|
|
316
|
+
{
|
|
317
|
+
pubkey: partnerFeeRecipient,
|
|
318
|
+
isSigner: false,
|
|
319
|
+
isWritable: true,
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
pubkey: partnerFeeMarkupAsPkey,
|
|
323
|
+
isSigner: false,
|
|
324
|
+
isWritable: false,
|
|
325
|
+
},
|
|
326
|
+
]
|
|
327
|
+
: []
|
|
328
|
+
)
|
|
329
|
+
.instruction();
|
|
208
330
|
|
|
209
331
|
const openAddCollateralInstruction = await lavarageProgram.methods
|
|
210
332
|
.tradingOpenAddCollateral(offer.account.interestRate)
|
|
@@ -217,12 +339,12 @@ export const openTradeV1 = async (lavarageProgram: Program<Lavarage>, offer: Pro
|
|
|
217
339
|
positionAccount,
|
|
218
340
|
randomAccountAsId: randomSeed.publicKey.toBase58(),
|
|
219
341
|
})
|
|
220
|
-
.instruction()
|
|
342
|
+
.instruction();
|
|
221
343
|
|
|
222
344
|
const jupiterIxs = [
|
|
223
345
|
...setupInstructions.map(deserializeInstruction),
|
|
224
346
|
deserializeInstruction(swapInstructionPayload),
|
|
225
|
-
]
|
|
347
|
+
];
|
|
226
348
|
|
|
227
349
|
const allInstructions = [
|
|
228
350
|
fromTokenAccount.instruction!,
|
|
@@ -230,64 +352,95 @@ export const openTradeV1 = async (lavarageProgram: Program<Lavarage>, offer: Pro
|
|
|
230
352
|
tradingOpenBorrowInstruction!,
|
|
231
353
|
...jupiterIxs,
|
|
232
354
|
openAddCollateralInstruction!,
|
|
233
|
-
].filter(Boolean)
|
|
355
|
+
].filter(Boolean);
|
|
234
356
|
|
|
235
357
|
const messageV0 = new TransactionMessage({
|
|
236
358
|
payerKey: lavarageProgram.provider.publicKey!,
|
|
237
359
|
recentBlockhash: blockhash,
|
|
238
360
|
instructions: allInstructions,
|
|
239
|
-
}).compileToV0Message(addressLookupTableAccounts)
|
|
240
|
-
|
|
241
|
-
const tx = new VersionedTransaction(messageV0)
|
|
242
|
-
|
|
243
|
-
return tx
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
export const openTradeV2 = async (
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
361
|
+
}).compileToV0Message(addressLookupTableAccounts);
|
|
362
|
+
|
|
363
|
+
const tx = new VersionedTransaction(messageV0);
|
|
364
|
+
|
|
365
|
+
return tx;
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
export const openTradeV2 = async (
|
|
369
|
+
lavarageProgram: Program<LavarageV2>,
|
|
370
|
+
offer: ProgramAccount<{
|
|
371
|
+
nodeWallet: PublicKey;
|
|
372
|
+
interestRate: number;
|
|
373
|
+
collateralType: PublicKey;
|
|
374
|
+
}>,
|
|
375
|
+
jupInstruction: {
|
|
376
|
+
instructions: {
|
|
377
|
+
setupInstructions: Record<string, unknown>[];
|
|
378
|
+
swapInstruction: Record<string, unknown>;
|
|
379
|
+
addressLookupTableAddresses: string[];
|
|
380
|
+
};
|
|
381
|
+
},
|
|
382
|
+
marginSOL: BN,
|
|
383
|
+
leverage: number,
|
|
384
|
+
randomSeed: Keypair,
|
|
385
|
+
quoteToken: PublicKey,
|
|
386
|
+
partnerFeeRecipient?: PublicKey,
|
|
387
|
+
partnerFeeMarkup?: number
|
|
388
|
+
) => {
|
|
389
|
+
let partnerFeeMarkupAsPkey;
|
|
258
390
|
if (partnerFeeMarkup) {
|
|
259
|
-
const feeBuffer = Buffer.alloc(8)
|
|
260
|
-
feeBuffer.writeBigUInt64LE(BigInt(partnerFeeMarkup))
|
|
261
|
-
const feeBuffer32 = Buffer.alloc(32)
|
|
262
|
-
feeBuffer32.set(feeBuffer, 0)
|
|
263
|
-
partnerFeeMarkupAsPkey = new PublicKey(feeBuffer32)
|
|
391
|
+
const feeBuffer = Buffer.alloc(8);
|
|
392
|
+
feeBuffer.writeBigUInt64LE(BigInt(partnerFeeMarkup));
|
|
393
|
+
const feeBuffer32 = Buffer.alloc(32);
|
|
394
|
+
feeBuffer32.set(feeBuffer, 0);
|
|
395
|
+
partnerFeeMarkupAsPkey = new PublicKey(feeBuffer32);
|
|
264
396
|
}
|
|
265
397
|
// assuming all token accounts are created prior
|
|
266
|
-
const positionAccount = getPositionAccountPDA(
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
const
|
|
273
|
-
|
|
274
|
-
|
|
398
|
+
const positionAccount = getPositionAccountPDA(
|
|
399
|
+
lavarageProgram,
|
|
400
|
+
offer,
|
|
401
|
+
randomSeed.publicKey
|
|
402
|
+
);
|
|
403
|
+
|
|
404
|
+
const mintAccount = await lavarageProgram.provider.connection.getAccountInfo(
|
|
405
|
+
offer.account.collateralType
|
|
406
|
+
);
|
|
407
|
+
const tokenProgram = mintAccount?.owner;
|
|
408
|
+
|
|
409
|
+
const quoteMintAccount =
|
|
410
|
+
await lavarageProgram.provider.connection.getAccountInfo(quoteToken);
|
|
411
|
+
const quoteTokenProgram = quoteMintAccount?.owner;
|
|
412
|
+
|
|
413
|
+
const fromTokenAccount = await getTokenAccountOrCreateIfNotExists(
|
|
414
|
+
lavarageProgram,
|
|
415
|
+
lavarageProgram.provider.publicKey!,
|
|
416
|
+
offer.account.collateralType,
|
|
417
|
+
tokenProgram
|
|
418
|
+
);
|
|
275
419
|
|
|
276
|
-
const toTokenAccount = await getTokenAccountOrCreateIfNotExists(
|
|
420
|
+
const toTokenAccount = await getTokenAccountOrCreateIfNotExists(
|
|
421
|
+
lavarageProgram,
|
|
422
|
+
positionAccount,
|
|
423
|
+
offer.account.collateralType,
|
|
424
|
+
tokenProgram
|
|
425
|
+
);
|
|
277
426
|
|
|
278
|
-
const tokenAccountCreationTx = new Transaction()
|
|
427
|
+
const tokenAccountCreationTx = new Transaction();
|
|
279
428
|
|
|
280
429
|
if (fromTokenAccount.instruction) {
|
|
281
|
-
tokenAccountCreationTx.add(fromTokenAccount.instruction)
|
|
430
|
+
tokenAccountCreationTx.add(fromTokenAccount.instruction);
|
|
282
431
|
}
|
|
283
432
|
|
|
284
433
|
if (toTokenAccount.instruction) {
|
|
285
|
-
tokenAccountCreationTx.add(toTokenAccount.instruction)
|
|
434
|
+
tokenAccountCreationTx.add(toTokenAccount.instruction);
|
|
286
435
|
}
|
|
287
436
|
|
|
288
|
-
const instructionsJup = jupInstruction.instructions
|
|
437
|
+
const instructionsJup = jupInstruction.instructions;
|
|
289
438
|
|
|
290
|
-
const {
|
|
439
|
+
const {
|
|
440
|
+
setupInstructions,
|
|
441
|
+
swapInstruction: swapInstructionPayload,
|
|
442
|
+
addressLookupTableAddresses,
|
|
443
|
+
} = instructionsJup;
|
|
291
444
|
|
|
292
445
|
const deserializeInstruction = (instruction: any) => {
|
|
293
446
|
return new TransactionInstruction({
|
|
@@ -298,35 +451,52 @@ export const openTradeV2 = async (lavarageProgram: Program<LavarageV2>, offer: P
|
|
|
298
451
|
isSigner: key.isSigner,
|
|
299
452
|
isWritable: key.isWritable,
|
|
300
453
|
})),
|
|
301
|
-
data: Buffer.from(instruction.data,
|
|
302
|
-
})
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
const getAddressLookupTableAccounts = async (
|
|
306
|
-
|
|
454
|
+
data: Buffer.from(instruction.data, "base64"),
|
|
455
|
+
});
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
const getAddressLookupTableAccounts = async (
|
|
459
|
+
keys: string[]
|
|
460
|
+
): Promise<AddressLookupTableAccount[]> => {
|
|
461
|
+
const addressLookupTableAccountInfos =
|
|
462
|
+
await lavarageProgram.provider.connection.getMultipleAccountsInfo(
|
|
463
|
+
keys.map((key) => new PublicKey(key))
|
|
464
|
+
);
|
|
307
465
|
|
|
308
466
|
return addressLookupTableAccountInfos.reduce((acc, accountInfo, index) => {
|
|
309
|
-
const addressLookupTableAddress = keys[index]
|
|
467
|
+
const addressLookupTableAddress = keys[index];
|
|
310
468
|
if (accountInfo) {
|
|
311
469
|
const addressLookupTableAccount = new AddressLookupTableAccount({
|
|
312
470
|
key: new PublicKey(addressLookupTableAddress),
|
|
313
|
-
state: AddressLookupTableAccount.deserialize(
|
|
314
|
-
|
|
315
|
-
|
|
471
|
+
state: AddressLookupTableAccount.deserialize(
|
|
472
|
+
Uint8Array.from(accountInfo.data)
|
|
473
|
+
),
|
|
474
|
+
});
|
|
475
|
+
acc.push(addressLookupTableAccount);
|
|
316
476
|
}
|
|
317
477
|
|
|
318
|
-
return acc
|
|
319
|
-
}, new Array<AddressLookupTableAccount>())
|
|
320
|
-
}
|
|
478
|
+
return acc;
|
|
479
|
+
}, new Array<AddressLookupTableAccount>());
|
|
480
|
+
};
|
|
321
481
|
|
|
322
|
-
const addressLookupTableAccounts: AddressLookupTableAccount[] = []
|
|
482
|
+
const addressLookupTableAccounts: AddressLookupTableAccount[] = [];
|
|
323
483
|
|
|
324
|
-
addressLookupTableAccounts.push(
|
|
484
|
+
addressLookupTableAccounts.push(
|
|
485
|
+
...(await getAddressLookupTableAccounts([
|
|
486
|
+
...addressLookupTableAddresses,
|
|
487
|
+
getQuoteCurrencySpecificAddressLookupTable(quoteToken.toBase58()),
|
|
488
|
+
"5LEAB3owNUSKvECm7vkr58tDtQpzbngQ2NYpc7qmRFdi",
|
|
489
|
+
]))
|
|
490
|
+
);
|
|
325
491
|
|
|
326
|
-
const { blockhash } =
|
|
492
|
+
const { blockhash } =
|
|
493
|
+
await lavarageProgram.provider.connection.getLatestBlockhash("finalized");
|
|
327
494
|
|
|
328
495
|
const tradingOpenBorrowInstruction = await lavarageProgram.methods
|
|
329
|
-
.tradingOpenBorrow(
|
|
496
|
+
.tradingOpenBorrow(
|
|
497
|
+
new BN((marginSOL.toNumber() * leverage).toFixed(0)),
|
|
498
|
+
marginSOL
|
|
499
|
+
)
|
|
330
500
|
.accountsStrict({
|
|
331
501
|
nodeWallet: offer.account.nodeWallet,
|
|
332
502
|
instructions: SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
@@ -336,21 +506,48 @@ export const openTradeV2 = async (lavarageProgram: Program<LavarageV2>, offer: P
|
|
|
336
506
|
systemProgram: SystemProgram.programId,
|
|
337
507
|
clock: SYSVAR_CLOCK_PUBKEY,
|
|
338
508
|
randomAccountAsId: randomSeed.publicKey.toBase58(),
|
|
339
|
-
feeTokenAccount: getAssociatedTokenAddressSync(
|
|
340
|
-
|
|
509
|
+
feeTokenAccount: getAssociatedTokenAddressSync(
|
|
510
|
+
quoteToken,
|
|
511
|
+
new PublicKey("6JfTobDvwuwZxZP6FR5JPmjdvQ4h4MovkEVH2FPsMSrF"),
|
|
512
|
+
true,
|
|
513
|
+
quoteTokenProgram
|
|
514
|
+
),
|
|
515
|
+
toTokenAccount: getAssociatedTokenAddressSync(
|
|
516
|
+
quoteToken,
|
|
517
|
+
lavarageProgram.provider.publicKey!,
|
|
518
|
+
true,
|
|
519
|
+
quoteTokenProgram
|
|
520
|
+
),
|
|
341
521
|
tokenProgram: quoteTokenProgram!,
|
|
342
|
-
fromTokenAccount: getAssociatedTokenAddressSync(
|
|
522
|
+
fromTokenAccount: getAssociatedTokenAddressSync(
|
|
523
|
+
quoteToken,
|
|
524
|
+
offer.account.nodeWallet,
|
|
525
|
+
true,
|
|
526
|
+
quoteTokenProgram
|
|
527
|
+
),
|
|
343
528
|
})
|
|
344
|
-
.remainingAccounts(
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
529
|
+
.remainingAccounts(
|
|
530
|
+
partnerFeeRecipient && partnerFeeMarkupAsPkey
|
|
531
|
+
? [
|
|
532
|
+
{
|
|
533
|
+
pubkey: getAssociatedTokenAddressSync(
|
|
534
|
+
quoteToken,
|
|
535
|
+
partnerFeeRecipient,
|
|
536
|
+
false,
|
|
537
|
+
quoteTokenProgram
|
|
538
|
+
),
|
|
539
|
+
isSigner: false,
|
|
540
|
+
isWritable: true,
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
pubkey: partnerFeeMarkupAsPkey,
|
|
544
|
+
isSigner: false,
|
|
545
|
+
isWritable: false,
|
|
546
|
+
},
|
|
547
|
+
]
|
|
548
|
+
: []
|
|
549
|
+
)
|
|
550
|
+
.instruction();
|
|
354
551
|
|
|
355
552
|
const openAddCollateralInstruction = await lavarageProgram.methods
|
|
356
553
|
.tradingOpenAddCollateral(offer.account.interestRate)
|
|
@@ -363,12 +560,12 @@ export const openTradeV2 = async (lavarageProgram: Program<LavarageV2>, offer: P
|
|
|
363
560
|
positionAccount,
|
|
364
561
|
randomAccountAsId: randomSeed.publicKey.toBase58(),
|
|
365
562
|
})
|
|
366
|
-
.instruction()
|
|
563
|
+
.instruction();
|
|
367
564
|
|
|
368
565
|
const jupiterIxs = [
|
|
369
566
|
...setupInstructions.map(deserializeInstruction),
|
|
370
567
|
deserializeInstruction(swapInstructionPayload),
|
|
371
|
-
]
|
|
568
|
+
];
|
|
372
569
|
|
|
373
570
|
const allInstructions = [
|
|
374
571
|
fromTokenAccount.instruction!,
|
|
@@ -376,234 +573,349 @@ export const openTradeV2 = async (lavarageProgram: Program<LavarageV2>, offer: P
|
|
|
376
573
|
tradingOpenBorrowInstruction!,
|
|
377
574
|
...jupiterIxs,
|
|
378
575
|
openAddCollateralInstruction!,
|
|
379
|
-
].filter(Boolean)
|
|
576
|
+
].filter(Boolean);
|
|
380
577
|
|
|
381
578
|
const messageV0 = new TransactionMessage({
|
|
382
579
|
payerKey: lavarageProgram.provider.publicKey!,
|
|
383
580
|
recentBlockhash: blockhash,
|
|
384
581
|
instructions: allInstructions,
|
|
385
|
-
}).compileToV0Message(addressLookupTableAccounts)
|
|
386
|
-
|
|
387
|
-
const tx = new VersionedTransaction(messageV0)
|
|
388
|
-
|
|
389
|
-
return tx
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
export const createTpDelegate = async (
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
582
|
+
}).compileToV0Message(addressLookupTableAccounts);
|
|
583
|
+
|
|
584
|
+
const tx = new VersionedTransaction(messageV0);
|
|
585
|
+
|
|
586
|
+
return tx;
|
|
587
|
+
};
|
|
588
|
+
|
|
589
|
+
export const createTpDelegate = async (
|
|
590
|
+
lavarageProgram: Program<Lavarage> | Program<LavarageV2>,
|
|
591
|
+
position: ProgramAccount<{
|
|
592
|
+
pool: PublicKey;
|
|
593
|
+
seed: PublicKey;
|
|
594
|
+
userPaid: BN;
|
|
595
|
+
amount: BN;
|
|
596
|
+
}>,
|
|
597
|
+
tpPrice: BN,
|
|
598
|
+
tpTolerence: BN,
|
|
599
|
+
prioFee: BN,
|
|
600
|
+
quoteToken: PublicKey,
|
|
601
|
+
partnerFeeRecipient?: PublicKey
|
|
602
|
+
) => {
|
|
603
|
+
const { blockhash } =
|
|
604
|
+
await lavarageProgram.provider.connection.getLatestBlockhash("finalized");
|
|
605
|
+
const ix = await lavarageProgram.methods
|
|
606
|
+
.tradingCreateTpDelegate(
|
|
607
|
+
tpPrice,
|
|
608
|
+
tpTolerence,
|
|
609
|
+
new PublicKey("6dA5GTDPWxnw3gvjoy3vYBDyY7iETxcTJzt8RqF9i9MV"),
|
|
610
|
+
new BN(10000)
|
|
611
|
+
)
|
|
400
612
|
.accountsStrict({
|
|
401
|
-
delegate: getPda(
|
|
613
|
+
delegate: getPda(
|
|
614
|
+
[Buffer.from("delegate"), position.publicKey.toBuffer()],
|
|
615
|
+
lavarageProgram.programId
|
|
616
|
+
),
|
|
402
617
|
originalOperator: lavarageProgram.provider.publicKey!,
|
|
403
618
|
delegatedAccount: position.publicKey,
|
|
404
619
|
systemProgram: SystemProgram.programId,
|
|
405
|
-
})
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
620
|
+
})
|
|
621
|
+
.remainingAccounts(
|
|
622
|
+
partnerFeeRecipient
|
|
623
|
+
? [
|
|
624
|
+
{
|
|
625
|
+
pubkey:
|
|
626
|
+
quoteToken.toBase58() ==
|
|
627
|
+
"So11111111111111111111111111111111111111112"
|
|
628
|
+
? partnerFeeRecipient
|
|
629
|
+
: getAssociatedTokenAddressSync(
|
|
630
|
+
quoteToken,
|
|
631
|
+
partnerFeeRecipient,
|
|
632
|
+
false
|
|
633
|
+
),
|
|
634
|
+
isSigner: false,
|
|
635
|
+
isWritable: true,
|
|
636
|
+
},
|
|
637
|
+
]
|
|
638
|
+
: []
|
|
639
|
+
)
|
|
640
|
+
.instruction();
|
|
411
641
|
|
|
412
642
|
const computeFeeIx = ComputeBudgetProgram.setComputeUnitPrice({
|
|
413
643
|
microLamports: prioFee.toNumber(),
|
|
414
|
-
})
|
|
644
|
+
});
|
|
415
645
|
|
|
416
646
|
const messageV0 = new TransactionMessage({
|
|
417
647
|
payerKey: lavarageProgram.provider.publicKey!,
|
|
418
648
|
recentBlockhash: blockhash,
|
|
419
|
-
instructions: [
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
649
|
+
instructions: [ix, computeFeeIx].filter(Boolean),
|
|
650
|
+
}).compileToV0Message();
|
|
651
|
+
|
|
652
|
+
return new VersionedTransaction(messageV0);
|
|
653
|
+
};
|
|
654
|
+
|
|
655
|
+
export const modifyTpDelegate = async (
|
|
656
|
+
lavarageProgram: Program<Lavarage> | Program<LavarageV2>,
|
|
657
|
+
position: ProgramAccount<{
|
|
658
|
+
pool: PublicKey;
|
|
659
|
+
seed: PublicKey;
|
|
660
|
+
userPaid: BN;
|
|
661
|
+
amount: BN;
|
|
662
|
+
}>,
|
|
663
|
+
tpPrice: BN,
|
|
664
|
+
tpTolerence: BN,
|
|
665
|
+
prioFee: BN,
|
|
666
|
+
quoteToken: PublicKey,
|
|
667
|
+
partnerFeeRecipient?: PublicKey
|
|
668
|
+
) => {
|
|
669
|
+
const { blockhash } =
|
|
670
|
+
await lavarageProgram.provider.connection.getLatestBlockhash("finalized");
|
|
671
|
+
const delegatePda = getPda(
|
|
672
|
+
[Buffer.from("delegate"), position.publicKey.toBuffer()],
|
|
673
|
+
lavarageProgram.programId
|
|
674
|
+
);
|
|
675
|
+
const removeIx = await lavarageProgram.methods
|
|
676
|
+
.tradingRemoveTpDelegate()
|
|
443
677
|
.accountsStrict({
|
|
444
678
|
delegate: delegatePda,
|
|
445
679
|
originalOperator: lavarageProgram.provider.publicKey!,
|
|
446
680
|
delegatedAccount: position.publicKey,
|
|
447
681
|
systemProgram: SystemProgram.programId,
|
|
448
|
-
})
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
682
|
+
})
|
|
683
|
+
.instruction();
|
|
684
|
+
const ix = await lavarageProgram.methods
|
|
685
|
+
.tradingCreateTpDelegate(
|
|
686
|
+
tpPrice,
|
|
687
|
+
tpTolerence,
|
|
688
|
+
new PublicKey("6dA5GTDPWxnw3gvjoy3vYBDyY7iETxcTJzt8RqF9i9MV"),
|
|
689
|
+
new BN(10000)
|
|
690
|
+
)
|
|
691
|
+
.accountsStrict({
|
|
692
|
+
delegate: delegatePda,
|
|
693
|
+
originalOperator: lavarageProgram.provider.publicKey!,
|
|
694
|
+
delegatedAccount: position.publicKey,
|
|
695
|
+
systemProgram: SystemProgram.programId,
|
|
696
|
+
})
|
|
697
|
+
.remainingAccounts(
|
|
698
|
+
partnerFeeRecipient
|
|
699
|
+
? [
|
|
700
|
+
{
|
|
701
|
+
pubkey:
|
|
702
|
+
quoteToken.toBase58() ==
|
|
703
|
+
"So11111111111111111111111111111111111111112"
|
|
704
|
+
? partnerFeeRecipient
|
|
705
|
+
: getAssociatedTokenAddressSync(
|
|
706
|
+
quoteToken,
|
|
707
|
+
partnerFeeRecipient,
|
|
708
|
+
false
|
|
709
|
+
),
|
|
710
|
+
isSigner: false,
|
|
711
|
+
isWritable: true,
|
|
712
|
+
},
|
|
713
|
+
]
|
|
714
|
+
: []
|
|
715
|
+
)
|
|
716
|
+
.instruction();
|
|
454
717
|
|
|
455
718
|
const computeFeeIx = ComputeBudgetProgram.setComputeUnitPrice({
|
|
456
719
|
microLamports: prioFee.toNumber(),
|
|
457
|
-
})
|
|
720
|
+
});
|
|
458
721
|
|
|
459
722
|
const messageV0 = new TransactionMessage({
|
|
460
723
|
payerKey: lavarageProgram.provider.publicKey!,
|
|
461
724
|
recentBlockhash: blockhash,
|
|
462
|
-
instructions: [
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
const { blockhash } =
|
|
479
|
-
|
|
480
|
-
const
|
|
481
|
-
delegate
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
725
|
+
instructions: [removeIx, ix, computeFeeIx].filter(Boolean),
|
|
726
|
+
}).compileToV0Message();
|
|
727
|
+
|
|
728
|
+
return new VersionedTransaction(messageV0);
|
|
729
|
+
};
|
|
730
|
+
|
|
731
|
+
export const removeTpDelegate = async (
|
|
732
|
+
lavarageProgram: Program<Lavarage> | Program<LavarageV2>,
|
|
733
|
+
position: ProgramAccount<{
|
|
734
|
+
pool: PublicKey;
|
|
735
|
+
seed: PublicKey;
|
|
736
|
+
userPaid: BN;
|
|
737
|
+
amount: BN;
|
|
738
|
+
}>,
|
|
739
|
+
prioFee: BN
|
|
740
|
+
) => {
|
|
741
|
+
const { blockhash } =
|
|
742
|
+
await lavarageProgram.provider.connection.getLatestBlockhash("finalized");
|
|
743
|
+
const delegatePda = getPda(
|
|
744
|
+
[Buffer.from("delegate"), position.publicKey.toBuffer()],
|
|
745
|
+
lavarageProgram.programId
|
|
746
|
+
);
|
|
747
|
+
const removeIx = await lavarageProgram.methods
|
|
748
|
+
.tradingRemoveTpDelegate()
|
|
749
|
+
.accountsStrict({
|
|
750
|
+
delegate: delegatePda,
|
|
751
|
+
originalOperator: lavarageProgram.provider.publicKey!,
|
|
752
|
+
delegatedAccount: position.publicKey,
|
|
753
|
+
systemProgram: SystemProgram.programId,
|
|
754
|
+
})
|
|
755
|
+
.instruction();
|
|
486
756
|
|
|
487
757
|
const computeFeeIx = ComputeBudgetProgram.setComputeUnitPrice({
|
|
488
758
|
microLamports: prioFee.toNumber(),
|
|
489
|
-
})
|
|
759
|
+
});
|
|
490
760
|
|
|
491
761
|
const messageV0 = new TransactionMessage({
|
|
492
762
|
payerKey: lavarageProgram.provider.publicKey!,
|
|
493
763
|
recentBlockhash: blockhash,
|
|
494
|
-
instructions: [
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
const
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
764
|
+
instructions: [removeIx, computeFeeIx].filter(Boolean),
|
|
765
|
+
}).compileToV0Message();
|
|
766
|
+
|
|
767
|
+
return new VersionedTransaction(messageV0);
|
|
768
|
+
};
|
|
769
|
+
|
|
770
|
+
export const partialRepayV1 = async (
|
|
771
|
+
lavarageProgram: Program<Lavarage>,
|
|
772
|
+
position: ProgramAccount<{
|
|
773
|
+
pool: PublicKey;
|
|
774
|
+
seed: PublicKey;
|
|
775
|
+
userPaid: BN;
|
|
776
|
+
amount: BN;
|
|
777
|
+
}>,
|
|
778
|
+
repaymentBps: number
|
|
779
|
+
) => {
|
|
780
|
+
const { blockhash } =
|
|
781
|
+
await lavarageProgram.provider.connection.getLatestBlockhash("finalized");
|
|
782
|
+
const pool = await lavarageProgram.account.pool.fetch(position.account.pool);
|
|
783
|
+
const positionAccountPDA = position.publicKey;
|
|
784
|
+
const ix = await lavarageProgram.methods
|
|
785
|
+
.tradingClosePartialRepaySol(new BN(repaymentBps))
|
|
786
|
+
.accountsStrict({
|
|
787
|
+
systemProgram: SystemProgram.programId,
|
|
788
|
+
positionAccount: positionAccountPDA,
|
|
789
|
+
tradingPool: position.account.pool,
|
|
790
|
+
nodeWallet: pool.nodeWallet,
|
|
791
|
+
trader: lavarageProgram.provider.publicKey!,
|
|
792
|
+
clock: SYSVAR_CLOCK_PUBKEY,
|
|
793
|
+
randomAccountAsId: position.account.seed,
|
|
794
|
+
feeReceipient: "6JfTobDvwuwZxZP6FR5JPmjdvQ4h4MovkEVH2FPsMSrF",
|
|
795
|
+
})
|
|
796
|
+
.instruction();
|
|
522
797
|
const messageV0 = new TransactionMessage({
|
|
523
798
|
payerKey: lavarageProgram.provider.publicKey!,
|
|
524
799
|
recentBlockhash: blockhash,
|
|
525
800
|
instructions: [ix],
|
|
526
|
-
}).compileToV0Message()
|
|
527
|
-
return new VersionedTransaction(messageV0)
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
export const partialRepayV2 = async (
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
801
|
+
}).compileToV0Message();
|
|
802
|
+
return new VersionedTransaction(messageV0);
|
|
803
|
+
};
|
|
804
|
+
|
|
805
|
+
export const partialRepayV2 = async (
|
|
806
|
+
lavarageProgram: Program<LavarageV2>,
|
|
807
|
+
position: ProgramAccount<{
|
|
808
|
+
pool: PublicKey;
|
|
809
|
+
seed: PublicKey;
|
|
810
|
+
userPaid: BN;
|
|
811
|
+
amount: BN;
|
|
812
|
+
}>,
|
|
813
|
+
repaymentBps: number
|
|
814
|
+
) => {
|
|
815
|
+
const { blockhash } =
|
|
816
|
+
await lavarageProgram.provider.connection.getLatestBlockhash("finalized");
|
|
817
|
+
const pool = await lavarageProgram.account.pool.fetch(position.account.pool);
|
|
818
|
+
const positionAccountPDA = position.publicKey;
|
|
819
|
+
const ix = await lavarageProgram.methods
|
|
820
|
+
.tradingPartialRepaySol(new BN(repaymentBps))
|
|
821
|
+
.accountsStrict({
|
|
822
|
+
systemProgram: SystemProgram.programId,
|
|
823
|
+
positionAccount: positionAccountPDA,
|
|
824
|
+
tradingPool: position.account.pool,
|
|
825
|
+
nodeWallet: pool.nodeWallet,
|
|
826
|
+
trader: lavarageProgram.provider.publicKey!,
|
|
827
|
+
clock: SYSVAR_CLOCK_PUBKEY,
|
|
828
|
+
randomAccountAsId: position.account.seed,
|
|
829
|
+
fromTokenAccount: getAssociatedTokenAddressSync(
|
|
830
|
+
pool.qtType,
|
|
831
|
+
lavarageProgram.provider.publicKey!
|
|
832
|
+
),
|
|
833
|
+
toTokenAccount: getAssociatedTokenAddressSync(
|
|
834
|
+
pool.qtType,
|
|
835
|
+
pool.nodeWallet,
|
|
836
|
+
true
|
|
837
|
+
),
|
|
838
|
+
mint: pool.qtType,
|
|
839
|
+
feeTokenAccount: getAssociatedTokenAddressSync(
|
|
840
|
+
pool.qtType,
|
|
841
|
+
new PublicKey("6JfTobDvwuwZxZP6FR5JPmjdvQ4h4MovkEVH2FPsMSrF")
|
|
842
|
+
),
|
|
843
|
+
tokenProgram: TOKEN_PROGRAM_ID,
|
|
844
|
+
})
|
|
845
|
+
.instruction();
|
|
553
846
|
|
|
554
847
|
const messageV0 = new TransactionMessage({
|
|
555
848
|
payerKey: lavarageProgram.provider.publicKey!,
|
|
556
849
|
recentBlockhash: blockhash,
|
|
557
850
|
instructions: [ix],
|
|
558
|
-
}).compileToV0Message()
|
|
559
|
-
|
|
560
|
-
return new VersionedTransaction(messageV0)
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
export const closeTradeV1 = async (
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
851
|
+
}).compileToV0Message();
|
|
852
|
+
|
|
853
|
+
return new VersionedTransaction(messageV0);
|
|
854
|
+
};
|
|
855
|
+
|
|
856
|
+
export const closeTradeV1 = async (
|
|
857
|
+
lavarageProgram: Program<Lavarage>,
|
|
858
|
+
position: ProgramAccount<{
|
|
859
|
+
pool: PublicKey;
|
|
860
|
+
seed: PublicKey;
|
|
861
|
+
userPaid: BN;
|
|
862
|
+
amount: BN;
|
|
863
|
+
}>,
|
|
864
|
+
offer: ProgramAccount<{
|
|
865
|
+
nodeWallet: PublicKey;
|
|
866
|
+
interestRate: number;
|
|
867
|
+
collateralType: PublicKey;
|
|
868
|
+
}>,
|
|
869
|
+
jupInstruction: {
|
|
870
|
+
instructions?: {
|
|
871
|
+
setupInstructions: Record<string, unknown>[];
|
|
872
|
+
swapInstruction: Record<string, unknown>;
|
|
873
|
+
cleanupInstruction: Record<string, unknown>;
|
|
874
|
+
addressLookupTableAddresses: string[];
|
|
875
|
+
tokenLedgerInstruction?: Record<string, unknown>;
|
|
876
|
+
};
|
|
877
|
+
quoteResponse: any;
|
|
579
878
|
},
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
879
|
+
partnerFeeRecipient?: PublicKey,
|
|
880
|
+
partnerFeeMarkup?: number
|
|
881
|
+
) => {
|
|
882
|
+
let partnerFeeMarkupAsPkey;
|
|
583
883
|
if (partnerFeeMarkup) {
|
|
584
|
-
const feeBuffer = Buffer.alloc(8)
|
|
585
|
-
feeBuffer.writeBigUInt64LE(BigInt(partnerFeeMarkup))
|
|
586
|
-
const feeBuffer32 = Buffer.alloc(32)
|
|
587
|
-
feeBuffer32.set(feeBuffer, 0)
|
|
588
|
-
partnerFeeMarkupAsPkey = new PublicKey(feeBuffer32)
|
|
884
|
+
const feeBuffer = Buffer.alloc(8);
|
|
885
|
+
feeBuffer.writeBigUInt64LE(BigInt(partnerFeeMarkup));
|
|
886
|
+
const feeBuffer32 = Buffer.alloc(32);
|
|
887
|
+
feeBuffer32.set(feeBuffer, 0);
|
|
888
|
+
partnerFeeMarkupAsPkey = new PublicKey(feeBuffer32);
|
|
589
889
|
}
|
|
590
|
-
if (position.account.pool.toBase58() != offer.publicKey.toBase58())
|
|
591
|
-
|
|
592
|
-
const
|
|
593
|
-
|
|
594
|
-
const tokenAddressPubKey = new PublicKey(offer.account.collateralType)
|
|
890
|
+
if (position.account.pool.toBase58() != offer.publicKey.toBase58())
|
|
891
|
+
throw "Mismatch offer";
|
|
892
|
+
const pool = offer;
|
|
893
|
+
const poolPubKey = offer.publicKey;
|
|
595
894
|
|
|
596
|
-
const
|
|
597
|
-
const tokenProgram = mintAccount?.owner
|
|
895
|
+
const tokenAddressPubKey = new PublicKey(offer.account.collateralType);
|
|
598
896
|
|
|
599
|
-
const
|
|
897
|
+
const mintAccount = await lavarageProgram.provider.connection.getAccountInfo(
|
|
898
|
+
offer.account.collateralType
|
|
899
|
+
);
|
|
900
|
+
const tokenProgram = mintAccount?.owner;
|
|
600
901
|
|
|
601
|
-
const
|
|
902
|
+
const positionAccountPDA = position.publicKey;
|
|
602
903
|
|
|
603
|
-
const
|
|
904
|
+
const fromTokenAccount = await getTokenAccountOrCreateIfNotExists(
|
|
905
|
+
lavarageProgram,
|
|
906
|
+
positionAccountPDA,
|
|
907
|
+
tokenAddressPubKey,
|
|
908
|
+
tokenProgram
|
|
909
|
+
);
|
|
604
910
|
|
|
605
|
-
const
|
|
911
|
+
const toTokenAccount = await getTokenAccountOrCreateIfNotExists(
|
|
912
|
+
lavarageProgram,
|
|
913
|
+
lavarageProgram.provider.publicKey!,
|
|
914
|
+
tokenAddressPubKey,
|
|
915
|
+
tokenProgram
|
|
916
|
+
);
|
|
606
917
|
|
|
918
|
+
const jupiterSellIx = jupInstruction!.instructions;
|
|
607
919
|
|
|
608
920
|
const deserializeInstruction = (instruction: any) => {
|
|
609
921
|
return new TransactionInstruction({
|
|
@@ -614,34 +926,38 @@ export const closeTradeV1 = async (lavarageProgram: Program<Lavarage>, position:
|
|
|
614
926
|
isSigner: key.isSigner,
|
|
615
927
|
isWritable: key.isWritable,
|
|
616
928
|
})),
|
|
617
|
-
data: Buffer.from(instruction.data,
|
|
618
|
-
})
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
const getAddressLookupTableAccounts = async (
|
|
622
|
-
|
|
929
|
+
data: Buffer.from(instruction.data, "base64"),
|
|
930
|
+
});
|
|
931
|
+
};
|
|
932
|
+
|
|
933
|
+
const getAddressLookupTableAccounts = async (
|
|
934
|
+
keys: string[]
|
|
935
|
+
): Promise<AddressLookupTableAccount[]> => {
|
|
936
|
+
const addressLookupTableAccountInfos =
|
|
937
|
+
await lavarageProgram.provider.connection.getMultipleAccountsInfo(
|
|
938
|
+
keys.map((key) => new PublicKey(key))
|
|
939
|
+
);
|
|
623
940
|
|
|
624
941
|
return addressLookupTableAccountInfos.reduce((acc, accountInfo, index) => {
|
|
625
|
-
const addressLookupTableAddress = keys[index]
|
|
942
|
+
const addressLookupTableAddress = keys[index];
|
|
626
943
|
if (accountInfo) {
|
|
627
944
|
const addressLookupTableAccount = new AddressLookupTableAccount({
|
|
628
945
|
key: new PublicKey(addressLookupTableAddress),
|
|
629
|
-
state: AddressLookupTableAccount.deserialize(
|
|
630
|
-
|
|
631
|
-
|
|
946
|
+
state: AddressLookupTableAccount.deserialize(
|
|
947
|
+
Uint8Array.from(accountInfo.data)
|
|
948
|
+
),
|
|
949
|
+
});
|
|
950
|
+
acc.push(addressLookupTableAccount);
|
|
632
951
|
}
|
|
633
952
|
|
|
634
|
-
return acc
|
|
635
|
-
}, new Array<AddressLookupTableAccount>())
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
const addressLookupTableAccounts: AddressLookupTableAccount[] = []
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
const { blockhash } = await lavarageProgram.provider.connection.getLatestBlockhash('finalized')
|
|
953
|
+
return acc;
|
|
954
|
+
}, new Array<AddressLookupTableAccount>());
|
|
955
|
+
};
|
|
643
956
|
|
|
957
|
+
const addressLookupTableAccounts: AddressLookupTableAccount[] = [];
|
|
644
958
|
|
|
959
|
+
const { blockhash } =
|
|
960
|
+
await lavarageProgram.provider.connection.getLatestBlockhash("finalized");
|
|
645
961
|
|
|
646
962
|
const closePositionIx = await lavarageProgram.methods
|
|
647
963
|
.tradingCloseBorrowCollateral()
|
|
@@ -658,13 +974,16 @@ export const closeTradeV1 = async (lavarageProgram: Program<Lavarage>, position:
|
|
|
658
974
|
tokenProgram: tokenProgram!,
|
|
659
975
|
randomAccountAsId: position.account.seed,
|
|
660
976
|
})
|
|
661
|
-
.instruction()
|
|
977
|
+
.instruction();
|
|
662
978
|
|
|
663
|
-
let repaySolIx: TransactionInstruction | null = null
|
|
664
|
-
let jupiterIxs: TransactionInstruction[] = []
|
|
979
|
+
let repaySolIx: TransactionInstruction | null = null;
|
|
980
|
+
let jupiterIxs: TransactionInstruction[] = [];
|
|
665
981
|
if (jupInstruction.instructions == undefined) {
|
|
666
982
|
repaySolIx = await lavarageProgram.methods
|
|
667
|
-
.tradingCloseRepaySol(
|
|
983
|
+
.tradingCloseRepaySol(
|
|
984
|
+
new BN(jupInstruction.quoteResponse.outAmount),
|
|
985
|
+
new BN(9997)
|
|
986
|
+
)
|
|
668
987
|
.accountsStrict({
|
|
669
988
|
nodeWallet: pool.account.nodeWallet,
|
|
670
989
|
positionAccount: positionAccountPDA,
|
|
@@ -673,21 +992,31 @@ export const closeTradeV1 = async (lavarageProgram: Program<Lavarage>, position:
|
|
|
673
992
|
systemProgram: SystemProgram.programId,
|
|
674
993
|
clock: SYSVAR_CLOCK_PUBKEY,
|
|
675
994
|
randomAccountAsId: position.account.seed,
|
|
676
|
-
feeReceipient:
|
|
995
|
+
feeReceipient: "6JfTobDvwuwZxZP6FR5JPmjdvQ4h4MovkEVH2FPsMSrF",
|
|
677
996
|
})
|
|
678
|
-
.remainingAccounts(
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
997
|
+
.remainingAccounts(
|
|
998
|
+
partnerFeeRecipient && partnerFeeMarkupAsPkey
|
|
999
|
+
? [
|
|
1000
|
+
{
|
|
1001
|
+
pubkey: partnerFeeRecipient,
|
|
1002
|
+
isSigner: false,
|
|
1003
|
+
isWritable: true,
|
|
1004
|
+
},
|
|
1005
|
+
{
|
|
1006
|
+
pubkey: partnerFeeMarkupAsPkey,
|
|
1007
|
+
isSigner: false,
|
|
1008
|
+
isWritable: false,
|
|
1009
|
+
},
|
|
1010
|
+
]
|
|
1011
|
+
: []
|
|
1012
|
+
)
|
|
1013
|
+
.instruction();
|
|
688
1014
|
} else {
|
|
689
1015
|
repaySolIx = await lavarageProgram.methods
|
|
690
|
-
.tradingCloseRepaySol(
|
|
1016
|
+
.tradingCloseRepaySol(
|
|
1017
|
+
new BN(jupInstruction.quoteResponse.outAmount),
|
|
1018
|
+
new BN(9998)
|
|
1019
|
+
)
|
|
691
1020
|
.accountsStrict({
|
|
692
1021
|
nodeWallet: pool.account.nodeWallet,
|
|
693
1022
|
positionAccount: positionAccountPDA,
|
|
@@ -696,102 +1025,149 @@ export const closeTradeV1 = async (lavarageProgram: Program<Lavarage>, position:
|
|
|
696
1025
|
systemProgram: SystemProgram.programId,
|
|
697
1026
|
clock: SYSVAR_CLOCK_PUBKEY,
|
|
698
1027
|
randomAccountAsId: position.account.seed,
|
|
699
|
-
feeReceipient:
|
|
1028
|
+
feeReceipient: "6JfTobDvwuwZxZP6FR5JPmjdvQ4h4MovkEVH2FPsMSrF",
|
|
700
1029
|
})
|
|
701
|
-
.remainingAccounts(
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
1030
|
+
.remainingAccounts(
|
|
1031
|
+
partnerFeeRecipient && partnerFeeMarkupAsPkey
|
|
1032
|
+
? [
|
|
1033
|
+
{
|
|
1034
|
+
pubkey: partnerFeeRecipient,
|
|
1035
|
+
isSigner: false,
|
|
1036
|
+
isWritable: true,
|
|
1037
|
+
},
|
|
1038
|
+
{
|
|
1039
|
+
pubkey: partnerFeeMarkupAsPkey,
|
|
1040
|
+
isSigner: false,
|
|
1041
|
+
isWritable: false,
|
|
1042
|
+
},
|
|
1043
|
+
]
|
|
1044
|
+
: []
|
|
1045
|
+
)
|
|
1046
|
+
.instruction();
|
|
1047
|
+
const {
|
|
1048
|
+
setupInstructions,
|
|
1049
|
+
swapInstruction: swapInstructionPayload,
|
|
1050
|
+
cleanupInstruction,
|
|
1051
|
+
addressLookupTableAddresses,
|
|
1052
|
+
} = jupiterSellIx!;
|
|
712
1053
|
jupiterIxs = [
|
|
713
1054
|
...setupInstructions.map(deserializeInstruction),
|
|
714
1055
|
deserializeInstruction(swapInstructionPayload),
|
|
715
1056
|
deserializeInstruction(cleanupInstruction),
|
|
716
|
-
]
|
|
717
|
-
addressLookupTableAccounts.push(
|
|
1057
|
+
];
|
|
1058
|
+
addressLookupTableAccounts.push(
|
|
1059
|
+
...(await getAddressLookupTableAccounts([
|
|
1060
|
+
"5LEAB3owNUSKvECm7vkr58tDtQpzbngQ2NYpc7qmRFdi",
|
|
1061
|
+
...addressLookupTableAddresses,
|
|
1062
|
+
]))
|
|
1063
|
+
);
|
|
718
1064
|
}
|
|
719
|
-
const profit = new BN(jupInstruction.quoteResponse.outAmount)
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
1065
|
+
const profit = new BN(jupInstruction.quoteResponse.outAmount)
|
|
1066
|
+
.sub(position.account.amount)
|
|
1067
|
+
.sub(position.account.userPaid);
|
|
1068
|
+
|
|
1069
|
+
let createAssociatedTokenAccountInstruction =
|
|
1070
|
+
createAssociatedTokenAccountIdempotentInstruction(
|
|
1071
|
+
lavarageProgram.provider.publicKey!,
|
|
1072
|
+
toTokenAccount.account!.address,
|
|
1073
|
+
lavarageProgram.provider.publicKey!,
|
|
1074
|
+
offer.account.collateralType,
|
|
1075
|
+
tokenProgram!
|
|
1076
|
+
);
|
|
728
1077
|
const allInstructions = [
|
|
729
|
-
jupInstruction.instructions?.tokenLedgerInstruction
|
|
730
|
-
|
|
1078
|
+
jupInstruction.instructions?.tokenLedgerInstruction
|
|
1079
|
+
? createAssociatedTokenAccountInstruction
|
|
1080
|
+
: null,
|
|
1081
|
+
jupInstruction.instructions?.tokenLedgerInstruction
|
|
1082
|
+
? deserializeInstruction(
|
|
1083
|
+
jupInstruction.instructions.tokenLedgerInstruction
|
|
1084
|
+
)
|
|
1085
|
+
: null,
|
|
731
1086
|
toTokenAccount.instruction!,
|
|
732
1087
|
closePositionIx,
|
|
733
1088
|
...jupiterIxs,
|
|
734
1089
|
repaySolIx,
|
|
735
|
-
].filter(i => !!i)
|
|
1090
|
+
].filter((i) => !!i);
|
|
736
1091
|
|
|
737
1092
|
const messageV0 = new TransactionMessage({
|
|
738
1093
|
payerKey: lavarageProgram.provider.publicKey!,
|
|
739
1094
|
recentBlockhash: blockhash,
|
|
740
1095
|
instructions: allInstructions,
|
|
741
|
-
}).compileToV0Message(addressLookupTableAccounts)
|
|
742
|
-
|
|
743
|
-
const tx = new VersionedTransaction(messageV0)
|
|
744
|
-
|
|
745
|
-
return tx
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
export const closeTradeV2 = async (
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
1096
|
+
}).compileToV0Message(addressLookupTableAccounts);
|
|
1097
|
+
|
|
1098
|
+
const tx = new VersionedTransaction(messageV0);
|
|
1099
|
+
|
|
1100
|
+
return tx;
|
|
1101
|
+
};
|
|
1102
|
+
|
|
1103
|
+
export const closeTradeV2 = async (
|
|
1104
|
+
lavarageProgram: Program<LavarageV2>,
|
|
1105
|
+
position: ProgramAccount<{
|
|
1106
|
+
pool: PublicKey;
|
|
1107
|
+
seed: PublicKey;
|
|
1108
|
+
userPaid: BN;
|
|
1109
|
+
amount: BN;
|
|
1110
|
+
}>,
|
|
1111
|
+
offer: ProgramAccount<{
|
|
1112
|
+
nodeWallet: PublicKey;
|
|
1113
|
+
interestRate: number;
|
|
1114
|
+
collateralType: PublicKey;
|
|
1115
|
+
}>,
|
|
1116
|
+
jupInstruction: {
|
|
1117
|
+
instructions?: {
|
|
1118
|
+
setupInstructions: Record<string, unknown>[];
|
|
1119
|
+
swapInstruction: Record<string, unknown>;
|
|
1120
|
+
cleanupInstruction: Record<string, unknown>;
|
|
1121
|
+
addressLookupTableAddresses: string[];
|
|
1122
|
+
tokenLedgerInstruction?: Record<string, unknown>;
|
|
1123
|
+
};
|
|
1124
|
+
quoteResponse: any;
|
|
764
1125
|
},
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
1126
|
+
quoteToken: PublicKey,
|
|
1127
|
+
partnerFeeRecipient?: PublicKey,
|
|
1128
|
+
partnerFeeMarkup?: number
|
|
1129
|
+
) => {
|
|
1130
|
+
let partnerFeeMarkupAsPkey;
|
|
768
1131
|
if (partnerFeeMarkup) {
|
|
769
|
-
const feeBuffer = Buffer.alloc(8)
|
|
770
|
-
feeBuffer.writeBigUInt64LE(BigInt(partnerFeeMarkup))
|
|
771
|
-
const feeBuffer32 = Buffer.alloc(32)
|
|
772
|
-
feeBuffer32.set(feeBuffer, 0)
|
|
773
|
-
partnerFeeMarkupAsPkey = new PublicKey(feeBuffer32)
|
|
1132
|
+
const feeBuffer = Buffer.alloc(8);
|
|
1133
|
+
feeBuffer.writeBigUInt64LE(BigInt(partnerFeeMarkup));
|
|
1134
|
+
const feeBuffer32 = Buffer.alloc(32);
|
|
1135
|
+
feeBuffer32.set(feeBuffer, 0);
|
|
1136
|
+
partnerFeeMarkupAsPkey = new PublicKey(feeBuffer32);
|
|
774
1137
|
}
|
|
775
|
-
if (position.account.pool.toBase58() != offer.publicKey.toBase58())
|
|
776
|
-
|
|
777
|
-
const
|
|
778
|
-
|
|
779
|
-
const tokenAddressPubKey = new PublicKey(offer.account.collateralType)
|
|
1138
|
+
if (position.account.pool.toBase58() != offer.publicKey.toBase58())
|
|
1139
|
+
throw "Mismatch offer";
|
|
1140
|
+
const pool = offer;
|
|
1141
|
+
const poolPubKey = offer.publicKey;
|
|
780
1142
|
|
|
781
|
-
const
|
|
782
|
-
const tokenProgram = mintAccount?.owner
|
|
1143
|
+
const tokenAddressPubKey = new PublicKey(offer.account.collateralType);
|
|
783
1144
|
|
|
784
|
-
const
|
|
785
|
-
|
|
1145
|
+
const mintAccount = await lavarageProgram.provider.connection.getAccountInfo(
|
|
1146
|
+
offer.account.collateralType
|
|
1147
|
+
);
|
|
1148
|
+
const tokenProgram = mintAccount?.owner;
|
|
786
1149
|
|
|
787
|
-
const
|
|
1150
|
+
const quoteMintAccount =
|
|
1151
|
+
await lavarageProgram.provider.connection.getAccountInfo(quoteToken);
|
|
1152
|
+
const quoteTokenProgram = quoteMintAccount?.owner;
|
|
788
1153
|
|
|
789
|
-
const
|
|
1154
|
+
const positionAccountPDA = position.publicKey;
|
|
790
1155
|
|
|
791
|
-
const
|
|
1156
|
+
const fromTokenAccount = await getTokenAccountOrCreateIfNotExists(
|
|
1157
|
+
lavarageProgram,
|
|
1158
|
+
positionAccountPDA,
|
|
1159
|
+
tokenAddressPubKey,
|
|
1160
|
+
tokenProgram
|
|
1161
|
+
);
|
|
792
1162
|
|
|
793
|
-
const
|
|
1163
|
+
const toTokenAccount = await getTokenAccountOrCreateIfNotExists(
|
|
1164
|
+
lavarageProgram,
|
|
1165
|
+
lavarageProgram.provider.publicKey!,
|
|
1166
|
+
tokenAddressPubKey,
|
|
1167
|
+
tokenProgram
|
|
1168
|
+
);
|
|
794
1169
|
|
|
1170
|
+
const jupiterSellIx = jupInstruction!.instructions;
|
|
795
1171
|
|
|
796
1172
|
const deserializeInstruction = (instruction: any) => {
|
|
797
1173
|
return new TransactionInstruction({
|
|
@@ -802,30 +1178,38 @@ export const closeTradeV2 = async (lavarageProgram: Program<LavarageV2>, positio
|
|
|
802
1178
|
isSigner: key.isSigner,
|
|
803
1179
|
isWritable: key.isWritable,
|
|
804
1180
|
})),
|
|
805
|
-
data: Buffer.from(instruction.data,
|
|
806
|
-
})
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
const getAddressLookupTableAccounts = async (
|
|
810
|
-
|
|
1181
|
+
data: Buffer.from(instruction.data, "base64"),
|
|
1182
|
+
});
|
|
1183
|
+
};
|
|
1184
|
+
|
|
1185
|
+
const getAddressLookupTableAccounts = async (
|
|
1186
|
+
keys: string[]
|
|
1187
|
+
): Promise<AddressLookupTableAccount[]> => {
|
|
1188
|
+
const addressLookupTableAccountInfos =
|
|
1189
|
+
await lavarageProgram.provider.connection.getMultipleAccountsInfo(
|
|
1190
|
+
keys.map((key) => new PublicKey(key))
|
|
1191
|
+
);
|
|
811
1192
|
|
|
812
1193
|
return addressLookupTableAccountInfos.reduce((acc, accountInfo, index) => {
|
|
813
|
-
const addressLookupTableAddress = keys[index]
|
|
1194
|
+
const addressLookupTableAddress = keys[index];
|
|
814
1195
|
if (accountInfo) {
|
|
815
1196
|
const addressLookupTableAccount = new AddressLookupTableAccount({
|
|
816
1197
|
key: new PublicKey(addressLookupTableAddress),
|
|
817
|
-
state: AddressLookupTableAccount.deserialize(
|
|
818
|
-
|
|
819
|
-
|
|
1198
|
+
state: AddressLookupTableAccount.deserialize(
|
|
1199
|
+
Uint8Array.from(accountInfo.data)
|
|
1200
|
+
),
|
|
1201
|
+
});
|
|
1202
|
+
acc.push(addressLookupTableAccount);
|
|
820
1203
|
}
|
|
821
1204
|
|
|
822
|
-
return acc
|
|
823
|
-
}, new Array<AddressLookupTableAccount>())
|
|
824
|
-
}
|
|
1205
|
+
return acc;
|
|
1206
|
+
}, new Array<AddressLookupTableAccount>());
|
|
1207
|
+
};
|
|
825
1208
|
|
|
826
|
-
const addressLookupTableAccounts: AddressLookupTableAccount[] = []
|
|
1209
|
+
const addressLookupTableAccounts: AddressLookupTableAccount[] = [];
|
|
827
1210
|
|
|
828
|
-
const { blockhash } =
|
|
1211
|
+
const { blockhash } =
|
|
1212
|
+
await lavarageProgram.provider.connection.getLatestBlockhash("finalized");
|
|
829
1213
|
|
|
830
1214
|
const closePositionIx = await lavarageProgram.methods
|
|
831
1215
|
.tradingCloseBorrowCollateral()
|
|
@@ -842,13 +1226,16 @@ export const closeTradeV2 = async (lavarageProgram: Program<LavarageV2>, positio
|
|
|
842
1226
|
tokenProgram: tokenProgram!,
|
|
843
1227
|
randomAccountAsId: position.account.seed,
|
|
844
1228
|
})
|
|
845
|
-
.instruction()
|
|
1229
|
+
.instruction();
|
|
846
1230
|
|
|
847
|
-
let repaySolIx: TransactionInstruction | null = null
|
|
848
|
-
let jupiterIxs: TransactionInstruction[] = []
|
|
1231
|
+
let repaySolIx: TransactionInstruction | null = null;
|
|
1232
|
+
let jupiterIxs: TransactionInstruction[] = [];
|
|
849
1233
|
if (jupInstruction.instructions == undefined) {
|
|
850
1234
|
repaySolIx = await lavarageProgram.methods
|
|
851
|
-
.tradingCloseRepaySol(
|
|
1235
|
+
.tradingCloseRepaySol(
|
|
1236
|
+
new BN(jupInstruction.quoteResponse.outAmount),
|
|
1237
|
+
new BN(9997)
|
|
1238
|
+
)
|
|
852
1239
|
.accountsStrict({
|
|
853
1240
|
nodeWallet: pool.account.nodeWallet,
|
|
854
1241
|
positionAccount: positionAccountPDA,
|
|
@@ -857,25 +1244,55 @@ export const closeTradeV2 = async (lavarageProgram: Program<LavarageV2>, positio
|
|
|
857
1244
|
systemProgram: SystemProgram.programId,
|
|
858
1245
|
clock: SYSVAR_CLOCK_PUBKEY,
|
|
859
1246
|
randomAccountAsId: position.account.seed,
|
|
860
|
-
feeTokenAccount: getAssociatedTokenAddressSync(
|
|
861
|
-
|
|
1247
|
+
feeTokenAccount: getAssociatedTokenAddressSync(
|
|
1248
|
+
quoteToken,
|
|
1249
|
+
new PublicKey("6JfTobDvwuwZxZP6FR5JPmjdvQ4h4MovkEVH2FPsMSrF"),
|
|
1250
|
+
false,
|
|
1251
|
+
quoteTokenProgram
|
|
1252
|
+
),
|
|
1253
|
+
fromTokenAccount: getAssociatedTokenAddressSync(
|
|
1254
|
+
quoteToken,
|
|
1255
|
+
lavarageProgram.provider.publicKey!,
|
|
1256
|
+
false,
|
|
1257
|
+
quoteTokenProgram
|
|
1258
|
+
),
|
|
862
1259
|
tokenProgram: quoteTokenProgram!,
|
|
863
|
-
toTokenAccount: getAssociatedTokenAddressSync(
|
|
1260
|
+
toTokenAccount: getAssociatedTokenAddressSync(
|
|
1261
|
+
quoteToken,
|
|
1262
|
+
pool.account.nodeWallet,
|
|
1263
|
+
true,
|
|
1264
|
+
quoteTokenProgram
|
|
1265
|
+
),
|
|
864
1266
|
mint: quoteToken,
|
|
865
1267
|
})
|
|
866
|
-
.remainingAccounts(
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
1268
|
+
.remainingAccounts(
|
|
1269
|
+
partnerFeeRecipient && partnerFeeMarkupAsPkey
|
|
1270
|
+
? [
|
|
1271
|
+
{
|
|
1272
|
+
pubkey: getAssociatedTokenAddressSync(
|
|
1273
|
+
quoteToken,
|
|
1274
|
+
partnerFeeRecipient,
|
|
1275
|
+
false,
|
|
1276
|
+
quoteTokenProgram
|
|
1277
|
+
),
|
|
1278
|
+
isSigner: false,
|
|
1279
|
+
isWritable: true,
|
|
1280
|
+
},
|
|
1281
|
+
{
|
|
1282
|
+
pubkey: partnerFeeMarkupAsPkey,
|
|
1283
|
+
isSigner: false,
|
|
1284
|
+
isWritable: false,
|
|
1285
|
+
},
|
|
1286
|
+
]
|
|
1287
|
+
: []
|
|
1288
|
+
)
|
|
1289
|
+
.instruction();
|
|
876
1290
|
} else {
|
|
877
1291
|
repaySolIx = await lavarageProgram.methods
|
|
878
|
-
.tradingCloseRepaySol(
|
|
1292
|
+
.tradingCloseRepaySol(
|
|
1293
|
+
new BN(jupInstruction.quoteResponse.outAmount),
|
|
1294
|
+
new BN(9998)
|
|
1295
|
+
)
|
|
879
1296
|
.accountsStrict({
|
|
880
1297
|
nodeWallet: pool.account.nodeWallet,
|
|
881
1298
|
positionAccount: positionAccountPDA,
|
|
@@ -884,127 +1301,213 @@ export const closeTradeV2 = async (lavarageProgram: Program<LavarageV2>, positio
|
|
|
884
1301
|
systemProgram: SystemProgram.programId,
|
|
885
1302
|
clock: SYSVAR_CLOCK_PUBKEY,
|
|
886
1303
|
randomAccountAsId: position.account.seed,
|
|
887
|
-
feeTokenAccount: getAssociatedTokenAddressSync(
|
|
888
|
-
|
|
1304
|
+
feeTokenAccount: getAssociatedTokenAddressSync(
|
|
1305
|
+
quoteToken,
|
|
1306
|
+
new PublicKey("6JfTobDvwuwZxZP6FR5JPmjdvQ4h4MovkEVH2FPsMSrF"),
|
|
1307
|
+
false,
|
|
1308
|
+
quoteTokenProgram
|
|
1309
|
+
),
|
|
1310
|
+
fromTokenAccount: getAssociatedTokenAddressSync(
|
|
1311
|
+
quoteToken,
|
|
1312
|
+
lavarageProgram.provider.publicKey!,
|
|
1313
|
+
false,
|
|
1314
|
+
quoteTokenProgram
|
|
1315
|
+
),
|
|
889
1316
|
tokenProgram: quoteTokenProgram!,
|
|
890
|
-
toTokenAccount: getAssociatedTokenAddressSync(
|
|
1317
|
+
toTokenAccount: getAssociatedTokenAddressSync(
|
|
1318
|
+
quoteToken,
|
|
1319
|
+
pool.account.nodeWallet,
|
|
1320
|
+
true,
|
|
1321
|
+
quoteTokenProgram
|
|
1322
|
+
),
|
|
891
1323
|
mint: quoteToken,
|
|
892
1324
|
})
|
|
893
|
-
.remainingAccounts(
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
1325
|
+
.remainingAccounts(
|
|
1326
|
+
partnerFeeRecipient && partnerFeeMarkupAsPkey
|
|
1327
|
+
? [
|
|
1328
|
+
{
|
|
1329
|
+
pubkey: partnerFeeRecipient,
|
|
1330
|
+
isSigner: false,
|
|
1331
|
+
isWritable: true,
|
|
1332
|
+
},
|
|
1333
|
+
{
|
|
1334
|
+
pubkey: partnerFeeMarkupAsPkey,
|
|
1335
|
+
isSigner: false,
|
|
1336
|
+
isWritable: false,
|
|
1337
|
+
},
|
|
1338
|
+
]
|
|
1339
|
+
: []
|
|
1340
|
+
)
|
|
1341
|
+
.instruction();
|
|
1342
|
+
const {
|
|
1343
|
+
setupInstructions,
|
|
1344
|
+
swapInstruction: swapInstructionPayload,
|
|
1345
|
+
cleanupInstruction,
|
|
1346
|
+
addressLookupTableAddresses,
|
|
1347
|
+
} = jupiterSellIx!;
|
|
904
1348
|
jupiterIxs = [
|
|
905
|
-
...setupInstructions.filter(i => !!i).map(deserializeInstruction),
|
|
906
|
-
swapInstructionPayload
|
|
1349
|
+
...setupInstructions.filter((i) => !!i).map(deserializeInstruction),
|
|
1350
|
+
swapInstructionPayload
|
|
1351
|
+
? deserializeInstruction(swapInstructionPayload)
|
|
1352
|
+
: null,
|
|
907
1353
|
cleanupInstruction ? deserializeInstruction(cleanupInstruction) : null,
|
|
908
|
-
].filter(i => !!i)
|
|
909
|
-
addressLookupTableAccounts.push(
|
|
1354
|
+
].filter((i) => !!i);
|
|
1355
|
+
addressLookupTableAccounts.push(
|
|
1356
|
+
...(await getAddressLookupTableAccounts([
|
|
1357
|
+
...addressLookupTableAddresses,
|
|
1358
|
+
getQuoteCurrencySpecificAddressLookupTable(quoteToken.toBase58()),
|
|
1359
|
+
"5LEAB3owNUSKvECm7vkr58tDtQpzbngQ2NYpc7qmRFdi",
|
|
1360
|
+
]))
|
|
1361
|
+
);
|
|
910
1362
|
}
|
|
911
|
-
const profit = new BN(jupInstruction.quoteResponse.outAmount)
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
1363
|
+
const profit = new BN(jupInstruction.quoteResponse.outAmount)
|
|
1364
|
+
.sub(position.account.amount)
|
|
1365
|
+
.sub(position.account.userPaid);
|
|
1366
|
+
|
|
1367
|
+
let createAssociatedTokenAccountInstruction =
|
|
1368
|
+
createAssociatedTokenAccountIdempotentInstruction(
|
|
1369
|
+
lavarageProgram.provider.publicKey!,
|
|
1370
|
+
toTokenAccount.account!.address,
|
|
1371
|
+
lavarageProgram.provider.publicKey!,
|
|
1372
|
+
offer.account.collateralType,
|
|
1373
|
+
tokenProgram!
|
|
1374
|
+
);
|
|
920
1375
|
const allInstructions = [
|
|
921
|
-
jupInstruction.instructions?.tokenLedgerInstruction
|
|
922
|
-
|
|
1376
|
+
jupInstruction.instructions?.tokenLedgerInstruction
|
|
1377
|
+
? createAssociatedTokenAccountInstruction
|
|
1378
|
+
: null,
|
|
1379
|
+
jupInstruction.instructions?.tokenLedgerInstruction
|
|
1380
|
+
? deserializeInstruction(
|
|
1381
|
+
jupInstruction.instructions.tokenLedgerInstruction
|
|
1382
|
+
)
|
|
1383
|
+
: null,
|
|
923
1384
|
toTokenAccount.instruction!,
|
|
924
1385
|
closePositionIx,
|
|
925
1386
|
...jupiterIxs,
|
|
926
1387
|
repaySolIx,
|
|
927
|
-
].filter(i => !!i)
|
|
1388
|
+
].filter((i) => !!i);
|
|
928
1389
|
|
|
929
1390
|
const messageV0 = new TransactionMessage({
|
|
930
1391
|
payerKey: lavarageProgram.provider.publicKey!,
|
|
931
1392
|
recentBlockhash: blockhash,
|
|
932
1393
|
instructions: allInstructions,
|
|
933
|
-
}).compileToV0Message(addressLookupTableAccounts)
|
|
934
|
-
|
|
935
|
-
const tx = new VersionedTransaction(messageV0)
|
|
936
|
-
|
|
937
|
-
return tx
|
|
938
|
-
}
|
|
939
|
-
|
|
940
|
-
export const getDelegateAccounts = async (
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
1394
|
+
}).compileToV0Message(addressLookupTableAccounts);
|
|
1395
|
+
|
|
1396
|
+
const tx = new VersionedTransaction(messageV0);
|
|
1397
|
+
|
|
1398
|
+
return tx;
|
|
1399
|
+
};
|
|
1400
|
+
|
|
1401
|
+
export const getDelegateAccounts = async (
|
|
1402
|
+
lavarageProgram: Program<Lavarage> | Program<LavarageV2>,
|
|
1403
|
+
userPubKey?: PublicKey
|
|
1404
|
+
) => {
|
|
1405
|
+
const delegateAccounts = await lavarageProgram.account.delegate.all(
|
|
1406
|
+
userPubKey
|
|
1407
|
+
? [
|
|
1408
|
+
{
|
|
1409
|
+
memcmp: {
|
|
1410
|
+
offset: 104,
|
|
1411
|
+
bytes: userPubKey.toBase58(),
|
|
1412
|
+
},
|
|
1413
|
+
},
|
|
1414
|
+
]
|
|
1415
|
+
: undefined
|
|
1416
|
+
);
|
|
1417
|
+
return delegateAccounts.map((d) => ({
|
|
948
1418
|
...d,
|
|
949
1419
|
parsed: {
|
|
950
1420
|
tpPrice: new BN(d.account.field1),
|
|
951
1421
|
tpThreshold: new BN(d.account.field2),
|
|
952
|
-
}
|
|
953
|
-
}))
|
|
954
|
-
}
|
|
1422
|
+
},
|
|
1423
|
+
}));
|
|
1424
|
+
};
|
|
955
1425
|
|
|
956
1426
|
const getQuoteCurrencySpecificAddressLookupTable = (quoteCurrency: string) => {
|
|
957
1427
|
switch (quoteCurrency) {
|
|
958
|
-
case
|
|
959
|
-
return
|
|
960
|
-
case
|
|
961
|
-
return
|
|
1428
|
+
case "J9BcrQfX4p9D1bvLzRNCbMDv8f44a9LFdeqNE4Yk2WMD":
|
|
1429
|
+
return "2EdNtwVhyjkEgkKDC7GShfSSczZYMKLuJraeoJzG4E4R";
|
|
1430
|
+
case "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v":
|
|
1431
|
+
return "CxLE1LRaZg2eYygzFfVRhgmSACsvqzyhySDrMHq3QSab";
|
|
962
1432
|
default:
|
|
963
|
-
return
|
|
1433
|
+
return "2EdNtwVhyjkEgkKDC7GShfSSczZYMKLuJraeoJzG4E4R";
|
|
964
1434
|
}
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
export const splitPositionV2 = async (
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
const
|
|
984
|
-
|
|
985
|
-
const
|
|
986
|
-
const
|
|
987
|
-
|
|
988
|
-
const
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
1435
|
+
};
|
|
1436
|
+
|
|
1437
|
+
export const splitPositionV2 = async (
|
|
1438
|
+
lavarageProgram: Program<LavarageV2>,
|
|
1439
|
+
position: ProgramAccount<{
|
|
1440
|
+
pool: PublicKey;
|
|
1441
|
+
seed: PublicKey;
|
|
1442
|
+
userPaid: BN;
|
|
1443
|
+
amount: BN;
|
|
1444
|
+
}>,
|
|
1445
|
+
offer: ProgramAccount<{
|
|
1446
|
+
nodeWallet: PublicKey;
|
|
1447
|
+
interestRate: number;
|
|
1448
|
+
collateralType: PublicKey;
|
|
1449
|
+
}>,
|
|
1450
|
+
quoteToken: PublicKey,
|
|
1451
|
+
propotionBps: number
|
|
1452
|
+
) => {
|
|
1453
|
+
const positionAccountPDA = position.publicKey;
|
|
1454
|
+
|
|
1455
|
+
const newPosition1Seed = Keypair.generate().publicKey;
|
|
1456
|
+
const newPosition2Seed = Keypair.generate().publicKey;
|
|
1457
|
+
|
|
1458
|
+
const newPosition1AccountPDA = getPositionAccountPDA(
|
|
1459
|
+
lavarageProgram,
|
|
1460
|
+
offer,
|
|
1461
|
+
newPosition1Seed
|
|
1462
|
+
);
|
|
1463
|
+
const newPosition2AccountPDA = getPositionAccountPDA(
|
|
1464
|
+
lavarageProgram,
|
|
1465
|
+
offer,
|
|
1466
|
+
newPosition2Seed
|
|
1467
|
+
);
|
|
1468
|
+
|
|
1469
|
+
const mintAccount = await lavarageProgram.provider.connection.getAccountInfo(
|
|
1470
|
+
offer.account.collateralType
|
|
1471
|
+
);
|
|
1472
|
+
const tokenProgram = mintAccount?.owner;
|
|
1473
|
+
|
|
1474
|
+
const newPosition1TokenAccount = getAssociatedTokenAddressSync(
|
|
1475
|
+
offer.account.collateralType,
|
|
994
1476
|
newPosition1AccountPDA,
|
|
1477
|
+
true,
|
|
1478
|
+
tokenProgram
|
|
1479
|
+
);
|
|
1480
|
+
const newPosition2TokenAccount = getAssociatedTokenAddressSync(
|
|
995
1481
|
offer.account.collateralType,
|
|
996
|
-
tokenProgram!,
|
|
997
|
-
)
|
|
998
|
-
|
|
999
|
-
const createNewPosition2TokenAccountIx = createAssociatedTokenAccountInstruction(
|
|
1000
|
-
lavarageProgram.provider.publicKey!,
|
|
1001
|
-
newPosition2TokenAccount,
|
|
1002
1482
|
newPosition2AccountPDA,
|
|
1003
|
-
|
|
1004
|
-
tokenProgram
|
|
1005
|
-
)
|
|
1006
|
-
|
|
1007
|
-
const
|
|
1483
|
+
true,
|
|
1484
|
+
tokenProgram
|
|
1485
|
+
);
|
|
1486
|
+
|
|
1487
|
+
const createNewPosition1TokenAccountIx =
|
|
1488
|
+
createAssociatedTokenAccountInstruction(
|
|
1489
|
+
lavarageProgram.provider.publicKey!,
|
|
1490
|
+
newPosition1TokenAccount,
|
|
1491
|
+
newPosition1AccountPDA,
|
|
1492
|
+
offer.account.collateralType,
|
|
1493
|
+
tokenProgram!
|
|
1494
|
+
);
|
|
1495
|
+
|
|
1496
|
+
const createNewPosition2TokenAccountIx =
|
|
1497
|
+
createAssociatedTokenAccountInstruction(
|
|
1498
|
+
lavarageProgram.provider.publicKey!,
|
|
1499
|
+
newPosition2TokenAccount,
|
|
1500
|
+
newPosition2AccountPDA,
|
|
1501
|
+
offer.account.collateralType,
|
|
1502
|
+
tokenProgram!
|
|
1503
|
+
);
|
|
1504
|
+
|
|
1505
|
+
const ix = await lavarageProgram.methods
|
|
1506
|
+
.tradingManagementSplitPosition(
|
|
1507
|
+
new BN(propotionBps),
|
|
1508
|
+
newPosition1Seed,
|
|
1509
|
+
newPosition2Seed
|
|
1510
|
+
)
|
|
1008
1511
|
.accountsStrict({
|
|
1009
1512
|
originalPosition: positionAccountPDA,
|
|
1010
1513
|
newPositionOne: newPosition1AccountPDA,
|
|
@@ -1013,72 +1516,97 @@ export const splitPositionV2 = async (lavarageProgram: Program<LavarageV2>, posi
|
|
|
1013
1516
|
systemProgram: SystemProgram.programId,
|
|
1014
1517
|
mint: offer.account.collateralType,
|
|
1015
1518
|
tokenProgram: tokenProgram!,
|
|
1016
|
-
originalPositionTokenAccount: getAssociatedTokenAddressSync(
|
|
1519
|
+
originalPositionTokenAccount: getAssociatedTokenAddressSync(
|
|
1520
|
+
offer.account.collateralType,
|
|
1521
|
+
positionAccountPDA,
|
|
1522
|
+
true,
|
|
1523
|
+
tokenProgram
|
|
1524
|
+
),
|
|
1017
1525
|
newPositionTokenAccountOne: newPosition1TokenAccount,
|
|
1018
1526
|
newPositionTokenAccountTwo: newPosition2TokenAccount,
|
|
1019
1527
|
})
|
|
1020
|
-
.instruction()
|
|
1528
|
+
.instruction();
|
|
1021
1529
|
|
|
1022
1530
|
const computeBudgetIx = ComputeBudgetProgram.setComputeUnitPrice({
|
|
1023
1531
|
microLamports: 100000,
|
|
1024
|
-
})
|
|
1532
|
+
});
|
|
1025
1533
|
|
|
1026
1534
|
const allInstructions = [
|
|
1027
1535
|
createNewPosition1TokenAccountIx,
|
|
1028
1536
|
createNewPosition2TokenAccountIx,
|
|
1029
1537
|
ix,
|
|
1030
1538
|
computeBudgetIx,
|
|
1031
|
-
].filter(i => !!i)
|
|
1539
|
+
].filter((i) => !!i);
|
|
1032
1540
|
|
|
1033
|
-
const { blockhash } =
|
|
1541
|
+
const { blockhash } =
|
|
1542
|
+
await lavarageProgram.provider.connection.getLatestBlockhash("finalized");
|
|
1034
1543
|
|
|
1035
1544
|
const messageV0 = new TransactionMessage({
|
|
1036
1545
|
payerKey: lavarageProgram.provider.publicKey!,
|
|
1037
1546
|
recentBlockhash: blockhash,
|
|
1038
1547
|
instructions: allInstructions,
|
|
1039
|
-
}).compileToV0Message()
|
|
1040
|
-
|
|
1041
|
-
const tx = new VersionedTransaction(messageV0)
|
|
1042
|
-
|
|
1043
|
-
return tx
|
|
1044
|
-
}
|
|
1045
|
-
|
|
1046
|
-
export const mergePositionV2 = async (
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
const
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1548
|
+
}).compileToV0Message();
|
|
1549
|
+
|
|
1550
|
+
const tx = new VersionedTransaction(messageV0);
|
|
1551
|
+
|
|
1552
|
+
return tx;
|
|
1553
|
+
};
|
|
1554
|
+
|
|
1555
|
+
export const mergePositionV2 = async (
|
|
1556
|
+
lavarageProgram: Program<LavarageV2>,
|
|
1557
|
+
position1: ProgramAccount<{
|
|
1558
|
+
pool: PublicKey;
|
|
1559
|
+
seed: PublicKey;
|
|
1560
|
+
userPaid: BN;
|
|
1561
|
+
amount: BN;
|
|
1562
|
+
}>,
|
|
1563
|
+
position2: ProgramAccount<{
|
|
1564
|
+
pool: PublicKey;
|
|
1565
|
+
seed: PublicKey;
|
|
1566
|
+
userPaid: BN;
|
|
1567
|
+
amount: BN;
|
|
1568
|
+
}>,
|
|
1569
|
+
offer: ProgramAccount<{
|
|
1570
|
+
nodeWallet: PublicKey;
|
|
1571
|
+
interestRate: number;
|
|
1572
|
+
collateralType: PublicKey;
|
|
1573
|
+
}>,
|
|
1574
|
+
quoteToken: PublicKey
|
|
1575
|
+
) => {
|
|
1576
|
+
const positionAccountPDA1 = position1.publicKey;
|
|
1577
|
+
const positionAccountPDA2 = position2.publicKey;
|
|
1578
|
+
|
|
1579
|
+
const newPositionSeed = Keypair.generate().publicKey;
|
|
1580
|
+
|
|
1581
|
+
const newPositionAccountPDA = getPositionAccountPDA(
|
|
1582
|
+
lavarageProgram,
|
|
1583
|
+
offer,
|
|
1584
|
+
newPositionSeed
|
|
1585
|
+
);
|
|
1586
|
+
|
|
1587
|
+
const mintAccount = await lavarageProgram.provider.connection.getAccountInfo(
|
|
1588
|
+
offer.account.collateralType
|
|
1589
|
+
);
|
|
1590
|
+
const tokenProgram = mintAccount?.owner;
|
|
1591
|
+
|
|
1592
|
+
const newPositionTokenAccount = getAssociatedTokenAddressSync(
|
|
1077
1593
|
offer.account.collateralType,
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1594
|
+
newPositionAccountPDA,
|
|
1595
|
+
true,
|
|
1596
|
+
tokenProgram
|
|
1597
|
+
);
|
|
1598
|
+
|
|
1599
|
+
const createNewPositionTokenAccountIx =
|
|
1600
|
+
createAssociatedTokenAccountInstruction(
|
|
1601
|
+
lavarageProgram.provider.publicKey!,
|
|
1602
|
+
newPositionTokenAccount,
|
|
1603
|
+
newPositionAccountPDA,
|
|
1604
|
+
offer.account.collateralType,
|
|
1605
|
+
tokenProgram!
|
|
1606
|
+
);
|
|
1607
|
+
|
|
1608
|
+
const ix = await lavarageProgram.methods
|
|
1609
|
+
.tradingManagementMergePositions(newPositionSeed)
|
|
1082
1610
|
.accountsStrict({
|
|
1083
1611
|
mergedPosition: newPositionAccountPDA,
|
|
1084
1612
|
positionOne: positionAccountPDA1,
|
|
@@ -1087,31 +1615,44 @@ export const mergePositionV2 = async (lavarageProgram: Program<LavarageV2>, posi
|
|
|
1087
1615
|
systemProgram: SystemProgram.programId,
|
|
1088
1616
|
mint: offer.account.collateralType,
|
|
1089
1617
|
tokenProgram: tokenProgram!,
|
|
1090
|
-
positionOneTokenAccount: getAssociatedTokenAddressSync(
|
|
1091
|
-
|
|
1618
|
+
positionOneTokenAccount: getAssociatedTokenAddressSync(
|
|
1619
|
+
offer.account.collateralType,
|
|
1620
|
+
positionAccountPDA1,
|
|
1621
|
+
true,
|
|
1622
|
+
tokenProgram
|
|
1623
|
+
),
|
|
1624
|
+
positionTwoTokenAccount: getAssociatedTokenAddressSync(
|
|
1625
|
+
offer.account.collateralType,
|
|
1626
|
+
positionAccountPDA2,
|
|
1627
|
+
true,
|
|
1628
|
+
tokenProgram
|
|
1629
|
+
),
|
|
1092
1630
|
mergedPositionTokenAccount: newPositionTokenAccount,
|
|
1093
1631
|
})
|
|
1094
|
-
.instruction()
|
|
1632
|
+
.instruction();
|
|
1095
1633
|
|
|
1096
1634
|
const computeBudgetIx = ComputeBudgetProgram.setComputeUnitPrice({
|
|
1097
1635
|
microLamports: 100000,
|
|
1098
|
-
})
|
|
1636
|
+
});
|
|
1099
1637
|
|
|
1100
1638
|
const allInstructions = [
|
|
1101
1639
|
createNewPositionTokenAccountIx,
|
|
1102
1640
|
ix,
|
|
1103
1641
|
computeBudgetIx,
|
|
1104
|
-
].filter(i => !!i)
|
|
1642
|
+
].filter((i) => !!i);
|
|
1105
1643
|
|
|
1106
|
-
const { blockhash } =
|
|
1644
|
+
const { blockhash } =
|
|
1645
|
+
await lavarageProgram.provider.connection.getLatestBlockhash("finalized");
|
|
1107
1646
|
|
|
1108
1647
|
const messageV0 = new TransactionMessage({
|
|
1109
1648
|
payerKey: lavarageProgram.provider.publicKey!,
|
|
1110
1649
|
recentBlockhash: blockhash,
|
|
1111
1650
|
instructions: allInstructions,
|
|
1112
|
-
}).compileToV0Message()
|
|
1651
|
+
}).compileToV0Message();
|
|
1652
|
+
|
|
1653
|
+
const tx = new VersionedTransaction(messageV0);
|
|
1113
1654
|
|
|
1114
|
-
|
|
1655
|
+
return tx;
|
|
1656
|
+
};
|
|
1115
1657
|
|
|
1116
|
-
|
|
1117
|
-
}
|
|
1658
|
+
export * from "./evm";
|