@send-fun/sdk 1.1.0 → 2.0.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/README.md +8 -9
- package/dist/index.cjs +777 -433
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +678 -217
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +678 -217
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +777 -433
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -7
- package/src/dex/generated/accounts/globalConfig.ts +39 -2
- package/src/dex/generated/accounts/pool.ts +60 -9
- package/src/dex/generated/accounts/rewardAccrual.ts +39 -2
- package/src/dex/generated/errors/sendDex.ts +16 -8
- package/src/dex/generated/events/creatorClaimEvent.ts +3 -2
- package/src/dex/generated/events/poolCreateEvent.ts +8 -2
- package/src/dex/generated/events/tokenCreateEvent.ts +8 -9
- package/src/dex/generated/events/tradeEvent.ts +9 -2
- package/src/dex/generated/index.ts +1 -0
- package/src/dex/generated/instructions/claimCreatorFees.ts +21 -5
- package/src/{nexus → dex}/generated/pdas/creatorFeeConfig.ts +6 -6
- package/src/dex/generated/pdas/index.ts +1 -0
- package/src/dex/generated/plugins/sendDex.ts +3 -0
- package/src/dex/generated/shared/index.ts +52 -0
- package/src/dex/trade.ts +12 -13
- package/src/launchpad/create.ts +13 -38
- package/src/launchpad/generated/accounts/bondingCurve.ts +62 -9
- package/src/launchpad/generated/accounts/globalConfig.ts +39 -2
- package/src/launchpad/generated/accounts/rewardAccrual.ts +39 -2
- package/src/launchpad/generated/errors/sendLaunchpad.ts +12 -4
- package/src/launchpad/generated/events/completeEvent.ts +3 -2
- package/src/launchpad/generated/events/creatorClaimEvent.ts +3 -2
- package/src/launchpad/generated/events/migrateEvent.ts +3 -2
- package/src/launchpad/generated/events/tokenCreateEvent.ts +10 -9
- package/src/launchpad/generated/events/tradeEvent.ts +9 -2
- package/src/launchpad/generated/index.ts +1 -0
- package/src/launchpad/generated/instructions/claimCreatorFees.ts +17 -4
- package/src/launchpad/generated/instructions/createToken.ts +32 -50
- package/src/launchpad/generated/instructions/migrate.ts +79 -12
- package/src/launchpad/generated/pdas/creatorFeeConfig.ts +39 -0
- package/src/launchpad/generated/pdas/index.ts +1 -0
- package/src/launchpad/generated/plugins/sendLaunchpad.ts +3 -0
- package/src/launchpad/generated/shared/index.ts +52 -0
- package/src/launchpad/migrate.ts +7 -4
- package/src/launchpad/trade.ts +15 -15
- package/src/math/amm.ts +40 -33
- package/src/math/fee-decay.ts +3 -2
- package/src/math/fees.ts +4 -2
- package/src/math/internal.ts +1 -1
- package/src/nexus/fee-helpers.ts +10 -5
- package/src/nexus/generated/accounts/altRegistry.ts +41 -2
- package/src/nexus/generated/accounts/feePreset.ts +43 -4
- package/src/nexus/generated/accounts/globalConfig.ts +39 -2
- package/src/nexus/generated/accounts/index.ts +0 -1
- package/src/nexus/generated/accounts/partnerConfig.ts +48 -5
- package/src/nexus/generated/accounts/partnerMetadata.ts +39 -2
- package/src/nexus/generated/accounts/rewardState.ts +41 -2
- package/src/nexus/generated/accounts/sendNexus.accounts.ts +0 -5
- package/src/nexus/generated/accounts/stakingConfig.ts +39 -2
- package/src/nexus/generated/accounts/userRewardDebt.ts +42 -5
- package/src/nexus/generated/accounts/userStakePosition.ts +42 -5
- package/src/nexus/generated/errors/sendNexus.ts +12 -4
- package/src/nexus/generated/index.ts +1 -0
- package/src/nexus/generated/pdas/index.ts +0 -1
- package/src/nexus/generated/plugins/sendNexus.ts +0 -35
- package/src/nexus/generated/shared/index.ts +52 -0
- package/src/nexus/generated/types/dexFees.ts +4 -4
- package/src/nexus/generated/types/index.ts +0 -1
- package/src/nexus/generated/types/launchpadFees.ts +4 -4
- package/src/nexus/staking.ts +45 -41
- package/src/platform.ts +2 -2
- package/src/transfer-fee.ts +19 -17
- package/src/utils/chunk.ts +1 -1
- package/src/utils/index.ts +2 -5
- package/src/utils/mint-info.ts +8 -7
- package/src/utils/partner.ts +1 -1
- package/src/utils/pda.ts +1 -1
- package/src/nexus/generated/accounts/creatorFeeConfig.ts +0 -200
- package/src/nexus/generated/types/callerType.ts +0 -38
- package/src/utils/creator-hash.ts +0 -57
package/src/math/amm.ts
CHANGED
|
@@ -4,7 +4,6 @@ const BPS_DIVISOR = 10_000n;
|
|
|
4
4
|
|
|
5
5
|
const U64_MAX = 18_446_744_073_709_551_615n;
|
|
6
6
|
|
|
7
|
-
/** Each call mirrors a `u64::try_from` in the Rust twin; drop one and an oversized leg fails in the encoder. */
|
|
8
7
|
function assertU64(label: string, value: bigint): bigint {
|
|
9
8
|
if (value > U64_MAX) {
|
|
10
9
|
throw new RangeError(`${label}: overflows u64`);
|
|
@@ -12,15 +11,15 @@ function assertU64(label: string, value: bigint): bigint {
|
|
|
12
11
|
return value;
|
|
13
12
|
}
|
|
14
13
|
|
|
15
|
-
/** Token-2022
|
|
14
|
+
/** A Token-2022 transfer fee for one epoch. Use the fee for the epoch the trade lands in. */
|
|
16
15
|
export interface MintFee {
|
|
17
16
|
/** 0 to 10_000. */
|
|
18
17
|
bps: number;
|
|
19
|
-
/**
|
|
18
|
+
/** Maximum fee per transfer, in the mint's raw units. */
|
|
20
19
|
maximumFee: bigint;
|
|
21
20
|
}
|
|
22
21
|
|
|
23
|
-
/**
|
|
22
|
+
/** Thrown when no transfer delivers exactly `amount` after the transfer fee. */
|
|
24
23
|
export class TransferFeeNotSettleableError extends RangeError {
|
|
25
24
|
readonly amount: bigint;
|
|
26
25
|
readonly mintFee: MintFee;
|
|
@@ -42,7 +41,8 @@ function assertMintFee(fee: MintFee): void {
|
|
|
42
41
|
}
|
|
43
42
|
}
|
|
44
43
|
|
|
45
|
-
/** Rounds up, then caps
|
|
44
|
+
/** Returns the transfer fee on `amount`. Rounds up, then caps at `maximumFee`, in SPL's order.
|
|
45
|
+
* Returns 0 without `fee`. Throws `RangeError` if `fee` is out of range. */
|
|
46
46
|
export function feeOn(amount: bigint, fee?: MintFee): bigint {
|
|
47
47
|
if (fee === undefined) return 0n;
|
|
48
48
|
assertMintFee(fee);
|
|
@@ -52,18 +52,18 @@ export function feeOn(amount: bigint, fee?: MintFee): bigint {
|
|
|
52
52
|
return raw < fee.maximumFee ? raw : fee.maximumFee;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
/**
|
|
55
|
+
/** Returns what the recipient receives when `amount` is sent. `grossUp` is the inverse. */
|
|
56
56
|
export function amountAfterFee(amount: bigint, fee?: MintFee): bigint {
|
|
57
57
|
return amount - feeOn(amount, fee);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
/**
|
|
60
|
+
/** Matches SPL `TransferFee::calculate_pre_fee_amount`. `undefined` if the result does not fit a u64. */
|
|
61
61
|
function preFeeAmount(amount: bigint, fee: MintFee): bigint | undefined {
|
|
62
62
|
const bps = BigInt(fee.bps);
|
|
63
63
|
if (bps === 0n) return amount;
|
|
64
|
-
// Unreachable
|
|
64
|
+
// Unreachable from `grossUp`. Kept to match SPL.
|
|
65
65
|
if (amount === 0n) return 0n;
|
|
66
|
-
// 100
|
|
66
|
+
// At 100%, the fee is always `maximumFee`.
|
|
67
67
|
if (bps === BPS_DIVISOR) {
|
|
68
68
|
const capped = amount + fee.maximumFee;
|
|
69
69
|
return capped > U64_MAX ? undefined : capped;
|
|
@@ -77,7 +77,8 @@ function preFeeAmount(amount: bigint, fee: MintFee): bigint | undefined {
|
|
|
77
77
|
return rawPreFee > U64_MAX ? undefined : rawPreFee;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
/**
|
|
80
|
+
/** Returns the amount to send so that exactly `amount` arrives. Returns `amount` without `fee`.
|
|
81
|
+
* Throws {@link TransferFeeNotSettleableError} if no such amount exists. */
|
|
81
82
|
export function grossUp(amount: bigint, fee?: MintFee): bigint {
|
|
82
83
|
if (fee === undefined) return amount;
|
|
83
84
|
assertMintFee(fee);
|
|
@@ -87,7 +88,7 @@ export function grossUp(amount: bigint, fee?: MintFee): bigint {
|
|
|
87
88
|
if (preFee === undefined)
|
|
88
89
|
throw new TransferFeeNotSettleableError(amount, fee);
|
|
89
90
|
|
|
90
|
-
// SPL's inverse is inexact (`feeOn(x) >= inverse(x - feeOn(x))`)
|
|
91
|
+
// SPL's inverse is inexact (`feeOn(x) >= inverse(x - feeOn(x))`). Check it forward and reject a mismatch.
|
|
91
92
|
const impliedFee = feeOn(preFee, fee);
|
|
92
93
|
const gross = amount + impliedFee;
|
|
93
94
|
if (gross > U64_MAX || feeOn(gross, fee) !== impliedFee) {
|
|
@@ -96,8 +97,8 @@ export function grossUp(amount: bigint, fee?: MintFee): bigint {
|
|
|
96
97
|
return gross;
|
|
97
98
|
}
|
|
98
99
|
|
|
99
|
-
/** `baseAmount
|
|
100
|
-
* fields
|
|
100
|
+
/** `baseAmount` and `quoteAmount` are the user's transfers.
|
|
101
|
+
* Read the net amounts from the fields of {@link BuyQuote} and {@link SellQuote}. Do not calculate them again. */
|
|
101
102
|
export interface TradeQuote {
|
|
102
103
|
/** Base sent: vault to user on a buy, user to vault on a sell. */
|
|
103
104
|
baseAmount: bigint;
|
|
@@ -110,20 +111,20 @@ export interface TradeQuote {
|
|
|
110
111
|
}
|
|
111
112
|
|
|
112
113
|
export interface BuyQuote extends TradeQuote {
|
|
113
|
-
/** Priced on the quote
|
|
114
|
+
/** Priced on the quote that reaches the vault. */
|
|
114
115
|
fee: bigint;
|
|
115
|
-
/** Base
|
|
116
|
+
/** Base the buyer receives, after the base mint's transfer fee. */
|
|
116
117
|
baseToUser: bigint;
|
|
117
118
|
/** Equals `quoteAmount`. */
|
|
118
119
|
quoteFromUser: bigint;
|
|
119
120
|
}
|
|
120
121
|
|
|
121
122
|
export interface SellQuote extends TradeQuote {
|
|
122
|
-
/** Priced on the quote
|
|
123
|
+
/** Priced on the AMM's quote output, before this fee. */
|
|
123
124
|
fee: bigint;
|
|
124
125
|
/** Equals `baseAmount`. */
|
|
125
126
|
baseFromUser: bigint;
|
|
126
|
-
/** Quote
|
|
127
|
+
/** Quote the seller receives, after the quote mint's transfer fee. */
|
|
127
128
|
quoteToUser: bigint;
|
|
128
129
|
}
|
|
129
130
|
|
|
@@ -139,7 +140,8 @@ function sqrtBigInt(value: bigint): bigint {
|
|
|
139
140
|
return x;
|
|
140
141
|
}
|
|
141
142
|
|
|
142
|
-
/**
|
|
143
|
+
/** Returns the constant-product output for `amountIn`, rounded down. Throws `RangeError` on a zero
|
|
144
|
+
* reserve, a zero `amountIn`, a zero output, or an output past u64. */
|
|
143
145
|
export function calculateOutput(
|
|
144
146
|
reserveIn: bigint,
|
|
145
147
|
reserveOut: bigint,
|
|
@@ -169,7 +171,8 @@ export function calculateOutput(
|
|
|
169
171
|
return assertU64('calculateOutput', amountOut);
|
|
170
172
|
}
|
|
171
173
|
|
|
172
|
-
/**
|
|
174
|
+
/** Returns the input needed for `amountOut`, rounded up. Throws `RangeError` on a zero reserve, a zero
|
|
175
|
+
* `amountOut`, an `amountOut` not below `reserveOut`, or an input past u64. */
|
|
173
176
|
export function calculateInputForOutput(
|
|
174
177
|
reserveIn: bigint,
|
|
175
178
|
reserveOut: bigint,
|
|
@@ -207,7 +210,7 @@ interface BaseQuoteParams {
|
|
|
207
210
|
baseFee?: MintFee;
|
|
208
211
|
}
|
|
209
212
|
|
|
210
|
-
/**
|
|
213
|
+
/** `baseReserveCap` is `bondingCurve.realBaseReserves`. A DEX pool has no cap. */
|
|
211
214
|
interface BaseReserveCap {
|
|
212
215
|
baseReserveCap?: bigint;
|
|
213
216
|
}
|
|
@@ -234,7 +237,7 @@ function ammBuyExactOut(
|
|
|
234
237
|
throw new RangeError('buyExactOut: invalid feeBps');
|
|
235
238
|
}
|
|
236
239
|
|
|
237
|
-
// A `feeBps` near 10_000
|
|
240
|
+
// A `feeBps` near 10_000 multiplies the leg by up to 10_000, so this can pass u64.
|
|
238
241
|
const totalQuote = assertU64(
|
|
239
242
|
'buyExactOut',
|
|
240
243
|
ceilDiv(quoteBeforeFee * BPS_DIVISOR, divisor),
|
|
@@ -251,7 +254,7 @@ function ammBuyExactIn(
|
|
|
251
254
|
params: { reserveQuote: bigint; reserveBase: bigint; feeBps: number },
|
|
252
255
|
quoteAmountIn: bigint,
|
|
253
256
|
): AmmLegs {
|
|
254
|
-
//
|
|
257
|
+
// The fee comes off before the swap. The net rounds down, and the fee takes the remainder.
|
|
255
258
|
const netFactor = BPS_DIVISOR - BigInt(params.feeBps);
|
|
256
259
|
if (netFactor <= 0n) {
|
|
257
260
|
throw new RangeError('buyExactIn: invalid feeBps');
|
|
@@ -337,7 +340,9 @@ function buyQuote(
|
|
|
337
340
|
};
|
|
338
341
|
}
|
|
339
342
|
|
|
340
|
-
/**
|
|
343
|
+
/** Quotes a buy where the buyer receives `baseAmountOut`. With `baseReserveCap`, the vault sends at
|
|
344
|
+
* most the cap. Guard with `calculateSlippageUp(quoteAmount, bps)`. `quoteAmount` includes the quote
|
|
345
|
+
* mint's transfer fee. */
|
|
341
346
|
export function buyExactOut(
|
|
342
347
|
params: BaseQuoteParams & BaseReserveCap & { baseAmountOut: bigint },
|
|
343
348
|
): BuyQuote {
|
|
@@ -352,7 +357,7 @@ export function buyExactOut(
|
|
|
352
357
|
cap !== undefined && baseOutOfVault > cap ? cap : baseOutOfVault;
|
|
353
358
|
|
|
354
359
|
const legs = ammBuyExactOut(params, baseAmount);
|
|
355
|
-
// The priced total must
|
|
360
|
+
// The priced total must reach the vault, so the user sends it grossed up.
|
|
356
361
|
const quoteFromUser = grossUp(legs.quoteAmount, params.quoteFee);
|
|
357
362
|
|
|
358
363
|
return buyQuote(
|
|
@@ -362,7 +367,8 @@ export function buyExactOut(
|
|
|
362
367
|
);
|
|
363
368
|
}
|
|
364
369
|
|
|
365
|
-
/** Guard with `calculateSlippageDown(baseToUser, bps)`, not
|
|
370
|
+
/** Quotes a buy that spends `quoteAmountIn`. Guard with `calculateSlippageDown(baseToUser, bps)`, not
|
|
371
|
+
* `baseAmount`. The program checks the minimum against what the buyer receives. */
|
|
366
372
|
export function buyExactIn(
|
|
367
373
|
params: BaseQuoteParams & BaseReserveCap & { quoteAmountIn: bigint },
|
|
368
374
|
): BuyQuote {
|
|
@@ -371,7 +377,7 @@ export function buyExactIn(
|
|
|
371
377
|
throw new RangeError('buyExactIn: invalid amount');
|
|
372
378
|
}
|
|
373
379
|
|
|
374
|
-
// The AMM only
|
|
380
|
+
// The AMM prices only what reaches the vault.
|
|
375
381
|
const quoteIntoVault = amountAfterFee(
|
|
376
382
|
params.quoteAmountIn,
|
|
377
383
|
params.quoteFee,
|
|
@@ -382,7 +388,7 @@ export function buyExactIn(
|
|
|
382
388
|
|
|
383
389
|
const uncapped = ammBuyExactIn(params, quoteIntoVault);
|
|
384
390
|
|
|
385
|
-
//
|
|
391
|
+
// Over the cap: price exact-out at the cap, then gross up. Clamping the base output alone overstates the quote leg.
|
|
386
392
|
const cap = params.baseReserveCap;
|
|
387
393
|
if (cap === undefined || uncapped.baseAmount <= cap) {
|
|
388
394
|
return buyQuote(
|
|
@@ -402,7 +408,7 @@ export function buyExactIn(
|
|
|
402
408
|
);
|
|
403
409
|
}
|
|
404
410
|
|
|
405
|
-
/** Guard with `calculateSlippageDown(quoteToUser, bps)`, not `quoteAmount`. */
|
|
411
|
+
/** Quotes a sell of `baseAmountIn`. Guard with `calculateSlippageDown(quoteToUser, bps)`, not `quoteAmount`. */
|
|
406
412
|
export function sellExactIn(
|
|
407
413
|
params: BaseQuoteParams & { baseAmountIn: bigint },
|
|
408
414
|
): SellQuote {
|
|
@@ -417,7 +423,7 @@ export function sellExactIn(
|
|
|
417
423
|
}
|
|
418
424
|
|
|
419
425
|
const legs = ammSellExactIn(params, baseIntoVault);
|
|
420
|
-
// `feeOn`,
|
|
426
|
+
// `feeOn`, not `grossUp`: the AMM's output leaves the vault as priced.
|
|
421
427
|
const quoteTransferFee = feeOn(legs.quoteAmount, params.quoteFee);
|
|
422
428
|
|
|
423
429
|
return {
|
|
@@ -431,7 +437,8 @@ export function sellExactIn(
|
|
|
431
437
|
};
|
|
432
438
|
}
|
|
433
439
|
|
|
434
|
-
/**
|
|
440
|
+
/** Quotes a sell where the seller receives `quoteAmountOut`. Guard with
|
|
441
|
+
* `calculateSlippageUp(baseFromUser, bps)`. `baseFromUser` includes the base mint's transfer fee. */
|
|
435
442
|
export function sellExactOut(
|
|
436
443
|
params: BaseQuoteParams & { quoteAmountOut: bigint },
|
|
437
444
|
): SellQuote {
|
|
@@ -478,7 +485,7 @@ export function calculateSlippageDown(
|
|
|
478
485
|
);
|
|
479
486
|
}
|
|
480
487
|
|
|
481
|
-
/**
|
|
488
|
+
/** Returns `sqrt(quoteAmount * baseAmount)`, rounded down. */
|
|
482
489
|
export function calculateInitialLp(
|
|
483
490
|
quoteAmount: bigint,
|
|
484
491
|
baseAmount: bigint,
|
|
@@ -486,7 +493,7 @@ export function calculateInitialLp(
|
|
|
486
493
|
return sqrtBigInt(quoteAmount * baseAmount);
|
|
487
494
|
}
|
|
488
495
|
|
|
489
|
-
/**
|
|
496
|
+
/** Returns the price of one base token in quote tokens, as a float. For display only. */
|
|
490
497
|
export function calculatePrice(params: {
|
|
491
498
|
quoteReserves: bigint;
|
|
492
499
|
baseReserves: bigint;
|
|
@@ -499,7 +506,7 @@ export function calculatePrice(params: {
|
|
|
499
506
|
return rawRatio * 10 ** (baseDecimals - quoteDecimals);
|
|
500
507
|
}
|
|
501
508
|
|
|
502
|
-
/**
|
|
509
|
+
/** Returns the market cap in raw quote units. */
|
|
503
510
|
export function calculateMarketCap(params: {
|
|
504
511
|
quoteReserves: bigint;
|
|
505
512
|
baseReserves: bigint;
|
package/src/math/fee-decay.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ceilDiv } from './internal.js';
|
|
2
2
|
|
|
3
|
-
/**
|
|
3
|
+
/** Returns the fee decay premium in bps, rounded up. The premium falls quadratically from
|
|
4
|
+
* `decayStartBps - standardFeeBps` at creation to 0 after `decaySeconds`. */
|
|
4
5
|
export function calculateFeeDecayPremium(params: {
|
|
5
6
|
currentTimestamp: bigint;
|
|
6
7
|
createdAtTimestamp: bigint;
|
|
@@ -23,7 +24,7 @@ export function calculateFeeDecayPremium(params: {
|
|
|
23
24
|
const standardBps = BigInt(standardFeeBps);
|
|
24
25
|
const decaySecondsBig = BigInt(decaySeconds);
|
|
25
26
|
|
|
26
|
-
//
|
|
27
|
+
// A creation time in the future pays the full premium.
|
|
27
28
|
if (createdAtTimestamp > currentTimestamp) {
|
|
28
29
|
if (startBps <= standardBps) return 0n;
|
|
29
30
|
return startBps - standardBps;
|
package/src/math/fees.ts
CHANGED
|
@@ -10,11 +10,13 @@ export interface FeeSplit {
|
|
|
10
10
|
protocol: bigint;
|
|
11
11
|
lp: bigint;
|
|
12
12
|
creator: bigint;
|
|
13
|
-
/**
|
|
13
|
+
/** The decay premium share. `protocol` includes it. It is not a separate payout. */
|
|
14
14
|
sniper: bigint;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
/**
|
|
17
|
+
/** Splits `feeAmount` into protocol, LP and creator shares. LP and creator round down. Protocol gets
|
|
18
|
+
* the decay premium and all remainders. Throws `RangeError` on a negative or non-integer input,
|
|
19
|
+
* a zero total bps, or `protocolBps + lpBps` above `baseTotalBps`. */
|
|
18
20
|
export function splitFeeAmount(args: FeeSplitArgs): FeeSplit {
|
|
19
21
|
const { feeAmount } = args;
|
|
20
22
|
const protocolBps = toBps(args.protocolBps, 'protocolBps');
|
package/src/math/internal.ts
CHANGED
package/src/nexus/fee-helpers.ts
CHANGED
|
@@ -8,7 +8,8 @@ import { findPartnerConfigPda } from './generated/pdas/partnerConfig.js';
|
|
|
8
8
|
import type { DexFees } from './generated/types/dexFees.js';
|
|
9
9
|
import type { LaunchpadFees } from './generated/types/launchpadFees.js';
|
|
10
10
|
|
|
11
|
-
/**
|
|
11
|
+
/** Fetches the `PartnerConfig` of `partner` on `platformConfig`. Throws if it does not exist.
|
|
12
|
+
* Use the `platformConfig` of the market you price. A partner's fees differ per platform. */
|
|
12
13
|
export async function fetchPartnerFees(
|
|
13
14
|
rpc: Rpc<GetAccountInfoApi>,
|
|
14
15
|
partner: Address,
|
|
@@ -27,17 +28,21 @@ export async function fetchPartnerFees(
|
|
|
27
28
|
return maybeAccount.data;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
/**
|
|
31
|
-
*
|
|
31
|
+
/** Returns the `feeBps` a trade pays: the standard rate plus the decay premium. The standard rate
|
|
32
|
+
* is the protocol and LP rates of `schedule` plus `creatorFeeBps`. `schedule` is the
|
|
33
|
+
* `PartnerConfig`'s `launchpad` for a curve or `dex` for a pool. `creatorFeeBps` and `createdAt`
|
|
34
|
+
* are the curve's or pool's. `schedule.maxCreatorFeeBps` has no effect. `createdAt` and `now`
|
|
35
|
+
* are in unix seconds. */
|
|
32
36
|
export function effectiveFeeBps(
|
|
33
37
|
schedule: LaunchpadFees | DexFees,
|
|
34
38
|
createdAt: bigint,
|
|
35
39
|
now: bigint,
|
|
40
|
+
creatorFeeBps: number,
|
|
36
41
|
): number {
|
|
37
42
|
const standardFeeBps =
|
|
38
43
|
schedule.protocolFeeBps +
|
|
39
|
-
schedule.
|
|
40
|
-
|
|
44
|
+
('lpFeeBps' in schedule ? schedule.lpFeeBps : 0) +
|
|
45
|
+
creatorFeeBps;
|
|
41
46
|
const premium = calculateFeeDecayPremium({
|
|
42
47
|
currentTimestamp: now,
|
|
43
48
|
createdAtTimestamp: createdAt,
|
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
type ReadonlyUint8Array,
|
|
39
39
|
} from '@solana/kit';
|
|
40
40
|
import { SEND_NEXUS_PROGRAM_ADDRESS } from '../programs/index.js';
|
|
41
|
+
import { accountIsCreated } from '../shared/index.js';
|
|
41
42
|
|
|
42
43
|
export const ALT_REGISTRY_DISCRIMINATOR: ReadonlyUint8Array = new Uint8Array([
|
|
43
44
|
184, 237, 52, 250, 77, 8, 59, 74,
|
|
@@ -97,9 +98,25 @@ export function getAltRegistryCodec(): FixedSizeCodec<
|
|
|
97
98
|
return combineCodec(getAltRegistryEncoder(), getAltRegistryDecoder());
|
|
98
99
|
}
|
|
99
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Decodes a `AltRegistry` account, throwing when another program owns it or its discriminator
|
|
103
|
+
* does not match.
|
|
104
|
+
*
|
|
105
|
+
* Unlike {@link fetchMaybeAltRegistry}, this throws for an address that only holds lamports rather
|
|
106
|
+
* than returning the non-existing variant: an account passed as existing must never come back as that
|
|
107
|
+
* variant typed as an `Account`. Apply {@link accountIsCreated} first to accounts fetched another way.
|
|
108
|
+
*/
|
|
100
109
|
export function decodeAltRegistry<TAddress extends string = string>(
|
|
101
110
|
encodedAccount: EncodedAccount<TAddress>,
|
|
102
111
|
): Account<AltRegistry, TAddress>;
|
|
112
|
+
/**
|
|
113
|
+
* Decodes a `AltRegistry` account, throwing when another program owns it or its discriminator
|
|
114
|
+
* does not match.
|
|
115
|
+
*
|
|
116
|
+
* Unlike {@link fetchMaybeAltRegistry}, this throws for an address that only holds lamports rather
|
|
117
|
+
* than returning the non-existing variant: an account passed as existing must never come back as that
|
|
118
|
+
* variant typed as an `Account`. Apply {@link accountIsCreated} first to accounts fetched another way.
|
|
119
|
+
*/
|
|
103
120
|
export function decodeAltRegistry<TAddress extends string = string>(
|
|
104
121
|
encodedAccount: MaybeEncodedAccount<TAddress>,
|
|
105
122
|
): MaybeAccount<AltRegistry, TAddress>;
|
|
@@ -130,6 +147,7 @@ export function decodeAltRegistry<TAddress extends string = string>(
|
|
|
130
147
|
);
|
|
131
148
|
}
|
|
132
149
|
|
|
150
|
+
/** Fetches a `AltRegistry` account, throwing when it does not exist or only holds lamports. */
|
|
133
151
|
export async function fetchAltRegistry<TAddress extends string = string>(
|
|
134
152
|
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
135
153
|
address: Address<TAddress>,
|
|
@@ -140,15 +158,25 @@ export async function fetchAltRegistry<TAddress extends string = string>(
|
|
|
140
158
|
return maybeAccount;
|
|
141
159
|
}
|
|
142
160
|
|
|
161
|
+
/**
|
|
162
|
+
* Fetches a `AltRegistry` account, or the non-existing variant when the address holds no
|
|
163
|
+
* account or only lamports (see {@link accountIsCreated}).
|
|
164
|
+
* {@link decodeAltRegistry} throws for a lamports-only account instead.
|
|
165
|
+
*/
|
|
143
166
|
export async function fetchMaybeAltRegistry<TAddress extends string = string>(
|
|
144
167
|
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
145
168
|
address: Address<TAddress>,
|
|
146
169
|
config?: FetchAccountConfig,
|
|
147
170
|
): Promise<MaybeAccount<AltRegistry, TAddress>> {
|
|
148
171
|
const maybeAccount = await fetchEncodedAccount(rpc, address, config);
|
|
149
|
-
return decodeAltRegistry(
|
|
172
|
+
return decodeAltRegistry(
|
|
173
|
+
accountIsCreated(maybeAccount)
|
|
174
|
+
? maybeAccount
|
|
175
|
+
: { address, exists: false },
|
|
176
|
+
);
|
|
150
177
|
}
|
|
151
178
|
|
|
179
|
+
/** Fetches `AltRegistry` accounts, throwing when any does not exist or only holds lamports. */
|
|
152
180
|
export async function fetchAllAltRegistry(
|
|
153
181
|
rpc: Parameters<typeof fetchEncodedAccounts>[0],
|
|
154
182
|
addresses: Array<Address>,
|
|
@@ -163,13 +191,24 @@ export async function fetchAllAltRegistry(
|
|
|
163
191
|
return maybeAccounts;
|
|
164
192
|
}
|
|
165
193
|
|
|
194
|
+
/**
|
|
195
|
+
* Fetches `AltRegistry` accounts, with the non-existing variant for each address that holds
|
|
196
|
+
* no account or only lamports (see {@link accountIsCreated}).
|
|
197
|
+
* {@link decodeAltRegistry} throws for a lamports-only account instead.
|
|
198
|
+
*/
|
|
166
199
|
export async function fetchAllMaybeAltRegistry(
|
|
167
200
|
rpc: Parameters<typeof fetchEncodedAccounts>[0],
|
|
168
201
|
addresses: Array<Address>,
|
|
169
202
|
config?: FetchAccountsConfig,
|
|
170
203
|
): Promise<MaybeAccount<AltRegistry>[]> {
|
|
171
204
|
const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config);
|
|
172
|
-
return maybeAccounts.map((maybeAccount) =>
|
|
205
|
+
return maybeAccounts.map((maybeAccount) =>
|
|
206
|
+
decodeAltRegistry(
|
|
207
|
+
accountIsCreated(maybeAccount)
|
|
208
|
+
? maybeAccount
|
|
209
|
+
: { address: maybeAccount.address, exists: false },
|
|
210
|
+
),
|
|
211
|
+
);
|
|
173
212
|
}
|
|
174
213
|
|
|
175
214
|
export function getAltRegistrySize(): number {
|
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
type ReadonlyUint8Array,
|
|
45
45
|
} from '@solana/kit';
|
|
46
46
|
import { SEND_NEXUS_PROGRAM_ADDRESS } from '../programs/index.js';
|
|
47
|
+
import { accountIsCreated } from '../shared/index.js';
|
|
47
48
|
import {
|
|
48
49
|
getDexFeesDecoder,
|
|
49
50
|
getDexFeesEncoder,
|
|
@@ -100,7 +101,7 @@ export function getFeePresetEncoder(): Encoder<FeePresetArgs> {
|
|
|
100
101
|
['launchpad', getLaunchpadFeesEncoder()],
|
|
101
102
|
['dex', getDexFeesEncoder()],
|
|
102
103
|
['platformConfig', getAddressEncoder()],
|
|
103
|
-
['reserved', fixEncoderSize(getBytesEncoder(),
|
|
104
|
+
['reserved', fixEncoderSize(getBytesEncoder(), 64)],
|
|
104
105
|
]),
|
|
105
106
|
(value) => ({ ...value, discriminator: FEE_PRESET_DISCRIMINATOR }),
|
|
106
107
|
);
|
|
@@ -117,7 +118,7 @@ export function getFeePresetDecoder(): Decoder<FeePreset> {
|
|
|
117
118
|
['launchpad', getLaunchpadFeesDecoder()],
|
|
118
119
|
['dex', getDexFeesDecoder()],
|
|
119
120
|
['platformConfig', getAddressDecoder()],
|
|
120
|
-
['reserved', fixDecoderSize(getBytesDecoder(),
|
|
121
|
+
['reserved', fixDecoderSize(getBytesDecoder(), 64)],
|
|
121
122
|
]);
|
|
122
123
|
}
|
|
123
124
|
|
|
@@ -126,9 +127,25 @@ export function getFeePresetCodec(): Codec<FeePresetArgs, FeePreset> {
|
|
|
126
127
|
return combineCodec(getFeePresetEncoder(), getFeePresetDecoder());
|
|
127
128
|
}
|
|
128
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Decodes a `FeePreset` account, throwing when another program owns it or its discriminator
|
|
132
|
+
* does not match.
|
|
133
|
+
*
|
|
134
|
+
* Unlike {@link fetchMaybeFeePreset}, this throws for an address that only holds lamports rather
|
|
135
|
+
* than returning the non-existing variant: an account passed as existing must never come back as that
|
|
136
|
+
* variant typed as an `Account`. Apply {@link accountIsCreated} first to accounts fetched another way.
|
|
137
|
+
*/
|
|
129
138
|
export function decodeFeePreset<TAddress extends string = string>(
|
|
130
139
|
encodedAccount: EncodedAccount<TAddress>,
|
|
131
140
|
): Account<FeePreset, TAddress>;
|
|
141
|
+
/**
|
|
142
|
+
* Decodes a `FeePreset` account, throwing when another program owns it or its discriminator
|
|
143
|
+
* does not match.
|
|
144
|
+
*
|
|
145
|
+
* Unlike {@link fetchMaybeFeePreset}, this throws for an address that only holds lamports rather
|
|
146
|
+
* than returning the non-existing variant: an account passed as existing must never come back as that
|
|
147
|
+
* variant typed as an `Account`. Apply {@link accountIsCreated} first to accounts fetched another way.
|
|
148
|
+
*/
|
|
132
149
|
export function decodeFeePreset<TAddress extends string = string>(
|
|
133
150
|
encodedAccount: MaybeEncodedAccount<TAddress>,
|
|
134
151
|
): MaybeAccount<FeePreset, TAddress>;
|
|
@@ -157,6 +174,7 @@ export function decodeFeePreset<TAddress extends string = string>(
|
|
|
157
174
|
);
|
|
158
175
|
}
|
|
159
176
|
|
|
177
|
+
/** Fetches a `FeePreset` account, throwing when it does not exist or only holds lamports. */
|
|
160
178
|
export async function fetchFeePreset<TAddress extends string = string>(
|
|
161
179
|
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
162
180
|
address: Address<TAddress>,
|
|
@@ -167,15 +185,25 @@ export async function fetchFeePreset<TAddress extends string = string>(
|
|
|
167
185
|
return maybeAccount;
|
|
168
186
|
}
|
|
169
187
|
|
|
188
|
+
/**
|
|
189
|
+
* Fetches a `FeePreset` account, or the non-existing variant when the address holds no
|
|
190
|
+
* account or only lamports (see {@link accountIsCreated}).
|
|
191
|
+
* {@link decodeFeePreset} throws for a lamports-only account instead.
|
|
192
|
+
*/
|
|
170
193
|
export async function fetchMaybeFeePreset<TAddress extends string = string>(
|
|
171
194
|
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
172
195
|
address: Address<TAddress>,
|
|
173
196
|
config?: FetchAccountConfig,
|
|
174
197
|
): Promise<MaybeAccount<FeePreset, TAddress>> {
|
|
175
198
|
const maybeAccount = await fetchEncodedAccount(rpc, address, config);
|
|
176
|
-
return decodeFeePreset(
|
|
199
|
+
return decodeFeePreset(
|
|
200
|
+
accountIsCreated(maybeAccount)
|
|
201
|
+
? maybeAccount
|
|
202
|
+
: { address, exists: false },
|
|
203
|
+
);
|
|
177
204
|
}
|
|
178
205
|
|
|
206
|
+
/** Fetches `FeePreset` accounts, throwing when any does not exist or only holds lamports. */
|
|
179
207
|
export async function fetchAllFeePreset(
|
|
180
208
|
rpc: Parameters<typeof fetchEncodedAccounts>[0],
|
|
181
209
|
addresses: Array<Address>,
|
|
@@ -186,11 +214,22 @@ export async function fetchAllFeePreset(
|
|
|
186
214
|
return maybeAccounts;
|
|
187
215
|
}
|
|
188
216
|
|
|
217
|
+
/**
|
|
218
|
+
* Fetches `FeePreset` accounts, with the non-existing variant for each address that holds
|
|
219
|
+
* no account or only lamports (see {@link accountIsCreated}).
|
|
220
|
+
* {@link decodeFeePreset} throws for a lamports-only account instead.
|
|
221
|
+
*/
|
|
189
222
|
export async function fetchAllMaybeFeePreset(
|
|
190
223
|
rpc: Parameters<typeof fetchEncodedAccounts>[0],
|
|
191
224
|
addresses: Array<Address>,
|
|
192
225
|
config?: FetchAccountsConfig,
|
|
193
226
|
): Promise<MaybeAccount<FeePreset>[]> {
|
|
194
227
|
const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config);
|
|
195
|
-
return maybeAccounts.map((maybeAccount) =>
|
|
228
|
+
return maybeAccounts.map((maybeAccount) =>
|
|
229
|
+
decodeFeePreset(
|
|
230
|
+
accountIsCreated(maybeAccount)
|
|
231
|
+
? maybeAccount
|
|
232
|
+
: { address: maybeAccount.address, exists: false },
|
|
233
|
+
),
|
|
234
|
+
);
|
|
196
235
|
}
|
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
type ReadonlyUint8Array,
|
|
41
41
|
} from '@solana/kit';
|
|
42
42
|
import { SEND_NEXUS_PROGRAM_ADDRESS } from '../programs/index.js';
|
|
43
|
+
import { accountIsCreated } from '../shared/index.js';
|
|
43
44
|
import {
|
|
44
45
|
getAuthPlatformEntryDecoder,
|
|
45
46
|
getAuthPlatformEntryEncoder,
|
|
@@ -110,9 +111,25 @@ export function getGlobalConfigCodec(): Codec<GlobalConfigArgs, GlobalConfig> {
|
|
|
110
111
|
return combineCodec(getGlobalConfigEncoder(), getGlobalConfigDecoder());
|
|
111
112
|
}
|
|
112
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Decodes a `GlobalConfig` account, throwing when another program owns it or its discriminator
|
|
116
|
+
* does not match.
|
|
117
|
+
*
|
|
118
|
+
* Unlike {@link fetchMaybeGlobalConfig}, this throws for an address that only holds lamports rather
|
|
119
|
+
* than returning the non-existing variant: an account passed as existing must never come back as that
|
|
120
|
+
* variant typed as an `Account`. Apply {@link accountIsCreated} first to accounts fetched another way.
|
|
121
|
+
*/
|
|
113
122
|
export function decodeGlobalConfig<TAddress extends string = string>(
|
|
114
123
|
encodedAccount: EncodedAccount<TAddress>,
|
|
115
124
|
): Account<GlobalConfig, TAddress>;
|
|
125
|
+
/**
|
|
126
|
+
* Decodes a `GlobalConfig` account, throwing when another program owns it or its discriminator
|
|
127
|
+
* does not match.
|
|
128
|
+
*
|
|
129
|
+
* Unlike {@link fetchMaybeGlobalConfig}, this throws for an address that only holds lamports rather
|
|
130
|
+
* than returning the non-existing variant: an account passed as existing must never come back as that
|
|
131
|
+
* variant typed as an `Account`. Apply {@link accountIsCreated} first to accounts fetched another way.
|
|
132
|
+
*/
|
|
116
133
|
export function decodeGlobalConfig<TAddress extends string = string>(
|
|
117
134
|
encodedAccount: MaybeEncodedAccount<TAddress>,
|
|
118
135
|
): MaybeAccount<GlobalConfig, TAddress>;
|
|
@@ -143,6 +160,7 @@ export function decodeGlobalConfig<TAddress extends string = string>(
|
|
|
143
160
|
);
|
|
144
161
|
}
|
|
145
162
|
|
|
163
|
+
/** Fetches a `GlobalConfig` account, throwing when it does not exist or only holds lamports. */
|
|
146
164
|
export async function fetchGlobalConfig<TAddress extends string = string>(
|
|
147
165
|
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
148
166
|
address: Address<TAddress>,
|
|
@@ -153,15 +171,25 @@ export async function fetchGlobalConfig<TAddress extends string = string>(
|
|
|
153
171
|
return maybeAccount;
|
|
154
172
|
}
|
|
155
173
|
|
|
174
|
+
/**
|
|
175
|
+
* Fetches a `GlobalConfig` account, or the non-existing variant when the address holds no
|
|
176
|
+
* account or only lamports (see {@link accountIsCreated}).
|
|
177
|
+
* {@link decodeGlobalConfig} throws for a lamports-only account instead.
|
|
178
|
+
*/
|
|
156
179
|
export async function fetchMaybeGlobalConfig<TAddress extends string = string>(
|
|
157
180
|
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
158
181
|
address: Address<TAddress>,
|
|
159
182
|
config?: FetchAccountConfig,
|
|
160
183
|
): Promise<MaybeAccount<GlobalConfig, TAddress>> {
|
|
161
184
|
const maybeAccount = await fetchEncodedAccount(rpc, address, config);
|
|
162
|
-
return decodeGlobalConfig(
|
|
185
|
+
return decodeGlobalConfig(
|
|
186
|
+
accountIsCreated(maybeAccount)
|
|
187
|
+
? maybeAccount
|
|
188
|
+
: { address, exists: false },
|
|
189
|
+
);
|
|
163
190
|
}
|
|
164
191
|
|
|
192
|
+
/** Fetches `GlobalConfig` accounts, throwing when any does not exist or only holds lamports. */
|
|
165
193
|
export async function fetchAllGlobalConfig(
|
|
166
194
|
rpc: Parameters<typeof fetchEncodedAccounts>[0],
|
|
167
195
|
addresses: Array<Address>,
|
|
@@ -176,6 +204,11 @@ export async function fetchAllGlobalConfig(
|
|
|
176
204
|
return maybeAccounts;
|
|
177
205
|
}
|
|
178
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Fetches `GlobalConfig` accounts, with the non-existing variant for each address that holds
|
|
209
|
+
* no account or only lamports (see {@link accountIsCreated}).
|
|
210
|
+
* {@link decodeGlobalConfig} throws for a lamports-only account instead.
|
|
211
|
+
*/
|
|
179
212
|
export async function fetchAllMaybeGlobalConfig(
|
|
180
213
|
rpc: Parameters<typeof fetchEncodedAccounts>[0],
|
|
181
214
|
addresses: Array<Address>,
|
|
@@ -183,6 +216,10 @@ export async function fetchAllMaybeGlobalConfig(
|
|
|
183
216
|
): Promise<MaybeAccount<GlobalConfig>[]> {
|
|
184
217
|
const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config);
|
|
185
218
|
return maybeAccounts.map((maybeAccount) =>
|
|
186
|
-
decodeGlobalConfig(
|
|
219
|
+
decodeGlobalConfig(
|
|
220
|
+
accountIsCreated(maybeAccount)
|
|
221
|
+
? maybeAccount
|
|
222
|
+
: { address: maybeAccount.address, exists: false },
|
|
223
|
+
),
|
|
187
224
|
);
|
|
188
225
|
}
|