@zcomb/programs-sdk 1.6.0 → 1.8.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/dist/futarchy/client.d.ts +132 -5
- package/dist/futarchy/client.js +80 -21
- package/dist/futarchy/instructions.d.ts +109 -1
- package/dist/futarchy/instructions.js +17 -3
- package/dist/generated/idls/futarchy.json +112 -0
- package/dist/generated/types/futarchy.d.ts +112 -0
- package/dist/generated/types/futarchy.js +1 -1
- package/package.json +1 -2
- package/src/amm/client.ts +0 -485
- package/src/amm/constants.ts +0 -31
- package/src/amm/index.ts +0 -5
- package/src/amm/instructions.ts +0 -139
- package/src/amm/types.ts +0 -62
- package/src/amm/utils.ts +0 -263
- package/src/futarchy/client.ts +0 -1032
- package/src/futarchy/constants.ts +0 -28
- package/src/futarchy/index.ts +0 -5
- package/src/futarchy/instructions.ts +0 -235
- package/src/futarchy/types.ts +0 -54
- package/src/futarchy/utils.ts +0 -108
- package/src/generated/idls/amm.json +0 -1252
- package/src/generated/idls/futarchy.json +0 -1763
- package/src/generated/idls/index.ts +0 -4
- package/src/generated/idls/svault.json +0 -2228
- package/src/generated/idls/vault.json +0 -1501
- package/src/generated/types/amm.ts +0 -1258
- package/src/generated/types/futarchy.ts +0 -1769
- package/src/generated/types/index.ts +0 -4
- package/src/generated/types/svault.ts +0 -2234
- package/src/generated/types/vault.ts +0 -1507
- package/src/index.ts +0 -163
- package/src/svault/client.ts +0 -401
- package/src/svault/constants.ts +0 -23
- package/src/svault/index.ts +0 -5
- package/src/svault/instructions.ts +0 -258
- package/src/svault/types.ts +0 -45
- package/src/svault/utils.ts +0 -145
- package/src/utils.ts +0 -41
- package/src/vault/client.ts +0 -333
- package/src/vault/constants.ts +0 -23
- package/src/vault/index.ts +0 -5
- package/src/vault/instructions.ts +0 -170
- package/src/vault/types.ts +0 -54
- package/src/vault/utils.ts +0 -70
package/src/amm/client.ts
DELETED
|
@@ -1,485 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* High-level client for the AMM program.
|
|
3
|
-
* Provides ergonomic methods for pool operations with automatic PDA derivation,
|
|
4
|
-
* native SOL wrapping/unwrapping, and compute budget management.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { Program, AnchorProvider, BN } from "@coral-xyz/anchor";
|
|
8
|
-
import {
|
|
9
|
-
PublicKey,
|
|
10
|
-
ComputeBudgetProgram,
|
|
11
|
-
SystemProgram,
|
|
12
|
-
TransactionInstruction,
|
|
13
|
-
} from "@solana/web3.js";
|
|
14
|
-
import {
|
|
15
|
-
getAccount,
|
|
16
|
-
getAssociatedTokenAddressSync,
|
|
17
|
-
getMint,
|
|
18
|
-
NATIVE_MINT,
|
|
19
|
-
createSyncNativeInstruction,
|
|
20
|
-
createCloseAccountInstruction,
|
|
21
|
-
createAssociatedTokenAccountIdempotentInstruction,
|
|
22
|
-
} from "@solana/spl-token";
|
|
23
|
-
import { PROGRAM_ID } from "./constants";
|
|
24
|
-
import { Amm, PoolAccount, SwapQuote, AmmActionOptions } from "./types";
|
|
25
|
-
import {
|
|
26
|
-
derivePoolPDA,
|
|
27
|
-
deriveReservePDA,
|
|
28
|
-
deriveFeeVaultPDA,
|
|
29
|
-
fetchPoolAccount,
|
|
30
|
-
createSwapQuote,
|
|
31
|
-
calculateSpotPrice,
|
|
32
|
-
calculateTwap,
|
|
33
|
-
} from "./utils";
|
|
34
|
-
import {
|
|
35
|
-
createPool as createPoolIx,
|
|
36
|
-
addLiquidity as addLiquidityIx,
|
|
37
|
-
removeLiquidity as removeLiquidityIx,
|
|
38
|
-
swap as swapIx,
|
|
39
|
-
crankTwap as crankTwapIx,
|
|
40
|
-
ceaseTrading as ceaseTradingIx,
|
|
41
|
-
} from "./instructions";
|
|
42
|
-
|
|
43
|
-
import { AmmIDL } from "../generated/idls";
|
|
44
|
-
|
|
45
|
-
const DEFAULT_COMPUTE_UNITS = 300_000;
|
|
46
|
-
|
|
47
|
-
export class AMMClient {
|
|
48
|
-
public program: Program<Amm>;
|
|
49
|
-
public programId: PublicKey;
|
|
50
|
-
public computeUnits: number;
|
|
51
|
-
|
|
52
|
-
constructor(
|
|
53
|
-
provider: AnchorProvider,
|
|
54
|
-
programId?: PublicKey,
|
|
55
|
-
computeUnits?: number
|
|
56
|
-
) {
|
|
57
|
-
this.programId = programId ?? PROGRAM_ID;
|
|
58
|
-
this.computeUnits = computeUnits ?? DEFAULT_COMPUTE_UNITS;
|
|
59
|
-
this.program = new Program(AmmIDL as Amm, provider);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/* PDA Helpers */
|
|
63
|
-
|
|
64
|
-
derivePoolPDA(
|
|
65
|
-
admin: PublicKey,
|
|
66
|
-
mintA: PublicKey,
|
|
67
|
-
mintB: PublicKey
|
|
68
|
-
): [PublicKey, number] {
|
|
69
|
-
return derivePoolPDA(admin, mintA, mintB, this.programId);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
deriveReservePDA(pool: PublicKey, mint: PublicKey): [PublicKey, number] {
|
|
73
|
-
return deriveReservePDA(pool, mint, this.programId);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
deriveFeeVaultPDA(pool: PublicKey): [PublicKey, number] {
|
|
77
|
-
return deriveFeeVaultPDA(pool, this.programId);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/* State Fetching */
|
|
81
|
-
|
|
82
|
-
async fetchPool(poolPda: PublicKey): Promise<PoolAccount> {
|
|
83
|
-
return fetchPoolAccount(this.program, poolPda);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
async fetchReserves(poolPda: PublicKey): Promise<{ reserveA: BN; reserveB: BN }> {
|
|
87
|
-
const pool = await this.fetchPool(poolPda);
|
|
88
|
-
const [reserveAPda] = this.deriveReservePDA(poolPda, pool.mintA);
|
|
89
|
-
const [reserveBPda] = this.deriveReservePDA(poolPda, pool.mintB);
|
|
90
|
-
|
|
91
|
-
const connection = this.program.provider.connection;
|
|
92
|
-
|
|
93
|
-
const [reserveAAccount, reserveBAccount] = await Promise.all([
|
|
94
|
-
getAccount(connection, reserveAPda),
|
|
95
|
-
getAccount(connection, reserveBPda),
|
|
96
|
-
]);
|
|
97
|
-
|
|
98
|
-
return {
|
|
99
|
-
reserveA: new BN(reserveAAccount.amount.toString()),
|
|
100
|
-
reserveB: new BN(reserveBAccount.amount.toString()),
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
async fetchMintDecimals(poolPda: PublicKey): Promise<{ decimalsA: number; decimalsB: number }> {
|
|
105
|
-
const pool = await this.fetchPool(poolPda);
|
|
106
|
-
const connection = this.program.provider.connection;
|
|
107
|
-
const [mintA, mintB] = await Promise.all([
|
|
108
|
-
getMint(connection, pool.mintA),
|
|
109
|
-
getMint(connection, pool.mintB),
|
|
110
|
-
]);
|
|
111
|
-
return { decimalsA: mintA.decimals, decimalsB: mintB.decimals };
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
async fetchSpotPrice(poolPda: PublicKey): Promise<BN> {
|
|
115
|
-
const { reserveA, reserveB } = await this.fetchReserves(poolPda);
|
|
116
|
-
const { decimalsA, decimalsB } = await this.fetchMintDecimals(poolPda);
|
|
117
|
-
return calculateSpotPrice(reserveA, reserveB, decimalsA, decimalsB);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
async fetchTwap(poolPda: PublicKey): Promise<BN | null> {
|
|
121
|
-
const pool = await this.fetchPool(poolPda);
|
|
122
|
-
return calculateTwap(pool.oracle);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/* Quote */
|
|
126
|
-
|
|
127
|
-
async quote(
|
|
128
|
-
poolPda: PublicKey,
|
|
129
|
-
swapAToB: boolean,
|
|
130
|
-
inputAmount: BN | number,
|
|
131
|
-
slippagePercent: number = 0.5,
|
|
132
|
-
): Promise<SwapQuote> {
|
|
133
|
-
const pool = await this.fetchPool(poolPda);
|
|
134
|
-
const { reserveA, reserveB } = await this.fetchReserves(poolPda);
|
|
135
|
-
const { decimalsA, decimalsB } = await this.fetchMintDecimals(poolPda);
|
|
136
|
-
|
|
137
|
-
const [reserveIn, reserveOut] = swapAToB
|
|
138
|
-
? [reserveA, reserveB]
|
|
139
|
-
: [reserveB, reserveA];
|
|
140
|
-
|
|
141
|
-
const [decimalsIn, decimalsOut] = swapAToB
|
|
142
|
-
? [decimalsA, decimalsB]
|
|
143
|
-
: [decimalsB, decimalsA];
|
|
144
|
-
|
|
145
|
-
return createSwapQuote(
|
|
146
|
-
inputAmount,
|
|
147
|
-
reserveIn,
|
|
148
|
-
reserveOut,
|
|
149
|
-
pool.fee,
|
|
150
|
-
decimalsIn,
|
|
151
|
-
decimalsOut,
|
|
152
|
-
swapAToB,
|
|
153
|
-
slippagePercent,
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/* Instruction Builders */
|
|
158
|
-
|
|
159
|
-
createPool(
|
|
160
|
-
payer: PublicKey,
|
|
161
|
-
admin: PublicKey,
|
|
162
|
-
mintA: PublicKey,
|
|
163
|
-
mintB: PublicKey,
|
|
164
|
-
fee: number,
|
|
165
|
-
startingObservation: BN,
|
|
166
|
-
maxObservationDelta: BN,
|
|
167
|
-
warmupDuration: number,
|
|
168
|
-
liquidityProvider: PublicKey | null = null
|
|
169
|
-
) {
|
|
170
|
-
const [poolPda] = this.derivePoolPDA(admin, mintA, mintB);
|
|
171
|
-
const [reserveA] = this.deriveReservePDA(poolPda, mintA);
|
|
172
|
-
const [reserveB] = this.deriveReservePDA(poolPda, mintB);
|
|
173
|
-
const [feeVault] = this.deriveFeeVaultPDA(poolPda);
|
|
174
|
-
|
|
175
|
-
const builder = createPoolIx(
|
|
176
|
-
this.program,
|
|
177
|
-
payer,
|
|
178
|
-
admin,
|
|
179
|
-
mintA,
|
|
180
|
-
mintB,
|
|
181
|
-
poolPda,
|
|
182
|
-
reserveA,
|
|
183
|
-
reserveB,
|
|
184
|
-
feeVault,
|
|
185
|
-
fee,
|
|
186
|
-
startingObservation,
|
|
187
|
-
maxObservationDelta,
|
|
188
|
-
warmupDuration,
|
|
189
|
-
liquidityProvider
|
|
190
|
-
);
|
|
191
|
-
|
|
192
|
-
return {
|
|
193
|
-
builder,
|
|
194
|
-
poolPda,
|
|
195
|
-
reserveA,
|
|
196
|
-
reserveB,
|
|
197
|
-
feeVault,
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
async addLiquidity(
|
|
202
|
-
depositor: PublicKey,
|
|
203
|
-
poolPda: PublicKey,
|
|
204
|
-
amountA: BN | number,
|
|
205
|
-
amountB: BN | number,
|
|
206
|
-
options?: AmmActionOptions
|
|
207
|
-
) {
|
|
208
|
-
const { autoWrapUnwrap = true, includeCuBudget = true, computeUnits } = options ?? {};
|
|
209
|
-
|
|
210
|
-
const pool = await this.fetchPool(poolPda);
|
|
211
|
-
const [reserveA] = this.deriveReservePDA(poolPda, pool.mintA);
|
|
212
|
-
const [reserveB] = this.deriveReservePDA(poolPda, pool.mintB);
|
|
213
|
-
const depositorTokenAccA = getAssociatedTokenAddressSync(pool.mintA, depositor);
|
|
214
|
-
const depositorTokenAccB = getAssociatedTokenAddressSync(pool.mintB, depositor);
|
|
215
|
-
|
|
216
|
-
const preIxs: TransactionInstruction[] = [];
|
|
217
|
-
|
|
218
|
-
if (includeCuBudget) {
|
|
219
|
-
preIxs.push(
|
|
220
|
-
ComputeBudgetProgram.setComputeUnitLimit({
|
|
221
|
-
units: computeUnits ?? this.computeUnits,
|
|
222
|
-
})
|
|
223
|
-
);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
if (autoWrapUnwrap && pool.mintA.equals(NATIVE_MINT)) {
|
|
227
|
-
const amountABN = typeof amountA === "number" ? new BN(amountA) : amountA;
|
|
228
|
-
preIxs.push(
|
|
229
|
-
createAssociatedTokenAccountIdempotentInstruction(
|
|
230
|
-
depositor,
|
|
231
|
-
depositorTokenAccA,
|
|
232
|
-
depositor,
|
|
233
|
-
pool.mintA
|
|
234
|
-
),
|
|
235
|
-
SystemProgram.transfer({
|
|
236
|
-
fromPubkey: depositor,
|
|
237
|
-
toPubkey: depositorTokenAccA,
|
|
238
|
-
lamports: BigInt(amountABN.toString()),
|
|
239
|
-
}),
|
|
240
|
-
createSyncNativeInstruction(depositorTokenAccA)
|
|
241
|
-
);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
if (autoWrapUnwrap && pool.mintB.equals(NATIVE_MINT)) {
|
|
245
|
-
const amountBBN = typeof amountB === "number" ? new BN(amountB) : amountB;
|
|
246
|
-
preIxs.push(
|
|
247
|
-
createAssociatedTokenAccountIdempotentInstruction(
|
|
248
|
-
depositor,
|
|
249
|
-
depositorTokenAccB,
|
|
250
|
-
depositor,
|
|
251
|
-
pool.mintB
|
|
252
|
-
),
|
|
253
|
-
SystemProgram.transfer({
|
|
254
|
-
fromPubkey: depositor,
|
|
255
|
-
toPubkey: depositorTokenAccB,
|
|
256
|
-
lamports: BigInt(amountBBN.toString()),
|
|
257
|
-
}),
|
|
258
|
-
createSyncNativeInstruction(depositorTokenAccB)
|
|
259
|
-
);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
let builder = addLiquidityIx(
|
|
263
|
-
this.program,
|
|
264
|
-
depositor,
|
|
265
|
-
poolPda,
|
|
266
|
-
reserveA,
|
|
267
|
-
reserveB,
|
|
268
|
-
depositorTokenAccA,
|
|
269
|
-
depositorTokenAccB,
|
|
270
|
-
amountA,
|
|
271
|
-
amountB
|
|
272
|
-
);
|
|
273
|
-
|
|
274
|
-
return preIxs.length > 0 ? builder.preInstructions(preIxs) : builder;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
async removeLiquidity(
|
|
278
|
-
depositor: PublicKey,
|
|
279
|
-
poolPda: PublicKey,
|
|
280
|
-
amountA: BN | number,
|
|
281
|
-
amountB: BN | number,
|
|
282
|
-
options?: AmmActionOptions
|
|
283
|
-
) {
|
|
284
|
-
const { autoWrapUnwrap = true, includeCuBudget = true, computeUnits } = options ?? {};
|
|
285
|
-
|
|
286
|
-
const pool = await this.fetchPool(poolPda);
|
|
287
|
-
const [reserveA] = this.deriveReservePDA(poolPda, pool.mintA);
|
|
288
|
-
const [reserveB] = this.deriveReservePDA(poolPda, pool.mintB);
|
|
289
|
-
const depositorTokenAccA = getAssociatedTokenAddressSync(pool.mintA, depositor);
|
|
290
|
-
const depositorTokenAccB = getAssociatedTokenAddressSync(pool.mintB, depositor);
|
|
291
|
-
|
|
292
|
-
let builder = removeLiquidityIx(
|
|
293
|
-
this.program,
|
|
294
|
-
depositor,
|
|
295
|
-
poolPda,
|
|
296
|
-
reserveA,
|
|
297
|
-
reserveB,
|
|
298
|
-
depositorTokenAccA,
|
|
299
|
-
depositorTokenAccB,
|
|
300
|
-
amountA,
|
|
301
|
-
amountB
|
|
302
|
-
);
|
|
303
|
-
|
|
304
|
-
if (includeCuBudget) {
|
|
305
|
-
builder = builder.preInstructions([
|
|
306
|
-
ComputeBudgetProgram.setComputeUnitLimit({
|
|
307
|
-
units: computeUnits ?? this.computeUnits,
|
|
308
|
-
}),
|
|
309
|
-
]);
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
const postIxs: TransactionInstruction[] = [];
|
|
313
|
-
|
|
314
|
-
if (autoWrapUnwrap && pool.mintA.equals(NATIVE_MINT)) {
|
|
315
|
-
postIxs.push(createCloseAccountInstruction(depositorTokenAccA, depositor, depositor));
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
if (autoWrapUnwrap && pool.mintB.equals(NATIVE_MINT)) {
|
|
319
|
-
postIxs.push(createCloseAccountInstruction(depositorTokenAccB, depositor, depositor));
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
return postIxs.length > 0 ? builder.postInstructions(postIxs) : builder;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
async swap(
|
|
326
|
-
trader: PublicKey,
|
|
327
|
-
poolPda: PublicKey,
|
|
328
|
-
swapAToB: boolean,
|
|
329
|
-
inputAmount: BN | number,
|
|
330
|
-
minOutputAmount: BN | number,
|
|
331
|
-
options?: AmmActionOptions
|
|
332
|
-
) {
|
|
333
|
-
const { autoCreateTokenAccounts = true, includeCuBudget = true, computeUnits } = options ?? {};
|
|
334
|
-
|
|
335
|
-
const pool = await this.fetchPool(poolPda);
|
|
336
|
-
const [reserveA] = this.deriveReservePDA(poolPda, pool.mintA);
|
|
337
|
-
const [reserveB] = this.deriveReservePDA(poolPda, pool.mintB);
|
|
338
|
-
const [feeVault] = this.deriveFeeVaultPDA(poolPda);
|
|
339
|
-
const traderAccountA = getAssociatedTokenAddressSync(pool.mintA, trader);
|
|
340
|
-
const traderAccountB = getAssociatedTokenAddressSync(pool.mintB, trader);
|
|
341
|
-
|
|
342
|
-
const preIxs: TransactionInstruction[] = [];
|
|
343
|
-
|
|
344
|
-
if (includeCuBudget) {
|
|
345
|
-
preIxs.push(
|
|
346
|
-
ComputeBudgetProgram.setComputeUnitLimit({
|
|
347
|
-
units: computeUnits ?? this.computeUnits,
|
|
348
|
-
})
|
|
349
|
-
);
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
if (autoCreateTokenAccounts) {
|
|
353
|
-
preIxs.push(
|
|
354
|
-
createAssociatedTokenAccountIdempotentInstruction(
|
|
355
|
-
trader,
|
|
356
|
-
traderAccountA,
|
|
357
|
-
trader,
|
|
358
|
-
pool.mintA
|
|
359
|
-
),
|
|
360
|
-
createAssociatedTokenAccountIdempotentInstruction(
|
|
361
|
-
trader,
|
|
362
|
-
traderAccountB,
|
|
363
|
-
trader,
|
|
364
|
-
pool.mintB
|
|
365
|
-
)
|
|
366
|
-
);
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
let builder = swapIx(
|
|
370
|
-
this.program,
|
|
371
|
-
trader,
|
|
372
|
-
poolPda,
|
|
373
|
-
reserveA,
|
|
374
|
-
reserveB,
|
|
375
|
-
feeVault,
|
|
376
|
-
traderAccountA,
|
|
377
|
-
traderAccountB,
|
|
378
|
-
swapAToB,
|
|
379
|
-
inputAmount,
|
|
380
|
-
minOutputAmount
|
|
381
|
-
);
|
|
382
|
-
|
|
383
|
-
if (preIxs.length > 0) {
|
|
384
|
-
builder = builder.preInstructions(preIxs);
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
return builder;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
async crankTwap(poolPda: PublicKey) {
|
|
391
|
-
const pool = await this.fetchPool(poolPda);
|
|
392
|
-
const [reserveA] = this.deriveReservePDA(poolPda, pool.mintA);
|
|
393
|
-
const [reserveB] = this.deriveReservePDA(poolPda, pool.mintB);
|
|
394
|
-
|
|
395
|
-
return crankTwapIx(this.program, poolPda, reserveA, reserveB);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
ceaseTrading(admin: PublicKey, poolPda: PublicKey) {
|
|
399
|
-
return ceaseTradingIx(this.program, admin, poolPda);
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
/* High-Level Swap with Slippage */
|
|
403
|
-
|
|
404
|
-
/**
|
|
405
|
-
* High-level swap function that:
|
|
406
|
-
* - Fetches current reserves and computes quote
|
|
407
|
-
* - Calculates minOutput based on slippage tolerance
|
|
408
|
-
* - Adds compute budget instruction (if includeCuBudget is true)
|
|
409
|
-
* - Creates token accounts if they don't exist (if autoCreateTokenAccounts is true)
|
|
410
|
-
*/
|
|
411
|
-
async swapWithSlippage(
|
|
412
|
-
trader: PublicKey,
|
|
413
|
-
poolPda: PublicKey,
|
|
414
|
-
swapAToB: boolean,
|
|
415
|
-
inputAmount: BN | number,
|
|
416
|
-
slippagePercent: number = 0.5,
|
|
417
|
-
options?: AmmActionOptions
|
|
418
|
-
) {
|
|
419
|
-
const { autoCreateTokenAccounts = true, includeCuBudget = true, computeUnits } = options ?? {};
|
|
420
|
-
|
|
421
|
-
const pool = await this.fetchPool(poolPda);
|
|
422
|
-
const input = typeof inputAmount === "number" ? new BN(inputAmount) : inputAmount;
|
|
423
|
-
|
|
424
|
-
// Get quote with slippage
|
|
425
|
-
const quoteResult = await this.quote(poolPda, swapAToB, input, slippagePercent);
|
|
426
|
-
|
|
427
|
-
// Derive accounts
|
|
428
|
-
const [reserveA] = this.deriveReservePDA(poolPda, pool.mintA);
|
|
429
|
-
const [reserveB] = this.deriveReservePDA(poolPda, pool.mintB);
|
|
430
|
-
const [feeVault] = this.deriveFeeVaultPDA(poolPda);
|
|
431
|
-
const traderAccountA = getAssociatedTokenAddressSync(pool.mintA, trader);
|
|
432
|
-
const traderAccountB = getAssociatedTokenAddressSync(pool.mintB, trader);
|
|
433
|
-
|
|
434
|
-
// Build base swap instruction
|
|
435
|
-
let builder = swapIx(
|
|
436
|
-
this.program,
|
|
437
|
-
trader,
|
|
438
|
-
poolPda,
|
|
439
|
-
reserveA,
|
|
440
|
-
reserveB,
|
|
441
|
-
feeVault,
|
|
442
|
-
traderAccountA,
|
|
443
|
-
traderAccountB,
|
|
444
|
-
swapAToB,
|
|
445
|
-
input,
|
|
446
|
-
quoteResult.minOutputAmount
|
|
447
|
-
);
|
|
448
|
-
|
|
449
|
-
const preIxs: TransactionInstruction[] = [];
|
|
450
|
-
|
|
451
|
-
if (includeCuBudget) {
|
|
452
|
-
preIxs.push(
|
|
453
|
-
ComputeBudgetProgram.setComputeUnitLimit({
|
|
454
|
-
units: computeUnits ?? this.computeUnits,
|
|
455
|
-
})
|
|
456
|
-
);
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
if (autoCreateTokenAccounts) {
|
|
460
|
-
preIxs.push(
|
|
461
|
-
createAssociatedTokenAccountIdempotentInstruction(
|
|
462
|
-
trader,
|
|
463
|
-
traderAccountA,
|
|
464
|
-
trader,
|
|
465
|
-
pool.mintA
|
|
466
|
-
),
|
|
467
|
-
createAssociatedTokenAccountIdempotentInstruction(
|
|
468
|
-
trader,
|
|
469
|
-
traderAccountB,
|
|
470
|
-
trader,
|
|
471
|
-
pool.mintB
|
|
472
|
-
)
|
|
473
|
-
);
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
if (preIxs.length > 0) {
|
|
477
|
-
builder = builder.preInstructions(preIxs);
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
return {
|
|
481
|
-
builder,
|
|
482
|
-
quote: quoteResult,
|
|
483
|
-
};
|
|
484
|
-
}
|
|
485
|
-
}
|
package/src/amm/constants.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Constants for the AMM program.
|
|
3
|
-
* Parsed from the generated IDL to stay in sync with the Rust program.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { PublicKey } from "@solana/web3.js";
|
|
7
|
-
import { AmmIDL } from "../generated/idls";
|
|
8
|
-
import { parseIdlBytes, getIdlConstant } from "../utils";
|
|
9
|
-
|
|
10
|
-
/* Program ID */
|
|
11
|
-
|
|
12
|
-
export const PROGRAM_ID = new PublicKey(AmmIDL.address);
|
|
13
|
-
|
|
14
|
-
/* Authorities */
|
|
15
|
-
|
|
16
|
-
export const FEE_AUTHORITY = new PublicKey(getIdlConstant(AmmIDL, "FEE_AUTHORITY"));
|
|
17
|
-
|
|
18
|
-
/* PDA Seeds */
|
|
19
|
-
|
|
20
|
-
export const POOL_SEED = parseIdlBytes(getIdlConstant(AmmIDL, "POOL_SEED"));
|
|
21
|
-
export const RESERVE_SEED = parseIdlBytes(getIdlConstant(AmmIDL, "RESERVE_SEED"));
|
|
22
|
-
export const FEE_VAULT_SEED = parseIdlBytes(getIdlConstant(AmmIDL, "FEE_VAULT_SEED"));
|
|
23
|
-
|
|
24
|
-
/* Numeric Constants */
|
|
25
|
-
|
|
26
|
-
export const MAX_FEE = Number(getIdlConstant(AmmIDL, "MAX_FEE"));
|
|
27
|
-
export const AMM_VERSION = Number(getIdlConstant(AmmIDL, "AMM_VERSION"));
|
|
28
|
-
|
|
29
|
-
/* Price Constants (not in IDL - internal to Rust) */
|
|
30
|
-
|
|
31
|
-
export const PRICE_SCALE = 1_000_000_000_000n;
|
package/src/amm/index.ts
DELETED
package/src/amm/instructions.ts
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Low-level instruction builders for the AMM program.
|
|
3
|
-
* These are thin wrappers around the program methods - use AMMClient for higher-level operations.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { Program, BN } from "@coral-xyz/anchor";
|
|
7
|
-
import { PublicKey } from "@solana/web3.js";
|
|
8
|
-
import { Amm } from "./types";
|
|
9
|
-
|
|
10
|
-
/* Instruction Builders */
|
|
11
|
-
|
|
12
|
-
export function createPool(
|
|
13
|
-
program: Program<Amm>,
|
|
14
|
-
payer: PublicKey,
|
|
15
|
-
admin: PublicKey,
|
|
16
|
-
mintA: PublicKey,
|
|
17
|
-
mintB: PublicKey,
|
|
18
|
-
pool: PublicKey,
|
|
19
|
-
reserveA: PublicKey,
|
|
20
|
-
reserveB: PublicKey,
|
|
21
|
-
feeVault: PublicKey,
|
|
22
|
-
fee: number,
|
|
23
|
-
startingObservation: BN,
|
|
24
|
-
maxObservationDelta: BN,
|
|
25
|
-
warmupDuration: number,
|
|
26
|
-
liquidityProvider: PublicKey | null = null
|
|
27
|
-
) {
|
|
28
|
-
return program.methods
|
|
29
|
-
.createPool(fee, startingObservation, maxObservationDelta, warmupDuration, liquidityProvider)
|
|
30
|
-
.accountsPartial({
|
|
31
|
-
payer,
|
|
32
|
-
admin,
|
|
33
|
-
mintA,
|
|
34
|
-
mintB,
|
|
35
|
-
pool,
|
|
36
|
-
reserveA,
|
|
37
|
-
reserveB,
|
|
38
|
-
feeVault,
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function addLiquidity(
|
|
43
|
-
program: Program<Amm>,
|
|
44
|
-
depositor: PublicKey,
|
|
45
|
-
pool: PublicKey,
|
|
46
|
-
reserveA: PublicKey,
|
|
47
|
-
reserveB: PublicKey,
|
|
48
|
-
depositorTokenAccA: PublicKey,
|
|
49
|
-
depositorTokenAccB: PublicKey,
|
|
50
|
-
amountA: BN | number,
|
|
51
|
-
amountB: BN | number
|
|
52
|
-
) {
|
|
53
|
-
const amountABN = typeof amountA === "number" ? new BN(amountA) : amountA;
|
|
54
|
-
const amountBBN = typeof amountB === "number" ? new BN(amountB) : amountB;
|
|
55
|
-
|
|
56
|
-
return program.methods.addLiquidity(amountABN, amountBBN).accountsPartial({
|
|
57
|
-
depositor,
|
|
58
|
-
pool,
|
|
59
|
-
reserveA,
|
|
60
|
-
reserveB,
|
|
61
|
-
depositorTokenAccA,
|
|
62
|
-
depositorTokenAccB,
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export function removeLiquidity(
|
|
67
|
-
program: Program<Amm>,
|
|
68
|
-
depositor: PublicKey,
|
|
69
|
-
pool: PublicKey,
|
|
70
|
-
reserveA: PublicKey,
|
|
71
|
-
reserveB: PublicKey,
|
|
72
|
-
depositorTokenAccA: PublicKey,
|
|
73
|
-
depositorTokenAccB: PublicKey,
|
|
74
|
-
amountA: BN | number,
|
|
75
|
-
amountB: BN | number
|
|
76
|
-
) {
|
|
77
|
-
const amountABN = typeof amountA === "number" ? new BN(amountA) : amountA;
|
|
78
|
-
const amountBBN = typeof amountB === "number" ? new BN(amountB) : amountB;
|
|
79
|
-
|
|
80
|
-
return program.methods.removeLiquidity(amountABN, amountBBN).accountsPartial({
|
|
81
|
-
depositor,
|
|
82
|
-
pool,
|
|
83
|
-
reserveA,
|
|
84
|
-
reserveB,
|
|
85
|
-
depositorTokenAccA,
|
|
86
|
-
depositorTokenAccB,
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export function swap(
|
|
91
|
-
program: Program<Amm>,
|
|
92
|
-
trader: PublicKey,
|
|
93
|
-
pool: PublicKey,
|
|
94
|
-
reserveA: PublicKey,
|
|
95
|
-
reserveB: PublicKey,
|
|
96
|
-
feeVault: PublicKey,
|
|
97
|
-
traderAccountA: PublicKey,
|
|
98
|
-
traderAccountB: PublicKey,
|
|
99
|
-
swapAToB: boolean,
|
|
100
|
-
inputAmount: BN | number,
|
|
101
|
-
minOutputAmount: BN | number
|
|
102
|
-
) {
|
|
103
|
-
const inputAmountBN = typeof inputAmount === "number" ? new BN(inputAmount) : inputAmount;
|
|
104
|
-
const minOutputAmountBN = typeof minOutputAmount === "number" ? new BN(minOutputAmount) : minOutputAmount;
|
|
105
|
-
|
|
106
|
-
return program.methods.swap(swapAToB, inputAmountBN, minOutputAmountBN).accountsPartial({
|
|
107
|
-
trader,
|
|
108
|
-
pool,
|
|
109
|
-
reserveA,
|
|
110
|
-
reserveB,
|
|
111
|
-
feeVault,
|
|
112
|
-
traderAccountA,
|
|
113
|
-
traderAccountB,
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export function crankTwap(
|
|
118
|
-
program: Program<Amm>,
|
|
119
|
-
pool: PublicKey,
|
|
120
|
-
reserveA: PublicKey,
|
|
121
|
-
reserveB: PublicKey
|
|
122
|
-
) {
|
|
123
|
-
return program.methods.crankTwap().accountsPartial({
|
|
124
|
-
pool,
|
|
125
|
-
reserveA,
|
|
126
|
-
reserveB,
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
export function ceaseTrading(
|
|
131
|
-
program: Program<Amm>,
|
|
132
|
-
admin: PublicKey,
|
|
133
|
-
pool: PublicKey
|
|
134
|
-
) {
|
|
135
|
-
return program.methods.ceaseTrading().accountsPartial({
|
|
136
|
-
admin,
|
|
137
|
-
pool,
|
|
138
|
-
});
|
|
139
|
-
}
|