@liquid-af/sdk 0.10.5 → 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.
- package/dist/client.d.ts +2 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +3 -3
- package/dist/client.js.map +1 -1
- package/dist/idl/liquid_events.d.ts +4 -11
- package/dist/idl/liquid_events.d.ts.map +1 -1
- package/dist/idl/liquid_events.json +4 -11
- package/dist/idl/liquid_fees.d.ts +0 -22
- package/dist/idl/liquid_fees.d.ts.map +1 -1
- package/dist/idl/liquid_fees.json +0 -22
- package/dist/instructions/liquid-fees.d.ts +3 -6
- package/dist/instructions/liquid-fees.d.ts.map +1 -1
- package/dist/instructions/liquid-fees.js +6 -11
- package/dist/instructions/liquid-fees.js.map +1 -1
- package/dist/math/bonding-curve.d.ts.map +1 -1
- package/dist/math/bonding-curve.js +6 -4
- package/dist/math/bonding-curve.js.map +1 -1
- package/dist/math/fees.d.ts +5 -2
- package/dist/math/fees.d.ts.map +1 -1
- package/dist/math/fees.js +32 -13
- package/dist/math/fees.js.map +1 -1
- package/dist/pda/liquid-fees.d.ts +3 -3
- package/dist/pda/liquid-fees.d.ts.map +1 -1
- package/dist/pda/liquid-fees.js +4 -4
- package/dist/pda/liquid-fees.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +2 -9
- package/src/idl/liquid_events.json +4 -11
- package/src/idl/liquid_events.ts +4 -11
- package/src/idl/liquid_fees.json +0 -22
- package/src/idl/liquid_fees.ts +0 -22
- package/src/instructions/liquid-fees.ts +4 -27
- package/src/math/bonding-curve.ts +6 -4
- package/src/math/fees.ts +33 -15
- package/src/pda/liquid-fees.ts +3 -4
package/src/idl/liquid_events.ts
CHANGED
|
@@ -1746,13 +1746,6 @@ export type LiquidEvents = {
|
|
|
1746
1746
|
"type": {
|
|
1747
1747
|
"kind": "struct",
|
|
1748
1748
|
"fields": [
|
|
1749
|
-
{
|
|
1750
|
-
"name": "feeConfig",
|
|
1751
|
-
"docs": [
|
|
1752
|
-
"The fee configuration PDA."
|
|
1753
|
-
],
|
|
1754
|
-
"type": "pubkey"
|
|
1755
|
-
},
|
|
1756
1749
|
{
|
|
1757
1750
|
"name": "mint",
|
|
1758
1751
|
"docs": [
|
|
@@ -2401,9 +2394,9 @@ export type LiquidEvents = {
|
|
|
2401
2394
|
{
|
|
2402
2395
|
"name": "cashback",
|
|
2403
2396
|
"docs": [
|
|
2404
|
-
"Cashback
|
|
2397
|
+
"Cashback earned (positive) or spent (negative) by the user."
|
|
2405
2398
|
],
|
|
2406
|
-
"type": "
|
|
2399
|
+
"type": "i64"
|
|
2407
2400
|
},
|
|
2408
2401
|
{
|
|
2409
2402
|
"name": "cashbackBps",
|
|
@@ -2694,9 +2687,9 @@ export type LiquidEvents = {
|
|
|
2694
2687
|
{
|
|
2695
2688
|
"name": "cashback",
|
|
2696
2689
|
"docs": [
|
|
2697
|
-
"Cashback
|
|
2690
|
+
"Cashback earned (positive) or spent (negative) by the user."
|
|
2698
2691
|
],
|
|
2699
|
-
"type": "
|
|
2692
|
+
"type": "i64"
|
|
2700
2693
|
},
|
|
2701
2694
|
{
|
|
2702
2695
|
"name": "cashbackBps",
|
package/src/idl/liquid_fees.json
CHANGED
|
@@ -115,10 +115,6 @@
|
|
|
115
115
|
116
|
|
116
116
|
]
|
|
117
117
|
},
|
|
118
|
-
{
|
|
119
|
-
"kind": "account",
|
|
120
|
-
"path": "fee_config"
|
|
121
|
-
},
|
|
122
118
|
{
|
|
123
119
|
"kind": "account",
|
|
124
120
|
"path": "recipient"
|
|
@@ -126,13 +122,6 @@
|
|
|
126
122
|
]
|
|
127
123
|
}
|
|
128
124
|
},
|
|
129
|
-
{
|
|
130
|
-
"name": "fee_config",
|
|
131
|
-
"docs": [
|
|
132
|
-
"The fee configuration this vault belongs to.",
|
|
133
|
-
"only the correct fee_config will produce a vault PDA that has funds."
|
|
134
|
-
]
|
|
135
|
-
},
|
|
136
125
|
{
|
|
137
126
|
"name": "system_program",
|
|
138
127
|
"address": "11111111111111111111111111111111"
|
|
@@ -299,13 +288,6 @@
|
|
|
299
288
|
],
|
|
300
289
|
"writable": true
|
|
301
290
|
},
|
|
302
|
-
{
|
|
303
|
-
"name": "fee_config",
|
|
304
|
-
"docs": [
|
|
305
|
-
"The fee configuration this vault belongs to.",
|
|
306
|
-
"only the correct fee_config will produce a vault PDA that has funds."
|
|
307
|
-
]
|
|
308
|
-
},
|
|
309
291
|
{
|
|
310
292
|
"name": "quote_mint",
|
|
311
293
|
"docs": [
|
|
@@ -339,10 +321,6 @@
|
|
|
339
321
|
116
|
|
340
322
|
]
|
|
341
323
|
},
|
|
342
|
-
{
|
|
343
|
-
"kind": "account",
|
|
344
|
-
"path": "fee_config"
|
|
345
|
-
},
|
|
346
324
|
{
|
|
347
325
|
"kind": "account",
|
|
348
326
|
"path": "recipient"
|
package/src/idl/liquid_fees.ts
CHANGED
|
@@ -121,10 +121,6 @@ export type LiquidFees = {
|
|
|
121
121
|
116
|
|
122
122
|
]
|
|
123
123
|
},
|
|
124
|
-
{
|
|
125
|
-
"kind": "account",
|
|
126
|
-
"path": "feeConfig"
|
|
127
|
-
},
|
|
128
124
|
{
|
|
129
125
|
"kind": "account",
|
|
130
126
|
"path": "recipient"
|
|
@@ -132,13 +128,6 @@ export type LiquidFees = {
|
|
|
132
128
|
]
|
|
133
129
|
}
|
|
134
130
|
},
|
|
135
|
-
{
|
|
136
|
-
"name": "feeConfig",
|
|
137
|
-
"docs": [
|
|
138
|
-
"The fee configuration this vault belongs to.",
|
|
139
|
-
"only the correct fee_config will produce a vault PDA that has funds."
|
|
140
|
-
]
|
|
141
|
-
},
|
|
142
131
|
{
|
|
143
132
|
"name": "systemProgram",
|
|
144
133
|
"address": "11111111111111111111111111111111"
|
|
@@ -305,13 +294,6 @@ export type LiquidFees = {
|
|
|
305
294
|
],
|
|
306
295
|
"writable": true
|
|
307
296
|
},
|
|
308
|
-
{
|
|
309
|
-
"name": "feeConfig",
|
|
310
|
-
"docs": [
|
|
311
|
-
"The fee configuration this vault belongs to.",
|
|
312
|
-
"only the correct fee_config will produce a vault PDA that has funds."
|
|
313
|
-
]
|
|
314
|
-
},
|
|
315
297
|
{
|
|
316
298
|
"name": "quoteMint",
|
|
317
299
|
"docs": [
|
|
@@ -345,10 +327,6 @@ export type LiquidFees = {
|
|
|
345
327
|
116
|
|
346
328
|
]
|
|
347
329
|
},
|
|
348
|
-
{
|
|
349
|
-
"kind": "account",
|
|
350
|
-
"path": "feeConfig"
|
|
351
|
-
},
|
|
352
330
|
{
|
|
353
331
|
"kind": "account",
|
|
354
332
|
"path": "recipient"
|
|
@@ -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,
|
|
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
|
-
*
|
|
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,
|
|
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
|
|
45
|
-
const
|
|
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
|
|
94
|
-
const
|
|
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
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
|
48
|
-
|
|
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
|
-
//
|
|
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(
|
|
76
|
+
? calcBps(protocolFee, config.creatorReferralBps)
|
|
53
77
|
: new BN(0);
|
|
54
78
|
const traderReferralFee = hasTraderRef
|
|
55
|
-
? calcBps(
|
|
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,
|
package/src/pda/liquid-fees.ts
CHANGED
|
@@ -54,20 +54,19 @@ export const getFeeVaultPDA = (
|
|
|
54
54
|
};
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
|
-
* Derives the recipient vault PDA for a specific recipient
|
|
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,
|
|
69
|
+
[SEED_RECIPIENT_VAULT, recipient.toBuffer()],
|
|
71
70
|
programId,
|
|
72
71
|
);
|
|
73
72
|
};
|