@namehash/ens-referrals 1.8.1 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,178 +1,307 @@
1
- import { Address } from 'viem';
2
- import { UnixTimestamp, AccountId, Duration } from '@ensnode/ensnode-sdk';
1
+ import { NormalizedAddress, UnixTimestamp, AccountId, Duration, Address } from 'enssdk';
2
+ import { PriceUsdc, PriceEth, SerializedPriceEth, SerializedPriceUsdc } from '@ensnode/ensnode-sdk';
3
3
 
4
- declare const validateLowercaseAddress: (address: Address) => void;
5
- declare const normalizeAddress: (address: Address) => Address;
4
+ declare const validateNormalizedAddress: (address: NormalizedAddress) => void;
6
5
 
7
6
  /**
8
- * Represents a quantity of USD.
7
+ * Discriminant values for the award model used in a referral program edition.
9
8
  *
10
- * @invariant Guaranteed to be a finite non-negative number (>= 0)
11
- */
12
- type USDQuantity = number;
13
- declare function isValidUSDQuantity(value: USDQuantity): boolean;
14
- declare function validateUSDQuantity(value: USDQuantity): void;
15
-
16
- /**
17
- * Start date for the ENS Holiday Awards referral program.
18
- * 2025-12-01T00:00:00Z (December 1, 2025 at 00:00:00 UTC)
19
- */
20
- declare const ENS_HOLIDAY_AWARDS_START_DATE: UnixTimestamp;
21
- /**
22
- * End date for the ENS Holiday Awards referral program.
23
- * 2025-12-31T23:59:59Z (December 31, 2025 at 23:59:59 UTC)
24
- */
25
- declare const ENS_HOLIDAY_AWARDS_END_DATE: UnixTimestamp;
9
+ * @remarks Clients MUST check `awardModel` before accessing model-specific fields.
10
+ * Editions with unrecognized `awardModel` values are preserved as
11
+ * {@link ReferralProgramRulesUnrecognized} during parsing (see
12
+ * `makeReferralProgramEditionConfigSetArraySchema`). Clients must handle this variant — typically
13
+ * by skipping those editions with a warning log rather than crashing.
14
+ */
15
+ declare const ReferralProgramAwardModels: {
16
+ readonly PieSplit: "pie-split";
17
+ readonly RevShareCap: "rev-share-cap";
18
+ readonly Unrecognized: "unrecognized";
19
+ };
20
+ type ReferralProgramAwardModel = (typeof ReferralProgramAwardModels)[keyof typeof ReferralProgramAwardModels];
26
21
  /**
27
- * The maximum number of qualified referrers for ENS Holiday Awards.
22
+ * Base fields shared across all referral program rule types.
23
+ *
24
+ * Both `ReferralProgramRulesPieSplit` and `ReferralProgramRulesRevShareCap` are structurally
25
+ * compatible with this interface, so it can be used wherever only the common fields are needed
26
+ * (e.g., `assertLeaderboardInputs`).
28
27
  */
29
- declare const ENS_HOLIDAY_AWARDS_MAX_QUALIFIED_REFERRERS = 10;
28
+ interface BaseReferralProgramRules {
29
+ /**
30
+ * Discriminant: identifies the award model for this edition.
31
+ */
32
+ awardModel: ReferralProgramAwardModel;
33
+ /**
34
+ * The start time of the referral program.
35
+ */
36
+ startTime: UnixTimestamp;
37
+ /**
38
+ * The end time of the referral program.
39
+ * @invariant Guaranteed to be greater than or equal to `startTime`
40
+ */
41
+ endTime: UnixTimestamp;
42
+ /**
43
+ * The account ID of the subregistry for the referral program.
44
+ */
45
+ subregistryId: AccountId;
46
+ /**
47
+ * URL to the full rules document for these rules.
48
+ * @example new URL("https://ensawards.org/ens-holiday-awards-rules")
49
+ */
50
+ rulesUrl: URL;
51
+ /**
52
+ * Whether the awards for this edition have been distributed.
53
+ *
54
+ * When `true` and `now > endTime`, the status transitions from `AwardsReview` to `Closed`.
55
+ */
56
+ areAwardsDistributed: boolean;
57
+ }
30
58
  /**
31
- * The total value of the award pool in USD.
59
+ * Rules for a referral program edition whose `awardModel` is not recognized by this client version.
60
+ *
61
+ * @remarks
62
+ * This is a **client-side forward-compatibility** type only. It is never serialized or processed
63
+ * by business logic on the backend. When the server introduces a new award model type, older
64
+ * clients preserve the edition rather than silently dropping it, and downstream code that
65
+ * encounters this type should skip it with a warning log rather than crashing.
32
66
  */
33
- declare const ENS_HOLIDAY_AWARDS_TOTAL_AWARD_POOL_VALUE: USDQuantity;
34
- interface ReferralProgramRules {
67
+ interface ReferralProgramRulesUnrecognized extends BaseReferralProgramRules {
35
68
  /**
36
- * The total value of the award pool in USD.
69
+ * Discriminant always `"unrecognized"`.
70
+ */
71
+ awardModel: typeof ReferralProgramAwardModels.Unrecognized;
72
+ /**
73
+ * The original, unrecognized `awardModel` string received from the server.
74
+ *
75
+ * @remarks Preserved for logging and debugging. Never used for business logic.
76
+ */
77
+ originalAwardModel: string;
78
+ }
79
+ declare const validateBaseReferralProgramRules: (rules: BaseReferralProgramRules) => void;
80
+
81
+ interface ReferralProgramRulesPieSplit extends BaseReferralProgramRules {
82
+ /**
83
+ * Discriminant: identifies this as a "pie-split" award model edition.
84
+ *
85
+ * In pie-split, the top-N referrers split an award pool proportionally
86
+ * based on their scored duration (with rank-based boost).
87
+ */
88
+ awardModel: typeof ReferralProgramAwardModels.PieSplit;
89
+ /**
90
+ * The award pool in USDC.
37
91
  *
38
92
  * NOTE: Awards will actually be distributed in $ENS tokens.
39
93
  */
40
- totalAwardPoolValue: USDQuantity;
94
+ awardPool: PriceUsdc;
41
95
  /**
42
96
  * The maximum number of referrers that will qualify to receive a non-zero `awardPoolShare`.
43
97
  *
44
98
  * @invariant Guaranteed to be a non-negative integer (>= 0)
45
99
  */
46
100
  maxQualifiedReferrers: number;
101
+ }
102
+ declare const validateReferralProgramRulesPieSplit: (rules: ReferralProgramRulesPieSplit) => void;
103
+ declare const buildReferralProgramRulesPieSplit: (awardPool: PriceUsdc, maxQualifiedReferrers: number, startTime: UnixTimestamp, endTime: UnixTimestamp, subregistryId: AccountId, rulesUrl: URL, areAwardsDistributed: boolean) => ReferralProgramRulesPieSplit;
104
+
105
+ /**
106
+ * The types of admin actions that can be taken upon a referrer in a rev-share-cap edition.
107
+ */
108
+ declare const AdminActionTypes: {
47
109
  /**
48
- * The start time of the referral program.
110
+ * The referrer is disqualified for awards.
49
111
  */
50
- startTime: UnixTimestamp;
112
+ readonly Disqualification: "Disqualification";
51
113
  /**
52
- * The end time of the referral program.
53
- * @invariant Guaranteed to be greater than or equal to `startTime`
114
+ * The referrer is warned about a potential disqualification but may still be qualified for awards.
54
115
  */
55
- endTime: UnixTimestamp;
116
+ readonly Warning: "Warning";
117
+ };
118
+ type AdminActionType = (typeof AdminActionTypes)[keyof typeof AdminActionTypes];
119
+ /**
120
+ * An admin action to disqualify a referrer from receiving awards for an edition.
121
+ */
122
+ interface AdminActionDisqualification {
123
+ actionType: typeof AdminActionTypes.Disqualification;
56
124
  /**
57
- * The account ID of the subregistry for the referral program.
125
+ * The Ethereum address of the affected referrer, as a {@link NormalizedAddress}.
58
126
  */
59
- subregistryId: AccountId;
127
+ referrer: NormalizedAddress;
128
+ /**
129
+ * A short message explaining the disqualification.
130
+ *
131
+ * @invariant Must be a trimmed, non-empty string.
132
+ */
133
+ reason: string;
60
134
  }
61
- declare const validateReferralProgramRules: (rules: ReferralProgramRules) => void;
62
- declare const buildReferralProgramRules: (totalAwardPoolValue: USDQuantity, maxQualifiedReferrers: number, startTime: UnixTimestamp, endTime: UnixTimestamp, subregistryId: AccountId) => ReferralProgramRules;
63
-
64
135
  /**
65
- * The score of a referrer.
66
- *
67
- * @invariant Guaranteed to be a finite non-negative number (>= 0)
136
+ * An admin action to warn a referrer that their eligibility for receiving awards for an edition
137
+ * is at risk unless the referrer takes corrective actions.
68
138
  */
69
- type ReferrerScore = number;
70
- declare const isValidReferrerScore: (score: ReferrerScore) => boolean;
71
- declare const validateReferrerScore: (score: ReferrerScore) => void;
139
+ interface AdminActionWarning {
140
+ actionType: typeof AdminActionTypes.Warning;
141
+ /**
142
+ * The Ethereum address of the affected referrer, as a {@link NormalizedAddress}.
143
+ */
144
+ referrer: NormalizedAddress;
145
+ /**
146
+ * A short message explaining the warning.
147
+ *
148
+ * @invariant Must be a trimmed, non-empty string.
149
+ */
150
+ reason: string;
151
+ }
72
152
  /**
73
- * Calculate the score of a referrer based on the total incremental duration
74
- * (in seconds) of registrations and renewals for direct subnames of .eth
75
- * referred by the referrer within the ENS Holiday Awards period.
76
- *
77
- * @param totalIncrementalDuration - The total incremental duration (in seconds)
78
- * of referrals made by a referrer within the {@link ReferralProgramRules}.
79
- * @returns The score of the referrer.
153
+ * A discriminated union of all admin action types.
80
154
  */
81
- declare const calcReferrerScore: (totalIncrementalDuration: Duration) => ReferrerScore;
82
-
155
+ type AdminAction = AdminActionDisqualification | AdminActionWarning;
156
+ interface ReferralProgramRulesRevShareCap extends BaseReferralProgramRules {
157
+ /**
158
+ * Discriminant: identifies this as a "rev-share-cap" award model edition.
159
+ *
160
+ * In rev-share-cap, each qualified referrer receives a share of their base revenue
161
+ * contribution (base-fee-only: `baseAnnualRevenueContribution` × years of incremental duration),
162
+ * subject to the award pool cap and a minimum qualification threshold.
163
+ */
164
+ awardModel: typeof ReferralProgramAwardModels.RevShareCap;
165
+ /**
166
+ * The award pool in USDC (acts as a cap on total payouts).
167
+ */
168
+ awardPool: PriceUsdc;
169
+ /**
170
+ * The minimum base revenue contribution required for a referrer to qualify for awards.
171
+ */
172
+ minBaseRevenueContribution: PriceUsdc;
173
+ /**
174
+ * Base revenue contribution in USDC per year of incremental duration from referred registrations and renewals.
175
+ *
176
+ * Used in `rev-share-cap` qualification and award calculations:
177
+ * 1 year of incremental duration → this many USDC of base revenue (base-fee-only, excluding premiums).
178
+ */
179
+ baseAnnualRevenueContribution: PriceUsdc;
180
+ /**
181
+ * The fraction of the referrer's base revenue contribution that constitutes their max potential award for each referral.
182
+ * This is the max for a referral that ignores the possibility of the referrer not having achieved qualification for awards yet, the referrer being disqualified from awards, or the award pool being exhausted.
183
+ *
184
+ * @invariant Guaranteed to be a number between 0 and 1 (inclusive)
185
+ */
186
+ maxBaseRevenueShare: number;
187
+ /**
188
+ * Admin actions for this edition.
189
+ *
190
+ * @invariant No duplicate referrer addresses (a referrer can have at most one admin action).
191
+ */
192
+ adminActions: AdminAction[];
193
+ }
194
+ declare const validateReferralProgramRulesRevShareCap: (rules: ReferralProgramRulesRevShareCap) => void;
195
+ declare const buildReferralProgramRulesRevShareCap: (awardPool: PriceUsdc, minBaseRevenueContribution: PriceUsdc, baseAnnualRevenueContribution: PriceUsdc, maxBaseRevenueShare: number, startTime: UnixTimestamp, endTime: UnixTimestamp, subregistryId: AccountId, rulesUrl: URL, areAwardsDistributed: boolean, adminActions?: AdminAction[]) => ReferralProgramRulesRevShareCap;
83
196
  /**
84
- * The rank of a referrer relative to all other referrers, where 1 is the
85
- * top-ranked referrer.
197
+ * Determine if a referrer is qualified under rev-share-cap rules.
86
198
  *
87
- * @invariant Guaranteed to be a positive integer (> 0)
199
+ * A referrer is qualified if they meet the revenue threshold AND are not admin-disqualified.
200
+ *
201
+ * @param referrer - The referrer's address.
202
+ * @param totalBaseRevenueContribution - The referrer's total base revenue contribution.
203
+ * @param rules - The rev-share-cap rules of the referral program.
88
204
  */
89
- type ReferrerRank = number;
90
- declare const validateReferrerRank: (rank: ReferrerRank) => void;
205
+ declare function isReferrerQualifiedRevShareCap(referrer: NormalizedAddress, totalBaseRevenueContribution: PriceUsdc, rules: ReferralProgramRulesRevShareCap): boolean;
206
+
91
207
  /**
92
- * Determine if a referrer with the given `rank` is qualified to receive a non-zero `awardPoolShare` according to the given `rules`.
208
+ * The rules of a referral program edition.
93
209
  *
94
- * @param rank - The rank of the referrer relative to all other referrers on a {@link ReferrerLeaderboard}.
95
- * @param rules - The rules of the referral program that generated the `rank`.
210
+ * Use `awardModel` to discriminate between rule types at runtime:
211
+ * - `"pie-split"` {@link ReferralProgramRulesPieSplit}
212
+ * - `"rev-share-cap"` → {@link ReferralProgramRulesRevShareCap}
213
+ * - `"unrecognized"` → {@link ReferralProgramRulesUnrecognized} (client-side forward-compatibility
214
+ * placeholder for editions whose `awardModel` string is not known to this client version)
215
+ *
216
+ * Internal business logic only handles the known variants (`pie-split`, `rev-share-cap`).
217
+ * Unrecognized editions should be skipped with a warning log rather than crashing.
96
218
  */
97
- declare function isReferrerQualified(rank: ReferrerRank, rules: ReferralProgramRules): boolean;
219
+ type ReferralProgramRules = ReferralProgramRulesPieSplit | ReferralProgramRulesRevShareCap | ReferralProgramRulesUnrecognized;
220
+
98
221
  /**
99
- * Calculate the final score boost of a referrer based on their rank.
222
+ * Referral program edition slug.
100
223
  *
101
- * @param rank - The rank of the referrer relative to all other referrers, where 1 is the
102
- * top-ranked referrer.
103
- * @returns The final score boost of the referrer as a number between 0 and 1 (inclusive).
224
+ * A URL-safe identifier for a referral program edition. Each edition represents
225
+ * a distinct referral program period with its own rules, leaderboard, and
226
+ * award distribution.
227
+ *
228
+ * @invariant Must contain only lowercase letters (a-z), digits (0-9), and hyphens (-).
229
+ * Must not start or end with a hyphen. Pattern: `^[a-z0-9]+(-[a-z0-9]+)*$`
230
+ *
231
+ * @example "2025-12" // December 2025 edition
232
+ * @example "2026-03" // March 2026 edition
233
+ * @example "holiday-special" // Custom named edition
104
234
  */
105
- declare function calcReferrerFinalScoreBoost(rank: ReferrerRank, rules: ReferralProgramRules): number;
235
+ type ReferralProgramEditionSlug = string;
106
236
  /**
107
- * Calculate the final score multiplier of a referrer based on their rank.
237
+ * Regex pattern that all {@link ReferralProgramEditionSlug} values must match.
108
238
  *
109
- * @param rank - The rank of the referrer relative to all other referrers, where 1 is the
110
- * top-ranked referrer.
111
- * @returns The final score multiplier of the referrer as a number between 1 and 2 (inclusive).
239
+ * Allows lowercase letters (a-z), digits (0-9), and hyphens (-).
240
+ * Must not start or end with a hyphen.
112
241
  */
113
- declare function calcReferrerFinalScoreMultiplier(rank: ReferrerRank, rules: ReferralProgramRules): number;
242
+ declare const REFERRAL_PROGRAM_EDITION_SLUG_PATTERN: RegExp;
114
243
  /**
115
- * Calculate the final score of a referrer based on their score and final score boost.
116
- *
117
- * @param rank - The rank of the referrer relative to all other referrers.
118
- * @param totalIncrementalDuration - The total incremental duration (in seconds)
119
- * of referrals made by the referrer within the `rules`.
120
- * @param rules - The rules of the referral program that generated the `rank`.
121
- * @returns The final score of the referrer.
244
+ * Represents a referral program edition configuration.
122
245
  */
123
- declare function calcReferrerFinalScore(rank: ReferrerRank, totalIncrementalDuration: Duration, rules: ReferralProgramRules): ReferrerScore;
124
- interface ReferrerMetricsForComparison {
246
+ interface ReferralProgramEditionConfig {
125
247
  /**
126
- * The total incremental duration (in seconds) of all referrals made by the referrer within
127
- * the {@link ReferralProgramRules}.
248
+ * Unique slug identifier for the edition.
128
249
  */
129
- totalIncrementalDuration: Duration;
250
+ slug: ReferralProgramEditionSlug;
130
251
  /**
131
- * The fully lowercase Ethereum address of the referrer.
132
- *
133
- * @invariant Guaranteed to be a valid EVM address in lowercase format.
252
+ * Human-readable display name for the edition.
253
+ * @example "ENS Holiday Awards"
134
254
  */
135
- referrer: Address;
255
+ displayName: string;
256
+ /**
257
+ * The rules that govern this referral program edition.
258
+ */
259
+ rules: ReferralProgramRules;
136
260
  }
137
- declare const compareReferrerMetrics: (a: ReferrerMetricsForComparison, b: ReferrerMetricsForComparison) => number;
138
-
139
261
  /**
140
- * Revenue Contribution
262
+ * A map from edition slug to edition configuration.
141
263
  *
142
- * Represents the total revenue contribution (in Wei) made to the ENS DAO.
264
+ * Used to store and look up all configured referral program editions.
143
265
  *
144
- * This is the sum of the total cost paid by registrants for registrar actions.
145
- * From the perspective of the ENS DAO, this represents revenue received.
266
+ * @invariant For each key-value pair in the map, the key must equal the value's slug property.
267
+ * That is, for all entries: `map.get(key)?.slug === key`
268
+ */
269
+ type ReferralProgramEditionConfigSet = Map<ReferralProgramEditionSlug, ReferralProgramEditionConfig>;
270
+ /**
271
+ * Validates that a ReferralProgramEditionConfigSet maintains the invariant
272
+ * that each map key equals the corresponding config's slug.
146
273
  *
147
- * @invariant Guaranteed to be a non-negative bigint value (>= 0n)
148
- * @invariant Never null (records with null `total` in the database are treated as 0 when summing)
274
+ * @param configSet - The edition config set to validate
275
+ * @throws {Error} If any entry violates the invariant (key !== value.slug)
149
276
  */
150
- type RevenueContribution = bigint;
277
+ declare function validateReferralProgramEditionConfigSet(configSet: ReferralProgramEditionConfigSet): void;
151
278
  /**
152
- * Check if a value is a valid revenue contribution.
279
+ * Builds a new ReferralProgramEditionConfigSet from an array of configs and validates the invariant.
153
280
  *
154
- * @param value - The value to check
155
- * @returns true if the value is a non-negative bigint, false otherwise
281
+ * @param configs - Array of edition configurations to add to the set
282
+ * @returns A validated edition config set
283
+ * @throws {Error} If duplicate slugs are detected or if any config would violate the invariant
156
284
  */
157
- declare function isValidRevenueContribution(value: unknown): value is RevenueContribution;
285
+ declare function buildReferralProgramEditionConfigSet(configs: ReferralProgramEditionConfig[]): ReferralProgramEditionConfigSet;
286
+
158
287
  /**
159
- * Validate that a value is a valid revenue contribution.
288
+ * The score of a referrer.
160
289
  *
161
- * @param value - The value to validate
162
- * @throws {Error} If the value is not a valid revenue contribution
290
+ * @invariant Guaranteed to be a finite non-negative number (>= 0)
163
291
  */
164
- declare function validateRevenueContribution(value: unknown): void;
292
+ type ReferrerScore = number;
293
+ declare const isValidReferrerScore: (score: ReferrerScore) => boolean;
294
+ declare const validateReferrerScore: (score: ReferrerScore) => void;
165
295
 
166
296
  /**
167
- * Represents metrics for a single referrer independent of other referrers.
297
+ * Metrics for a single referrer, as aggregated from the DB layer.
298
+ * Independent of other referrers and award model; does not carry an `awardModel` discriminant.
168
299
  */
169
300
  interface ReferrerMetrics {
170
301
  /**
171
- * The fully lowercase Ethereum address of the referrer.
172
- *
173
- * @invariant Guaranteed to be a valid EVM address in lowercase format
302
+ * The Ethereum address of the referrer, as a {@link NormalizedAddress}.
174
303
  */
175
- referrer: Address;
304
+ referrer: NormalizedAddress;
176
305
  /**
177
306
  * The total number of referrals made by the referrer within the {@link ReferralProgramRules}.
178
307
  * @invariant Guaranteed to be a non-negative integer (>= 0)
@@ -184,54 +313,79 @@ interface ReferrerMetrics {
184
313
  */
185
314
  totalIncrementalDuration: Duration;
186
315
  /**
187
- * The total revenue contribution (in Wei) made to the ENS DAO by all referrals
316
+ * The total revenue contribution in ETH made to the ENS DAO by all referrals
188
317
  * from this referrer.
189
318
  *
190
319
  * This is the sum of the total cost paid by registrants for all registrar actions
191
320
  * where this address was the referrer.
192
321
  *
193
- * @invariant Guaranteed to be a non-negative bigint value (>= 0n)
194
322
  * @invariant Never null (records with null `total` in the database are treated as 0 when summing)
195
323
  */
196
- totalRevenueContribution: RevenueContribution;
324
+ totalRevenueContribution: PriceEth;
197
325
  }
198
- declare const buildReferrerMetrics: (referrer: Address, totalReferrals: number, totalIncrementalDuration: Duration, totalRevenueContribution: RevenueContribution) => ReferrerMetrics;
326
+ declare const buildReferrerMetrics: (referrer: NormalizedAddress, totalReferrals: number, totalIncrementalDuration: Duration, totalRevenueContribution: PriceEth) => ReferrerMetrics;
199
327
  declare const validateReferrerMetrics: (metrics: ReferrerMetrics) => void;
328
+
329
+ /**
330
+ * The rank of a referrer relative to all other referrers, where 1 is the
331
+ * top-ranked referrer.
332
+ *
333
+ * @invariant Guaranteed to be a positive integer (> 0)
334
+ */
335
+ type ReferrerRank = number;
336
+ declare const validateReferrerRank: (rank: ReferrerRank) => void;
337
+ interface ReferrerMetricsForComparison {
338
+ /**
339
+ * The total incremental duration (in seconds) of all referrals made by the referrer within
340
+ * the {@link ReferralProgramRules}.
341
+ */
342
+ totalIncrementalDuration: Duration;
343
+ /**
344
+ * The Ethereum address of the referrer, as a {@link NormalizedAddress}.
345
+ */
346
+ referrer: NormalizedAddress;
347
+ }
348
+ declare const compareReferrerMetrics: (a: ReferrerMetricsForComparison, b: ReferrerMetricsForComparison) => number;
349
+ /**
350
+ * Sorts a list of referrers for leaderboard ranking.
351
+ * Returns a new array — does not mutate the input.
352
+ */
200
353
  declare const sortReferrerMetrics: (referrers: ReferrerMetrics[]) => ReferrerMetrics[];
354
+
201
355
  /**
202
356
  * Represents metrics for a single referrer independent of other referrers,
203
357
  * including a calculation of the referrer's score.
204
358
  */
205
- interface ScoredReferrerMetrics extends ReferrerMetrics {
359
+ interface ScoredReferrerMetricsPieSplit extends ReferrerMetrics {
206
360
  /**
207
361
  * The referrer's score.
208
362
  *
209
- * @invariant Guaranteed to be `calcReferrerScore(totalIncrementalDuration)`
363
+ * @invariant Guaranteed to be `calcReferrerScorePieSplit(totalIncrementalDuration)`
210
364
  */
211
365
  score: ReferrerScore;
212
366
  }
213
- declare const buildScoredReferrerMetrics: (referrer: ReferrerMetrics) => ScoredReferrerMetrics;
214
- declare const validateScoredReferrerMetrics: (metrics: ScoredReferrerMetrics) => void;
367
+ declare const buildScoredReferrerMetricsPieSplit: (referrer: ReferrerMetrics) => ScoredReferrerMetricsPieSplit;
368
+ declare const validateScoredReferrerMetricsPieSplit: (metrics: ScoredReferrerMetricsPieSplit) => void;
215
369
  /**
216
- * Extends {@link ScoredReferrerMetrics} to include additional metrics
217
- * relative to all other referrers on a {@link ReferrerLeaderboard} and {@link ReferralProgramRules}.
370
+ * Extends {@link ScoredReferrerMetricsPieSplit} to include additional metrics relative to all
371
+ * other referrers on a {@link ReferrerLeaderboardPieSplit} and {@link ReferralProgramRulesPieSplit}.
218
372
  */
219
- interface RankedReferrerMetrics extends ScoredReferrerMetrics {
373
+ interface RankedReferrerMetricsPieSplit extends ScoredReferrerMetricsPieSplit {
220
374
  /**
221
- * The referrer's rank on the {@link ReferrerLeaderboard} relative to all other referrers.
375
+ * The referrer's rank on the {@link ReferrerLeaderboardPieSplit} relative to all other referrers.
222
376
  */
223
377
  rank: ReferrerRank;
224
378
  /**
225
- * Identifies if the referrer meets the qualifications of the {@link ReferralProgramRules} to receive a non-zero `awardPoolShare`.
379
+ * Identifies if the referrer meets the qualifications of the {@link ReferralProgramRulesPieSplit} to receive a non-zero `awardPoolShare`.
226
380
  *
227
- * @invariant true if and only if `rank` is less than or equal to {@link ReferralProgramRules.maxQualifiedReferrers}
381
+ * @invariant true if and only if `rank` is less than or equal to {@link ReferralProgramRulesPieSplit.maxQualifiedReferrers}
228
382
  */
229
383
  isQualified: boolean;
230
384
  /**
231
385
  * The referrer's final score boost.
232
386
  *
233
387
  * @invariant Guaranteed to be a number between 0 and 1 (inclusive)
234
- * @invariant Calculated as: `1-((rank-1)/({@link ReferralProgramRules.maxQualifiedReferrers}-1))` if `isQualified` is `true`, else `0`
388
+ * @invariant Calculated as: `1-((rank-1)/({@link ReferralProgramRulesPieSplit.maxQualifiedReferrers}-1))` if `isQualified` is `true`, else `0`
235
389
  */
236
390
  finalScoreBoost: number;
237
391
  /**
@@ -241,43 +395,42 @@ interface RankedReferrerMetrics extends ScoredReferrerMetrics {
241
395
  */
242
396
  finalScore: ReferrerScore;
243
397
  }
244
- declare const validateRankedReferrerMetrics: (metrics: RankedReferrerMetrics, rules: ReferralProgramRules) => void;
245
- declare const buildRankedReferrerMetrics: (referrer: ScoredReferrerMetrics, rank: ReferrerRank, rules: ReferralProgramRules) => RankedReferrerMetrics;
398
+ declare const validateRankedReferrerMetricsPieSplit: (metrics: RankedReferrerMetricsPieSplit, rules: ReferralProgramRulesPieSplit) => void;
399
+ declare const buildRankedReferrerMetricsPieSplit: (referrer: ScoredReferrerMetricsPieSplit, rank: ReferrerRank, rules: ReferralProgramRulesPieSplit) => RankedReferrerMetricsPieSplit;
246
400
  /**
247
401
  * Calculate the share of the award pool for a referrer.
248
402
  * @param referrer - The referrer to calculate the award pool share for.
249
403
  * @param aggregatedMetrics - Aggregated metrics for all referrers.
250
- * @param rules - The rules of the referral program.
251
404
  * @returns The referrer's share of the award pool as a number between 0 and 1 (inclusive).
252
405
  */
253
- declare const calcReferrerAwardPoolShare: (referrer: RankedReferrerMetrics, aggregatedMetrics: AggregatedReferrerMetrics, rules: ReferralProgramRules) => number;
406
+ declare const calcReferrerAwardPoolSharePieSplit: (referrer: RankedReferrerMetricsPieSplit, aggregatedMetrics: AggregatedReferrerMetricsPieSplit) => number;
254
407
  /**
255
- * Extends {@link RankedReferrerMetrics} to include additional metrics
256
- * relative to {@link AggregatedRankedReferrerMetrics}.
408
+ * Extends {@link RankedReferrerMetricsPieSplit} to include additional metrics
409
+ * relative to {@link AggregatedReferrerMetricsPieSplit}.
257
410
  */
258
- interface AwardedReferrerMetrics extends RankedReferrerMetrics {
411
+ interface AwardedReferrerMetricsPieSplit extends RankedReferrerMetricsPieSplit {
259
412
  /**
260
413
  * The referrer's share of the award pool.
261
414
  *
262
415
  * @invariant Guaranteed to be a number between 0 and 1 (inclusive)
263
- * @invariant Calculated as: `finalScore / {@link AggregatedRankedReferrerMetrics.grandTotalQualifiedReferrersFinalScore}` if `isQualified` is `true`, else `0`
416
+ * @invariant Calculated as: `finalScore / {@link AggregatedReferrerMetricsPieSplit.grandTotalQualifiedReferrersFinalScore}` if `isQualified` is `true`, else `0`
264
417
  */
265
418
  awardPoolShare: number;
266
419
  /**
267
- * The approximate {@link USDQuantity} of the referrer's share of the {@link ReferralProgramRules.totalAwardPoolValue}.
420
+ * The approximate USDC value of the referrer's share of the {@link ReferralProgramRulesPieSplit.awardPool}.
268
421
  *
269
- * @invariant Guaranteed to be a number between 0 and {@link ReferralProgramRules.totalAwardPoolValue} (inclusive)
270
- * @invariant Calculated as: `awardPoolShare` * {@link ReferralProgramRules.totalAwardPoolValue}
422
+ * @invariant Guaranteed to be a valid PriceUsdc with amount between 0 and {@link ReferralProgramRulesPieSplit.awardPool.amount} (inclusive)
423
+ * @invariant Calculated as: `awardPoolShare` * {@link ReferralProgramRulesPieSplit.awardPool.amount}
271
424
  */
272
- awardPoolApproxValue: USDQuantity;
425
+ awardPoolApproxValue: PriceUsdc;
273
426
  }
274
- declare const validateAwardedReferrerMetrics: (referrer: AwardedReferrerMetrics, rules: ReferralProgramRules) => void;
275
- declare const buildAwardedReferrerMetrics: (referrer: RankedReferrerMetrics, aggregatedMetrics: AggregatedReferrerMetrics, rules: ReferralProgramRules) => AwardedReferrerMetrics;
427
+ declare const validateAwardedReferrerMetricsPieSplit: (referrer: AwardedReferrerMetricsPieSplit, rules: ReferralProgramRulesPieSplit) => void;
428
+ declare const buildAwardedReferrerMetricsPieSplit: (referrer: RankedReferrerMetricsPieSplit, aggregatedMetrics: AggregatedReferrerMetricsPieSplit, rules: ReferralProgramRulesPieSplit) => AwardedReferrerMetricsPieSplit;
276
429
  /**
277
- * Extends {@link AwardedReferrerMetrics} but with rank set to null to represent
430
+ * Extends {@link AwardedReferrerMetricsPieSplit} but with rank set to null to represent
278
431
  * a referrer who is not on the leaderboard (has zero referrals within the rules associated with the leaderboard).
279
432
  */
280
- interface UnrankedReferrerMetrics extends Omit<AwardedReferrerMetrics, "rank" | "isQualified"> {
433
+ interface UnrankedReferrerMetricsPieSplit extends Omit<AwardedReferrerMetricsPieSplit, "rank" | "isQualified"> {
281
434
  /**
282
435
  * The referrer is not on the leaderboard and therefore has no rank.
283
436
  */
@@ -287,7 +440,7 @@ interface UnrankedReferrerMetrics extends Omit<AwardedReferrerMetrics, "rank" |
287
440
  */
288
441
  isQualified: false;
289
442
  }
290
- declare const validateUnrankedReferrerMetrics: (metrics: UnrankedReferrerMetrics) => void;
443
+ declare const validateUnrankedReferrerMetricsPieSplit: (metrics: UnrankedReferrerMetricsPieSplit) => void;
291
444
  /**
292
445
  * Build an unranked zero-score referrer record for a referrer address that is not in the leaderboard.
293
446
  *
@@ -295,34 +448,34 @@ declare const validateUnrankedReferrerMetrics: (metrics: UnrankedReferrerMetrics
295
448
  * and is not qualified for the leaderboard.
296
449
  *
297
450
  * @param referrer - The referrer address
298
- * @returns An {@link UnrankedReferrerMetrics} with zero values for all metrics and null rank
451
+ * @returns An {@link UnrankedReferrerMetricsPieSplit} with zero values for all metrics and null rank
299
452
  */
300
- declare const buildUnrankedReferrerMetrics: (referrer: Address) => UnrankedReferrerMetrics;
453
+ declare const buildUnrankedReferrerMetricsPieSplit: (referrer: NormalizedAddress) => UnrankedReferrerMetricsPieSplit;
301
454
 
302
455
  /**
303
- * Represents aggregated metrics for a list of `RankedReferrerMetrics`.
456
+ * Represents aggregated metrics for a list of {@link RankedReferrerMetricsPieSplit}.
304
457
  */
305
- interface AggregatedReferrerMetrics {
458
+ interface AggregatedReferrerMetricsPieSplit {
306
459
  /**
307
- * @invariant The sum of `totalReferrals` across all `RankedReferrerMetrics` in the list.
460
+ * @invariant The sum of `totalReferrals` across all {@link RankedReferrerMetricsPieSplit} in the list.
308
461
  * @invariant Guaranteed to be a non-negative integer (>= 0)
309
462
  */
310
463
  grandTotalReferrals: number;
311
464
  /**
312
- * @invariant The sum of `totalIncrementalDuration` across all `RankedReferrerMetrics` in the list.
465
+ * @invariant The sum of `totalIncrementalDuration` across all {@link RankedReferrerMetricsPieSplit} in the list.
313
466
  */
314
467
  grandTotalIncrementalDuration: Duration;
315
468
  /**
316
- * The total revenue contribution (in Wei) to the ENS DAO from all referrals
469
+ * The total revenue contribution in ETH to the ENS DAO from all referrals
317
470
  * across all referrers on the leaderboard.
318
471
  *
319
- * This is the sum of `totalRevenueContribution` across all `RankedReferrerMetrics` in the list.
472
+ * This is the sum of `totalRevenueContribution` across all {@link RankedReferrerMetricsPieSplit} in the list.
320
473
  *
321
- * @invariant Guaranteed to be a non-negative bigint value (>= 0n)
474
+ * @invariant Guaranteed to be a valid PriceEth with non-negative amount (>= 0n)
322
475
  */
323
- grandTotalRevenueContribution: RevenueContribution;
476
+ grandTotalRevenueContribution: PriceEth;
324
477
  /**
325
- * @invariant The sum of `finalScore` across all `RankedReferrerMetrics` where `isQualified` is `true`.
478
+ * @invariant The sum of `finalScore` across all {@link RankedReferrerMetricsPieSplit} where `isQualified` is `true`.
326
479
  */
327
480
  grandTotalQualifiedReferrersFinalScore: ReferrerScore;
328
481
  /**
@@ -334,41 +487,557 @@ interface AggregatedReferrerMetrics {
334
487
  */
335
488
  minFinalScoreToQualify: ReferrerScore;
336
489
  }
337
- declare const validateAggregatedReferrerMetrics: (metrics: AggregatedReferrerMetrics) => void;
338
- declare const buildAggregatedReferrerMetrics: (referrers: RankedReferrerMetrics[], rules: ReferralProgramRules) => AggregatedReferrerMetrics;
490
+ declare const validateAggregatedReferrerMetricsPieSplit: (metrics: AggregatedReferrerMetricsPieSplit) => void;
491
+ /**
492
+ * Builds aggregated pie-split metrics from a complete, globally ranked list of referrers.
493
+ *
494
+ * **IMPORTANT: This function expects a complete ranking of all referrers.**
495
+ *
496
+ * @param referrers - Must be a complete, globally ranked list of {@link RankedReferrerMetricsPieSplit}
497
+ * where ranks start at 1 and are consecutive.
498
+ * **This must NOT be a paginated or partial slice of the rankings.**
499
+ *
500
+ * @param rules - The {@link ReferralProgramRulesPieSplit} object that define qualification criteria,
501
+ * including `maxQualifiedReferrers` (the maximum number of referrers
502
+ * that can qualify for rewards).
503
+ *
504
+ * @returns Aggregated metrics including totals across all referrers and the minimum
505
+ * score required to qualify.
506
+ *
507
+ * @remarks
508
+ * - If you need to work with paginated data, aggregate the full ranking first before
509
+ * calling this function, or call this function on the complete dataset and then paginate
510
+ * the results.
511
+ * - If `rules.maxQualifiedReferrers === 0`, no referrers can qualify and
512
+ * `minFinalScoreToQualify` will be set to `Number.MAX_SAFE_INTEGER`.
513
+ * - If `referrers` is empty and `rules.maxQualifiedReferrers > 0`,
514
+ * `minFinalScoreToQualify` will be set to `0` (anyone can qualify).
515
+ */
516
+ declare const buildAggregatedReferrerMetricsPieSplit: (referrers: RankedReferrerMetricsPieSplit[], rules: ReferralProgramRulesPieSplit) => AggregatedReferrerMetricsPieSplit;
339
517
 
340
518
  /**
341
- * Represents a leaderboard for any number of referrers.
519
+ * The type of referrer edition metrics data.
342
520
  */
343
- interface ReferrerLeaderboard {
521
+ declare const ReferrerEditionMetricsTypeIds: {
344
522
  /**
345
- * The rules of the referral program that generated the {@link ReferrerLeaderboard}.
523
+ * Represents a referrer who is ranked on the leaderboard.
346
524
  */
347
- rules: ReferralProgramRules;
525
+ readonly Ranked: "ranked";
526
+ /**
527
+ * Represents a referrer who is not ranked on the leaderboard.
528
+ */
529
+ readonly Unranked: "unranked";
530
+ };
531
+ /**
532
+ * The derived string union of possible {@link ReferrerEditionMetricsTypeIds}.
533
+ */
534
+ type ReferrerEditionMetricsTypeId = (typeof ReferrerEditionMetricsTypeIds)[keyof typeof ReferrerEditionMetricsTypeIds];
535
+ /**
536
+ * Referrer edition metrics for an edition whose `awardModel` is not recognized by this client version.
537
+ *
538
+ * @remarks
539
+ * This is a **client-side forward-compatibility** type only. It is never serialized or processed
540
+ * by business logic on the backend. When the server introduces a new award model type, older
541
+ * clients preserve the metrics rather than throwing, and downstream code that encounters this type
542
+ * should handle it gracefully rather than crashing.
543
+ */
544
+ interface ReferrerEditionMetricsUnrecognized {
545
+ /**
546
+ * Discriminant — always `"unrecognized"`.
547
+ */
548
+ awardModel: typeof ReferralProgramAwardModels.Unrecognized;
549
+ /**
550
+ * The original, unrecognized `awardModel` string received from the server.
551
+ *
552
+ * @remarks Preserved for logging and debugging. Never used for business logic.
553
+ */
554
+ originalAwardModel: string;
555
+ }
556
+
557
+ /**
558
+ * The type of referral program edition's status.
559
+ */
560
+ declare const ReferralProgramEditionStatuses: {
561
+ /**
562
+ * Represents a referral program edition that has been announced, but hasn't started yet.
563
+ */
564
+ readonly Scheduled: "Scheduled";
348
565
  /**
349
- * The {@link AggregatedReferrerMetrics} for all `RankedReferrerMetrics` values in `leaderboard`.
566
+ * Represents a currently ongoing referral program edition.
350
567
  */
351
- aggregatedMetrics: AggregatedReferrerMetrics;
568
+ readonly Active: "Active";
569
+ /**
570
+ * Represents a referral program edition that is still within its active window
571
+ * but whose award pool has been fully consumed.
572
+ *
573
+ * @note Not all award models may support this status.
574
+ */
575
+ readonly Exhausted: "Exhausted";
352
576
  /**
353
- * Ordered map containing `AwardedReferrerMetrics` for all referrers with 1 or more
354
- * `totalReferrals` within the `rules` as of `updatedAt`.
577
+ * Represents a referral program edition that has passed its end time but whose awards have not yet
578
+ * been distributed. The edition is in a review window before full closure.
579
+ *
580
+ * Transitions to {@link ReferralProgramEditionStatuses.Closed} once `areAwardsDistributed` is set to `true`.
581
+ */
582
+ readonly AwardsReview: "AwardsReview";
583
+ /**
584
+ * Represents a referral program edition that has already ended and whose awards have been distributed.
585
+ */
586
+ readonly Closed: "Closed";
587
+ };
588
+ /**
589
+ * The derived string union of possible {@link ReferralProgramEditionStatuses}.
590
+ */
591
+ type ReferralProgramEditionStatusId = (typeof ReferralProgramEditionStatuses)[keyof typeof ReferralProgramEditionStatuses];
592
+ /**
593
+ * Calculate the base status of a referral program edition using only its rules and
594
+ * the current time (makes no consideration of the awards possibly being exhausted).
595
+ *
596
+ * @param rules - Related referral program's rules containing program's start/end date and
597
+ * `areAwardsDistributed` flag.
598
+ * @param now - Current date in {@link UnixTimestamp} format.
599
+ */
600
+ declare const calcBaseReferralProgramEditionStatus: (rules: BaseReferralProgramRules, now: UnixTimestamp) => ReferralProgramEditionStatusId;
601
+
602
+ /**
603
+ * Referrer edition metrics data for a specific referrer address on the pie-split leaderboard.
604
+ *
605
+ * Includes the referrer's awarded metrics from the leaderboard plus timestamp.
606
+ *
607
+ * Invariants:
608
+ * - `type` is always {@link ReferrerEditionMetricsTypeIds.Ranked}.
609
+ * - `awardModel` is always {@link ReferralProgramAwardModels.PieSplit} and equals `rules.awardModel`.
610
+ *
611
+ * @see {@link AwardedReferrerMetricsPieSplit}
612
+ */
613
+ interface ReferrerEditionMetricsRankedPieSplit {
614
+ /**
615
+ * Discriminant identifying this as data from a pie-split leaderboard edition.
616
+ *
617
+ * @invariant Always equals `rules.awardModel` ({@link ReferralProgramAwardModels.PieSplit}).
618
+ */
619
+ awardModel: typeof ReferralProgramAwardModels.PieSplit;
620
+ /**
621
+ * The type of referrer edition metrics data.
622
+ */
623
+ type: typeof ReferrerEditionMetricsTypeIds.Ranked;
624
+ /**
625
+ * The {@link ReferralProgramRulesPieSplit} used to calculate the {@link AwardedReferrerMetricsPieSplit}.
626
+ */
627
+ rules: ReferralProgramRulesPieSplit;
628
+ /**
629
+ * The awarded referrer metrics from the leaderboard.
630
+ *
631
+ * Contains all calculated metrics including score, rank, qualification status,
632
+ * and award pool share information.
633
+ */
634
+ referrer: AwardedReferrerMetricsPieSplit;
635
+ /**
636
+ * Aggregated metrics for all referrers on the leaderboard.
637
+ */
638
+ aggregatedMetrics: AggregatedReferrerMetricsPieSplit;
639
+ /**
640
+ * The status of the referral program edition
641
+ * calculated based on the program's timing relative to {@link accurateAsOf}.
642
+ */
643
+ status: ReferralProgramEditionStatusId;
644
+ /**
645
+ * The {@link UnixTimestamp} of when the data used to build the {@link ReferrerEditionMetricsRankedPieSplit} was accurate as of.
646
+ */
647
+ accurateAsOf: UnixTimestamp;
648
+ }
649
+ /**
650
+ * Referrer edition metrics data for a specific referrer address NOT on the pie-split leaderboard.
651
+ *
652
+ * Includes the referrer's unranked metrics (with null rank and isQualified: false) plus timestamp.
653
+ *
654
+ * Invariants:
655
+ * - `type` is always {@link ReferrerEditionMetricsTypeIds.Unranked}.
656
+ * - `awardModel` is always {@link ReferralProgramAwardModels.PieSplit} and equals `rules.awardModel`.
657
+ *
658
+ * @see {@link UnrankedReferrerMetricsPieSplit}
659
+ */
660
+ interface ReferrerEditionMetricsUnrankedPieSplit {
661
+ /**
662
+ * Discriminant identifying this as data from a pie-split leaderboard edition.
663
+ *
664
+ * @invariant Always equals `rules.awardModel` ({@link ReferralProgramAwardModels.PieSplit}).
665
+ */
666
+ awardModel: typeof ReferralProgramAwardModels.PieSplit;
667
+ /**
668
+ * The type of referrer edition metrics data.
669
+ */
670
+ type: typeof ReferrerEditionMetricsTypeIds.Unranked;
671
+ /**
672
+ * The {@link ReferralProgramRulesPieSplit} used to calculate the {@link UnrankedReferrerMetricsPieSplit}.
673
+ */
674
+ rules: ReferralProgramRulesPieSplit;
675
+ /**
676
+ * The unranked referrer metrics (not on the leaderboard).
677
+ *
678
+ * Contains all calculated metrics with rank set to null and isQualified set to false.
679
+ */
680
+ referrer: UnrankedReferrerMetricsPieSplit;
681
+ /**
682
+ * Aggregated metrics for all referrers on the leaderboard.
683
+ */
684
+ aggregatedMetrics: AggregatedReferrerMetricsPieSplit;
685
+ /**
686
+ * The status of the referral program edition
687
+ * calculated based on the program's timing relative to {@link accurateAsOf}.
688
+ */
689
+ status: ReferralProgramEditionStatusId;
690
+ /**
691
+ * The {@link UnixTimestamp} of when the data used to build the {@link ReferrerEditionMetricsUnrankedPieSplit} was accurate as of.
692
+ */
693
+ accurateAsOf: UnixTimestamp;
694
+ }
695
+ /**
696
+ * All referrer edition metrics variants for the pie-split award model.
697
+ *
698
+ * Use `type` to determine if the referrer is ranked or unranked.
699
+ */
700
+ type ReferrerEditionMetricsPieSplit = ReferrerEditionMetricsRankedPieSplit | ReferrerEditionMetricsUnrankedPieSplit;
701
+
702
+ /**
703
+ * Base fields shared by all edition summary variants.
704
+ */
705
+ interface BaseReferralProgramEditionSummary {
706
+ /**
707
+ * Discriminant: identifies the award model for this edition.
708
+ *
709
+ * @invariant Always equals `rules.awardModel`.
710
+ */
711
+ awardModel: ReferralProgramAwardModel;
712
+ /**
713
+ * Unique slug identifier for the edition.
714
+ */
715
+ slug: ReferralProgramEditionSlug;
716
+ /**
717
+ * Human-readable display name for the edition.
718
+ */
719
+ displayName: string;
720
+ /**
721
+ * The current runtime status of the edition.
722
+ */
723
+ status: ReferralProgramEditionStatusId;
724
+ /**
725
+ * The rules for this edition. Per-model subtypes narrow this to their specific rules type.
726
+ */
727
+ rules: BaseReferralProgramRules;
728
+ }
729
+ /**
730
+ * Edition summary for an edition whose `awardModel` is not recognized by this client version.
731
+ *
732
+ * @remarks
733
+ * This is a **client-side forward-compatibility** type only. It is never serialized or produced
734
+ * by the server. When the server sends a new award model, older clients preserve the edition
735
+ * summary rather than crashing, and downstream code should handle it gracefully.
736
+ */
737
+ interface ReferralProgramEditionSummaryUnrecognized extends BaseReferralProgramEditionSummary {
738
+ /**
739
+ * Discriminant — always `"unrecognized"`.
740
+ */
741
+ awardModel: typeof ReferralProgramAwardModels.Unrecognized;
742
+ /**
743
+ * The unrecognized rules — preserves `originalAwardModel` for logging/debugging.
744
+ */
745
+ rules: ReferralProgramRulesUnrecognized;
746
+ }
747
+ declare const validateBaseReferralProgramEditionSummary: (summary: BaseReferralProgramEditionSummary) => void;
748
+
749
+ /**
750
+ * Represents a leaderboard with the pie-split award model for any number of referrers.
751
+ */
752
+ interface ReferrerLeaderboardPieSplit {
753
+ /**
754
+ * Discriminant identifying this as a pie-split leaderboard.
755
+ *
756
+ * @invariant Always equals `rules.awardModel` ({@link ReferralProgramAwardModels.PieSplit}).
757
+ */
758
+ awardModel: typeof ReferralProgramAwardModels.PieSplit;
759
+ /**
760
+ * The rules of the referral program that generated the {@link ReferrerLeaderboardPieSplit}.
761
+ */
762
+ rules: ReferralProgramRulesPieSplit;
763
+ /**
764
+ * The {@link AggregatedReferrerMetricsPieSplit} for all {@link RankedReferrerMetricsPieSplit} values in `referrers`.
765
+ */
766
+ aggregatedMetrics: AggregatedReferrerMetricsPieSplit;
767
+ /**
768
+ * Ordered map containing `AwardedReferrerMetricsPieSplit` for all referrers with 1 or more
769
+ * `totalReferrals` within the `rules` as of `accurateAsOf`.
355
770
  *
356
771
  * @invariant Map entries are ordered by `rank` (ascending).
357
772
  * @invariant Map is empty if there are no referrers with 1 or more `totalReferrals`
358
- * within the `rules` as of `updatedAt`.
359
- * @invariant If a fully-lowercase `Address` is not a key in this map then that `Address` had
773
+ * within the `rules` as of `accurateAsOf`.
774
+ * @invariant If a `NormalizedAddress` is not a key in this map then that `NormalizedAddress` had
360
775
  * 0 `totalReferrals`, `totalIncrementalDuration`, and `score` within the
361
- * `rules` as of `updatedAt`.
776
+ * `rules` as of `accurateAsOf`.
362
777
  * @invariant Each value in this map is guaranteed to have a non-zero
363
778
  * `totalReferrals`, `totalIncrementalDuration`, and `score`.
364
779
  */
365
- referrers: Map<Address, AwardedReferrerMetrics>;
780
+ referrers: Map<NormalizedAddress, AwardedReferrerMetricsPieSplit>;
781
+ /**
782
+ * The {@link UnixTimestamp} of when the data used to build the {@link ReferrerLeaderboardPieSplit} was accurate as of.
783
+ */
784
+ accurateAsOf: UnixTimestamp;
785
+ }
786
+ declare const buildReferrerLeaderboardPieSplit: (allReferrers: ReferrerMetrics[], rules: ReferralProgramRulesPieSplit, accurateAsOf: UnixTimestamp) => ReferrerLeaderboardPieSplit;
787
+
788
+ /**
789
+ * Edition summary for a `pie-split` referral program edition.
790
+ */
791
+ interface ReferralProgramEditionSummaryPieSplit extends BaseReferralProgramEditionSummary {
792
+ /**
793
+ * Discriminant — always `"pie-split"`.
794
+ *
795
+ * @invariant Always equals `rules.awardModel` ({@link ReferralProgramAwardModels.PieSplit}).
796
+ */
797
+ awardModel: typeof ReferralProgramAwardModels.PieSplit;
798
+ /**
799
+ * The pie-split rules for this edition.
800
+ */
801
+ rules: ReferralProgramRulesPieSplit;
802
+ }
803
+ declare const validateEditionSummaryPieSplit: (summary: ReferralProgramEditionSummaryPieSplit) => void;
804
+ /**
805
+ * Build a {@link ReferralProgramEditionSummaryPieSplit} from a pie-split edition config and the
806
+ * edition's leaderboard.
807
+ */
808
+ declare function buildEditionSummaryPieSplit(slug: ReferralProgramEditionSlug, displayName: string, rules: ReferralProgramRulesPieSplit, leaderboard: ReferrerLeaderboardPieSplit): ReferralProgramEditionSummaryPieSplit;
809
+
810
+ /**
811
+ * Extends {@link ReferrerMetrics} with computed base revenue contribution.
812
+ */
813
+ interface ReferrerMetricsRevShareCap extends ReferrerMetrics {
814
+ /**
815
+ * The referrer's base revenue contribution
816
+ * (`rules.baseAnnualRevenueContribution` × years of incremental duration).
817
+ * Used for qualification and award calculation in the rev-share-cap model.
818
+ *
819
+ * @invariant Guaranteed to be `priceUsdc(rules.baseAnnualRevenueContribution.amount * BigInt(totalIncrementalDuration) / BigInt(SECONDS_PER_YEAR))`
820
+ */
821
+ totalBaseRevenueContribution: PriceUsdc;
822
+ }
823
+ declare const validateReferrerMetricsRevShareCap: (metrics: ReferrerMetricsRevShareCap, rules: ReferralProgramRulesRevShareCap) => void;
824
+ declare const buildReferrerMetricsRevShareCap: (metrics: ReferrerMetrics, rules: ReferralProgramRulesRevShareCap) => ReferrerMetricsRevShareCap;
825
+ /**
826
+ * Extends {@link ReferrerMetricsRevShareCap} with rank, qualification status, and admin disqualification.
827
+ */
828
+ interface RankedReferrerMetricsRevShareCap extends ReferrerMetricsRevShareCap {
829
+ /**
830
+ * The referrer's rank on the {@link ReferrerLeaderboardRevShareCap} relative to all other referrers.
831
+ */
832
+ rank: ReferrerRank;
833
+ /**
834
+ * Identifies if the referrer is eligible for an award under the {@link ReferralProgramRulesRevShareCap}.
835
+ *
836
+ * Note: this is a purely rule-based eligibility predicate and does NOT guarantee
837
+ * `cappedAward.amount > 0n` — a qualified referrer may still receive $0 if the
838
+ * capped award pool is already exhausted by earlier referrers in the race.
839
+ *
840
+ * @invariant true if and only if `totalBaseRevenueContribution` is greater than or equal to
841
+ * {@link ReferralProgramRulesRevShareCap.minBaseRevenueContribution} AND
842
+ * {@link adminAction} does not have `actionType` of {@link AdminActionTypes.Disqualification}.
843
+ */
844
+ isQualified: boolean;
845
+ /**
846
+ * The admin action taken on this referrer, or null if no admin action has been taken.
847
+ *
848
+ * @invariant null when no admin action has been taken on this referrer.
849
+ * @invariant Must match the corresponding entry in {@link ReferralProgramRulesRevShareCap.adminActions}.
850
+ */
851
+ adminAction: AdminAction | null;
852
+ }
853
+ declare const validateRankedReferrerMetricsRevShareCap: (metrics: RankedReferrerMetricsRevShareCap, rules: ReferralProgramRulesRevShareCap) => void;
854
+ declare const buildRankedReferrerMetricsRevShareCap: (referrer: ReferrerMetricsRevShareCap, rank: ReferrerRank, rules: ReferralProgramRulesRevShareCap) => RankedReferrerMetricsRevShareCap;
855
+ /**
856
+ * Extends {@link RankedReferrerMetricsRevShareCap} with the referrer's uncapped and capped awards.
857
+ */
858
+ interface AwardedReferrerMetricsRevShareCap extends RankedReferrerMetricsRevShareCap {
859
+ /**
860
+ * The uncapped USDC award for this referrer, computed as
861
+ * `maxBaseRevenueShare × totalBaseRevenueContribution`.
862
+ *
863
+ * Represents what the referrer would receive if the pool were uncapped and the referrer were qualified.
864
+ * Independent of the pool state, qualification status, and admin disqualification status.
865
+ */
866
+ uncappedAward: PriceUsdc;
867
+ /**
868
+ * The referrer's (tentative) capped USDC award.
869
+ *
870
+ * This is the amount (tentatively) claimed from the award pool by this referrer, capped by
871
+ * the remaining award pool at the time of their qualifying referrals.
872
+ *
873
+ * @invariant Guaranteed to be a valid PriceUsdc with amount between 0 and {@link ReferralProgramRulesRevShareCap.awardPool.amount} (inclusive)
874
+ * @invariant Always <= uncappedAward.amount
875
+ * @invariant Amount equal to 0 when {@link adminAction} has `actionType` of {@link AdminActionTypes.Disqualification}.
876
+ * @invariant Amount equal to 0 when {@link isQualified} is false.
877
+ */
878
+ cappedAward: PriceUsdc;
879
+ }
880
+ declare const validateAwardedReferrerMetricsRevShareCap: (metrics: AwardedReferrerMetricsRevShareCap, rules: ReferralProgramRulesRevShareCap) => void;
881
+ declare const buildAwardedReferrerMetricsRevShareCap: (referrer: RankedReferrerMetricsRevShareCap, uncappedAward: PriceUsdc, cappedAward: PriceUsdc, rules: ReferralProgramRulesRevShareCap) => AwardedReferrerMetricsRevShareCap;
882
+ /**
883
+ * Extends {@link AwardedReferrerMetricsRevShareCap} but with rank set to null to represent
884
+ * a referrer who is not on the leaderboard (has zero referrals within the rules associated with the leaderboard).
885
+ */
886
+ interface UnrankedReferrerMetricsRevShareCap extends Omit<AwardedReferrerMetricsRevShareCap, "rank" | "isQualified"> {
887
+ /**
888
+ * The referrer is not on the leaderboard and therefore has no rank.
889
+ */
890
+ rank: null;
891
+ /**
892
+ * Always false for unranked referrers.
893
+ */
894
+ isQualified: false;
895
+ }
896
+ declare const validateUnrankedReferrerMetricsRevShareCap: (metrics: UnrankedReferrerMetricsRevShareCap, rules: ReferralProgramRulesRevShareCap) => void;
897
+ /**
898
+ * Build an unranked zero-metrics rev-share-cap referrer record for an address not on the leaderboard.
899
+ */
900
+ declare const buildUnrankedReferrerMetricsRevShareCap: (referrer: NormalizedAddress, rules: ReferralProgramRulesRevShareCap) => UnrankedReferrerMetricsRevShareCap;
901
+
902
+ /**
903
+ * Represents aggregated metrics for a list of referrers on a rev-share-cap leaderboard.
904
+ */
905
+ interface AggregatedReferrerMetricsRevShareCap {
906
+ /**
907
+ * @invariant The sum of `totalReferrals` across all referrers in the list.
908
+ * @invariant Guaranteed to be a non-negative integer (>= 0)
909
+ */
910
+ grandTotalReferrals: number;
911
+ /**
912
+ * @invariant The sum of `totalIncrementalDuration` across all referrers in the list.
913
+ */
914
+ grandTotalIncrementalDuration: Duration;
915
+ /**
916
+ * The total revenue contribution in ETH to the ENS DAO from all referrals
917
+ * across all referrers on the leaderboard.
918
+ *
919
+ * This is the sum of `totalRevenueContribution` across all referrers in the list.
920
+ *
921
+ * @invariant Guaranteed to be a valid PriceEth with non-negative amount (>= 0n)
922
+ */
923
+ grandTotalRevenueContribution: PriceEth;
366
924
  /**
367
- * The {@link UnixTimestamp} of when the data used to build the {@link ReferrerLeaderboard} was accurate as of.
925
+ * The remaining amount in the award pool after subtracting all capped awards
926
+ * claimed during the sequential race processing.
927
+ *
928
+ * @invariant Guaranteed to be a valid PriceUsdc with non-negative amount (>= 0n)
929
+ */
930
+ awardPoolRemaining: PriceUsdc;
931
+ }
932
+ declare const validateAggregatedReferrerMetricsRevShareCap: (metrics: AggregatedReferrerMetricsRevShareCap) => void;
933
+ /**
934
+ * Builds aggregated rev-share-cap metrics from a complete list of referrers and
935
+ * the award pool remaining after sequential race processing.
936
+ *
937
+ * **IMPORTANT: This function expects a complete list of all referrers.**
938
+ *
939
+ * @param referrers - Must be a complete list of referrers with their totals.
940
+ * **This must NOT be a paginated or partial slice.**
941
+ *
942
+ * @param awardPoolRemaining - The amount remaining in the award pool after the sequential
943
+ * race algorithm has processed all events.
944
+ *
945
+ * @returns Aggregated metrics including totals across all referrers and the award pool remaining.
946
+ */
947
+ declare const buildAggregatedReferrerMetricsRevShareCap: (referrers: AwardedReferrerMetricsRevShareCap[], awardPoolRemaining: PriceUsdc) => AggregatedReferrerMetricsRevShareCap;
948
+
949
+ /**
950
+ * Represents a single raw referral event.
951
+ *
952
+ * Used as input to the sequential race algorithm for the rev-share-cap award model.
953
+ * Events are processed in chronological order to determine award claims from the pool.
954
+ */
955
+ interface ReferralEvent {
956
+ /**
957
+ * The Ethereum address of the referrer, as a {@link NormalizedAddress}.
958
+ */
959
+ referrer: NormalizedAddress;
960
+ /**
961
+ * Unix seconds block timestamp.
962
+ */
963
+ timestamp: UnixTimestamp;
964
+ /**
965
+ * Registrar action ID.
966
+ *
967
+ * @invariant Deterministic and globally unique identifier for the "logical registrar action"
968
+ * associated with this ReferralEvent.
969
+ * @invariant Sorting by this value achieves a chronological ordering of each registrar action
970
+ * by the order they were executed onchain.
971
+ */
972
+ id: string;
973
+ /**
974
+ * Duration in seconds contributed by this single referral event.
975
+ */
976
+ incrementalDuration: Duration;
977
+ /**
978
+ * Revenue contribution in ETH from this single referral event.
979
+ */
980
+ incrementalRevenueContribution: PriceEth;
981
+ }
982
+
983
+ /**
984
+ * Represents a leaderboard with the rev-share-cap award model for any number of referrers.
985
+ */
986
+ interface ReferrerLeaderboardRevShareCap {
987
+ /**
988
+ * Discriminant identifying this as a rev-share-cap leaderboard.
989
+ *
990
+ * @invariant Always equals `rules.awardModel` ({@link ReferralProgramAwardModels.RevShareCap}).
991
+ */
992
+ awardModel: typeof ReferralProgramAwardModels.RevShareCap;
993
+ /**
994
+ * The rules of the referral program that generated the {@link ReferrerLeaderboardRevShareCap}.
995
+ */
996
+ rules: ReferralProgramRulesRevShareCap;
997
+ /**
998
+ * The {@link AggregatedReferrerMetricsRevShareCap} for all {@link AwardedReferrerMetricsRevShareCap} values in `referrers`.
999
+ */
1000
+ aggregatedMetrics: AggregatedReferrerMetricsRevShareCap;
1001
+ /**
1002
+ * Ordered map containing {@link AwardedReferrerMetricsRevShareCap} for all referrers with 1 or more
1003
+ * `totalReferrals` within the `rules` as of `accurateAsOf`.
1004
+ *
1005
+ * @invariant Map entries are ordered by `rank` (ascending).
1006
+ * @invariant Map is empty if there are no referrers with 1 or more `totalReferrals`
1007
+ * within the `rules` as of `accurateAsOf`.
1008
+ * @invariant If a `NormalizedAddress` is not a key in this map then that `NormalizedAddress` had
1009
+ * 0 `totalReferrals`, `totalIncrementalDuration`, and `totalRevenueContribution` within the
1010
+ * `rules` as of `accurateAsOf`.
1011
+ * @invariant Each value in this map is guaranteed to have a non-zero
1012
+ * `totalReferrals` and `totalIncrementalDuration`.
1013
+ */
1014
+ referrers: Map<NormalizedAddress, AwardedReferrerMetricsRevShareCap>;
1015
+ /**
1016
+ * The {@link UnixTimestamp} of when the data used to build the {@link ReferrerLeaderboardRevShareCap} was accurate as of.
368
1017
  */
369
1018
  accurateAsOf: UnixTimestamp;
370
1019
  }
371
- declare const buildReferrerLeaderboard: (allReferrers: ReferrerMetrics[], rules: ReferralProgramRules, accurateAsOf: UnixTimestamp) => ReferrerLeaderboard;
1020
+ /**
1021
+ * Builds a {@link ReferrerLeaderboardRevShareCap} using a sequential "first-come, first-served"
1022
+ * race algorithm over individual referral events.
1023
+ *
1024
+ * Events are processed in chronological order. When a referrer first crosses the qualification
1025
+ * threshold, they claim ALL accumulated uncapped awards at once (capped by remaining award pool).
1026
+ * After qualifying, each referrer's subsequent referrals claim that event's incremental capped award.
1027
+ * Once the award pool is exhausted, no further awards are issued to anyone.
1028
+ *
1029
+ * @param events - Raw referral events from ENSDb (unsorted; will be sorted internally).
1030
+ * @param rules - The {@link ReferralProgramRulesRevShareCap} defining the program parameters.
1031
+ * @param accurateAsOf - Timestamp indicating data freshness.
1032
+ */
1033
+ declare const buildReferrerLeaderboardRevShareCap: (events: ReferralEvent[], rules: ReferralProgramRulesRevShareCap, accurateAsOf: UnixTimestamp) => ReferrerLeaderboardRevShareCap;
1034
+
1035
+ /**
1036
+ * Represents a leaderboard for any number of referrers.
1037
+ *
1038
+ * Use `awardModel` to narrow the specific variant at runtime.
1039
+ */
1040
+ type ReferrerLeaderboard = ReferrerLeaderboardPieSplit | ReferrerLeaderboardRevShareCap;
372
1041
 
373
1042
  /**
374
1043
  * The default number of referrers per leaderboard page.
@@ -409,7 +1078,7 @@ interface ReferrerLeaderboardPageContext extends Required<ReferrerLeaderboardPag
409
1078
  totalPages: number;
410
1079
  /**
411
1080
  * Indicates if there is a next page available
412
- * @invariant true if and only if (`page` * `recordsPerPage` < `total`)
1081
+ * @invariant true if and only if (`page` * `recordsPerPage` < `totalRecords`)
413
1082
  */
414
1083
  hasNext: boolean;
415
1084
  /**
@@ -437,150 +1106,423 @@ interface ReferrerLeaderboardPageContext extends Required<ReferrerLeaderboardPag
437
1106
  */
438
1107
  endIndex?: number;
439
1108
  }
440
- declare const validateReferrerLeaderboardPageContext: (context: ReferrerLeaderboardPageContext) => void;
441
- declare const buildReferrerLeaderboardPageContext: (optionalParams: ReferrerLeaderboardPageParams, leaderboard: ReferrerLeaderboard) => ReferrerLeaderboardPageContext;
1109
+ declare const validateReferrerLeaderboardPageContext: (context: ReferrerLeaderboardPageContext) => void;
1110
+ declare const buildReferrerLeaderboardPageContext: (optionalParams: ReferrerLeaderboardPageParams, leaderboard: ReferrerLeaderboard) => ReferrerLeaderboardPageContext;
1111
+ /**
1112
+ * Base fields shared by all leaderboard page variants.
1113
+ */
1114
+ interface BaseReferrerLeaderboardPage {
1115
+ /**
1116
+ * Discriminant identifying the award model for this leaderboard page.
1117
+ */
1118
+ awardModel: ReferralProgramAwardModel;
1119
+ /**
1120
+ * The {@link ReferrerLeaderboardPageContext} of this page relative to the overall leaderboard.
1121
+ */
1122
+ pageContext: ReferrerLeaderboardPageContext;
1123
+ /**
1124
+ * The status of the referral program edition.
1125
+ */
1126
+ status: ReferralProgramEditionStatusId;
1127
+ /**
1128
+ * The {@link UnixTimestamp} of when the data used to build this page was accurate as of.
1129
+ */
1130
+ accurateAsOf: UnixTimestamp;
1131
+ }
1132
+ /**
1133
+ * A leaderboard page whose `awardModel` is not recognized by this client version.
1134
+ *
1135
+ * @remarks
1136
+ * This is a **client-side forward-compatibility** type only. It is never serialized or processed
1137
+ * by business logic on the backend. When the server introduces a new award model type, older
1138
+ * clients preserve the page rather than throwing, and downstream code that encounters this type
1139
+ * should handle it gracefully rather than crashing.
1140
+ */
1141
+ interface ReferrerLeaderboardPageUnrecognized extends BaseReferrerLeaderboardPage {
1142
+ /**
1143
+ * Discriminant — always `"unrecognized"`.
1144
+ */
1145
+ awardModel: typeof ReferralProgramAwardModels.Unrecognized;
1146
+ /**
1147
+ * The original, unrecognized `awardModel` string received from the server.
1148
+ *
1149
+ * @remarks Preserved for logging and debugging. Never used for business logic.
1150
+ */
1151
+ originalAwardModel: string;
1152
+ }
1153
+ /**
1154
+ * Extracts the referrers for the current page from a fully-ranked Map.
1155
+ * Generic over the referrer type so each model variant retains its specific type.
1156
+ */
1157
+ declare function sliceReferrers<T>(referrers: Map<NormalizedAddress, T>, pageContext: ReferrerLeaderboardPageContext): T[];
1158
+
1159
+ /**
1160
+ * A page of referrers from the pie-split referrer leaderboard.
1161
+ */
1162
+ interface ReferrerLeaderboardPagePieSplit extends BaseReferrerLeaderboardPage {
1163
+ /**
1164
+ * Discriminant identifying this as a page from a pie-split leaderboard.
1165
+ *
1166
+ * @invariant Always equals `rules.awardModel` ({@link ReferralProgramAwardModels.PieSplit}).
1167
+ */
1168
+ awardModel: typeof ReferralProgramAwardModels.PieSplit;
1169
+ /**
1170
+ * The {@link ReferralProgramRulesPieSplit} used to generate the {@link ReferrerLeaderboardPieSplit}
1171
+ * that this {@link ReferrerLeaderboardPagePieSplit} comes from.
1172
+ */
1173
+ rules: ReferralProgramRulesPieSplit;
1174
+ /**
1175
+ * Ordered list of {@link AwardedReferrerMetricsPieSplit} for the {@link ReferrerLeaderboardPagePieSplit}
1176
+ * described by {@link pageContext} within the related {@link ReferrerLeaderboardPieSplit}.
1177
+ *
1178
+ * @invariant Array will be empty if `pageContext.totalRecords` is 0.
1179
+ * @invariant Array entries are ordered by `rank` (ascending).
1180
+ */
1181
+ referrers: AwardedReferrerMetricsPieSplit[];
1182
+ /**
1183
+ * The aggregated metrics for all referrers on the leaderboard.
1184
+ */
1185
+ aggregatedMetrics: AggregatedReferrerMetricsPieSplit;
1186
+ }
1187
+ declare function buildLeaderboardPagePieSplit(pageContext: ReferrerLeaderboardPageContext, leaderboard: ReferrerLeaderboardPieSplit): ReferrerLeaderboardPagePieSplit;
1188
+
1189
+ /**
1190
+ * Serialized representation of {@link ReferralProgramRulesPieSplit}.
1191
+ */
1192
+ interface SerializedReferralProgramRulesPieSplit extends Omit<ReferralProgramRulesPieSplit, "awardPool" | "rulesUrl"> {
1193
+ awardPool: SerializedPriceUsdc;
1194
+ rulesUrl: string;
1195
+ }
1196
+ /**
1197
+ * Serialized representation of {@link AggregatedReferrerMetricsPieSplit}.
1198
+ */
1199
+ interface SerializedAggregatedReferrerMetricsPieSplit extends Omit<AggregatedReferrerMetricsPieSplit, "grandTotalRevenueContribution"> {
1200
+ grandTotalRevenueContribution: SerializedPriceEth;
1201
+ }
1202
+ /**
1203
+ * Serialized representation of {@link AwardedReferrerMetricsPieSplit}.
1204
+ */
1205
+ interface SerializedAwardedReferrerMetricsPieSplit extends Omit<AwardedReferrerMetricsPieSplit, "totalRevenueContribution" | "awardPoolApproxValue"> {
1206
+ totalRevenueContribution: SerializedPriceEth;
1207
+ awardPoolApproxValue: SerializedPriceUsdc;
1208
+ }
1209
+ /**
1210
+ * Serialized representation of {@link UnrankedReferrerMetricsPieSplit}.
1211
+ */
1212
+ interface SerializedUnrankedReferrerMetricsPieSplit extends Omit<UnrankedReferrerMetricsPieSplit, "totalRevenueContribution" | "awardPoolApproxValue"> {
1213
+ totalRevenueContribution: SerializedPriceEth;
1214
+ awardPoolApproxValue: SerializedPriceUsdc;
1215
+ }
1216
+ /**
1217
+ * Serialized representation of {@link ReferrerLeaderboardPagePieSplit}.
1218
+ */
1219
+ interface SerializedReferrerLeaderboardPagePieSplit extends Omit<ReferrerLeaderboardPagePieSplit, "rules" | "referrers" | "aggregatedMetrics"> {
1220
+ rules: SerializedReferralProgramRulesPieSplit;
1221
+ referrers: SerializedAwardedReferrerMetricsPieSplit[];
1222
+ aggregatedMetrics: SerializedAggregatedReferrerMetricsPieSplit;
1223
+ }
1224
+ /**
1225
+ * Serialized representation of {@link ReferrerEditionMetricsRankedPieSplit}.
1226
+ */
1227
+ interface SerializedReferrerEditionMetricsRankedPieSplit extends Omit<ReferrerEditionMetricsRankedPieSplit, "rules" | "referrer" | "aggregatedMetrics"> {
1228
+ rules: SerializedReferralProgramRulesPieSplit;
1229
+ referrer: SerializedAwardedReferrerMetricsPieSplit;
1230
+ aggregatedMetrics: SerializedAggregatedReferrerMetricsPieSplit;
1231
+ }
1232
+ /**
1233
+ * Serialized representation of {@link ReferrerEditionMetricsUnrankedPieSplit}.
1234
+ */
1235
+ interface SerializedReferrerEditionMetricsUnrankedPieSplit extends Omit<ReferrerEditionMetricsUnrankedPieSplit, "rules" | "referrer" | "aggregatedMetrics"> {
1236
+ rules: SerializedReferralProgramRulesPieSplit;
1237
+ referrer: SerializedUnrankedReferrerMetricsPieSplit;
1238
+ aggregatedMetrics: SerializedAggregatedReferrerMetricsPieSplit;
1239
+ }
1240
+ /**
1241
+ * Serialized representation of {@link ReferrerEditionMetricsPieSplit}.
1242
+ */
1243
+ type SerializedReferrerEditionMetricsPieSplit = SerializedReferrerEditionMetricsRankedPieSplit | SerializedReferrerEditionMetricsUnrankedPieSplit;
1244
+ /**
1245
+ * Serialized representation of {@link ReferralProgramEditionSummaryPieSplit}.
1246
+ */
1247
+ interface SerializedReferralProgramEditionSummaryPieSplit extends Omit<ReferralProgramEditionSummaryPieSplit, "rules"> {
1248
+ rules: SerializedReferralProgramRulesPieSplit;
1249
+ }
1250
+
442
1251
  /**
443
- * A page of referrers from the referrer leaderboard.
1252
+ * Referrer edition metrics data for a specific referrer on a rev-share-cap leaderboard.
1253
+ *
1254
+ * Includes the referrer's awarded metrics from the leaderboard plus timestamp.
1255
+ *
1256
+ * @see {@link AwardedReferrerMetricsRevShareCap}
444
1257
  */
445
- interface ReferrerLeaderboardPage {
1258
+ interface ReferrerEditionMetricsRankedRevShareCap {
446
1259
  /**
447
- * The {@link ReferralProgramRules} used to generate the {@link ReferrerLeaderboard}
448
- * that this {@link ReferrerLeaderboardPage} comes from.
1260
+ * Discriminant identifying this as data from a rev-share-cap leaderboard edition.
1261
+ *
1262
+ * @invariant Always equals `rules.awardModel` ({@link ReferralProgramAwardModels.RevShareCap}).
449
1263
  */
450
- rules: ReferralProgramRules;
1264
+ awardModel: typeof ReferralProgramAwardModels.RevShareCap;
451
1265
  /**
452
- * Ordered list of {@link AwardedReferrerMetrics} for the {@link ReferrerLeaderboardPage}
453
- * described by `pageContext` within the related {@link ReferrerLeaderboard}.
454
- *
455
- * @invariant Array will be empty if `pageContext.totalRecords` is 0.
456
- * @invariant Array entries are ordered by `rank` (ascending).
1266
+ * The type of referrer edition metrics data.
457
1267
  */
458
- referrers: AwardedReferrerMetrics[];
1268
+ type: typeof ReferrerEditionMetricsTypeIds.Ranked;
459
1269
  /**
460
- * Aggregated metrics for all referrers on the leaderboard.
1270
+ * The {@link ReferralProgramRulesRevShareCap} used to calculate the {@link AwardedReferrerMetricsRevShareCap}.
461
1271
  */
462
- aggregatedMetrics: AggregatedReferrerMetrics;
1272
+ rules: ReferralProgramRulesRevShareCap;
463
1273
  /**
464
- * The {@link ReferrerLeaderboardPageContext} of this {@link ReferrerLeaderboardPage} relative to the overall
465
- * {@link ReferrerLeaderboard}.
1274
+ * The awarded referrer metrics from the leaderboard.
1275
+ *
1276
+ * Contains all calculated metrics including rank, qualification status,
1277
+ * uncapped award, and capped award.
466
1278
  */
467
- pageContext: ReferrerLeaderboardPageContext;
1279
+ referrer: AwardedReferrerMetricsRevShareCap;
468
1280
  /**
469
- * The {@link UnixTimestamp} of when the data used to build the {@link ReferrerLeaderboardPage} was accurate as of.
1281
+ * Aggregated metrics for all referrers on the leaderboard.
470
1282
  */
471
- accurateAsOf: UnixTimestamp;
472
- }
473
- declare const getReferrerLeaderboardPage: (pageParams: ReferrerLeaderboardPageParams, leaderboard: ReferrerLeaderboard) => ReferrerLeaderboardPage;
474
-
475
- /**
476
- * The type of referrer detail data.
477
- */
478
- declare const ReferrerDetailTypeIds: {
1283
+ aggregatedMetrics: AggregatedReferrerMetricsRevShareCap;
479
1284
  /**
480
- * Represents a referrer who is ranked on the leaderboard.
1285
+ * The status of the referral program edition
1286
+ * calculated based on the program's timing relative to {@link accurateAsOf}.
481
1287
  */
482
- readonly Ranked: "ranked";
1288
+ status: ReferralProgramEditionStatusId;
483
1289
  /**
484
- * Represents a referrer who is not ranked on the leaderboard.
1290
+ * The {@link UnixTimestamp} of when the data used to build the {@link ReferrerEditionMetricsRankedRevShareCap} was accurate as of.
485
1291
  */
486
- readonly Unranked: "unranked";
487
- };
488
- /**
489
- * The derived string union of possible {@link ReferrerDetailTypeIds}.
490
- */
491
- type ReferrerDetailTypeId = (typeof ReferrerDetailTypeIds)[keyof typeof ReferrerDetailTypeIds];
1292
+ accurateAsOf: UnixTimestamp;
1293
+ }
492
1294
  /**
493
- * Referrer detail data for a specific referrer address on the leaderboard.
494
- *
495
- * Includes the referrer's awarded metrics from the leaderboard plus timestamp.
1295
+ * Referrer edition metrics data for a specific referrer address NOT on the rev-share-cap leaderboard.
496
1296
  *
497
- * Invariants:
498
- * - `type` is always {@link ReferrerDetailTypeIds.Ranked}.
1297
+ * Includes the referrer's unranked metrics (with null rank and isQualified: false) plus timestamp.
499
1298
  *
500
- * @see {@link AwardedReferrerMetrics}
1299
+ * @see {@link UnrankedReferrerMetricsRevShareCap}
501
1300
  */
502
- interface ReferrerDetailRanked {
1301
+ interface ReferrerEditionMetricsUnrankedRevShareCap {
503
1302
  /**
504
- * The type of referrer detail data.
1303
+ * Discriminant identifying this as data from a rev-share-cap leaderboard edition.
1304
+ *
1305
+ * @invariant Always equals `rules.awardModel` ({@link ReferralProgramAwardModels.RevShareCap}).
505
1306
  */
506
- type: typeof ReferrerDetailTypeIds.Ranked;
1307
+ awardModel: typeof ReferralProgramAwardModels.RevShareCap;
507
1308
  /**
508
- * The {@link ReferralProgramRules} used to calculate the {@link AwardedReferrerMetrics}.
1309
+ * The type of referrer edition metrics data.
509
1310
  */
510
- rules: ReferralProgramRules;
1311
+ type: typeof ReferrerEditionMetricsTypeIds.Unranked;
511
1312
  /**
512
- * The awarded referrer metrics from the leaderboard.
1313
+ * The {@link ReferralProgramRulesRevShareCap} used to calculate the {@link UnrankedReferrerMetricsRevShareCap}.
1314
+ */
1315
+ rules: ReferralProgramRulesRevShareCap;
1316
+ /**
1317
+ * The unranked referrer metrics (not on the leaderboard).
513
1318
  *
514
- * Contains all calculated metrics including score, rank, qualification status,
515
- * and award pool share information.
1319
+ * Contains all calculated metrics with rank set to null and isQualified set to false.
516
1320
  */
517
- referrer: AwardedReferrerMetrics;
1321
+ referrer: UnrankedReferrerMetricsRevShareCap;
518
1322
  /**
519
1323
  * Aggregated metrics for all referrers on the leaderboard.
520
1324
  */
521
- aggregatedMetrics: AggregatedReferrerMetrics;
1325
+ aggregatedMetrics: AggregatedReferrerMetricsRevShareCap;
1326
+ /**
1327
+ * The status of the referral program edition
1328
+ * calculated based on the program's timing relative to {@link accurateAsOf}.
1329
+ */
1330
+ status: ReferralProgramEditionStatusId;
522
1331
  /**
523
- * The {@link UnixTimestamp} of when the data used to build the {@link ReferrerDetailData} was accurate as of.
1332
+ * The {@link UnixTimestamp} of when the data used to build the {@link ReferrerEditionMetricsUnrankedRevShareCap} was accurate as of.
524
1333
  */
525
1334
  accurateAsOf: UnixTimestamp;
526
1335
  }
527
1336
  /**
528
- * Referrer detail data for a specific referrer address NOT on the leaderboard.
1337
+ * All referrer edition metrics variants for the rev-share-cap award model.
529
1338
  *
530
- * Includes the referrer's unranked metrics (with null rank and isQualified: false) plus timestamp.
531
- *
532
- * Invariants:
533
- * - `type` is always {@link ReferrerDetailTypeIds.Unranked}.
1339
+ * Use `type` to determine if the referrer is ranked or unranked.
1340
+ */
1341
+ type ReferrerEditionMetricsRevShareCap = ReferrerEditionMetricsRankedRevShareCap | ReferrerEditionMetricsUnrankedRevShareCap;
1342
+
1343
+ /**
1344
+ * Edition summary for a `rev-share-cap` referral program edition.
534
1345
  *
535
- * @see {@link UnrankedReferrerMetrics}
1346
+ * Includes `awardPoolRemaining` so consumers can display pool exhaustion state
1347
+ * without needing to fetch the full leaderboard.
536
1348
  */
537
- interface ReferrerDetailUnranked {
1349
+ interface ReferralProgramEditionSummaryRevShareCap extends BaseReferralProgramEditionSummary {
538
1350
  /**
539
- * The type of referrer detail data.
1351
+ * Discriminant always `"rev-share-cap"`.
1352
+ *
1353
+ * @invariant Always equals `rules.awardModel` ({@link ReferralProgramAwardModels.RevShareCap}).
540
1354
  */
541
- type: typeof ReferrerDetailTypeIds.Unranked;
1355
+ awardModel: typeof ReferralProgramAwardModels.RevShareCap;
542
1356
  /**
543
- * The {@link ReferralProgramRules} used to calculate the {@link UnrankedReferrerMetrics}.
1357
+ * The rev-share-cap rules for this edition.
544
1358
  */
545
- rules: ReferralProgramRules;
1359
+ rules: ReferralProgramRulesRevShareCap;
546
1360
  /**
547
- * The unranked referrer metrics (not on the leaderboard).
1361
+ * The remaining award pool after sequential race processing.
548
1362
  *
549
- * Contains all calculated metrics with rank set to null and isQualified set to false.
1363
+ * When `0n`, the edition's status will be {@link ReferralProgramEditionStatuses.Exhausted}
1364
+ * if the edition is still within its active window.
1365
+ */
1366
+ awardPoolRemaining: PriceUsdc;
1367
+ }
1368
+ declare const validateEditionSummaryRevShareCap: (summary: ReferralProgramEditionSummaryRevShareCap) => void;
1369
+ /**
1370
+ * Build a {@link ReferralProgramEditionSummaryRevShareCap} from a rev-share-cap edition
1371
+ * config and the edition's leaderboard.
1372
+ */
1373
+ declare function buildEditionSummaryRevShareCap(slug: ReferralProgramEditionSlug, displayName: string, rules: ReferralProgramRulesRevShareCap, leaderboard: ReferrerLeaderboardRevShareCap): ReferralProgramEditionSummaryRevShareCap;
1374
+
1375
+ /**
1376
+ * A page of referrers from the rev-share-cap referrer leaderboard.
1377
+ */
1378
+ interface ReferrerLeaderboardPageRevShareCap extends BaseReferrerLeaderboardPage {
1379
+ /**
1380
+ * Discriminant identifying this as a page from a rev-share-cap leaderboard.
1381
+ *
1382
+ * @invariant Always equals `rules.awardModel` ({@link ReferralProgramAwardModels.RevShareCap}).
550
1383
  */
551
- referrer: UnrankedReferrerMetrics;
1384
+ awardModel: typeof ReferralProgramAwardModels.RevShareCap;
552
1385
  /**
553
- * Aggregated metrics for all referrers on the leaderboard.
1386
+ * The {@link ReferralProgramRulesRevShareCap} used to generate the {@link ReferrerLeaderboardRevShareCap}
1387
+ * that this {@link ReferrerLeaderboardPageRevShareCap} comes from.
554
1388
  */
555
- aggregatedMetrics: AggregatedReferrerMetrics;
1389
+ rules: ReferralProgramRulesRevShareCap;
556
1390
  /**
557
- * The {@link UnixTimestamp} of when the data used to build the {@link UnrankedReferrerDetailData} was accurate as of.
1391
+ * Ordered list of {@link AwardedReferrerMetricsRevShareCap} for the {@link ReferrerLeaderboardPageRevShareCap}
1392
+ * described by {@link pageContext} within the related {@link ReferrerLeaderboard}.
1393
+ *
1394
+ * @invariant Array will be empty if `pageContext.totalRecords` is 0.
1395
+ * @invariant Array entries are ordered by `rank` (ascending).
558
1396
  */
559
- accurateAsOf: UnixTimestamp;
1397
+ referrers: AwardedReferrerMetricsRevShareCap[];
1398
+ /**
1399
+ * The aggregated metrics for all referrers on the leaderboard.
1400
+ */
1401
+ aggregatedMetrics: AggregatedReferrerMetricsRevShareCap;
1402
+ }
1403
+ declare function buildLeaderboardPageRevShareCap(pageContext: ReferrerLeaderboardPageContext, leaderboard: ReferrerLeaderboardRevShareCap): ReferrerLeaderboardPageRevShareCap;
1404
+
1405
+ /**
1406
+ * Serialized representation of {@link ReferralProgramRulesRevShareCap}.
1407
+ */
1408
+ interface SerializedReferralProgramRulesRevShareCap extends Omit<ReferralProgramRulesRevShareCap, "awardPool" | "minBaseRevenueContribution" | "baseAnnualRevenueContribution" | "rulesUrl"> {
1409
+ awardPool: SerializedPriceUsdc;
1410
+ minBaseRevenueContribution: SerializedPriceUsdc;
1411
+ baseAnnualRevenueContribution: SerializedPriceUsdc;
1412
+ rulesUrl: string;
1413
+ }
1414
+ /**
1415
+ * Serialized representation of {@link AggregatedReferrerMetricsRevShareCap}.
1416
+ */
1417
+ interface SerializedAggregatedReferrerMetricsRevShareCap extends Omit<AggregatedReferrerMetricsRevShareCap, "grandTotalRevenueContribution" | "awardPoolRemaining"> {
1418
+ grandTotalRevenueContribution: SerializedPriceEth;
1419
+ awardPoolRemaining: SerializedPriceUsdc;
1420
+ }
1421
+ /**
1422
+ * Serialized representation of {@link AwardedReferrerMetricsRevShareCap}.
1423
+ */
1424
+ interface SerializedAwardedReferrerMetricsRevShareCap extends Omit<AwardedReferrerMetricsRevShareCap, "totalRevenueContribution" | "totalBaseRevenueContribution" | "uncappedAward" | "cappedAward"> {
1425
+ totalRevenueContribution: SerializedPriceEth;
1426
+ totalBaseRevenueContribution: SerializedPriceUsdc;
1427
+ uncappedAward: SerializedPriceUsdc;
1428
+ cappedAward: SerializedPriceUsdc;
1429
+ }
1430
+ /**
1431
+ * Serialized representation of {@link UnrankedReferrerMetricsRevShareCap}.
1432
+ */
1433
+ interface SerializedUnrankedReferrerMetricsRevShareCap extends Omit<UnrankedReferrerMetricsRevShareCap, "totalRevenueContribution" | "totalBaseRevenueContribution" | "uncappedAward" | "cappedAward"> {
1434
+ totalRevenueContribution: SerializedPriceEth;
1435
+ totalBaseRevenueContribution: SerializedPriceUsdc;
1436
+ uncappedAward: SerializedPriceUsdc;
1437
+ cappedAward: SerializedPriceUsdc;
1438
+ }
1439
+ /**
1440
+ * Serialized representation of {@link ReferrerLeaderboardPageRevShareCap}.
1441
+ */
1442
+ interface SerializedReferrerLeaderboardPageRevShareCap extends Omit<ReferrerLeaderboardPageRevShareCap, "rules" | "referrers" | "aggregatedMetrics"> {
1443
+ rules: SerializedReferralProgramRulesRevShareCap;
1444
+ referrers: SerializedAwardedReferrerMetricsRevShareCap[];
1445
+ aggregatedMetrics: SerializedAggregatedReferrerMetricsRevShareCap;
1446
+ }
1447
+ /**
1448
+ * Serialized representation of {@link ReferrerEditionMetricsRankedRevShareCap}.
1449
+ */
1450
+ interface SerializedReferrerEditionMetricsRankedRevShareCap extends Omit<ReferrerEditionMetricsRankedRevShareCap, "rules" | "referrer" | "aggregatedMetrics"> {
1451
+ rules: SerializedReferralProgramRulesRevShareCap;
1452
+ referrer: SerializedAwardedReferrerMetricsRevShareCap;
1453
+ aggregatedMetrics: SerializedAggregatedReferrerMetricsRevShareCap;
1454
+ }
1455
+ /**
1456
+ * Serialized representation of {@link ReferrerEditionMetricsUnrankedRevShareCap}.
1457
+ */
1458
+ interface SerializedReferrerEditionMetricsUnrankedRevShareCap extends Omit<ReferrerEditionMetricsUnrankedRevShareCap, "rules" | "referrer" | "aggregatedMetrics"> {
1459
+ rules: SerializedReferralProgramRulesRevShareCap;
1460
+ referrer: SerializedUnrankedReferrerMetricsRevShareCap;
1461
+ aggregatedMetrics: SerializedAggregatedReferrerMetricsRevShareCap;
560
1462
  }
561
1463
  /**
562
- * Referrer detail data for a specific referrer address.
1464
+ * Serialized representation of {@link ReferrerEditionMetricsRevShareCap}.
1465
+ */
1466
+ type SerializedReferrerEditionMetricsRevShareCap = SerializedReferrerEditionMetricsRankedRevShareCap | SerializedReferrerEditionMetricsUnrankedRevShareCap;
1467
+ /**
1468
+ * Serialized representation of {@link ReferralProgramEditionSummaryRevShareCap}.
1469
+ */
1470
+ interface SerializedReferralProgramEditionSummaryRevShareCap extends Omit<ReferralProgramEditionSummaryRevShareCap, "rules" | "awardPoolRemaining"> {
1471
+ rules: SerializedReferralProgramRulesRevShareCap;
1472
+ awardPoolRemaining: SerializedPriceUsdc;
1473
+ }
1474
+
1475
+ /**
1476
+ * Referrer edition metrics data for a specific referrer address.
563
1477
  *
564
- * Use the `type` field to determine the specific type interpretation
565
- * at runtime.
1478
+ * Use `awardModel` to narrow the award model variant, then `type` to narrow ranked vs unranked.
1479
+ * When `awardModel` is `"unrecognized"`, the data was produced by a server running a newer
1480
+ * version — use {@link ReferrerEditionMetricsUnrecognized} to access `originalAwardModel`.
566
1481
  */
567
- type ReferrerDetail = ReferrerDetailRanked | ReferrerDetailUnranked;
1482
+ type ReferrerEditionMetrics = ReferrerEditionMetricsPieSplit | ReferrerEditionMetricsRevShareCap | ReferrerEditionMetricsUnrecognized;
568
1483
  /**
569
- * Get the detail for a specific referrer from the leaderboard.
1484
+ * Get the edition metrics for a specific referrer from the leaderboard.
570
1485
  *
571
- * Returns a {@link ReferrerDetailRanked} if the referrer is on the leaderboard,
572
- * or a {@link ReferrerDetailUnranked} if the referrer has no referrals.
1486
+ * Returns a {@link ReferrerEditionMetricsPieSplit} or {@link ReferrerEditionMetricsRevShareCap}
1487
+ * with `type: "ranked"` if the referrer is on the leaderboard, or `type: "unranked"` otherwise.
573
1488
  *
574
1489
  * @param referrer - The referrer address to look up
575
1490
  * @param leaderboard - The referrer leaderboard to query
576
- * @returns The appropriate {@link ReferrerDetail} (ranked or unranked)
577
1491
  */
578
- declare const getReferrerDetail: (referrer: Address, leaderboard: ReferrerLeaderboard) => ReferrerDetail;
1492
+ declare const getReferrerEditionMetrics: (referrer: NormalizedAddress, leaderboard: ReferrerLeaderboard) => ReferrerEditionMetrics;
1493
+
1494
+ /**
1495
+ * Runtime summary of a referral program edition, enriched with current status and pool data.
1496
+ *
1497
+ * Use `awardModel` to discriminate between variants at runtime.
1498
+ */
1499
+ type ReferralProgramEditionSummary = ReferralProgramEditionSummaryPieSplit | ReferralProgramEditionSummaryRevShareCap | ReferralProgramEditionSummaryUnrecognized;
1500
+ /**
1501
+ * Build a runtime edition summary from an edition config and the edition's leaderboard.
1502
+ * Dispatches to the appropriate per-model builder based on `leaderboard.awardModel`.
1503
+ *
1504
+ * @param config - The edition configuration (provides `slug` and `displayName`).
1505
+ * @param leaderboard - The resolved leaderboard for this edition.
1506
+ */
1507
+ declare function buildEditionSummary(config: ReferralProgramEditionConfig, leaderboard: ReferrerLeaderboard): ReferralProgramEditionSummary;
1508
+
1509
+ /**
1510
+ * A page of referrers from the referrer leaderboard.
1511
+ *
1512
+ * Use `awardModel` to narrow the specific variant at runtime. Within each variant,
1513
+ * `rules`, `referrers`, and `aggregatedMetrics` are all guaranteed to be from the same model.
1514
+ * When `awardModel` is `"unrecognized"`, the page was produced by a server running a newer
1515
+ * version — use {@link ReferrerLeaderboardPageUnrecognized} to access `originalAwardModel`.
1516
+ */
1517
+ type ReferrerLeaderboardPage = ReferrerLeaderboardPagePieSplit | ReferrerLeaderboardPageRevShareCap | ReferrerLeaderboardPageUnrecognized;
1518
+ declare const getReferrerLeaderboardPage: (pageParams: ReferrerLeaderboardPageParams, leaderboard: ReferrerLeaderboard) => ReferrerLeaderboardPage;
579
1519
 
580
1520
  /**
581
1521
  * Request parameters for a referrer leaderboard page query.
582
1522
  */
583
1523
  interface ReferrerLeaderboardPageRequest extends ReferrerLeaderboardPageParams {
1524
+ /** The referral program edition slug */
1525
+ edition: ReferralProgramEditionSlug;
584
1526
  }
585
1527
  /**
586
1528
  * A status code for a referrer leaderboard page API response.
@@ -622,18 +1564,24 @@ type ReferrerLeaderboardPageResponseError = {
622
1564
  */
623
1565
  type ReferrerLeaderboardPageResponse = ReferrerLeaderboardPageResponseOk | ReferrerLeaderboardPageResponseError;
624
1566
  /**
625
- * Request parameters for referrer detail query.
1567
+ * Maximum number of editions that can be requested in a single {@link ReferrerMetricsEditionsRequest}.
626
1568
  */
627
- interface ReferrerDetailRequest {
1569
+ declare const MAX_EDITIONS_PER_REQUEST = 20;
1570
+ /**
1571
+ * Request parameters for referrer metrics query.
1572
+ */
1573
+ interface ReferrerMetricsEditionsRequest {
628
1574
  /** The Ethereum address of the referrer to query */
629
1575
  referrer: Address;
1576
+ /** Array of edition slugs to query (min 1, max {@link MAX_EDITIONS_PER_REQUEST}, must be distinct) */
1577
+ editions: ReferralProgramEditionSlug[];
630
1578
  }
631
1579
  /**
632
- * A status code for referrer detail API responses.
1580
+ * A status code for referrer metrics API responses.
633
1581
  */
634
- declare const ReferrerDetailResponseCodes: {
1582
+ declare const ReferrerMetricsEditionsResponseCodes: {
635
1583
  /**
636
- * Represents that the referrer detail data is available.
1584
+ * Represents that the referrer metrics data for the requested editions is available.
637
1585
  */
638
1586
  readonly Ok: "ok";
639
1587
  /**
@@ -642,87 +1590,99 @@ declare const ReferrerDetailResponseCodes: {
642
1590
  readonly Error: "error";
643
1591
  };
644
1592
  /**
645
- * The derived string union of possible {@link ReferrerDetailResponseCodes}.
1593
+ * The derived string union of possible {@link ReferrerMetricsEditionsResponseCodes}.
1594
+ */
1595
+ type ReferrerMetricsEditionsResponseCode = (typeof ReferrerMetricsEditionsResponseCodes)[keyof typeof ReferrerMetricsEditionsResponseCodes];
1596
+ /**
1597
+ * Referrer metrics data for requested editions.
1598
+ *
1599
+ * Maps each requested edition slug to the referrer's metrics for that edition.
1600
+ * Uses Partial because TypeScript cannot know at compile time which specific edition
1601
+ * slugs are requested. At runtime, when responseCode is Ok, all requested edition slugs
1602
+ * are guaranteed to be present in this record.
646
1603
  */
647
- type ReferrerDetailResponseCode = (typeof ReferrerDetailResponseCodes)[keyof typeof ReferrerDetailResponseCodes];
1604
+ type ReferrerMetricsEditionsData = Partial<Record<ReferralProgramEditionSlug, ReferrerEditionMetrics>>;
648
1605
  /**
649
- * A referrer detail response when the data is available for a referrer on the leaderboard.
1606
+ * A successful response containing referrer metrics for the requested editions.
650
1607
  */
651
- type ReferrerDetailResponseOk = {
652
- responseCode: typeof ReferrerDetailResponseCodes.Ok;
653
- data: ReferrerDetail;
1608
+ type ReferrerMetricsEditionsResponseOk = {
1609
+ responseCode: typeof ReferrerMetricsEditionsResponseCodes.Ok;
1610
+ data: ReferrerMetricsEditionsData;
654
1611
  };
655
1612
  /**
656
- * A referrer detail response when an error occurs.
1613
+ * A referrer metrics editions response when an error occurs.
657
1614
  */
658
- type ReferrerDetailResponseError = {
659
- responseCode: typeof ReferrerDetailResponseCodes.Error;
1615
+ type ReferrerMetricsEditionsResponseError = {
1616
+ responseCode: typeof ReferrerMetricsEditionsResponseCodes.Error;
660
1617
  error: string;
661
1618
  errorMessage: string;
662
1619
  };
663
1620
  /**
664
- * A referrer detail API response.
1621
+ * A referrer metrics editions API response.
665
1622
  *
666
1623
  * Use the `responseCode` field to determine the specific type interpretation
667
1624
  * at runtime.
668
1625
  */
669
- type ReferrerDetailResponse = ReferrerDetailResponseOk | ReferrerDetailResponseError;
670
-
1626
+ type ReferrerMetricsEditionsResponse = ReferrerMetricsEditionsResponseOk | ReferrerMetricsEditionsResponseError;
671
1627
  /**
672
- * Serialized representation of {@link RevenueContribution}.
673
- *
674
- * RevenueContribution is a bigint, which is serialized as a string for JSON compatibility.
1628
+ * A status code for referral program edition summaries API responses.
675
1629
  */
676
- type SerializedRevenueContribution = string;
1630
+ declare const ReferralProgramEditionSummariesResponseCodes: {
1631
+ /**
1632
+ * Represents that the edition summaries are available.
1633
+ */
1634
+ readonly Ok: "ok";
1635
+ /**
1636
+ * Represents that the edition summaries are not available.
1637
+ */
1638
+ readonly Error: "error";
1639
+ };
677
1640
  /**
678
- * Serialized representation of {@link ReferralProgramRules}.
679
- *
680
- * Note: All fields are already serializable primitives, so this type is identical to the source type.
1641
+ * The derived string union of possible {@link ReferralProgramEditionSummariesResponseCodes}.
681
1642
  */
682
- type SerializedReferralProgramRules = ReferralProgramRules;
1643
+ type ReferralProgramEditionSummariesResponseCode = (typeof ReferralProgramEditionSummariesResponseCodes)[keyof typeof ReferralProgramEditionSummariesResponseCodes];
683
1644
  /**
684
- * Serialized representation of {@link AwardedReferrerMetrics}.
1645
+ * The data payload containing edition summaries.
1646
+ * Editions are sorted in descending order by start timestamp.
685
1647
  */
686
- interface SerializedAwardedReferrerMetrics extends Omit<AwardedReferrerMetrics, "totalRevenueContribution"> {
687
- totalRevenueContribution: SerializedRevenueContribution;
688
- }
1648
+ type ReferralProgramEditionSummariesData = {
1649
+ editions: ReferralProgramEditionSummary[];
1650
+ };
689
1651
  /**
690
- * Serialized representation of {@link UnrankedReferrerMetrics}.
1652
+ * A successful response containing edition summaries.
691
1653
  */
692
- interface SerializedUnrankedReferrerMetrics extends Omit<UnrankedReferrerMetrics, "totalRevenueContribution"> {
693
- totalRevenueContribution: SerializedRevenueContribution;
694
- }
1654
+ type ReferralProgramEditionSummariesResponseOk = {
1655
+ responseCode: typeof ReferralProgramEditionSummariesResponseCodes.Ok;
1656
+ data: ReferralProgramEditionSummariesData;
1657
+ };
695
1658
  /**
696
- * Serialized representation of {@link AggregatedReferrerMetrics}.
1659
+ * An edition summaries response when an error occurs.
697
1660
  */
698
- interface SerializedAggregatedReferrerMetrics extends Omit<AggregatedReferrerMetrics, "grandTotalRevenueContribution"> {
699
- grandTotalRevenueContribution: SerializedRevenueContribution;
700
- }
1661
+ type ReferralProgramEditionSummariesResponseError = {
1662
+ responseCode: typeof ReferralProgramEditionSummariesResponseCodes.Error;
1663
+ error: string;
1664
+ errorMessage: string;
1665
+ };
701
1666
  /**
702
- * Serialized representation of {@link ReferrerLeaderboardPage}.
1667
+ * A referral program edition summaries API response.
1668
+ *
1669
+ * Use the `responseCode` field to determine the specific type interpretation
1670
+ * at runtime.
703
1671
  */
704
- interface SerializedReferrerLeaderboardPage extends Omit<ReferrerLeaderboardPage, "referrers" | "aggregatedMetrics"> {
705
- referrers: SerializedAwardedReferrerMetrics[];
706
- aggregatedMetrics: SerializedAggregatedReferrerMetrics;
707
- }
1672
+ type ReferralProgramEditionSummariesResponse = ReferralProgramEditionSummariesResponseOk | ReferralProgramEditionSummariesResponseError;
1673
+
708
1674
  /**
709
- * Serialized representation of {@link ReferrerDetailRanked}.
1675
+ * Serialized representation of {@link ReferralProgramRules}.
710
1676
  */
711
- interface SerializedReferrerDetailRanked extends Omit<ReferrerDetailRanked, "referrer" | "aggregatedMetrics"> {
712
- referrer: SerializedAwardedReferrerMetrics;
713
- aggregatedMetrics: SerializedAggregatedReferrerMetrics;
714
- }
1677
+ type SerializedReferralProgramRules = SerializedReferralProgramRulesPieSplit | SerializedReferralProgramRulesRevShareCap;
715
1678
  /**
716
- * Serialized representation of {@link ReferrerDetailUnranked}.
1679
+ * Serialized representation of {@link ReferrerLeaderboardPage}.
717
1680
  */
718
- interface SerializedReferrerDetailUnranked extends Omit<ReferrerDetailUnranked, "referrer" | "aggregatedMetrics"> {
719
- referrer: SerializedUnrankedReferrerMetrics;
720
- aggregatedMetrics: SerializedAggregatedReferrerMetrics;
721
- }
1681
+ type SerializedReferrerLeaderboardPage = SerializedReferrerLeaderboardPagePieSplit | SerializedReferrerLeaderboardPageRevShareCap;
722
1682
  /**
723
- * Serialized representation of {@link ReferrerDetail} (union of ranked and unranked).
1683
+ * Serialized representation of {@link ReferrerEditionMetrics}.
724
1684
  */
725
- type SerializedReferrerDetail = SerializedReferrerDetailRanked | SerializedReferrerDetailUnranked;
1685
+ type SerializedReferrerEditionMetrics = SerializedReferrerEditionMetricsPieSplit | SerializedReferrerEditionMetricsRevShareCap;
726
1686
  /**
727
1687
  * Serialized representation of {@link ReferrerLeaderboardPageResponseError}.
728
1688
  *
@@ -740,61 +1700,147 @@ interface SerializedReferrerLeaderboardPageResponseOk extends Omit<ReferrerLeade
740
1700
  */
741
1701
  type SerializedReferrerLeaderboardPageResponse = SerializedReferrerLeaderboardPageResponseOk | SerializedReferrerLeaderboardPageResponseError;
742
1702
  /**
743
- * Serialized representation of {@link ReferrerDetailResponseError}.
1703
+ * Serialized representation of {@link ReferralProgramEditionSummary}.
1704
+ */
1705
+ type SerializedReferralProgramEditionSummary = SerializedReferralProgramEditionSummaryPieSplit | SerializedReferralProgramEditionSummaryRevShareCap;
1706
+ /**
1707
+ * Serialized representation of referrer metrics data for requested editions.
1708
+ * Uses Partial because TypeScript cannot know at compile time which specific edition
1709
+ * slugs are requested. At runtime, when responseCode is Ok, all requested edition slugs
1710
+ * are guaranteed to be present in this record.
1711
+ */
1712
+ type SerializedReferrerMetricsEditionsData = Partial<Record<ReferralProgramEditionSlug, SerializedReferrerEditionMetrics>>;
1713
+ /**
1714
+ * Serialized representation of {@link ReferrerMetricsEditionsResponseOk}.
1715
+ */
1716
+ interface SerializedReferrerMetricsEditionsResponseOk extends Omit<ReferrerMetricsEditionsResponseOk, "data"> {
1717
+ data: SerializedReferrerMetricsEditionsData;
1718
+ }
1719
+ /**
1720
+ * Serialized representation of {@link ReferrerMetricsEditionsResponseError}.
744
1721
  *
745
1722
  * Note: All fields are already serializable, so this type is identical to the source type.
746
1723
  */
747
- type SerializedReferrerDetailResponseError = ReferrerDetailResponseError;
1724
+ type SerializedReferrerMetricsEditionsResponseError = ReferrerMetricsEditionsResponseError;
1725
+ /**
1726
+ * Serialized representation of {@link ReferrerMetricsEditionsResponse}.
1727
+ */
1728
+ type SerializedReferrerMetricsEditionsResponse = SerializedReferrerMetricsEditionsResponseOk | SerializedReferrerMetricsEditionsResponseError;
1729
+ /**
1730
+ * Serialized representation of {@link ReferralProgramEditionSummariesData}.
1731
+ */
1732
+ interface SerializedReferralProgramEditionSummariesData extends Omit<ReferralProgramEditionSummariesData, "editions"> {
1733
+ editions: SerializedReferralProgramEditionSummary[];
1734
+ }
748
1735
  /**
749
- * Serialized representation of {@link ReferrerDetailResponseOk}.
1736
+ * Serialized representation of {@link ReferralProgramEditionSummariesResponseOk}.
750
1737
  */
751
- interface SerializedReferrerDetailResponseOk extends Omit<ReferrerDetailResponseOk, "data"> {
752
- data: SerializedReferrerDetail;
1738
+ interface SerializedReferralProgramEditionSummariesResponseOk extends Omit<ReferralProgramEditionSummariesResponseOk, "data"> {
1739
+ data: SerializedReferralProgramEditionSummariesData;
753
1740
  }
754
1741
  /**
755
- * Serialized representation of {@link ReferrerDetailResponse}.
1742
+ * Serialized representation of {@link ReferralProgramEditionSummariesResponseError}.
1743
+ *
1744
+ * Note: All fields are already serializable, so this type is identical to the source type.
1745
+ */
1746
+ type SerializedReferralProgramEditionSummariesResponseError = ReferralProgramEditionSummariesResponseError;
1747
+ /**
1748
+ * Serialized representation of {@link ReferralProgramEditionSummariesResponse}.
756
1749
  */
757
- type SerializedReferrerDetailResponse = SerializedReferrerDetailResponseOk | SerializedReferrerDetailResponseError;
1750
+ type SerializedReferralProgramEditionSummariesResponse = SerializedReferralProgramEditionSummariesResponseOk | SerializedReferralProgramEditionSummariesResponseError;
758
1751
 
759
1752
  /**
760
1753
  * Deserialize a {@link ReferrerLeaderboardPageResponse} object.
761
- *
762
- * Note: This function explicitly deserializes each subobject to convert string
763
- * RevenueContribution values back to bigint, then validates using Zod schemas
764
- * to enforce invariants on the data.
765
1754
  */
766
1755
  declare function deserializeReferrerLeaderboardPageResponse(maybeResponse: SerializedReferrerLeaderboardPageResponse, valueLabel?: string): ReferrerLeaderboardPageResponse;
767
1756
  /**
768
- * Deserialize a {@link ReferrerDetailResponse} object.
769
- *
770
- * Note: This function explicitly deserializes each subobject to convert string
771
- * RevenueContribution values back to bigint, then validates using Zod schemas
772
- * to enforce invariants on the data.
1757
+ * Deserialize a {@link ReferrerMetricsEditionsResponse} object.
773
1758
  */
774
- declare function deserializeReferrerDetailResponse(maybeResponse: SerializedReferrerDetailResponse, valueLabel?: string): ReferrerDetailResponse;
1759
+ declare function deserializeReferrerMetricsEditionsResponse(maybeResponse: SerializedReferrerMetricsEditionsResponse, valueLabel?: string): ReferrerMetricsEditionsResponse;
1760
+ /**
1761
+ * Deserializes an array of {@link ReferralProgramEditionConfig} objects.
1762
+ */
1763
+ declare function deserializeReferralProgramEditionConfigSetArray(maybeArray: unknown, valueLabel?: string): ReferralProgramEditionConfig[];
1764
+ /**
1765
+ * Deserialize a {@link ReferralProgramEditionSummariesResponse} object.
1766
+ */
1767
+ declare function deserializeReferralProgramEditionSummariesResponse(maybeResponse: SerializedReferralProgramEditionSummariesResponse, valueLabel?: string): ReferralProgramEditionSummariesResponse;
775
1768
 
1769
+ /**
1770
+ * Serializes a {@link ReferralProgramRules} object.
1771
+ *
1772
+ * @throws if called with a {@link ReferralProgramRulesUnrecognized} — unrecognized editions are
1773
+ * client-side forward-compatibility placeholders and must never be serialized.
1774
+ */
1775
+ declare function serializeReferralProgramRules(rules: ReferralProgramRules): SerializedReferralProgramRules;
1776
+ /**
1777
+ * Serializes a {@link ReferralProgramEditionSummary} object.
1778
+ *
1779
+ * @throws if called with a {@link ReferralProgramEditionSummaryUnrecognized} — unrecognized
1780
+ * summaries are client-side forward-compatibility placeholders and must never be serialized.
1781
+ */
1782
+ declare function serializeReferralProgramEditionSummary(summary: ReferralProgramEditionSummary): SerializedReferralProgramEditionSummary;
776
1783
  /**
777
1784
  * Serialize a {@link ReferrerLeaderboardPageResponse} object.
778
1785
  */
779
1786
  declare function serializeReferrerLeaderboardPageResponse(response: ReferrerLeaderboardPageResponse): SerializedReferrerLeaderboardPageResponse;
780
1787
  /**
781
- * Serialize a {@link ReferrerDetailResponse} object.
1788
+ * Serialize a {@link ReferrerMetricsEditionsResponse} object.
1789
+ */
1790
+ declare function serializeReferrerMetricsEditionsResponse(response: ReferrerMetricsEditionsResponse): SerializedReferrerMetricsEditionsResponse;
1791
+ /**
1792
+ * Serialize a {@link ReferralProgramEditionSummariesResponse} object.
1793
+ */
1794
+ declare function serializeReferralProgramEditionSummariesResponse(response: ReferralProgramEditionSummariesResponse): SerializedReferralProgramEditionSummariesResponse;
1795
+
1796
+ /**
1797
+ * Calculate the score of a referrer based on the total incremental duration
1798
+ * (in seconds) of registrations and renewals for direct subnames of .eth
1799
+ * referred by the referrer within the referral program edition.
1800
+ *
1801
+ * Used exclusively in the pie-split award model pipeline.
1802
+ *
1803
+ * @param totalIncrementalDuration - The total incremental duration (in seconds)
1804
+ * of referrals made by a referrer within the {@link ReferralProgramRulesPieSplit}.
1805
+ */
1806
+ declare const calcReferrerScorePieSplit: (totalIncrementalDuration: Duration) => ReferrerScore;
1807
+
1808
+ /**
1809
+ * Calculate the status of a `pie-split` referral program.
1810
+ *
1811
+ * Delegates entirely to {@link calcBaseReferralProgramEditionStatus} — pie-split has no additional
1812
+ * runtime conditions that affect status beyond the time-based lifecycle.
1813
+ *
1814
+ * @param rules - The pie-split rules for the edition.
1815
+ * @param now - Current date in {@link UnixTimestamp} format.
1816
+ */
1817
+ declare const calcReferralProgramEditionStatusPieSplit: (rules: ReferralProgramRulesPieSplit, now: UnixTimestamp) => ReferralProgramEditionStatusId;
1818
+
1819
+ /**
1820
+ * Calculate the status of a `rev-share-cap` referral program.
1821
+ *
1822
+ * Returns `Exhausted` when the program is `Active` but its award pool has been fully consumed
1823
+ * (`awardPoolRemaining.amount === 0n`). Otherwise delegates to {@link calcBaseReferralProgramEditionStatus}.
1824
+ *
1825
+ * @param rules - The rev-share-cap rules for the edition.
1826
+ * @param now - Current date in {@link UnixTimestamp} format.
1827
+ * @param aggregatedMetrics - The aggregated leaderboard metrics, used to check `awardPoolRemaining`.
782
1828
  */
783
- declare function serializeReferrerDetailResponse(response: ReferrerDetailResponse): SerializedReferrerDetailResponse;
1829
+ declare const calcReferralProgramEditionStatusRevShareCap: (rules: ReferralProgramRulesRevShareCap, now: UnixTimestamp, aggregatedMetrics: AggregatedReferrerMetricsRevShareCap) => ReferralProgramEditionStatusId;
784
1830
 
785
1831
  /**
786
- * Default ENSNode API endpoint URL
1832
+ * Default ENSNode endpoint URL
787
1833
  */
788
1834
  declare const DEFAULT_ENSNODE_API_URL: "https://api.alpha.ensnode.io";
789
1835
  /**
790
- * Configuration options for ENS Referrals API client
1836
+ * Configuration options for an ENS Referrals client
791
1837
  */
792
1838
  interface ClientOptions {
793
- /** The ENSNode API URL */
1839
+ /** The ENSNode URL */
794
1840
  url: URL;
795
1841
  }
796
1842
  /**
797
- * ENS Referrals API Client
1843
+ * ENS Referrals Client
798
1844
  *
799
1845
  * Provides access to ENS Referrals data and leaderboard information.
800
1846
  *
@@ -803,8 +1849,9 @@ interface ClientOptions {
803
1849
  * // Create client with default options
804
1850
  * const client = new ENSReferralsClient();
805
1851
  *
806
- * // Get referrer leaderboard
1852
+ * // Get referrer leaderboard for December 2025 edition
807
1853
  * const leaderboardPage = await client.getReferrerLeaderboardPage({
1854
+ * edition: "2025-12",
808
1855
  * page: 1,
809
1856
  * recordsPerPage: 25
810
1857
  * });
@@ -823,51 +1870,83 @@ declare class ENSReferralsClient {
823
1870
  static defaultOptions(): ClientOptions;
824
1871
  constructor(options?: Partial<ClientOptions>);
825
1872
  getOptions(): Readonly<ClientOptions>;
1873
+ /**
1874
+ * Get Referral Program Edition Config Set
1875
+ *
1876
+ * Fetches and deserializes a referral program edition config set from a remote URL.
1877
+ *
1878
+ * @param url - The URL to fetch the edition config set from
1879
+ * @returns A ReferralProgramEditionConfigSet (Map of edition slugs to edition configurations)
1880
+ *
1881
+ * @remarks Editions whose `rules.awardModel` is not recognized by this client version are
1882
+ * preserved as {@link ReferralProgramRulesUnrecognized}. The returned map includes all
1883
+ * editions — recognized and unrecognized alike. Callers should check `editionConfig.rules.awardModel`
1884
+ * and skip editions with `"unrecognized"` as appropriate. The returned map may be empty.
1885
+ *
1886
+ * @throws if the fetch fails
1887
+ * @throws if the response is not valid JSON
1888
+ * @throws if the data doesn't match the expected schema
1889
+ *
1890
+ * @example
1891
+ * ```typescript
1892
+ * const url = new URL("https://example.com/editions.json");
1893
+ * const editionConfigSet = await ENSReferralsClient.getReferralProgramEditionConfigSet(url);
1894
+ * console.log(`Loaded ${editionConfigSet.size} editions`);
1895
+ * ```
1896
+ */
1897
+ static getReferralProgramEditionConfigSet(url: URL): Promise<ReferralProgramEditionConfigSet>;
826
1898
  /**
827
1899
  * Fetch Referrer Leaderboard Page
828
1900
  *
829
- * Retrieves a paginated list of referrer leaderboard metrics with contribution percentages.
830
- * Each referrer's contribution is calculated as a percentage of the grand totals across all referrers.
1901
+ * Retrieves a paginated list of referrer leaderboard metrics for a specific referral program edition.
831
1902
  *
832
- * @param request - Pagination parameters
1903
+ * @param request - Request parameters including edition and pagination
1904
+ * @param request.edition - The referral program edition slug (e.g., "2025-12", "2026-03", or any other configured edition slug)
833
1905
  * @param request.page - The page number to retrieve (1-indexed, default: 1)
834
1906
  * @param request.recordsPerPage - Number of records per page (default: 25, max: 100)
835
1907
  * @returns {ReferrerLeaderboardPageResponse}
836
1908
  *
1909
+ * @remarks If the server returns a leaderboard page whose `awardModel` is not recognized by
1910
+ * this client version, it is preserved as {@link ReferrerLeaderboardPageUnrecognized}. Callers
1911
+ * should check `response.data.awardModel` and handle the `"unrecognized"` case accordingly.
1912
+ *
837
1913
  * @throws if the ENSNode request fails
838
1914
  * @throws if the ENSNode API returns an error response
839
1915
  * @throws if the ENSNode response breaks required invariants
840
1916
  *
841
1917
  * @example
842
1918
  * ```typescript
843
- * // Get first page with default page size (25 records)
844
- * const response = await client.getReferrerLeaderboardPage();
1919
+ * // Get first page of 2025-12 leaderboard with default page size (25 records)
1920
+ * const editionSlug = "2025-12";
1921
+ * const response = await client.getReferrerLeaderboardPage({ edition: editionSlug });
845
1922
  * if (response.responseCode === ReferrerLeaderboardPageResponseCodes.Ok) {
846
- * const {
847
- * aggregatedMetrics,
848
- * referrers,
849
- * rules,
850
- * pageContext,
851
- * updatedAt
852
- * } = response.data;
853
- * console.log(aggregatedMetrics);
854
- * console.log(referrers);
855
- * console.log(rules);
856
- * console.log(updatedAt);
857
- * console.log(`Page ${pageContext.page} of ${pageContext.totalPages}`);
1923
+ * const { awardModel, pageContext, accurateAsOf } = response.data;
1924
+ * if (awardModel === ReferralProgramAwardModels.Unrecognized) {
1925
+ * console.log(`Unrecognized award model: ${response.data.originalAwardModel} — skipping`);
1926
+ * } else {
1927
+ * const { aggregatedMetrics, referrers, rules } = response.data;
1928
+ * console.log(`Edition: ${editionSlug}`);
1929
+ * console.log(`Subregistry: ${rules.subregistryId}`);
1930
+ * console.log(`Total Referrers: ${pageContext.totalRecords}`);
1931
+ * console.log(`Page ${pageContext.page} of ${pageContext.totalPages}`);
1932
+ * }
858
1933
  * }
859
1934
  * ```
860
1935
  *
861
1936
  * @example
862
1937
  * ```typescript
863
- * // Get second page with 50 records per page
864
- * const response = await client.getReferrerLeaderboardPage({ page: 2, recordsPerPage: 50 });
1938
+ * // Get second page of 2026-03 with 50 records per page
1939
+ * const response = await client.getReferrerLeaderboardPage({
1940
+ * edition: "2026-03",
1941
+ * page: 2,
1942
+ * recordsPerPage: 50
1943
+ * });
865
1944
  * ```
866
1945
  *
867
1946
  * @example
868
1947
  * ```typescript
869
- * // Handle error response, ie. when Referrer Leaderboard is not currently available.
870
- * const response = await client.getReferrerLeaderboardPage();
1948
+ * // Handle error response (e.g., unknown edition or data not available)
1949
+ * const response = await client.getReferrerLeaderboardPage({ edition: "2025-12" });
871
1950
  *
872
1951
  * if (response.responseCode === ReferrerLeaderboardPageResponseCodes.Error) {
873
1952
  * console.error(response.error);
@@ -875,84 +1954,136 @@ declare class ENSReferralsClient {
875
1954
  * }
876
1955
  * ```
877
1956
  */
878
- getReferrerLeaderboardPage(request?: ReferrerLeaderboardPageRequest): Promise<ReferrerLeaderboardPageResponse>;
1957
+ getReferrerLeaderboardPage(request: ReferrerLeaderboardPageRequest): Promise<ReferrerLeaderboardPageResponse>;
879
1958
  /**
880
- * Fetch Referrer Detail
1959
+ * Fetch Referrer Metrics for Specific Editions
881
1960
  *
882
- * Retrieves detailed information about a specific referrer, whether they are on the
883
- * leaderboard or not.
1961
+ * Retrieves detailed information about a specific referrer for the requested
1962
+ * referral program editions. Returns a record mapping each requested edition slug
1963
+ * to the referrer's metrics for that edition.
884
1964
  *
885
- * The response data is a discriminated union type with a `type` field:
1965
+ * The response data maps edition slugs to referrer metrics. Each edition's entry is a
1966
+ * {@link ReferrerEditionMetrics} discriminated union. Narrow on `awardModel` first to
1967
+ * exclude unrecognized models, then on `type` to distinguish ranked from unranked:
886
1968
  *
887
- * **For referrers on the leaderboard** (`ReferrerDetailRanked`):
888
- * - `type`: {@link ReferrerDetailTypeIds.Ranked}
889
- * - `referrer`: The `AwardedReferrerMetrics` from @namehash/ens-referrals
890
- * - `rules`: The referral program rules
891
- * - `aggregatedMetrics`: Aggregated metrics for all referrers on the leaderboard
892
- * - `accurateAsOf`: Unix timestamp indicating when the data was last updated
1969
+ * - `awardModel: "unrecognized"` ({@link ReferrerEditionMetricsUnrecognized}): the server
1970
+ * returned an award model this client does not recognize. Only `originalAwardModel` is
1971
+ * available; no model-specific fields are present.
1972
+ * - `type: "ranked"` ({@link ReferrerEditionMetricsTypeIds.Ranked}): the referrer appears on
1973
+ * the leaderboard. `referrer` contains rank, qualification status, and award share.
1974
+ * - `type: "unranked"` ({@link ReferrerEditionMetricsTypeIds.Unranked}): the referrer has no
1975
+ * activity in this edition. `referrer` contains zero-value placeholders.
893
1976
  *
894
- * **For referrers NOT on the leaderboard** (`ReferrerDetailUnranked`):
895
- * - `type`: {@link ReferrerDetailTypeIds.Unranked}
896
- * - `referrer`: The `UnrankedReferrerMetrics` from @namehash/ens-referrals
897
- * - `rules`: The referral program rules
898
- * - `aggregatedMetrics`: Aggregated metrics for all referrers on the leaderboard
899
- * - `accurateAsOf`: Unix timestamp indicating when the data was last updated
1977
+ * **Note:** This endpoint does not allow partial success. When `responseCode === Ok`,
1978
+ * all requested editions are guaranteed to be present in the response data. If any
1979
+ * requested edition cannot be returned, the entire request fails with an error.
900
1980
  *
901
1981
  * @see {@link https://www.npmjs.com/package/@namehash/ens-referrals|@namehash/ens-referrals} for calculation details
902
1982
  *
903
- * @param request The referrer address to query
904
- * @returns {ReferrerDetailResponse} Returns the referrer detail response
1983
+ * @param request The referrer address and edition slugs to query
1984
+ * @returns {ReferrerMetricsEditionsResponse} Returns the referrer metrics for requested editions
1985
+ *
1986
+ * @remarks If the server returns metrics for an edition whose `awardModel` is not recognized by
1987
+ * this client version, that edition's entry in `response.data` is preserved as
1988
+ * {@link ReferrerEditionMetricsUnrecognized}. Callers should check each edition's `awardModel`
1989
+ * and handle the `"unrecognized"` case accordingly.
905
1990
  *
906
1991
  * @throws if the ENSNode request fails
907
1992
  * @throws if the response data is malformed
908
1993
  *
909
1994
  * @example
910
1995
  * ```typescript
911
- * // Get referrer detail for a specific address
912
- * const response = await client.getReferrerDetail({
913
- * referrer: "0x1234567890123456789012345678901234567890"
1996
+ * // Get referrer metrics for specific editions
1997
+ * const response = await client.getReferrerMetricsEditions({
1998
+ * referrer: "0x1234567890123456789012345678901234567890",
1999
+ * editions: ["2025-12", "2026-01"]
914
2000
  * });
915
- * if (response.responseCode === ReferrerDetailResponseCodes.Ok) {
916
- * const { type, referrer, rules, aggregatedMetrics, accurateAsOf } = response.data;
917
- * console.log(type); // ReferrerDetailTypeIds.Ranked or ReferrerDetailTypeIds.Unranked
918
- * console.log(referrer);
919
- * console.log(accurateAsOf);
2001
+ * if (response.responseCode === ReferrerMetricsEditionsResponseCodes.Ok) {
2002
+ * // All requested editions are present in response.data
2003
+ * for (const [editionSlug, detail] of Object.entries(response.data)) {
2004
+ * console.log(`Edition: ${editionSlug}`);
2005
+ * if (detail.awardModel === ReferralProgramAwardModels.Unrecognized) {
2006
+ * console.log(`Unrecognized award model: ${detail.originalAwardModel} — skipping`);
2007
+ * continue;
2008
+ * }
2009
+ * console.log(`Type: ${detail.type}`);
2010
+ * if (detail.type === ReferrerEditionMetricsTypeIds.Ranked) {
2011
+ * console.log(`Rank: ${detail.referrer.rank}`);
2012
+ * console.log(`Award Share: ${detail.referrer.awardPoolShare * 100}%`);
2013
+ * }
2014
+ * }
920
2015
  * }
921
2016
  * ```
922
2017
  *
923
2018
  * @example
924
2019
  * ```typescript
925
- * // Use discriminated union to check if referrer is ranked
926
- * const response = await client.getReferrerDetail({
927
- * referrer: "0x1234567890123456789012345678901234567890"
2020
+ * // Access specific edition data directly (edition is guaranteed to exist when OK)
2021
+ * const response = await client.getReferrerMetricsEditions({
2022
+ * referrer: "0x1234567890123456789012345678901234567890",
2023
+ * editions: ["2025-12"]
928
2024
  * });
929
- * if (response.responseCode === ReferrerDetailResponseCodes.Ok) {
930
- * if (response.data.type === ReferrerDetailTypeIds.Ranked) {
931
- * // TypeScript knows this is ReferrerDetailRanked
932
- * console.log(`Rank: ${response.data.referrer.rank}`);
933
- * console.log(`Qualified: ${response.data.referrer.isQualified}`);
934
- * console.log(`Award Pool Share: ${response.data.referrer.awardPoolShare * 100}%`);
935
- * } else {
936
- * // TypeScript knows this is ReferrerDetailUnranked
937
- * console.log("Referrer is not on the leaderboard (no referrals yet)");
2025
+ * if (response.responseCode === ReferrerMetricsEditionsResponseCodes.Ok) {
2026
+ * const detail = response.data["2025-12"];
2027
+ * if (detail && detail.awardModel === ReferralProgramAwardModels.Unrecognized) {
2028
+ * console.log(`Unrecognized award model: ${detail.originalAwardModel} — skipping`);
2029
+ * } else if (detail && detail.type === ReferrerEditionMetricsTypeIds.Ranked) {
2030
+ * console.log(`Edition 2025-12 Rank: ${detail.referrer.rank}`);
2031
+ * } else if (detail) {
2032
+ * console.log("Referrer is not on the leaderboard for 2025-12");
938
2033
  * }
939
2034
  * }
940
2035
  * ```
941
2036
  *
942
2037
  * @example
943
2038
  * ```typescript
944
- * // Handle error response, ie. when Referrer Detail is not currently available.
945
- * const response = await client.getReferrerDetail({
946
- * referrer: "0x1234567890123456789012345678901234567890"
2039
+ * // Handle error response (e.g., unknown edition or data not available)
2040
+ * const response = await client.getReferrerMetricsEditions({
2041
+ * referrer: "0x1234567890123456789012345678901234567890",
2042
+ * editions: ["2025-12", "invalid-edition"]
947
2043
  * });
948
2044
  *
949
- * if (response.responseCode === ReferrerDetailResponseCodes.Error) {
2045
+ * if (response.responseCode === ReferrerMetricsEditionsResponseCodes.Error) {
2046
+ * console.error(response.error);
2047
+ * console.error(response.errorMessage);
2048
+ * }
2049
+ * ```
2050
+ */
2051
+ getReferrerMetricsEditions(request: ReferrerMetricsEditionsRequest): Promise<ReferrerMetricsEditionsResponse>;
2052
+ /**
2053
+ * Get the currently configured referral program edition summaries.
2054
+ * Editions are sorted in descending order by start timestamp (most recent first).
2055
+ *
2056
+ * @returns A response containing edition summaries, or an error response if unavailable.
2057
+ *
2058
+ * @remarks Editions whose `rules.awardModel` is not recognized by this client version are
2059
+ * preserved as {@link ReferralProgramEditionSummaryUnrecognized}. The returned response includes all
2060
+ * editions — recognized and unrecognized alike. Callers should check `edition.awardModel`
2061
+ * and skip editions with `"unrecognized"` as appropriate. The returned editions list may be empty.
2062
+ *
2063
+ * @example
2064
+ * ```typescript
2065
+ * const response = await client.getEditionSummaries();
2066
+ *
2067
+ * if (response.responseCode === ReferralProgramEditionSummariesResponseCodes.Ok) {
2068
+ * console.log(`Found ${response.data.editions.length} editions`);
2069
+ * for (const edition of response.data.editions) {
2070
+ * console.log(`${edition.slug}: ${edition.displayName}`);
2071
+ * }
2072
+ * }
2073
+ * ```
2074
+ *
2075
+ * @example
2076
+ * ```typescript
2077
+ * // Handle error response
2078
+ * const response = await client.getEditionSummaries();
2079
+ *
2080
+ * if (response.responseCode === ReferralProgramEditionSummariesResponseCodes.Error) {
950
2081
  * console.error(response.error);
951
2082
  * console.error(response.errorMessage);
952
2083
  * }
953
2084
  * ```
954
2085
  */
955
- getReferrerDetail(request: ReferrerDetailRequest): Promise<ReferrerDetailResponse>;
2086
+ getEditionSummaries(): Promise<ReferralProgramEditionSummariesResponse>;
956
2087
  }
957
2088
 
958
2089
  /**
@@ -967,38 +2098,6 @@ declare const isPositiveInteger: (value: number) => boolean;
967
2098
  declare const validateNonNegativeInteger: (value: number) => void;
968
2099
  declare const isFiniteNonNegativeNumber: (value: number) => boolean;
969
2100
 
970
- /**
971
- * The type of referral program's status.
972
- */
973
- declare const ReferralProgramStatuses: {
974
- /**
975
- * Represents a referral program that has been announced, but hasn't started yet.
976
- */
977
- readonly Scheduled: "Scheduled";
978
- /**
979
- * Represents a currently ongoing referral program.
980
- */
981
- readonly Active: "Active";
982
- /**
983
- * Represents a referral program that has already ended.
984
- */
985
- readonly Closed: "Closed";
986
- };
987
- /**
988
- * The derived string union of possible {@link ReferralProgramStatuses}.
989
- */
990
- type ReferralProgramStatusId = (typeof ReferralProgramStatuses)[keyof typeof ReferralProgramStatuses];
991
- /**
992
- * Calculate the status of the referral program based on the current date
993
- * and program's timeframe available in its rules.
994
- *
995
- * @param referralProgramRules - Related referral program's rules containing
996
- * program's start date and end date.
997
- *
998
- * @param now - Current date in {@link UnixTimestamp} format.
999
- */
1000
- declare const calcReferralProgramStatus: (referralProgramRules: ReferralProgramRules, now: UnixTimestamp) => ReferralProgramStatusId;
1001
-
1002
2101
  declare const validateUnixTimestamp: (timestamp: UnixTimestamp) => void;
1003
2102
  /**
1004
2103
  * The number of seconds in a year.
@@ -1010,4 +2109,4 @@ declare const SECONDS_PER_YEAR: Duration;
1010
2109
  declare function isValidDuration(duration: Duration): boolean;
1011
2110
  declare function validateDuration(duration: Duration): void;
1012
2111
 
1013
- export { type AggregatedReferrerMetrics, type AwardedReferrerMetrics, type ClientOptions, DEFAULT_ENSNODE_API_URL, ENSReferralsClient, ENS_HOLIDAY_AWARDS_END_DATE, ENS_HOLIDAY_AWARDS_MAX_QUALIFIED_REFERRERS, ENS_HOLIDAY_AWARDS_START_DATE, ENS_HOLIDAY_AWARDS_TOTAL_AWARD_POOL_VALUE, REFERRERS_PER_LEADERBOARD_PAGE_DEFAULT, REFERRERS_PER_LEADERBOARD_PAGE_MAX, type RankedReferrerMetrics, type ReferralProgramRules, type ReferralProgramStatusId, ReferralProgramStatuses, type ReferrerDetail, type ReferrerDetailRanked, type ReferrerDetailRequest, type ReferrerDetailResponse, type ReferrerDetailResponseCode, ReferrerDetailResponseCodes, type ReferrerDetailResponseError, type ReferrerDetailResponseOk, type ReferrerDetailTypeId, ReferrerDetailTypeIds, type ReferrerDetailUnranked, type ReferrerLeaderboard, type ReferrerLeaderboardPage, type ReferrerLeaderboardPageContext, type ReferrerLeaderboardPageParams, type ReferrerLeaderboardPageRequest, type ReferrerLeaderboardPageResponse, type ReferrerLeaderboardPageResponseCode, ReferrerLeaderboardPageResponseCodes, type ReferrerLeaderboardPageResponseError, type ReferrerLeaderboardPageResponseOk, type ReferrerMetrics, type ReferrerMetricsForComparison, type ReferrerRank, type ReferrerScore, type RevenueContribution, SECONDS_PER_YEAR, type ScoredReferrerMetrics, type SerializedAggregatedReferrerMetrics, type SerializedAwardedReferrerMetrics, type SerializedReferralProgramRules, type SerializedReferrerDetail, type SerializedReferrerDetailRanked, type SerializedReferrerDetailResponse, type SerializedReferrerDetailResponseError, type SerializedReferrerDetailResponseOk, type SerializedReferrerDetailUnranked, type SerializedReferrerLeaderboardPage, type SerializedReferrerLeaderboardPageResponse, type SerializedReferrerLeaderboardPageResponseError, type SerializedReferrerLeaderboardPageResponseOk, type SerializedRevenueContribution, type SerializedUnrankedReferrerMetrics, type USDQuantity, type UnrankedReferrerMetrics, buildAggregatedReferrerMetrics, buildAwardedReferrerMetrics, buildEnsReferralUrl, buildRankedReferrerMetrics, buildReferralProgramRules, buildReferrerLeaderboard, buildReferrerLeaderboardPageContext, buildReferrerLeaderboardPageParams, buildReferrerMetrics, buildScoredReferrerMetrics, buildUnrankedReferrerMetrics, calcReferralProgramStatus, calcReferrerAwardPoolShare, calcReferrerFinalScore, calcReferrerFinalScoreBoost, calcReferrerFinalScoreMultiplier, calcReferrerScore, compareReferrerMetrics, deserializeReferrerDetailResponse, deserializeReferrerLeaderboardPageResponse, getReferrerDetail, getReferrerLeaderboardPage, isFiniteNonNegativeNumber, isInteger, isNonNegativeInteger, isPositiveInteger, isReferrerQualified, isValidDuration, isValidReferrerScore, isValidRevenueContribution, isValidUSDQuantity, normalizeAddress, serializeReferrerDetailResponse, serializeReferrerLeaderboardPageResponse, sortReferrerMetrics, validateAggregatedReferrerMetrics, validateAwardedReferrerMetrics, validateDuration, validateLowercaseAddress, validateNonNegativeInteger, validateRankedReferrerMetrics, validateReferralProgramRules, validateReferrerLeaderboardPageContext, validateReferrerMetrics, validateReferrerRank, validateReferrerScore, validateRevenueContribution, validateScoredReferrerMetrics, validateUSDQuantity, validateUnixTimestamp, validateUnrankedReferrerMetrics };
2112
+ export { type AdminAction, type AdminActionDisqualification, type AdminActionType, AdminActionTypes, type AdminActionWarning, type AggregatedReferrerMetricsPieSplit, type AggregatedReferrerMetricsRevShareCap, type AwardedReferrerMetricsPieSplit, type AwardedReferrerMetricsRevShareCap, type BaseReferralProgramEditionSummary, type BaseReferralProgramRules, type BaseReferrerLeaderboardPage, type ClientOptions, DEFAULT_ENSNODE_API_URL, ENSReferralsClient, MAX_EDITIONS_PER_REQUEST, REFERRAL_PROGRAM_EDITION_SLUG_PATTERN, REFERRERS_PER_LEADERBOARD_PAGE_DEFAULT, REFERRERS_PER_LEADERBOARD_PAGE_MAX, type RankedReferrerMetricsPieSplit, type RankedReferrerMetricsRevShareCap, type ReferralEvent, type ReferralProgramAwardModel, ReferralProgramAwardModels, type ReferralProgramEditionConfig, type ReferralProgramEditionConfigSet, type ReferralProgramEditionSlug, type ReferralProgramEditionStatusId, ReferralProgramEditionStatuses, type ReferralProgramEditionSummariesData, type ReferralProgramEditionSummariesResponse, type ReferralProgramEditionSummariesResponseCode, ReferralProgramEditionSummariesResponseCodes, type ReferralProgramEditionSummariesResponseError, type ReferralProgramEditionSummariesResponseOk, type ReferralProgramEditionSummary, type ReferralProgramEditionSummaryPieSplit, type ReferralProgramEditionSummaryRevShareCap, type ReferralProgramEditionSummaryUnrecognized, type ReferralProgramRules, type ReferralProgramRulesPieSplit, type ReferralProgramRulesRevShareCap, type ReferralProgramRulesUnrecognized, type ReferrerEditionMetrics, type ReferrerEditionMetricsPieSplit, type ReferrerEditionMetricsRankedPieSplit, type ReferrerEditionMetricsRankedRevShareCap, type ReferrerEditionMetricsRevShareCap, type ReferrerEditionMetricsTypeId, ReferrerEditionMetricsTypeIds, type ReferrerEditionMetricsUnrankedPieSplit, type ReferrerEditionMetricsUnrankedRevShareCap, type ReferrerEditionMetricsUnrecognized, type ReferrerLeaderboard, type ReferrerLeaderboardPage, type ReferrerLeaderboardPageContext, type ReferrerLeaderboardPageParams, type ReferrerLeaderboardPagePieSplit, type ReferrerLeaderboardPageRequest, type ReferrerLeaderboardPageResponse, type ReferrerLeaderboardPageResponseCode, ReferrerLeaderboardPageResponseCodes, type ReferrerLeaderboardPageResponseError, type ReferrerLeaderboardPageResponseOk, type ReferrerLeaderboardPageRevShareCap, type ReferrerLeaderboardPageUnrecognized, type ReferrerLeaderboardPieSplit, type ReferrerLeaderboardRevShareCap, type ReferrerMetrics, type ReferrerMetricsEditionsData, type ReferrerMetricsEditionsRequest, type ReferrerMetricsEditionsResponse, type ReferrerMetricsEditionsResponseCode, ReferrerMetricsEditionsResponseCodes, type ReferrerMetricsEditionsResponseError, type ReferrerMetricsEditionsResponseOk, type ReferrerMetricsForComparison, type ReferrerMetricsRevShareCap, type ReferrerRank, type ReferrerScore, SECONDS_PER_YEAR, type ScoredReferrerMetricsPieSplit, type SerializedAggregatedReferrerMetricsPieSplit, type SerializedAggregatedReferrerMetricsRevShareCap, type SerializedAwardedReferrerMetricsPieSplit, type SerializedAwardedReferrerMetricsRevShareCap, type SerializedReferralProgramEditionSummariesData, type SerializedReferralProgramEditionSummariesResponse, type SerializedReferralProgramEditionSummariesResponseError, type SerializedReferralProgramEditionSummariesResponseOk, type SerializedReferralProgramEditionSummary, type SerializedReferralProgramEditionSummaryPieSplit, type SerializedReferralProgramEditionSummaryRevShareCap, type SerializedReferralProgramRules, type SerializedReferralProgramRulesPieSplit, type SerializedReferralProgramRulesRevShareCap, type SerializedReferrerEditionMetrics, type SerializedReferrerEditionMetricsPieSplit, type SerializedReferrerEditionMetricsRankedPieSplit, type SerializedReferrerEditionMetricsRankedRevShareCap, type SerializedReferrerEditionMetricsRevShareCap, type SerializedReferrerEditionMetricsUnrankedPieSplit, type SerializedReferrerEditionMetricsUnrankedRevShareCap, type SerializedReferrerLeaderboardPage, type SerializedReferrerLeaderboardPagePieSplit, type SerializedReferrerLeaderboardPageResponse, type SerializedReferrerLeaderboardPageResponseError, type SerializedReferrerLeaderboardPageResponseOk, type SerializedReferrerLeaderboardPageRevShareCap, type SerializedReferrerMetricsEditionsData, type SerializedReferrerMetricsEditionsResponse, type SerializedReferrerMetricsEditionsResponseError, type SerializedReferrerMetricsEditionsResponseOk, type SerializedUnrankedReferrerMetricsPieSplit, type SerializedUnrankedReferrerMetricsRevShareCap, type UnrankedReferrerMetricsPieSplit, type UnrankedReferrerMetricsRevShareCap, buildAggregatedReferrerMetricsPieSplit, buildAggregatedReferrerMetricsRevShareCap, buildAwardedReferrerMetricsPieSplit, buildAwardedReferrerMetricsRevShareCap, buildEditionSummary, buildEditionSummaryPieSplit, buildEditionSummaryRevShareCap, buildEnsReferralUrl, buildLeaderboardPagePieSplit, buildLeaderboardPageRevShareCap, buildRankedReferrerMetricsPieSplit, buildRankedReferrerMetricsRevShareCap, buildReferralProgramEditionConfigSet, buildReferralProgramRulesPieSplit, buildReferralProgramRulesRevShareCap, buildReferrerLeaderboardPageContext, buildReferrerLeaderboardPageParams, buildReferrerLeaderboardPieSplit, buildReferrerLeaderboardRevShareCap, buildReferrerMetrics, buildReferrerMetricsRevShareCap, buildScoredReferrerMetricsPieSplit, buildUnrankedReferrerMetricsPieSplit, buildUnrankedReferrerMetricsRevShareCap, calcBaseReferralProgramEditionStatus, calcReferralProgramEditionStatusPieSplit, calcReferralProgramEditionStatusRevShareCap, calcReferrerAwardPoolSharePieSplit, calcReferrerScorePieSplit, compareReferrerMetrics, deserializeReferralProgramEditionConfigSetArray, deserializeReferralProgramEditionSummariesResponse, deserializeReferrerLeaderboardPageResponse, deserializeReferrerMetricsEditionsResponse, getReferrerEditionMetrics, getReferrerLeaderboardPage, isFiniteNonNegativeNumber, isInteger, isNonNegativeInteger, isPositiveInteger, isReferrerQualifiedRevShareCap, isValidDuration, isValidReferrerScore, serializeReferralProgramEditionSummariesResponse, serializeReferralProgramEditionSummary, serializeReferralProgramRules, serializeReferrerLeaderboardPageResponse, serializeReferrerMetricsEditionsResponse, sliceReferrers, sortReferrerMetrics, validateAggregatedReferrerMetricsPieSplit, validateAggregatedReferrerMetricsRevShareCap, validateAwardedReferrerMetricsPieSplit, validateAwardedReferrerMetricsRevShareCap, validateBaseReferralProgramEditionSummary, validateBaseReferralProgramRules, validateDuration, validateEditionSummaryPieSplit, validateEditionSummaryRevShareCap, validateNonNegativeInteger, validateNormalizedAddress, validateRankedReferrerMetricsPieSplit, validateRankedReferrerMetricsRevShareCap, validateReferralProgramEditionConfigSet, validateReferralProgramRulesPieSplit, validateReferralProgramRulesRevShareCap, validateReferrerLeaderboardPageContext, validateReferrerMetrics, validateReferrerMetricsRevShareCap, validateReferrerRank, validateReferrerScore, validateScoredReferrerMetricsPieSplit, validateUnixTimestamp, validateUnrankedReferrerMetricsPieSplit, validateUnrankedReferrerMetricsRevShareCap };