@liquid-af/sdk 0.10.4 → 0.11.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 (50) hide show
  1. package/dist/client.d.ts +2 -5
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +3 -3
  4. package/dist/client.js.map +1 -1
  5. package/dist/idl/liquid.d.ts +2490 -2490
  6. package/dist/idl/liquid.d.ts.map +1 -1
  7. package/dist/idl/liquid.json +2490 -2490
  8. package/dist/idl/liquid_events.d.ts +5 -12
  9. package/dist/idl/liquid_events.d.ts.map +1 -1
  10. package/dist/idl/liquid_events.json +5 -12
  11. package/dist/idl/liquid_fees.d.ts +8 -30
  12. package/dist/idl/liquid_fees.d.ts.map +1 -1
  13. package/dist/idl/liquid_fees.json +8 -30
  14. package/dist/idl/liquid_state.d.ts +72 -72
  15. package/dist/idl/liquid_state.d.ts.map +1 -1
  16. package/dist/idl/liquid_state.json +72 -72
  17. package/dist/idl/liquid_swap.d.ts +998 -998
  18. package/dist/idl/liquid_swap.d.ts.map +1 -1
  19. package/dist/idl/liquid_swap.json +998 -998
  20. package/dist/instructions/liquid-fees.d.ts +3 -6
  21. package/dist/instructions/liquid-fees.d.ts.map +1 -1
  22. package/dist/instructions/liquid-fees.js +6 -11
  23. package/dist/instructions/liquid-fees.js.map +1 -1
  24. package/dist/math/bonding-curve.d.ts.map +1 -1
  25. package/dist/math/bonding-curve.js +6 -4
  26. package/dist/math/bonding-curve.js.map +1 -1
  27. package/dist/math/fees.d.ts +5 -2
  28. package/dist/math/fees.d.ts.map +1 -1
  29. package/dist/math/fees.js +32 -13
  30. package/dist/math/fees.js.map +1 -1
  31. package/dist/pda/liquid-fees.d.ts +3 -3
  32. package/dist/pda/liquid-fees.d.ts.map +1 -1
  33. package/dist/pda/liquid-fees.js +4 -4
  34. package/dist/pda/liquid-fees.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/client.ts +2 -9
  37. package/src/idl/liquid.json +2490 -2490
  38. package/src/idl/liquid.ts +2490 -2490
  39. package/src/idl/liquid_events.json +5 -12
  40. package/src/idl/liquid_events.ts +5 -12
  41. package/src/idl/liquid_fees.json +8 -30
  42. package/src/idl/liquid_fees.ts +8 -30
  43. package/src/idl/liquid_state.json +72 -72
  44. package/src/idl/liquid_state.ts +72 -72
  45. package/src/idl/liquid_swap.json +998 -998
  46. package/src/idl/liquid_swap.ts +998 -998
  47. package/src/instructions/liquid-fees.ts +4 -27
  48. package/src/math/bonding-curve.ts +6 -4
  49. package/src/math/fees.ts +33 -15
  50. package/src/pda/liquid-fees.ts +3 -4
@@ -209,14 +209,13 @@ export function buildDistributeTokenFees(
209
209
 
210
210
  export interface BuildClaimFeesParams {
211
211
  recipient: PublicKey;
212
- tokenMint: PublicKey;
213
- quoteMint: PublicKey;
214
212
  config: LiquidConfig;
215
213
  }
216
214
 
217
215
  /**
218
216
  * Builds a claimFees instruction.
219
217
  * Allows a recipient to claim accumulated SOL fees from their vault PDA.
218
+ * Vaults are shared across all fee configs — one claim drains all SOL fees.
220
219
  *
221
220
  * @param params - {@link BuildClaimFeesParams}
222
221
  * @returns Transaction instruction
@@ -224,26 +223,19 @@ export interface BuildClaimFeesParams {
224
223
  export function buildClaimFees(
225
224
  params: BuildClaimFeesParams,
226
225
  ): Promise<TransactionInstruction> {
227
- const { recipient, tokenMint, quoteMint, config } = params;
226
+ const { recipient, config } = params;
228
227
  const program = getCachedFeesProgram(config);
229
- const [feeConfig] = getFeeConfigPDA(
230
- tokenMint,
231
- quoteMint,
232
- config.liquidFeesProgramId,
233
- );
234
228
 
235
229
  return program.methods
236
230
  .claimFees()
237
231
  .accounts({
238
232
  recipient,
239
- feeConfig,
240
233
  })
241
234
  .instruction();
242
235
  }
243
236
 
244
237
  export interface BuildClaimTokenFeesParams {
245
238
  recipient: PublicKey;
246
- tokenMint: PublicKey;
247
239
  quoteMint: PublicKey;
248
240
  recipientTokenAccount?: PublicKey;
249
241
  config: LiquidConfig;
@@ -252,7 +244,7 @@ export interface BuildClaimTokenFeesParams {
252
244
  /**
253
245
  * Builds a claimTokenFees instruction.
254
246
  * Allows a recipient to claim accumulated token fees from their vault ATA.
255
- * Closes the vault ATA after claiming to reclaim rent.
247
+ * Vaults are shared across all fee configs one claim drains all token fees for the quote mint.
256
248
  *
257
249
  * @param params - {@link BuildClaimTokenFeesParams}
258
250
  * @returns Transaction instruction
@@ -260,14 +252,8 @@ export interface BuildClaimTokenFeesParams {
260
252
  export function buildClaimTokenFees(
261
253
  params: BuildClaimTokenFeesParams,
262
254
  ): Promise<TransactionInstruction> {
263
- const { recipient, tokenMint, quoteMint, recipientTokenAccount, config } =
264
- params;
255
+ const { recipient, quoteMint, recipientTokenAccount, config } = params;
265
256
  const program = getCachedFeesProgram(config);
266
- const [feeConfig] = getFeeConfigPDA(
267
- tokenMint,
268
- quoteMint,
269
- config.liquidFeesProgramId,
270
- );
271
257
 
272
258
  const resolvedRecipientTokenAccount =
273
259
  recipientTokenAccount ??
@@ -277,7 +263,6 @@ export function buildClaimTokenFees(
277
263
  .claimTokenFees()
278
264
  .accounts({
279
265
  recipient,
280
- feeConfig,
281
266
  quoteMint,
282
267
  recipientTokenAccount: resolvedRecipientTokenAccount,
283
268
  })
@@ -313,26 +298,18 @@ export function buildInitializeGlobalConfig(
313
298
  /**
314
299
  * Helper: derives recipient vault PDA pairs for use with buildDistributeTokenFees.
315
300
  *
316
- * @param tokenMint - Token mint address
317
301
  * @param recipients - Array of recipient public keys in fee_config order
318
302
  * @param quoteMint - Quote mint for ATA derivation
319
303
  * @param config - Liquid protocol config
320
304
  * @returns Array of RecipientVaultPair for remaining accounts
321
305
  */
322
306
  export function deriveRecipientVaultPairs(
323
- tokenMint: PublicKey,
324
307
  recipients: PublicKey[],
325
308
  quoteMint: PublicKey,
326
309
  config: LiquidConfig,
327
310
  ): RecipientVaultPair[] {
328
- const [feeConfig] = getFeeConfigPDA(
329
- tokenMint,
330
- quoteMint,
331
- config.liquidFeesProgramId,
332
- );
333
311
  return recipients.map((recipient) => {
334
312
  const [vaultPda] = getRecipientVaultPDA(
335
- feeConfig,
336
313
  recipient,
337
314
  config.liquidFeesProgramId,
338
315
  );
@@ -41,8 +41,9 @@ export const calculateBuyExpectation = (
41
41
  // New quote reserves after adding net amount
42
42
  const newVirtualQuote = curveState.virtualQuoteReserves.add(amountInNet);
43
43
 
44
- // Solve for new token reserves: newToken = k / newQuote + 1 (ceiling division)
45
- const newVirtualToken = k.div(newVirtualQuote).add(new BN(1));
44
+ // Solve for new token reserves: newToken = k / newQuote
45
+ const { div: q1, mod: r1 } = k.divmod(newVirtualQuote);
46
+ const newVirtualToken = r1.isZero() ? q1 : q1.add(new BN(1));
46
47
 
47
48
  // Tokens out = difference in token reserves
48
49
  const tokensOut = curveState.virtualTokenReserves.sub(newVirtualToken);
@@ -90,8 +91,9 @@ export const calculateSellExpectation = (
90
91
  // New token reserves after adding sold tokens
91
92
  const newVirtualToken = curveState.virtualTokenReserves.add(amountInTokens);
92
93
 
93
- // Solve for new quote reserves: newQuote = k / newToken + 1 (ceiling division)
94
- const newVirtualQuote = k.div(newVirtualToken).add(new BN(1));
94
+ // Solve for new quote reserves: newQuote = k / newToken
95
+ const { div: q2, mod: r2 } = k.divmod(newVirtualToken);
96
+ const newVirtualQuote = r2.isZero() ? q2 : q2.add(new BN(1));
95
97
 
96
98
  // Gross quote out (before fees)
97
99
  const quoteOutGross = curveState.virtualQuoteReserves.sub(newVirtualQuote);
package/src/math/fees.ts CHANGED
@@ -9,14 +9,18 @@ import type {
9
9
 
10
10
  /**
11
11
  * Calculates basis points of an amount.
12
- * result = (amount * bps) / 10000
12
+ * result = ceil(amount * bps / 10000)
13
13
  *
14
14
  * @param amount - The amount to calculate basis points of
15
15
  * @param bps - Basis points (1 bps = 0.01%)
16
16
  * @returns The calculated portion
17
17
  */
18
- export const calcBps = (amount: BN, bps: number): BN =>
19
- amount.mul(new BN(bps)).div(new BN(BPS_DENOMINATOR));
18
+ export const calcBps = (amount: BN, bps: number): BN => {
19
+ if (bps === 0) return new BN(0);
20
+ const numerator = amount.mul(new BN(bps));
21
+ const denom = new BN(BPS_DENOMINATOR);
22
+ return numerator.add(denom).sub(new BN(1)).div(denom);
23
+ };
20
24
 
21
25
  /**
22
26
  * Fee configuration for bonding curve trades.
@@ -30,7 +34,10 @@ export interface FeeConfig {
30
34
 
31
35
  /**
32
36
  * Calculates fee distribution for a given trade amount.
33
- * Referral fees are carved from the protocol fee, not the trade amount.
37
+ * Matches the on-chain algorithm in `trade_utils::fees::calculate_fees`:
38
+ * - Single ceiling division for total fees
39
+ * - Proportional floor distribution for creator; protocol gets remainder (dust)
40
+ * - Referral fees use ceiling (carved from protocol fee, not trade amount)
34
41
  *
35
42
  * @param amount - Gross trade amount (before fees)
36
43
  * @param config - Fee configuration in basis points
@@ -44,23 +51,34 @@ export const calculateFees = (
44
51
  hasCreatorRef: boolean,
45
52
  hasTraderRef: boolean,
46
53
  ): FeeDistribution => {
47
- const baseProtocolFee = calcBps(amount, config.protocolFeeBps);
48
- const creatorFee = calcBps(amount, config.creatorFeeBps);
54
+ const totalBps = config.protocolFeeBps + config.creatorFeeBps;
55
+ if (totalBps === 0) {
56
+ return {
57
+ protocolFee: new BN(0),
58
+ creatorFee: new BN(0),
59
+ creatorReferralFee: new BN(0),
60
+ traderReferralFee: new BN(0),
61
+ totalFees: new BN(0),
62
+ };
63
+ }
64
+
65
+ // Single ceiling division for total fees (matches on-chain)
66
+ const totalFees = calcBps(amount, totalBps);
49
67
 
50
- // Referral amounts are BPS of the protocol fee (not trade amount)
68
+ // Proportional floor distribution: creator gets floor, protocol gets remainder
69
+ const creatorFee = totalFees
70
+ .mul(new BN(config.creatorFeeBps))
71
+ .div(new BN(totalBps));
72
+ const protocolFee = totalFees.sub(creatorFee);
73
+
74
+ // Referral amounts are ceiling BPS of the protocol fee (not trade amount)
51
75
  const creatorReferralFee = hasCreatorRef
52
- ? calcBps(baseProtocolFee, config.creatorReferralBps)
76
+ ? calcBps(protocolFee, config.creatorReferralBps)
53
77
  : new BN(0);
54
78
  const traderReferralFee = hasTraderRef
55
- ? calcBps(baseProtocolFee, config.traderReferralBps)
79
+ ? calcBps(protocolFee, config.traderReferralBps)
56
80
  : new BN(0);
57
81
 
58
- // Protocol fee starts at base amount. On-chain, it is only reduced
59
- // when referral transfers actually succeed.
60
- const protocolFee = baseProtocolFee;
61
- // Referrals are carved from protocol fee (not additive), so total = protocol + creator.
62
- const totalFees = protocolFee.add(creatorFee);
63
-
64
82
  return {
65
83
  protocolFee,
66
84
  creatorFee,
@@ -54,20 +54,19 @@ export const getFeeVaultPDA = (
54
54
  };
55
55
 
56
56
  /**
57
- * Derives the recipient vault PDA for a specific recipient within a fee config.
57
+ * Derives the recipient vault PDA for a specific recipient.
58
+ * Vaults are shared across all fee configs — one vault per recipient.
58
59
  *
59
- * @param feeConfig - Fee config PDA address
60
60
  * @param recipient - Recipient wallet address
61
61
  * @param programId - Liquid Fees program ID
62
62
  * @returns Tuple of [PDA address, bump seed]
63
63
  */
64
64
  export const getRecipientVaultPDA = (
65
- feeConfig: PublicKey,
66
65
  recipient: PublicKey,
67
66
  programId: PublicKey,
68
67
  ): [PublicKey, number] => {
69
68
  return PublicKey.findProgramAddressSync(
70
- [SEED_RECIPIENT_VAULT, feeConfig.toBuffer(), recipient.toBuffer()],
69
+ [SEED_RECIPIENT_VAULT, recipient.toBuffer()],
71
70
  programId,
72
71
  );
73
72
  };