@send-fun/sdk 1.1.0 → 1.2.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 +526 -98
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +595 -93
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +595 -93
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +526 -98
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/dex/generated/accounts/globalConfig.ts +39 -2
- package/src/dex/generated/accounts/pool.ts +41 -2
- package/src/dex/generated/accounts/rewardAccrual.ts +39 -2
- package/src/dex/generated/index.ts +1 -0
- package/src/dex/generated/shared/index.ts +52 -0
- package/src/dex/trade.ts +12 -13
- package/src/launchpad/create.ts +8 -8
- package/src/launchpad/generated/accounts/bondingCurve.ts +39 -2
- package/src/launchpad/generated/accounts/globalConfig.ts +39 -2
- package/src/launchpad/generated/accounts/rewardAccrual.ts +39 -2
- package/src/launchpad/generated/index.ts +1 -0
- package/src/launchpad/generated/shared/index.ts +52 -0
- package/src/launchpad/migrate.ts +1 -1
- 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 +5 -3
- package/src/nexus/generated/accounts/altRegistry.ts +41 -2
- package/src/nexus/generated/accounts/creatorFeeConfig.ts +39 -2
- package/src/nexus/generated/accounts/feePreset.ts +41 -2
- package/src/nexus/generated/accounts/globalConfig.ts +39 -2
- package/src/nexus/generated/accounts/partnerConfig.ts +39 -2
- package/src/nexus/generated/accounts/partnerMetadata.ts +39 -2
- package/src/nexus/generated/accounts/rewardState.ts +41 -2
- package/src/nexus/generated/accounts/stakingConfig.ts +39 -2
- package/src/nexus/generated/accounts/userRewardDebt.ts +39 -2
- package/src/nexus/generated/accounts/userStakePosition.ts +39 -2
- package/src/nexus/generated/index.ts +1 -0
- package/src/nexus/generated/shared/index.ts +52 -0
- 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/creator-hash.ts +6 -3
- package/src/utils/index.ts +2 -0
- package/src/utils/mint-info.ts +8 -7
- package/src/utils/partner.ts +1 -1
- package/src/utils/pda.ts +1 -1
package/package.json
CHANGED
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
type ReadonlyUint8Array,
|
|
41
41
|
} from '@solana/kit';
|
|
42
42
|
import { SEND_DEX_PROGRAM_ADDRESS } from '../programs/index.js';
|
|
43
|
+
import { accountIsCreated } from '../shared/index.js';
|
|
43
44
|
|
|
44
45
|
export const GLOBAL_CONFIG_DISCRIMINATOR: ReadonlyUint8Array = new Uint8Array([
|
|
45
46
|
149, 8, 156, 202, 160, 252, 176, 217,
|
|
@@ -107,9 +108,25 @@ export function getGlobalConfigCodec(): FixedSizeCodec<
|
|
|
107
108
|
return combineCodec(getGlobalConfigEncoder(), getGlobalConfigDecoder());
|
|
108
109
|
}
|
|
109
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Decodes a `GlobalConfig` account, throwing when another program owns it or its discriminator
|
|
113
|
+
* does not match.
|
|
114
|
+
*
|
|
115
|
+
* Unlike {@link fetchMaybeGlobalConfig}, this throws for an address that only holds lamports rather
|
|
116
|
+
* than returning the non-existing variant: an account passed as existing must never come back as that
|
|
117
|
+
* variant typed as an `Account`. Apply {@link accountIsCreated} first to accounts fetched another way.
|
|
118
|
+
*/
|
|
110
119
|
export function decodeGlobalConfig<TAddress extends string = string>(
|
|
111
120
|
encodedAccount: EncodedAccount<TAddress>,
|
|
112
121
|
): Account<GlobalConfig, TAddress>;
|
|
122
|
+
/**
|
|
123
|
+
* Decodes a `GlobalConfig` account, throwing when another program owns it or its discriminator
|
|
124
|
+
* does not match.
|
|
125
|
+
*
|
|
126
|
+
* Unlike {@link fetchMaybeGlobalConfig}, this throws for an address that only holds lamports rather
|
|
127
|
+
* than returning the non-existing variant: an account passed as existing must never come back as that
|
|
128
|
+
* variant typed as an `Account`. Apply {@link accountIsCreated} first to accounts fetched another way.
|
|
129
|
+
*/
|
|
113
130
|
export function decodeGlobalConfig<TAddress extends string = string>(
|
|
114
131
|
encodedAccount: MaybeEncodedAccount<TAddress>,
|
|
115
132
|
): MaybeAccount<GlobalConfig, TAddress>;
|
|
@@ -140,6 +157,7 @@ export function decodeGlobalConfig<TAddress extends string = string>(
|
|
|
140
157
|
);
|
|
141
158
|
}
|
|
142
159
|
|
|
160
|
+
/** Fetches a `GlobalConfig` account, throwing when it does not exist or only holds lamports. */
|
|
143
161
|
export async function fetchGlobalConfig<TAddress extends string = string>(
|
|
144
162
|
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
145
163
|
address: Address<TAddress>,
|
|
@@ -150,15 +168,25 @@ export async function fetchGlobalConfig<TAddress extends string = string>(
|
|
|
150
168
|
return maybeAccount;
|
|
151
169
|
}
|
|
152
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Fetches a `GlobalConfig` account, or the non-existing variant when the address holds no
|
|
173
|
+
* account or only lamports (see {@link accountIsCreated}).
|
|
174
|
+
* {@link decodeGlobalConfig} throws for a lamports-only account instead.
|
|
175
|
+
*/
|
|
153
176
|
export async function fetchMaybeGlobalConfig<TAddress extends string = string>(
|
|
154
177
|
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
155
178
|
address: Address<TAddress>,
|
|
156
179
|
config?: FetchAccountConfig,
|
|
157
180
|
): Promise<MaybeAccount<GlobalConfig, TAddress>> {
|
|
158
181
|
const maybeAccount = await fetchEncodedAccount(rpc, address, config);
|
|
159
|
-
return decodeGlobalConfig(
|
|
182
|
+
return decodeGlobalConfig(
|
|
183
|
+
accountIsCreated(maybeAccount)
|
|
184
|
+
? maybeAccount
|
|
185
|
+
: { address, exists: false },
|
|
186
|
+
);
|
|
160
187
|
}
|
|
161
188
|
|
|
189
|
+
/** Fetches `GlobalConfig` accounts, throwing when any does not exist or only holds lamports. */
|
|
162
190
|
export async function fetchAllGlobalConfig(
|
|
163
191
|
rpc: Parameters<typeof fetchEncodedAccounts>[0],
|
|
164
192
|
addresses: Array<Address>,
|
|
@@ -173,6 +201,11 @@ export async function fetchAllGlobalConfig(
|
|
|
173
201
|
return maybeAccounts;
|
|
174
202
|
}
|
|
175
203
|
|
|
204
|
+
/**
|
|
205
|
+
* Fetches `GlobalConfig` accounts, with the non-existing variant for each address that holds
|
|
206
|
+
* no account or only lamports (see {@link accountIsCreated}).
|
|
207
|
+
* {@link decodeGlobalConfig} throws for a lamports-only account instead.
|
|
208
|
+
*/
|
|
176
209
|
export async function fetchAllMaybeGlobalConfig(
|
|
177
210
|
rpc: Parameters<typeof fetchEncodedAccounts>[0],
|
|
178
211
|
addresses: Array<Address>,
|
|
@@ -180,7 +213,11 @@ export async function fetchAllMaybeGlobalConfig(
|
|
|
180
213
|
): Promise<MaybeAccount<GlobalConfig>[]> {
|
|
181
214
|
const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config);
|
|
182
215
|
return maybeAccounts.map((maybeAccount) =>
|
|
183
|
-
decodeGlobalConfig(
|
|
216
|
+
decodeGlobalConfig(
|
|
217
|
+
accountIsCreated(maybeAccount)
|
|
218
|
+
? maybeAccount
|
|
219
|
+
: { address: maybeAccount.address, exists: false },
|
|
220
|
+
),
|
|
184
221
|
);
|
|
185
222
|
}
|
|
186
223
|
|
|
@@ -42,6 +42,7 @@ import {
|
|
|
42
42
|
type ReadonlyUint8Array,
|
|
43
43
|
} from '@solana/kit';
|
|
44
44
|
import { SEND_DEX_PROGRAM_ADDRESS } from '../programs/index.js';
|
|
45
|
+
import { accountIsCreated } from '../shared/index.js';
|
|
45
46
|
import {
|
|
46
47
|
getPoolStatusDecoder,
|
|
47
48
|
getPoolStatusEncoder,
|
|
@@ -170,9 +171,25 @@ export function getPoolCodec(): FixedSizeCodec<PoolArgs, Pool> {
|
|
|
170
171
|
return combineCodec(getPoolEncoder(), getPoolDecoder());
|
|
171
172
|
}
|
|
172
173
|
|
|
174
|
+
/**
|
|
175
|
+
* Decodes a `Pool` account, throwing when another program owns it or its discriminator
|
|
176
|
+
* does not match.
|
|
177
|
+
*
|
|
178
|
+
* Unlike {@link fetchMaybePool}, this throws for an address that only holds lamports rather
|
|
179
|
+
* than returning the non-existing variant: an account passed as existing must never come back as that
|
|
180
|
+
* variant typed as an `Account`. Apply {@link accountIsCreated} first to accounts fetched another way.
|
|
181
|
+
*/
|
|
173
182
|
export function decodePool<TAddress extends string = string>(
|
|
174
183
|
encodedAccount: EncodedAccount<TAddress>,
|
|
175
184
|
): Account<Pool, TAddress>;
|
|
185
|
+
/**
|
|
186
|
+
* Decodes a `Pool` account, throwing when another program owns it or its discriminator
|
|
187
|
+
* does not match.
|
|
188
|
+
*
|
|
189
|
+
* Unlike {@link fetchMaybePool}, this throws for an address that only holds lamports rather
|
|
190
|
+
* than returning the non-existing variant: an account passed as existing must never come back as that
|
|
191
|
+
* variant typed as an `Account`. Apply {@link accountIsCreated} first to accounts fetched another way.
|
|
192
|
+
*/
|
|
176
193
|
export function decodePool<TAddress extends string = string>(
|
|
177
194
|
encodedAccount: MaybeEncodedAccount<TAddress>,
|
|
178
195
|
): MaybeAccount<Pool, TAddress>;
|
|
@@ -201,6 +218,7 @@ export function decodePool<TAddress extends string = string>(
|
|
|
201
218
|
);
|
|
202
219
|
}
|
|
203
220
|
|
|
221
|
+
/** Fetches a `Pool` account, throwing when it does not exist or only holds lamports. */
|
|
204
222
|
export async function fetchPool<TAddress extends string = string>(
|
|
205
223
|
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
206
224
|
address: Address<TAddress>,
|
|
@@ -211,15 +229,25 @@ export async function fetchPool<TAddress extends string = string>(
|
|
|
211
229
|
return maybeAccount;
|
|
212
230
|
}
|
|
213
231
|
|
|
232
|
+
/**
|
|
233
|
+
* Fetches a `Pool` account, or the non-existing variant when the address holds no
|
|
234
|
+
* account or only lamports (see {@link accountIsCreated}).
|
|
235
|
+
* {@link decodePool} throws for a lamports-only account instead.
|
|
236
|
+
*/
|
|
214
237
|
export async function fetchMaybePool<TAddress extends string = string>(
|
|
215
238
|
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
216
239
|
address: Address<TAddress>,
|
|
217
240
|
config?: FetchAccountConfig,
|
|
218
241
|
): Promise<MaybeAccount<Pool, TAddress>> {
|
|
219
242
|
const maybeAccount = await fetchEncodedAccount(rpc, address, config);
|
|
220
|
-
return decodePool(
|
|
243
|
+
return decodePool(
|
|
244
|
+
accountIsCreated(maybeAccount)
|
|
245
|
+
? maybeAccount
|
|
246
|
+
: { address, exists: false },
|
|
247
|
+
);
|
|
221
248
|
}
|
|
222
249
|
|
|
250
|
+
/** Fetches `Pool` accounts, throwing when any does not exist or only holds lamports. */
|
|
223
251
|
export async function fetchAllPool(
|
|
224
252
|
rpc: Parameters<typeof fetchEncodedAccounts>[0],
|
|
225
253
|
addresses: Array<Address>,
|
|
@@ -230,13 +258,24 @@ export async function fetchAllPool(
|
|
|
230
258
|
return maybeAccounts;
|
|
231
259
|
}
|
|
232
260
|
|
|
261
|
+
/**
|
|
262
|
+
* Fetches `Pool` accounts, with the non-existing variant for each address that holds
|
|
263
|
+
* no account or only lamports (see {@link accountIsCreated}).
|
|
264
|
+
* {@link decodePool} throws for a lamports-only account instead.
|
|
265
|
+
*/
|
|
233
266
|
export async function fetchAllMaybePool(
|
|
234
267
|
rpc: Parameters<typeof fetchEncodedAccounts>[0],
|
|
235
268
|
addresses: Array<Address>,
|
|
236
269
|
config?: FetchAccountsConfig,
|
|
237
270
|
): Promise<MaybeAccount<Pool>[]> {
|
|
238
271
|
const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config);
|
|
239
|
-
return maybeAccounts.map((maybeAccount) =>
|
|
272
|
+
return maybeAccounts.map((maybeAccount) =>
|
|
273
|
+
decodePool(
|
|
274
|
+
accountIsCreated(maybeAccount)
|
|
275
|
+
? maybeAccount
|
|
276
|
+
: { address: maybeAccount.address, exists: false },
|
|
277
|
+
),
|
|
278
|
+
);
|
|
240
279
|
}
|
|
241
280
|
|
|
242
281
|
export function getPoolSize(): number {
|
|
@@ -42,6 +42,7 @@ import {
|
|
|
42
42
|
type ReadonlyUint8Array,
|
|
43
43
|
} from '@solana/kit';
|
|
44
44
|
import { SEND_DEX_PROGRAM_ADDRESS } from '../programs/index.js';
|
|
45
|
+
import { accountIsCreated } from '../shared/index.js';
|
|
45
46
|
|
|
46
47
|
export const REWARD_ACCRUAL_DISCRIMINATOR: ReadonlyUint8Array = new Uint8Array([
|
|
47
48
|
158, 244, 116, 30, 227, 132, 105, 182,
|
|
@@ -109,9 +110,25 @@ export function getRewardAccrualCodec(): FixedSizeCodec<
|
|
|
109
110
|
return combineCodec(getRewardAccrualEncoder(), getRewardAccrualDecoder());
|
|
110
111
|
}
|
|
111
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Decodes a `RewardAccrual` account, throwing when another program owns it or its discriminator
|
|
115
|
+
* does not match.
|
|
116
|
+
*
|
|
117
|
+
* Unlike {@link fetchMaybeRewardAccrual}, this throws for an address that only holds lamports rather
|
|
118
|
+
* than returning the non-existing variant: an account passed as existing must never come back as that
|
|
119
|
+
* variant typed as an `Account`. Apply {@link accountIsCreated} first to accounts fetched another way.
|
|
120
|
+
*/
|
|
112
121
|
export function decodeRewardAccrual<TAddress extends string = string>(
|
|
113
122
|
encodedAccount: EncodedAccount<TAddress>,
|
|
114
123
|
): Account<RewardAccrual, TAddress>;
|
|
124
|
+
/**
|
|
125
|
+
* Decodes a `RewardAccrual` account, throwing when another program owns it or its discriminator
|
|
126
|
+
* does not match.
|
|
127
|
+
*
|
|
128
|
+
* Unlike {@link fetchMaybeRewardAccrual}, this throws for an address that only holds lamports rather
|
|
129
|
+
* than returning the non-existing variant: an account passed as existing must never come back as that
|
|
130
|
+
* variant typed as an `Account`. Apply {@link accountIsCreated} first to accounts fetched another way.
|
|
131
|
+
*/
|
|
115
132
|
export function decodeRewardAccrual<TAddress extends string = string>(
|
|
116
133
|
encodedAccount: MaybeEncodedAccount<TAddress>,
|
|
117
134
|
): MaybeAccount<RewardAccrual, TAddress>;
|
|
@@ -142,6 +159,7 @@ export function decodeRewardAccrual<TAddress extends string = string>(
|
|
|
142
159
|
);
|
|
143
160
|
}
|
|
144
161
|
|
|
162
|
+
/** Fetches a `RewardAccrual` account, throwing when it does not exist or only holds lamports. */
|
|
145
163
|
export async function fetchRewardAccrual<TAddress extends string = string>(
|
|
146
164
|
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
147
165
|
address: Address<TAddress>,
|
|
@@ -152,15 +170,25 @@ export async function fetchRewardAccrual<TAddress extends string = string>(
|
|
|
152
170
|
return maybeAccount;
|
|
153
171
|
}
|
|
154
172
|
|
|
173
|
+
/**
|
|
174
|
+
* Fetches a `RewardAccrual` account, or the non-existing variant when the address holds no
|
|
175
|
+
* account or only lamports (see {@link accountIsCreated}).
|
|
176
|
+
* {@link decodeRewardAccrual} throws for a lamports-only account instead.
|
|
177
|
+
*/
|
|
155
178
|
export async function fetchMaybeRewardAccrual<TAddress extends string = string>(
|
|
156
179
|
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
157
180
|
address: Address<TAddress>,
|
|
158
181
|
config?: FetchAccountConfig,
|
|
159
182
|
): Promise<MaybeAccount<RewardAccrual, TAddress>> {
|
|
160
183
|
const maybeAccount = await fetchEncodedAccount(rpc, address, config);
|
|
161
|
-
return decodeRewardAccrual(
|
|
184
|
+
return decodeRewardAccrual(
|
|
185
|
+
accountIsCreated(maybeAccount)
|
|
186
|
+
? maybeAccount
|
|
187
|
+
: { address, exists: false },
|
|
188
|
+
);
|
|
162
189
|
}
|
|
163
190
|
|
|
191
|
+
/** Fetches `RewardAccrual` accounts, throwing when any does not exist or only holds lamports. */
|
|
164
192
|
export async function fetchAllRewardAccrual(
|
|
165
193
|
rpc: Parameters<typeof fetchEncodedAccounts>[0],
|
|
166
194
|
addresses: Array<Address>,
|
|
@@ -175,6 +203,11 @@ export async function fetchAllRewardAccrual(
|
|
|
175
203
|
return maybeAccounts;
|
|
176
204
|
}
|
|
177
205
|
|
|
206
|
+
/**
|
|
207
|
+
* Fetches `RewardAccrual` accounts, with the non-existing variant for each address that holds
|
|
208
|
+
* no account or only lamports (see {@link accountIsCreated}).
|
|
209
|
+
* {@link decodeRewardAccrual} throws for a lamports-only account instead.
|
|
210
|
+
*/
|
|
178
211
|
export async function fetchAllMaybeRewardAccrual(
|
|
179
212
|
rpc: Parameters<typeof fetchEncodedAccounts>[0],
|
|
180
213
|
addresses: Array<Address>,
|
|
@@ -182,7 +215,11 @@ export async function fetchAllMaybeRewardAccrual(
|
|
|
182
215
|
): Promise<MaybeAccount<RewardAccrual>[]> {
|
|
183
216
|
const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config);
|
|
184
217
|
return maybeAccounts.map((maybeAccount) =>
|
|
185
|
-
decodeRewardAccrual(
|
|
218
|
+
decodeRewardAccrual(
|
|
219
|
+
accountIsCreated(maybeAccount)
|
|
220
|
+
? maybeAccount
|
|
221
|
+
: { address: maybeAccount.address, exists: false },
|
|
222
|
+
),
|
|
186
223
|
);
|
|
187
224
|
}
|
|
188
225
|
|
|
@@ -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
|
@@ -15,8 +15,8 @@ export interface CreateTokenParams {
|
|
|
15
15
|
name: string;
|
|
16
16
|
symbol: string;
|
|
17
17
|
uri: string;
|
|
18
|
-
/** An enabled nexus auth platform
|
|
19
|
-
* `creatorId` into the creator fee identity.
|
|
18
|
+
/** An enabled nexus auth platform, for example "wallet", of at most 32 bytes. It is hashed
|
|
19
|
+
* with `creatorId` into the creator fee identity. It is not `platformConfig`. */
|
|
20
20
|
creatorPlatform: string;
|
|
21
21
|
creatorId: string;
|
|
22
22
|
partner: PartnerInput;
|
|
@@ -30,11 +30,11 @@ export interface CreateAndBuyParams extends CreateTokenParams {
|
|
|
30
30
|
slippageBps: number;
|
|
31
31
|
initialVirtualQuoteReserves: bigint;
|
|
32
32
|
initialVirtualBaseReserves: bigint;
|
|
33
|
-
/** `globalConfig.initialRealBaseReserves
|
|
33
|
+
/** `globalConfig.initialRealBaseReserves`. Caps the buy. */
|
|
34
34
|
initialRealBaseReserves: bigint;
|
|
35
|
-
/**
|
|
36
|
-
* ignores the mint's cut, and a cut above `slippageBps` can
|
|
37
|
-
*
|
|
35
|
+
/** The quote mint's transfer fee for the epoch the launch lands in. Without it, `minAmountOut`
|
|
36
|
+
* ignores the mint's cut, and a cut above `slippageBps` can make the buy fail. The new base
|
|
37
|
+
* mint has no transfer fee. */
|
|
38
38
|
quoteFee?: MintFee;
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -55,7 +55,7 @@ async function buildCreateTokenInstructionWithHash(
|
|
|
55
55
|
creatorHash,
|
|
56
56
|
quoteMint: params.quoteMint,
|
|
57
57
|
});
|
|
58
|
-
//
|
|
58
|
+
// `user` pays the creation fee in native SOL. The generated client fills in the WSOL staking vault.
|
|
59
59
|
return getCreateTokenInstructionAsync({
|
|
60
60
|
user: params.user,
|
|
61
61
|
payer: params.payer ?? params.user,
|
|
@@ -98,7 +98,7 @@ export async function buildCreateAndBuyInstructions(
|
|
|
98
98
|
virtualQuoteReserves: params.initialVirtualQuoteReserves,
|
|
99
99
|
virtualBaseReserves: params.initialVirtualBaseReserves,
|
|
100
100
|
realBaseReserves: params.initialRealBaseReserves,
|
|
101
|
-
//
|
|
101
|
+
// `create_token` sets the curve's `platformConfig` to this key.
|
|
102
102
|
platformConfig: params.platformConfig,
|
|
103
103
|
feeBps: params.feeBps,
|
|
104
104
|
slippageBps: params.slippageBps,
|
|
@@ -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
|
import {
|
|
46
47
|
getBondingCurveStatusDecoder,
|
|
47
48
|
getBondingCurveStatusEncoder,
|
|
@@ -191,9 +192,25 @@ export function getBondingCurveCodec(): FixedSizeCodec<
|
|
|
191
192
|
return combineCodec(getBondingCurveEncoder(), getBondingCurveDecoder());
|
|
192
193
|
}
|
|
193
194
|
|
|
195
|
+
/**
|
|
196
|
+
* Decodes a `BondingCurve` account, throwing when another program owns it or its discriminator
|
|
197
|
+
* does not match.
|
|
198
|
+
*
|
|
199
|
+
* Unlike {@link fetchMaybeBondingCurve}, this throws for an address that only holds lamports rather
|
|
200
|
+
* than returning the non-existing variant: an account passed as existing must never come back as that
|
|
201
|
+
* variant typed as an `Account`. Apply {@link accountIsCreated} first to accounts fetched another way.
|
|
202
|
+
*/
|
|
194
203
|
export function decodeBondingCurve<TAddress extends string = string>(
|
|
195
204
|
encodedAccount: EncodedAccount<TAddress>,
|
|
196
205
|
): Account<BondingCurve, TAddress>;
|
|
206
|
+
/**
|
|
207
|
+
* Decodes a `BondingCurve` account, throwing when another program owns it or its discriminator
|
|
208
|
+
* does not match.
|
|
209
|
+
*
|
|
210
|
+
* Unlike {@link fetchMaybeBondingCurve}, this throws for an address that only holds lamports rather
|
|
211
|
+
* than returning the non-existing variant: an account passed as existing must never come back as that
|
|
212
|
+
* variant typed as an `Account`. Apply {@link accountIsCreated} first to accounts fetched another way.
|
|
213
|
+
*/
|
|
197
214
|
export function decodeBondingCurve<TAddress extends string = string>(
|
|
198
215
|
encodedAccount: MaybeEncodedAccount<TAddress>,
|
|
199
216
|
): MaybeAccount<BondingCurve, TAddress>;
|
|
@@ -224,6 +241,7 @@ export function decodeBondingCurve<TAddress extends string = string>(
|
|
|
224
241
|
);
|
|
225
242
|
}
|
|
226
243
|
|
|
244
|
+
/** Fetches a `BondingCurve` account, throwing when it does not exist or only holds lamports. */
|
|
227
245
|
export async function fetchBondingCurve<TAddress extends string = string>(
|
|
228
246
|
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
229
247
|
address: Address<TAddress>,
|
|
@@ -234,15 +252,25 @@ export async function fetchBondingCurve<TAddress extends string = string>(
|
|
|
234
252
|
return maybeAccount;
|
|
235
253
|
}
|
|
236
254
|
|
|
255
|
+
/**
|
|
256
|
+
* Fetches a `BondingCurve` account, or the non-existing variant when the address holds no
|
|
257
|
+
* account or only lamports (see {@link accountIsCreated}).
|
|
258
|
+
* {@link decodeBondingCurve} throws for a lamports-only account instead.
|
|
259
|
+
*/
|
|
237
260
|
export async function fetchMaybeBondingCurve<TAddress extends string = string>(
|
|
238
261
|
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
239
262
|
address: Address<TAddress>,
|
|
240
263
|
config?: FetchAccountConfig,
|
|
241
264
|
): Promise<MaybeAccount<BondingCurve, TAddress>> {
|
|
242
265
|
const maybeAccount = await fetchEncodedAccount(rpc, address, config);
|
|
243
|
-
return decodeBondingCurve(
|
|
266
|
+
return decodeBondingCurve(
|
|
267
|
+
accountIsCreated(maybeAccount)
|
|
268
|
+
? maybeAccount
|
|
269
|
+
: { address, exists: false },
|
|
270
|
+
);
|
|
244
271
|
}
|
|
245
272
|
|
|
273
|
+
/** Fetches `BondingCurve` accounts, throwing when any does not exist or only holds lamports. */
|
|
246
274
|
export async function fetchAllBondingCurve(
|
|
247
275
|
rpc: Parameters<typeof fetchEncodedAccounts>[0],
|
|
248
276
|
addresses: Array<Address>,
|
|
@@ -257,6 +285,11 @@ export async function fetchAllBondingCurve(
|
|
|
257
285
|
return maybeAccounts;
|
|
258
286
|
}
|
|
259
287
|
|
|
288
|
+
/**
|
|
289
|
+
* Fetches `BondingCurve` accounts, with the non-existing variant for each address that holds
|
|
290
|
+
* no account or only lamports (see {@link accountIsCreated}).
|
|
291
|
+
* {@link decodeBondingCurve} throws for a lamports-only account instead.
|
|
292
|
+
*/
|
|
260
293
|
export async function fetchAllMaybeBondingCurve(
|
|
261
294
|
rpc: Parameters<typeof fetchEncodedAccounts>[0],
|
|
262
295
|
addresses: Array<Address>,
|
|
@@ -264,7 +297,11 @@ export async function fetchAllMaybeBondingCurve(
|
|
|
264
297
|
): Promise<MaybeAccount<BondingCurve>[]> {
|
|
265
298
|
const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config);
|
|
266
299
|
return maybeAccounts.map((maybeAccount) =>
|
|
267
|
-
decodeBondingCurve(
|
|
300
|
+
decodeBondingCurve(
|
|
301
|
+
accountIsCreated(maybeAccount)
|
|
302
|
+
? maybeAccount
|
|
303
|
+
: { address: maybeAccount.address, exists: false },
|
|
304
|
+
),
|
|
268
305
|
);
|
|
269
306
|
}
|
|
270
307
|
|
|
@@ -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
|
|