proof-of-take-sdk 2.0.0 → 3.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.
@@ -13,6 +13,34 @@ import { Miztake, UserStats, MiztakeStatistics, SeasonSettings, Season, SeasonMe
13
13
  * @returns Current Unix timestamp in seconds
14
14
  */
15
15
  export declare function getCurrentTimestamp(now?: BN): BN;
16
+ /**
17
+ * Build the Season account object that is expected to be created by on-chain lazy initialization.
18
+ *
19
+ * This is a PURE helper (no RPC). It mirrors `season_helpers::initialize_season`:
20
+ * - `season_state = Active`
21
+ * - `started_at = current_time`
22
+ * - `ends_at = current_time + season_duration`
23
+ * - all counters and totals initialized to zero
24
+ * - schedule `eligible_stake_per_window` initialized to 21 zeros
25
+ * - PDA bump derived locally from seeds (no RPC)
26
+ *
27
+ * IMPORTANT:
28
+ * To match on-chain state exactly, you must supply the same `startedAt` that the transaction
29
+ * will observe on-chain (i.e. `Clock::get()?.unix_timestamp` at execution time) and the same
30
+ * season duration as stored in SeasonSettings at that moment. If you don't have settings locally,
31
+ * we fall back to the canonical defaults (7 days, 21 windows).
32
+ */
33
+ export declare function expectedToBeLazyInitialized(params: {
34
+ /** Season number to initialize. */
35
+ seasonNumber: BN;
36
+ /** Unix timestamp in seconds used as `started_at` (i64 on-chain). */
37
+ startedAt: BN;
38
+ /**
39
+ * Optional settings snapshot (recommended) to compute `endsAt` and `totalWindows`.
40
+ * Providing this avoids drift if settings ever change.
41
+ */
42
+ seasonSettings?: Pick<SeasonSettings, "seasonDuration" | "totalWindowsPerSeason" | "lastSeasonEndsAt">;
43
+ }): Season;
16
44
  /**
17
45
  * Create an empty/initialized UserStats object
18
46
  * Used when initializing a new user stats account
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getCurrentTimestamp = getCurrentTimestamp;
4
+ exports.expectedToBeLazyInitialized = expectedToBeLazyInitialized;
4
5
  exports.createEmptyUserStats = createEmptyUserStats;
5
6
  exports.initializeUserStats = initializeUserStats;
6
7
  exports.updateUserStatsForMiztakeCreation = updateUserStatsForMiztakeCreation;
@@ -42,6 +43,55 @@ function getCurrentTimestamp(now) {
42
43
  return now;
43
44
  return new anchor_1.BN(Math.floor(Date.now() / 1000)); // Convert JS milliseconds → seconds
44
45
  }
46
+ /**
47
+ * Build the Season account object that is expected to be created by on-chain lazy initialization.
48
+ *
49
+ * This is a PURE helper (no RPC). It mirrors `season_helpers::initialize_season`:
50
+ * - `season_state = Active`
51
+ * - `started_at = current_time`
52
+ * - `ends_at = current_time + season_duration`
53
+ * - all counters and totals initialized to zero
54
+ * - schedule `eligible_stake_per_window` initialized to 21 zeros
55
+ * - PDA bump derived locally from seeds (no RPC)
56
+ *
57
+ * IMPORTANT:
58
+ * To match on-chain state exactly, you must supply the same `startedAt` that the transaction
59
+ * will observe on-chain (i.e. `Clock::get()?.unix_timestamp` at execution time) and the same
60
+ * season duration as stored in SeasonSettings at that moment. If you don't have settings locally,
61
+ * we fall back to the canonical defaults (7 days, 21 windows).
62
+ */
63
+ function expectedToBeLazyInitialized(params) {
64
+ const seasonDuration = params.seasonSettings?.seasonDuration ?? new anchor_1.BN(604800); // 7 days
65
+ const totalWindows = params.seasonSettings?.totalWindowsPerSeason ?? 21;
66
+ // Derive bump seed locally (mirrors Anchor ctx.bumps.season).
67
+ const [, bump] = (0, pdas_1.getSeasonPda)(params.seasonNumber);
68
+ const lastSeasonEndsAt = params.seasonSettings?.lastSeasonEndsAt ?? new anchor_1.BN(0);
69
+ // If lastSeasonEndsAt is 0 (first season), use params.startedAt.
70
+ // Otherwise, use lastSeasonEndsAt exactly (gapless).
71
+ // Note: We ignore params.startedAt in the gapless case to match on-chain logic,
72
+ // but in practice the caller should ideally pass the correct gapless time.
73
+ const effectiveStartedAt = lastSeasonEndsAt.isZero()
74
+ ? params.startedAt
75
+ : lastSeasonEndsAt;
76
+ return {
77
+ seasonNumber: params.seasonNumber,
78
+ seasonState: types_1.SeasonState.Active,
79
+ startedAt: effectiveStartedAt,
80
+ endsAt: effectiveStartedAt.add(seasonDuration),
81
+ totalWindows,
82
+ totalMembers: new anchor_1.BN(0),
83
+ copperMembersCount: new anchor_1.BN(0),
84
+ silverMembersCount: new anchor_1.BN(0),
85
+ goldMembersCount: new anchor_1.BN(0),
86
+ platinumMembersCount: new anchor_1.BN(0),
87
+ mithrilMembersCount: new anchor_1.BN(0),
88
+ eligibleStakePerWindow: Array.from({ length: 21 }, () => new anchor_1.BN(0)),
89
+ totalDepositsHeld: new anchor_1.BN(0),
90
+ totalSuccessfulPosts: new anchor_1.BN(0),
91
+ totalPenaltiesCollected: new anchor_1.BN(0),
92
+ bump,
93
+ };
94
+ }
45
95
  /**
46
96
  * Create an empty/initialized UserStats object
47
97
  * Used when initializing a new user stats account
@@ -30,8 +30,8 @@ class PDAManager {
30
30
  seasonSettings: (0, pdas_1.getSeasonSettingsPda)()[0],
31
31
  season: (0, pdas_1.getSeasonPda)(params.seasonNumber)[0],
32
32
  seasonMembership: (0, pdas_1.getSeasonMembershipPda)(params.seasonNumber, params.user, params.tier)[0],
33
- seasonDepositVault: (0, pdas_1.getSeasonDepositVaultPda)()[0],
34
- seasonEscrowVault: (0, pdas_1.getSeasonEscrowVaultPda)()[0],
33
+ seasonDepositVault: (0, pdas_1.getSeasonDepositVaultPda)(params.seasonNumber)[0],
34
+ seasonEscrowVault: (0, pdas_1.getSeasonEscrowVaultPda)(params.seasonNumber)[0],
35
35
  };
36
36
  }
37
37
  /**
@@ -57,7 +57,7 @@ class PDAManager {
57
57
  rewardWindow: (0, pdas_1.getRewardWindowPda)(params.seasonNumber, params.windowNumber)[0],
58
58
  userWindowParticipation: (0, pdas_1.getUserWindowParticipationPda)(params.seasonNumber, params.user, params.tier, params.windowNumber)[0],
59
59
  seasonMembership: (0, pdas_1.getSeasonMembershipPda)(params.seasonNumber, params.user, params.tier)[0],
60
- seasonDepositVault: (0, pdas_1.getSeasonDepositVaultPda)()[0],
60
+ seasonDepositVault: (0, pdas_1.getSeasonDepositVaultPda)(params.seasonNumber)[0],
61
61
  };
62
62
  }
63
63
  /**
@@ -68,8 +68,8 @@ class PDAManager {
68
68
  seasonSettings: (0, pdas_1.getSeasonSettingsPda)()[0],
69
69
  season: (0, pdas_1.getSeasonPda)(params.seasonNumber)[0],
70
70
  seasonMembership: (0, pdas_1.getSeasonMembershipPda)(params.seasonNumber, params.user, params.tier)[0],
71
- seasonDepositVault: (0, pdas_1.getSeasonDepositVaultPda)()[0],
72
- seasonEscrowVault: (0, pdas_1.getSeasonEscrowVaultPda)()[0],
71
+ seasonDepositVault: (0, pdas_1.getSeasonDepositVaultPda)(params.seasonNumber)[0],
72
+ seasonEscrowVault: (0, pdas_1.getSeasonEscrowVaultPda)(params.seasonNumber)[0],
73
73
  };
74
74
  }
75
75
  /**
@@ -82,7 +82,7 @@ class PDAManager {
82
82
  seasonMembership: (0, pdas_1.getSeasonMembershipPda)(params.seasonNumber, params.referredUser, params.tier)[0],
83
83
  userWindowParticipation: (0, pdas_1.getUserWindowParticipationPda)(params.seasonNumber, params.referredUser, params.tier, params.windowNumber)[0],
84
84
  referralPenaltyClaim: (0, pdas_1.getReferralPenaltyClaimPda)(params.seasonNumber, params.referredUser, params.tier, params.windowNumber)[0],
85
- seasonDepositVault: (0, pdas_1.getSeasonDepositVaultPda)()[0],
85
+ seasonDepositVault: (0, pdas_1.getSeasonDepositVaultPda)(params.seasonNumber)[0],
86
86
  };
87
87
  }
88
88
  }
@@ -59,11 +59,11 @@ export declare function getUserWindowParticipationPda(seasonNumber: BN, user: Pu
59
59
  /**
60
60
  * Derive the Season Deposit Vault PDA
61
61
  */
62
- export declare function getSeasonDepositVaultPda(): [PublicKey, number];
62
+ export declare function getSeasonDepositVaultPda(seasonNumber: BN): [PublicKey, number];
63
63
  /**
64
64
  * Derive the Season Escrow Vault PDA
65
65
  */
66
- export declare function getSeasonEscrowVaultPda(): [PublicKey, number];
66
+ export declare function getSeasonEscrowVaultPda(seasonNumber: BN): [PublicKey, number];
67
67
  /**
68
68
  * Derive the ReferralPenaltyClaim PDA
69
69
  * PDA model:
@@ -111,14 +111,14 @@ function getUserWindowParticipationPda(seasonNumber, user, tier, windowNumber) {
111
111
  /**
112
112
  * Derive the Season Deposit Vault PDA
113
113
  */
114
- function getSeasonDepositVaultPda() {
115
- return web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("season_deposit_vault")], constants_1.PROGRAM_ID);
114
+ function getSeasonDepositVaultPda(seasonNumber) {
115
+ return web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("season_deposit_vault"), seasonNumber.toArrayLike(Buffer, "le", 8)], constants_1.PROGRAM_ID);
116
116
  }
117
117
  /**
118
118
  * Derive the Season Escrow Vault PDA
119
119
  */
120
- function getSeasonEscrowVaultPda() {
121
- return web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("season_escrow_vault")], constants_1.PROGRAM_ID);
120
+ function getSeasonEscrowVaultPda(seasonNumber) {
121
+ return web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("season_escrow_vault"), seasonNumber.toArrayLike(Buffer, "le", 8)], constants_1.PROGRAM_ID);
122
122
  }
123
123
  /**
124
124
  * Derive the ReferralPenaltyClaim PDA
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "proof-of-take-sdk",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "TypeScript SDK for Proof of Take Solana program",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",