proof-of-take-sdk 1.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 (90) hide show
  1. package/FINAL_USAGE.md +342 -0
  2. package/LIBRARY_GUIDE.md +400 -0
  3. package/LICENSE +22 -0
  4. package/README.md +370 -0
  5. package/dist/client.d.ts +32 -0
  6. package/dist/client.js +47 -0
  7. package/dist/constants/season.d.ts +18 -0
  8. package/dist/constants/season.js +22 -0
  9. package/dist/getters/getMiztake.d.ts +11 -0
  10. package/dist/getters/getMiztake.js +34 -0
  11. package/dist/getters/getMiztakeStatistics.d.ts +10 -0
  12. package/dist/getters/getMiztakeStatistics.js +20 -0
  13. package/dist/getters/getTokenVault.d.ts +30 -0
  14. package/dist/getters/getTokenVault.js +56 -0
  15. package/dist/getters/getUserStats.d.ts +21 -0
  16. package/dist/getters/getUserStats.js +43 -0
  17. package/dist/getters/index.d.ts +7 -0
  18. package/dist/getters/index.js +23 -0
  19. package/dist/idl/idl.d.ts +2 -0
  20. package/dist/idl/idl.js +8 -0
  21. package/dist/idl/proof_of_take.json +3803 -0
  22. package/dist/index.d.ts +48 -0
  23. package/dist/index.js +92 -0
  24. package/dist/instructions/claimReferralPenaltyForWindow.d.ts +38 -0
  25. package/dist/instructions/claimReferralPenaltyForWindow.js +72 -0
  26. package/dist/instructions/claimWindowRewards.d.ts +48 -0
  27. package/dist/instructions/claimWindowRewards.js +94 -0
  28. package/dist/instructions/confirmedPostOnX.d.ts +51 -0
  29. package/dist/instructions/confirmedPostOnX.js +78 -0
  30. package/dist/instructions/createMiztake.d.ts +90 -0
  31. package/dist/instructions/createMiztake.js +166 -0
  32. package/dist/instructions/initializeEscrowVault.d.ts +15 -0
  33. package/dist/instructions/initializeEscrowVault.js +36 -0
  34. package/dist/instructions/initializeSeasonSettings.d.ts +20 -0
  35. package/dist/instructions/initializeSeasonSettings.js +39 -0
  36. package/dist/instructions/initializeSeasonVault.d.ts +20 -0
  37. package/dist/instructions/initializeSeasonVault.js +43 -0
  38. package/dist/instructions/initializeStatistics.d.ts +32 -0
  39. package/dist/instructions/initializeStatistics.js +73 -0
  40. package/dist/instructions/joinSeason.d.ts +50 -0
  41. package/dist/instructions/joinSeason.js +120 -0
  42. package/dist/instructions/toggleSeasonPause.d.ts +22 -0
  43. package/dist/instructions/toggleSeasonPause.js +42 -0
  44. package/dist/instructions/updateSeasonAdmin.d.ts +23 -0
  45. package/dist/instructions/updateSeasonAdmin.js +43 -0
  46. package/dist/instructions/viewCurrentSeason.d.ts +12 -0
  47. package/dist/instructions/viewCurrentSeason.js +30 -0
  48. package/dist/instructions/viewSeasonMembershipStatus.d.ts +16 -0
  49. package/dist/instructions/viewSeasonMembershipStatus.js +33 -0
  50. package/dist/instructions/viewWindowStatus.d.ts +15 -0
  51. package/dist/instructions/viewWindowStatus.js +28 -0
  52. package/dist/instructions/withdrawSeasonDeposit.d.ts +38 -0
  53. package/dist/instructions/withdrawSeasonDeposit.js +66 -0
  54. package/dist/optimistic/index.d.ts +7 -0
  55. package/dist/optimistic/index.js +33 -0
  56. package/dist/types/accountTypes.d.ts +121 -0
  57. package/dist/types/accountTypes.js +2 -0
  58. package/dist/types/instructionResults.d.ts +44 -0
  59. package/dist/types/instructionResults.js +2 -0
  60. package/dist/types/proof_of_take.d.ts +3809 -0
  61. package/dist/types/proof_of_take.js +2 -0
  62. package/dist/types.d.ts +232 -0
  63. package/dist/types.js +16 -0
  64. package/dist/utils/accountUpdates.d.ts +245 -0
  65. package/dist/utils/accountUpdates.js +611 -0
  66. package/dist/utils/anchorHelpers.d.ts +7 -0
  67. package/dist/utils/anchorHelpers.js +21 -0
  68. package/dist/utils/constants.d.ts +21 -0
  69. package/dist/utils/constants.js +31 -0
  70. package/dist/utils/conversions.d.ts +25 -0
  71. package/dist/utils/conversions.js +53 -0
  72. package/dist/utils/enumHelpers.d.ts +63 -0
  73. package/dist/utils/enumHelpers.js +110 -0
  74. package/dist/utils/index.d.ts +0 -0
  75. package/dist/utils/index.js +2 -0
  76. package/dist/utils/pdaManager.d.ts +106 -0
  77. package/dist/utils/pdaManager.js +89 -0
  78. package/dist/utils/pdas.d.ts +68 -0
  79. package/dist/utils/pdas.js +128 -0
  80. package/dist/utils/programHelpers.d.ts +9 -0
  81. package/dist/utils/programHelpers.js +18 -0
  82. package/dist/utils/signerHelpers.d.ts +17 -0
  83. package/dist/utils/signerHelpers.js +21 -0
  84. package/dist/utils/simulationHelpers.d.ts +121 -0
  85. package/dist/utils/simulationHelpers.js +183 -0
  86. package/dist/utils/tierPenalty.d.ts +9 -0
  87. package/dist/utils/tierPenalty.js +24 -0
  88. package/dist/utils/transactionBuilder.d.ts +77 -0
  89. package/dist/utils/transactionBuilder.js +147 -0
  90. package/package.json +50 -0
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createMiztake = createMiztake;
4
+ exports.getMiztakePdaForParams = getMiztakePdaForParams;
5
+ const anchor_1 = require("@coral-xyz/anchor");
6
+ const web3_js_1 = require("@solana/web3.js");
7
+ const types_1 = require("../types");
8
+ const pdaManager_1 = require("../utils/pdaManager");
9
+ const programHelpers_1 = require("../utils/programHelpers");
10
+ const signerHelpers_1 = require("../utils/signerHelpers");
11
+ const conversions_1 = require("../utils/conversions");
12
+ const optimistic_1 = require("../optimistic");
13
+ const enumHelpers_1 = require("../utils/enumHelpers");
14
+ /**
15
+ * Create a new miztake
16
+ *
17
+ * 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)
20
+ *
21
+ * @param options - Create miztake options
22
+ * @returns Instructions, signers, PDAs, and optimistically updated accounts
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * const result = await createMiztake({
27
+ * connection,
28
+ * params,
29
+ * user: userWallet.publicKey,
30
+ * admin: adminWallet.publicKey,
31
+ * seasonNumber: new BN(1),
32
+ * windowNumber: new BN(5),
33
+ * seasonMembershipId: new BN(123),
34
+ * currentAccounts: {
35
+ * userStats: currentUserStats,
36
+ * miztakeStatistics: currentStats,
37
+ * season: currentSeason,
38
+ * seasonSettings: settings,
39
+ * }
40
+ * });
41
+ * ```
42
+ */
43
+ async function createMiztake(options) {
44
+ const program = (0, programHelpers_1.getProgram)(options.connection);
45
+ // Derive all PDAs using PDAManager
46
+ const pdas = pdaManager_1.PDAManager.deriveMiztakePdas({
47
+ shaHash: options.params.shaHash,
48
+ telegramId: options.params.telegramId,
49
+ seasonNumber: options.seasonNumber,
50
+ windowNumber: options.windowNumber,
51
+ seasonMembershipId: options.seasonMembershipId,
52
+ user: options.user,
53
+ });
54
+ // Build typed accounts object
55
+ const accounts = {
56
+ miztake: pdas.miztake,
57
+ userStats: pdas.userStats,
58
+ miztakeStatistics: pdas.miztakeStatistics,
59
+ seasonSettings: pdas.seasonSettings,
60
+ season: pdas.season,
61
+ seasonMembership: pdas.seasonMembership,
62
+ rewardWindow: pdas.rewardWindow,
63
+ userWindowParticipation: pdas.userWindowParticipation,
64
+ user: options.user,
65
+ admin: options.admin,
66
+ systemProgram: web3_js_1.SystemProgram.programId,
67
+ };
68
+ // Build instruction
69
+ const shaHashBytes = (0, conversions_1.sha256HexToBytes32)(options.params.shaHash);
70
+ const instruction = await program.methods
71
+ .createMiztake(
72
+ // Anchor expects BN for u64 args.
73
+ options.params.telegramId, options.params.telegramUsername, options.params.perceptualHash, options.params.averageHash, options.params.differenceHash, options.params.waveletHash, options.params.shaHash, Array.from(shaHashBytes), options.params.computedAt, options.seasonNumber, options.windowNumber, options.seasonMembershipId)
74
+ .accounts(accounts)
75
+ .instruction();
76
+ // Build signers
77
+ const signers = (0, signerHelpers_1.buildSigners)([
78
+ { publicKey: options.user, role: "user" },
79
+ { publicKey: options.admin, role: "admin" },
80
+ ], options.feePayer);
81
+ // OPTIMISTIC UPDATES
82
+ const now = (0, optimistic_1.getCurrentTimestamp)(options.now);
83
+ const curr = options.currentAccounts || {};
84
+ // 1. Update or initialize UserStats
85
+ const updatedUserStats = curr.userStats
86
+ ? (0, optimistic_1.updateUserStatsForMiztakeCreation)(curr.userStats, options.params.telegramId, now)
87
+ : undefined;
88
+ // 2. Update MiztakeStatistics
89
+ let updatedStatistics;
90
+ let newMiztakeId;
91
+ if (curr.miztakeStatistics) {
92
+ const result = (0, optimistic_1.updateMiztakeStatisticsForCreation)(curr.miztakeStatistics);
93
+ updatedStatistics = result.statistics;
94
+ newMiztakeId = result.newMiztakeId;
95
+ }
96
+ else {
97
+ newMiztakeId = new anchor_1.BN(1); // Placeholder
98
+ }
99
+ // 3. Initialize UserWindowParticipation
100
+ const updatedUserWindowParticipation = (0, optimistic_1.initializeUserWindowParticipation)(options.user, options.seasonNumber, options.windowNumber, options.seasonMembershipId, newMiztakeId);
101
+ // 4. Initialize RewardWindow if needed
102
+ let updatedRewardWindow;
103
+ if (curr.rewardWindow) {
104
+ // Use helper to handle both enum formats
105
+ if ((0, enumHelpers_1.isWindowState)(curr.rewardWindow.windowState, types_1.WindowState.Uninitialized) &&
106
+ curr.season &&
107
+ curr.seasonSettings) {
108
+ updatedRewardWindow = (0, optimistic_1.initializeRewardWindow)(options.seasonNumber, options.windowNumber, curr.season, curr.seasonSettings.windowDuration);
109
+ }
110
+ else {
111
+ updatedRewardWindow = curr.rewardWindow;
112
+ }
113
+ }
114
+ else if (curr.season && curr.seasonSettings) {
115
+ updatedRewardWindow = (0, optimistic_1.initializeRewardWindow)(options.seasonNumber, options.windowNumber, curr.season, curr.seasonSettings.windowDuration);
116
+ }
117
+ // 5. Build expected Miztake object
118
+ const miztake = {
119
+ id: newMiztakeId,
120
+ telegramId: options.params.telegramId,
121
+ telegramUsername: options.params.telegramUsername,
122
+ perceptualHash: options.params.perceptualHash,
123
+ averageHash: options.params.averageHash,
124
+ differenceHash: options.params.differenceHash,
125
+ waveletHash: options.params.waveletHash,
126
+ shaHash: options.params.shaHash,
127
+ computedAt: options.params.computedAt,
128
+ creator: options.user,
129
+ userStats: pdas.userStats,
130
+ userKey: options.user,
131
+ onchainCreatedAt: now,
132
+ usedInSeason: new anchor_1.BN(0),
133
+ usedInWindow: new anchor_1.BN(0),
134
+ };
135
+ return {
136
+ instructions: [instruction],
137
+ signers,
138
+ pdas,
139
+ updatedAccounts: {
140
+ miztake,
141
+ ...(updatedUserStats && { userStats: updatedUserStats }),
142
+ ...(updatedStatistics && { miztakeStatistics: updatedStatistics }),
143
+ ...(curr.seasonSettings && { seasonSettings: curr.seasonSettings }),
144
+ ...(curr.season && { season: curr.season }),
145
+ ...(curr.seasonMembership && { seasonMembership: curr.seasonMembership }),
146
+ ...(updatedRewardWindow && { rewardWindow: updatedRewardWindow }),
147
+ ...(updatedUserWindowParticipation && {
148
+ userWindowParticipation: updatedUserWindowParticipation,
149
+ }),
150
+ },
151
+ };
152
+ }
153
+ /**
154
+ * Get the miztake PDA that would be created for given parameters
155
+ * Useful for checking if a miztake already exists
156
+ */
157
+ function getMiztakePdaForParams(params) {
158
+ return pdaManager_1.PDAManager.deriveMiztakePdas({
159
+ shaHash: params.shaHash,
160
+ telegramId: params.telegramId,
161
+ seasonNumber: new anchor_1.BN(0),
162
+ windowNumber: new anchor_1.BN(0),
163
+ seasonMembershipId: new anchor_1.BN(0),
164
+ user: web3_js_1.PublicKey.default,
165
+ }).miztake;
166
+ }
@@ -0,0 +1,15 @@
1
+ import { Connection, PublicKey, TransactionInstruction } from "@solana/web3.js";
2
+ import { SignerInfo } from "../utils/signerHelpers";
3
+ /**
4
+ * Initialize season escrow vault
5
+ *
6
+ * Single signer: admin (pays for account creation)
7
+ * This initializes the token vault for escrowed (protected) deposits.
8
+ */
9
+ export declare function initializeEscrowVault(connection: Connection, admin: PublicKey, feePayer?: PublicKey): Promise<{
10
+ instructions: TransactionInstruction[];
11
+ signers: SignerInfo[];
12
+ pdas: {
13
+ vault: PublicKey;
14
+ };
15
+ }>;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initializeEscrowVault = initializeEscrowVault;
4
+ const web3_js_1 = require("@solana/web3.js");
5
+ const spl_token_1 = require("@solana/spl-token");
6
+ const pdas_1 = require("../utils/pdas");
7
+ const constants_1 = require("../utils/constants");
8
+ const programHelpers_1 = require("../utils/programHelpers");
9
+ const signerHelpers_1 = require("../utils/signerHelpers");
10
+ /**
11
+ * Initialize season escrow vault
12
+ *
13
+ * Single signer: admin (pays for account creation)
14
+ * This initializes the token vault for escrowed (protected) deposits.
15
+ */
16
+ async function initializeEscrowVault(connection, admin, feePayer) {
17
+ const program = (0, programHelpers_1.getProgram)(connection);
18
+ const [vaultPda] = (0, pdas_1.getSeasonEscrowVaultPda)();
19
+ const accounts = {
20
+ seasonEscrowVault: vaultPda,
21
+ mizdMint: constants_1.MIZD_TOKEN_MINT,
22
+ admin,
23
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
24
+ systemProgram: web3_js_1.SystemProgram.programId,
25
+ };
26
+ const instruction = await program.methods
27
+ .initializeEscrowVault()
28
+ .accounts(accounts)
29
+ .instruction();
30
+ const signers = (0, signerHelpers_1.buildSigners)([{ publicKey: admin, role: "admin" }], feePayer);
31
+ return {
32
+ instructions: [instruction],
33
+ signers,
34
+ pdas: { vault: vaultPda },
35
+ };
36
+ }
@@ -0,0 +1,20 @@
1
+ import { Connection, PublicKey, TransactionInstruction } from "@solana/web3.js";
2
+ import { SignerInfo } from "../utils/signerHelpers";
3
+ /**
4
+ * Initialize season settings
5
+ *
6
+ * Single signer: admin (pays for account creation)
7
+ * This initializes the global season settings account
8
+ *
9
+ * @param connection - Solana connection
10
+ * @param admin - Admin public key (must sign and pays for account)
11
+ * @param feePayer - Optional separate fee payer for transaction fees
12
+ * @returns Instructions, signers array, and season settings PDA
13
+ */
14
+ export declare function initializeSeasonSettings(connection: Connection, admin: PublicKey, feePayer?: PublicKey): Promise<{
15
+ instructions: TransactionInstruction[];
16
+ signers: SignerInfo[];
17
+ pdas: {
18
+ seasonSettings: PublicKey;
19
+ };
20
+ }>;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initializeSeasonSettings = initializeSeasonSettings;
4
+ const web3_js_1 = require("@solana/web3.js");
5
+ const pdas_1 = require("../utils/pdas");
6
+ const programHelpers_1 = require("../utils/programHelpers");
7
+ const signerHelpers_1 = require("../utils/signerHelpers");
8
+ /**
9
+ * Initialize season settings
10
+ *
11
+ * Single signer: admin (pays for account creation)
12
+ * This initializes the global season settings account
13
+ *
14
+ * @param connection - Solana connection
15
+ * @param admin - Admin public key (must sign and pays for account)
16
+ * @param feePayer - Optional separate fee payer for transaction fees
17
+ * @returns Instructions, signers array, and season settings PDA
18
+ */
19
+ async function initializeSeasonSettings(connection, admin, feePayer) {
20
+ const program = (0, programHelpers_1.getProgram)(connection);
21
+ const [seasonSettingsPda] = (0, pdas_1.getSeasonSettingsPda)();
22
+ const accounts = {
23
+ seasonSettings: seasonSettingsPda,
24
+ admin: admin,
25
+ systemProgram: web3_js_1.SystemProgram.programId,
26
+ };
27
+ const instruction = await program.methods
28
+ .initializeSeasonSettings()
29
+ .accounts(accounts)
30
+ .instruction();
31
+ const signers = (0, signerHelpers_1.buildSigners)([{ publicKey: admin, role: "admin" }], feePayer);
32
+ return {
33
+ instructions: [instruction],
34
+ signers,
35
+ pdas: {
36
+ seasonSettings: seasonSettingsPda,
37
+ },
38
+ };
39
+ }
@@ -0,0 +1,20 @@
1
+ import { Connection, PublicKey, TransactionInstruction } from "@solana/web3.js";
2
+ import { SignerInfo } from "../utils/signerHelpers";
3
+ /**
4
+ * Initialize season deposit vault
5
+ *
6
+ * Single signer: admin (pays for account creation)
7
+ * This initializes the token vault for season deposits
8
+ *
9
+ * @param connection - Solana connection
10
+ * @param admin - Admin public key (must sign and pays for account)
11
+ * @param feePayer - Optional separate fee payer for transaction fees
12
+ * @returns Instructions, signers array, and vault PDA
13
+ */
14
+ export declare function initializeSeasonVault(connection: Connection, admin: PublicKey, feePayer?: PublicKey): Promise<{
15
+ instructions: TransactionInstruction[];
16
+ signers: SignerInfo[];
17
+ pdas: {
18
+ vault: PublicKey;
19
+ };
20
+ }>;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initializeSeasonVault = initializeSeasonVault;
4
+ const web3_js_1 = require("@solana/web3.js");
5
+ const spl_token_1 = require("@solana/spl-token");
6
+ const pdas_1 = require("../utils/pdas");
7
+ const constants_1 = require("../utils/constants");
8
+ const programHelpers_1 = require("../utils/programHelpers");
9
+ const signerHelpers_1 = require("../utils/signerHelpers");
10
+ /**
11
+ * Initialize season deposit vault
12
+ *
13
+ * Single signer: admin (pays for account creation)
14
+ * This initializes the token vault for season deposits
15
+ *
16
+ * @param connection - Solana connection
17
+ * @param admin - Admin public key (must sign and pays for account)
18
+ * @param feePayer - Optional separate fee payer for transaction fees
19
+ * @returns Instructions, signers array, and vault PDA
20
+ */
21
+ async function initializeSeasonVault(connection, admin, feePayer) {
22
+ const program = (0, programHelpers_1.getProgram)(connection);
23
+ const [vaultPda] = (0, pdas_1.getSeasonDepositVaultPda)();
24
+ const accounts = {
25
+ seasonDepositVault: vaultPda,
26
+ mizdMint: constants_1.MIZD_TOKEN_MINT,
27
+ admin: admin,
28
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
29
+ systemProgram: web3_js_1.SystemProgram.programId,
30
+ };
31
+ const instruction = await program.methods
32
+ .initializeSeasonVault()
33
+ .accounts(accounts)
34
+ .instruction();
35
+ const signers = (0, signerHelpers_1.buildSigners)([{ publicKey: admin, role: "admin" }], feePayer);
36
+ return {
37
+ instructions: [instruction],
38
+ signers,
39
+ pdas: {
40
+ vault: vaultPda,
41
+ },
42
+ };
43
+ }
@@ -0,0 +1,32 @@
1
+ import { Connection, PublicKey, TransactionInstruction } from "@solana/web3.js";
2
+ /**
3
+ * Initialize the global statistics PDA
4
+ *
5
+ * ADMIN ONLY - Must be called once before program can be used
6
+ *
7
+ * @param connection - Solana connection
8
+ * @param admin - Admin public key (must match ADMIN_PUBLIC_KEY)
9
+ * @param payer - Public key paying for account creation (can be same as admin)
10
+ * @returns Instructions, signers, and created PDA
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const { instructions, signers, miztakeStatisticsPda } = await initializeStatistics(
15
+ * connection,
16
+ * adminWallet.publicKey,
17
+ * adminWallet.publicKey // Admin pays for creation
18
+ * );
19
+ * ```
20
+ */
21
+ export declare function initializeStatistics(connection: Connection, admin: PublicKey, payer?: PublicKey): Promise<{
22
+ instructions: TransactionInstruction[];
23
+ signers: {
24
+ publicKey: PublicKey;
25
+ role: string;
26
+ }[];
27
+ miztakeStatisticsPda: PublicKey;
28
+ }>;
29
+ /**
30
+ * Check if statistics are already initialized
31
+ */
32
+ export declare function isInitialized(connection: Connection): Promise<boolean>;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initializeStatistics = initializeStatistics;
4
+ exports.isInitialized = isInitialized;
5
+ const anchor_1 = require("@coral-xyz/anchor");
6
+ const web3_js_1 = require("@solana/web3.js");
7
+ const pdas_1 = require("../utils/pdas");
8
+ const idl_1 = require("../idl/idl");
9
+ const anchorHelpers_1 = require("../utils/anchorHelpers");
10
+ /**
11
+ * Initialize the global statistics PDA
12
+ *
13
+ * ADMIN ONLY - Must be called once before program can be used
14
+ *
15
+ * @param connection - Solana connection
16
+ * @param admin - Admin public key (must match ADMIN_PUBLIC_KEY)
17
+ * @param payer - Public key paying for account creation (can be same as admin)
18
+ * @returns Instructions, signers, and created PDA
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const { instructions, signers, miztakeStatisticsPda } = await initializeStatistics(
23
+ * connection,
24
+ * adminWallet.publicKey,
25
+ * adminWallet.publicKey // Admin pays for creation
26
+ * );
27
+ * ```
28
+ */
29
+ async function initializeStatistics(connection, admin, payer) {
30
+ // Create program instance
31
+ const provider = (0, anchorHelpers_1.createReadOnlyProvider)(connection);
32
+ const program = new anchor_1.Program(idl_1.IDL, provider);
33
+ const actualPayer = payer || admin;
34
+ // Derive PDA
35
+ const [miztakeStatisticsPda] = (0, pdas_1.getMiztakeStatisticsPda)();
36
+ // Build instruction
37
+ const accounts = {
38
+ miztakeStatistics: miztakeStatisticsPda,
39
+ admin,
40
+ payer: actualPayer,
41
+ systemProgram: web3_js_1.SystemProgram.programId,
42
+ };
43
+ const instruction = await program.methods
44
+ .initializeStatistics()
45
+ .accounts(accounts)
46
+ .instruction();
47
+ // Build signers list
48
+ const signers = [{ publicKey: admin, role: "admin" }];
49
+ if (actualPayer.toBase58() !== admin.toBase58()) {
50
+ signers.push({ publicKey: actualPayer, role: "payer" });
51
+ }
52
+ return {
53
+ instructions: [instruction],
54
+ signers,
55
+ miztakeStatisticsPda, // Created by this instruction
56
+ };
57
+ }
58
+ /**
59
+ * Check if statistics are already initialized
60
+ */
61
+ async function isInitialized(connection) {
62
+ try {
63
+ // Create program instance
64
+ const provider = (0, anchorHelpers_1.createReadOnlyProvider)(connection);
65
+ const program = new anchor_1.Program(idl_1.IDL, provider);
66
+ const [statisticsPda] = (0, pdas_1.getMiztakeStatisticsPda)();
67
+ await program.account.miztakeStatistics.fetch(statisticsPda);
68
+ return true;
69
+ }
70
+ catch {
71
+ return false;
72
+ }
73
+ }
@@ -0,0 +1,50 @@
1
+ import { BN } from "@coral-xyz/anchor";
2
+ import { Connection, PublicKey, TransactionInstruction } from "@solana/web3.js";
3
+ import { Season, SeasonMembership, SeasonSettings, SeasonDepositTier } from "../types";
4
+ import { SignerInfo } from "../utils/signerHelpers";
5
+ /**
6
+ * Options for joinSeason instruction
7
+ */
8
+ export interface JoinSeasonOptions {
9
+ connection: Connection;
10
+ user: PublicKey;
11
+ userTokenAccount: PublicKey;
12
+ seasonMembershipId: BN;
13
+ seasonNumber: BN;
14
+ depositTier: SeasonDepositTier;
15
+ /** Optional referrer (PublicKey.default means no referrer) */
16
+ referrer?: PublicKey;
17
+ /** Optional injected timestamp (seconds) for optimistic state calculation */
18
+ now?: BN;
19
+ feePayer?: PublicKey;
20
+ currentAccounts?: {
21
+ seasonSettings?: SeasonSettings;
22
+ season?: Season;
23
+ };
24
+ }
25
+ /**
26
+ * Join a season
27
+ *
28
+ * Single signer: user (pays for accounts and transfers full tier deposit)
29
+ * User pays for season (if needed) and membership accounts
30
+ * Transfers full tier deposit from user to vault, then escrows the pre-join portion
31
+ *
32
+ * @param options - Join season options
33
+ * @returns Instructions, signers, PDAs, and optimistically created/updated accounts
34
+ */
35
+ export declare function joinSeason(options: JoinSeasonOptions): Promise<{
36
+ instructions: TransactionInstruction[];
37
+ signers: SignerInfo[];
38
+ pdas: {
39
+ seasonSettings: PublicKey;
40
+ season: PublicKey;
41
+ seasonMembership: PublicKey;
42
+ seasonDepositVault: PublicKey;
43
+ seasonEscrowVault: PublicKey;
44
+ };
45
+ updatedAccounts?: {
46
+ seasonSettings?: SeasonSettings;
47
+ season?: Season;
48
+ seasonMembership?: SeasonMembership;
49
+ };
50
+ }>;
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.joinSeason = joinSeason;
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 types_1 = require("../types");
8
+ const pdaManager_1 = require("../utils/pdaManager");
9
+ const constants_1 = require("../utils/constants");
10
+ const programHelpers_1 = require("../utils/programHelpers");
11
+ const signerHelpers_1 = require("../utils/signerHelpers");
12
+ const optimistic_1 = require("../optimistic");
13
+ const pdas_1 = require("../utils/pdas");
14
+ /**
15
+ * Join a season
16
+ *
17
+ * Single signer: user (pays for accounts and transfers full tier deposit)
18
+ * User pays for season (if needed) and membership accounts
19
+ * Transfers full tier deposit from user to vault, then escrows the pre-join portion
20
+ *
21
+ * @param options - Join season options
22
+ * @returns Instructions, signers, PDAs, and optimistically created/updated accounts
23
+ */
24
+ async function joinSeason(options) {
25
+ const program = (0, programHelpers_1.getProgram)(options.connection);
26
+ const pdas = pdaManager_1.PDAManager.deriveJoinSeasonPdas({
27
+ user: options.user,
28
+ seasonNumber: options.seasonNumber,
29
+ seasonMembershipId: options.seasonMembershipId,
30
+ });
31
+ const accounts = {
32
+ seasonSettings: pdas.seasonSettings,
33
+ season: pdas.season,
34
+ seasonMembership: pdas.seasonMembership,
35
+ seasonDepositVault: pdas.seasonDepositVault,
36
+ seasonEscrowVault: pdas.seasonEscrowVault,
37
+ mizdMint: constants_1.MIZD_TOKEN_MINT,
38
+ userTokenAccount: options.userTokenAccount,
39
+ user: options.user,
40
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
41
+ systemProgram: web3_js_1.SystemProgram.programId,
42
+ };
43
+ const instruction = await program.methods
44
+ // Anchor expects BN for u64 args.
45
+ .joinSeason(options.seasonMembershipId, options.seasonNumber, options.depositTier, options.referrer ?? web3_js_1.PublicKey.default)
46
+ .accounts(accounts)
47
+ .instruction();
48
+ const signers = (0, signerHelpers_1.buildSigners)([{ publicKey: options.user, role: "user" }], options.feePayer);
49
+ // OPTIMISTIC UPDATES
50
+ const curr = options.currentAccounts || {};
51
+ const now = (0, optimistic_1.getCurrentTimestamp)(options.now);
52
+ let newSeasonMembership;
53
+ let updatedSeason;
54
+ if (curr.seasonSettings) {
55
+ const [, bump] = (0, pdas_1.getSeasonMembershipPda)(options.user, options.seasonMembershipId);
56
+ // Mirror on-chain join_season.rs:
57
+ // current_window = (now - season.started_at) / window_duration (integer division)
58
+ // joined_window_number = current_window (after bounds checks)
59
+ const totalWindows = curr.seasonSettings.totalWindowsPerSeason;
60
+ const perWindowPenalty = getTierPenaltyPerWindow(options.depositTier);
61
+ const depositFull = perWindowPenalty.muln(totalWindows);
62
+ let joinedWindowNumber = new anchor_1.BN(0);
63
+ if (curr.season) {
64
+ if (curr.season.seasonState === types_1.SeasonState.Uninitialized) {
65
+ // On-chain: season is initialized with started_at = now, so elapsed = 0 -> current_window = 0
66
+ joinedWindowNumber = new anchor_1.BN(0);
67
+ }
68
+ else if (curr.seasonSettings.windowDuration &&
69
+ !curr.seasonSettings.windowDuration.isZero()) {
70
+ const startedAt = curr.season.startedAt;
71
+ const elapsed = now.gte(startedAt) ? now.sub(startedAt) : new anchor_1.BN(0);
72
+ joinedWindowNumber = elapsed.div(curr.seasonSettings.windowDuration);
73
+ }
74
+ }
75
+ // If this would fail on-chain (current_window >= total_windows), skip optimistic updates.
76
+ if (joinedWindowNumber.gte(new anchor_1.BN(totalWindows))) {
77
+ return {
78
+ instructions: [instruction],
79
+ signers,
80
+ pdas,
81
+ };
82
+ }
83
+ const depositEscrowed = perWindowPenalty.mul(joinedWindowNumber);
84
+ const depositActive = depositFull.sub(depositEscrowed);
85
+ newSeasonMembership = (0, optimistic_1.initializeSeasonMembership)(options.user, options.seasonMembershipId, options.seasonNumber, options.depositTier, options.referrer ?? web3_js_1.PublicKey.default, depositActive, depositEscrowed, now, joinedWindowNumber, bump);
86
+ if (curr.season) {
87
+ updatedSeason = (0, optimistic_1.updateSeasonForJoin)(curr.season, depositActive, options.depositTier, joinedWindowNumber, totalWindows);
88
+ }
89
+ }
90
+ return {
91
+ instructions: [instruction],
92
+ signers,
93
+ pdas,
94
+ ...(curr.seasonSettings || updatedSeason || newSeasonMembership
95
+ ? {
96
+ updatedAccounts: {
97
+ ...(curr.seasonSettings && { seasonSettings: curr.seasonSettings }),
98
+ ...(updatedSeason && { season: updatedSeason }),
99
+ ...(newSeasonMembership && {
100
+ seasonMembership: newSeasonMembership,
101
+ }),
102
+ },
103
+ }
104
+ : {}),
105
+ };
106
+ }
107
+ function getTierPenaltyPerWindow(tier) {
108
+ // Base units (7 decimals): 1 MIZD = 10_000_000
109
+ if ("copper" in tier)
110
+ return new anchor_1.BN(1000000); // 0.1 MIZD
111
+ if ("silver" in tier)
112
+ return new anchor_1.BN(10000000); // 1 MIZD
113
+ if ("gold" in tier)
114
+ return new anchor_1.BN(100000000); // 10 MIZD
115
+ if ("platinum" in tier)
116
+ return new anchor_1.BN(1000000000); // 100 MIZD
117
+ if ("mithril" in tier)
118
+ return new anchor_1.BN(10000000000); // 1,000 MIZD
119
+ throw new Error("Unknown depositTier");
120
+ }
@@ -0,0 +1,22 @@
1
+ import { Connection, PublicKey, TransactionInstruction } from "@solana/web3.js";
2
+ import { SeasonSettings } from "../types";
3
+ import { SignerInfo } from "../utils/signerHelpers";
4
+ /**
5
+ * Toggle season system pause
6
+ *
7
+ * Single signer: admin (season admin)
8
+ * Toggles the isPaused flag on season settings
9
+ *
10
+ * @param connection - Solana connection
11
+ * @param admin - Season admin's public key
12
+ * @param feePayer - Optional separate fee payer for transaction fees
13
+ * @param seasonSettings - Optional season settings (returns updated version)
14
+ * @returns Instructions, signers, and optimistically updated settings
15
+ */
16
+ export declare function toggleSeasonPause(connection: Connection, admin: PublicKey, feePayer?: PublicKey, seasonSettings?: SeasonSettings): Promise<{
17
+ instructions: TransactionInstruction[];
18
+ signers: SignerInfo[];
19
+ updatedAccounts?: {
20
+ seasonSettings: SeasonSettings;
21
+ };
22
+ }>;