proof-of-take-sdk 5.0.11 → 5.0.13

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.
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.joinSeason = joinSeason;
4
- exports.joinSeasonClassic = joinSeasonClassic;
3
+ exports.createMoonpool = createMoonpool;
4
+ exports.joinMoonpoolSeason = joinMoonpoolSeason;
5
+ exports.joinSunpool = joinSunpool;
5
6
  exports.joinSeasonLaunchpad = joinSeasonLaunchpad;
6
- exports.joinSeasonAndInitialize = joinSeasonAndInitialize;
7
- exports.joinSeasonLaunchpadAndInitialize = joinSeasonLaunchpadAndInitialize;
7
+ exports.joinSeasonClassic = joinSeasonClassic;
8
8
  const anchor_1 = require("@coral-xyz/anchor");
9
9
  const web3_js_1 = require("@solana/web3.js");
10
10
  const spl_token_1 = require("@solana/spl-token");
@@ -13,268 +13,319 @@ const pdas_1 = require("../utils/pdas");
13
13
  const constants_1 = require("../utils/constants");
14
14
  const programHelpers_1 = require("../utils/programHelpers");
15
15
  const signerHelpers_1 = require("../utils/signerHelpers");
16
- const optimistic_1 = require("../optimistic");
17
- const remainingAccounts_1 = require("../utils/remainingAccounts");
18
16
  /**
19
- * Join a season
20
- *
21
- * Signers: user + root admin (root admin pays for signup-rewards vault ATA creation when a referrer is present)
22
- * User pays for season (if needed) and membership accounts
23
- * Transfers active deposit into the season vault; the late-join escrow portion is converted into non-withdrawable join credit
17
+ * Create a new Moonpool and perform the first launchpad join.
24
18
  *
25
- * IMPORTANT: If providing a referrer, you MUST also provide referrerTier.
26
- * The referrerTier must match the tier the referrer actually joined the season with.
27
- * The referrer must have already joined the season before being used as a referrer.
19
+ * This instruction:
20
+ * - Creates a new launchpad_token_mint (SPL Token-2022)
21
+ * - Initializes the Moonpool
22
+ * - Initializes the Season (scoped to launchpad_token_mint)
23
+ * - Creates the first SeasonMembership
28
24
  *
29
- * @param options - Join season options
30
- * @returns Instructions, signers, PDAs, and optimistically created/updated accounts
25
+ * @param options - CreateMoonpool options
26
+ * @returns Instructions, signers, PDAs, and metadata with the generated keypair
31
27
  */
32
- async function joinSeason(options) {
28
+ async function createMoonpool(options) {
33
29
  const program = (0, programHelpers_1.getProgram)(options.connection);
34
- const tokenMint = options.tokenMint ?? constants_1.MIZD_TOKEN_MINT;
35
- const launchpad = options.launchpad ?? false;
36
- // Determine launchpadTokenMint FIRST (before deriving PDAs)
37
- // For BOTH launchpad and classic mode, Season/SeasonMembership PDAs are scoped to launchpadTokenMint
38
- let launchpadTokenMintKeypair;
39
- let launchpadTokenMintPubkey;
40
- if (launchpad) {
41
- // If forceNewLaunchpadMint is set, skip on-chain checks and always generate a new keypair
42
- if (options.forceNewLaunchpadMint) {
43
- launchpadTokenMintKeypair = web3_js_1.Keypair.generate();
44
- launchpadTokenMintPubkey = launchpadTokenMintKeypair.publicKey;
45
- console.log("[joinSeason] forceNewLaunchpadMint=true - generated new launchpad mint keypair:", launchpadTokenMintPubkey.toString());
46
- }
47
- else {
48
- // For non-force mode, we need an existing launchpadTokenMint to find the moonpool
49
- // Check currentAccounts first (for LiteSVM or optimistic updates)
50
- let moonpoolData = options.currentAccounts?.moonpool ?? null;
51
- if (moonpoolData && !moonpoolData.launchpadTokenMint.equals(web3_js_1.PublicKey.default)) {
52
- // Use the launchpadTokenMint from the provided moonpool data
53
- launchpadTokenMintPubkey = moonpoolData.launchpadTokenMint;
54
- console.log("[joinSeason] Using launchpadTokenMint from currentAccounts:", launchpadTokenMintPubkey.toString());
55
- }
56
- else {
57
- // No moonpool data provided - this is a first join scenario
58
- // Generate a keypair for the mint (the mint will be created on-chain)
59
- launchpadTokenMintKeypair = web3_js_1.Keypair.generate();
60
- launchpadTokenMintPubkey = launchpadTokenMintKeypair.publicKey;
61
- console.log("[joinSeason] First join - generated launchpad mint keypair:", launchpadTokenMintPubkey.toString());
62
- }
63
- }
30
+ // Validate required fields
31
+ if (!options.starFlagPrompt || options.starFlagPrompt.length === 0) {
32
+ throw new Error("starFlagPrompt is required when creating a new Moonpool");
64
33
  }
65
- else {
66
- // Classic mode: use the launchpad token mint PDA derived from tokenMint
67
- // The on-chain program expects launchpad_token_mint.key() for Season/SeasonMembership PDAs
68
- const [launchpadMintPda] = (0, pdas_1.getLaunchpadTokenMintPda)(tokenMint);
69
- launchpadTokenMintPubkey = launchpadMintPda;
34
+ if (options.starFlagPrompt.length > 33) {
35
+ throw new Error("starFlagPrompt cannot exceed 33 characters");
36
+ }
37
+ if (!options.symbol || options.symbol.length === 0) {
38
+ throw new Error("symbol is required when creating a new Moonpool");
39
+ }
40
+ if (options.symbol.length > 4) {
41
+ throw new Error("symbol cannot exceed 4 characters");
70
42
  }
71
- // Derive PDAs with launchpadTokenMint for BOTH modes
72
- // Season/SeasonMembership PDAs are always scoped to launchpadTokenMint
43
+ // Generate a new keypair for the launchpad token mint
44
+ const launchpadTokenMintKeypair = web3_js_1.Keypair.generate();
45
+ const launchpadTokenMintPubkey = launchpadTokenMintKeypair.publicKey;
46
+ console.log("[createMoonpool] Generated new launchpad mint keypair:", launchpadTokenMintPubkey.toString());
47
+ // Derive PDAs with the new launchpadTokenMint
73
48
  const pdasBase = pdaManager_1.PDAManager.deriveJoinSeasonPdas({
74
49
  user: options.user,
75
50
  seasonNumber: options.seasonNumber,
76
51
  tier: options.tier,
77
- tokenMint,
52
+ tokenMint: constants_1.MIZD_TOKEN_MINT,
78
53
  launchpadTokenMint: launchpadTokenMintPubkey,
79
54
  });
80
- // Derive Moonpool and Treasury PDAs using the launchpadTokenMint
55
+ // Derive Moonpool and Treasury PDAs
81
56
  const [moonpoolPda] = (0, pdas_1.getMoonpoolPda)(launchpadTokenMintPubkey);
82
57
  const [moonpoolTreasuryPda] = (0, pdas_1.getMoonpoolTreasuryPda)(launchpadTokenMintPubkey);
83
- const rootAdminTokenAccount = launchpad
84
- ? null
85
- : (0, spl_token_1.getAssociatedTokenAddressSync)(constants_1.MIZD_TOKEN_MINT, constants_1.ADMIN_PUBLIC_KEY);
86
- const userMizdAta = launchpad
87
- ? null
88
- : (0, spl_token_1.getAssociatedTokenAddressSync)(constants_1.MIZD_TOKEN_MINT, options.user);
89
- // Join credit PDA + its vault ATA (owner is off-curve PDA, so allowOwnerOffCurve=true).
90
- const userJoinCreditVault = launchpad
91
- ? null
92
- : (0, spl_token_1.getAssociatedTokenAddressSync)(constants_1.MIZD_TOKEN_MINT, pdasBase.userJoinCredit, true);
93
58
  const pdas = {
94
- ...pdasBase,
59
+ seasonSettings: pdasBase.seasonSettings,
60
+ season: pdasBase.season,
61
+ seasonMembership: pdasBase.seasonMembership,
95
62
  moonpool: moonpoolPda,
96
63
  moonpoolTreasury: moonpoolTreasuryPda,
97
64
  launchpadTokenMint: launchpadTokenMintPubkey,
98
- userJoinCreditVault: userJoinCreditVault ?? web3_js_1.PublicKey.default,
99
65
  };
66
+ const referrer = options.referrer ?? web3_js_1.PublicKey.default;
100
67
  const accounts = {
101
68
  seasonSettings: pdas.seasonSettings,
102
69
  season: pdas.season,
103
70
  seasonMembership: pdas.seasonMembership,
104
- // SECURITY: Pool accounts are now MANDATORY (non-optional) to prevent bypassing
105
- // the mode check. The on-chain program validates pool state to ensure
106
- // subsequent seasons use the same mode (launchpad/classic) as the first season.
107
71
  moonpool: moonpoolPda,
108
72
  moonpoolTreasury: moonpoolTreasuryPda,
109
- launchpadTokenMint: pdas.launchpadTokenMint,
110
- sunpool: pdas.sunpool,
111
- seasonDepositVault: launchpad ? null : pdas.seasonDepositVault,
112
- userJoinCredit: launchpad ? null : pdas.userJoinCredit,
113
- userJoinCreditVault: launchpad ? null : userJoinCreditVault,
114
- mizdMint: constants_1.MIZD_TOKEN_MINT,
115
- tokenMint,
73
+ launchpadTokenMint: launchpadTokenMintPubkey,
116
74
  rootAdmin: constants_1.ADMIN_PUBLIC_KEY,
117
- rootAdminTokenAccount,
118
- // Always pass the canonical ATA; it may not exist yet (created on-chain with root admin as payer).
119
- userTokenAccount: userMizdAta,
120
75
  user: options.user,
121
- associatedTokenProgram: spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID,
122
- tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
123
76
  token2022Program: spl_token_1.TOKEN_2022_PROGRAM_ID,
124
77
  systemProgram: web3_js_1.SystemProgram.programId,
125
78
  };
126
- const referrer = options.referrer ?? web3_js_1.PublicKey.default;
127
- const hasReferrer = !referrer.equals(web3_js_1.PublicKey.default);
128
- // Validate: if referrer is provided, referrerTier must also be provided
129
- if (hasReferrer && options.referrerTier === undefined) {
130
- throw new Error("referrerTier is required when referrer is provided");
131
- }
132
- const remainingAccounts = hasReferrer
133
- ? (0, remainingAccounts_1.getJoinSeasonRemainingAccounts)({
134
- seasonNumber: options.seasonNumber,
135
- tier: options.tier,
136
- referrer,
137
- referrerTier: options.referrerTier,
138
- tokenMint,
139
- })
140
- : [];
141
- const methodBuilder = program.methods
142
- // Anchor expects BN for u64 args.
143
- // referrerTier defaults to 0 if no referrer (ignored on-chain)
144
- .joinSeason(options.seasonNumber, options.tier, referrer, options.referrerTier ?? 0, options.star ?? false, launchpad, options.maxSolInLamports ?? new anchor_1.BN(0), options.expectedSolInLamports ?? new anchor_1.BN(0), options.maxSlippageBps ?? 0, options.starFlagPrompt ?? "", options.symbol ?? "", options.forceNewLaunchpadMint ?? false)
145
- .accounts(accounts);
146
- if (remainingAccounts.length > 0) {
147
- methodBuilder.remainingAccounts(remainingAccounts);
148
- }
149
- const instruction = await methodBuilder.instruction();
150
- // For star joins, make the transaction fully sponsored: force the fee payer to be the root admin.
151
- // This prevents clients from accidentally using an unfunded/nonexistent fee payer account.
79
+ const instruction = await program.methods
80
+ .createMoonpool(options.seasonNumber, options.tier, referrer, options.star ?? false, options.maxSolInLamports ?? new anchor_1.BN(0), options.expectedSolInLamports ?? new anchor_1.BN(0), options.maxSlippageBps ?? 0, options.starFlagPrompt, options.symbol)
81
+ .accounts(accounts)
82
+ .instruction();
83
+ // For star joins, root admin pays
152
84
  const feePayer = options.star ? constants_1.ADMIN_PUBLIC_KEY : (0, signerHelpers_1.getDefaultFeePayer)(options.feePayer);
153
- // Build signers array
154
- const signersList = [(0, signerHelpers_1.asAdminSigner)(constants_1.ADMIN_PUBLIC_KEY), (0, signerHelpers_1.asUserSigner)(options.user)];
155
- // Add launchpad token mint keypair as signer if it exists (either provided or auto-generated)
156
- if (launchpad && launchpadTokenMintKeypair) {
157
- signersList.push({
158
- publicKey: launchpadTokenMintKeypair.publicKey,
159
- role: "payer", // Use 'payer' role for the mint keypair
160
- });
161
- }
85
+ // Build signers array - must include the launchpad mint keypair
86
+ const signersList = [
87
+ (0, signerHelpers_1.asAdminSigner)(constants_1.ADMIN_PUBLIC_KEY),
88
+ (0, signerHelpers_1.asUserSigner)(options.user),
89
+ { publicKey: launchpadTokenMintKeypair.publicKey, role: "payer" },
90
+ ];
162
91
  const signers = (0, signerHelpers_1.buildSigners)(signersList, feePayer);
163
- // OPTIMISTIC UPDATES
164
- const curr = options.currentAccounts || {};
165
- const now = (0, optimistic_1.getCurrentTimestamp)(options.now);
166
- let newSeasonMembership;
167
- let updatedSeason;
168
- if (curr.seasonSettings) {
169
- const optimistic = (0, optimistic_1.computeJoinSeasonOptimistic)({
170
- user: options.user,
171
- seasonNumber: options.seasonNumber,
172
- tier: options.tier,
173
- referrer: options.referrer ?? web3_js_1.PublicKey.default,
174
- tokenMint,
175
- now,
176
- star: options.star ?? false,
177
- seasonSettings: curr.seasonSettings,
178
- ...(curr.season ? { season: curr.season } : {}),
179
- });
180
- if (optimistic.kind === "skip") {
181
- return {
182
- instructions: [instruction],
183
- signers,
184
- pdas,
185
- };
186
- }
187
- newSeasonMembership = optimistic.newSeasonMembership;
188
- updatedSeason = optimistic.updatedSeason;
189
- }
190
92
  return {
191
93
  instructions: [instruction],
192
94
  signers,
193
95
  pdas,
194
- ...(curr.seasonSettings || updatedSeason || newSeasonMembership
195
- ? {
196
- updatedAccounts: {
197
- ...(curr.seasonSettings && { seasonSettings: curr.seasonSettings }),
198
- ...(updatedSeason && { season: updatedSeason }),
199
- ...(newSeasonMembership && {
200
- seasonMembership: newSeasonMembership,
201
- }),
202
- },
203
- }
204
- : {}),
205
- ...(launchpadTokenMintKeypair
206
- ? {
207
- meta: {
208
- launchpadTokenMintKeypair,
209
- },
210
- }
211
- : {}),
96
+ metadata: {
97
+ launchpadTokenMintKeypair,
98
+ },
212
99
  };
213
100
  }
214
101
  /**
215
- * Convenience wrapper: classic (non-launchpad) joinSeason.
216
- * - Keeps the existing MIZD-based join behavior.
217
- * - App code never passes nullable optional accounts.
102
+ * Join an existing Moonpool season.
103
+ *
104
+ * This instruction:
105
+ * - Requires Moonpool to already exist
106
+ * - Lazily initializes Season if needed (for new seasons with existing Moonpool)
107
+ * - Creates new SeasonMembership
108
+ *
109
+ * @param options - JoinMoonpoolSeason options
110
+ * @returns Instructions, signers, and PDAs
218
111
  */
219
- async function joinSeasonClassic(options) {
220
- // IMPORTANT: With `exactOptionalPropertyTypes`, we must OMIT optional props (not set them to `undefined`).
221
- return joinSeason({ ...options, launchpad: false });
112
+ async function joinMoonpoolSeason(options) {
113
+ const program = (0, programHelpers_1.getProgram)(options.connection);
114
+ const launchpadTokenMintPubkey = options.launchpadTokenMint;
115
+ console.log("[joinMoonpoolSeason] Using existing launchpadTokenMint:", launchpadTokenMintPubkey.toString());
116
+ // Derive PDAs with the existing launchpadTokenMint
117
+ const pdasBase = pdaManager_1.PDAManager.deriveJoinSeasonPdas({
118
+ user: options.user,
119
+ seasonNumber: options.seasonNumber,
120
+ tier: options.tier,
121
+ tokenMint: constants_1.MIZD_TOKEN_MINT,
122
+ launchpadTokenMint: launchpadTokenMintPubkey,
123
+ });
124
+ // Derive Moonpool and Treasury PDAs
125
+ const [moonpoolPda] = (0, pdas_1.getMoonpoolPda)(launchpadTokenMintPubkey);
126
+ const [moonpoolTreasuryPda] = (0, pdas_1.getMoonpoolTreasuryPda)(launchpadTokenMintPubkey);
127
+ const pdas = {
128
+ seasonSettings: pdasBase.seasonSettings,
129
+ season: pdasBase.season,
130
+ seasonMembership: pdasBase.seasonMembership,
131
+ moonpool: moonpoolPda,
132
+ moonpoolTreasury: moonpoolTreasuryPda,
133
+ launchpadTokenMint: launchpadTokenMintPubkey,
134
+ };
135
+ const referrer = options.referrer ?? web3_js_1.PublicKey.default;
136
+ const accounts = {
137
+ seasonSettings: pdas.seasonSettings,
138
+ season: pdas.season,
139
+ seasonMembership: pdas.seasonMembership,
140
+ moonpool: moonpoolPda,
141
+ moonpoolTreasury: moonpoolTreasuryPda,
142
+ launchpadTokenMint: launchpadTokenMintPubkey,
143
+ rootAdmin: constants_1.ADMIN_PUBLIC_KEY,
144
+ user: options.user,
145
+ token2022Program: spl_token_1.TOKEN_2022_PROGRAM_ID,
146
+ systemProgram: web3_js_1.SystemProgram.programId,
147
+ };
148
+ const instruction = await program.methods
149
+ .joinMoonpoolSeason(options.seasonNumber, options.tier, referrer, options.star ?? false, options.maxSolInLamports ?? new anchor_1.BN(0), options.expectedSolInLamports ?? new anchor_1.BN(0), options.maxSlippageBps ?? 0)
150
+ .accounts(accounts)
151
+ .instruction();
152
+ // For star joins, root admin pays
153
+ const feePayer = options.star ? constants_1.ADMIN_PUBLIC_KEY : (0, signerHelpers_1.getDefaultFeePayer)(options.feePayer);
154
+ // Build signers array
155
+ const signersList = [
156
+ (0, signerHelpers_1.asAdminSigner)(constants_1.ADMIN_PUBLIC_KEY),
157
+ (0, signerHelpers_1.asUserSigner)(options.user),
158
+ ];
159
+ const signers = (0, signerHelpers_1.buildSigners)(signersList, feePayer);
160
+ return {
161
+ instructions: [instruction],
162
+ signers,
163
+ pdas,
164
+ };
222
165
  }
223
166
  /**
224
- * Convenience wrapper: launchpad joinSeason.
225
- * - Uses SOL in + virtual token escrow.
226
- * - App code never passes nullable optional accounts.
167
+ * Join a Sunpool season (classic mode with MIZD).
168
+ *
169
+ * This instruction:
170
+ * - Lazily initializes Sunpool if needed
171
+ * - Lazily initializes Season if needed
172
+ * - Creates SeasonMembership
173
+ * - Handles MIZD token transfers and join credit
174
+ *
175
+ * @param options - JoinSunpool options
176
+ * @returns Instructions, signers, and PDAs
227
177
  */
228
- async function joinSeasonLaunchpad(options) {
229
- // IMPORTANT: With `exactOptionalPropertyTypes`, we must OMIT optional props (not set them to `undefined`).
230
- const { maxSolInLamports, expectedSolInLamports, maxSlippageBps, ...rest } = options;
231
- return joinSeason({
232
- ...rest,
233
- launchpad: true,
234
- ...(maxSolInLamports ? { maxSolInLamports } : {}),
235
- ...(expectedSolInLamports ? { expectedSolInLamports } : {}),
236
- ...(typeof maxSlippageBps === "number" ? { maxSlippageBps } : {}),
178
+ async function joinSunpool(options) {
179
+ const program = (0, programHelpers_1.getProgram)(options.connection);
180
+ const tokenMint = options.tokenMint ?? constants_1.MIZD_TOKEN_MINT;
181
+ console.log("[joinSunpool] Classic mode join with tokenMint:", tokenMint.toString());
182
+ // Derive PDAs - for Sunpool, use tokenMint for PDA derivation
183
+ const pdasBase = pdaManager_1.PDAManager.deriveJoinSeasonPdas({
184
+ user: options.user,
185
+ seasonNumber: options.seasonNumber,
186
+ tier: options.tier,
187
+ tokenMint,
188
+ launchpadTokenMint: tokenMint, // Sunpool uses tokenMint for Season/Membership PDAs
237
189
  });
190
+ // Derive Sunpool PDA
191
+ const [sunpoolPda] = (0, pdas_1.getSunpoolPda)(tokenMint);
192
+ // User join credit vault ATA
193
+ const userJoinCreditVault = (0, spl_token_1.getAssociatedTokenAddressSync)(constants_1.MIZD_TOKEN_MINT, pdasBase.userJoinCredit, true);
194
+ // Token accounts
195
+ const rootAdminTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(constants_1.MIZD_TOKEN_MINT, constants_1.ADMIN_PUBLIC_KEY);
196
+ const userMizdAta = (0, spl_token_1.getAssociatedTokenAddressSync)(constants_1.MIZD_TOKEN_MINT, options.user);
197
+ const pdas = {
198
+ seasonSettings: pdasBase.seasonSettings,
199
+ season: pdasBase.season,
200
+ seasonMembership: pdasBase.seasonMembership,
201
+ sunpool: sunpoolPda,
202
+ seasonDepositVault: pdasBase.seasonDepositVault,
203
+ userJoinCredit: pdasBase.userJoinCredit,
204
+ userJoinCreditVault,
205
+ };
206
+ const referrer = options.referrer ?? web3_js_1.PublicKey.default;
207
+ const hasReferrer = !referrer.equals(web3_js_1.PublicKey.default);
208
+ // Validate referrer tier
209
+ if (hasReferrer && options.referrerTier === undefined) {
210
+ throw new Error("referrerTier is required when referrer is provided");
211
+ }
212
+ const accounts = {
213
+ seasonSettings: pdas.seasonSettings,
214
+ season: pdas.season,
215
+ seasonMembership: pdas.seasonMembership,
216
+ sunpool: sunpoolPda,
217
+ seasonDepositVault: pdas.seasonDepositVault,
218
+ userJoinCredit: pdas.userJoinCredit,
219
+ userJoinCreditVault,
220
+ mizdMint: constants_1.MIZD_TOKEN_MINT,
221
+ tokenMint,
222
+ rootAdmin: constants_1.ADMIN_PUBLIC_KEY,
223
+ rootAdminTokenAccount,
224
+ userTokenAccount: userMizdAta,
225
+ user: options.user,
226
+ associatedTokenProgram: spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID,
227
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
228
+ systemProgram: web3_js_1.SystemProgram.programId,
229
+ };
230
+ const instruction = await program.methods
231
+ .joinSunpool(options.seasonNumber, options.tier, referrer, options.referrerTier ?? 0, options.star ?? false, options.starFlagPrompt ?? "", options.symbol ?? "")
232
+ .accounts(accounts)
233
+ .instruction();
234
+ // For star joins, root admin pays
235
+ const feePayer = options.star ? constants_1.ADMIN_PUBLIC_KEY : (0, signerHelpers_1.getDefaultFeePayer)(options.feePayer);
236
+ // Build signers array
237
+ const signersList = [
238
+ (0, signerHelpers_1.asAdminSigner)(constants_1.ADMIN_PUBLIC_KEY),
239
+ (0, signerHelpers_1.asUserSigner)(options.user),
240
+ ];
241
+ const signers = (0, signerHelpers_1.buildSigners)(signersList, feePayer);
242
+ return {
243
+ instructions: [instruction],
244
+ signers,
245
+ pdas,
246
+ };
238
247
  }
239
248
  /**
240
- * Join season AND initialize it (first joiner).
241
- * Use this when you know the season doesn't exist yet.
249
+ * Convenience wrapper for launchpad mode joins.
250
+ *
251
+ * This function automatically determines whether to call:
252
+ * - createMoonpool (if forceNewLaunchpadMint=true or no existing moonpool)
253
+ * - joinMoonpoolSeason (if joining an existing moonpool)
242
254
  *
243
- * @param options - Options with REQUIRED starFlagPrompt
244
- * @throws Error if starFlagPrompt is empty or exceeds 33 characters
255
+ * @param options - Join options
256
+ * @returns Instructions, signers, PDAs, and metadata
245
257
  */
246
- async function joinSeasonAndInitialize(options) {
247
- // Validate starFlagPrompt
248
- if (!options.starFlagPrompt || options.starFlagPrompt.length === 0) {
249
- throw new Error("starFlagPrompt is required when initializing a new season");
258
+ async function joinSeasonLaunchpad(options) {
259
+ // Determine if we're creating a new Moonpool or joining an existing one
260
+ const shouldCreateNewMoonpool = options.forceNewLaunchpadMint ||
261
+ !options.currentAccounts?.moonpool ||
262
+ options.currentAccounts.moonpool.launchpadTokenMint?.equals(web3_js_1.PublicKey.default);
263
+ if (shouldCreateNewMoonpool) {
264
+ // Creating a new Moonpool - starFlagPrompt and symbol are required
265
+ if (!options.starFlagPrompt) {
266
+ throw new Error("starFlagPrompt is required when creating a new Moonpool");
267
+ }
268
+ if (!options.symbol) {
269
+ throw new Error("symbol is required when creating a new Moonpool");
270
+ }
271
+ return createMoonpool({
272
+ connection: options.connection,
273
+ user: options.user,
274
+ seasonNumber: options.seasonNumber,
275
+ tier: options.tier,
276
+ starFlagPrompt: options.starFlagPrompt,
277
+ symbol: options.symbol,
278
+ ...(options.referrer !== undefined && { referrer: options.referrer }),
279
+ ...(options.star !== undefined && { star: options.star }),
280
+ ...(options.maxSolInLamports !== undefined && { maxSolInLamports: options.maxSolInLamports }),
281
+ ...(options.expectedSolInLamports !== undefined && { expectedSolInLamports: options.expectedSolInLamports }),
282
+ ...(options.maxSlippageBps !== undefined && { maxSlippageBps: options.maxSlippageBps }),
283
+ ...(options.now !== undefined && { now: options.now }),
284
+ ...(options.feePayer !== undefined && { feePayer: options.feePayer }),
285
+ ...(options.currentAccounts !== undefined && { currentAccounts: options.currentAccounts }),
286
+ });
250
287
  }
251
- if (options.starFlagPrompt.length > 33) {
252
- throw new Error("starFlagPrompt cannot exceed 33 characters");
288
+ else {
289
+ // Joining an existing Moonpool
290
+ const launchpadTokenMint = options.currentAccounts.moonpool.launchpadTokenMint;
291
+ return joinMoonpoolSeason({
292
+ connection: options.connection,
293
+ user: options.user,
294
+ seasonNumber: options.seasonNumber,
295
+ launchpadTokenMint,
296
+ tier: options.tier,
297
+ ...(options.referrer !== undefined && { referrer: options.referrer }),
298
+ ...(options.star !== undefined && { star: options.star }),
299
+ ...(options.maxSolInLamports !== undefined && { maxSolInLamports: options.maxSolInLamports }),
300
+ ...(options.expectedSolInLamports !== undefined && { expectedSolInLamports: options.expectedSolInLamports }),
301
+ ...(options.maxSlippageBps !== undefined && { maxSlippageBps: options.maxSlippageBps }),
302
+ ...(options.now !== undefined && { now: options.now }),
303
+ ...(options.feePayer !== undefined && { feePayer: options.feePayer }),
304
+ ...(options.currentAccounts !== undefined && { currentAccounts: options.currentAccounts }),
305
+ });
253
306
  }
254
- return joinSeason(options);
255
307
  }
256
308
  /**
257
- * Join season AND initialize it in launchpad mode (first joiner).
258
- * Use this when you know the season doesn't exist yet and want launchpad mode.
309
+ * Convenience wrapper for classic (non-launchpad) mode joins.
310
+ * Routes to joinSunpool instruction.
259
311
  *
260
- * @param options - Options with REQUIRED starFlagPrompt
261
- * @throws Error if starFlagPrompt is empty or exceeds 33 characters
312
+ * @param options - Join options
313
+ * @returns Instructions, signers, and PDAs
262
314
  */
263
- async function joinSeasonLaunchpadAndInitialize(options) {
264
- // Validate starFlagPrompt
265
- if (!options.starFlagPrompt || options.starFlagPrompt.length === 0) {
266
- throw new Error("starFlagPrompt is required when initializing a new season");
267
- }
268
- if (options.starFlagPrompt.length > 33) {
269
- throw new Error("starFlagPrompt cannot exceed 33 characters");
270
- }
271
- const { maxSolInLamports, expectedSolInLamports, maxSlippageBps, ...rest } = options;
272
- return joinSeason({
273
- ...rest,
274
- launchpad: true,
275
- ...(maxSolInLamports ? { maxSolInLamports } : {}),
276
- ...(expectedSolInLamports ? { expectedSolInLamports } : {}),
277
- ...(typeof maxSlippageBps === "number" ? { maxSlippageBps } : {}),
315
+ async function joinSeasonClassic(options) {
316
+ return joinSunpool({
317
+ connection: options.connection,
318
+ user: options.user,
319
+ seasonNumber: options.seasonNumber,
320
+ tier: options.tier,
321
+ ...(options.tokenMint !== undefined && { tokenMint: options.tokenMint }),
322
+ ...(options.referrer !== undefined && { referrer: options.referrer }),
323
+ ...(options.referrerTier !== undefined && { referrerTier: options.referrerTier }),
324
+ ...(options.star !== undefined && { star: options.star }),
325
+ ...(options.starFlagPrompt !== undefined && { starFlagPrompt: options.starFlagPrompt }),
326
+ ...(options.symbol !== undefined && { symbol: options.symbol }),
327
+ ...(options.now !== undefined && { now: options.now }),
328
+ ...(options.feePayer !== undefined && { feePayer: options.feePayer }),
329
+ ...(options.currentAccounts !== undefined && { currentAccounts: options.currentAccounts }),
278
330
  });
279
331
  }
280
- // getTierPenaltyPerWindow imported from ../utils/tierPenalty