@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
package/README.md ADDED
@@ -0,0 +1,776 @@
1
+ # @liquid-af/sdk
2
+
3
+ TypeScript SDK for the Liquid DeFi protocol on Solana — bonding curve token launches and AMM trading.
4
+
5
+ ## Protocol Overview
6
+
7
+ Liquid is a four-program system on Solana:
8
+
9
+ ```
10
+ ┌──────────────────────┐ ┌───────────────────────┐
11
+ │ liquid │ │ liquid-swap │
12
+ │ Bonding curve: │ │ CPMM AMM: │
13
+ │ create, buy, sell, │ │ pools, swaps, │
14
+ │ migrate │ │ deposits, withdraws │
15
+ └────────┬─────────────┘ └────────┬──────────────┘
16
+ │ │
17
+ │ ┌───────────────┐ │
18
+ ├────►│ liquid-fees │◄─────┤
19
+ │ │ Fee config │ │
20
+ │ └───────────────┘ │
21
+ │ ┌───────────────┐ │
22
+ └────►│ liquid-state │◄─────┘
23
+ │ User state │
24
+ └───────────────┘
25
+ ```
26
+
27
+ Tokens launch on a bonding curve. Once the curve fills, liquidity migrates to an AMM pool for open trading.
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ npm install @liquid-af/sdk
33
+ ```
34
+
35
+ Peer dependencies:
36
+
37
+ ```bash
38
+ npm install @coral-xyz/anchor @solana/web3.js @solana/spl-token bn.js
39
+ ```
40
+
41
+ ## Quick Start
42
+
43
+ ```typescript
44
+ import { Connection, Keypair, PublicKey } from "@solana/web3.js";
45
+ import BN from "bn.js";
46
+ import { LiquidClient } from "@liquid-af/sdk";
47
+
48
+ const connection = new Connection("https://api.mainnet-beta.solana.com");
49
+ const client = new LiquidClient({ connection });
50
+
51
+ // Preview a buy on a bonding curve
52
+ const mint = new PublicKey("Token111...");
53
+ const preview = await client.previewBuyOnCurve(mint, new BN(100_000_000)); // 0.1 SOL
54
+ console.log("Tokens out:", preview.tokensOut.toString());
55
+ console.log("Price impact:", preview.priceImpactBps, "bps");
56
+ console.log("Total fees:", preview.fees.totalFees.toString());
57
+
58
+ // Build the buy instruction
59
+ const ix = await client.buildBuyOnCurveAutoResolve({
60
+ user: wallet.publicKey,
61
+ mint,
62
+ amountIn: new BN(100_000_000),
63
+ minAmountOut: preview.tokensOut.muln(95).divn(100), // 5% slippage
64
+ feeRecipient: protocolFeeRecipient,
65
+ });
66
+
67
+ // Build a transaction with priority fee
68
+ const tx = await client.buildTransaction([ix], {
69
+ feePayer: wallet.publicKey,
70
+ computeUnits: 300_000,
71
+ priorityFee: 50_000, // micro-lamports per CU
72
+ });
73
+
74
+ // Sign and send (wallet-dependent)
75
+ tx.sign(wallet);
76
+ const sig = await connection.sendRawTransaction(tx.serialize());
77
+ ```
78
+
79
+ ## Configuration
80
+
81
+ ### Pre-built Configs
82
+
83
+ ```typescript
84
+ import { LiquidClient, MAINNET_CONFIG, DEVNET_CONFIG, LOCALNET_CONFIG } from "@liquid-af/sdk";
85
+
86
+ const client = new LiquidClient({ connection }); // defaults to mainnet
87
+ const testClient = new LiquidClient({ connection, config: DEVNET_CONFIG });
88
+ ```
89
+
90
+ ### Constants
91
+
92
+ | Constant | Value | Description |
93
+ |----------|-------|-------------|
94
+ | `BPS_DENOMINATOR` | 10,000 | 100% in basis points |
95
+ | `WSOL_MINT` | `So11111111...112` | Wrapped SOL mint |
96
+ | `MIN_TRANSACTION_AMOUNT` | 100,000 | Minimum trade in lamports |
97
+ | `MAX_FEE_RECIPIENTS_FEES` | 10 | Max per-token fee recipients |
98
+ | `LIMITS.NAME` | 1–32 chars | Token name length |
99
+ | `LIMITS.SYMBOL` | 1–16 chars | Token symbol length |
100
+ | `LIMITS.URI` | 10–100 chars | Token URI length |
101
+
102
+ ## Bonding Curve
103
+
104
+ ### Create a Token
105
+
106
+ ```typescript
107
+ const mint = Keypair.generate();
108
+
109
+ const ix = await client.buildCreateCurve({
110
+ creator: wallet.publicKey,
111
+ mint: mint.publicKey,
112
+ name: "My Token",
113
+ symbol: "MTK",
114
+ uri: "https://example.com/metadata.json",
115
+ });
116
+ ```
117
+
118
+ ### Buy Tokens
119
+
120
+ ```typescript
121
+ // Standard — you provide the creator address
122
+ const ix = await client.buildBuyOnCurve({
123
+ user: wallet.publicKey,
124
+ mint,
125
+ creator: creatorPubkey,
126
+ amountIn: new BN(500_000_000), // 0.5 SOL
127
+ minAmountOut: new BN(1_000_000), // slippage protection
128
+ feeRecipient: protocolFeeRecipient,
129
+ });
130
+
131
+ // Auto-resolve — fetches creator from on-chain state
132
+ const ix = await client.buildBuyOnCurveAutoResolve({
133
+ user: wallet.publicKey,
134
+ mint,
135
+ amountIn: new BN(500_000_000),
136
+ minAmountOut: new BN(1_000_000),
137
+ feeRecipient: protocolFeeRecipient,
138
+ });
139
+ ```
140
+
141
+ With referral vaults:
142
+
143
+ ```typescript
144
+ const ix = await client.buildBuyOnCurveAutoResolve({
145
+ user: wallet.publicKey,
146
+ mint,
147
+ amountIn: new BN(500_000_000),
148
+ minAmountOut: new BN(1_000_000),
149
+ feeRecipient: protocolFeeRecipient,
150
+ creatorReferralVault: creatorRefVault, // creator's referrer earns rewards
151
+ traderReferralVault: traderRefVault, // buyer's referrer earns rewards
152
+ });
153
+ ```
154
+
155
+ ### Sell Tokens
156
+
157
+ ```typescript
158
+ const ix = await client.buildSellOnCurveAutoResolve({
159
+ user: wallet.publicKey,
160
+ mint,
161
+ amountIn: new BN(5_000_000), // tokens to sell
162
+ minAmountOut: new BN(100_000_000), // minimum SOL back
163
+ feeRecipient: protocolFeeRecipient,
164
+ });
165
+ ```
166
+
167
+ ### Migrate to AMM
168
+
169
+ When a bonding curve completes (all real tokens sold), anyone can trigger migration:
170
+
171
+ ```typescript
172
+ const ix = await client.buildMigrateNative({
173
+ migrator: wallet.publicKey,
174
+ mint,
175
+ });
176
+ ```
177
+
178
+ ### Withdraw Referral Rewards
179
+
180
+ ```typescript
181
+ const ix = await client.buildWithdrawReferralRewards({ user: wallet.publicKey });
182
+ ```
183
+
184
+ ### Buyback (Permissionless)
185
+
186
+ When a token's fee config is revoked, accumulated fees are used for buyback-and-burn:
187
+
188
+ ```typescript
189
+ const ix = await client.buildExecuteBuyback({
190
+ payer: wallet.publicKey,
191
+ mint,
192
+ });
193
+ ```
194
+
195
+ ## AMM (Liquidity Pools)
196
+
197
+ All AMM methods auto-resolve token programs (SPL Token vs Token-2022) and default `quoteMint` to WSOL.
198
+
199
+ ### Swap — Sell (Fixed Input)
200
+
201
+ Sell a fixed amount of base tokens for quote tokens:
202
+
203
+ ```typescript
204
+ const ix = await client.buildSwapSell({
205
+ payer: wallet.publicKey,
206
+ creator: creatorPubkey,
207
+ baseMint: tokenMint,
208
+ amountIn: new BN(10_000_000), // base tokens to sell
209
+ minimumAmountOut: new BN(50_000_000), // min SOL received
210
+ feeRecipient: protocolFeeRecipient,
211
+ });
212
+ ```
213
+
214
+ ### Swap — Buy (Fixed Output)
215
+
216
+ Buy a fixed amount of base tokens, paying up to a maximum in quote tokens:
217
+
218
+ ```typescript
219
+ const ix = await client.buildSwapBuy({
220
+ payer: wallet.publicKey,
221
+ creator: creatorPubkey,
222
+ baseMint: tokenMint,
223
+ maxAmountIn: new BN(500_000_000), // max SOL to spend
224
+ amountOut: new BN(10_000_000), // exact base tokens to receive
225
+ feeRecipient: protocolFeeRecipient,
226
+ });
227
+ ```
228
+
229
+ ### Deposit Liquidity
230
+
231
+ ```typescript
232
+ const ix = await client.buildDeposit({
233
+ owner: wallet.publicKey,
234
+ baseMint: tokenMint,
235
+ lpTokenAmount: new BN(1_000_000),
236
+ maximumBaseAmount: new BN(10_000_000),
237
+ maximumQuoteAmount: new BN(500_000_000),
238
+ });
239
+ ```
240
+
241
+ ### Withdraw Liquidity
242
+
243
+ ```typescript
244
+ const ix = await client.buildWithdraw({
245
+ owner: wallet.publicKey,
246
+ baseMint: tokenMint,
247
+ lpTokenAmount: new BN(1_000_000),
248
+ minimumBaseAmount: new BN(9_000_000),
249
+ minimumQuoteAmount: new BN(450_000_000),
250
+ });
251
+ ```
252
+
253
+ ### Create Pool
254
+
255
+ ```typescript
256
+ const ix = await client.buildCreatePool({
257
+ signer: wallet.publicKey,
258
+ baseMint: tokenMint,
259
+ initAmountBase: new BN(100_000_000),
260
+ initAmountQuote: new BN(5_000_000_000),
261
+ creator: creatorPubkey,
262
+ });
263
+ ```
264
+
265
+ ### AMM Buyback
266
+
267
+ ```typescript
268
+ const ix = await client.buildSwapExecuteBuyback({
269
+ payer: wallet.publicKey,
270
+ baseMint: tokenMint,
271
+ });
272
+ ```
273
+
274
+ ## Trade Previews
275
+
276
+ ### Async Previews (Auto-Fetch)
277
+
278
+ These fetch on-chain state automatically:
279
+
280
+ ```typescript
281
+ // Bonding curve — buy preview
282
+ const buyPreview = await client.previewBuyOnCurve(mint, new BN(100_000_000));
283
+ console.log(buyPreview.tokensOut.toString()); // tokens you'd receive
284
+ console.log(buyPreview.fees.totalFees.toString()); // total fees
285
+ console.log(buyPreview.priceImpactBps); // price impact in basis points
286
+ console.log(buyPreview.willComplete); // would this buy complete the curve?
287
+
288
+ // Bonding curve — sell preview
289
+ const sellPreview = await client.previewSellOnCurve(mint, new BN(5_000_000));
290
+ console.log(sellPreview.solOutNet.toString()); // SOL after fees
291
+
292
+ // AMM — sell preview (base → quote)
293
+ const ammSell = await client.previewSwapSell(baseMint, WSOL_MINT, new BN(10_000_000));
294
+ console.log(ammSell.amountOutNet.toString()); // quote tokens after fees
295
+
296
+ // AMM — buy preview (quote → base)
297
+ const ammBuy = await client.previewSwapBuy(baseMint, WSOL_MINT, new BN(10_000_000));
298
+ console.log(ammBuy.amountOutNet.toString()); // quote tokens needed
299
+ ```
300
+
301
+ ### Pure Math Previews (No Network)
302
+
303
+ Use these when you already have the on-chain state (avoids redundant RPC calls):
304
+
305
+ ```typescript
306
+ import { calculateBuyCurvePreview, calculateSwapSellPreview } from "@liquid-af/sdk";
307
+
308
+ // Bonding curve — you supply the state
309
+ const preview = calculateBuyCurvePreview(new BN(100_000_000), {
310
+ globalConfig: {
311
+ protocolFeeBasisPoints: 100,
312
+ creatorFeeBasisPoints: 50,
313
+ creatorReferralRewardBasisPoints: 500,
314
+ traderReferralRewardBasisPoints: 500,
315
+ },
316
+ bondingCurve: {
317
+ virtualSolReserves: new BN(30_000_000_000),
318
+ virtualTokenReserves: new BN(1_000_000_000_000),
319
+ realTokenReserves: new BN(800_000_000_000),
320
+ },
321
+ });
322
+
323
+ // AMM — you supply vault balances
324
+ const ammPreview = calculateSwapSellPreview(new BN(10_000_000), {
325
+ ammConfig: { lpFeeRate: 20, creatorFeeRate: 95, protocolFeeRate: 5 },
326
+ baseVaultBalance: new BN(500_000_000),
327
+ quoteVaultBalance: new BN(2_000_000_000),
328
+ });
329
+ ```
330
+
331
+ ### Prefetching Pattern
332
+
333
+ Batch your RPC calls and pass prefetched state to avoid extra requests:
334
+
335
+ ```typescript
336
+ // Fetch once, preview multiple amounts
337
+ const [globalConfig, bondingCurve] = await Promise.all([
338
+ client.fetchLiquidGlobalConfig(),
339
+ client.fetchNativeBondingCurve(mint),
340
+ ]);
341
+
342
+ const preview1 = await client.previewBuyOnCurve(mint, new BN(100_000_000), {
343
+ prefetched: { globalConfig, bondingCurve },
344
+ });
345
+ const preview2 = await client.previewBuyOnCurve(mint, new BN(500_000_000), {
346
+ prefetched: { globalConfig, bondingCurve },
347
+ });
348
+ ```
349
+
350
+ ## Fee Configuration
351
+
352
+ Tokens can have one of three fee modes:
353
+
354
+ | Mode | Behavior |
355
+ |------|----------|
356
+ | `Recipients` | Fees split among up to 10 recipients by BPS allocation |
357
+ | `Revoked` | Fee config is permanently locked; fees route to buyback |
358
+
359
+ ### Update
360
+
361
+ ```typescript
362
+ const ix = await client.buildUpdateFeeConfig({
363
+ authority: wallet.publicKey,
364
+ tokenMint: mint,
365
+ recipients: [{ pubkey: newRecipient, basisPoints: 10_000 }],
366
+ newUpdateAuthority: null, // keep existing
367
+ });
368
+ ```
369
+
370
+ ### Revoke (Permanent)
371
+
372
+ ```typescript
373
+ const ix = await client.buildRevokeFeeConfig({
374
+ authority: wallet.publicKey,
375
+ tokenMint: mint,
376
+ });
377
+ ```
378
+
379
+ ### Distribute Fees (Permissionless)
380
+
381
+ ```typescript
382
+ const ix = await client.buildDistributeFees({
383
+ payer: wallet.publicKey,
384
+ tokenMint: mint,
385
+ recipientVaults: [vault1, vault2],
386
+ });
387
+ ```
388
+
389
+ ### Fee Helpers
390
+
391
+ ```typescript
392
+ import {
393
+ createRecipients,
394
+ createEqualRecipients,
395
+ createSingleRecipient,
396
+ validateRecipientsSum,
397
+ calculateDistribution,
398
+ } from "@liquid-af/sdk";
399
+
400
+ // Custom split
401
+ const recipients = createRecipients([pk1, pk2, pk3], [5000, 3000, 2000]);
402
+
403
+ // Equal split across 4 recipients
404
+ const equal = createEqualRecipients(4, [pk1, pk2, pk3, pk4]);
405
+
406
+ // Single recipient (100%)
407
+ const solo = createSingleRecipient(pk1);
408
+
409
+ // Validate sum equals 10,000 BPS
410
+ validateRecipientsSum(recipients); // true
411
+
412
+ // Calculate expected distribution from a vault balance
413
+ const amounts = calculateDistribution(10_000_000, recipients);
414
+ // [{ pubkey: pk1, amount: 4554560 }, { pubkey: pk2, amount: 2733336 }, ...]
415
+ ```
416
+
417
+ ## User State & Referrals
418
+
419
+ ### Initialize User
420
+
421
+ ```typescript
422
+ const ix = await client.buildInitializeUser({ user: wallet.publicKey });
423
+ ```
424
+
425
+ ### Set Referrer (One-Time)
426
+
427
+ ```typescript
428
+ const ix = await client.buildSetReferrer({
429
+ user: wallet.publicKey,
430
+ referrer: referrerPubkey,
431
+ });
432
+ ```
433
+
434
+ ### Activate Cashback Spending
435
+
436
+ ```typescript
437
+ const ix = await client.buildSetCashbackMode({ user: wallet.publicKey });
438
+ ```
439
+
440
+ ### Fetch User Data
441
+
442
+ ```typescript
443
+ const props = await client.fetchUserProperties(wallet.publicKey);
444
+ console.log("Total SOL volume:", props.totalSolVolume.toString());
445
+ console.log("Cashback credits:", props.cashbackCredits.toString());
446
+ console.log("Referrer:", props.referrer?.toString() ?? "none");
447
+ console.log("Spending active:", props.isSpending);
448
+
449
+ const volume = await client.fetchTokenVolume(mint);
450
+ console.log("Token SOL volume:", volume.totalSolVolume.toString());
451
+ ```
452
+
453
+ ## Account Fetching
454
+
455
+ All fetchers return deserialized, typed account data.
456
+
457
+ | Method | Returns | Description |
458
+ |--------|---------|-------------|
459
+ | `fetchLiquidGlobalConfig()` | `GlobalConfiguration` | Bonding curve protocol config |
460
+ | `fetchNativeBondingCurve(mint)` | `BondingCurveState` | Curve state for a token |
461
+ | `fetchNativeBondingCurveByAddress(addr)` | `BondingCurveState` | Curve state by PDA address |
462
+ | `fetchAmmConfig()` | `AmmConfig` | AMM protocol config |
463
+ | `fetchPoolState(baseMint, quoteMint?)` | `PoolState` | Pool state by mints |
464
+ | `fetchPoolStateByAddress(addr)` | `PoolState` | Pool state by PDA address |
465
+ | `fetchObservationState(poolAddr)` | `ObservationState` | Oracle observation data |
466
+ | `fetchFeeConfig(tokenMint)` | `UnifiedFeeConfiguration` | Fee config for a token |
467
+ | `fetchFeeConfigByAddress(addr)` | `UnifiedFeeConfiguration` | Fee config by PDA address |
468
+ | `fetchUserProperties(user)` | `UserProperties` | User volumes and referral data |
469
+ | `fetchTokenVolume(mint)` | `TokenVolumeAccumulator` | Per-token volume stats |
470
+ | `fetchGlobalCurveVolume()` | `GlobalCurveVolume` | Total bonding curve volumes |
471
+ | `fetchGlobalAmmVolume()` | `GlobalAmmVolume` | Total AMM volumes |
472
+ | `fetchCashbackConfig()` | `CashbackConfiguration` | Cashback tier config |
473
+
474
+ ```typescript
475
+ const curve = await client.fetchNativeBondingCurve(mint);
476
+ console.log("Creator:", curve.creator.toString());
477
+ console.log("Real SOL reserves:", curve.realSolReserves.toString());
478
+ console.log("Complete:", curve.complete);
479
+ console.log("Migrated:", curve.migrated);
480
+ ```
481
+
482
+ ## PDA Derivation
483
+
484
+ ### Individual PDAs
485
+
486
+ Each returns `[PublicKey, number]` (address + bump):
487
+
488
+ ```typescript
489
+ const [bondingCurve, bump] = client.getBondingCurvePDA(mint);
490
+ const [solVault] = client.getBondingCurveSolVaultPDA(bondingCurve);
491
+ const [referralVault] = client.getReferralVaultPDA(referrer);
492
+ const [buybackVault] = client.getBuybackVaultPDA(bondingCurve);
493
+ const [pool] = client.getPoolPDA(baseMint, quoteMint);
494
+ const [lpMint] = client.getPoolLpMintPDA(pool);
495
+ const [vault] = client.getPoolVaultPDA(pool, mint);
496
+ const [observation] = client.getObservationPDA(pool);
497
+ const [feeConfig] = client.getFeeConfigPDA(tokenMint);
498
+ const [feeVault] = client.getFeeVaultPDA(feeConfig);
499
+ const [userProps] = client.getUserPropertiesPDA(user);
500
+ const [tokenVolume] = client.getTokenVolumePDA(mint);
501
+ ```
502
+
503
+ ### Batch PDAs
504
+
505
+ ```typescript
506
+ // All PDAs for a bonding curve token
507
+ const curvePdas = client.getAllBondingCurvePDAs(mint, creator);
508
+ // { bondingCurve, bondingCurveSolVault, referralVault,
509
+ // buybackVault, feeConfig, feeVault, userProperties, tokenVolume }
510
+
511
+ // All PDAs for an AMM pool
512
+ const poolPdas = client.getAllPoolPDAs(baseMint);
513
+ // { poolState, lpMint, baseVault, quoteVault, observation,
514
+ // ammConfig, ammAuthority, feeConfig, tokenVolume }
515
+
516
+ // All PDAs needed for migration
517
+ const migrationPdas = client.getMigrationPDAs(tokenMint);
518
+ // { bondingCurve, ammPoolState, ammLpMint, ammBaseVault,
519
+ // ammQuoteVault, ammObservation, ammConfig, ammAuthority }
520
+ ```
521
+
522
+ ## Math Utilities
523
+
524
+ Pure functions with no side effects or network calls.
525
+
526
+ ### Bonding Curve Math
527
+
528
+ ```typescript
529
+ import { calculateBuyExpectation, calculateSellExpectation } from "@liquid-af/sdk";
530
+
531
+ const buyResult = calculateBuyExpectation(
532
+ new BN(100_000_000), // SOL in
533
+ { virtualSolReserves, virtualTokenReserves, realTokenReserves },
534
+ { protocolFeeBps: 100, creatorFeeBps: 50, creatorReferralBps: 500, traderReferralBps: 500 },
535
+ false, // hasCreatorRef
536
+ false, // hasTraderRef
537
+ );
538
+ // { tokensOut, protocolFee, creatorFee, ..., newVirtualSol, newVirtualToken }
539
+ ```
540
+
541
+ ### AMM Math
542
+
543
+ ```typescript
544
+ import { calculateAmmSellOutput, calculateAmmBuyInput, calculateLpToTokens } from "@liquid-af/sdk";
545
+
546
+ const sell = calculateAmmSellOutput(
547
+ new BN(10_000_000), // base tokens in
548
+ baseVaultBalance,
549
+ quoteVaultBalance,
550
+ { lpFeeRate: 20, creatorFeeRate: 95, protocolFeeRate: 5 },
551
+ );
552
+ // { quoteOut, quoteOutNet, lpFee, creatorFee, protocolFee, totalFees }
553
+
554
+ const buy = calculateAmmBuyInput(
555
+ new BN(10_000_000), // base tokens desired
556
+ baseVaultBalance,
557
+ quoteVaultBalance,
558
+ { lpFeeRate: 20, creatorFeeRate: 10, protocolFeeRate: 15 },
559
+ );
560
+ // { quoteIn, quoteInGross, lpFee, creatorFee, protocolFee, totalFees }
561
+
562
+ const { baseAmount, quoteAmount } = calculateLpToTokens(
563
+ lpTokens, totalLpSupply, baseVaultBalance, quoteVaultBalance,
564
+ );
565
+ ```
566
+
567
+ ### Fee Math
568
+
569
+ ```typescript
570
+ import { calculateFees, calcBps } from "@liquid-af/sdk";
571
+
572
+ const fees = calculateFees(
573
+ new BN(1_000_000_000),
574
+ { protocolFeeBps: 100, creatorFeeBps: 50, creatorReferralBps: 500, traderReferralBps: 500 },
575
+ true, // hasCreatorRef
576
+ false, // hasTraderRef
577
+ );
578
+ // { protocolFee, creatorFee, creatorReferralFee, traderReferralFee, totalFees }
579
+
580
+ const amount = calcBps(new BN(1_000_000), 250); // 2.5% of 1M
581
+ ```
582
+
583
+ ## Events
584
+
585
+ ### Parse Transaction Logs
586
+
587
+ ```typescript
588
+ import { parseTransactionEvents, getLiquidProgram } from "@liquid-af/sdk";
589
+
590
+ const program = getLiquidProgram(provider);
591
+ const txDetails = await connection.getTransaction(signature, { commitment: "confirmed" });
592
+ const events = parseTransactionEvents(txDetails.meta.logMessages, program);
593
+
594
+ for (const event of events) {
595
+ if (event.name === "TradeEvent") {
596
+ const data = event.data as TradeEvent;
597
+ console.log("Trade on", data.mint.toString());
598
+ }
599
+ }
600
+ ```
601
+
602
+ ### Listen for Events
603
+
604
+ ```typescript
605
+ import { addEventListener, getLiquidSwapProgram } from "@liquid-af/sdk";
606
+
607
+ const program = getLiquidSwapProgram(provider);
608
+ const listenerId = addEventListener<SwapEvent>(program, "SwapEvent", (event) => {
609
+ console.log("Swap:", event.inputAmount.toString(), "→", event.outputAmount.toString());
610
+ });
611
+
612
+ // Later: cleanup
613
+ await program.removeEventListener(listenerId);
614
+ ```
615
+
616
+ ### Wait for a Specific Event
617
+
618
+ ```typescript
619
+ import { waitForEvent } from "@liquid-af/sdk";
620
+
621
+ const { result: signature, event } = await waitForEvent<TradeEvent>(
622
+ program,
623
+ "TradeEvent",
624
+ () => sendAndConfirm(connection, () => program.methods.buyNative(...).rpc()),
625
+ 5000, // timeout ms
626
+ );
627
+ ```
628
+
629
+ ### Event Types
630
+
631
+ | Event | Emitted by | When |
632
+ |-------|-----------|------|
633
+ | `TokenCreatedEvent` | liquid | Token + bonding curve created |
634
+ | `TradeEvent` | liquid | Buy or sell on bonding curve |
635
+ | `MigrationCompletedEvent` | liquid | Curve migrated to AMM |
636
+ | `SwapEvent` | liquid-swap | AMM swap executed |
637
+ | `LpChangeEvent` | liquid-swap | Deposit or withdrawal |
638
+
639
+ ## Transaction Building
640
+
641
+ ### Build Unsigned Transaction
642
+
643
+ ```typescript
644
+ const ix1 = await client.buildBuyOnCurveAutoResolve({ ... });
645
+ const ix2 = await client.buildSetCashbackMode({ user: wallet.publicKey });
646
+
647
+ const tx = await client.buildTransaction([ix1, ix2], {
648
+ feePayer: wallet.publicKey,
649
+ computeUnits: 400_000,
650
+ priorityFee: 100_000, // micro-lamports per CU
651
+ });
652
+ // tx is unsigned — sign with your wallet before sending
653
+ ```
654
+
655
+ ### Compute Budget Helper
656
+
657
+ ```typescript
658
+ import { withComputeBudget } from "@liquid-af/sdk";
659
+
660
+ const instructions = [ix1, ix2];
661
+ const withBudget = withComputeBudget(instructions, {
662
+ computeUnits: 400_000,
663
+ priorityFee: 100_000,
664
+ });
665
+ // Returns [SetComputeUnitLimit, SetComputeUnitPrice, ix1, ix2]
666
+ ```
667
+
668
+ ### Send & Confirm
669
+
670
+ ```typescript
671
+ import { sendAndConfirm, confirmTx } from "@liquid-af/sdk";
672
+
673
+ // Handles timeout recovery automatically
674
+ const sig = await sendAndConfirm(connection, () => program.methods.buyNative(...).rpc());
675
+
676
+ // Or confirm a known signature
677
+ await confirmTx(connection, signature, blockhash, lastValidBlockHeight);
678
+ ```
679
+
680
+ ### Resolve Token Program
681
+
682
+ ```typescript
683
+ // Detects whether a mint uses SPL Token or Token-2022
684
+ const tokenProgram = await client.resolveTokenProgram(mint);
685
+ ```
686
+
687
+ ## Error Handling
688
+
689
+ ```typescript
690
+ import { LiquidError, LiquidErrorCode } from "@liquid-af/sdk";
691
+
692
+ try {
693
+ const curve = await client.fetchNativeBondingCurve(mint);
694
+ } catch (err) {
695
+ const liquidErr = LiquidError.fromAnchorError(err);
696
+ switch (liquidErr.code) {
697
+ case LiquidErrorCode.AccountNotFound:
698
+ console.log("Bonding curve doesn't exist for this mint");
699
+ break;
700
+ case LiquidErrorCode.TransactionTimeout:
701
+ console.log("Transaction timed out — may still land");
702
+ break;
703
+ case LiquidErrorCode.SimulationFailed:
704
+ console.log("Simulation failed:", liquidErr.message);
705
+ break;
706
+ default:
707
+ throw liquidErr;
708
+ }
709
+ }
710
+ ```
711
+
712
+ Error codes: `WalletNotConnected`, `InvalidConfig`, `AccountNotFound`, `AccountDeserializationFailed`, `TransactionBuildFailed`, `TransactionTimeout`, `SimulationFailed`.
713
+
714
+ ## Subpath Imports
715
+
716
+ For tree-shaking or minimal bundles, import only what you need:
717
+
718
+ ```typescript
719
+ import { LiquidClient } from "@liquid-af/sdk/client";
720
+ import { getBondingCurvePDA, getPoolPDA } from "@liquid-af/sdk/pda";
721
+ import { calculateBuyExpectation } from "@liquid-af/sdk/math";
722
+ import { fetchNativeBondingCurve } from "@liquid-af/sdk/accounts";
723
+ import { buildBuyNative } from "@liquid-af/sdk/instructions";
724
+ import { previewBuyOnCurve } from "@liquid-af/sdk/helpers";
725
+ import { parseTransactionEvents } from "@liquid-af/sdk/events";
726
+ import { buildTransaction } from "@liquid-af/sdk/transaction";
727
+ import { createReadonlyProvider } from "@liquid-af/sdk/provider";
728
+ import { LiquidError } from "@liquid-af/sdk/errors";
729
+ ```
730
+
731
+ | Subpath | Contents |
732
+ |---------|----------|
733
+ | `@liquid-af/sdk` | Everything (default) |
734
+ | `@liquid-af/sdk/client` | `LiquidClient` class |
735
+ | `@liquid-af/sdk/pda` | PDA derivation functions |
736
+ | `@liquid-af/sdk/math` | Pure calculation functions |
737
+ | `@liquid-af/sdk/accounts` | Account fetchers |
738
+ | `@liquid-af/sdk/instructions` | Instruction builders |
739
+ | `@liquid-af/sdk/helpers` | Preview functions and user helpers |
740
+ | `@liquid-af/sdk/events` | Event parsing and listeners |
741
+ | `@liquid-af/sdk/transaction` | Transaction building and sending |
742
+ | `@liquid-af/sdk/provider` | Anchor provider utilities |
743
+ | `@liquid-af/sdk/errors` | Error types |
744
+
745
+ ## Standalone Functions
746
+
747
+ Every method on `LiquidClient` delegates to a standalone function exported from its respective subpath. The client adds convenience (stores `connection` and `config`), but you can use the functions directly:
748
+
749
+ ```typescript
750
+ import { buildBuyNative } from "@liquid-af/sdk/instructions";
751
+ import { fetchNativeBondingCurve } from "@liquid-af/sdk/accounts";
752
+ import { getBondingCurvePDA } from "@liquid-af/sdk/pda";
753
+ import { MAINNET_CONFIG } from "@liquid-af/sdk";
754
+
755
+ // Standalone usage — pass config and connection explicitly
756
+ const curve = await fetchNativeBondingCurve(connection, mint, MAINNET_CONFIG);
757
+ const [pda] = getBondingCurvePDA(mint, MAINNET_CONFIG.liquidProgramId);
758
+ const ix = await buildBuyNative({ ..., config: MAINNET_CONFIG });
759
+ ```
760
+
761
+ ## IDL & Program Instances
762
+
763
+ For advanced use cases that need direct Anchor program access:
764
+
765
+ ```typescript
766
+ import {
767
+ getLiquidProgram,
768
+ getLiquidSwapProgram,
769
+ getLiquidFeesProgram,
770
+ getLiquidStateProgram,
771
+ liquidIdl,
772
+ } from "@liquid-af/sdk";
773
+
774
+ const program = getLiquidProgram(provider); // Program<Liquid>
775
+ const swapProgram = getLiquidSwapProgram(provider); // Program<LiquidSwap>
776
+ ```