proof-of-take-sdk 3.1.2 → 4.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.
Files changed (57) hide show
  1. package/dist/getters/getSeasonLaunchpadPool.d.ts +31 -0
  2. package/dist/getters/getSeasonLaunchpadPool.js +49 -0
  3. package/dist/getters/index.d.ts +1 -0
  4. package/dist/getters/index.js +1 -0
  5. package/dist/idl/proof_of_take.json +4490 -1674
  6. package/dist/index.d.ts +14 -7
  7. package/dist/index.js +20 -3
  8. package/dist/instructions/buyMizd.d.ts +19 -0
  9. package/dist/instructions/buyMizd.js +41 -0
  10. package/dist/instructions/claimReferralPenaltyForWindow.d.ts +53 -2
  11. package/dist/instructions/claimReferralPenaltyForWindow.js +45 -3
  12. package/dist/instructions/claimSignupRewards.d.ts +30 -0
  13. package/dist/instructions/claimSignupRewards.js +37 -3
  14. package/dist/instructions/claimWindowRewards.d.ts +42 -1
  15. package/dist/instructions/claimWindowRewards.js +47 -3
  16. package/dist/instructions/confirmedPostOnX.d.ts +2 -0
  17. package/dist/instructions/confirmedPostOnX.js +10 -0
  18. package/dist/instructions/createMiztake.d.ts +3 -2
  19. package/dist/instructions/createMiztake.js +5 -2
  20. package/dist/instructions/initializeBondingCurve.d.ts +24 -0
  21. package/dist/instructions/initializeBondingCurve.js +37 -0
  22. package/dist/instructions/initializeRewardWindow.d.ts +2 -0
  23. package/dist/instructions/initializeRewardWindow.js +5 -2
  24. package/dist/instructions/initializeSeasonVault.d.ts +1 -1
  25. package/dist/instructions/initializeSeasonVault.js +3 -2
  26. package/dist/instructions/joinSeason.d.ts +92 -3
  27. package/dist/instructions/joinSeason.js +117 -40
  28. package/dist/instructions/sellMizd.d.ts +19 -0
  29. package/dist/instructions/sellMizd.js +41 -0
  30. package/dist/instructions/viewSeasonMembershipStatus.d.ts +1 -1
  31. package/dist/instructions/viewSeasonMembershipStatus.js +13 -8
  32. package/dist/instructions/withdrawSeasonDeposit.d.ts +2 -0
  33. package/dist/instructions/withdrawSeasonDeposit.js +6 -1
  34. package/dist/optimistic/index.d.ts +1 -0
  35. package/dist/optimistic/index.js +5 -1
  36. package/dist/optimistic/joinSeasonOptimistic.d.ts +31 -0
  37. package/dist/optimistic/joinSeasonOptimistic.js +55 -0
  38. package/dist/types/accountTypes.d.ts +72 -18
  39. package/dist/types/anchorAccounts.d.ts +2 -0
  40. package/dist/types/proof_of_take.d.ts +4471 -1655
  41. package/dist/types.d.ts +10 -2
  42. package/dist/utils/accountConverters.js +7 -1
  43. package/dist/utils/accountUpdates.d.ts +38 -8
  44. package/dist/utils/accountUpdates.js +109 -19
  45. package/dist/utils/constants.d.ts +11 -0
  46. package/dist/utils/constants.js +14 -1
  47. package/dist/utils/pdaManager.d.ts +42 -2
  48. package/dist/utils/pdaManager.js +70 -28
  49. package/dist/utils/pdas.d.ts +46 -8
  50. package/dist/utils/pdas.js +111 -11
  51. package/dist/utils/remainingAccounts.d.ts +1 -0
  52. package/dist/utils/remainingAccounts.js +3 -2
  53. package/dist/utils/seedRegistry.d.ts +10 -0
  54. package/dist/utils/seedRegistry.js +10 -0
  55. package/package.json +1 -1
  56. package/dist/instructions/initializeEscrowVault.d.ts +0 -12
  57. package/dist/instructions/initializeEscrowVault.js +0 -37
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.confirmedPostOnX = confirmedPostOnX;
4
4
  const pdaManager_1 = require("../utils/pdaManager");
5
5
  const programHelpers_1 = require("../utils/programHelpers");
6
+ const constants_1 = require("../utils/constants");
6
7
  const signerHelpers_1 = require("../utils/signerHelpers");
7
8
  const conversions_1 = require("../utils/conversions");
8
9
  const tierPenalty_1 = require("../utils/tierPenalty");
@@ -20,6 +21,7 @@ const optimistic_1 = require("../optimistic");
20
21
  async function confirmedPostOnX(options) {
21
22
  // Guardrail: this program uses a 21-window schedule (0..20).
22
23
  const windowNumber = (0, conversions_1.toWindowNumberBn)(options.windowNumber);
24
+ const tokenMint = options.tokenMint ?? constants_1.MIZD_TOKEN_MINT;
23
25
  const program = (0, programHelpers_1.getProgram)(options.connection);
24
26
  const curr = options.currentAccounts || {};
25
27
  const pdas = pdaManager_1.PDAManager.deriveConfirmedPostPdas({
@@ -28,6 +30,7 @@ async function confirmedPostOnX(options) {
28
30
  windowNumber,
29
31
  tier: options.tier,
30
32
  miztakeShaHash: options.miztakeShaHash,
33
+ tokenMint,
31
34
  });
32
35
  const accounts = {
33
36
  seasonSettings: pdas.seasonSettings,
@@ -35,6 +38,7 @@ async function confirmedPostOnX(options) {
35
38
  season: pdas.season,
36
39
  rewardWindow: pdas.rewardWindow,
37
40
  userWindowParticipation: pdas.userWindowParticipation,
41
+ tokenMint,
38
42
  miztake: pdas.miztake,
39
43
  admin: options.adminKey,
40
44
  };
@@ -46,6 +50,12 @@ async function confirmedPostOnX(options) {
46
50
  feePayer: options.feePayer,
47
51
  admin: options.adminKey,
48
52
  });
53
+ // Safety: confirmations should always be paid by the admin wallet.
54
+ // If a caller accidentally sets the user as fee payer (common in bots),
55
+ // the tx will fail when users have 0 SOL.
56
+ if (!feePayer.equals(options.adminKey)) {
57
+ throw new Error("confirmedPostOnX: feePayer must be adminKey (admin pays tx fees for confirmations)");
58
+ }
49
59
  const signers = (0, signerHelpers_1.buildSigners)([(0, signerHelpers_1.asAdminSigner)(options.adminKey)], feePayer);
50
60
  // OPTIMISTIC UPDATES
51
61
  let updatedAccounts = undefined;
@@ -11,6 +11,8 @@ export interface CreateMiztakeOptions {
11
11
  user: PublicKey;
12
12
  admin: PublicKey;
13
13
  seasonNumber: BN;
14
+ /** Token mint this season is scoped to (used for PDA derivation). Defaults to MIZD_TOKEN_MINT. */
15
+ tokenMint?: PublicKey;
14
16
  windowNumber: WindowNumberLike;
15
17
  /** Tier number: 0=copper, 1=silver, 2=gold, 3=platinum, 4=mithril */
16
18
  tier: TierNumber;
@@ -55,8 +57,7 @@ export type CreateMiztakeResult = StandardInstructionResultWithPdasAndAccounts<C
55
57
  * Create a new miztake
56
58
  *
57
59
  * Requires dual signature: user + admin
58
- * User pays for miztake, user_stats, and user_window_participation accounts
59
- * Admin pays for reward_window account (if needed)
60
+ * Admin pays for all account creations (miztake, user_stats, user_window_participation, reward_window)
60
61
  *
61
62
  * @param options - Create miztake options
62
63
  * @returns Instructions, signers, PDAs, and optimistically updated accounts
@@ -7,6 +7,7 @@ const web3_js_1 = require("@solana/web3.js");
7
7
  const types_1 = require("../types");
8
8
  const pdaManager_1 = require("../utils/pdaManager");
9
9
  const programHelpers_1 = require("../utils/programHelpers");
10
+ const constants_1 = require("../utils/constants");
10
11
  const signerHelpers_1 = require("../utils/signerHelpers");
11
12
  const conversions_1 = require("../utils/conversions");
12
13
  const optimistic_1 = require("../optimistic");
@@ -15,8 +16,7 @@ const enumHelpers_1 = require("../utils/enumHelpers");
15
16
  * Create a new miztake
16
17
  *
17
18
  * Requires dual signature: user + admin
18
- * User pays for miztake, user_stats, and user_window_participation accounts
19
- * Admin pays for reward_window account (if needed)
19
+ * Admin pays for all account creations (miztake, user_stats, user_window_participation, reward_window)
20
20
  *
21
21
  * @param options - Create miztake options
22
22
  * @returns Instructions, signers, PDAs, and optimistically updated accounts
@@ -42,6 +42,7 @@ const enumHelpers_1 = require("../utils/enumHelpers");
42
42
  */
43
43
  async function createMiztake(options) {
44
44
  const program = (0, programHelpers_1.getProgram)(options.connection);
45
+ const tokenMint = options.tokenMint ?? constants_1.MIZD_TOKEN_MINT;
45
46
  // Guardrail: this program uses a 21-window schedule (0..20).
46
47
  const windowNumber = (0, conversions_1.toWindowNumberBn)(options.windowNumber);
47
48
  const shaHash = (0, conversions_1.toSha256HexString)(options.params.shaHash);
@@ -53,6 +54,7 @@ async function createMiztake(options) {
53
54
  windowNumber,
54
55
  user: options.user,
55
56
  tier: options.tier,
57
+ tokenMint,
56
58
  });
57
59
  // Build typed accounts object
58
60
  const accounts = {
@@ -64,6 +66,7 @@ async function createMiztake(options) {
64
66
  seasonMembership: pdas.seasonMembership,
65
67
  rewardWindow: pdas.rewardWindow,
66
68
  userWindowParticipation: pdas.userWindowParticipation,
69
+ tokenMint,
67
70
  user: options.user,
68
71
  admin: options.admin,
69
72
  systemProgram: web3_js_1.SystemProgram.programId,
@@ -0,0 +1,24 @@
1
+ import { BN } from "@coral-xyz/anchor";
2
+ import { Connection, PublicKey } from "@solana/web3.js";
3
+ import { StandardInstructionResultWithPdas } from "../types/instructionResults";
4
+ export interface InitializeBondingCurveOptions {
5
+ connection: Connection;
6
+ /** Must be the on-chain root admin (ADMIN_PUBLIC_KEY). */
7
+ admin?: PublicKey;
8
+ /** Initial MIZD inventory deposited into the vault (base units). */
9
+ initialMizdDepositUnits: BN;
10
+ /** Initial SOL reserve deposited into the curve PDA (lamports). */
11
+ initialSolDepositLamports: BN;
12
+ /** Virtual SOL reserve (lamports). */
13
+ virtualSolReserveLamports?: BN;
14
+ /** Virtual MIZD reserve (base units). */
15
+ virtualMizdReserveUnits?: BN;
16
+ /** Fee in bps (0..=10000). Default 0. */
17
+ feeBps?: number;
18
+ feePayer?: PublicKey;
19
+ }
20
+ export declare function initializeBondingCurve(opts: InitializeBondingCurveOptions): Promise<StandardInstructionResultWithPdas<{
21
+ bondingCurve: PublicKey;
22
+ mizdVault: PublicKey;
23
+ adminMizdAta: PublicKey;
24
+ }>>;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initializeBondingCurve = initializeBondingCurve;
4
+ const anchor_1 = require("@coral-xyz/anchor");
5
+ const web3_js_1 = require("@solana/web3.js");
6
+ const spl_token_1 = require("@solana/spl-token");
7
+ const instructionResultHelpers_1 = require("../utils/instructionResultHelpers");
8
+ const constants_1 = require("../utils/constants");
9
+ const pdaManager_1 = require("../utils/pdaManager");
10
+ const programHelpers_1 = require("../utils/programHelpers");
11
+ const signerHelpers_1 = require("../utils/signerHelpers");
12
+ async function initializeBondingCurve(opts) {
13
+ const program = (0, programHelpers_1.getProgram)(opts.connection);
14
+ const admin = opts.admin ?? constants_1.ADMIN_PUBLIC_KEY;
15
+ const pdas = pdaManager_1.PDAManager.deriveBondingCurvePdas();
16
+ const adminMizdAta = (0, spl_token_1.getAssociatedTokenAddressSync)(constants_1.MIZD_TOKEN_MINT, admin);
17
+ const accounts = {
18
+ bondingCurve: pdas.bondingCurve,
19
+ mizdVault: pdas.mizdVault,
20
+ mizdMint: constants_1.MIZD_TOKEN_MINT,
21
+ admin,
22
+ adminMizdAta,
23
+ associatedTokenProgram: spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID,
24
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
25
+ systemProgram: web3_js_1.SystemProgram.programId,
26
+ };
27
+ const instruction = await program.methods
28
+ .initializeBondingCurve(opts.initialMizdDepositUnits, opts.initialSolDepositLamports, opts.virtualSolReserveLamports ?? new anchor_1.BN(0), opts.virtualMizdReserveUnits ?? new anchor_1.BN(0), opts.feeBps ?? 0)
29
+ .accounts(accounts)
30
+ .instruction();
31
+ const feePayer = (0, signerHelpers_1.resolveFeePayer)({ feePayer: opts.feePayer, admin });
32
+ const signers = (0, signerHelpers_1.buildSigners)([(0, signerHelpers_1.asAdminSigner)(admin)], feePayer);
33
+ return (0, instructionResultHelpers_1.singleInstruction)(instruction, {
34
+ signers,
35
+ pdas: { bondingCurve: pdas.bondingCurve, mizdVault: pdas.mizdVault, adminMizdAta },
36
+ });
37
+ }
@@ -12,6 +12,8 @@ export interface InitializeRewardWindowOptions {
12
12
  admin: PublicKey;
13
13
  seasonNumber: SeasonNumberLike;
14
14
  windowNumber: WindowNumberLike;
15
+ /** Token mint this season is scoped to (used for PDA derivation). Defaults to MIZD_TOKEN_MINT. */
16
+ tokenMint?: PublicKey;
15
17
  feePayer?: PublicKey;
16
18
  }
17
19
  /**
@@ -7,6 +7,7 @@ const programHelpers_1 = require("../utils/programHelpers");
7
7
  const signerHelpers_1 = require("../utils/signerHelpers");
8
8
  const instructionResultHelpers_1 = require("../utils/instructionResultHelpers");
9
9
  const conversions_1 = require("../utils/conversions");
10
+ const constants_1 = require("../utils/constants");
10
11
  /**
11
12
  * Initialize (materialize) a missing RewardWindow PDA (root-admin only).
12
13
  *
@@ -17,13 +18,15 @@ async function initializeRewardWindow(options) {
17
18
  const program = (0, programHelpers_1.getProgram)(options.connection);
18
19
  const seasonNumberBn = (0, conversions_1.toSeasonNumberBn)(options.seasonNumber);
19
20
  const windowNumberBn = (0, conversions_1.toWindowNumberBn)(options.windowNumber);
21
+ const tokenMint = options.tokenMint ?? constants_1.MIZD_TOKEN_MINT;
20
22
  const [seasonSettings] = (0, pdas_1.getSeasonSettingsPda)();
21
- const [season] = (0, pdas_1.getSeasonPda)(seasonNumberBn);
22
- const [rewardWindow] = (0, pdas_1.getRewardWindowPda)(seasonNumberBn, windowNumberBn);
23
+ const [season] = (0, pdas_1.getSeasonPda)(seasonNumberBn, tokenMint);
24
+ const [rewardWindow] = (0, pdas_1.getRewardWindowPda)(seasonNumberBn, windowNumberBn, tokenMint);
23
25
  const accounts = {
24
26
  seasonSettings,
25
27
  season,
26
28
  rewardWindow,
29
+ tokenMint,
27
30
  admin: options.admin,
28
31
  systemProgram: web3_js_1.SystemProgram.programId,
29
32
  };
@@ -12,6 +12,6 @@ import { StandardInstructionResultWithPdas } from "../types/instructionResults";
12
12
  * @param feePayer - Optional separate fee payer for transaction fees
13
13
  * @returns Instructions, signers array, and vault PDA
14
14
  */
15
- export declare function initializeSeasonVault(connection: Connection, admin: PublicKey, seasonNumber: BN, feePayer?: PublicKey): Promise<StandardInstructionResultWithPdas<{
15
+ export declare function initializeSeasonVault(connection: Connection, admin: PublicKey, seasonNumber: BN, tokenMint?: PublicKey, feePayer?: PublicKey): Promise<StandardInstructionResultWithPdas<{
16
16
  vault: PublicKey;
17
17
  }>>;
@@ -19,12 +19,13 @@ const instructionResultHelpers_1 = require("../utils/instructionResultHelpers");
19
19
  * @param feePayer - Optional separate fee payer for transaction fees
20
20
  * @returns Instructions, signers array, and vault PDA
21
21
  */
22
- async function initializeSeasonVault(connection, admin, seasonNumber, feePayer) {
22
+ async function initializeSeasonVault(connection, admin, seasonNumber, tokenMint = constants_1.MIZD_TOKEN_MINT, feePayer) {
23
23
  const program = (0, programHelpers_1.getProgram)(connection);
24
- const [vaultPda] = (0, pdas_1.getSeasonDepositVaultPda)(seasonNumber);
24
+ const [vaultPda] = (0, pdas_1.getSeasonDepositVaultPda)(seasonNumber, tokenMint);
25
25
  const accounts = {
26
26
  seasonDepositVault: vaultPda,
27
27
  mizdMint: constants_1.MIZD_TOKEN_MINT,
28
+ tokenMint,
28
29
  admin: admin,
29
30
  tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
30
31
  systemProgram: web3_js_1.SystemProgram.programId,
@@ -3,12 +3,14 @@ import { Connection, PublicKey } from "@solana/web3.js";
3
3
  import { Season, SeasonMembership, SeasonSettings, TierNumber } from "../types";
4
4
  import { StandardInstructionResultWithPdas } from "../types/instructionResults";
5
5
  /**
6
- * Options for joinSeason instruction
6
+ * Options for joinSeason instruction (joining an existing season)
7
7
  */
8
8
  export interface JoinSeasonOptions {
9
9
  connection: Connection;
10
10
  user: PublicKey;
11
11
  seasonNumber: BN;
12
+ /** Token mint this season is scoped to (used for PDA derivation). Defaults to MIZD_TOKEN_MINT. */
13
+ tokenMint?: PublicKey;
12
14
  /** Tier number: 0=copper, 1=silver, 2=gold, 3=platinum, 4=mithril */
13
15
  tier: TierNumber;
14
16
  /** Optional referrer (PublicKey.default means no referrer) */
@@ -17,6 +19,24 @@ export interface JoinSeasonOptions {
17
19
  referrerTier?: TierNumber;
18
20
  /** If true, root admin funds join fee + deposit (currently only allowed for tier=0 on-chain). */
19
21
  star?: boolean;
22
+ /** If true, join uses launchpad mode (SOL in, virtual tokens escrowed; no SPL token accounts needed). */
23
+ launchpad?: boolean;
24
+ /** Launchpad slippage cap (lamports). Only used when launchpad=true. Defaults to u64::MAX. */
25
+ maxSolInLamports?: BN;
26
+ /**
27
+ * Launchpad slippage ergonomics:
28
+ * - Provide `expectedSolInLamports` (your quote) and `maxSlippageBps` and the program will enforce
29
+ * `sol_required <= expected * (1 + bps/10_000)`.
30
+ * - If both this and `maxSolInLamports` are provided, the program uses the tighter cap.
31
+ */
32
+ expectedSolInLamports?: BN;
33
+ /** Max slippage in basis points (0..=10_000). Used only when expectedSolInLamports > 0. */
34
+ maxSlippageBps?: number;
35
+ /**
36
+ * Star flag prompt: a short message (max 33 chars) displayed when users raise their flag.
37
+ * Only used when initializing a new season (first join). Ignored when joining existing season.
38
+ */
39
+ starFlagPrompt?: string;
20
40
  /** Optional injected timestamp (seconds) for optimistic state calculation */
21
41
  now?: BN;
22
42
  feePayer?: PublicKey;
@@ -25,12 +45,51 @@ export interface JoinSeasonOptions {
25
45
  season?: Season;
26
46
  };
27
47
  }
48
+ /**
49
+ * Options for initializing a new season (first joiner).
50
+ * Requires starFlagPrompt since it will be stored in the Season account.
51
+ */
52
+ export type JoinSeasonAndInitializeOptions = Omit<JoinSeasonOptions, "starFlagPrompt"> & {
53
+ /**
54
+ * Star flag prompt: a short message (max 33 chars) displayed when users raise their flag.
55
+ * REQUIRED when initializing a new season.
56
+ */
57
+ starFlagPrompt: string;
58
+ };
59
+ /**
60
+ * Options for the classic (non-launchpad) joinSeason wrapper.
61
+ * This avoids exposing nullable optional accounts to app code.
62
+ */
63
+ export type JoinSeasonClassicOptions = Omit<JoinSeasonOptions, "launchpad" | "maxSolInLamports" | "expectedSolInLamports" | "maxSlippageBps"> & {
64
+ launchpad?: never;
65
+ maxSolInLamports?: never;
66
+ expectedSolInLamports?: never;
67
+ maxSlippageBps?: never;
68
+ };
69
+ /**
70
+ * Options for the launchpad joinSeason wrapper.
71
+ * (No SPL token accounts needed; user pays SOL to the pool PDA.)
72
+ */
73
+ export type JoinSeasonLaunchpadOptions = Omit<JoinSeasonOptions, "launchpad" | "maxSolInLamports" | "expectedSolInLamports" | "maxSlippageBps"> & {
74
+ launchpad?: never;
75
+ /** Optional hard cap in lamports (0 disables this cap on-chain). */
76
+ maxSolInLamports?: BN;
77
+ /** Optional expected SOL in lamports for bps slippage protection (0 disables on-chain). */
78
+ expectedSolInLamports?: BN;
79
+ /** Optional max slippage bps (0 disables on-chain). */
80
+ maxSlippageBps?: number;
81
+ };
28
82
  type JoinSeasonPdas = {
29
83
  seasonSettings: PublicKey;
30
84
  season: PublicKey;
31
85
  seasonMembership: PublicKey;
86
+ moonpool: PublicKey;
87
+ moonpoolTreasury: PublicKey;
88
+ launchpadTokenMint: PublicKey;
89
+ sunpool: PublicKey;
32
90
  seasonDepositVault: PublicKey;
33
- seasonEscrowVault: PublicKey;
91
+ userJoinCredit: PublicKey;
92
+ userJoinCreditVault: PublicKey;
34
93
  };
35
94
  type JoinSeasonUpdatedAccounts = {
36
95
  seasonSettings?: SeasonSettings;
@@ -42,7 +101,7 @@ type JoinSeasonUpdatedAccounts = {
42
101
  *
43
102
  * Signers: user + root admin (root admin pays for signup-rewards vault ATA creation when a referrer is present)
44
103
  * User pays for season (if needed) and membership accounts
45
- * Transfers full tier deposit from user to vault, then escrows the pre-join portion
104
+ * Transfers active deposit into the season vault; the late-join escrow portion is converted into non-withdrawable join credit
46
105
  *
47
106
  * IMPORTANT: If providing a referrer, you MUST also provide referrerTier.
48
107
  * The referrerTier must match the tier the referrer actually joined the season with.
@@ -52,4 +111,34 @@ type JoinSeasonUpdatedAccounts = {
52
111
  * @returns Instructions, signers, PDAs, and optimistically created/updated accounts
53
112
  */
54
113
  export declare function joinSeason(options: JoinSeasonOptions): Promise<StandardInstructionResultWithPdas<JoinSeasonPdas, JoinSeasonUpdatedAccounts>>;
114
+ /**
115
+ * Convenience wrapper: classic (non-launchpad) joinSeason.
116
+ * - Keeps the existing MIZD-based join behavior.
117
+ * - App code never passes nullable optional accounts.
118
+ */
119
+ export declare function joinSeasonClassic(options: JoinSeasonClassicOptions): Promise<StandardInstructionResultWithPdas<JoinSeasonPdas, JoinSeasonUpdatedAccounts>>;
120
+ /**
121
+ * Convenience wrapper: launchpad joinSeason.
122
+ * - Uses SOL in + virtual token escrow.
123
+ * - App code never passes nullable optional accounts.
124
+ */
125
+ export declare function joinSeasonLaunchpad(options: JoinSeasonLaunchpadOptions): Promise<StandardInstructionResultWithPdas<JoinSeasonPdas, JoinSeasonUpdatedAccounts>>;
126
+ /**
127
+ * Join season AND initialize it (first joiner).
128
+ * Use this when you know the season doesn't exist yet.
129
+ *
130
+ * @param options - Options with REQUIRED starFlagPrompt
131
+ * @throws Error if starFlagPrompt is empty or exceeds 33 characters
132
+ */
133
+ export declare function joinSeasonAndInitialize(options: JoinSeasonAndInitializeOptions): Promise<StandardInstructionResultWithPdas<JoinSeasonPdas, JoinSeasonUpdatedAccounts>>;
134
+ /**
135
+ * Join season AND initialize it in launchpad mode (first joiner).
136
+ * Use this when you know the season doesn't exist yet and want launchpad mode.
137
+ *
138
+ * @param options - Options with REQUIRED starFlagPrompt
139
+ * @throws Error if starFlagPrompt is empty or exceeds 33 characters
140
+ */
141
+ export declare function joinSeasonLaunchpadAndInitialize(options: Omit<JoinSeasonLaunchpadOptions, "starFlagPrompt"> & {
142
+ starFlagPrompt: string;
143
+ }): Promise<StandardInstructionResultWithPdas<JoinSeasonPdas, JoinSeasonUpdatedAccounts>>;
55
144
  export {};
@@ -1,25 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.joinSeason = joinSeason;
4
+ exports.joinSeasonClassic = joinSeasonClassic;
5
+ exports.joinSeasonLaunchpad = joinSeasonLaunchpad;
6
+ exports.joinSeasonAndInitialize = joinSeasonAndInitialize;
7
+ exports.joinSeasonLaunchpadAndInitialize = joinSeasonLaunchpadAndInitialize;
4
8
  const anchor_1 = require("@coral-xyz/anchor");
5
9
  const web3_js_1 = require("@solana/web3.js");
6
10
  const spl_token_1 = require("@solana/spl-token");
7
- const types_1 = require("../types");
8
11
  const pdaManager_1 = require("../utils/pdaManager");
9
12
  const constants_1 = require("../utils/constants");
10
13
  const programHelpers_1 = require("../utils/programHelpers");
11
14
  const signerHelpers_1 = require("../utils/signerHelpers");
12
15
  const optimistic_1 = require("../optimistic");
13
- const pdas_1 = require("../utils/pdas");
14
- const tierPenalty_1 = require("../utils/tierPenalty");
15
- const enumHelpers_1 = require("../utils/enumHelpers");
16
16
  const remainingAccounts_1 = require("../utils/remainingAccounts");
17
17
  /**
18
18
  * Join a season
19
19
  *
20
20
  * Signers: user + root admin (root admin pays for signup-rewards vault ATA creation when a referrer is present)
21
21
  * User pays for season (if needed) and membership accounts
22
- * Transfers full tier deposit from user to vault, then escrows the pre-join portion
22
+ * Transfers active deposit into the season vault; the late-join escrow portion is converted into non-withdrawable join credit
23
23
  *
24
24
  * IMPORTANT: If providing a referrer, you MUST also provide referrerTier.
25
25
  * The referrerTier must match the tier the referrer actually joined the season with.
@@ -30,20 +30,44 @@ const remainingAccounts_1 = require("../utils/remainingAccounts");
30
30
  */
31
31
  async function joinSeason(options) {
32
32
  const program = (0, programHelpers_1.getProgram)(options.connection);
33
- const pdas = pdaManager_1.PDAManager.deriveJoinSeasonPdas({
33
+ const tokenMint = options.tokenMint ?? constants_1.MIZD_TOKEN_MINT;
34
+ const launchpad = options.launchpad ?? false;
35
+ const pdasBase = pdaManager_1.PDAManager.deriveJoinSeasonPdas({
34
36
  user: options.user,
35
37
  seasonNumber: options.seasonNumber,
36
38
  tier: options.tier,
39
+ tokenMint,
37
40
  });
38
- const rootAdminTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(constants_1.MIZD_TOKEN_MINT, constants_1.ADMIN_PUBLIC_KEY);
39
- const userMizdAta = (0, spl_token_1.getAssociatedTokenAddressSync)(constants_1.MIZD_TOKEN_MINT, options.user);
41
+ const rootAdminTokenAccount = launchpad
42
+ ? null
43
+ : (0, spl_token_1.getAssociatedTokenAddressSync)(constants_1.MIZD_TOKEN_MINT, constants_1.ADMIN_PUBLIC_KEY);
44
+ const userMizdAta = launchpad
45
+ ? null
46
+ : (0, spl_token_1.getAssociatedTokenAddressSync)(constants_1.MIZD_TOKEN_MINT, options.user);
47
+ // Join credit PDA + its vault ATA (owner is off-curve PDA, so allowOwnerOffCurve=true).
48
+ const userJoinCreditVault = launchpad
49
+ ? null
50
+ : (0, spl_token_1.getAssociatedTokenAddressSync)(constants_1.MIZD_TOKEN_MINT, pdasBase.userJoinCredit, true);
51
+ const pdas = {
52
+ ...pdasBase,
53
+ userJoinCreditVault: userJoinCreditVault ?? web3_js_1.PublicKey.default,
54
+ };
40
55
  const accounts = {
41
56
  seasonSettings: pdas.seasonSettings,
42
57
  season: pdas.season,
43
58
  seasonMembership: pdas.seasonMembership,
44
- seasonDepositVault: pdas.seasonDepositVault,
45
- seasonEscrowVault: pdas.seasonEscrowVault,
59
+ // SECURITY: Pool accounts are now MANDATORY (non-optional) to prevent bypassing
60
+ // the mode check. The on-chain program validates pool state to ensure
61
+ // subsequent seasons use the same mode (launchpad/classic) as the first season.
62
+ moonpool: pdas.moonpool,
63
+ moonpoolTreasury: pdas.moonpoolTreasury,
64
+ launchpadTokenMint: pdas.launchpadTokenMint,
65
+ sunpool: pdas.sunpool,
66
+ seasonDepositVault: launchpad ? null : pdas.seasonDepositVault,
67
+ userJoinCredit: launchpad ? null : pdas.userJoinCredit,
68
+ userJoinCreditVault: launchpad ? null : userJoinCreditVault,
46
69
  mizdMint: constants_1.MIZD_TOKEN_MINT,
70
+ tokenMint,
47
71
  rootAdmin: constants_1.ADMIN_PUBLIC_KEY,
48
72
  rootAdminTokenAccount,
49
73
  // Always pass the canonical ATA; it may not exist yet (created on-chain with root admin as payer).
@@ -51,6 +75,7 @@ async function joinSeason(options) {
51
75
  user: options.user,
52
76
  associatedTokenProgram: spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID,
53
77
  tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
78
+ token2022Program: spl_token_1.TOKEN_2022_PROGRAM_ID,
54
79
  systemProgram: web3_js_1.SystemProgram.programId,
55
80
  };
56
81
  const referrer = options.referrer ?? web3_js_1.PublicKey.default;
@@ -65,12 +90,13 @@ async function joinSeason(options) {
65
90
  tier: options.tier,
66
91
  referrer,
67
92
  referrerTier: options.referrerTier,
93
+ tokenMint,
68
94
  })
69
95
  : [];
70
96
  const methodBuilder = program.methods
71
97
  // Anchor expects BN for u64 args.
72
98
  // referrerTier defaults to 0 if no referrer (ignored on-chain)
73
- .joinSeason(options.seasonNumber, options.tier, referrer, options.referrerTier ?? 0, options.star ?? false)
99
+ .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 ?? "")
74
100
  .accounts(accounts);
75
101
  if (remainingAccounts.length > 0) {
76
102
  methodBuilder.remainingAccounts(remainingAccounts);
@@ -86,41 +112,26 @@ async function joinSeason(options) {
86
112
  let newSeasonMembership;
87
113
  let updatedSeason;
88
114
  if (curr.seasonSettings) {
89
- const [, bump] = (0, pdas_1.getSeasonMembershipPda)(options.seasonNumber, options.user, options.tier);
90
- // Mirror on-chain join_season.rs:
91
- // current_window = (now - season.started_at) / window_duration (integer division)
92
- // joined_window_number = current_window (after bounds checks)
93
- const totalWindows = curr.seasonSettings.totalWindowsPerSeason;
94
- const depositTier = (0, tierPenalty_1.tierNumberToDepositTier)(options.tier);
95
- const perWindowPenalty = (0, tierPenalty_1.getTierPenaltyPerWindow)(depositTier);
96
- const depositFull = perWindowPenalty.muln(totalWindows);
97
- let joinedWindowNumber = new anchor_1.BN(0);
98
- if (curr.season) {
99
- if ((0, enumHelpers_1.isSeasonState)(curr.season.seasonState, types_1.SeasonState.Uninitialized)) {
100
- // On-chain: season is initialized with started_at = now, so elapsed = 0 -> current_window = 0
101
- joinedWindowNumber = new anchor_1.BN(0);
102
- }
103
- else if (curr.seasonSettings.windowDuration &&
104
- !curr.seasonSettings.windowDuration.isZero()) {
105
- const startedAt = curr.season.startedAt;
106
- const elapsed = now.gte(startedAt) ? now.sub(startedAt) : new anchor_1.BN(0);
107
- joinedWindowNumber = elapsed.div(curr.seasonSettings.windowDuration);
108
- }
109
- }
110
- // If this would fail on-chain (current_window >= total_windows), skip optimistic updates.
111
- if (joinedWindowNumber.gte(new anchor_1.BN(totalWindows))) {
115
+ const optimistic = (0, optimistic_1.computeJoinSeasonOptimistic)({
116
+ user: options.user,
117
+ seasonNumber: options.seasonNumber,
118
+ tier: options.tier,
119
+ referrer: options.referrer ?? web3_js_1.PublicKey.default,
120
+ tokenMint,
121
+ now,
122
+ star: options.star ?? false,
123
+ seasonSettings: curr.seasonSettings,
124
+ ...(curr.season ? { season: curr.season } : {}),
125
+ });
126
+ if (optimistic.kind === "skip") {
112
127
  return {
113
128
  instructions: [instruction],
114
129
  signers,
115
130
  pdas,
116
131
  };
117
132
  }
118
- const depositEscrowed = perWindowPenalty.mul(joinedWindowNumber);
119
- const depositActive = depositFull.sub(depositEscrowed);
120
- newSeasonMembership = (0, optimistic_1.initializeSeasonMembership)(options.user, options.seasonNumber, depositTier, options.referrer ?? web3_js_1.PublicKey.default, depositActive, depositEscrowed, now, joinedWindowNumber, bump, options.star ?? false);
121
- if (curr.season) {
122
- updatedSeason = (0, optimistic_1.updateSeasonForJoin)(curr.season, depositActive, depositTier, joinedWindowNumber, totalWindows);
123
- }
133
+ newSeasonMembership = optimistic.newSeasonMembership;
134
+ updatedSeason = optimistic.updatedSeason;
124
135
  }
125
136
  return {
126
137
  instructions: [instruction],
@@ -139,4 +150,70 @@ async function joinSeason(options) {
139
150
  : {}),
140
151
  };
141
152
  }
153
+ /**
154
+ * Convenience wrapper: classic (non-launchpad) joinSeason.
155
+ * - Keeps the existing MIZD-based join behavior.
156
+ * - App code never passes nullable optional accounts.
157
+ */
158
+ async function joinSeasonClassic(options) {
159
+ // IMPORTANT: With `exactOptionalPropertyTypes`, we must OMIT optional props (not set them to `undefined`).
160
+ return joinSeason({ ...options, launchpad: false });
161
+ }
162
+ /**
163
+ * Convenience wrapper: launchpad joinSeason.
164
+ * - Uses SOL in + virtual token escrow.
165
+ * - App code never passes nullable optional accounts.
166
+ */
167
+ async function joinSeasonLaunchpad(options) {
168
+ // IMPORTANT: With `exactOptionalPropertyTypes`, we must OMIT optional props (not set them to `undefined`).
169
+ const { maxSolInLamports, expectedSolInLamports, maxSlippageBps, ...rest } = options;
170
+ return joinSeason({
171
+ ...rest,
172
+ launchpad: true,
173
+ ...(maxSolInLamports ? { maxSolInLamports } : {}),
174
+ ...(expectedSolInLamports ? { expectedSolInLamports } : {}),
175
+ ...(typeof maxSlippageBps === "number" ? { maxSlippageBps } : {}),
176
+ });
177
+ }
178
+ /**
179
+ * Join season AND initialize it (first joiner).
180
+ * Use this when you know the season doesn't exist yet.
181
+ *
182
+ * @param options - Options with REQUIRED starFlagPrompt
183
+ * @throws Error if starFlagPrompt is empty or exceeds 33 characters
184
+ */
185
+ async function joinSeasonAndInitialize(options) {
186
+ // Validate starFlagPrompt
187
+ if (!options.starFlagPrompt || options.starFlagPrompt.length === 0) {
188
+ throw new Error("starFlagPrompt is required when initializing a new season");
189
+ }
190
+ if (options.starFlagPrompt.length > 33) {
191
+ throw new Error("starFlagPrompt cannot exceed 33 characters");
192
+ }
193
+ return joinSeason(options);
194
+ }
195
+ /**
196
+ * Join season AND initialize it in launchpad mode (first joiner).
197
+ * Use this when you know the season doesn't exist yet and want launchpad mode.
198
+ *
199
+ * @param options - Options with REQUIRED starFlagPrompt
200
+ * @throws Error if starFlagPrompt is empty or exceeds 33 characters
201
+ */
202
+ async function joinSeasonLaunchpadAndInitialize(options) {
203
+ // Validate starFlagPrompt
204
+ if (!options.starFlagPrompt || options.starFlagPrompt.length === 0) {
205
+ throw new Error("starFlagPrompt is required when initializing a new season");
206
+ }
207
+ if (options.starFlagPrompt.length > 33) {
208
+ throw new Error("starFlagPrompt cannot exceed 33 characters");
209
+ }
210
+ const { maxSolInLamports, expectedSolInLamports, maxSlippageBps, ...rest } = options;
211
+ return joinSeason({
212
+ ...rest,
213
+ launchpad: true,
214
+ ...(maxSolInLamports ? { maxSolInLamports } : {}),
215
+ ...(expectedSolInLamports ? { expectedSolInLamports } : {}),
216
+ ...(typeof maxSlippageBps === "number" ? { maxSlippageBps } : {}),
217
+ });
218
+ }
142
219
  // getTierPenaltyPerWindow imported from ../utils/tierPenalty
@@ -0,0 +1,19 @@
1
+ import { BN } from "@coral-xyz/anchor";
2
+ import { Connection, PublicKey } from "@solana/web3.js";
3
+ import { StandardInstructionResultWithPdas } from "../types/instructionResults";
4
+ export interface SellMizdOptions {
5
+ connection: Connection;
6
+ user: PublicKey;
7
+ /** MIZD input (base units). */
8
+ mizdInUnits: BN;
9
+ /** Slippage protection: minimum SOL out (lamports). */
10
+ minSolOutLamports: BN;
11
+ /** Must be the on-chain root admin (ADMIN_PUBLIC_KEY); required signer on-chain. */
12
+ admin?: PublicKey;
13
+ feePayer?: PublicKey;
14
+ }
15
+ export declare function sellMizd(opts: SellMizdOptions): Promise<StandardInstructionResultWithPdas<{
16
+ bondingCurve: PublicKey;
17
+ mizdVault: PublicKey;
18
+ userMizdAta: PublicKey;
19
+ }>>;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sellMizd = sellMizd;
4
+ const web3_js_1 = require("@solana/web3.js");
5
+ const spl_token_1 = require("@solana/spl-token");
6
+ const instructionResultHelpers_1 = require("../utils/instructionResultHelpers");
7
+ const constants_1 = require("../utils/constants");
8
+ const pdaManager_1 = require("../utils/pdaManager");
9
+ const programHelpers_1 = require("../utils/programHelpers");
10
+ const signerHelpers_1 = require("../utils/signerHelpers");
11
+ async function sellMizd(opts) {
12
+ const program = (0, programHelpers_1.getProgram)(opts.connection);
13
+ const admin = opts.admin ?? constants_1.ADMIN_PUBLIC_KEY;
14
+ const pdas = pdaManager_1.PDAManager.deriveBondingCurvePdas();
15
+ const userMizdAta = (0, spl_token_1.getAssociatedTokenAddressSync)(constants_1.MIZD_TOKEN_MINT, opts.user);
16
+ const accounts = {
17
+ bondingCurve: pdas.bondingCurve,
18
+ mizdVault: pdas.mizdVault,
19
+ mizdMint: constants_1.MIZD_TOKEN_MINT,
20
+ admin,
21
+ user: opts.user,
22
+ userMizdAta,
23
+ associatedTokenProgram: spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID,
24
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
25
+ systemProgram: web3_js_1.SystemProgram.programId,
26
+ };
27
+ const instruction = await program.methods
28
+ .sellMizd(opts.mizdInUnits, opts.minSolOutLamports)
29
+ .accounts(accounts)
30
+ .instruction();
31
+ const feePayer = (0, signerHelpers_1.resolveFeePayer)({ feePayer: opts.feePayer, admin });
32
+ const signers = (0, signerHelpers_1.buildSigners)([(0, signerHelpers_1.asAdminSigner)(admin), (0, signerHelpers_1.asUserSigner)(opts.user)], feePayer);
33
+ return (0, instructionResultHelpers_1.singleInstruction)(instruction, {
34
+ signers,
35
+ pdas: {
36
+ bondingCurve: pdas.bondingCurve,
37
+ mizdVault: pdas.mizdVault,
38
+ userMizdAta,
39
+ },
40
+ });
41
+ }