@liquid-af/sdk 0.10.5 → 0.11.1
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 +8 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +8 -4
- 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/index.d.ts +2 -2
- package/dist/instructions/index.d.ts.map +1 -1
- package/dist/instructions/index.js +1 -1
- package/dist/instructions/index.js.map +1 -1
- package/dist/instructions/liquid-fees.d.ts +18 -7
- package/dist/instructions/liquid-fees.d.ts.map +1 -1
- package/dist/instructions/liquid-fees.js +20 -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 +12 -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/index.ts +2 -0
- package/src/instructions/liquid-fees.ts +28 -28
- package/src/math/bonding-curve.ts +6 -4
- package/src/math/fees.ts +33 -15
- package/src/pda/liquid-fees.ts +3 -4
package/dist/pda/liquid-fees.js
CHANGED
|
@@ -34,14 +34,14 @@ export const getFeeVaultPDA = (feeConfig, programId) => {
|
|
|
34
34
|
return PublicKey.findProgramAddressSync([SEED_FEE_VAULT, feeConfig.toBuffer()], programId);
|
|
35
35
|
};
|
|
36
36
|
/**
|
|
37
|
-
* Derives the recipient vault PDA for a specific recipient
|
|
37
|
+
* Derives the recipient vault PDA for a specific recipient.
|
|
38
|
+
* Vaults are shared across all fee configs — one vault per recipient.
|
|
38
39
|
*
|
|
39
|
-
* @param feeConfig - Fee config PDA address
|
|
40
40
|
* @param recipient - Recipient wallet address
|
|
41
41
|
* @param programId - Liquid Fees program ID
|
|
42
42
|
* @returns Tuple of [PDA address, bump seed]
|
|
43
43
|
*/
|
|
44
|
-
export const getRecipientVaultPDA = (
|
|
45
|
-
return PublicKey.findProgramAddressSync([SEED_RECIPIENT_VAULT,
|
|
44
|
+
export const getRecipientVaultPDA = (recipient, programId) => {
|
|
45
|
+
return PublicKey.findProgramAddressSync([SEED_RECIPIENT_VAULT, recipient.toBuffer()], programId);
|
|
46
46
|
};
|
|
47
47
|
//# sourceMappingURL=liquid-fees.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"liquid-fees.js","sourceRoot":"","sources":["../../src/pda/liquid-fees.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AAClD,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAChD,MAAM,kBAAkB,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;AACxD,MAAM,oBAAoB,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;AAE5D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC9B,SAAoB,EACpB,SAAoB,EACpB,SAAoB,EACE,EAAE;IACxB,OAAO,SAAS,CAAC,sBAAsB,CACtC,CAAC,eAAe,EAAE,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,EAC7D,SAAS,CACT,CAAC;AACH,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACpC,SAAoB,EACE,EAAE;IACxB,OAAO,SAAS,CAAC,sBAAsB,CAAC,CAAC,kBAAkB,CAAC,EAAE,SAAS,CAAC,CAAC;AAC1E,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC7B,SAAoB,EACpB,SAAoB,EACE,EAAE;IACxB,OAAO,SAAS,CAAC,sBAAsB,CACtC,CAAC,cAAc,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,EACtC,SAAS,CACT,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CACnC,SAAoB,EACpB,SAAoB,
|
|
1
|
+
{"version":3,"file":"liquid-fees.js","sourceRoot":"","sources":["../../src/pda/liquid-fees.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AAClD,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAChD,MAAM,kBAAkB,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;AACxD,MAAM,oBAAoB,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;AAE5D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC9B,SAAoB,EACpB,SAAoB,EACpB,SAAoB,EACE,EAAE;IACxB,OAAO,SAAS,CAAC,sBAAsB,CACtC,CAAC,eAAe,EAAE,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,EAC7D,SAAS,CACT,CAAC;AACH,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACpC,SAAoB,EACE,EAAE;IACxB,OAAO,SAAS,CAAC,sBAAsB,CAAC,CAAC,kBAAkB,CAAC,EAAE,SAAS,CAAC,CAAC;AAC1E,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC7B,SAAoB,EACpB,SAAoB,EACE,EAAE;IACxB,OAAO,SAAS,CAAC,sBAAsB,CACtC,CAAC,cAAc,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,EACtC,SAAS,CACT,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CACnC,SAAoB,EACpB,SAAoB,EACE,EAAE;IACxB,OAAO,SAAS,CAAC,sBAAsB,CACtC,CAAC,oBAAoB,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,EAC5C,SAAS,CACT,CAAC;AACH,CAAC,CAAC"}
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -50,6 +50,7 @@ import {
|
|
|
50
50
|
import {
|
|
51
51
|
buildUpdateFeeConfig,
|
|
52
52
|
buildRevokeFeeConfig,
|
|
53
|
+
buildRevokeUpdateAuthority,
|
|
53
54
|
buildDistributeFees,
|
|
54
55
|
buildDistributeTokenFees,
|
|
55
56
|
buildClaimFees,
|
|
@@ -686,6 +687,15 @@ export class LiquidClient {
|
|
|
686
687
|
return buildRevokeFeeConfig({ ...params, config: this.config });
|
|
687
688
|
}
|
|
688
689
|
|
|
690
|
+
/** Revokes the update authority by setting it to the default pubkey. Irreversible. */
|
|
691
|
+
buildRevokeUpdateAuthority(params: {
|
|
692
|
+
authority: PublicKey;
|
|
693
|
+
tokenMint: PublicKey;
|
|
694
|
+
quoteMint: PublicKey;
|
|
695
|
+
}): Promise<TransactionInstruction> {
|
|
696
|
+
return buildRevokeUpdateAuthority({ ...params, config: this.config });
|
|
697
|
+
}
|
|
698
|
+
|
|
689
699
|
/** Builds a permissionless distributeFees instruction (SOL fees). */
|
|
690
700
|
buildDistributeFees(params: {
|
|
691
701
|
payer: PublicKey;
|
|
@@ -709,8 +719,6 @@ export class LiquidClient {
|
|
|
709
719
|
/** Builds a claimFees instruction. Recipient claims accumulated SOL from their vault PDA. */
|
|
710
720
|
buildClaimFees(params: {
|
|
711
721
|
recipient: PublicKey;
|
|
712
|
-
tokenMint: PublicKey;
|
|
713
|
-
quoteMint: PublicKey;
|
|
714
722
|
}): Promise<TransactionInstruction> {
|
|
715
723
|
return buildClaimFees({ ...params, config: this.config });
|
|
716
724
|
}
|
|
@@ -718,7 +726,6 @@ export class LiquidClient {
|
|
|
718
726
|
/** Builds a claimTokenFees instruction. Recipient claims accumulated tokens from their vault ATA. */
|
|
719
727
|
buildClaimTokenFees(params: {
|
|
720
728
|
recipient: PublicKey;
|
|
721
|
-
tokenMint: PublicKey;
|
|
722
729
|
quoteMint: PublicKey;
|
|
723
730
|
}): Promise<TransactionInstruction> {
|
|
724
731
|
return buildClaimTokenFees({ ...params, config: this.config });
|
|
@@ -1027,13 +1034,9 @@ export class LiquidClient {
|
|
|
1027
1034
|
return getFeeVaultPDA(feeConfig, this.config.liquidFeesProgramId);
|
|
1028
1035
|
}
|
|
1029
1036
|
|
|
1030
|
-
/** Derives the recipient vault PDA for a specific recipient
|
|
1031
|
-
getRecipientVaultPDA(
|
|
1032
|
-
feeConfig: PublicKey,
|
|
1033
|
-
recipient: PublicKey,
|
|
1034
|
-
): [PublicKey, number] {
|
|
1037
|
+
/** Derives the recipient vault PDA for a specific recipient. */
|
|
1038
|
+
getRecipientVaultPDA(recipient: PublicKey): [PublicKey, number] {
|
|
1035
1039
|
return getRecipientVaultPDA(
|
|
1036
|
-
feeConfig,
|
|
1037
1040
|
recipient,
|
|
1038
1041
|
this.config.liquidFeesProgramId,
|
|
1039
1042
|
);
|
|
@@ -1740,13 +1740,6 @@
|
|
|
1740
1740
|
"type": {
|
|
1741
1741
|
"kind": "struct",
|
|
1742
1742
|
"fields": [
|
|
1743
|
-
{
|
|
1744
|
-
"name": "fee_config",
|
|
1745
|
-
"docs": [
|
|
1746
|
-
"The fee configuration PDA."
|
|
1747
|
-
],
|
|
1748
|
-
"type": "pubkey"
|
|
1749
|
-
},
|
|
1750
1743
|
{
|
|
1751
1744
|
"name": "mint",
|
|
1752
1745
|
"docs": [
|
|
@@ -2395,9 +2388,9 @@
|
|
|
2395
2388
|
{
|
|
2396
2389
|
"name": "cashback",
|
|
2397
2390
|
"docs": [
|
|
2398
|
-
"Cashback
|
|
2391
|
+
"Cashback earned (positive) or spent (negative) by the user."
|
|
2399
2392
|
],
|
|
2400
|
-
"type": "
|
|
2393
|
+
"type": "i64"
|
|
2401
2394
|
},
|
|
2402
2395
|
{
|
|
2403
2396
|
"name": "cashback_bps",
|
|
@@ -2688,9 +2681,9 @@
|
|
|
2688
2681
|
{
|
|
2689
2682
|
"name": "cashback",
|
|
2690
2683
|
"docs": [
|
|
2691
|
-
"Cashback
|
|
2684
|
+
"Cashback earned (positive) or spent (negative) by the user."
|
|
2692
2685
|
],
|
|
2693
|
-
"type": "
|
|
2686
|
+
"type": "i64"
|
|
2694
2687
|
},
|
|
2695
2688
|
{
|
|
2696
2689
|
"name": "cashback_bps",
|
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"
|
|
@@ -78,6 +78,7 @@ export {
|
|
|
78
78
|
buildInitializeGlobalConfig,
|
|
79
79
|
buildUpdateFeeConfig,
|
|
80
80
|
buildRevokeFeeConfig,
|
|
81
|
+
buildRevokeUpdateAuthority,
|
|
81
82
|
buildDistributeFees,
|
|
82
83
|
buildDistributeTokenFees,
|
|
83
84
|
buildClaimFees,
|
|
@@ -88,6 +89,7 @@ export type {
|
|
|
88
89
|
BuildInitializeGlobalConfigParams,
|
|
89
90
|
BuildUpdateFeeConfigParams,
|
|
90
91
|
BuildRevokeFeeConfigParams,
|
|
92
|
+
BuildRevokeUpdateAuthorityParams,
|
|
91
93
|
BuildDistributeFeesParams,
|
|
92
94
|
BuildDistributeTokenFeesParams,
|
|
93
95
|
BuildClaimFeesParams,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { PublicKey, type TransactionInstruction } from "@solana/web3.js";
|
|
2
2
|
import { getAssociatedTokenAddressSync } from "@solana/spl-token";
|
|
3
3
|
import type { LiquidConfig } from "../config.js";
|
|
4
4
|
import type { FeeRecipient } from "../types.js";
|
|
@@ -122,6 +122,29 @@ export function buildRevokeFeeConfig(
|
|
|
122
122
|
.instruction();
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
export interface BuildRevokeUpdateAuthorityParams {
|
|
126
|
+
authority: PublicKey;
|
|
127
|
+
tokenMint: PublicKey;
|
|
128
|
+
quoteMint: PublicKey;
|
|
129
|
+
config: LiquidConfig;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Builds an updateFeeConfig instruction that permanently revokes the update authority
|
|
134
|
+
* by setting it to the default public key (all zeros). Irreversible.
|
|
135
|
+
*
|
|
136
|
+
* @param params - {@link BuildRevokeUpdateAuthorityParams}
|
|
137
|
+
* @returns Transaction instruction
|
|
138
|
+
*/
|
|
139
|
+
export function buildRevokeUpdateAuthority(
|
|
140
|
+
params: BuildRevokeUpdateAuthorityParams,
|
|
141
|
+
): Promise<TransactionInstruction> {
|
|
142
|
+
return buildUpdateFeeConfig({
|
|
143
|
+
...params,
|
|
144
|
+
newUpdateAuthority: PublicKey.default,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
125
148
|
export interface BuildDistributeFeesParams {
|
|
126
149
|
payer: PublicKey;
|
|
127
150
|
tokenMint: PublicKey;
|
|
@@ -209,14 +232,13 @@ export function buildDistributeTokenFees(
|
|
|
209
232
|
|
|
210
233
|
export interface BuildClaimFeesParams {
|
|
211
234
|
recipient: PublicKey;
|
|
212
|
-
tokenMint: PublicKey;
|
|
213
|
-
quoteMint: PublicKey;
|
|
214
235
|
config: LiquidConfig;
|
|
215
236
|
}
|
|
216
237
|
|
|
217
238
|
/**
|
|
218
239
|
* Builds a claimFees instruction.
|
|
219
240
|
* Allows a recipient to claim accumulated SOL fees from their vault PDA.
|
|
241
|
+
* Vaults are shared across all fee configs — one claim drains all SOL fees.
|
|
220
242
|
*
|
|
221
243
|
* @param params - {@link BuildClaimFeesParams}
|
|
222
244
|
* @returns Transaction instruction
|
|
@@ -224,26 +246,19 @@ export interface BuildClaimFeesParams {
|
|
|
224
246
|
export function buildClaimFees(
|
|
225
247
|
params: BuildClaimFeesParams,
|
|
226
248
|
): Promise<TransactionInstruction> {
|
|
227
|
-
const { recipient,
|
|
249
|
+
const { recipient, config } = params;
|
|
228
250
|
const program = getCachedFeesProgram(config);
|
|
229
|
-
const [feeConfig] = getFeeConfigPDA(
|
|
230
|
-
tokenMint,
|
|
231
|
-
quoteMint,
|
|
232
|
-
config.liquidFeesProgramId,
|
|
233
|
-
);
|
|
234
251
|
|
|
235
252
|
return program.methods
|
|
236
253
|
.claimFees()
|
|
237
254
|
.accounts({
|
|
238
255
|
recipient,
|
|
239
|
-
feeConfig,
|
|
240
256
|
})
|
|
241
257
|
.instruction();
|
|
242
258
|
}
|
|
243
259
|
|
|
244
260
|
export interface BuildClaimTokenFeesParams {
|
|
245
261
|
recipient: PublicKey;
|
|
246
|
-
tokenMint: PublicKey;
|
|
247
262
|
quoteMint: PublicKey;
|
|
248
263
|
recipientTokenAccount?: PublicKey;
|
|
249
264
|
config: LiquidConfig;
|
|
@@ -252,7 +267,7 @@ export interface BuildClaimTokenFeesParams {
|
|
|
252
267
|
/**
|
|
253
268
|
* Builds a claimTokenFees instruction.
|
|
254
269
|
* Allows a recipient to claim accumulated token fees from their vault ATA.
|
|
255
|
-
*
|
|
270
|
+
* Vaults are shared across all fee configs — one claim drains all token fees for the quote mint.
|
|
256
271
|
*
|
|
257
272
|
* @param params - {@link BuildClaimTokenFeesParams}
|
|
258
273
|
* @returns Transaction instruction
|
|
@@ -260,14 +275,8 @@ export interface BuildClaimTokenFeesParams {
|
|
|
260
275
|
export function buildClaimTokenFees(
|
|
261
276
|
params: BuildClaimTokenFeesParams,
|
|
262
277
|
): Promise<TransactionInstruction> {
|
|
263
|
-
const { recipient,
|
|
264
|
-
params;
|
|
278
|
+
const { recipient, quoteMint, recipientTokenAccount, config } = params;
|
|
265
279
|
const program = getCachedFeesProgram(config);
|
|
266
|
-
const [feeConfig] = getFeeConfigPDA(
|
|
267
|
-
tokenMint,
|
|
268
|
-
quoteMint,
|
|
269
|
-
config.liquidFeesProgramId,
|
|
270
|
-
);
|
|
271
280
|
|
|
272
281
|
const resolvedRecipientTokenAccount =
|
|
273
282
|
recipientTokenAccount ??
|
|
@@ -277,7 +286,6 @@ export function buildClaimTokenFees(
|
|
|
277
286
|
.claimTokenFees()
|
|
278
287
|
.accounts({
|
|
279
288
|
recipient,
|
|
280
|
-
feeConfig,
|
|
281
289
|
quoteMint,
|
|
282
290
|
recipientTokenAccount: resolvedRecipientTokenAccount,
|
|
283
291
|
})
|
|
@@ -313,26 +321,18 @@ export function buildInitializeGlobalConfig(
|
|
|
313
321
|
/**
|
|
314
322
|
* Helper: derives recipient vault PDA pairs for use with buildDistributeTokenFees.
|
|
315
323
|
*
|
|
316
|
-
* @param tokenMint - Token mint address
|
|
317
324
|
* @param recipients - Array of recipient public keys in fee_config order
|
|
318
325
|
* @param quoteMint - Quote mint for ATA derivation
|
|
319
326
|
* @param config - Liquid protocol config
|
|
320
327
|
* @returns Array of RecipientVaultPair for remaining accounts
|
|
321
328
|
*/
|
|
322
329
|
export function deriveRecipientVaultPairs(
|
|
323
|
-
tokenMint: PublicKey,
|
|
324
330
|
recipients: PublicKey[],
|
|
325
331
|
quoteMint: PublicKey,
|
|
326
332
|
config: LiquidConfig,
|
|
327
333
|
): RecipientVaultPair[] {
|
|
328
|
-
const [feeConfig] = getFeeConfigPDA(
|
|
329
|
-
tokenMint,
|
|
330
|
-
quoteMint,
|
|
331
|
-
config.liquidFeesProgramId,
|
|
332
|
-
);
|
|
333
334
|
return recipients.map((recipient) => {
|
|
334
335
|
const [vaultPda] = getRecipientVaultPDA(
|
|
335
|
-
feeConfig,
|
|
336
336
|
recipient,
|
|
337
337
|
config.liquidFeesProgramId,
|
|
338
338
|
);
|
|
@@ -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
|
};
|