@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.
Files changed (44) hide show
  1. package/dist/futarchy/client.d.ts +132 -5
  2. package/dist/futarchy/client.js +80 -21
  3. package/dist/futarchy/instructions.d.ts +109 -1
  4. package/dist/futarchy/instructions.js +17 -3
  5. package/dist/generated/idls/futarchy.json +112 -0
  6. package/dist/generated/types/futarchy.d.ts +112 -0
  7. package/dist/generated/types/futarchy.js +1 -1
  8. package/package.json +1 -2
  9. package/src/amm/client.ts +0 -485
  10. package/src/amm/constants.ts +0 -31
  11. package/src/amm/index.ts +0 -5
  12. package/src/amm/instructions.ts +0 -139
  13. package/src/amm/types.ts +0 -62
  14. package/src/amm/utils.ts +0 -263
  15. package/src/futarchy/client.ts +0 -1032
  16. package/src/futarchy/constants.ts +0 -28
  17. package/src/futarchy/index.ts +0 -5
  18. package/src/futarchy/instructions.ts +0 -235
  19. package/src/futarchy/types.ts +0 -54
  20. package/src/futarchy/utils.ts +0 -108
  21. package/src/generated/idls/amm.json +0 -1252
  22. package/src/generated/idls/futarchy.json +0 -1763
  23. package/src/generated/idls/index.ts +0 -4
  24. package/src/generated/idls/svault.json +0 -2228
  25. package/src/generated/idls/vault.json +0 -1501
  26. package/src/generated/types/amm.ts +0 -1258
  27. package/src/generated/types/futarchy.ts +0 -1769
  28. package/src/generated/types/index.ts +0 -4
  29. package/src/generated/types/svault.ts +0 -2234
  30. package/src/generated/types/vault.ts +0 -1507
  31. package/src/index.ts +0 -163
  32. package/src/svault/client.ts +0 -401
  33. package/src/svault/constants.ts +0 -23
  34. package/src/svault/index.ts +0 -5
  35. package/src/svault/instructions.ts +0 -258
  36. package/src/svault/types.ts +0 -45
  37. package/src/svault/utils.ts +0 -145
  38. package/src/utils.ts +0 -41
  39. package/src/vault/client.ts +0 -333
  40. package/src/vault/constants.ts +0 -23
  41. package/src/vault/index.ts +0 -5
  42. package/src/vault/instructions.ts +0 -170
  43. package/src/vault/types.ts +0 -54
  44. package/src/vault/utils.ts +0 -70
package/src/amm/types.ts DELETED
@@ -1,62 +0,0 @@
1
- /*
2
- * Type definitions for the AMM program.
3
- * Exports IDL-derived types and SDK-friendly enums.
4
- */
5
-
6
- import { BN, IdlAccounts, IdlEvents, IdlTypes } from "@coral-xyz/anchor";
7
- import { TxOptions } from "../utils";
8
-
9
- /* IDL Type Re-export */
10
-
11
- export { Amm } from "../generated/types";
12
- import type { Amm } from "../generated/types";
13
-
14
- /* IDL-derived Types */
15
-
16
- export type PoolAccount = IdlAccounts<Amm>["poolAccount"];
17
- export type PoolStateRaw = IdlTypes<Amm>["poolState"];
18
- export type TwapOracle = IdlTypes<Amm>["twapOracle"];
19
- export type PoolBumps = IdlTypes<Amm>["poolBumps"];
20
-
21
- /* Event Types */
22
-
23
- export type PoolCreatedEvent = IdlEvents<Amm>["poolCreated"];
24
- export type LiquidityAddedEvent = IdlEvents<Amm>["liquidityAdded"];
25
- export type LiquidityRemovedEvent = IdlEvents<Amm>["liquidityRemoved"];
26
- export type CondSwapEvent = IdlEvents<Amm>["condSwap"];
27
- export type TWAPUpdateEvent = IdlEvents<Amm>["twapUpdate"];
28
-
29
- /* Enums */
30
-
31
- export enum PoolState {
32
- Trading = "trading",
33
- Finalized = "finalized",
34
- }
35
-
36
- /* Quote Types */
37
-
38
- export interface SwapQuote {
39
- inputAmount: BN;
40
- outputAmount: BN;
41
- minOutputAmount: BN;
42
- feeAmount: BN;
43
- priceImpact: number;
44
- spotPriceBefore: BN;
45
- spotPriceAfter: BN;
46
- }
47
-
48
- /* Event Union Type */
49
-
50
- export type AMMEvent =
51
- | { name: "PoolCreated"; data: PoolCreatedEvent }
52
- | { name: "LiquidityAdded"; data: LiquidityAddedEvent }
53
- | { name: "LiquidityRemoved"; data: LiquidityRemovedEvent }
54
- | { name: "CondSwap"; data: CondSwapEvent }
55
- | { name: "TWAPUpdate"; data: TWAPUpdateEvent };
56
-
57
- /* Options */
58
-
59
- export interface AmmActionOptions extends TxOptions {
60
- autoWrapUnwrap?: boolean; // Auto wrap/unwrap native SOL (default: true) - for liquidity operations
61
- autoCreateTokenAccounts?: boolean; // Auto create token accounts (default: true) - for swaps
62
- }
package/src/amm/utils.ts DELETED
@@ -1,263 +0,0 @@
1
- /*
2
- * Utility functions for the AMM program.
3
- * PDA derivation, state parsing, price calculations, and account fetching.
4
- */
5
-
6
- import { Program, BN } from "@coral-xyz/anchor";
7
- import { PublicKey } from "@solana/web3.js";
8
- import { POOL_SEED, RESERVE_SEED, FEE_VAULT_SEED, PROGRAM_ID, PRICE_SCALE } from "./constants";
9
- import { Amm, PoolState, PoolAccount, TwapOracle, SwapQuote } from "./types";
10
-
11
- /* PDA Derivation */
12
-
13
- export function derivePoolPDA(
14
- admin: PublicKey,
15
- mintA: PublicKey,
16
- mintB: PublicKey,
17
- programId: PublicKey = PROGRAM_ID
18
- ): [PublicKey, number] {
19
- return PublicKey.findProgramAddressSync(
20
- [POOL_SEED, admin.toBuffer(), mintA.toBuffer(), mintB.toBuffer()],
21
- programId
22
- );
23
- }
24
-
25
- export function deriveReservePDA(
26
- pool: PublicKey,
27
- mint: PublicKey,
28
- programId: PublicKey = PROGRAM_ID
29
- ): [PublicKey, number] {
30
- return PublicKey.findProgramAddressSync(
31
- [RESERVE_SEED, pool.toBuffer(), mint.toBuffer()],
32
- programId
33
- );
34
- }
35
-
36
- export function deriveFeeVaultPDA(
37
- pool: PublicKey,
38
- programId: PublicKey = PROGRAM_ID
39
- ): [PublicKey, number] {
40
- return PublicKey.findProgramAddressSync(
41
- [FEE_VAULT_SEED, pool.toBuffer()],
42
- programId
43
- );
44
- }
45
-
46
- /* Parsers */
47
-
48
- export function parsePoolState(state: any): PoolState {
49
- if ("trading" in state) return PoolState.Trading;
50
- if ("finalized" in state) return PoolState.Finalized;
51
- throw new Error("Unknown pool state");
52
- }
53
-
54
- /* Fetch */
55
-
56
- export async function fetchPoolAccount(
57
- program: Program<Amm>,
58
- poolPda: PublicKey
59
- ): Promise<PoolAccount> {
60
- return program.account.poolAccount.fetch(poolPda);
61
- }
62
-
63
- /* Math Utilities */
64
-
65
- const PRICE_SCALE_BN = new BN(PRICE_SCALE.toString());
66
-
67
- export function calculateSpotPrice(
68
- reserveA: BN,
69
- reserveB: BN,
70
- decimalsA: number,
71
- decimalsB: number,
72
- ): BN {
73
- if (reserveB.isZero()) return new BN(0);
74
-
75
- const decimalDiff = decimalsB - decimalsA;
76
-
77
- if (decimalDiff >= 0) {
78
- const multiplier = new BN(10).pow(new BN(decimalDiff));
79
- return reserveA.mul(multiplier).mul(PRICE_SCALE_BN).div(reserveB);
80
- } else {
81
- const divisor = new BN(10).pow(new BN(-decimalDiff));
82
- return reserveA.mul(PRICE_SCALE_BN).div(reserveB).div(divisor);
83
- }
84
- }
85
-
86
- /**
87
- * Compute swap output using constant product formula.
88
- * Fee is ALWAYS collected in token A:
89
- * - A -> B: fee on input (before swap)
90
- * - B -> A: fee on output (after swap)
91
- */
92
- export function computeSwapOutput(
93
- inputAmount: BN | number,
94
- reserveIn: BN,
95
- reserveOut: BN,
96
- feeBps: number,
97
- swapAToB: boolean
98
- ): { outputAmount: BN; feeAmount: BN } {
99
- const input = typeof inputAmount === "number" ? new BN(inputAmount) : inputAmount;
100
-
101
- if (reserveIn.isZero() || reserveOut.isZero()) {
102
- return { outputAmount: new BN(0), feeAmount: new BN(0) };
103
- }
104
-
105
- if (swapAToB) {
106
- // A -> B: fee on input (token A)
107
- const feeAmount = input.mul(new BN(feeBps)).div(new BN(10000));
108
- const inputAfterFee = input.sub(feeAmount);
109
-
110
- // Constant product: output = reserveOut * inputAfterFee / (reserveIn + inputAfterFee)
111
- const numerator = reserveOut.mul(inputAfterFee);
112
- const denominator = reserveIn.add(inputAfterFee);
113
- const outputAmount = numerator.div(denominator);
114
-
115
- return { outputAmount, feeAmount };
116
- } else {
117
- // B -> A: fee on output (token A)
118
- // First compute gross output without fee
119
- const numerator = reserveOut.mul(input);
120
- const denominator = reserveIn.add(input);
121
- const grossOutput = numerator.div(denominator);
122
-
123
- // Then deduct fee from output
124
- const feeAmount = grossOutput.mul(new BN(feeBps)).div(new BN(10000));
125
- const outputAmount = grossOutput.sub(feeAmount);
126
-
127
- return { outputAmount, feeAmount };
128
- }
129
- }
130
-
131
- /**
132
- * Compute swap input needed to get a specific output.
133
- * Fee is ALWAYS collected in token A:
134
- * - A -> B: fee on input
135
- * - B -> A: fee on output
136
- */
137
- export function computeSwapInput(
138
- outputAmount: BN | number,
139
- reserveIn: BN,
140
- reserveOut: BN,
141
- feeBps: number,
142
- swapAToB: boolean
143
- ): { inputAmount: BN; feeAmount: BN } {
144
- const output = typeof outputAmount === "number" ? new BN(outputAmount) : outputAmount;
145
-
146
- if (reserveIn.isZero() || reserveOut.isZero() || output.gte(reserveOut)) {
147
- return { inputAmount: new BN(0), feeAmount: new BN(0) };
148
- }
149
-
150
- if (swapAToB) {
151
- // A -> B: fee on input
152
- // We need: output = (reserveOut * inputAfterFee) / (reserveIn + inputAfterFee)
153
- // Solve for inputAfterFee: inputAfterFee = (reserveIn * output) / (reserveOut - output)
154
- const numerator = reserveIn.mul(output);
155
- const denominator = reserveOut.sub(output);
156
- const inputAfterFee = numerator.div(denominator).add(new BN(1)); // Round up
157
-
158
- // inputAmount = inputAfterFee * 10000 / (10000 - feeBps)
159
- const inputAmount = inputAfterFee.mul(new BN(10000)).div(new BN(10000 - feeBps)).add(new BN(1));
160
- const feeAmount = inputAmount.sub(inputAfterFee);
161
-
162
- return { inputAmount, feeAmount };
163
- } else {
164
- // B -> A: fee on output
165
- // User wants `output` after fee, so grossOutput = output * 10000 / (10000 - feeBps)
166
- const grossOutput = output.mul(new BN(10000)).div(new BN(10000 - feeBps)).add(new BN(1));
167
- const feeAmount = grossOutput.sub(output);
168
-
169
- // Now compute input needed for grossOutput
170
- // grossOutput = (reserveOut * input) / (reserveIn + input)
171
- // input = (reserveIn * grossOutput) / (reserveOut - grossOutput)
172
- const numerator = reserveIn.mul(grossOutput);
173
- const denominator = reserveOut.sub(grossOutput);
174
-
175
- if (denominator.lte(new BN(0))) {
176
- return { inputAmount: new BN(0), feeAmount: new BN(0) };
177
- }
178
-
179
- const inputAmount = numerator.div(denominator).add(new BN(1)); // Round up
180
-
181
- return { inputAmount, feeAmount };
182
- }
183
- }
184
-
185
- export function calculatePriceImpact(
186
- inputAmount: BN,
187
- outputAmount: BN,
188
- reserveIn: BN,
189
- reserveOut: BN,
190
- decimalsIn: number,
191
- decimalsOut: number,
192
- ): number {
193
- if (reserveIn.isZero() || reserveOut.isZero() || inputAmount.isZero()) {
194
- return 0;
195
- }
196
-
197
- const spotPrice = calculateSpotPrice(reserveIn, reserveOut, decimalsIn, decimalsOut);
198
- const executionPrice = calculateSpotPrice(inputAmount, outputAmount, decimalsIn, decimalsOut);
199
-
200
- if (spotPrice.isZero()) return 0;
201
-
202
- const impact = executionPrice.sub(spotPrice).mul(new BN(10000)).div(spotPrice);
203
- return Math.abs(impact.toNumber()) / 100;
204
- }
205
-
206
- export function createSwapQuote(
207
- inputAmount: BN | number,
208
- reserveIn: BN,
209
- reserveOut: BN,
210
- feeBps: number,
211
- decimalsIn: number,
212
- decimalsOut: number,
213
- swapAToB: boolean,
214
- slippagePercent: number = 0.5,
215
- ): SwapQuote {
216
- const input = typeof inputAmount === "number" ? new BN(inputAmount) : inputAmount;
217
-
218
- const { outputAmount, feeAmount } = computeSwapOutput(input, reserveIn, reserveOut, feeBps, swapAToB);
219
-
220
- const slippageBps = Math.floor(slippagePercent * 100);
221
- const minOutputAmount = outputAmount.mul(new BN(10000 - slippageBps)).div(new BN(10000));
222
-
223
- const spotPriceBefore = calculateSpotPrice(reserveIn, reserveOut, decimalsIn, decimalsOut);
224
- const newReserveIn = reserveIn.add(input);
225
- const newReserveOut = reserveOut.sub(outputAmount);
226
- const spotPriceAfter = calculateSpotPrice(newReserveIn, newReserveOut, decimalsIn, decimalsOut);
227
-
228
- const priceImpact = calculatePriceImpact(input, outputAmount, reserveIn, reserveOut, decimalsIn, decimalsOut);
229
-
230
- return {
231
- inputAmount: input,
232
- outputAmount,
233
- minOutputAmount,
234
- feeAmount,
235
- priceImpact,
236
- spotPriceBefore,
237
- spotPriceAfter,
238
- };
239
- }
240
-
241
- /* TWAP Utilities */
242
-
243
- export function calculateTwap(oracle: TwapOracle): BN | null {
244
- const warmupEnd = oracle.createdAtUnixTime.add(new BN(oracle.warmupDuration));
245
-
246
- if (oracle.lastUpdateUnixTime.lte(warmupEnd)) {
247
- return oracle.startingObservation;
248
- }
249
-
250
- const elapsed = oracle.lastUpdateUnixTime.sub(warmupEnd);
251
-
252
- if (elapsed.isZero() || oracle.cumulativeObservations.isZero()) {
253
- return null;
254
- }
255
-
256
- return oracle.cumulativeObservations.div(elapsed);
257
- }
258
-
259
- export function isOracleInWarmup(oracle: TwapOracle, currentTime?: BN): boolean {
260
- const now = currentTime ?? new BN(Math.floor(Date.now() / 1000));
261
- const warmupEnd = oracle.createdAtUnixTime.add(new BN(oracle.warmupDuration));
262
- return now.lt(warmupEnd);
263
- }