@namehash/ens-referrals 0.0.0-next-20260102143513

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.js ADDED
@@ -0,0 +1,646 @@
1
+ // src/address.ts
2
+ import { isAddress } from "viem";
3
+ var validateLowercaseAddress = (address) => {
4
+ if (!isAddress(address, { strict: false })) {
5
+ throw new Error(`Invalid address: ${address}. Address must be a valid EVM address.`);
6
+ }
7
+ if (address !== address.toLowerCase()) {
8
+ throw new Error(`Invalid address: ${address}. Address must be in lowercase format.`);
9
+ }
10
+ };
11
+ var normalizeAddress = (address) => {
12
+ return address.toLowerCase();
13
+ };
14
+
15
+ // src/number.ts
16
+ var isInteger = (value) => {
17
+ return Number.isInteger(value);
18
+ };
19
+ var isNonNegativeInteger = (value) => {
20
+ return value >= 0 && Number.isInteger(value);
21
+ };
22
+ var isPositiveInteger = (value) => {
23
+ return value >= 1 && Number.isInteger(value);
24
+ };
25
+ var validateNonNegativeInteger = (value) => {
26
+ if (!isNonNegativeInteger(value)) {
27
+ throw new Error(`Invalid non-negative integer: ${value}.`);
28
+ }
29
+ };
30
+ var isFiniteNonNegativeNumber = (value) => {
31
+ return value >= 0 && Number.isFinite(value);
32
+ };
33
+
34
+ // src/revenue-contribution.ts
35
+ function isValidRevenueContribution(value) {
36
+ return typeof value === "bigint" && value >= 0n;
37
+ }
38
+ function validateRevenueContribution(value) {
39
+ if (typeof value !== "bigint") {
40
+ throw new Error(`Invalid revenue contribution: must be a bigint, got: ${typeof value}`);
41
+ }
42
+ if (value < 0n) {
43
+ throw new Error(`Invalid revenue contribution: must be non-negative, got: ${value.toString()}`);
44
+ }
45
+ }
46
+
47
+ // src/time.ts
48
+ var validateUnixTimestamp = (timestamp) => {
49
+ if (!isInteger(timestamp)) {
50
+ throw new Error(`Invalid Unix timestamp: ${timestamp}. Unix timestamp must be an integer.`);
51
+ }
52
+ };
53
+ var SECONDS_PER_YEAR = 31556952;
54
+ function isValidDuration(duration) {
55
+ return isNonNegativeInteger(duration);
56
+ }
57
+ function validateDuration(duration) {
58
+ if (!isValidDuration(duration)) {
59
+ throw new Error(`Invalid duration: ${duration}. Duration must be a non-negative integer.`);
60
+ }
61
+ }
62
+
63
+ // src/score.ts
64
+ var isValidReferrerScore = (score) => {
65
+ return score >= 0 && Number.isFinite(score);
66
+ };
67
+ var validateReferrerScore = (score) => {
68
+ if (!isValidReferrerScore(score)) {
69
+ throw new Error(
70
+ `Invalid referrer score: ${score}. Referrer score must be a finite non-negative number.`
71
+ );
72
+ }
73
+ };
74
+ var calcReferrerScore = (totalIncrementalDuration) => {
75
+ return totalIncrementalDuration / SECONDS_PER_YEAR;
76
+ };
77
+
78
+ // src/aggregations.ts
79
+ var validateAggregatedReferrerMetrics = (metrics) => {
80
+ validateNonNegativeInteger(metrics.grandTotalReferrals);
81
+ validateDuration(metrics.grandTotalIncrementalDuration);
82
+ validateRevenueContribution(metrics.grandTotalRevenueContribution);
83
+ validateReferrerScore(metrics.grandTotalQualifiedReferrersFinalScore);
84
+ validateReferrerScore(metrics.minFinalScoreToQualify);
85
+ };
86
+ var buildAggregatedReferrerMetrics = (referrers, rules) => {
87
+ let grandTotalReferrals = 0;
88
+ let grandTotalIncrementalDuration = 0;
89
+ let grandTotalRevenueContribution = 0n;
90
+ let grandTotalQualifiedReferrersFinalScore = 0;
91
+ let minFinalScoreToQualify = Number.MAX_SAFE_INTEGER;
92
+ for (const referrer of referrers) {
93
+ grandTotalReferrals += referrer.totalReferrals;
94
+ grandTotalIncrementalDuration += referrer.totalIncrementalDuration;
95
+ grandTotalRevenueContribution += referrer.totalRevenueContribution;
96
+ if (referrer.isQualified) {
97
+ grandTotalQualifiedReferrersFinalScore += referrer.finalScore;
98
+ if (referrer.finalScore < minFinalScoreToQualify) {
99
+ minFinalScoreToQualify = referrer.finalScore;
100
+ }
101
+ }
102
+ }
103
+ if (minFinalScoreToQualify === Number.MAX_SAFE_INTEGER) {
104
+ if (rules.maxQualifiedReferrers === 0) {
105
+ } else {
106
+ if (referrers.length !== 0) {
107
+ throw new Error(
108
+ "AggregatedReferrerMetrics: There are referrers on the leaderboard, and the rules allow for qualified referrers, but no qualified referrers."
109
+ );
110
+ }
111
+ minFinalScoreToQualify = 0;
112
+ }
113
+ }
114
+ const result = {
115
+ grandTotalReferrals,
116
+ grandTotalIncrementalDuration,
117
+ grandTotalRevenueContribution,
118
+ grandTotalQualifiedReferrersFinalScore,
119
+ minFinalScoreToQualify
120
+ };
121
+ validateAggregatedReferrerMetrics(result);
122
+ return result;
123
+ };
124
+
125
+ // src/currency.ts
126
+ function isValidUSDQuantity(value) {
127
+ return isFiniteNonNegativeNumber(value);
128
+ }
129
+ function validateUSDQuantity(value) {
130
+ if (!isValidUSDQuantity(value)) {
131
+ throw new Error(`Invalid USD quantity: ${value}.`);
132
+ }
133
+ }
134
+
135
+ // src/encoding.ts
136
+ import { getAddress, pad, size, slice, zeroAddress } from "viem";
137
+ var ENCODED_REFERRER_BYTE_OFFSET = 12;
138
+ var ENCODED_REFERRER_BYTE_LENGTH = 32;
139
+ var EXPECTED_ENCODED_REFERRER_PADDING = pad("0x", {
140
+ size: ENCODED_REFERRER_BYTE_OFFSET,
141
+ dir: "left"
142
+ });
143
+ var ZERO_ENCODED_REFERRER = pad("0x", {
144
+ size: ENCODED_REFERRER_BYTE_LENGTH,
145
+ dir: "left"
146
+ });
147
+ function buildEncodedReferrer(address) {
148
+ const lowercaseAddress = address.toLowerCase();
149
+ return pad(lowercaseAddress, { size: ENCODED_REFERRER_BYTE_LENGTH, dir: "left" });
150
+ }
151
+ function decodeEncodedReferrer(encodedReferrer) {
152
+ if (size(encodedReferrer) !== ENCODED_REFERRER_BYTE_LENGTH) {
153
+ throw new Error(
154
+ `Encoded referrer value must be represented by ${ENCODED_REFERRER_BYTE_LENGTH} bytes.`
155
+ );
156
+ }
157
+ const padding = slice(encodedReferrer, 0, ENCODED_REFERRER_BYTE_OFFSET);
158
+ if (padding !== EXPECTED_ENCODED_REFERRER_PADDING) {
159
+ return zeroAddress;
160
+ }
161
+ const decodedReferrer = slice(encodedReferrer, ENCODED_REFERRER_BYTE_OFFSET);
162
+ try {
163
+ return getAddress(decodedReferrer);
164
+ } catch {
165
+ throw new Error(`Decoded referrer value must be a valid EVM address.`);
166
+ }
167
+ }
168
+
169
+ // src/rank.ts
170
+ var validateReferrerRank = (rank) => {
171
+ if (!isPositiveInteger(rank)) {
172
+ throw new Error(`Invalid ReferrerRank: ${rank}. ReferrerRank must be a positive integer.`);
173
+ }
174
+ };
175
+ function isReferrerQualified(rank, rules) {
176
+ return rank <= rules.maxQualifiedReferrers;
177
+ }
178
+ function calcReferrerFinalScoreBoost(rank, rules) {
179
+ if (!isReferrerQualified(rank, rules)) return 0;
180
+ return 1 - (rank - 1) / (rules.maxQualifiedReferrers - 1);
181
+ }
182
+ function calcReferrerFinalScoreMultiplier(rank, rules) {
183
+ return 1 + calcReferrerFinalScoreBoost(rank, rules);
184
+ }
185
+ function calcReferrerFinalScore(rank, totalIncrementalDuration, rules) {
186
+ return calcReferrerScore(totalIncrementalDuration) * calcReferrerFinalScoreMultiplier(rank, rules);
187
+ }
188
+ var compareReferrerMetrics = (a, b) => {
189
+ if (a.totalIncrementalDuration !== b.totalIncrementalDuration) {
190
+ return b.totalIncrementalDuration - a.totalIncrementalDuration;
191
+ }
192
+ if (b.referrer > a.referrer) return 1;
193
+ if (b.referrer < a.referrer) return -1;
194
+ return 0;
195
+ };
196
+
197
+ // src/referrer-metrics.ts
198
+ var buildReferrerMetrics = (referrer, totalReferrals, totalIncrementalDuration, totalRevenueContribution) => {
199
+ const result = {
200
+ referrer: normalizeAddress(referrer),
201
+ totalReferrals,
202
+ totalIncrementalDuration,
203
+ totalRevenueContribution
204
+ };
205
+ validateReferrerMetrics(result);
206
+ return result;
207
+ };
208
+ var validateReferrerMetrics = (metrics) => {
209
+ validateLowercaseAddress(metrics.referrer);
210
+ validateNonNegativeInteger(metrics.totalReferrals);
211
+ validateDuration(metrics.totalIncrementalDuration);
212
+ validateRevenueContribution(metrics.totalRevenueContribution);
213
+ };
214
+ var sortReferrerMetrics = (referrers) => {
215
+ return [...referrers].sort(compareReferrerMetrics);
216
+ };
217
+ var buildScoredReferrerMetrics = (referrer) => {
218
+ const result = {
219
+ ...referrer,
220
+ score: calcReferrerScore(referrer.totalIncrementalDuration)
221
+ };
222
+ validateScoredReferrerMetrics(result);
223
+ return result;
224
+ };
225
+ var validateScoredReferrerMetrics = (metrics) => {
226
+ validateReferrerMetrics(metrics);
227
+ validateReferrerScore(metrics.score);
228
+ const expectedScore = calcReferrerScore(metrics.totalIncrementalDuration);
229
+ if (metrics.score !== expectedScore) {
230
+ throw new Error(`Referrer: Invalid score: ${metrics.score}, expected: ${expectedScore}.`);
231
+ }
232
+ };
233
+ var validateRankedReferrerMetrics = (metrics, rules) => {
234
+ validateScoredReferrerMetrics(metrics);
235
+ validateReferrerRank(metrics.rank);
236
+ if (metrics.finalScoreBoost < 0 || metrics.finalScoreBoost > 1) {
237
+ throw new Error(
238
+ `Invalid RankedReferrerMetrics: Invalid finalScoreBoost: ${metrics.finalScoreBoost}. finalScoreBoost must be between 0 and 1 (inclusive).`
239
+ );
240
+ }
241
+ validateReferrerScore(metrics.finalScore);
242
+ const expectedIsQualified = isReferrerQualified(metrics.rank, rules);
243
+ if (metrics.isQualified !== expectedIsQualified) {
244
+ throw new Error(
245
+ `RankedReferrerMetrics: Invalid isQualified: ${metrics.isQualified}, expected: ${expectedIsQualified}.`
246
+ );
247
+ }
248
+ const expectedFinalScoreBoost = calcReferrerFinalScoreBoost(metrics.rank, rules);
249
+ if (metrics.finalScoreBoost !== expectedFinalScoreBoost) {
250
+ throw new Error(
251
+ `RankedReferrerMetrics: Invalid finalScoreBoost: ${metrics.finalScoreBoost}, expected: ${expectedFinalScoreBoost}.`
252
+ );
253
+ }
254
+ const expectedFinalScore = calcReferrerFinalScore(
255
+ metrics.rank,
256
+ metrics.totalIncrementalDuration,
257
+ rules
258
+ );
259
+ if (metrics.finalScore !== expectedFinalScore) {
260
+ throw new Error(
261
+ `RankedReferrerMetrics: Invalid finalScore: ${metrics.finalScore}, expected: ${expectedFinalScore}.`
262
+ );
263
+ }
264
+ };
265
+ var buildRankedReferrerMetrics = (referrer, rank, rules) => {
266
+ const result = {
267
+ ...referrer,
268
+ rank,
269
+ isQualified: isReferrerQualified(rank, rules),
270
+ finalScoreBoost: calcReferrerFinalScoreBoost(rank, rules),
271
+ finalScore: calcReferrerFinalScore(rank, referrer.totalIncrementalDuration, rules)
272
+ };
273
+ validateRankedReferrerMetrics(result, rules);
274
+ return result;
275
+ };
276
+ var calcReferrerAwardPoolShare = (referrer, aggregatedMetrics, rules) => {
277
+ if (!isReferrerQualified(referrer.rank, rules)) return 0;
278
+ if (aggregatedMetrics.grandTotalQualifiedReferrersFinalScore === 0) return 0;
279
+ return calcReferrerFinalScore(referrer.rank, referrer.totalIncrementalDuration, rules) / aggregatedMetrics.grandTotalQualifiedReferrersFinalScore;
280
+ };
281
+ var validateAwardedReferrerMetrics = (referrer, rules) => {
282
+ validateRankedReferrerMetrics(referrer, rules);
283
+ if (referrer.awardPoolShare < 0 || referrer.awardPoolShare > 1) {
284
+ throw new Error(
285
+ `Invalid AwardedReferrerMetrics: ${referrer.awardPoolShare}. awardPoolShare must be between 0 and 1 (inclusive).`
286
+ );
287
+ }
288
+ if (referrer.awardPoolApproxValue < 0 || referrer.awardPoolApproxValue > rules.totalAwardPoolValue) {
289
+ throw new Error(
290
+ `Invalid AwardedReferrerMetrics: ${referrer.awardPoolApproxValue}. awardPoolApproxValue must be between 0 and ${rules.totalAwardPoolValue} (inclusive).`
291
+ );
292
+ }
293
+ };
294
+ var buildAwardedReferrerMetrics = (referrer, aggregatedMetrics, rules) => {
295
+ const awardPoolShare = calcReferrerAwardPoolShare(referrer, aggregatedMetrics, rules);
296
+ const result = {
297
+ ...referrer,
298
+ awardPoolShare,
299
+ awardPoolApproxValue: awardPoolShare * rules.totalAwardPoolValue
300
+ };
301
+ validateAwardedReferrerMetrics(result, rules);
302
+ return result;
303
+ };
304
+ var validateUnrankedReferrerMetrics = (metrics) => {
305
+ validateScoredReferrerMetrics(metrics);
306
+ if (metrics.rank !== null) {
307
+ throw new Error(`Invalid UnrankedReferrerMetrics: rank must be null, got: ${metrics.rank}.`);
308
+ }
309
+ if (metrics.isQualified !== false) {
310
+ throw new Error(
311
+ `Invalid UnrankedReferrerMetrics: isQualified must be false, got: ${metrics.isQualified}.`
312
+ );
313
+ }
314
+ if (metrics.totalReferrals !== 0) {
315
+ throw new Error(
316
+ `Invalid UnrankedReferrerMetrics: totalReferrals must be 0, got: ${metrics.totalReferrals}.`
317
+ );
318
+ }
319
+ if (metrics.totalIncrementalDuration !== 0) {
320
+ throw new Error(
321
+ `Invalid UnrankedReferrerMetrics: totalIncrementalDuration must be 0, got: ${metrics.totalIncrementalDuration}.`
322
+ );
323
+ }
324
+ if (metrics.totalRevenueContribution !== 0n) {
325
+ throw new Error(
326
+ `Invalid UnrankedReferrerMetrics: totalRevenueContribution must be 0n, got: ${metrics.totalRevenueContribution.toString()}.`
327
+ );
328
+ }
329
+ if (metrics.score !== 0) {
330
+ throw new Error(`Invalid UnrankedReferrerMetrics: score must be 0, got: ${metrics.score}.`);
331
+ }
332
+ if (metrics.finalScoreBoost !== 0) {
333
+ throw new Error(
334
+ `Invalid UnrankedReferrerMetrics: finalScoreBoost must be 0, got: ${metrics.finalScoreBoost}.`
335
+ );
336
+ }
337
+ if (metrics.finalScore !== 0) {
338
+ throw new Error(
339
+ `Invalid UnrankedReferrerMetrics: finalScore must be 0, got: ${metrics.finalScore}.`
340
+ );
341
+ }
342
+ if (metrics.awardPoolShare !== 0) {
343
+ throw new Error(
344
+ `Invalid UnrankedReferrerMetrics: awardPoolShare must be 0, got: ${metrics.awardPoolShare}.`
345
+ );
346
+ }
347
+ if (metrics.awardPoolApproxValue !== 0) {
348
+ throw new Error(
349
+ `Invalid UnrankedReferrerMetrics: awardPoolApproxValue must be 0, got: ${metrics.awardPoolApproxValue}.`
350
+ );
351
+ }
352
+ };
353
+ var buildUnrankedReferrerMetrics = (referrer) => {
354
+ const baseMetrics = buildReferrerMetrics(referrer, 0, 0, 0n);
355
+ const scoredMetrics = buildScoredReferrerMetrics(baseMetrics);
356
+ const result = {
357
+ ...scoredMetrics,
358
+ rank: null,
359
+ isQualified: false,
360
+ finalScoreBoost: 0,
361
+ finalScore: 0,
362
+ awardPoolShare: 0,
363
+ awardPoolApproxValue: 0
364
+ };
365
+ validateUnrankedReferrerMetrics(result);
366
+ return result;
367
+ };
368
+
369
+ // src/leaderboard.ts
370
+ var buildReferrerLeaderboard = (allReferrers, rules, accurateAsOf) => {
371
+ const uniqueReferrers = allReferrers.map((referrer) => referrer.referrer);
372
+ if (uniqueReferrers.length !== allReferrers.length) {
373
+ throw new Error(
374
+ "ReferrerLeaderboard: Cannot buildReferrerLeaderboard containing duplicate referrers"
375
+ );
376
+ }
377
+ if (accurateAsOf < rules.startTime && allReferrers.length > 0) {
378
+ throw new Error(
379
+ `ReferrerLeaderboard: accurateAsOf (${accurateAsOf}) is before startTime (${rules.startTime}) which indicates allReferrers should be empty, but allReferrers is not empty.`
380
+ );
381
+ }
382
+ const sortedReferrers = sortReferrerMetrics(allReferrers);
383
+ const scoredReferrers = sortedReferrers.map((referrer) => buildScoredReferrerMetrics(referrer));
384
+ const rankedReferrers = scoredReferrers.map((referrer, index) => {
385
+ return buildRankedReferrerMetrics(referrer, index + 1, rules);
386
+ });
387
+ const aggregatedMetrics = buildAggregatedReferrerMetrics(rankedReferrers, rules);
388
+ const awardedReferrers = rankedReferrers.map((referrer) => {
389
+ return buildAwardedReferrerMetrics(referrer, aggregatedMetrics, rules);
390
+ });
391
+ const referrers = new Map(
392
+ awardedReferrers.map((referrer) => {
393
+ return [referrer.referrer, referrer];
394
+ })
395
+ );
396
+ return {
397
+ rules,
398
+ aggregatedMetrics,
399
+ referrers,
400
+ accurateAsOf
401
+ };
402
+ };
403
+
404
+ // src/leaderboard-page.ts
405
+ var REFERRERS_PER_LEADERBOARD_PAGE_DEFAULT = 25;
406
+ var REFERRERS_PER_LEADERBOARD_PAGE_MAX = 100;
407
+ var validateReferrerLeaderboardPageParams = (params) => {
408
+ if (params.page !== void 0 && !isPositiveInteger(params.page)) {
409
+ throw new Error(
410
+ `Invalid ReferrerLeaderboardPageParams: ${params.page}. page must be a positive integer.`
411
+ );
412
+ }
413
+ if (params.recordsPerPage !== void 0 && !isPositiveInteger(params.recordsPerPage)) {
414
+ throw new Error(
415
+ `Invalid ReferrerLeaderboardPageParams: ${params.recordsPerPage}. recordsPerPage must be a positive integer.`
416
+ );
417
+ }
418
+ if (params.recordsPerPage !== void 0 && params.recordsPerPage > REFERRERS_PER_LEADERBOARD_PAGE_MAX) {
419
+ throw new Error(
420
+ `Invalid ReferrerLeaderboardPageParams: ${params.recordsPerPage}. recordsPerPage must be less than or equal to ${REFERRERS_PER_LEADERBOARD_PAGE_MAX}.`
421
+ );
422
+ }
423
+ };
424
+ var buildReferrerLeaderboardPageParams = (params) => {
425
+ const result = {
426
+ page: params.page ?? 1,
427
+ recordsPerPage: params.recordsPerPage ?? REFERRERS_PER_LEADERBOARD_PAGE_DEFAULT
428
+ };
429
+ validateReferrerLeaderboardPageParams(result);
430
+ return result;
431
+ };
432
+ var validateReferrerLeaderboardPageContext = (context) => {
433
+ validateReferrerLeaderboardPageParams(context);
434
+ if (!isNonNegativeInteger(context.totalRecords)) {
435
+ throw new Error(
436
+ `Invalid ReferrerLeaderboardPageContext: total must be a non-negative integer but is ${context.totalRecords}.`
437
+ );
438
+ }
439
+ const startIndex = (context.page - 1) * context.recordsPerPage;
440
+ const endIndex = startIndex + context.recordsPerPage;
441
+ if (!context.hasNext && endIndex < context.totalRecords) {
442
+ throw new Error(
443
+ `Invalid ReferrerLeaderboardPageContext: if hasNext is false, endIndex (${endIndex}) must be greater than or equal to total (${context.totalRecords}).`
444
+ );
445
+ } else if (context.hasNext && context.page * context.recordsPerPage >= context.totalRecords) {
446
+ throw new Error(
447
+ `Invalid ReferrerLeaderboardPageContext: if hasNext is true, endIndex (${endIndex}) must be less than total (${context.totalRecords}).`
448
+ );
449
+ }
450
+ if (!context.hasPrev && context.page !== 1) {
451
+ throw new Error(
452
+ `Invalid ReferrerLeaderboardPageContext: if hasPrev is false, page must be the first page (1) but is ${context.page}.`
453
+ );
454
+ } else if (context.hasPrev && context.page === 1) {
455
+ throw new Error(
456
+ `Invalid ReferrerLeaderboardPageContext: if hasPrev is true, page must not be the first page (1) but is ${context.page}.`
457
+ );
458
+ }
459
+ };
460
+ var buildReferrerLeaderboardPageContext = (optionalParams, leaderboard) => {
461
+ const materializedParams = buildReferrerLeaderboardPageParams(optionalParams);
462
+ const totalRecords = leaderboard.referrers.size;
463
+ const totalPages = Math.max(1, Math.ceil(totalRecords / materializedParams.recordsPerPage));
464
+ if (materializedParams.page > totalPages) {
465
+ throw new Error(
466
+ `Invalid ReferrerLeaderboardPageContext: page ${materializedParams.page} exceeds total pages ${totalPages}.`
467
+ );
468
+ }
469
+ if (totalRecords === 0) {
470
+ return {
471
+ ...materializedParams,
472
+ totalRecords: 0,
473
+ totalPages: 1,
474
+ hasNext: false,
475
+ hasPrev: false,
476
+ startIndex: void 0,
477
+ endIndex: void 0
478
+ };
479
+ }
480
+ const startIndex = (materializedParams.page - 1) * materializedParams.recordsPerPage;
481
+ const maxTheoreticalIndexOnPage = startIndex + (materializedParams.recordsPerPage - 1);
482
+ const endIndex = Math.min(maxTheoreticalIndexOnPage, totalRecords - 1);
483
+ const hasNext = maxTheoreticalIndexOnPage < totalRecords - 1;
484
+ const hasPrev = materializedParams.page > 1;
485
+ const result = {
486
+ ...materializedParams,
487
+ totalRecords,
488
+ totalPages,
489
+ hasNext,
490
+ hasPrev,
491
+ startIndex,
492
+ endIndex
493
+ };
494
+ validateReferrerLeaderboardPageContext(result);
495
+ return result;
496
+ };
497
+ var getReferrerLeaderboardPage = (pageParams, leaderboard) => {
498
+ const pageContext = buildReferrerLeaderboardPageContext(pageParams, leaderboard);
499
+ let referrers;
500
+ if (pageContext.totalRecords > 0 && typeof pageContext.startIndex !== "undefined" && typeof pageContext.endIndex !== "undefined") {
501
+ referrers = Array.from(leaderboard.referrers.values()).slice(
502
+ pageContext.startIndex,
503
+ pageContext.endIndex + 1
504
+ // For `slice`, this is exclusive of the element at the index 'end'. We need it to be inclusive, hence plus one.
505
+ );
506
+ } else {
507
+ referrers = [];
508
+ }
509
+ return {
510
+ rules: leaderboard.rules,
511
+ referrers,
512
+ aggregatedMetrics: leaderboard.aggregatedMetrics,
513
+ pageContext,
514
+ accurateAsOf: leaderboard.accurateAsOf
515
+ };
516
+ };
517
+
518
+ // src/link.ts
519
+ import { getAddress as getAddress2 } from "viem";
520
+ function buildEnsReferralUrl(address) {
521
+ const ensAppUrl = new URL("https://app.ens.domains");
522
+ ensAppUrl.searchParams.set("referrer", getAddress2(address));
523
+ return ensAppUrl;
524
+ }
525
+
526
+ // src/referrer-detail.ts
527
+ var ReferrerDetailTypeIds = {
528
+ /**
529
+ * Represents a referrer who is ranked on the leaderboard.
530
+ */
531
+ Ranked: "ranked",
532
+ /**
533
+ * Represents a referrer who is not ranked on the leaderboard.
534
+ */
535
+ Unranked: "unranked"
536
+ };
537
+ var getReferrerDetail = (referrer, leaderboard) => {
538
+ const awardedReferrerMetrics = leaderboard.referrers.get(referrer);
539
+ if (awardedReferrerMetrics) {
540
+ return {
541
+ type: ReferrerDetailTypeIds.Ranked,
542
+ rules: leaderboard.rules,
543
+ referrer: awardedReferrerMetrics,
544
+ aggregatedMetrics: leaderboard.aggregatedMetrics,
545
+ accurateAsOf: leaderboard.accurateAsOf
546
+ };
547
+ }
548
+ return {
549
+ type: ReferrerDetailTypeIds.Unranked,
550
+ rules: leaderboard.rules,
551
+ referrer: buildUnrankedReferrerMetrics(referrer),
552
+ aggregatedMetrics: leaderboard.aggregatedMetrics,
553
+ accurateAsOf: leaderboard.accurateAsOf
554
+ };
555
+ };
556
+
557
+ // src/rules.ts
558
+ var ENS_HOLIDAY_AWARDS_START_DATE = 1764547200;
559
+ var ENS_HOLIDAY_AWARDS_END_DATE = 1767225599;
560
+ var ENS_HOLIDAY_AWARDS_MAX_QUALIFIED_REFERRERS = 10;
561
+ var ENS_HOLIDAY_AWARDS_TOTAL_AWARD_POOL_VALUE = 1e4;
562
+ var validateReferralProgramRules = (rules) => {
563
+ validateUSDQuantity(rules.totalAwardPoolValue);
564
+ validateNonNegativeInteger(rules.maxQualifiedReferrers);
565
+ validateUnixTimestamp(rules.startTime);
566
+ validateUnixTimestamp(rules.endTime);
567
+ if (rules.endTime < rules.startTime) {
568
+ throw new Error(
569
+ `ReferralProgramRules: startTime: ${rules.startTime} is after endTime: ${rules.endTime}.`
570
+ );
571
+ }
572
+ };
573
+ var buildReferralProgramRules = (totalAwardPoolValue, maxQualifiedReferrers, startTime, endTime, subregistryId) => {
574
+ const result = {
575
+ totalAwardPoolValue,
576
+ maxQualifiedReferrers,
577
+ startTime,
578
+ endTime,
579
+ subregistryId
580
+ };
581
+ validateReferralProgramRules(result);
582
+ return result;
583
+ };
584
+ export {
585
+ ENCODED_REFERRER_BYTE_LENGTH,
586
+ ENCODED_REFERRER_BYTE_OFFSET,
587
+ ENS_HOLIDAY_AWARDS_END_DATE,
588
+ ENS_HOLIDAY_AWARDS_MAX_QUALIFIED_REFERRERS,
589
+ ENS_HOLIDAY_AWARDS_START_DATE,
590
+ ENS_HOLIDAY_AWARDS_TOTAL_AWARD_POOL_VALUE,
591
+ EXPECTED_ENCODED_REFERRER_PADDING,
592
+ REFERRERS_PER_LEADERBOARD_PAGE_DEFAULT,
593
+ REFERRERS_PER_LEADERBOARD_PAGE_MAX,
594
+ ReferrerDetailTypeIds,
595
+ SECONDS_PER_YEAR,
596
+ ZERO_ENCODED_REFERRER,
597
+ buildAggregatedReferrerMetrics,
598
+ buildAwardedReferrerMetrics,
599
+ buildEncodedReferrer,
600
+ buildEnsReferralUrl,
601
+ buildRankedReferrerMetrics,
602
+ buildReferralProgramRules,
603
+ buildReferrerLeaderboard,
604
+ buildReferrerLeaderboardPageContext,
605
+ buildReferrerLeaderboardPageParams,
606
+ buildReferrerMetrics,
607
+ buildScoredReferrerMetrics,
608
+ buildUnrankedReferrerMetrics,
609
+ calcReferrerAwardPoolShare,
610
+ calcReferrerFinalScore,
611
+ calcReferrerFinalScoreBoost,
612
+ calcReferrerFinalScoreMultiplier,
613
+ calcReferrerScore,
614
+ compareReferrerMetrics,
615
+ decodeEncodedReferrer,
616
+ getReferrerDetail,
617
+ getReferrerLeaderboardPage,
618
+ isFiniteNonNegativeNumber,
619
+ isInteger,
620
+ isNonNegativeInteger,
621
+ isPositiveInteger,
622
+ isReferrerQualified,
623
+ isValidDuration,
624
+ isValidReferrerScore,
625
+ isValidRevenueContribution,
626
+ isValidUSDQuantity,
627
+ normalizeAddress,
628
+ sortReferrerMetrics,
629
+ validateAggregatedReferrerMetrics,
630
+ validateAwardedReferrerMetrics,
631
+ validateDuration,
632
+ validateLowercaseAddress,
633
+ validateNonNegativeInteger,
634
+ validateRankedReferrerMetrics,
635
+ validateReferralProgramRules,
636
+ validateReferrerLeaderboardPageContext,
637
+ validateReferrerMetrics,
638
+ validateReferrerRank,
639
+ validateReferrerScore,
640
+ validateRevenueContribution,
641
+ validateScoredReferrerMetrics,
642
+ validateUSDQuantity,
643
+ validateUnixTimestamp,
644
+ validateUnrankedReferrerMetrics
645
+ };
646
+ //# sourceMappingURL=index.js.map