@namehash/ens-referrals 1.9.0 → 1.10.1

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