@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
|
@@ -42,7 +42,11 @@ import {
|
|
|
42
42
|
getAddressFromResolvedInstructionAccount,
|
|
43
43
|
type ResolvedInstructionAccount,
|
|
44
44
|
} from '@solana/kit/program-client-core';
|
|
45
|
-
import {
|
|
45
|
+
import {
|
|
46
|
+
EVENT_AUTHORITY_PDA_ADDRESS,
|
|
47
|
+
findCreatorFeeConfigPda,
|
|
48
|
+
findPoolPda,
|
|
49
|
+
} from '../pdas/index.js';
|
|
46
50
|
import { SEND_DEX_PROGRAM_ADDRESS } from '../programs/index.js';
|
|
47
51
|
|
|
48
52
|
export const CLAIM_CREATOR_FEES_DISCRIMINATOR: ReadonlyUint8Array =
|
|
@@ -93,7 +97,7 @@ export type ClaimCreatorFeesInstruction<
|
|
|
93
97
|
? WritableAccount<TAccountPool>
|
|
94
98
|
: TAccountPool,
|
|
95
99
|
TAccountCreatorFeeConfig extends string
|
|
96
|
-
?
|
|
100
|
+
? WritableAccount<TAccountCreatorFeeConfig>
|
|
97
101
|
: TAccountCreatorFeeConfig,
|
|
98
102
|
TAccountNexusGlobalConfig extends string
|
|
99
103
|
? ReadonlyAccount<TAccountNexusGlobalConfig>
|
|
@@ -181,7 +185,7 @@ export type ClaimCreatorFeesAsyncInput<
|
|
|
181
185
|
claimer: TransactionSigner<TAccountClaimer>;
|
|
182
186
|
payer: TransactionSigner<TAccountPayer>;
|
|
183
187
|
pool?: Address<TAccountPool>;
|
|
184
|
-
creatorFeeConfig
|
|
188
|
+
creatorFeeConfig?: Address<TAccountCreatorFeeConfig>;
|
|
185
189
|
baseMint: Address<TAccountBaseMint>;
|
|
186
190
|
quoteMint: Address<TAccountQuoteMint>;
|
|
187
191
|
quoteVault?: Address<TAccountQuoteVault>;
|
|
@@ -244,7 +248,7 @@ export async function getClaimCreatorFeesInstructionAsync<
|
|
|
244
248
|
pool: { value: input.pool ?? null, isWritable: true },
|
|
245
249
|
creatorFeeConfig: {
|
|
246
250
|
value: input.creatorFeeConfig ?? null,
|
|
247
|
-
isWritable:
|
|
251
|
+
isWritable: true,
|
|
248
252
|
},
|
|
249
253
|
nexusGlobalConfig: { value: null, isWritable: false },
|
|
250
254
|
baseMint: { value: input.baseMint ?? null, isWritable: false },
|
|
@@ -282,6 +286,18 @@ export async function getClaimCreatorFeesInstructionAsync<
|
|
|
282
286
|
),
|
|
283
287
|
});
|
|
284
288
|
}
|
|
289
|
+
if (!accounts.creatorFeeConfig.value) {
|
|
290
|
+
accounts.creatorFeeConfig.value = await findCreatorFeeConfigPda({
|
|
291
|
+
baseMint: getAddressFromResolvedInstructionAccount(
|
|
292
|
+
'baseMint',
|
|
293
|
+
accounts.baseMint.value,
|
|
294
|
+
),
|
|
295
|
+
quoteMint: getAddressFromResolvedInstructionAccount(
|
|
296
|
+
'quoteMint',
|
|
297
|
+
accounts.quoteMint.value,
|
|
298
|
+
),
|
|
299
|
+
});
|
|
300
|
+
}
|
|
285
301
|
if (!accounts.nexusGlobalConfig.value) {
|
|
286
302
|
accounts.nexusGlobalConfig.value =
|
|
287
303
|
'3bycfBeRULfXYqcg3DmiYFBjv6mMVidMuqKdFZJTGdNr' as Address<'3bycfBeRULfXYqcg3DmiYFBjv6mMVidMuqKdFZJTGdNr'>;
|
|
@@ -474,7 +490,7 @@ export function getClaimCreatorFeesInstruction<
|
|
|
474
490
|
pool: { value: input.pool ?? null, isWritable: true },
|
|
475
491
|
creatorFeeConfig: {
|
|
476
492
|
value: input.creatorFeeConfig ?? null,
|
|
477
|
-
isWritable:
|
|
493
|
+
isWritable: true,
|
|
478
494
|
},
|
|
479
495
|
nexusGlobalConfig: { value: null, isWritable: false },
|
|
480
496
|
baseMint: { value: input.baseMint ?? null, isWritable: false },
|
|
@@ -13,10 +13,10 @@ import {
|
|
|
13
13
|
type Address,
|
|
14
14
|
type ProgramDerivedAddress,
|
|
15
15
|
} from '@solana/kit';
|
|
16
|
-
import {
|
|
16
|
+
import { SEND_DEX_PROGRAM_ADDRESS } from '../programs/index.js';
|
|
17
17
|
|
|
18
18
|
export type CreatorFeeConfigSeeds = {
|
|
19
|
-
|
|
19
|
+
baseMint: Address;
|
|
20
20
|
quoteMint: Address;
|
|
21
21
|
};
|
|
22
22
|
|
|
@@ -24,15 +24,15 @@ export async function findCreatorFeeConfigPda(
|
|
|
24
24
|
seeds: CreatorFeeConfigSeeds,
|
|
25
25
|
): Promise<ProgramDerivedAddress> {
|
|
26
26
|
return await getProgramDerivedAddress({
|
|
27
|
-
programAddress:
|
|
27
|
+
programAddress: SEND_DEX_PROGRAM_ADDRESS,
|
|
28
28
|
seeds: [
|
|
29
29
|
getBytesEncoder().encode(
|
|
30
30
|
new Uint8Array([
|
|
31
|
-
99, 114, 101, 97, 116, 111, 114, 95, 102, 101, 101, 95,
|
|
32
|
-
|
|
31
|
+
99, 114, 101, 97, 116, 111, 114, 95, 102, 101, 101, 95, 99,
|
|
32
|
+
111, 110, 102, 105, 103,
|
|
33
33
|
]),
|
|
34
34
|
),
|
|
35
|
-
getAddressEncoder().encode(seeds.
|
|
35
|
+
getAddressEncoder().encode(seeds.baseMint),
|
|
36
36
|
getAddressEncoder().encode(seeds.quoteMint),
|
|
37
37
|
],
|
|
38
38
|
});
|
|
@@ -70,6 +70,7 @@ import {
|
|
|
70
70
|
type SellExactOutAsyncInput,
|
|
71
71
|
} from '../instructions/index.js';
|
|
72
72
|
import {
|
|
73
|
+
findCreatorFeeConfigPda,
|
|
73
74
|
findEventAuthorityPda,
|
|
74
75
|
findGlobalConfigPda,
|
|
75
76
|
findLpMintPda,
|
|
@@ -135,6 +136,7 @@ export type SendDexPluginInstructions = {
|
|
|
135
136
|
export type SendDexPluginPdas = {
|
|
136
137
|
pool: typeof findPoolPda;
|
|
137
138
|
eventAuthority: typeof findEventAuthorityPda;
|
|
139
|
+
creatorFeeConfig: typeof findCreatorFeeConfigPda;
|
|
138
140
|
rewardAccrual: typeof findRewardAccrualPda;
|
|
139
141
|
globalConfig: typeof findGlobalConfigPda;
|
|
140
142
|
lpMint: typeof findLpMintPda;
|
|
@@ -266,6 +268,7 @@ export function sendDexProgram() {
|
|
|
266
268
|
pdas: {
|
|
267
269
|
pool: findPoolPda,
|
|
268
270
|
eventAuthority: findEventAuthorityPda,
|
|
271
|
+
creatorFeeConfig: findCreatorFeeConfigPda,
|
|
269
272
|
rewardAccrual: findRewardAccrualPda,
|
|
270
273
|
globalConfig: findGlobalConfigPda,
|
|
271
274
|
lpMint: findLpMintPda,
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This code was AUTOGENERATED using the Codama library.
|
|
3
|
+
* Please DO NOT EDIT THIS FILE, instead use visitors
|
|
4
|
+
* to add features, then rerun Codama to update it.
|
|
5
|
+
*
|
|
6
|
+
* @see https://github.com/codama-idl/codama
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { Address, EncodedAccount, MaybeEncodedAccount } from '@solana/kit';
|
|
10
|
+
|
|
11
|
+
/** The System Program, which owns every address nobody has created an account at yet. */
|
|
12
|
+
const SYSTEM_PROGRAM_ADDRESS =
|
|
13
|
+
'11111111111111111111111111111111' as Address<'11111111111111111111111111111111'>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Whether an encoded account was created on-chain, rather than merely sent lamports.
|
|
17
|
+
*
|
|
18
|
+
* Anyone can send lamports to an address before its account is created, which leaves it on-chain,
|
|
19
|
+
* owned by the System Program, with no data. This returns `false` for that shape, as it does for an
|
|
20
|
+
* account that does not exist. Any other existing account counts as created, whoever owns it; the
|
|
21
|
+
* `decode*` functions still check the owner.
|
|
22
|
+
*
|
|
23
|
+
* The generated `fetchMaybe*` and `fetchAllMaybe*` helpers apply this rule themselves. Apply it to
|
|
24
|
+
* accounts you fetch or receive another way (subscriptions, batch loaders, caches) before passing
|
|
25
|
+
* them to a `decode*` function, which throws for a lamports-only account: an account passed to it as
|
|
26
|
+
* existing must never come back as the non-existing variant typed as an `Account`.
|
|
27
|
+
*
|
|
28
|
+
* Only a `true` result narrows the type. A lamports-only account is still `exists: true` at runtime,
|
|
29
|
+
* so a `false` result leaves the type unchanged instead of narrowing it to the non-existing variant.
|
|
30
|
+
* The `uncreated` property in the narrowed type is never present; it exists only to prevent that.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* const maybeAccount = decodeMyAccount(
|
|
35
|
+
* accountIsCreated(encodedAccount) ? encodedAccount : { address: encodedAccount.address, exists: false },
|
|
36
|
+
* );
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export function accountIsCreated<
|
|
40
|
+
TAccount extends EncodedAccount | MaybeEncodedAccount,
|
|
41
|
+
>(
|
|
42
|
+
account: TAccount,
|
|
43
|
+
): account is Exclude<TAccount, { readonly exists: false }> & {
|
|
44
|
+
readonly uncreated?: never;
|
|
45
|
+
} {
|
|
46
|
+
const maybeAccount: EncodedAccount | MaybeEncodedAccount = account;
|
|
47
|
+
if ('exists' in maybeAccount && !maybeAccount.exists) return false;
|
|
48
|
+
return !(
|
|
49
|
+
maybeAccount.programAddress === SYSTEM_PROGRAM_ADDRESS &&
|
|
50
|
+
maybeAccount.data.length === 0
|
|
51
|
+
);
|
|
52
|
+
}
|
package/src/dex/trade.ts
CHANGED
|
@@ -19,7 +19,7 @@ export interface DexTradeParams {
|
|
|
19
19
|
partner: PartnerInput;
|
|
20
20
|
platformConfig: Address;
|
|
21
21
|
quoteTokenProgram: Address;
|
|
22
|
-
/**
|
|
22
|
+
/** The quote mint's transfer fee for the epoch the trade lands in. A missing or old fee gives wrong slippage bounds. */
|
|
23
23
|
quoteFee?: MintFee;
|
|
24
24
|
baseFee?: MintFee;
|
|
25
25
|
/** {@inheritDoc DexInstructionParams.userQuoteAccount} */
|
|
@@ -36,16 +36,15 @@ export interface DexInstructionParams {
|
|
|
36
36
|
partner: PartnerInput;
|
|
37
37
|
platformConfig: Address;
|
|
38
38
|
quoteTokenProgram: Address;
|
|
39
|
-
/** Any
|
|
40
|
-
*
|
|
41
|
-
* a throwaway `createAccountWithSeed` account is cheaper. */
|
|
39
|
+
/** Any quote-mint token account that `user` owns. Defaults to the user's ATA.
|
|
40
|
+
* The program creates a missing ATA, and `payer` pays the rent. */
|
|
42
41
|
userQuoteAccount?: Address;
|
|
43
|
-
/** Any
|
|
44
|
-
*
|
|
42
|
+
/** Any base-mint token account that `user` owns. Defaults to the user's ATA.
|
|
43
|
+
* The program creates a missing ATA, and `payer` pays the rent. */
|
|
45
44
|
userBaseAccount?: Address;
|
|
46
45
|
}
|
|
47
46
|
|
|
48
|
-
/** `baseAmountOut` is
|
|
47
|
+
/** `baseAmountOut` is the base the buyer receives, after the base mint's transfer fee. */
|
|
49
48
|
export async function buyExactOut(
|
|
50
49
|
params: DexTradeParams & { baseAmountOut: bigint },
|
|
51
50
|
): Promise<{ instruction: Instruction; quote: BuyQuote }> {
|
|
@@ -57,7 +56,7 @@ export async function buyExactOut(
|
|
|
57
56
|
quoteFee: params.quoteFee,
|
|
58
57
|
baseFee: params.baseFee,
|
|
59
58
|
});
|
|
60
|
-
// The
|
|
59
|
+
// The program checks `maxAmountIn` against the gross the buyer sends, quote transfer fee included.
|
|
61
60
|
const maxQuoteIn = amm.calculateSlippageUp(
|
|
62
61
|
quote.quoteFromUser,
|
|
63
62
|
params.slippageBps,
|
|
@@ -83,7 +82,7 @@ export async function buyExactIn(
|
|
|
83
82
|
quoteFee: params.quoteFee,
|
|
84
83
|
baseFee: params.baseFee,
|
|
85
84
|
});
|
|
86
|
-
// The
|
|
85
|
+
// The program checks `minAmountOut` against what the buyer receives, not the vault's debit.
|
|
87
86
|
const minBaseOut = amm.calculateSlippageDown(
|
|
88
87
|
quote.baseToUser,
|
|
89
88
|
params.slippageBps,
|
|
@@ -109,7 +108,7 @@ export async function sellExactIn(
|
|
|
109
108
|
quoteFee: params.quoteFee,
|
|
110
109
|
baseFee: params.baseFee,
|
|
111
110
|
});
|
|
112
|
-
// The
|
|
111
|
+
// The program checks `minAmountOut` against what the seller receives, not the vault's debit.
|
|
113
112
|
const minQuoteOut = amm.calculateSlippageDown(
|
|
114
113
|
quote.quoteToUser,
|
|
115
114
|
params.slippageBps,
|
|
@@ -124,7 +123,7 @@ export async function sellExactIn(
|
|
|
124
123
|
};
|
|
125
124
|
}
|
|
126
125
|
|
|
127
|
-
/** `quoteAmountOut` is
|
|
126
|
+
/** `quoteAmountOut` is the quote the seller receives, after the quote mint's transfer fee. */
|
|
128
127
|
export async function sellExactOut(
|
|
129
128
|
params: DexTradeParams & { quoteAmountOut: bigint },
|
|
130
129
|
): Promise<{ instruction: Instruction; quote: SellQuote }> {
|
|
@@ -136,7 +135,7 @@ export async function sellExactOut(
|
|
|
136
135
|
quoteFee: params.quoteFee,
|
|
137
136
|
baseFee: params.baseFee,
|
|
138
137
|
});
|
|
139
|
-
// The
|
|
138
|
+
// The program checks `maxAmountIn` against the gross the seller sends, base transfer fee included.
|
|
140
139
|
const maxBaseIn = amm.calculateSlippageUp(
|
|
141
140
|
quote.baseFromUser,
|
|
142
141
|
params.slippageBps,
|
|
@@ -204,7 +203,7 @@ function resolveSharedAccounts(params: DexInstructionParams) {
|
|
|
204
203
|
partner: params.partner,
|
|
205
204
|
platformConfig: params.platformConfig,
|
|
206
205
|
quoteTokenProgram: params.quoteTokenProgram,
|
|
207
|
-
//
|
|
206
|
+
// When omitted, the generated client derives the ATA.
|
|
208
207
|
...(params.userQuoteAccount !== undefined && {
|
|
209
208
|
userQuoteAccount: params.userQuoteAccount,
|
|
210
209
|
}),
|
package/src/launchpad/create.ts
CHANGED
|
@@ -1,27 +1,26 @@
|
|
|
1
1
|
import type { Address, Instruction, TransactionSigner } from '@solana/kit';
|
|
2
2
|
import type { MintFee, TradeQuote } from '../math/amm.js';
|
|
3
3
|
import type { PartnerInput } from '../utils/partner.js';
|
|
4
|
-
import { creatorHashFromId } from '../utils/creator-hash.js';
|
|
5
|
-
import { findCreatorFeeConfigPda } from '../nexus/generated/pdas/creatorFeeConfig.js';
|
|
6
4
|
import { getCreateTokenInstructionAsync } from './generated/instructions/createToken.js';
|
|
7
5
|
import { buyExactIn } from './trade.js';
|
|
8
6
|
|
|
9
7
|
export interface CreateTokenParams {
|
|
10
8
|
user: TransactionSigner;
|
|
11
9
|
payer?: TransactionSigner;
|
|
10
|
+
/** The wallet that claims the creator fees. */
|
|
12
11
|
coinCreator: Address;
|
|
13
12
|
baseMint: TransactionSigner;
|
|
14
13
|
quoteMint: Address;
|
|
15
14
|
name: string;
|
|
16
15
|
symbol: string;
|
|
17
16
|
uri: string;
|
|
18
|
-
/** An enabled nexus auth platform (e.g. "wallet"), max 32 bytes; hashed with
|
|
19
|
-
* `creatorId` into the creator fee identity. Unrelated to `platformConfig`. */
|
|
20
|
-
creatorPlatform: string;
|
|
21
|
-
creatorId: string;
|
|
22
17
|
partner: PartnerInput;
|
|
23
18
|
platformConfig: Address;
|
|
24
19
|
quoteTokenProgram: Address;
|
|
20
|
+
creatorFeeMode: number;
|
|
21
|
+
creatorFeeBps: number;
|
|
22
|
+
/** The creator fee of the pool after migration, in bps. */
|
|
23
|
+
dexCreatorFeeBps: number;
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
export interface CreateAndBuyParams extends CreateTokenParams {
|
|
@@ -30,62 +29,39 @@ export interface CreateAndBuyParams extends CreateTokenParams {
|
|
|
30
29
|
slippageBps: number;
|
|
31
30
|
initialVirtualQuoteReserves: bigint;
|
|
32
31
|
initialVirtualBaseReserves: bigint;
|
|
33
|
-
/** `globalConfig.initialRealBaseReserves
|
|
32
|
+
/** `globalConfig.initialRealBaseReserves`. Caps the buy. */
|
|
34
33
|
initialRealBaseReserves: bigint;
|
|
35
|
-
/**
|
|
36
|
-
* ignores the mint's cut, and a cut above `slippageBps` can
|
|
37
|
-
*
|
|
34
|
+
/** The quote mint's transfer fee for the epoch the launch lands in. Without it, `minAmountOut`
|
|
35
|
+
* ignores the mint's cut, and a cut above `slippageBps` can make the buy fail. The new base
|
|
36
|
+
* mint has no transfer fee. */
|
|
38
37
|
quoteFee?: MintFee;
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
export async function buildCreateTokenInstruction(
|
|
42
41
|
params: CreateTokenParams,
|
|
43
42
|
): Promise<Instruction> {
|
|
44
|
-
return buildCreateTokenInstructionWithHash(
|
|
45
|
-
params,
|
|
46
|
-
await creatorHashFromId(params.creatorPlatform, params.creatorId),
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
async function buildCreateTokenInstructionWithHash(
|
|
51
|
-
params: CreateTokenParams,
|
|
52
|
-
creatorHash: Address,
|
|
53
|
-
): Promise<Instruction> {
|
|
54
|
-
const [creatorFeeConfig] = await findCreatorFeeConfigPda({
|
|
55
|
-
creatorHash,
|
|
56
|
-
quoteMint: params.quoteMint,
|
|
57
|
-
});
|
|
58
|
-
// The creation fee is native SOL from `user`; the client derives the WSOL staking vault.
|
|
59
43
|
return getCreateTokenInstructionAsync({
|
|
60
44
|
user: params.user,
|
|
61
45
|
payer: params.payer ?? params.user,
|
|
62
46
|
coinCreator: params.coinCreator,
|
|
63
47
|
baseMint: params.baseMint,
|
|
64
48
|
quoteMint: params.quoteMint,
|
|
65
|
-
creatorFeeConfig,
|
|
66
49
|
partner: params.partner,
|
|
67
50
|
platformConfig: params.platformConfig,
|
|
68
51
|
quoteTokenProgram: params.quoteTokenProgram,
|
|
69
|
-
creatorPlatform: params.creatorPlatform,
|
|
70
|
-
creatorId: params.creatorId,
|
|
71
|
-
creatorHash,
|
|
72
52
|
name: params.name,
|
|
73
53
|
symbol: params.symbol,
|
|
74
54
|
uri: params.uri,
|
|
55
|
+
creatorFeeMode: params.creatorFeeMode,
|
|
56
|
+
creatorFeeBps: params.creatorFeeBps,
|
|
57
|
+
dexCreatorFeeBps: params.dexCreatorFeeBps,
|
|
75
58
|
});
|
|
76
59
|
}
|
|
77
60
|
|
|
78
61
|
export async function buildCreateAndBuyInstructions(
|
|
79
62
|
params: CreateAndBuyParams,
|
|
80
63
|
): Promise<{ instructions: Instruction[]; quote?: TradeQuote }> {
|
|
81
|
-
const
|
|
82
|
-
params.creatorPlatform,
|
|
83
|
-
params.creatorId,
|
|
84
|
-
);
|
|
85
|
-
const createIx = await buildCreateTokenInstructionWithHash(
|
|
86
|
-
params,
|
|
87
|
-
creatorHash,
|
|
88
|
-
);
|
|
64
|
+
const createIx = await buildCreateTokenInstruction(params);
|
|
89
65
|
const instructions: Instruction[] = [createIx];
|
|
90
66
|
let quote: TradeQuote | undefined;
|
|
91
67
|
|
|
@@ -98,7 +74,6 @@ export async function buildCreateAndBuyInstructions(
|
|
|
98
74
|
virtualQuoteReserves: params.initialVirtualQuoteReserves,
|
|
99
75
|
virtualBaseReserves: params.initialVirtualBaseReserves,
|
|
100
76
|
realBaseReserves: params.initialRealBaseReserves,
|
|
101
|
-
// The curve was just stamped with this same key.
|
|
102
77
|
platformConfig: params.platformConfig,
|
|
103
78
|
feeBps: params.feeBps,
|
|
104
79
|
slippageBps: params.slippageBps,
|
|
@@ -18,12 +18,16 @@ import {
|
|
|
18
18
|
fixEncoderSize,
|
|
19
19
|
getAddressDecoder,
|
|
20
20
|
getAddressEncoder,
|
|
21
|
+
getArrayDecoder,
|
|
22
|
+
getArrayEncoder,
|
|
21
23
|
getBytesDecoder,
|
|
22
24
|
getBytesEncoder,
|
|
23
25
|
getI64Decoder,
|
|
24
26
|
getI64Encoder,
|
|
25
27
|
getStructDecoder,
|
|
26
28
|
getStructEncoder,
|
|
29
|
+
getU16Decoder,
|
|
30
|
+
getU16Encoder,
|
|
27
31
|
getU64Decoder,
|
|
28
32
|
getU64Encoder,
|
|
29
33
|
getU8Decoder,
|
|
@@ -42,6 +46,7 @@ import {
|
|
|
42
46
|
type ReadonlyUint8Array,
|
|
43
47
|
} from '@solana/kit';
|
|
44
48
|
import { SEND_LAUNCHPAD_PROGRAM_ADDRESS } from '../programs/index.js';
|
|
49
|
+
import { accountIsCreated } from '../shared/index.js';
|
|
45
50
|
import {
|
|
46
51
|
getBondingCurveStatusDecoder,
|
|
47
52
|
getBondingCurveStatusEncoder,
|
|
@@ -73,7 +78,7 @@ export type BondingCurve = {
|
|
|
73
78
|
quoteMint: Address;
|
|
74
79
|
quoteDecimals: number;
|
|
75
80
|
coinCreator: Address;
|
|
76
|
-
|
|
81
|
+
padding0: Array<bigint>;
|
|
77
82
|
partner: Address;
|
|
78
83
|
baseVault: Address;
|
|
79
84
|
quoteVault: Address;
|
|
@@ -85,6 +90,9 @@ export type BondingCurve = {
|
|
|
85
90
|
protocolOwed: bigint;
|
|
86
91
|
creatorOwed: bigint;
|
|
87
92
|
platformConfig: Address;
|
|
93
|
+
creatorFeeMode: number;
|
|
94
|
+
creatorFeeBps: number;
|
|
95
|
+
dexCreatorFeeBps: number;
|
|
88
96
|
reserved: ReadonlyUint8Array;
|
|
89
97
|
};
|
|
90
98
|
|
|
@@ -101,7 +109,7 @@ export type BondingCurveArgs = {
|
|
|
101
109
|
quoteMint: Address;
|
|
102
110
|
quoteDecimals: number;
|
|
103
111
|
coinCreator: Address;
|
|
104
|
-
|
|
112
|
+
padding0: Array<number | bigint>;
|
|
105
113
|
partner: Address;
|
|
106
114
|
baseVault: Address;
|
|
107
115
|
quoteVault: Address;
|
|
@@ -113,6 +121,9 @@ export type BondingCurveArgs = {
|
|
|
113
121
|
protocolOwed: number | bigint;
|
|
114
122
|
creatorOwed: number | bigint;
|
|
115
123
|
platformConfig: Address;
|
|
124
|
+
creatorFeeMode: number;
|
|
125
|
+
creatorFeeBps: number;
|
|
126
|
+
dexCreatorFeeBps: number;
|
|
116
127
|
reserved: ReadonlyUint8Array;
|
|
117
128
|
};
|
|
118
129
|
|
|
@@ -133,7 +144,7 @@ export function getBondingCurveEncoder(): FixedSizeEncoder<BondingCurveArgs> {
|
|
|
133
144
|
['quoteMint', getAddressEncoder()],
|
|
134
145
|
['quoteDecimals', getU8Encoder()],
|
|
135
146
|
['coinCreator', getAddressEncoder()],
|
|
136
|
-
['
|
|
147
|
+
['padding0', getArrayEncoder(getU64Encoder(), { size: 4 })],
|
|
137
148
|
['partner', getAddressEncoder()],
|
|
138
149
|
['baseVault', getAddressEncoder()],
|
|
139
150
|
['quoteVault', getAddressEncoder()],
|
|
@@ -145,7 +156,10 @@ export function getBondingCurveEncoder(): FixedSizeEncoder<BondingCurveArgs> {
|
|
|
145
156
|
['protocolOwed', getU64Encoder()],
|
|
146
157
|
['creatorOwed', getU64Encoder()],
|
|
147
158
|
['platformConfig', getAddressEncoder()],
|
|
148
|
-
['
|
|
159
|
+
['creatorFeeMode', getU8Encoder()],
|
|
160
|
+
['creatorFeeBps', getU16Encoder()],
|
|
161
|
+
['dexCreatorFeeBps', getU16Encoder()],
|
|
162
|
+
['reserved', fixEncoderSize(getBytesEncoder(), 256)],
|
|
149
163
|
]),
|
|
150
164
|
(value) => ({ ...value, discriminator: BONDING_CURVE_DISCRIMINATOR }),
|
|
151
165
|
);
|
|
@@ -167,7 +181,7 @@ export function getBondingCurveDecoder(): FixedSizeDecoder<BondingCurve> {
|
|
|
167
181
|
['quoteMint', getAddressDecoder()],
|
|
168
182
|
['quoteDecimals', getU8Decoder()],
|
|
169
183
|
['coinCreator', getAddressDecoder()],
|
|
170
|
-
['
|
|
184
|
+
['padding0', getArrayDecoder(getU64Decoder(), { size: 4 })],
|
|
171
185
|
['partner', getAddressDecoder()],
|
|
172
186
|
['baseVault', getAddressDecoder()],
|
|
173
187
|
['quoteVault', getAddressDecoder()],
|
|
@@ -179,7 +193,10 @@ export function getBondingCurveDecoder(): FixedSizeDecoder<BondingCurve> {
|
|
|
179
193
|
['protocolOwed', getU64Decoder()],
|
|
180
194
|
['creatorOwed', getU64Decoder()],
|
|
181
195
|
['platformConfig', getAddressDecoder()],
|
|
182
|
-
['
|
|
196
|
+
['creatorFeeMode', getU8Decoder()],
|
|
197
|
+
['creatorFeeBps', getU16Decoder()],
|
|
198
|
+
['dexCreatorFeeBps', getU16Decoder()],
|
|
199
|
+
['reserved', fixDecoderSize(getBytesDecoder(), 256)],
|
|
183
200
|
]);
|
|
184
201
|
}
|
|
185
202
|
|
|
@@ -191,9 +208,25 @@ export function getBondingCurveCodec(): FixedSizeCodec<
|
|
|
191
208
|
return combineCodec(getBondingCurveEncoder(), getBondingCurveDecoder());
|
|
192
209
|
}
|
|
193
210
|
|
|
211
|
+
/**
|
|
212
|
+
* Decodes a `BondingCurve` account, throwing when another program owns it or its discriminator
|
|
213
|
+
* does not match.
|
|
214
|
+
*
|
|
215
|
+
* Unlike {@link fetchMaybeBondingCurve}, this throws for an address that only holds lamports rather
|
|
216
|
+
* than returning the non-existing variant: an account passed as existing must never come back as that
|
|
217
|
+
* variant typed as an `Account`. Apply {@link accountIsCreated} first to accounts fetched another way.
|
|
218
|
+
*/
|
|
194
219
|
export function decodeBondingCurve<TAddress extends string = string>(
|
|
195
220
|
encodedAccount: EncodedAccount<TAddress>,
|
|
196
221
|
): Account<BondingCurve, TAddress>;
|
|
222
|
+
/**
|
|
223
|
+
* Decodes a `BondingCurve` account, throwing when another program owns it or its discriminator
|
|
224
|
+
* does not match.
|
|
225
|
+
*
|
|
226
|
+
* Unlike {@link fetchMaybeBondingCurve}, this throws for an address that only holds lamports rather
|
|
227
|
+
* than returning the non-existing variant: an account passed as existing must never come back as that
|
|
228
|
+
* variant typed as an `Account`. Apply {@link accountIsCreated} first to accounts fetched another way.
|
|
229
|
+
*/
|
|
197
230
|
export function decodeBondingCurve<TAddress extends string = string>(
|
|
198
231
|
encodedAccount: MaybeEncodedAccount<TAddress>,
|
|
199
232
|
): MaybeAccount<BondingCurve, TAddress>;
|
|
@@ -224,6 +257,7 @@ export function decodeBondingCurve<TAddress extends string = string>(
|
|
|
224
257
|
);
|
|
225
258
|
}
|
|
226
259
|
|
|
260
|
+
/** Fetches a `BondingCurve` account, throwing when it does not exist or only holds lamports. */
|
|
227
261
|
export async function fetchBondingCurve<TAddress extends string = string>(
|
|
228
262
|
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
229
263
|
address: Address<TAddress>,
|
|
@@ -234,15 +268,25 @@ export async function fetchBondingCurve<TAddress extends string = string>(
|
|
|
234
268
|
return maybeAccount;
|
|
235
269
|
}
|
|
236
270
|
|
|
271
|
+
/**
|
|
272
|
+
* Fetches a `BondingCurve` account, or the non-existing variant when the address holds no
|
|
273
|
+
* account or only lamports (see {@link accountIsCreated}).
|
|
274
|
+
* {@link decodeBondingCurve} throws for a lamports-only account instead.
|
|
275
|
+
*/
|
|
237
276
|
export async function fetchMaybeBondingCurve<TAddress extends string = string>(
|
|
238
277
|
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
239
278
|
address: Address<TAddress>,
|
|
240
279
|
config?: FetchAccountConfig,
|
|
241
280
|
): Promise<MaybeAccount<BondingCurve, TAddress>> {
|
|
242
281
|
const maybeAccount = await fetchEncodedAccount(rpc, address, config);
|
|
243
|
-
return decodeBondingCurve(
|
|
282
|
+
return decodeBondingCurve(
|
|
283
|
+
accountIsCreated(maybeAccount)
|
|
284
|
+
? maybeAccount
|
|
285
|
+
: { address, exists: false },
|
|
286
|
+
);
|
|
244
287
|
}
|
|
245
288
|
|
|
289
|
+
/** Fetches `BondingCurve` accounts, throwing when any does not exist or only holds lamports. */
|
|
246
290
|
export async function fetchAllBondingCurve(
|
|
247
291
|
rpc: Parameters<typeof fetchEncodedAccounts>[0],
|
|
248
292
|
addresses: Array<Address>,
|
|
@@ -257,6 +301,11 @@ export async function fetchAllBondingCurve(
|
|
|
257
301
|
return maybeAccounts;
|
|
258
302
|
}
|
|
259
303
|
|
|
304
|
+
/**
|
|
305
|
+
* Fetches `BondingCurve` accounts, with the non-existing variant for each address that holds
|
|
306
|
+
* no account or only lamports (see {@link accountIsCreated}).
|
|
307
|
+
* {@link decodeBondingCurve} throws for a lamports-only account instead.
|
|
308
|
+
*/
|
|
260
309
|
export async function fetchAllMaybeBondingCurve(
|
|
261
310
|
rpc: Parameters<typeof fetchEncodedAccounts>[0],
|
|
262
311
|
addresses: Array<Address>,
|
|
@@ -264,10 +313,14 @@ export async function fetchAllMaybeBondingCurve(
|
|
|
264
313
|
): Promise<MaybeAccount<BondingCurve>[]> {
|
|
265
314
|
const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config);
|
|
266
315
|
return maybeAccounts.map((maybeAccount) =>
|
|
267
|
-
decodeBondingCurve(
|
|
316
|
+
decodeBondingCurve(
|
|
317
|
+
accountIsCreated(maybeAccount)
|
|
318
|
+
? maybeAccount
|
|
319
|
+
: { address: maybeAccount.address, exists: false },
|
|
320
|
+
),
|
|
268
321
|
);
|
|
269
322
|
}
|
|
270
323
|
|
|
271
324
|
export function getBondingCurveSize(): number {
|
|
272
|
-
return
|
|
325
|
+
return 618;
|
|
273
326
|
}
|
|
@@ -42,6 +42,7 @@ import {
|
|
|
42
42
|
type ReadonlyUint8Array,
|
|
43
43
|
} from '@solana/kit';
|
|
44
44
|
import { SEND_LAUNCHPAD_PROGRAM_ADDRESS } from '../programs/index.js';
|
|
45
|
+
import { accountIsCreated } from '../shared/index.js';
|
|
45
46
|
|
|
46
47
|
export const GLOBAL_CONFIG_DISCRIMINATOR: ReadonlyUint8Array = new Uint8Array([
|
|
47
48
|
149, 8, 156, 202, 160, 252, 176, 217,
|
|
@@ -129,9 +130,25 @@ export function getGlobalConfigCodec(): FixedSizeCodec<
|
|
|
129
130
|
return combineCodec(getGlobalConfigEncoder(), getGlobalConfigDecoder());
|
|
130
131
|
}
|
|
131
132
|
|
|
133
|
+
/**
|
|
134
|
+
* Decodes a `GlobalConfig` account, throwing when another program owns it or its discriminator
|
|
135
|
+
* does not match.
|
|
136
|
+
*
|
|
137
|
+
* Unlike {@link fetchMaybeGlobalConfig}, this throws for an address that only holds lamports rather
|
|
138
|
+
* than returning the non-existing variant: an account passed as existing must never come back as that
|
|
139
|
+
* variant typed as an `Account`. Apply {@link accountIsCreated} first to accounts fetched another way.
|
|
140
|
+
*/
|
|
132
141
|
export function decodeGlobalConfig<TAddress extends string = string>(
|
|
133
142
|
encodedAccount: EncodedAccount<TAddress>,
|
|
134
143
|
): Account<GlobalConfig, TAddress>;
|
|
144
|
+
/**
|
|
145
|
+
* Decodes a `GlobalConfig` account, throwing when another program owns it or its discriminator
|
|
146
|
+
* does not match.
|
|
147
|
+
*
|
|
148
|
+
* Unlike {@link fetchMaybeGlobalConfig}, this throws for an address that only holds lamports rather
|
|
149
|
+
* than returning the non-existing variant: an account passed as existing must never come back as that
|
|
150
|
+
* variant typed as an `Account`. Apply {@link accountIsCreated} first to accounts fetched another way.
|
|
151
|
+
*/
|
|
135
152
|
export function decodeGlobalConfig<TAddress extends string = string>(
|
|
136
153
|
encodedAccount: MaybeEncodedAccount<TAddress>,
|
|
137
154
|
): MaybeAccount<GlobalConfig, TAddress>;
|
|
@@ -162,6 +179,7 @@ export function decodeGlobalConfig<TAddress extends string = string>(
|
|
|
162
179
|
);
|
|
163
180
|
}
|
|
164
181
|
|
|
182
|
+
/** Fetches a `GlobalConfig` account, throwing when it does not exist or only holds lamports. */
|
|
165
183
|
export async function fetchGlobalConfig<TAddress extends string = string>(
|
|
166
184
|
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
167
185
|
address: Address<TAddress>,
|
|
@@ -172,15 +190,25 @@ export async function fetchGlobalConfig<TAddress extends string = string>(
|
|
|
172
190
|
return maybeAccount;
|
|
173
191
|
}
|
|
174
192
|
|
|
193
|
+
/**
|
|
194
|
+
* Fetches a `GlobalConfig` account, or the non-existing variant when the address holds no
|
|
195
|
+
* account or only lamports (see {@link accountIsCreated}).
|
|
196
|
+
* {@link decodeGlobalConfig} throws for a lamports-only account instead.
|
|
197
|
+
*/
|
|
175
198
|
export async function fetchMaybeGlobalConfig<TAddress extends string = string>(
|
|
176
199
|
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
177
200
|
address: Address<TAddress>,
|
|
178
201
|
config?: FetchAccountConfig,
|
|
179
202
|
): Promise<MaybeAccount<GlobalConfig, TAddress>> {
|
|
180
203
|
const maybeAccount = await fetchEncodedAccount(rpc, address, config);
|
|
181
|
-
return decodeGlobalConfig(
|
|
204
|
+
return decodeGlobalConfig(
|
|
205
|
+
accountIsCreated(maybeAccount)
|
|
206
|
+
? maybeAccount
|
|
207
|
+
: { address, exists: false },
|
|
208
|
+
);
|
|
182
209
|
}
|
|
183
210
|
|
|
211
|
+
/** Fetches `GlobalConfig` accounts, throwing when any does not exist or only holds lamports. */
|
|
184
212
|
export async function fetchAllGlobalConfig(
|
|
185
213
|
rpc: Parameters<typeof fetchEncodedAccounts>[0],
|
|
186
214
|
addresses: Array<Address>,
|
|
@@ -195,6 +223,11 @@ export async function fetchAllGlobalConfig(
|
|
|
195
223
|
return maybeAccounts;
|
|
196
224
|
}
|
|
197
225
|
|
|
226
|
+
/**
|
|
227
|
+
* Fetches `GlobalConfig` accounts, with the non-existing variant for each address that holds
|
|
228
|
+
* no account or only lamports (see {@link accountIsCreated}).
|
|
229
|
+
* {@link decodeGlobalConfig} throws for a lamports-only account instead.
|
|
230
|
+
*/
|
|
198
231
|
export async function fetchAllMaybeGlobalConfig(
|
|
199
232
|
rpc: Parameters<typeof fetchEncodedAccounts>[0],
|
|
200
233
|
addresses: Array<Address>,
|
|
@@ -202,7 +235,11 @@ export async function fetchAllMaybeGlobalConfig(
|
|
|
202
235
|
): Promise<MaybeAccount<GlobalConfig>[]> {
|
|
203
236
|
const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config);
|
|
204
237
|
return maybeAccounts.map((maybeAccount) =>
|
|
205
|
-
decodeGlobalConfig(
|
|
238
|
+
decodeGlobalConfig(
|
|
239
|
+
accountIsCreated(maybeAccount)
|
|
240
|
+
? maybeAccount
|
|
241
|
+
: { address: maybeAccount.address, exists: false },
|
|
242
|
+
),
|
|
206
243
|
);
|
|
207
244
|
}
|
|
208
245
|
|