@liquid-af/sdk 0.1.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 (225) hide show
  1. package/README.md +776 -0
  2. package/dist/accounts/index.d.ts +5 -0
  3. package/dist/accounts/index.d.ts.map +1 -0
  4. package/dist/accounts/index.js +5 -0
  5. package/dist/accounts/index.js.map +1 -0
  6. package/dist/accounts/liquid-fees.d.ts +63 -0
  7. package/dist/accounts/liquid-fees.d.ts.map +1 -0
  8. package/dist/accounts/liquid-fees.js +27 -0
  9. package/dist/accounts/liquid-fees.js.map +1 -0
  10. package/dist/accounts/liquid-state.d.ts +112 -0
  11. package/dist/accounts/liquid-state.d.ts.map +1 -0
  12. package/dist/accounts/liquid-state.js +92 -0
  13. package/dist/accounts/liquid-state.js.map +1 -0
  14. package/dist/accounts/liquid-swap.d.ts +97 -0
  15. package/dist/accounts/liquid-swap.d.ts.map +1 -0
  16. package/dist/accounts/liquid-swap.js +54 -0
  17. package/dist/accounts/liquid-swap.js.map +1 -0
  18. package/dist/accounts/liquid.d.ts +175 -0
  19. package/dist/accounts/liquid.d.ts.map +1 -0
  20. package/dist/accounts/liquid.js +66 -0
  21. package/dist/accounts/liquid.js.map +1 -0
  22. package/dist/client.d.ts +621 -0
  23. package/dist/client.d.ts.map +1 -0
  24. package/dist/client.js +511 -0
  25. package/dist/client.js.map +1 -0
  26. package/dist/config.d.ts +56 -0
  27. package/dist/config.d.ts.map +1 -0
  28. package/dist/config.js +44 -0
  29. package/dist/config.js.map +1 -0
  30. package/dist/errors.d.ts +39 -0
  31. package/dist/errors.d.ts.map +1 -0
  32. package/dist/errors.js +63 -0
  33. package/dist/errors.js.map +1 -0
  34. package/dist/events/index.d.ts +4 -0
  35. package/dist/events/index.d.ts.map +1 -0
  36. package/dist/events/index.js +2 -0
  37. package/dist/events/index.js.map +1 -0
  38. package/dist/events/parser.d.ts +40 -0
  39. package/dist/events/parser.d.ts.map +1 -0
  40. package/dist/events/parser.js +67 -0
  41. package/dist/events/parser.js.map +1 -0
  42. package/dist/events/types.d.ts +286 -0
  43. package/dist/events/types.d.ts.map +1 -0
  44. package/dist/events/types.js +2 -0
  45. package/dist/events/types.js.map +1 -0
  46. package/dist/helpers/index.d.ts +4 -0
  47. package/dist/helpers/index.d.ts.map +1 -0
  48. package/dist/helpers/index.js +3 -0
  49. package/dist/helpers/index.js.map +1 -0
  50. package/dist/helpers/preview.d.ts +259 -0
  51. package/dist/helpers/preview.d.ts.map +1 -0
  52. package/dist/helpers/preview.js +458 -0
  53. package/dist/helpers/preview.js.map +1 -0
  54. package/dist/helpers/user.d.ts +11 -0
  55. package/dist/helpers/user.d.ts.map +1 -0
  56. package/dist/helpers/user.js +20 -0
  57. package/dist/helpers/user.js.map +1 -0
  58. package/dist/idl/index.d.ts +53 -0
  59. package/dist/idl/index.d.ts.map +1 -0
  60. package/dist/idl/index.js +64 -0
  61. package/dist/idl/index.js.map +1 -0
  62. package/dist/idl/liquid.d.ts +10523 -0
  63. package/dist/idl/liquid.d.ts.map +1 -0
  64. package/dist/idl/liquid.js +2 -0
  65. package/dist/idl/liquid.js.map +1 -0
  66. package/dist/idl/liquid.json +10516 -0
  67. package/dist/idl/liquid_fees.d.ts +1520 -0
  68. package/dist/idl/liquid_fees.d.ts.map +1 -0
  69. package/dist/idl/liquid_fees.js +2 -0
  70. package/dist/idl/liquid_fees.js.map +1 -0
  71. package/dist/idl/liquid_fees.json +1513 -0
  72. package/dist/idl/liquid_state.d.ts +2936 -0
  73. package/dist/idl/liquid_state.d.ts.map +1 -0
  74. package/dist/idl/liquid_state.js +2 -0
  75. package/dist/idl/liquid_state.js.map +1 -0
  76. package/dist/idl/liquid_state.json +2929 -0
  77. package/dist/idl/liquid_swap.d.ts +5849 -0
  78. package/dist/idl/liquid_swap.d.ts.map +1 -0
  79. package/dist/idl/liquid_swap.js +2 -0
  80. package/dist/idl/liquid_swap.js.map +1 -0
  81. package/dist/idl/liquid_swap.json +5842 -0
  82. package/dist/index.d.ts +19 -0
  83. package/dist/index.d.ts.map +1 -0
  84. package/dist/index.js +15 -0
  85. package/dist/index.js.map +1 -0
  86. package/dist/instructions/index.d.ts +9 -0
  87. package/dist/instructions/index.d.ts.map +1 -0
  88. package/dist/instructions/index.js +9 -0
  89. package/dist/instructions/index.js.map +1 -0
  90. package/dist/instructions/liquid-fees.d.ts +111 -0
  91. package/dist/instructions/liquid-fees.d.ts.map +1 -0
  92. package/dist/instructions/liquid-fees.js +169 -0
  93. package/dist/instructions/liquid-fees.js.map +1 -0
  94. package/dist/instructions/liquid-state.d.ts +173 -0
  95. package/dist/instructions/liquid-state.d.ts.map +1 -0
  96. package/dist/instructions/liquid-state.js +194 -0
  97. package/dist/instructions/liquid-state.js.map +1 -0
  98. package/dist/instructions/liquid-swap.d.ts +122 -0
  99. package/dist/instructions/liquid-swap.d.ts.map +1 -0
  100. package/dist/instructions/liquid-swap.js +167 -0
  101. package/dist/instructions/liquid-swap.js.map +1 -0
  102. package/dist/instructions/liquid.d.ts +297 -0
  103. package/dist/instructions/liquid.d.ts.map +1 -0
  104. package/dist/instructions/liquid.js +483 -0
  105. package/dist/instructions/liquid.js.map +1 -0
  106. package/dist/instructions/program-cache.d.ts +35 -0
  107. package/dist/instructions/program-cache.d.ts.map +1 -0
  108. package/dist/instructions/program-cache.js +68 -0
  109. package/dist/instructions/program-cache.js.map +1 -0
  110. package/dist/math/amm.d.ts +42 -0
  111. package/dist/math/amm.d.ts.map +1 -0
  112. package/dist/math/amm.js +109 -0
  113. package/dist/math/amm.js.map +1 -0
  114. package/dist/math/bonding-curve.d.ts +34 -0
  115. package/dist/math/bonding-curve.d.ts.map +1 -0
  116. package/dist/math/bonding-curve.js +80 -0
  117. package/dist/math/bonding-curve.js.map +1 -0
  118. package/dist/math/constants.d.ts +14 -0
  119. package/dist/math/constants.d.ts.map +1 -0
  120. package/dist/math/constants.js +14 -0
  121. package/dist/math/constants.js.map +1 -0
  122. package/dist/math/fees.d.ts +88 -0
  123. package/dist/math/fees.d.ts.map +1 -0
  124. package/dist/math/fees.js +135 -0
  125. package/dist/math/fees.js.map +1 -0
  126. package/dist/math/index.d.ts +8 -0
  127. package/dist/math/index.d.ts.map +1 -0
  128. package/dist/math/index.js +6 -0
  129. package/dist/math/index.js.map +1 -0
  130. package/dist/math/tiered-fees.d.ts +80 -0
  131. package/dist/math/tiered-fees.d.ts.map +1 -0
  132. package/dist/math/tiered-fees.js +129 -0
  133. package/dist/math/tiered-fees.js.map +1 -0
  134. package/dist/oracle.d.ts +53 -0
  135. package/dist/oracle.d.ts.map +1 -0
  136. package/dist/oracle.js +70 -0
  137. package/dist/oracle.js.map +1 -0
  138. package/dist/pda/index.d.ts +89 -0
  139. package/dist/pda/index.d.ts.map +1 -0
  140. package/dist/pda/index.js +127 -0
  141. package/dist/pda/index.js.map +1 -0
  142. package/dist/pda/liquid-fees.d.ts +27 -0
  143. package/dist/pda/liquid-fees.d.ts.map +1 -0
  144. package/dist/pda/liquid-fees.js +36 -0
  145. package/dist/pda/liquid-fees.js.map +1 -0
  146. package/dist/pda/liquid-state.d.ts +56 -0
  147. package/dist/pda/liquid-state.d.ts.map +1 -0
  148. package/dist/pda/liquid-state.js +79 -0
  149. package/dist/pda/liquid-state.js.map +1 -0
  150. package/dist/pda/liquid-swap.d.ts +76 -0
  151. package/dist/pda/liquid-swap.d.ts.map +1 -0
  152. package/dist/pda/liquid-swap.js +103 -0
  153. package/dist/pda/liquid-swap.js.map +1 -0
  154. package/dist/pda/liquid.d.ts +67 -0
  155. package/dist/pda/liquid.d.ts.map +1 -0
  156. package/dist/pda/liquid.js +91 -0
  157. package/dist/pda/liquid.js.map +1 -0
  158. package/dist/provider.d.ts +26 -0
  159. package/dist/provider.d.ts.map +1 -0
  160. package/dist/provider.js +47 -0
  161. package/dist/provider.js.map +1 -0
  162. package/dist/transaction/builder.d.ts +30 -0
  163. package/dist/transaction/builder.d.ts.map +1 -0
  164. package/dist/transaction/builder.js +48 -0
  165. package/dist/transaction/builder.js.map +1 -0
  166. package/dist/transaction/index.d.ts +3 -0
  167. package/dist/transaction/index.d.ts.map +1 -0
  168. package/dist/transaction/index.js +3 -0
  169. package/dist/transaction/index.js.map +1 -0
  170. package/dist/transaction/send.d.ts +25 -0
  171. package/dist/transaction/send.d.ts.map +1 -0
  172. package/dist/transaction/send.js +52 -0
  173. package/dist/transaction/send.js.map +1 -0
  174. package/dist/types.d.ts +311 -0
  175. package/dist/types.d.ts.map +1 -0
  176. package/dist/types.js +46 -0
  177. package/dist/types.js.map +1 -0
  178. package/package.json +112 -0
  179. package/src/accounts/index.ts +26 -0
  180. package/src/accounts/liquid-fees.ts +38 -0
  181. package/src/accounts/liquid-state.ts +134 -0
  182. package/src/accounts/liquid-swap.ts +79 -0
  183. package/src/accounts/liquid.ts +100 -0
  184. package/src/client.ts +1001 -0
  185. package/src/config.ts +91 -0
  186. package/src/errors.ts +94 -0
  187. package/src/events/index.ts +42 -0
  188. package/src/events/parser.ts +90 -0
  189. package/src/events/types.ts +310 -0
  190. package/src/helpers/index.ts +23 -0
  191. package/src/helpers/preview.ts +798 -0
  192. package/src/helpers/user.ts +24 -0
  193. package/src/idl/index.ts +94 -0
  194. package/src/idl/liquid.json +10516 -0
  195. package/src/idl/liquid.ts +10522 -0
  196. package/src/idl/liquid_fees.json +1513 -0
  197. package/src/idl/liquid_fees.ts +1519 -0
  198. package/src/idl/liquid_state.json +2929 -0
  199. package/src/idl/liquid_state.ts +2935 -0
  200. package/src/idl/liquid_swap.json +5842 -0
  201. package/src/idl/liquid_swap.ts +5848 -0
  202. package/src/index.ts +98 -0
  203. package/src/instructions/index.ts +109 -0
  204. package/src/instructions/liquid-fees.ts +289 -0
  205. package/src/instructions/liquid-state.ts +336 -0
  206. package/src/instructions/liquid-swap.ts +414 -0
  207. package/src/instructions/liquid.ts +884 -0
  208. package/src/instructions/program-cache.ts +106 -0
  209. package/src/math/amm.ts +146 -0
  210. package/src/math/bonding-curve.ts +122 -0
  211. package/src/math/constants.ts +19 -0
  212. package/src/math/fees.ts +191 -0
  213. package/src/math/index.ts +40 -0
  214. package/src/math/tiered-fees.ts +165 -0
  215. package/src/oracle.ts +97 -0
  216. package/src/pda/index.ts +331 -0
  217. package/src/pda/liquid-fees.ts +58 -0
  218. package/src/pda/liquid-state.ts +123 -0
  219. package/src/pda/liquid-swap.ts +162 -0
  220. package/src/pda/liquid.ts +152 -0
  221. package/src/provider.ts +60 -0
  222. package/src/transaction/builder.ts +80 -0
  223. package/src/transaction/index.ts +6 -0
  224. package/src/transaction/send.ts +72 -0
  225. package/src/types.ts +354 -0
@@ -0,0 +1,884 @@
1
+ import type {
2
+ Connection,
3
+ PublicKey,
4
+ TransactionInstruction,
5
+ } from "@solana/web3.js";
6
+ import {
7
+ getAssociatedTokenAddressSync,
8
+ TOKEN_PROGRAM_ID,
9
+ } from "@solana/spl-token";
10
+ import type BN from "bn.js";
11
+ import { WSOL_MINT, type LiquidConfig } from "../config.js";
12
+ import {
13
+ getBondingCurvePDA,
14
+ getBondingCurveTokenAccount,
15
+ getStableBondingCurvePDA,
16
+ } from "../pda/liquid.js";
17
+ import { getUserPropertiesPDA, getTokenVolumePDA } from "../pda/liquid-state.js";
18
+ import {
19
+ getPoolPDA,
20
+ getPoolLpMintPDA,
21
+ getPoolVaultPDA,
22
+ getObservationPDA,
23
+ getSwapGlobalConfigPDA,
24
+ getSwapAuthorityPDA,
25
+ getSwapBuybackVaultPDA,
26
+ } from "../pda/liquid-swap.js";
27
+ import { getCachedLiquidProgram } from "./program-cache.js";
28
+ import {
29
+ fetchNativeBondingCurve,
30
+ fetchStableBondingCurve,
31
+ } from "../accounts/liquid.js";
32
+ export interface BuildCreateNativeCurveParams {
33
+ creator: PublicKey;
34
+ mint: PublicKey;
35
+ pythPriceFeed: PublicKey;
36
+ name: string;
37
+ symbol: string;
38
+ uri: string;
39
+ config: LiquidConfig;
40
+ }
41
+
42
+ /**
43
+ * Builds a createNativeCurve instruction.
44
+ * The mint Keypair must be passed as a signer when sending the transaction.
45
+ * Atomically initializes the fee configuration via CPI to liquid-fees
46
+ * with the creator as the sole recipient (100%). Use `buildUpdateFeeConfig`
47
+ * to set custom recipients afterward.
48
+ *
49
+ * @param params - {@link BuildCreateNativeCurveParams}
50
+ * @returns Transaction instruction
51
+ */
52
+ export function buildCreateNativeCurve(
53
+ params: BuildCreateNativeCurveParams
54
+ ): Promise<TransactionInstruction> {
55
+ const { creator, mint, pythPriceFeed, name, symbol, uri, config } = params;
56
+ const program = getCachedLiquidProgram(config);
57
+
58
+ const bondingCurveTokenAccount = getBondingCurveTokenAccount(
59
+ mint,
60
+ config.liquidProgramId
61
+ );
62
+ return program.methods
63
+ .createNativeCurve({
64
+ name,
65
+ symbol,
66
+ uri,
67
+ })
68
+ .accounts({
69
+ creator,
70
+ mint,
71
+ pythPriceFeed,
72
+ bondingCurveTokenAccount,
73
+ })
74
+ .instruction();
75
+ }
76
+
77
+ export interface BuildBumpNativeParams {
78
+ mint: PublicKey;
79
+ pythPriceFeed: PublicKey;
80
+ config: LiquidConfig;
81
+ }
82
+
83
+ /**
84
+ * Builds a bumpNative instruction.
85
+ * Re-evaluates a native bonding curve's market cap against the current oracle price
86
+ * and marks it as complete if the threshold is exceeded. Permissionless.
87
+ *
88
+ * @param params - {@link BuildBumpNativeParams}
89
+ * @returns Transaction instruction
90
+ */
91
+ export function buildBumpNative(
92
+ params: BuildBumpNativeParams
93
+ ): Promise<TransactionInstruction> {
94
+ const { mint, pythPriceFeed, config } = params;
95
+ const program = getCachedLiquidProgram(config);
96
+
97
+ return program.methods
98
+ .bumpNative()
99
+ .accounts({
100
+ mint,
101
+ pythPriceFeed,
102
+ })
103
+ .instruction();
104
+ }
105
+
106
+ export interface BuildBuyNativeParams {
107
+ user: PublicKey;
108
+ mint: PublicKey;
109
+ creator: PublicKey;
110
+ pythPriceFeed: PublicKey;
111
+ amountIn: BN;
112
+ minAmountOut: BN;
113
+ feeRecipient: PublicKey;
114
+ creatorReferralVault?: PublicKey | null;
115
+ traderReferralVault?: PublicKey | null;
116
+ config: LiquidConfig;
117
+ }
118
+
119
+ /**
120
+ * Builds a buyNative instruction.
121
+ * Requires the bonding curve creator and Pyth price feed to be known.
122
+ *
123
+ * @param params - {@link BuildBuyNativeParams}
124
+ * @returns Transaction instruction
125
+ */
126
+ export function buildBuyNative(
127
+ params: BuildBuyNativeParams
128
+ ): Promise<TransactionInstruction> {
129
+ const {
130
+ user,
131
+ mint,
132
+ creator,
133
+ pythPriceFeed,
134
+ amountIn,
135
+ minAmountOut,
136
+ feeRecipient,
137
+ creatorReferralVault,
138
+ traderReferralVault,
139
+ config,
140
+ } = params;
141
+
142
+ const program = getCachedLiquidProgram(config);
143
+
144
+ // Derive creator-related accounts that Anchor can't auto-resolve
145
+ const [creatorUserProperties] = getUserPropertiesPDA(
146
+ creator,
147
+ config.liquidStateProgramId
148
+ );
149
+
150
+ return program.methods
151
+ .buyNative(amountIn, minAmountOut)
152
+ .accountsPartial({
153
+ user,
154
+ feeRecipient,
155
+ mint,
156
+ pythPriceFeed,
157
+ creatorUserProperties,
158
+ creatorReferralVault: creatorReferralVault ?? null,
159
+ traderReferralVault: traderReferralVault ?? null,
160
+ liquidState: {
161
+ user,
162
+ tokenMint: mint,
163
+ },
164
+ })
165
+ .instruction();
166
+ }
167
+
168
+ /**
169
+ * Builds a buyNative instruction, automatically fetching the bonding curve
170
+ * creator from chain. Convenience wrapper around `buildBuyNative`.
171
+ *
172
+ * @param connection - Solana RPC connection
173
+ * @param params - {@link BuildBuyNativeParams} without `creator`
174
+ * @returns Transaction instruction
175
+ */
176
+ export async function buildBuyNativeAutoResolve(
177
+ connection: Connection,
178
+ params: Omit<BuildBuyNativeParams, "creator">
179
+ ): Promise<TransactionInstruction> {
180
+ const curve = await fetchNativeBondingCurve(
181
+ connection,
182
+ params.mint,
183
+ params.config
184
+ );
185
+ return buildBuyNative({
186
+ ...params,
187
+ creator: curve.creator,
188
+ pythPriceFeed: params.pythPriceFeed,
189
+ });
190
+ }
191
+
192
+ export interface BuildSellNativeParams {
193
+ user: PublicKey;
194
+ mint: PublicKey;
195
+ creator: PublicKey;
196
+ pythPriceFeed: PublicKey;
197
+ amountIn: BN;
198
+ minAmountOut: BN;
199
+ feeRecipient: PublicKey;
200
+ creatorReferralVault?: PublicKey | null;
201
+ traderReferralVault?: PublicKey | null;
202
+ config: LiquidConfig;
203
+ }
204
+
205
+ /**
206
+ * Builds a sellNative instruction.
207
+ * Requires the bonding curve creator and Pyth price feed to be known.
208
+ *
209
+ * @param params - {@link BuildSellNativeParams}
210
+ * @returns Transaction instruction
211
+ */
212
+ export function buildSellNative(
213
+ params: BuildSellNativeParams
214
+ ): Promise<TransactionInstruction> {
215
+ const {
216
+ user,
217
+ mint,
218
+ creator,
219
+ pythPriceFeed,
220
+ amountIn,
221
+ minAmountOut,
222
+ feeRecipient,
223
+ creatorReferralVault,
224
+ traderReferralVault,
225
+ config,
226
+ } = params;
227
+
228
+ const program = getCachedLiquidProgram(config);
229
+
230
+ // Derive creator-related accounts that Anchor can't auto-resolve
231
+ const [creatorUserProperties] = getUserPropertiesPDA(
232
+ creator,
233
+ config.liquidStateProgramId
234
+ );
235
+
236
+ return program.methods
237
+ .sellNative(amountIn, minAmountOut)
238
+ .accountsPartial({
239
+ user,
240
+ feeRecipient,
241
+ mint,
242
+ pythPriceFeed,
243
+ creatorUserProperties,
244
+ creatorReferralVault: creatorReferralVault ?? null,
245
+ traderReferralVault: traderReferralVault ?? null,
246
+ liquidState: {
247
+ user,
248
+ tokenMint: mint,
249
+ },
250
+ })
251
+ .instruction();
252
+ }
253
+
254
+ /**
255
+ * Builds a sellNative instruction, automatically fetching the bonding curve
256
+ * creator from chain. Convenience wrapper around `buildSellNative`.
257
+ *
258
+ * @param connection - Solana RPC connection
259
+ * @param params - {@link BuildSellNativeParams} without `creator`
260
+ * @returns Transaction instruction
261
+ */
262
+ export async function buildSellNativeAutoResolve(
263
+ connection: Connection,
264
+ params: Omit<BuildSellNativeParams, "creator">
265
+ ): Promise<TransactionInstruction> {
266
+ const curve = await fetchNativeBondingCurve(
267
+ connection,
268
+ params.mint,
269
+ params.config
270
+ );
271
+ return buildSellNative({
272
+ ...params,
273
+ creator: curve.creator,
274
+ pythPriceFeed: params.pythPriceFeed,
275
+ });
276
+ }
277
+
278
+ export interface BuildMigrateNativeParams {
279
+ migrator: PublicKey;
280
+ mint: PublicKey;
281
+ config: LiquidConfig;
282
+ }
283
+
284
+ /**
285
+ * Builds a migrate instruction (bonding curve -> AMM pool).
286
+ * Permissionless — anyone can trigger migration once the curve is complete.
287
+ *
288
+ * @param params - {@link BuildMigrateNativeParams}
289
+ * @returns Transaction instruction
290
+ */
291
+ export function buildMigrateNative(
292
+ params: BuildMigrateNativeParams
293
+ ): Promise<TransactionInstruction> {
294
+ const { migrator, mint, config } = params;
295
+ const program = getCachedLiquidProgram(config);
296
+
297
+ // Derive AMM PDAs
298
+ const [bondingCurve] = getBondingCurvePDA(mint, config.liquidProgramId);
299
+ const [ammPoolState] = getPoolPDA(
300
+ mint,
301
+ WSOL_MINT,
302
+ config.liquidSwapProgramId
303
+ );
304
+ const [ammLpMint] = getPoolLpMintPDA(
305
+ ammPoolState,
306
+ config.liquidSwapProgramId
307
+ );
308
+ const [ammBaseVault] = getPoolVaultPDA(
309
+ ammPoolState,
310
+ mint,
311
+ config.liquidSwapProgramId
312
+ );
313
+ const [ammQuoteVault] = getPoolVaultPDA(
314
+ ammPoolState,
315
+ WSOL_MINT,
316
+ config.liquidSwapProgramId
317
+ );
318
+ const [ammObservationState] = getObservationPDA(
319
+ ammPoolState,
320
+ config.liquidSwapProgramId
321
+ );
322
+ const [ammGlobalConfig] = getSwapGlobalConfigPDA(
323
+ config.liquidSwapProgramId
324
+ );
325
+ const [ammAuthority] = getSwapAuthorityPDA(config.liquidSwapProgramId);
326
+ const [tokenVolume] = getTokenVolumePDA(mint, config.liquidStateProgramId);
327
+ const bondingCurveLpToken = getAssociatedTokenAddressSync(
328
+ ammLpMint,
329
+ bondingCurve,
330
+ true,
331
+ TOKEN_PROGRAM_ID
332
+ );
333
+ const [ammBuybackVault] = getSwapBuybackVaultPDA(
334
+ ammPoolState,
335
+ WSOL_MINT,
336
+ config.liquidSwapProgramId
337
+ );
338
+ return program.methods
339
+ .migrate()
340
+ .accounts({
341
+ signer: migrator,
342
+ mint,
343
+ ammPoolState,
344
+ ammLpMint,
345
+ ammBaseVault,
346
+ ammQuoteVault,
347
+ ammObservationState,
348
+ ammGlobalConfig,
349
+ ammAuthority,
350
+ bondingCurveLpToken,
351
+ tokenVolume,
352
+ ammBuybackVault,
353
+ })
354
+ .instruction();
355
+ }
356
+
357
+ export interface BuildInitializeNativeReferralVaultParams {
358
+ user: PublicKey;
359
+ config: LiquidConfig;
360
+ }
361
+
362
+ /**
363
+ * Builds an initializeNativeReferralVault instruction (creates native SOL referral vault).
364
+ *
365
+ * @param params - {@link BuildInitializeNativeReferralVaultParams}
366
+ * @returns Transaction instruction
367
+ */
368
+ export function buildInitializeNativeReferralVault(
369
+ params: BuildInitializeNativeReferralVaultParams
370
+ ): Promise<TransactionInstruction> {
371
+ const { user, config } = params;
372
+ const program = getCachedLiquidProgram(config);
373
+
374
+ return program.methods
375
+ .initializeNativeReferralVault()
376
+ .accounts({ user })
377
+ .instruction();
378
+ }
379
+
380
+ export interface BuildWithdrawReferralRewardsParams {
381
+ user: PublicKey;
382
+ config: LiquidConfig;
383
+ }
384
+
385
+ /**
386
+ * Builds a withdrawReferralRewards instruction.
387
+ *
388
+ * @param params - {@link BuildWithdrawReferralRewardsParams}
389
+ * @returns Transaction instruction
390
+ */
391
+ export function buildWithdrawReferralRewards(
392
+ params: BuildWithdrawReferralRewardsParams
393
+ ): Promise<TransactionInstruction> {
394
+ const { user, config } = params;
395
+ const program = getCachedLiquidProgram(config);
396
+
397
+ return program.methods
398
+ .withdrawReferralRewards()
399
+ .accounts({ user })
400
+ .instruction();
401
+ }
402
+
403
+ export interface BuildExecuteBuybackNativeParams {
404
+ payer: PublicKey;
405
+ mint: PublicKey;
406
+ pythPriceFeed: PublicKey;
407
+ config: LiquidConfig;
408
+ }
409
+
410
+ /**
411
+ * Builds an executeBuybackNative instruction for a native SOL bonding curve.
412
+ * Permissionless — anyone can trigger. Only works when fee config is Revoked.
413
+ *
414
+ * @param params - {@link BuildExecuteBuybackNativeParams}
415
+ * @returns Transaction instruction
416
+ */
417
+ export function buildExecuteBuybackNative(
418
+ params: BuildExecuteBuybackNativeParams
419
+ ): Promise<TransactionInstruction> {
420
+ const { payer, mint, pythPriceFeed, config } = params;
421
+ const program = getCachedLiquidProgram(config);
422
+
423
+ return program.methods
424
+ .executeBuybackNative()
425
+ .accountsPartial({
426
+ payer,
427
+ mint,
428
+ pythPriceFeed,
429
+ })
430
+ .instruction();
431
+ }
432
+
433
+ export interface BuildExecuteBuybackTokenParams {
434
+ payer: PublicKey;
435
+ mint: PublicKey;
436
+ quoteMint: PublicKey;
437
+ config: LiquidConfig;
438
+ }
439
+
440
+ /**
441
+ * Builds an executeBuybackToken instruction for a token-based bonding curve.
442
+ * Permissionless — anyone can trigger. Only works when fee config is Revoked.
443
+ *
444
+ * @param params - {@link BuildExecuteBuybackTokenParams}
445
+ * @returns Transaction instruction
446
+ */
447
+ export function buildExecuteBuybackToken(
448
+ params: BuildExecuteBuybackTokenParams
449
+ ): Promise<TransactionInstruction> {
450
+ const { payer, mint, quoteMint, config } = params;
451
+ const program = getCachedLiquidProgram(config);
452
+
453
+ return program.methods
454
+ .executeBuybackToken()
455
+ .accountsPartial({
456
+ payer,
457
+ mint,
458
+ quoteMint,
459
+ })
460
+ .instruction();
461
+ }
462
+
463
+ export interface BuildCreateStableCurveParams {
464
+ creator: PublicKey;
465
+ mint: PublicKey;
466
+ quoteMint: PublicKey;
467
+ name: string;
468
+ symbol: string;
469
+ uri: string;
470
+ config: LiquidConfig;
471
+ }
472
+
473
+ /**
474
+ * Builds a createStableCurve instruction.
475
+ * Creates a token-based bonding curve (e.g., using USDC as quote).
476
+ * The mint Keypair must be passed as a signer when sending the transaction.
477
+ * Atomically initializes the fee configuration via CPI to liquid-fees
478
+ * with the creator as the sole recipient (100%). Use `buildUpdateFeeConfig`
479
+ * to set custom recipients afterward.
480
+ *
481
+ * @param params - {@link BuildCreateStableCurveParams}
482
+ * @returns Transaction instruction
483
+ */
484
+ export function buildCreateStableCurve(
485
+ params: BuildCreateStableCurveParams
486
+ ): Promise<TransactionInstruction> {
487
+ const { creator, mint, quoteMint, name, symbol, uri, config } = params;
488
+ const program = getCachedLiquidProgram(config);
489
+
490
+ return program.methods
491
+ .createStableCurve({
492
+ name,
493
+ symbol,
494
+ uri,
495
+ })
496
+ .accounts({
497
+ creator,
498
+ mint,
499
+ quoteMint,
500
+ })
501
+ .instruction();
502
+ }
503
+
504
+ export interface BuildBuyStableParams {
505
+ user: PublicKey;
506
+ mint: PublicKey;
507
+ quoteMint: PublicKey;
508
+ creator: PublicKey;
509
+ amountIn: BN;
510
+ minAmountOut: BN;
511
+ feeRecipient: PublicKey;
512
+ creatorReferralVault?: PublicKey | null;
513
+ traderReferralVault?: PublicKey | null;
514
+ config: LiquidConfig;
515
+ }
516
+
517
+ /**
518
+ * Builds a buyStable instruction.
519
+ * Buys tokens from a token-based bonding curve using quote tokens (e.g., USDC).
520
+ *
521
+ * @param params - {@link BuildBuyStableParams}
522
+ * @returns Transaction instruction
523
+ */
524
+ export function buildBuyStable(
525
+ params: BuildBuyStableParams
526
+ ): Promise<TransactionInstruction> {
527
+ const {
528
+ user,
529
+ mint,
530
+ quoteMint,
531
+ creator,
532
+ amountIn,
533
+ minAmountOut,
534
+ feeRecipient,
535
+ creatorReferralVault,
536
+ traderReferralVault,
537
+ config,
538
+ } = params;
539
+
540
+ const program = getCachedLiquidProgram(config);
541
+
542
+ // Fee recipient quote token account
543
+ const feeRecipientQuoteAccount = getAssociatedTokenAddressSync(
544
+ quoteMint,
545
+ feeRecipient,
546
+ true,
547
+ TOKEN_PROGRAM_ID
548
+ );
549
+
550
+ // Derive creator-related accounts that Anchor can't auto-resolve
551
+ const [creatorUserProperties] = getUserPropertiesPDA(
552
+ creator,
553
+ config.liquidStateProgramId
554
+ );
555
+
556
+ return program.methods
557
+ .buyStable(amountIn, minAmountOut)
558
+ .accountsPartial({
559
+ user,
560
+ mint,
561
+ quoteMint,
562
+ feeRecipient: feeRecipientQuoteAccount,
563
+ creatorUserProperties,
564
+ creatorReferralVault: creatorReferralVault ?? null,
565
+ traderReferralVault: traderReferralVault ?? null,
566
+ liquidState: {
567
+ user,
568
+ tokenMint: mint,
569
+ },
570
+ })
571
+ .instruction();
572
+ }
573
+
574
+ /**
575
+ * Builds a buyStable instruction, automatically fetching the bonding curve
576
+ * creator from chain. Convenience wrapper around `buildBuyStable`.
577
+ *
578
+ * @param connection - Solana RPC connection
579
+ * @param params - {@link BuildBuyStableParams} without `creator`
580
+ * @returns Transaction instruction
581
+ */
582
+ export async function buildBuyStableAutoResolve(
583
+ connection: Connection,
584
+ params: Omit<BuildBuyStableParams, "creator">
585
+ ): Promise<TransactionInstruction> {
586
+ const curve = await fetchStableBondingCurve(
587
+ connection,
588
+ params.mint,
589
+ params.quoteMint,
590
+ params.config
591
+ );
592
+ return buildBuyStable({ ...params, creator: curve.creator });
593
+ }
594
+
595
+ export interface BuildSellStableParams {
596
+ user: PublicKey;
597
+ mint: PublicKey;
598
+ quoteMint: PublicKey;
599
+ creator: PublicKey;
600
+ amountIn: BN;
601
+ minAmountOut: BN;
602
+ feeRecipient: PublicKey;
603
+ creatorReferralVault?: PublicKey | null;
604
+ traderReferralVault?: PublicKey | null;
605
+ config: LiquidConfig;
606
+ }
607
+
608
+ /**
609
+ * Builds a sellStable instruction.
610
+ * Sells tokens to a token-based bonding curve for quote tokens (e.g., USDC).
611
+ *
612
+ * @param params - {@link BuildSellStableParams}
613
+ * @returns Transaction instruction
614
+ */
615
+ export function buildSellStable(
616
+ params: BuildSellStableParams
617
+ ): Promise<TransactionInstruction> {
618
+ const {
619
+ user,
620
+ mint,
621
+ quoteMint,
622
+ creator,
623
+ amountIn,
624
+ minAmountOut,
625
+ feeRecipient,
626
+ creatorReferralVault,
627
+ traderReferralVault,
628
+ config,
629
+ } = params;
630
+
631
+ const program = getCachedLiquidProgram(config);
632
+
633
+ // Fee recipient quote token account
634
+ const feeRecipientQuoteAccount = getAssociatedTokenAddressSync(
635
+ quoteMint,
636
+ feeRecipient,
637
+ true,
638
+ TOKEN_PROGRAM_ID
639
+ );
640
+
641
+ // Derive creator-related accounts that Anchor can't auto-resolve
642
+ const [creatorUserProperties] = getUserPropertiesPDA(
643
+ creator,
644
+ config.liquidStateProgramId
645
+ );
646
+
647
+ return program.methods
648
+ .sellStable(amountIn, minAmountOut)
649
+ .accountsPartial({
650
+ user,
651
+ mint,
652
+ quoteMint,
653
+ feeRecipient: feeRecipientQuoteAccount,
654
+ creatorUserProperties,
655
+ creatorReferralVault: creatorReferralVault ?? null,
656
+ traderReferralVault: traderReferralVault ?? null,
657
+ liquidState: {
658
+ user,
659
+ tokenMint: mint,
660
+ },
661
+ })
662
+ .instruction();
663
+ }
664
+
665
+ /**
666
+ * Builds a sellStable instruction, automatically fetching the bonding curve
667
+ * creator from chain. Convenience wrapper around `buildSellStable`.
668
+ *
669
+ * @param connection - Solana RPC connection
670
+ * @param params - {@link BuildSellStableParams} without `creator`
671
+ * @returns Transaction instruction
672
+ */
673
+ export async function buildSellStableAutoResolve(
674
+ connection: Connection,
675
+ params: Omit<BuildSellStableParams, "creator">
676
+ ): Promise<TransactionInstruction> {
677
+ const curve = await fetchStableBondingCurve(
678
+ connection,
679
+ params.mint,
680
+ params.quoteMint,
681
+ params.config
682
+ );
683
+ return buildSellStable({ ...params, creator: curve.creator });
684
+ }
685
+
686
+ export interface BuildMigrateStableParams {
687
+ migrator: PublicKey;
688
+ mint: PublicKey;
689
+ quoteMint: PublicKey;
690
+ config: LiquidConfig;
691
+ }
692
+
693
+ /**
694
+ * Builds a migrateStable instruction (token bonding curve -> AMM pool).
695
+ * Permissionless — anyone can trigger migration once the curve is complete.
696
+ *
697
+ * @param params - {@link BuildMigrateStableParams}
698
+ * @returns Transaction instruction
699
+ */
700
+ export function buildMigrateStable(
701
+ params: BuildMigrateStableParams
702
+ ): Promise<TransactionInstruction> {
703
+ const { migrator, mint, quoteMint, config } = params;
704
+ const program = getCachedLiquidProgram(config);
705
+
706
+ // Derive AMM PDAs
707
+ const [bondingCurve] = getStableBondingCurvePDA(
708
+ mint,
709
+ quoteMint,
710
+ config.liquidProgramId
711
+ );
712
+ const [ammPoolState] = getPoolPDA(
713
+ mint,
714
+ quoteMint,
715
+ config.liquidSwapProgramId
716
+ );
717
+ const [ammLpMint] = getPoolLpMintPDA(
718
+ ammPoolState,
719
+ config.liquidSwapProgramId
720
+ );
721
+ const [ammBaseVault] = getPoolVaultPDA(
722
+ ammPoolState,
723
+ mint,
724
+ config.liquidSwapProgramId
725
+ );
726
+ const [ammQuoteVault] = getPoolVaultPDA(
727
+ ammPoolState,
728
+ quoteMint,
729
+ config.liquidSwapProgramId
730
+ );
731
+ const [ammObservationState] = getObservationPDA(
732
+ ammPoolState,
733
+ config.liquidSwapProgramId
734
+ );
735
+ const [ammGlobalConfig] = getSwapGlobalConfigPDA(
736
+ config.liquidSwapProgramId
737
+ );
738
+ const [ammAuthority] = getSwapAuthorityPDA(config.liquidSwapProgramId);
739
+ const [tokenVolume] = getTokenVolumePDA(mint, config.liquidStateProgramId);
740
+ const bondingCurveLpToken = getAssociatedTokenAddressSync(
741
+ ammLpMint,
742
+ bondingCurve,
743
+ true,
744
+ TOKEN_PROGRAM_ID
745
+ );
746
+ const [ammBuybackVault] = getSwapBuybackVaultPDA(
747
+ ammPoolState,
748
+ quoteMint,
749
+ config.liquidSwapProgramId
750
+ );
751
+ return program.methods
752
+ .migrateStable()
753
+ .accounts({
754
+ signer: migrator,
755
+ mint,
756
+ quoteMint,
757
+ ammPoolState,
758
+ ammLpMint,
759
+ ammBaseVault,
760
+ ammQuoteVault,
761
+ ammObservationState,
762
+ ammGlobalConfig,
763
+ ammAuthority,
764
+ bondingCurveLpToken,
765
+ tokenVolume,
766
+ ammBuybackVault,
767
+ })
768
+ .instruction();
769
+ }
770
+
771
+ export interface BuildSetFeeRecipientsParams {
772
+ admin: PublicKey;
773
+ /** Array of 8 fee recipient pubkeys */
774
+ feeRecipients: PublicKey[];
775
+ config: LiquidConfig;
776
+ }
777
+
778
+ /**
779
+ * Builds a setFeeRecipients instruction.
780
+ * Admin-only instruction to set/update the protocol fee recipients.
781
+ *
782
+ * @param params - {@link BuildSetFeeRecipientsParams}
783
+ * @returns Transaction instruction
784
+ */
785
+ export function buildSetFeeRecipients(
786
+ params: BuildSetFeeRecipientsParams
787
+ ): Promise<TransactionInstruction> {
788
+ const { admin, feeRecipients, config } = params;
789
+
790
+ if (feeRecipients.length !== 8) {
791
+ throw new Error("feeRecipients must have exactly 8 elements");
792
+ }
793
+
794
+ const program = getCachedLiquidProgram(config);
795
+
796
+ return program.methods
797
+ .setFeeRecipients(feeRecipients)
798
+ .accounts({
799
+ admin,
800
+ feeRecipient1: feeRecipients[0],
801
+ feeRecipient2: feeRecipients[1],
802
+ feeRecipient3: feeRecipients[2],
803
+ feeRecipient4: feeRecipients[3],
804
+ feeRecipient5: feeRecipients[4],
805
+ feeRecipient6: feeRecipients[5],
806
+ feeRecipient7: feeRecipients[6],
807
+ feeRecipient8: feeRecipients[7],
808
+ })
809
+ .instruction();
810
+ }
811
+
812
+ export interface BuildInitializeFeeRecipientVaultsParams {
813
+ payer: PublicKey;
814
+ quoteMint: PublicKey;
815
+ /** Array of 8 fee recipient pubkeys (must match config) */
816
+ feeRecipients: PublicKey[];
817
+ config: LiquidConfig;
818
+ }
819
+
820
+ /**
821
+ * Builds an initializeFeeRecipientVaults instruction.
822
+ * Permissionless instruction to create token accounts for all fee recipients
823
+ * for a given quote mint. Call this before trading stable curves.
824
+ *
825
+ * @param params - {@link BuildInitializeFeeRecipientVaultsParams}
826
+ * @returns Transaction instruction
827
+ */
828
+ export function buildInitializeFeeRecipientVaults(
829
+ params: BuildInitializeFeeRecipientVaultsParams
830
+ ): Promise<TransactionInstruction> {
831
+ const { payer, quoteMint, feeRecipients, config } = params;
832
+
833
+ if (feeRecipients.length !== 8) {
834
+ throw new Error("feeRecipients must have exactly 8 elements");
835
+ }
836
+
837
+ const program = getCachedLiquidProgram(config);
838
+
839
+ return program.methods
840
+ .initializeFeeRecipientVaults()
841
+ .accounts({
842
+ payer,
843
+ quoteMint,
844
+ feeRecipient1: feeRecipients[0],
845
+ feeRecipient2: feeRecipients[1],
846
+ feeRecipient3: feeRecipients[2],
847
+ feeRecipient4: feeRecipients[3],
848
+ feeRecipient5: feeRecipients[4],
849
+ feeRecipient6: feeRecipients[5],
850
+ feeRecipient7: feeRecipients[6],
851
+ feeRecipient8: feeRecipients[7],
852
+ })
853
+ .instruction();
854
+ }
855
+
856
+ export interface BuildInitializeReferralTokenVaultParams {
857
+ user: PublicKey;
858
+ quoteMint: PublicKey;
859
+ config: LiquidConfig;
860
+ }
861
+
862
+ /**
863
+ * Builds an initializeReferralTokenVault instruction.
864
+ * Creates a referral token vault (ATA) for the user for a specific quote mint.
865
+ * Users must call this for each quote mint they want to receive referral rewards for.
866
+ * If not initialized, referral fees will be redirected to protocol fees.
867
+ *
868
+ * @param params - {@link BuildInitializeReferralTokenVaultParams}
869
+ * @returns Transaction instruction
870
+ */
871
+ export function buildInitializeReferralTokenVault(
872
+ params: BuildInitializeReferralTokenVaultParams
873
+ ): Promise<TransactionInstruction> {
874
+ const { user, quoteMint, config } = params;
875
+ const program = getCachedLiquidProgram(config);
876
+
877
+ return program.methods
878
+ .initializeReferralTokenVault()
879
+ .accounts({
880
+ user,
881
+ quoteMint,
882
+ })
883
+ .instruction();
884
+ }