@namehash/ens-referrals 1.8.1 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +151 -14
- package/dist/index.cjs +2360 -828
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1525 -426
- package/dist/index.d.ts +1525 -426
- package/dist/index.js +2347 -825
- package/dist/index.js.map +1 -1
- package/package.json +4 -13
- package/dist/v1/index.cjs +0 -20902
- package/dist/v1/index.cjs.map +0 -1
- package/dist/v1/index.d.cts +0 -2098
- package/dist/v1/index.d.ts +0 -2098
- package/dist/v1/index.js +0 -20879
- package/dist/v1/index.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,132 +1,16 @@
|
|
|
1
1
|
// src/address.ts
|
|
2
|
-
import {
|
|
3
|
-
var
|
|
4
|
-
if (!
|
|
5
|
-
throw new Error(`Invalid address: ${address}. Address must be a
|
|
2
|
+
import { isNormalizedAddress } from "enssdk";
|
|
3
|
+
var validateNormalizedAddress = (address) => {
|
|
4
|
+
if (!isNormalizedAddress(address)) {
|
|
5
|
+
throw new Error(`Invalid address: '${address}'. Address must be a lowercase EVM Address.`);
|
|
6
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
7
|
};
|
|
124
8
|
|
|
125
9
|
// src/api/deserialize.ts
|
|
126
10
|
import { prettifyError } from "zod/v4";
|
|
127
11
|
|
|
128
12
|
// src/api/zod-schemas.ts
|
|
129
|
-
import
|
|
13
|
+
import z5 from "zod/v4";
|
|
130
14
|
|
|
131
15
|
// ../../node_modules/.pnpm/caip@1.1.1/node_modules/caip/dist/index.mjs
|
|
132
16
|
function _extends() {
|
|
@@ -428,12 +312,84 @@ var AssetId = /* @__PURE__ */ (function() {
|
|
|
428
312
|
AssetId.spec = CAIP["19"].assetId;
|
|
429
313
|
|
|
430
314
|
// ../ensnode-sdk/src/shared/zod-schemas.ts
|
|
431
|
-
import {
|
|
315
|
+
import { reinterpretName, toNormalizedAddress } from "enssdk";
|
|
316
|
+
import { isAddress, isHex, size } from "viem";
|
|
432
317
|
import { z } from "zod/v4";
|
|
433
318
|
|
|
434
|
-
// ../ensnode-sdk/src/shared/
|
|
435
|
-
|
|
436
|
-
|
|
319
|
+
// ../ensnode-sdk/src/shared/currencies.ts
|
|
320
|
+
import { parseUnits } from "viem";
|
|
321
|
+
|
|
322
|
+
// ../ensnode-sdk/src/shared/numbers.ts
|
|
323
|
+
function scaleBigintByNumber(value, scaleFactor) {
|
|
324
|
+
if (value < 0n) {
|
|
325
|
+
throw new Error(`scaleBigintByNumber: value must be non-negative, got: ${value.toString()}`);
|
|
326
|
+
}
|
|
327
|
+
if (!Number.isFinite(scaleFactor)) {
|
|
328
|
+
throw new Error(
|
|
329
|
+
`scaleBigintByNumber: scaleFactor must be a finite number, got: ${scaleFactor}`
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
if (scaleFactor < 0) {
|
|
333
|
+
throw new Error(`scaleBigintByNumber: scaleFactor must be non-negative, got: ${scaleFactor}`);
|
|
334
|
+
}
|
|
335
|
+
if (scaleFactor >= 1e21) {
|
|
336
|
+
throw new Error(`scaleBigintByNumber: scaleFactor must be less than 1e21, got: ${scaleFactor}`);
|
|
337
|
+
}
|
|
338
|
+
if (value === 0n || scaleFactor === 0) {
|
|
339
|
+
return 0n;
|
|
340
|
+
}
|
|
341
|
+
if (scaleFactor === 1) {
|
|
342
|
+
return value;
|
|
343
|
+
}
|
|
344
|
+
const fixedStr = scaleFactor.toFixed(20);
|
|
345
|
+
const [integerPart, decimalPart = ""] = fixedStr.split(".");
|
|
346
|
+
const trimmedDecimal = decimalPart.replace(/0+$/, "") || "0";
|
|
347
|
+
const numerator = BigInt(integerPart + trimmedDecimal);
|
|
348
|
+
const denominator = 10n ** BigInt(trimmedDecimal.length);
|
|
349
|
+
return value * numerator / denominator;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// ../ensnode-sdk/src/shared/currencies.ts
|
|
353
|
+
var CurrencyIds = {
|
|
354
|
+
ETH: "ETH",
|
|
355
|
+
USDC: "USDC",
|
|
356
|
+
DAI: "DAI"
|
|
357
|
+
};
|
|
358
|
+
var currencyInfo = {
|
|
359
|
+
[CurrencyIds.ETH]: {
|
|
360
|
+
id: CurrencyIds.ETH,
|
|
361
|
+
name: "ETH",
|
|
362
|
+
decimals: 18
|
|
363
|
+
},
|
|
364
|
+
[CurrencyIds.USDC]: {
|
|
365
|
+
id: CurrencyIds.USDC,
|
|
366
|
+
name: "USDC",
|
|
367
|
+
decimals: 6
|
|
368
|
+
},
|
|
369
|
+
[CurrencyIds.DAI]: {
|
|
370
|
+
id: CurrencyIds.DAI,
|
|
371
|
+
name: "Dai Stablecoin",
|
|
372
|
+
decimals: 18
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
function priceEth(amount) {
|
|
376
|
+
return {
|
|
377
|
+
amount,
|
|
378
|
+
currency: CurrencyIds.ETH
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
function priceUsdc(amount) {
|
|
382
|
+
return {
|
|
383
|
+
amount,
|
|
384
|
+
currency: CurrencyIds.USDC
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
function scalePrice(price, scaleFactor) {
|
|
388
|
+
const scaledAmount = scaleBigintByNumber(price.amount, scaleFactor);
|
|
389
|
+
return {
|
|
390
|
+
...price,
|
|
391
|
+
amount: scaledAmount
|
|
392
|
+
};
|
|
437
393
|
}
|
|
438
394
|
|
|
439
395
|
// ../ensnode-sdk/src/shared/zod-schemas.ts
|
|
@@ -457,22 +413,78 @@ var makeDurationSchema = (valueLabel = "Value") => z.number({
|
|
|
457
413
|
error: `${valueLabel} must be a number.`
|
|
458
414
|
}).pipe(makeNonNegativeIntegerSchema(valueLabel));
|
|
459
415
|
var makeChainIdSchema = (valueLabel = "Chain ID") => makePositiveIntegerSchema(valueLabel).transform((val) => val);
|
|
460
|
-
var
|
|
461
|
-
if (!
|
|
416
|
+
var makeNormalizedAddressSchema = (valueLabel = "EVM address") => z.string().check((ctx) => {
|
|
417
|
+
if (!isAddress(ctx.value, { strict: false })) {
|
|
462
418
|
ctx.issues.push({
|
|
463
419
|
code: "custom",
|
|
464
420
|
message: `${valueLabel} must be a valid EVM address`,
|
|
465
421
|
input: ctx.value
|
|
466
422
|
});
|
|
467
423
|
}
|
|
468
|
-
}).transform((val) =>
|
|
424
|
+
}).transform((val) => toNormalizedAddress(val));
|
|
469
425
|
var makeUnixTimestampSchema = (valueLabel = "Timestamp") => makeIntegerSchema(valueLabel);
|
|
426
|
+
var makeUrlSchema = (valueLabel = "Value") => z.url({
|
|
427
|
+
error: `${valueLabel} must be a valid URL string (e.g., http://localhost:8080 or https://example.com).`,
|
|
428
|
+
abort: true
|
|
429
|
+
}).transform((v) => new URL(v));
|
|
430
|
+
var makePriceAmountSchema = (valueLabel = "Amount") => z.coerce.bigint({
|
|
431
|
+
error: `${valueLabel} must represent a bigint.`
|
|
432
|
+
}).nonnegative({
|
|
433
|
+
error: `${valueLabel} must not be negative.`
|
|
434
|
+
});
|
|
435
|
+
var makePriceCurrencySchema = (currency, valueLabel = "Price Currency") => z.strictObject({
|
|
436
|
+
amount: makePriceAmountSchema(`${valueLabel} amount`),
|
|
437
|
+
currency: z.literal(currency, {
|
|
438
|
+
error: `${valueLabel} currency must be set to '${currency}'.`
|
|
439
|
+
})
|
|
440
|
+
});
|
|
441
|
+
var makePriceEthSchema = (valueLabel = "Price ETH") => makePriceCurrencySchema(CurrencyIds.ETH, valueLabel).transform((v) => v);
|
|
442
|
+
var makePriceUsdcSchema = (valueLabel = "Price USDC") => makePriceCurrencySchema(CurrencyIds.USDC, valueLabel).transform((v) => v);
|
|
470
443
|
var makeAccountIdSchema = (valueLabel = "AccountId") => z.strictObject({
|
|
471
444
|
chainId: makeChainIdSchema(`${valueLabel} chain ID`),
|
|
472
|
-
address:
|
|
445
|
+
address: makeNormalizedAddressSchema(`${valueLabel} address`)
|
|
473
446
|
});
|
|
474
447
|
|
|
475
|
-
// src/
|
|
448
|
+
// ../ensnode-sdk/src/shared/serialize.ts
|
|
449
|
+
function serializePrice(price) {
|
|
450
|
+
return {
|
|
451
|
+
currency: price.currency,
|
|
452
|
+
amount: price.amount.toString()
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
function serializePriceEth(price) {
|
|
456
|
+
return serializePrice(price);
|
|
457
|
+
}
|
|
458
|
+
function serializePriceUsdc(price) {
|
|
459
|
+
return serializePrice(price);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// src/award-models/pie-split/api/zod-schemas.ts
|
|
463
|
+
import z3 from "zod/v4";
|
|
464
|
+
|
|
465
|
+
// src/award-models/shared/api/zod-schemas.ts
|
|
466
|
+
import z2 from "zod/v4";
|
|
467
|
+
|
|
468
|
+
// src/number.ts
|
|
469
|
+
var isInteger = (value) => {
|
|
470
|
+
return Number.isInteger(value);
|
|
471
|
+
};
|
|
472
|
+
var isNonNegativeInteger = (value) => {
|
|
473
|
+
return value >= 0 && Number.isInteger(value);
|
|
474
|
+
};
|
|
475
|
+
var isPositiveInteger = (value) => {
|
|
476
|
+
return value >= 1 && Number.isInteger(value);
|
|
477
|
+
};
|
|
478
|
+
var validateNonNegativeInteger = (value) => {
|
|
479
|
+
if (!isNonNegativeInteger(value)) {
|
|
480
|
+
throw new Error(`Invalid non-negative integer: ${value}.`);
|
|
481
|
+
}
|
|
482
|
+
};
|
|
483
|
+
var isFiniteNonNegativeNumber = (value) => {
|
|
484
|
+
return value >= 0 && Number.isFinite(value);
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
// src/award-models/shared/leaderboard-page.ts
|
|
476
488
|
var REFERRERS_PER_LEADERBOARD_PAGE_DEFAULT = 25;
|
|
477
489
|
var REFERRERS_PER_LEADERBOARD_PAGE_MAX = 100;
|
|
478
490
|
var validateReferrerLeaderboardPageParams = (params) => {
|
|
@@ -504,18 +516,67 @@ var validateReferrerLeaderboardPageContext = (context) => {
|
|
|
504
516
|
validateReferrerLeaderboardPageParams(context);
|
|
505
517
|
if (!isNonNegativeInteger(context.totalRecords)) {
|
|
506
518
|
throw new Error(
|
|
507
|
-
`Invalid ReferrerLeaderboardPageContext:
|
|
519
|
+
`Invalid ReferrerLeaderboardPageContext: totalRecords must be a non-negative integer but is ${context.totalRecords}.`
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
if (!isPositiveInteger(context.totalPages)) {
|
|
523
|
+
throw new Error(
|
|
524
|
+
`Invalid ReferrerLeaderboardPageContext: totalPages must be a positive integer (>= 1) but is ${context.totalPages}.`
|
|
525
|
+
);
|
|
526
|
+
}
|
|
527
|
+
const expectedTotalPages = context.totalRecords === 0 ? 1 : Math.ceil(context.totalRecords / context.recordsPerPage);
|
|
528
|
+
if (context.totalPages !== expectedTotalPages) {
|
|
529
|
+
throw new Error(
|
|
530
|
+
`Invalid ReferrerLeaderboardPageContext: totalPages is ${context.totalPages} but expected ${expectedTotalPages} based on totalRecords (${context.totalRecords}) and recordsPerPage (${context.recordsPerPage}).`
|
|
508
531
|
);
|
|
509
532
|
}
|
|
533
|
+
if (context.page > context.totalPages) {
|
|
534
|
+
throw new Error(
|
|
535
|
+
`Invalid ReferrerLeaderboardPageContext: page ${context.page} exceeds totalPages ${context.totalPages}.`
|
|
536
|
+
);
|
|
537
|
+
}
|
|
538
|
+
const expectedStartIndex = (context.page - 1) * context.recordsPerPage;
|
|
539
|
+
const expectedEndIndex = Math.min(
|
|
540
|
+
expectedStartIndex + context.recordsPerPage - 1,
|
|
541
|
+
context.totalRecords - 1
|
|
542
|
+
);
|
|
543
|
+
if (context.totalRecords === 0) {
|
|
544
|
+
if (context.startIndex !== void 0) {
|
|
545
|
+
throw new Error(
|
|
546
|
+
`Invalid ReferrerLeaderboardPageContext: startIndex must be undefined when totalRecords is 0 but is ${context.startIndex}.`
|
|
547
|
+
);
|
|
548
|
+
}
|
|
549
|
+
if (context.endIndex !== void 0) {
|
|
550
|
+
throw new Error(
|
|
551
|
+
`Invalid ReferrerLeaderboardPageContext: endIndex must be undefined when totalRecords is 0 but is ${context.endIndex}.`
|
|
552
|
+
);
|
|
553
|
+
}
|
|
554
|
+
} else {
|
|
555
|
+
if (context.startIndex !== expectedStartIndex) {
|
|
556
|
+
throw new Error(
|
|
557
|
+
`Invalid ReferrerLeaderboardPageContext: startIndex is ${context.startIndex} but expected ${expectedStartIndex} based on page (${context.page}) and recordsPerPage (${context.recordsPerPage}).`
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
if (context.endIndex !== expectedEndIndex) {
|
|
561
|
+
throw new Error(
|
|
562
|
+
`Invalid ReferrerLeaderboardPageContext: endIndex is ${context.endIndex} but expected ${expectedEndIndex} based on startIndex (${expectedStartIndex}), recordsPerPage (${context.recordsPerPage}), and totalRecords (${context.totalRecords}).`
|
|
563
|
+
);
|
|
564
|
+
}
|
|
565
|
+
if (typeof context.endIndex !== "undefined" && typeof context.startIndex !== "undefined" && context.endIndex < context.startIndex) {
|
|
566
|
+
throw new Error(
|
|
567
|
+
`Invalid ReferrerLeaderboardPageContext: endIndex (${context.endIndex}) must be greater than or equal to startIndex (${context.startIndex}).`
|
|
568
|
+
);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
510
571
|
const startIndex = (context.page - 1) * context.recordsPerPage;
|
|
511
572
|
const endIndex = startIndex + context.recordsPerPage;
|
|
512
573
|
if (!context.hasNext && endIndex < context.totalRecords) {
|
|
513
574
|
throw new Error(
|
|
514
|
-
`Invalid ReferrerLeaderboardPageContext: if hasNext is false, endIndex (${endIndex}) must be greater than or equal to
|
|
575
|
+
`Invalid ReferrerLeaderboardPageContext: if hasNext is false, endIndex (${endIndex}) must be greater than or equal to totalRecords (${context.totalRecords}).`
|
|
515
576
|
);
|
|
516
577
|
} else if (context.hasNext && context.page * context.recordsPerPage >= context.totalRecords) {
|
|
517
578
|
throw new Error(
|
|
518
|
-
`Invalid ReferrerLeaderboardPageContext: if hasNext is true, endIndex (${endIndex}) must be less than
|
|
579
|
+
`Invalid ReferrerLeaderboardPageContext: if hasNext is true, endIndex (${endIndex}) must be less than totalRecords (${context.totalRecords}).`
|
|
519
580
|
);
|
|
520
581
|
}
|
|
521
582
|
if (!context.hasPrev && context.page !== 1) {
|
|
@@ -565,60 +626,1369 @@ var buildReferrerLeaderboardPageContext = (optionalParams, leaderboard) => {
|
|
|
565
626
|
validateReferrerLeaderboardPageContext(result);
|
|
566
627
|
return result;
|
|
567
628
|
};
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
if (pageContext.totalRecords > 0 && typeof pageContext.startIndex !== "undefined" && typeof pageContext.endIndex !== "undefined") {
|
|
572
|
-
referrers = Array.from(leaderboard.referrers.values()).slice(
|
|
573
|
-
pageContext.startIndex,
|
|
574
|
-
pageContext.endIndex + 1
|
|
575
|
-
// For `slice`, this is exclusive of the element at the index 'end'. We need it to be inclusive, hence plus one.
|
|
576
|
-
);
|
|
577
|
-
} else {
|
|
578
|
-
referrers = [];
|
|
629
|
+
function sliceReferrers(referrers, pageContext) {
|
|
630
|
+
if (pageContext.totalRecords === 0 || pageContext.startIndex === void 0 || pageContext.endIndex === void 0) {
|
|
631
|
+
return [];
|
|
579
632
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
633
|
+
const all = [...referrers.values()];
|
|
634
|
+
return all.slice(pageContext.startIndex, pageContext.endIndex + 1);
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
// src/award-models/shared/status.ts
|
|
638
|
+
var ReferralProgramEditionStatuses = {
|
|
639
|
+
/**
|
|
640
|
+
* Represents a referral program edition that has been announced, but hasn't started yet.
|
|
641
|
+
*/
|
|
642
|
+
Scheduled: "Scheduled",
|
|
643
|
+
/**
|
|
644
|
+
* Represents a currently ongoing referral program edition.
|
|
645
|
+
*/
|
|
646
|
+
Active: "Active",
|
|
647
|
+
/**
|
|
648
|
+
* Represents a referral program edition that is still within its active window
|
|
649
|
+
* but whose award pool has been fully consumed.
|
|
650
|
+
*
|
|
651
|
+
* @note Not all award models may support this status.
|
|
652
|
+
*/
|
|
653
|
+
Exhausted: "Exhausted",
|
|
654
|
+
/**
|
|
655
|
+
* Represents a referral program edition that has passed its end time but whose awards have not yet
|
|
656
|
+
* been distributed. The edition is in a review window before full closure.
|
|
657
|
+
*
|
|
658
|
+
* Transitions to {@link ReferralProgramEditionStatuses.Closed} once `areAwardsDistributed` is set to `true`.
|
|
659
|
+
*/
|
|
660
|
+
AwardsReview: "AwardsReview",
|
|
661
|
+
/**
|
|
662
|
+
* Represents a referral program edition that has already ended and whose awards have been distributed.
|
|
663
|
+
*/
|
|
664
|
+
Closed: "Closed"
|
|
665
|
+
};
|
|
666
|
+
var calcBaseReferralProgramEditionStatus = (rules, now) => {
|
|
667
|
+
if (now < rules.startTime) return ReferralProgramEditionStatuses.Scheduled;
|
|
668
|
+
if (now > rules.endTime)
|
|
669
|
+
return rules.areAwardsDistributed ? ReferralProgramEditionStatuses.Closed : ReferralProgramEditionStatuses.AwardsReview;
|
|
670
|
+
return ReferralProgramEditionStatuses.Active;
|
|
587
671
|
};
|
|
588
672
|
|
|
589
|
-
// src/
|
|
590
|
-
var
|
|
591
|
-
|
|
592
|
-
|
|
673
|
+
// src/award-models/shared/api/zod-schemas.ts
|
|
674
|
+
var makeBaseReferralProgramRulesSchema = (valueLabel) => z2.object({
|
|
675
|
+
awardModel: z2.string(),
|
|
676
|
+
startTime: makeUnixTimestampSchema(`${valueLabel}.startTime`),
|
|
677
|
+
endTime: makeUnixTimestampSchema(`${valueLabel}.endTime`),
|
|
678
|
+
subregistryId: makeAccountIdSchema(`${valueLabel}.subregistryId`),
|
|
679
|
+
rulesUrl: makeUrlSchema(`${valueLabel}.rulesUrl`),
|
|
680
|
+
areAwardsDistributed: z2.boolean()
|
|
681
|
+
}).refine((data) => data.endTime >= data.startTime, {
|
|
682
|
+
message: `${valueLabel}.endTime must be >= ${valueLabel}.startTime`,
|
|
683
|
+
path: ["endTime"]
|
|
684
|
+
});
|
|
685
|
+
var makeReferrerLeaderboardPageContextSchema = (valueLabel = "ReferrerLeaderboardPageContext") => z2.object({
|
|
686
|
+
page: makePositiveIntegerSchema(`${valueLabel}.page`),
|
|
687
|
+
recordsPerPage: makePositiveIntegerSchema(`${valueLabel}.recordsPerPage`).max(
|
|
688
|
+
REFERRERS_PER_LEADERBOARD_PAGE_MAX,
|
|
689
|
+
`${valueLabel}.recordsPerPage must not exceed ${REFERRERS_PER_LEADERBOARD_PAGE_MAX}`
|
|
690
|
+
),
|
|
691
|
+
totalRecords: makeNonNegativeIntegerSchema(`${valueLabel}.totalRecords`),
|
|
692
|
+
totalPages: makePositiveIntegerSchema(`${valueLabel}.totalPages`),
|
|
693
|
+
hasNext: z2.boolean(),
|
|
694
|
+
hasPrev: z2.boolean(),
|
|
695
|
+
startIndex: z2.optional(makeNonNegativeIntegerSchema(`${valueLabel}.startIndex`)),
|
|
696
|
+
endIndex: z2.optional(makeNonNegativeIntegerSchema(`${valueLabel}.endIndex`))
|
|
697
|
+
});
|
|
698
|
+
var makeReferralProgramStatusSchema = (_valueLabel = "status") => z2.enum(ReferralProgramEditionStatuses);
|
|
699
|
+
var makeBaseReferralProgramEditionSummarySchema = (valueLabel) => z2.object({
|
|
700
|
+
awardModel: z2.string(),
|
|
701
|
+
slug: z2.string().min(1, `${valueLabel}.slug must not be empty`),
|
|
702
|
+
displayName: z2.string().min(1, `${valueLabel}.displayName must not be empty`),
|
|
703
|
+
status: makeReferralProgramStatusSchema(`${valueLabel}.status`),
|
|
704
|
+
rules: makeBaseReferralProgramRulesSchema(`${valueLabel}.rules`)
|
|
705
|
+
});
|
|
706
|
+
var makeBaseReferrerLeaderboardPageSchema = (valueLabel) => z2.object({
|
|
707
|
+
awardModel: z2.string(),
|
|
708
|
+
pageContext: makeReferrerLeaderboardPageContextSchema(`${valueLabel}.pageContext`),
|
|
709
|
+
status: makeReferralProgramStatusSchema(`${valueLabel}.status`),
|
|
710
|
+
accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
|
|
711
|
+
});
|
|
712
|
+
|
|
713
|
+
// src/award-models/shared/edition-metrics.ts
|
|
714
|
+
var ReferrerEditionMetricsTypeIds = {
|
|
715
|
+
/**
|
|
716
|
+
* Represents a referrer who is ranked on the leaderboard.
|
|
717
|
+
*/
|
|
718
|
+
Ranked: "ranked",
|
|
719
|
+
/**
|
|
720
|
+
* Represents a referrer who is not ranked on the leaderboard.
|
|
721
|
+
*/
|
|
722
|
+
Unranked: "unranked"
|
|
723
|
+
};
|
|
724
|
+
|
|
725
|
+
// src/time.ts
|
|
726
|
+
var validateUnixTimestamp = (timestamp) => {
|
|
727
|
+
if (!isInteger(timestamp)) {
|
|
728
|
+
throw new Error(`Invalid Unix timestamp: ${timestamp}. Unix timestamp must be an integer.`);
|
|
593
729
|
}
|
|
594
730
|
};
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
function calcReferrerFinalScoreBoost(rank, rules) {
|
|
599
|
-
if (!isReferrerQualified(rank, rules)) return 0;
|
|
600
|
-
return 1 - (rank - 1) / (rules.maxQualifiedReferrers - 1);
|
|
601
|
-
}
|
|
602
|
-
function calcReferrerFinalScoreMultiplier(rank, rules) {
|
|
603
|
-
return 1 + calcReferrerFinalScoreBoost(rank, rules);
|
|
604
|
-
}
|
|
605
|
-
function calcReferrerFinalScore(rank, totalIncrementalDuration, rules) {
|
|
606
|
-
return calcReferrerScore(totalIncrementalDuration) * calcReferrerFinalScoreMultiplier(rank, rules);
|
|
731
|
+
var SECONDS_PER_YEAR = 31556952;
|
|
732
|
+
function isValidDuration(duration) {
|
|
733
|
+
return isNonNegativeInteger(duration);
|
|
607
734
|
}
|
|
608
|
-
|
|
609
|
-
if (
|
|
610
|
-
|
|
735
|
+
function validateDuration(duration) {
|
|
736
|
+
if (!isValidDuration(duration)) {
|
|
737
|
+
throw new Error(`Invalid duration: ${duration}. Duration must be a non-negative integer.`);
|
|
611
738
|
}
|
|
612
|
-
|
|
613
|
-
if (b.referrer < a.referrer) return -1;
|
|
614
|
-
return 0;
|
|
615
|
-
};
|
|
739
|
+
}
|
|
616
740
|
|
|
617
|
-
// src/
|
|
618
|
-
var
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
741
|
+
// src/award-models/shared/rules.ts
|
|
742
|
+
var ReferralProgramAwardModels = {
|
|
743
|
+
PieSplit: "pie-split",
|
|
744
|
+
RevShareCap: "rev-share-cap",
|
|
745
|
+
Unrecognized: "unrecognized"
|
|
746
|
+
};
|
|
747
|
+
var validateBaseReferralProgramRules = (rules) => {
|
|
748
|
+
makeAccountIdSchema("BaseReferralProgramRules.subregistryId").parse(rules.subregistryId);
|
|
749
|
+
validateUnixTimestamp(rules.startTime);
|
|
750
|
+
validateUnixTimestamp(rules.endTime);
|
|
751
|
+
if (!(rules.rulesUrl instanceof URL)) {
|
|
752
|
+
throw new Error(
|
|
753
|
+
`BaseReferralProgramRules: rulesUrl must be a URL instance, got ${typeof rules.rulesUrl}.`
|
|
754
|
+
);
|
|
755
|
+
}
|
|
756
|
+
if (rules.endTime < rules.startTime) {
|
|
757
|
+
throw new Error(
|
|
758
|
+
`BaseReferralProgramRules: startTime: ${rules.startTime} is after endTime: ${rules.endTime}.`
|
|
759
|
+
);
|
|
760
|
+
}
|
|
761
|
+
};
|
|
762
|
+
|
|
763
|
+
// src/award-models/pie-split/api/zod-schemas.ts
|
|
764
|
+
var makeReferralProgramRulesPieSplitSchema = (valueLabel = "ReferralProgramRulesPieSplit") => makeBaseReferralProgramRulesSchema(valueLabel).safeExtend({
|
|
765
|
+
awardModel: z3.literal(ReferralProgramAwardModels.PieSplit),
|
|
766
|
+
awardPool: makePriceUsdcSchema(`${valueLabel}.awardPool`),
|
|
767
|
+
maxQualifiedReferrers: makeNonNegativeIntegerSchema(`${valueLabel}.maxQualifiedReferrers`)
|
|
768
|
+
});
|
|
769
|
+
var makeAwardedReferrerMetricsPieSplitSchema = (valueLabel = "AwardedReferrerMetricsPieSplit") => z3.object({
|
|
770
|
+
referrer: makeNormalizedAddressSchema(`${valueLabel}.referrer`),
|
|
771
|
+
totalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.totalReferrals`),
|
|
772
|
+
totalIncrementalDuration: makeDurationSchema(`${valueLabel}.totalIncrementalDuration`),
|
|
773
|
+
totalRevenueContribution: makePriceEthSchema(`${valueLabel}.totalRevenueContribution`),
|
|
774
|
+
score: makeFiniteNonNegativeNumberSchema(`${valueLabel}.score`),
|
|
775
|
+
rank: makePositiveIntegerSchema(`${valueLabel}.rank`),
|
|
776
|
+
isQualified: z3.boolean(),
|
|
777
|
+
finalScoreBoost: makeFiniteNonNegativeNumberSchema(`${valueLabel}.finalScoreBoost`).max(
|
|
778
|
+
1,
|
|
779
|
+
`${valueLabel}.finalScoreBoost must be <= 1`
|
|
780
|
+
),
|
|
781
|
+
finalScore: makeFiniteNonNegativeNumberSchema(`${valueLabel}.finalScore`),
|
|
782
|
+
awardPoolShare: makeFiniteNonNegativeNumberSchema(`${valueLabel}.awardPoolShare`).max(
|
|
783
|
+
1,
|
|
784
|
+
`${valueLabel}.awardPoolShare must be <= 1`
|
|
785
|
+
),
|
|
786
|
+
awardPoolApproxValue: makePriceUsdcSchema(`${valueLabel}.awardPoolApproxValue`)
|
|
787
|
+
});
|
|
788
|
+
var makeUnrankedReferrerMetricsPieSplitSchema = (valueLabel = "UnrankedReferrerMetricsPieSplit") => z3.object({
|
|
789
|
+
referrer: makeNormalizedAddressSchema(`${valueLabel}.referrer`),
|
|
790
|
+
totalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.totalReferrals`),
|
|
791
|
+
totalIncrementalDuration: makeDurationSchema(`${valueLabel}.totalIncrementalDuration`),
|
|
792
|
+
totalRevenueContribution: makePriceEthSchema(`${valueLabel}.totalRevenueContribution`),
|
|
793
|
+
score: makeFiniteNonNegativeNumberSchema(`${valueLabel}.score`),
|
|
794
|
+
rank: z3.null(),
|
|
795
|
+
isQualified: z3.literal(false),
|
|
796
|
+
finalScoreBoost: makeFiniteNonNegativeNumberSchema(`${valueLabel}.finalScoreBoost`).max(
|
|
797
|
+
1,
|
|
798
|
+
`${valueLabel}.finalScoreBoost must be <= 1`
|
|
799
|
+
),
|
|
800
|
+
finalScore: makeFiniteNonNegativeNumberSchema(`${valueLabel}.finalScore`),
|
|
801
|
+
awardPoolShare: makeFiniteNonNegativeNumberSchema(`${valueLabel}.awardPoolShare`).max(
|
|
802
|
+
1,
|
|
803
|
+
`${valueLabel}.awardPoolShare must be <= 1`
|
|
804
|
+
),
|
|
805
|
+
awardPoolApproxValue: makePriceUsdcSchema(`${valueLabel}.awardPoolApproxValue`)
|
|
806
|
+
});
|
|
807
|
+
var makeAggregatedReferrerMetricsPieSplitSchema = (valueLabel = "AggregatedReferrerMetricsPieSplit") => z3.object({
|
|
808
|
+
grandTotalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.grandTotalReferrals`),
|
|
809
|
+
grandTotalIncrementalDuration: makeDurationSchema(
|
|
810
|
+
`${valueLabel}.grandTotalIncrementalDuration`
|
|
811
|
+
),
|
|
812
|
+
grandTotalRevenueContribution: makePriceEthSchema(
|
|
813
|
+
`${valueLabel}.grandTotalRevenueContribution`
|
|
814
|
+
),
|
|
815
|
+
grandTotalQualifiedReferrersFinalScore: makeFiniteNonNegativeNumberSchema(
|
|
816
|
+
`${valueLabel}.grandTotalQualifiedReferrersFinalScore`
|
|
817
|
+
),
|
|
818
|
+
minFinalScoreToQualify: makeFiniteNonNegativeNumberSchema(
|
|
819
|
+
`${valueLabel}.minFinalScoreToQualify`
|
|
820
|
+
)
|
|
821
|
+
});
|
|
822
|
+
var makeReferrerEditionMetricsRankedPieSplitSchema = (valueLabel = "ReferrerEditionMetricsRankedPieSplit") => z3.object({
|
|
823
|
+
awardModel: z3.literal(ReferralProgramAwardModels.PieSplit),
|
|
824
|
+
type: z3.literal(ReferrerEditionMetricsTypeIds.Ranked),
|
|
825
|
+
rules: makeReferralProgramRulesPieSplitSchema(`${valueLabel}.rules`),
|
|
826
|
+
referrer: makeAwardedReferrerMetricsPieSplitSchema(`${valueLabel}.referrer`),
|
|
827
|
+
aggregatedMetrics: makeAggregatedReferrerMetricsPieSplitSchema(
|
|
828
|
+
`${valueLabel}.aggregatedMetrics`
|
|
829
|
+
),
|
|
830
|
+
status: makeReferralProgramStatusSchema(`${valueLabel}.status`),
|
|
831
|
+
accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
|
|
832
|
+
}).refine((data) => data.awardModel === data.rules.awardModel, {
|
|
833
|
+
message: `${valueLabel}.awardModel must equal ${valueLabel}.rules.awardModel`,
|
|
834
|
+
path: ["awardModel"]
|
|
835
|
+
});
|
|
836
|
+
var makeReferrerEditionMetricsUnrankedPieSplitSchema = (valueLabel = "ReferrerEditionMetricsUnrankedPieSplit") => z3.object({
|
|
837
|
+
awardModel: z3.literal(ReferralProgramAwardModels.PieSplit),
|
|
838
|
+
type: z3.literal(ReferrerEditionMetricsTypeIds.Unranked),
|
|
839
|
+
rules: makeReferralProgramRulesPieSplitSchema(`${valueLabel}.rules`),
|
|
840
|
+
referrer: makeUnrankedReferrerMetricsPieSplitSchema(`${valueLabel}.referrer`),
|
|
841
|
+
aggregatedMetrics: makeAggregatedReferrerMetricsPieSplitSchema(
|
|
842
|
+
`${valueLabel}.aggregatedMetrics`
|
|
843
|
+
),
|
|
844
|
+
status: makeReferralProgramStatusSchema(`${valueLabel}.status`),
|
|
845
|
+
accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
|
|
846
|
+
}).refine((data) => data.awardModel === data.rules.awardModel, {
|
|
847
|
+
message: `${valueLabel}.awardModel must equal ${valueLabel}.rules.awardModel`,
|
|
848
|
+
path: ["awardModel"]
|
|
849
|
+
});
|
|
850
|
+
var makeReferrerEditionMetricsPieSplitSchema = (valueLabel = "ReferrerEditionMetricsPieSplit") => z3.discriminatedUnion("type", [
|
|
851
|
+
makeReferrerEditionMetricsRankedPieSplitSchema(valueLabel),
|
|
852
|
+
makeReferrerEditionMetricsUnrankedPieSplitSchema(valueLabel)
|
|
853
|
+
]);
|
|
854
|
+
var makeReferralProgramEditionSummaryPieSplitSchema = (valueLabel = "ReferralProgramEditionSummaryPieSplit") => makeBaseReferralProgramEditionSummarySchema(valueLabel).safeExtend({
|
|
855
|
+
awardModel: z3.literal(ReferralProgramAwardModels.PieSplit),
|
|
856
|
+
rules: makeReferralProgramRulesPieSplitSchema(`${valueLabel}.rules`)
|
|
857
|
+
}).refine((data) => data.awardModel === data.rules.awardModel, {
|
|
858
|
+
message: `${valueLabel}.awardModel must equal ${valueLabel}.rules.awardModel`,
|
|
859
|
+
path: ["awardModel"]
|
|
860
|
+
});
|
|
861
|
+
var makeReferrerLeaderboardPagePieSplitSchema = (valueLabel = "ReferrerLeaderboardPagePieSplit") => makeBaseReferrerLeaderboardPageSchema(valueLabel).safeExtend({
|
|
862
|
+
awardModel: z3.literal(ReferralProgramAwardModels.PieSplit),
|
|
863
|
+
rules: makeReferralProgramRulesPieSplitSchema(`${valueLabel}.rules`),
|
|
864
|
+
referrers: z3.array(
|
|
865
|
+
makeAwardedReferrerMetricsPieSplitSchema(`${valueLabel}.referrers[record]`)
|
|
866
|
+
),
|
|
867
|
+
aggregatedMetrics: makeAggregatedReferrerMetricsPieSplitSchema(
|
|
868
|
+
`${valueLabel}.aggregatedMetrics`
|
|
869
|
+
)
|
|
870
|
+
}).refine((data) => data.awardModel === data.rules.awardModel, {
|
|
871
|
+
message: `${valueLabel}.awardModel must equal ${valueLabel}.rules.awardModel`,
|
|
872
|
+
path: ["awardModel"]
|
|
873
|
+
});
|
|
874
|
+
|
|
875
|
+
// src/award-models/rev-share-cap/api/zod-schemas.ts
|
|
876
|
+
import z4 from "zod/v4";
|
|
877
|
+
|
|
878
|
+
// src/award-models/rev-share-cap/rules.ts
|
|
879
|
+
var AdminActionTypes = {
|
|
880
|
+
/**
|
|
881
|
+
* The referrer is disqualified for awards.
|
|
882
|
+
*/
|
|
883
|
+
Disqualification: "Disqualification",
|
|
884
|
+
/**
|
|
885
|
+
* The referrer is warned about a potential disqualification but may still be qualified for awards.
|
|
886
|
+
*/
|
|
887
|
+
Warning: "Warning"
|
|
888
|
+
};
|
|
889
|
+
var validateReferralProgramRulesRevShareCap = (rules) => {
|
|
890
|
+
if (rules.awardModel !== ReferralProgramAwardModels.RevShareCap) {
|
|
891
|
+
throw new Error(
|
|
892
|
+
`ReferralProgramRulesRevShareCap: awardModel must be "${ReferralProgramAwardModels.RevShareCap}", got "${rules.awardModel}".`
|
|
893
|
+
);
|
|
894
|
+
}
|
|
895
|
+
makePriceUsdcSchema("ReferralProgramRulesRevShareCap.awardPool").parse(rules.awardPool);
|
|
896
|
+
makePriceUsdcSchema("ReferralProgramRulesRevShareCap.minBaseRevenueContribution").parse(
|
|
897
|
+
rules.minBaseRevenueContribution
|
|
898
|
+
);
|
|
899
|
+
makePriceUsdcSchema("ReferralProgramRulesRevShareCap.baseAnnualRevenueContribution").parse(
|
|
900
|
+
rules.baseAnnualRevenueContribution
|
|
901
|
+
);
|
|
902
|
+
if (!Number.isFinite(rules.maxBaseRevenueShare) || rules.maxBaseRevenueShare < 0 || rules.maxBaseRevenueShare > 1) {
|
|
903
|
+
throw new Error(
|
|
904
|
+
`ReferralProgramRulesRevShareCap: maxBaseRevenueShare must be between 0 and 1 (inclusive), got ${rules.maxBaseRevenueShare}.`
|
|
905
|
+
);
|
|
906
|
+
}
|
|
907
|
+
for (const action of rules.adminActions) {
|
|
908
|
+
validateNormalizedAddress(action.referrer);
|
|
909
|
+
if (action.reason.trim().length === 0 || action.reason !== action.reason.trim()) {
|
|
910
|
+
throw new Error(
|
|
911
|
+
"ReferralProgramRulesRevShareCap: admin action reason must be a trimmed, non-empty string."
|
|
912
|
+
);
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
const adminActionAddresses = rules.adminActions.map((a) => a.referrer);
|
|
916
|
+
const uniqueAdminActionAddresses = new Set(adminActionAddresses);
|
|
917
|
+
if (uniqueAdminActionAddresses.size !== adminActionAddresses.length) {
|
|
918
|
+
throw new Error(
|
|
919
|
+
"ReferralProgramRulesRevShareCap: adminActions must not contain duplicate referrer addresses."
|
|
920
|
+
);
|
|
921
|
+
}
|
|
922
|
+
validateBaseReferralProgramRules(rules);
|
|
923
|
+
};
|
|
924
|
+
var buildReferralProgramRulesRevShareCap = (awardPool, minBaseRevenueContribution, baseAnnualRevenueContribution, maxBaseRevenueShare, startTime, endTime, subregistryId, rulesUrl, areAwardsDistributed, adminActions = []) => {
|
|
925
|
+
const result = {
|
|
926
|
+
awardModel: ReferralProgramAwardModels.RevShareCap,
|
|
927
|
+
awardPool,
|
|
928
|
+
minBaseRevenueContribution,
|
|
929
|
+
baseAnnualRevenueContribution,
|
|
930
|
+
maxBaseRevenueShare,
|
|
931
|
+
startTime,
|
|
932
|
+
endTime,
|
|
933
|
+
subregistryId,
|
|
934
|
+
rulesUrl,
|
|
935
|
+
areAwardsDistributed,
|
|
936
|
+
adminActions
|
|
937
|
+
};
|
|
938
|
+
validateReferralProgramRulesRevShareCap(result);
|
|
939
|
+
return result;
|
|
940
|
+
};
|
|
941
|
+
function isReferrerQualifiedRevShareCap(referrer, totalBaseRevenueContribution, rules) {
|
|
942
|
+
const isAdminDisqualified = rules.adminActions.some(
|
|
943
|
+
(a) => a.referrer === referrer && a.actionType === AdminActionTypes.Disqualification
|
|
944
|
+
);
|
|
945
|
+
return totalBaseRevenueContribution.amount >= rules.minBaseRevenueContribution.amount && !isAdminDisqualified;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
// src/award-models/rev-share-cap/api/zod-schemas.ts
|
|
949
|
+
var makeAdminActionDisqualificationSchema = (valueLabel = "AdminActionDisqualification") => z4.object({
|
|
950
|
+
actionType: z4.literal(AdminActionTypes.Disqualification),
|
|
951
|
+
referrer: makeNormalizedAddressSchema(`${valueLabel}.referrer`),
|
|
952
|
+
reason: z4.string().trim().min(1, `${valueLabel}.reason must not be empty`)
|
|
953
|
+
});
|
|
954
|
+
var makeAdminActionWarningSchema = (valueLabel = "AdminActionWarning") => z4.object({
|
|
955
|
+
actionType: z4.literal(AdminActionTypes.Warning),
|
|
956
|
+
referrer: makeNormalizedAddressSchema(`${valueLabel}.referrer`),
|
|
957
|
+
reason: z4.string().trim().min(1, `${valueLabel}.reason must not be empty`)
|
|
958
|
+
});
|
|
959
|
+
var makeAdminActionSchema = (valueLabel = "AdminAction") => z4.discriminatedUnion("actionType", [
|
|
960
|
+
makeAdminActionDisqualificationSchema(valueLabel),
|
|
961
|
+
makeAdminActionWarningSchema(valueLabel)
|
|
962
|
+
]);
|
|
963
|
+
var makeReferralProgramRulesRevShareCapSchema = (valueLabel = "ReferralProgramRulesRevShareCap") => makeBaseReferralProgramRulesSchema(valueLabel).safeExtend({
|
|
964
|
+
awardModel: z4.literal(ReferralProgramAwardModels.RevShareCap),
|
|
965
|
+
awardPool: makePriceUsdcSchema(`${valueLabel}.awardPool`),
|
|
966
|
+
minBaseRevenueContribution: makePriceUsdcSchema(`${valueLabel}.minBaseRevenueContribution`),
|
|
967
|
+
baseAnnualRevenueContribution: makePriceUsdcSchema(
|
|
968
|
+
`${valueLabel}.baseAnnualRevenueContribution`
|
|
969
|
+
),
|
|
970
|
+
maxBaseRevenueShare: makeFiniteNonNegativeNumberSchema(`${valueLabel}.maxBaseRevenueShare`).max(
|
|
971
|
+
1,
|
|
972
|
+
`${valueLabel}.maxBaseRevenueShare must be <= 1`
|
|
973
|
+
),
|
|
974
|
+
adminActions: z4.array(makeAdminActionSchema(`${valueLabel}.adminActions[item]`)).refine(
|
|
975
|
+
(items) => {
|
|
976
|
+
const referrers = items.map((a) => a.referrer);
|
|
977
|
+
return new Set(referrers).size === referrers.length;
|
|
978
|
+
},
|
|
979
|
+
{
|
|
980
|
+
message: `${valueLabel}.adminActions must not contain duplicate referrer addresses`
|
|
981
|
+
}
|
|
982
|
+
).default([])
|
|
983
|
+
});
|
|
984
|
+
var makeAwardedReferrerMetricsRevShareCapSchema = (valueLabel = "AwardedReferrerMetricsRevShareCap") => z4.object({
|
|
985
|
+
referrer: makeNormalizedAddressSchema(`${valueLabel}.referrer`),
|
|
986
|
+
totalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.totalReferrals`),
|
|
987
|
+
totalIncrementalDuration: makeDurationSchema(`${valueLabel}.totalIncrementalDuration`),
|
|
988
|
+
totalRevenueContribution: makePriceEthSchema(`${valueLabel}.totalRevenueContribution`),
|
|
989
|
+
totalBaseRevenueContribution: makePriceUsdcSchema(
|
|
990
|
+
`${valueLabel}.totalBaseRevenueContribution`
|
|
991
|
+
),
|
|
992
|
+
rank: makePositiveIntegerSchema(`${valueLabel}.rank`),
|
|
993
|
+
isQualified: z4.boolean(),
|
|
994
|
+
uncappedAward: makePriceUsdcSchema(`${valueLabel}.uncappedAward`),
|
|
995
|
+
cappedAward: makePriceUsdcSchema(`${valueLabel}.cappedAward`),
|
|
996
|
+
adminAction: makeAdminActionSchema(`${valueLabel}.adminAction`).nullable()
|
|
997
|
+
}).refine((data) => data.cappedAward.amount <= data.uncappedAward.amount, {
|
|
998
|
+
message: `${valueLabel}.cappedAward must be <= ${valueLabel}.uncappedAward`,
|
|
999
|
+
path: ["cappedAward"]
|
|
1000
|
+
}).refine(
|
|
1001
|
+
(data) => data.adminAction?.actionType !== AdminActionTypes.Disqualification || data.isQualified === false && data.cappedAward.amount === 0n,
|
|
1002
|
+
{
|
|
1003
|
+
message: `When ${valueLabel}.adminAction.actionType is Disqualification, isQualified must be false and cappedAward.amount must be 0`,
|
|
1004
|
+
path: ["adminAction"]
|
|
1005
|
+
}
|
|
1006
|
+
).refine((data) => data.isQualified || data.cappedAward.amount === 0n, {
|
|
1007
|
+
message: `${valueLabel}.cappedAward must be 0 when isQualified is false`,
|
|
1008
|
+
path: ["cappedAward"]
|
|
1009
|
+
}).refine((data) => data.adminAction === null || data.adminAction.referrer === data.referrer, {
|
|
1010
|
+
message: `${valueLabel}.adminAction.referrer must match ${valueLabel}.referrer`,
|
|
1011
|
+
path: ["adminAction", "referrer"]
|
|
1012
|
+
});
|
|
1013
|
+
var makeUnrankedReferrerMetricsRevShareCapSchema = (valueLabel = "UnrankedReferrerMetricsRevShareCap") => z4.object({
|
|
1014
|
+
referrer: makeNormalizedAddressSchema(`${valueLabel}.referrer`),
|
|
1015
|
+
totalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.totalReferrals`),
|
|
1016
|
+
totalIncrementalDuration: makeDurationSchema(`${valueLabel}.totalIncrementalDuration`),
|
|
1017
|
+
totalRevenueContribution: makePriceEthSchema(`${valueLabel}.totalRevenueContribution`),
|
|
1018
|
+
totalBaseRevenueContribution: makePriceUsdcSchema(
|
|
1019
|
+
`${valueLabel}.totalBaseRevenueContribution`
|
|
1020
|
+
),
|
|
1021
|
+
rank: z4.null(),
|
|
1022
|
+
isQualified: z4.literal(false),
|
|
1023
|
+
uncappedAward: makePriceUsdcSchema(`${valueLabel}.uncappedAward`),
|
|
1024
|
+
cappedAward: makePriceUsdcSchema(`${valueLabel}.cappedAward`),
|
|
1025
|
+
adminAction: makeAdminActionSchema(`${valueLabel}.adminAction`).nullable()
|
|
1026
|
+
}).refine((data) => data.totalReferrals === 0, {
|
|
1027
|
+
message: `${valueLabel}.totalReferrals must be 0 for unranked referrers`,
|
|
1028
|
+
path: ["totalReferrals"]
|
|
1029
|
+
}).refine((data) => data.totalIncrementalDuration === 0, {
|
|
1030
|
+
message: `${valueLabel}.totalIncrementalDuration must be 0 for unranked referrers`,
|
|
1031
|
+
path: ["totalIncrementalDuration"]
|
|
1032
|
+
}).refine((data) => data.totalRevenueContribution.amount === 0n, {
|
|
1033
|
+
message: `${valueLabel}.totalRevenueContribution must be 0 for unranked referrers`,
|
|
1034
|
+
path: ["totalRevenueContribution"]
|
|
1035
|
+
}).refine((data) => data.totalBaseRevenueContribution.amount === 0n, {
|
|
1036
|
+
message: `${valueLabel}.totalBaseRevenueContribution must be 0 for unranked referrers`,
|
|
1037
|
+
path: ["totalBaseRevenueContribution"]
|
|
1038
|
+
}).refine((data) => data.uncappedAward.amount === 0n, {
|
|
1039
|
+
message: `${valueLabel}.uncappedAward must be 0 for unranked referrers`,
|
|
1040
|
+
path: ["uncappedAward"]
|
|
1041
|
+
}).refine((data) => data.cappedAward.amount === 0n, {
|
|
1042
|
+
message: `${valueLabel}.cappedAward must be 0 for unranked referrers`,
|
|
1043
|
+
path: ["cappedAward"]
|
|
1044
|
+
}).refine((data) => data.adminAction === null || data.adminAction.referrer === data.referrer, {
|
|
1045
|
+
message: `${valueLabel}.adminAction.referrer must match ${valueLabel}.referrer`,
|
|
1046
|
+
path: ["adminAction", "referrer"]
|
|
1047
|
+
});
|
|
1048
|
+
var makeAggregatedReferrerMetricsRevShareCapSchema = (valueLabel = "AggregatedReferrerMetricsRevShareCap") => z4.object({
|
|
1049
|
+
grandTotalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.grandTotalReferrals`),
|
|
1050
|
+
grandTotalIncrementalDuration: makeDurationSchema(
|
|
1051
|
+
`${valueLabel}.grandTotalIncrementalDuration`
|
|
1052
|
+
),
|
|
1053
|
+
grandTotalRevenueContribution: makePriceEthSchema(
|
|
1054
|
+
`${valueLabel}.grandTotalRevenueContribution`
|
|
1055
|
+
),
|
|
1056
|
+
awardPoolRemaining: makePriceUsdcSchema(`${valueLabel}.awardPoolRemaining`)
|
|
1057
|
+
});
|
|
1058
|
+
var addAdminActionConsistencyIssues = (ctx, metricsAdminAction, referrer, rulesAdminActions, path) => {
|
|
1059
|
+
const expected = rulesAdminActions.find((a) => a.referrer === referrer) ?? null;
|
|
1060
|
+
if (expected === null && metricsAdminAction !== null) {
|
|
1061
|
+
ctx.addIssue({
|
|
1062
|
+
code: z4.ZodIssueCode.custom,
|
|
1063
|
+
message: `adminAction expected null, got actionType="${metricsAdminAction.actionType}"`,
|
|
1064
|
+
path
|
|
1065
|
+
});
|
|
1066
|
+
return;
|
|
1067
|
+
}
|
|
1068
|
+
if (expected !== null && (metricsAdminAction === null || metricsAdminAction.actionType !== expected.actionType || metricsAdminAction.referrer !== expected.referrer || metricsAdminAction.reason !== expected.reason)) {
|
|
1069
|
+
ctx.addIssue({
|
|
1070
|
+
code: z4.ZodIssueCode.custom,
|
|
1071
|
+
message: `adminAction does not match the corresponding entry in rules.adminActions`,
|
|
1072
|
+
path
|
|
1073
|
+
});
|
|
1074
|
+
}
|
|
1075
|
+
};
|
|
1076
|
+
var makeReferrerEditionMetricsRankedRevShareCapSchema = (valueLabel = "ReferrerEditionMetricsRankedRevShareCap") => z4.object({
|
|
1077
|
+
awardModel: z4.literal(ReferralProgramAwardModels.RevShareCap),
|
|
1078
|
+
type: z4.literal(ReferrerEditionMetricsTypeIds.Ranked),
|
|
1079
|
+
rules: makeReferralProgramRulesRevShareCapSchema(`${valueLabel}.rules`),
|
|
1080
|
+
referrer: makeAwardedReferrerMetricsRevShareCapSchema(`${valueLabel}.referrer`),
|
|
1081
|
+
aggregatedMetrics: makeAggregatedReferrerMetricsRevShareCapSchema(
|
|
1082
|
+
`${valueLabel}.aggregatedMetrics`
|
|
1083
|
+
),
|
|
1084
|
+
status: makeReferralProgramStatusSchema(`${valueLabel}.status`),
|
|
1085
|
+
accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
|
|
1086
|
+
}).refine((data) => data.awardModel === data.rules.awardModel, {
|
|
1087
|
+
message: `${valueLabel}.awardModel must equal ${valueLabel}.rules.awardModel`,
|
|
1088
|
+
path: ["awardModel"]
|
|
1089
|
+
}).refine((data) => data.referrer.cappedAward.amount <= data.rules.awardPool.amount, {
|
|
1090
|
+
message: `${valueLabel}.referrer.cappedAward must be <= ${valueLabel}.rules.awardPool`,
|
|
1091
|
+
path: ["referrer", "cappedAward", "amount"]
|
|
1092
|
+
}).superRefine((data, ctx) => {
|
|
1093
|
+
addAdminActionConsistencyIssues(
|
|
1094
|
+
ctx,
|
|
1095
|
+
data.referrer.adminAction,
|
|
1096
|
+
data.referrer.referrer,
|
|
1097
|
+
data.rules.adminActions,
|
|
1098
|
+
["referrer", "adminAction"]
|
|
1099
|
+
);
|
|
1100
|
+
});
|
|
1101
|
+
var makeReferrerEditionMetricsUnrankedRevShareCapSchema = (valueLabel = "ReferrerEditionMetricsUnrankedRevShareCap") => z4.object({
|
|
1102
|
+
awardModel: z4.literal(ReferralProgramAwardModels.RevShareCap),
|
|
1103
|
+
type: z4.literal(ReferrerEditionMetricsTypeIds.Unranked),
|
|
1104
|
+
rules: makeReferralProgramRulesRevShareCapSchema(`${valueLabel}.rules`),
|
|
1105
|
+
referrer: makeUnrankedReferrerMetricsRevShareCapSchema(`${valueLabel}.referrer`),
|
|
1106
|
+
aggregatedMetrics: makeAggregatedReferrerMetricsRevShareCapSchema(
|
|
1107
|
+
`${valueLabel}.aggregatedMetrics`
|
|
1108
|
+
),
|
|
1109
|
+
status: makeReferralProgramStatusSchema(`${valueLabel}.status`),
|
|
1110
|
+
accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
|
|
1111
|
+
}).refine((data) => data.awardModel === data.rules.awardModel, {
|
|
1112
|
+
message: `${valueLabel}.awardModel must equal ${valueLabel}.rules.awardModel`,
|
|
1113
|
+
path: ["awardModel"]
|
|
1114
|
+
}).superRefine((data, ctx) => {
|
|
1115
|
+
addAdminActionConsistencyIssues(
|
|
1116
|
+
ctx,
|
|
1117
|
+
data.referrer.adminAction,
|
|
1118
|
+
data.referrer.referrer,
|
|
1119
|
+
data.rules.adminActions,
|
|
1120
|
+
["referrer", "adminAction"]
|
|
1121
|
+
);
|
|
1122
|
+
});
|
|
1123
|
+
var makeReferrerEditionMetricsRevShareCapSchema = (valueLabel = "ReferrerEditionMetricsRevShareCap") => z4.discriminatedUnion("type", [
|
|
1124
|
+
makeReferrerEditionMetricsRankedRevShareCapSchema(valueLabel),
|
|
1125
|
+
makeReferrerEditionMetricsUnrankedRevShareCapSchema(valueLabel)
|
|
1126
|
+
]);
|
|
1127
|
+
var makeReferralProgramEditionSummaryRevShareCapSchema = (valueLabel = "ReferralProgramEditionSummaryRevShareCap") => makeBaseReferralProgramEditionSummarySchema(valueLabel).safeExtend({
|
|
1128
|
+
awardModel: z4.literal(ReferralProgramAwardModels.RevShareCap),
|
|
1129
|
+
rules: makeReferralProgramRulesRevShareCapSchema(`${valueLabel}.rules`),
|
|
1130
|
+
awardPoolRemaining: makePriceUsdcSchema(`${valueLabel}.awardPoolRemaining`)
|
|
1131
|
+
}).refine((data) => data.awardModel === data.rules.awardModel, {
|
|
1132
|
+
message: `${valueLabel}.awardModel must equal ${valueLabel}.rules.awardModel`,
|
|
1133
|
+
path: ["awardModel"]
|
|
1134
|
+
});
|
|
1135
|
+
var makeReferrerLeaderboardPageRevShareCapSchema = (valueLabel = "ReferrerLeaderboardPageRevShareCap") => makeBaseReferrerLeaderboardPageSchema(valueLabel).safeExtend({
|
|
1136
|
+
awardModel: z4.literal(ReferralProgramAwardModels.RevShareCap),
|
|
1137
|
+
rules: makeReferralProgramRulesRevShareCapSchema(`${valueLabel}.rules`),
|
|
1138
|
+
referrers: z4.array(
|
|
1139
|
+
makeAwardedReferrerMetricsRevShareCapSchema(`${valueLabel}.referrers[record]`)
|
|
1140
|
+
),
|
|
1141
|
+
aggregatedMetrics: makeAggregatedReferrerMetricsRevShareCapSchema(
|
|
1142
|
+
`${valueLabel}.aggregatedMetrics`
|
|
1143
|
+
)
|
|
1144
|
+
}).refine((data) => data.awardModel === data.rules.awardModel, {
|
|
1145
|
+
message: `${valueLabel}.awardModel must equal ${valueLabel}.rules.awardModel`,
|
|
1146
|
+
path: ["awardModel"]
|
|
1147
|
+
}).superRefine((data, ctx) => {
|
|
1148
|
+
data.referrers.forEach((referrer, index) => {
|
|
1149
|
+
if (referrer.cappedAward.amount > data.rules.awardPool.amount) {
|
|
1150
|
+
ctx.addIssue({
|
|
1151
|
+
code: z4.ZodIssueCode.custom,
|
|
1152
|
+
message: `${valueLabel}.referrers[${index}].cappedAward must be <= ${valueLabel}.rules.awardPool`,
|
|
1153
|
+
path: ["referrers", index, "cappedAward", "amount"]
|
|
1154
|
+
});
|
|
1155
|
+
}
|
|
1156
|
+
addAdminActionConsistencyIssues(
|
|
1157
|
+
ctx,
|
|
1158
|
+
referrer.adminAction,
|
|
1159
|
+
referrer.referrer,
|
|
1160
|
+
data.rules.adminActions,
|
|
1161
|
+
["referrers", index, "adminAction"]
|
|
1162
|
+
);
|
|
1163
|
+
});
|
|
1164
|
+
});
|
|
1165
|
+
|
|
1166
|
+
// src/api/types.ts
|
|
1167
|
+
var ReferrerLeaderboardPageResponseCodes = {
|
|
1168
|
+
/**
|
|
1169
|
+
* Represents that the requested referrer leaderboard page is available.
|
|
1170
|
+
*/
|
|
1171
|
+
Ok: "ok",
|
|
1172
|
+
/**
|
|
1173
|
+
* Represents that the referrer leaderboard data is not available.
|
|
1174
|
+
*/
|
|
1175
|
+
Error: "error"
|
|
1176
|
+
};
|
|
1177
|
+
var MAX_EDITIONS_PER_REQUEST = 20;
|
|
1178
|
+
var ReferrerMetricsEditionsResponseCodes = {
|
|
1179
|
+
/**
|
|
1180
|
+
* Represents that the referrer metrics data for the requested editions is available.
|
|
1181
|
+
*/
|
|
1182
|
+
Ok: "ok",
|
|
1183
|
+
/**
|
|
1184
|
+
* Represents that an error occurred while fetching the data.
|
|
1185
|
+
*/
|
|
1186
|
+
Error: "error"
|
|
1187
|
+
};
|
|
1188
|
+
var ReferralProgramEditionSummariesResponseCodes = {
|
|
1189
|
+
/**
|
|
1190
|
+
* Represents that the edition summaries are available.
|
|
1191
|
+
*/
|
|
1192
|
+
Ok: "ok",
|
|
1193
|
+
/**
|
|
1194
|
+
* Represents that the edition summaries are not available.
|
|
1195
|
+
*/
|
|
1196
|
+
Error: "error"
|
|
1197
|
+
};
|
|
1198
|
+
|
|
1199
|
+
// src/api/zod-schemas.ts
|
|
1200
|
+
var reemitIssues = (ctx, issues, pathPrefix = []) => {
|
|
1201
|
+
for (const issue of issues) {
|
|
1202
|
+
ctx.addIssue({
|
|
1203
|
+
...issue,
|
|
1204
|
+
path: [...pathPrefix, ...issue.path]
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1207
|
+
};
|
|
1208
|
+
var makeReferralProgramRulesSchema = (valueLabel = "ReferralProgramRules") => z5.discriminatedUnion("awardModel", [
|
|
1209
|
+
makeReferralProgramRulesPieSplitSchema(valueLabel),
|
|
1210
|
+
makeReferralProgramRulesRevShareCapSchema(valueLabel)
|
|
1211
|
+
]);
|
|
1212
|
+
var makeReferrerLeaderboardPageSchema = (valueLabel = "ReferrerLeaderboardPage") => {
|
|
1213
|
+
const knownAwardModels = Object.values(ReferralProgramAwardModels).filter(
|
|
1214
|
+
(m) => m !== ReferralProgramAwardModels.Unrecognized
|
|
1215
|
+
);
|
|
1216
|
+
const looseSchema = z5.looseObject({ awardModel: z5.string() });
|
|
1217
|
+
const knownSchema = z5.discriminatedUnion("awardModel", [
|
|
1218
|
+
makeReferrerLeaderboardPagePieSplitSchema(valueLabel),
|
|
1219
|
+
makeReferrerLeaderboardPageRevShareCapSchema(valueLabel)
|
|
1220
|
+
]);
|
|
1221
|
+
const baseSchema = makeBaseReferrerLeaderboardPageSchema(valueLabel);
|
|
1222
|
+
return looseSchema.transform((data, ctx) => {
|
|
1223
|
+
if (knownAwardModels.includes(data.awardModel)) {
|
|
1224
|
+
const parsed2 = knownSchema.safeParse(data);
|
|
1225
|
+
if (!parsed2.success) {
|
|
1226
|
+
reemitIssues(ctx, parsed2.error.issues);
|
|
1227
|
+
return z5.NEVER;
|
|
1228
|
+
}
|
|
1229
|
+
return parsed2.data;
|
|
1230
|
+
}
|
|
1231
|
+
const parsed = baseSchema.safeParse(data);
|
|
1232
|
+
if (!parsed.success) {
|
|
1233
|
+
reemitIssues(ctx, parsed.error.issues);
|
|
1234
|
+
return z5.NEVER;
|
|
1235
|
+
}
|
|
1236
|
+
return {
|
|
1237
|
+
...parsed.data,
|
|
1238
|
+
awardModel: ReferralProgramAwardModels.Unrecognized,
|
|
1239
|
+
originalAwardModel: data.awardModel
|
|
1240
|
+
};
|
|
1241
|
+
});
|
|
1242
|
+
};
|
|
1243
|
+
var makeReferrerLeaderboardPageResponseOkSchema = (valueLabel = "ReferrerLeaderboardPageResponseOk") => z5.object({
|
|
1244
|
+
responseCode: z5.literal(ReferrerLeaderboardPageResponseCodes.Ok),
|
|
1245
|
+
data: makeReferrerLeaderboardPageSchema(`${valueLabel}.data`)
|
|
1246
|
+
});
|
|
1247
|
+
var makeReferrerLeaderboardPageResponseErrorSchema = (_valueLabel = "ReferrerLeaderboardPageResponseError") => z5.object({
|
|
1248
|
+
responseCode: z5.literal(ReferrerLeaderboardPageResponseCodes.Error),
|
|
1249
|
+
error: z5.string(),
|
|
1250
|
+
errorMessage: z5.string()
|
|
1251
|
+
});
|
|
1252
|
+
var makeReferrerLeaderboardPageResponseSchema = (valueLabel = "ReferrerLeaderboardPageResponse") => z5.discriminatedUnion("responseCode", [
|
|
1253
|
+
makeReferrerLeaderboardPageResponseOkSchema(valueLabel),
|
|
1254
|
+
makeReferrerLeaderboardPageResponseErrorSchema(valueLabel)
|
|
1255
|
+
]);
|
|
1256
|
+
var makeReferrerEditionMetricsSchema = (valueLabel = "ReferrerEditionMetrics") => {
|
|
1257
|
+
const knownAwardModels = Object.values(ReferralProgramAwardModels).filter(
|
|
1258
|
+
(m) => m !== ReferralProgramAwardModels.Unrecognized
|
|
1259
|
+
);
|
|
1260
|
+
const looseSchema = z5.looseObject({ awardModel: z5.string() });
|
|
1261
|
+
const knownSchema = z5.discriminatedUnion("awardModel", [
|
|
1262
|
+
makeReferrerEditionMetricsPieSplitSchema(valueLabel),
|
|
1263
|
+
makeReferrerEditionMetricsRevShareCapSchema(valueLabel)
|
|
1264
|
+
]);
|
|
1265
|
+
return looseSchema.transform((data, ctx) => {
|
|
1266
|
+
if (knownAwardModels.includes(data.awardModel)) {
|
|
1267
|
+
const parsed = knownSchema.safeParse(data);
|
|
1268
|
+
if (!parsed.success) {
|
|
1269
|
+
reemitIssues(ctx, parsed.error.issues);
|
|
1270
|
+
return z5.NEVER;
|
|
1271
|
+
}
|
|
1272
|
+
return parsed.data;
|
|
1273
|
+
}
|
|
1274
|
+
return {
|
|
1275
|
+
awardModel: ReferralProgramAwardModels.Unrecognized,
|
|
1276
|
+
originalAwardModel: data.awardModel
|
|
1277
|
+
};
|
|
1278
|
+
});
|
|
1279
|
+
};
|
|
1280
|
+
var makeReferralProgramEditionSlugSchema = (valueLabel = "ReferralProgramEditionSlug") => z5.string().min(1, `${valueLabel} must not be empty`).regex(
|
|
1281
|
+
/^[a-z0-9]+(-[a-z0-9]+)*$/,
|
|
1282
|
+
`${valueLabel} must contain only lowercase letters, digits, and hyphens. Must not start or end with a hyphen.`
|
|
1283
|
+
);
|
|
1284
|
+
var makeReferrerMetricsEditionsResponseOkSchema = (valueLabel = "ReferrerMetricsEditionsResponseOk") => z5.object({
|
|
1285
|
+
responseCode: z5.literal(ReferrerMetricsEditionsResponseCodes.Ok),
|
|
1286
|
+
data: z5.record(
|
|
1287
|
+
makeReferralProgramEditionSlugSchema(`${valueLabel}.data[edition]`),
|
|
1288
|
+
makeReferrerEditionMetricsSchema(`${valueLabel}.data[edition]`)
|
|
1289
|
+
)
|
|
1290
|
+
});
|
|
1291
|
+
var makeReferrerMetricsEditionsResponseErrorSchema = (_valueLabel = "ReferrerMetricsEditionsResponseError") => z5.object({
|
|
1292
|
+
responseCode: z5.literal(ReferrerMetricsEditionsResponseCodes.Error),
|
|
1293
|
+
error: z5.string(),
|
|
1294
|
+
errorMessage: z5.string()
|
|
1295
|
+
});
|
|
1296
|
+
var makeReferrerMetricsEditionsResponseSchema = (valueLabel = "ReferrerMetricsEditionsResponse") => z5.discriminatedUnion("responseCode", [
|
|
1297
|
+
makeReferrerMetricsEditionsResponseOkSchema(valueLabel),
|
|
1298
|
+
makeReferrerMetricsEditionsResponseErrorSchema(valueLabel)
|
|
1299
|
+
]);
|
|
1300
|
+
var makeReferralProgramEditionConfigBaseSchema = (valueLabel) => z5.object({
|
|
1301
|
+
slug: makeReferralProgramEditionSlugSchema(`${valueLabel}.slug`),
|
|
1302
|
+
displayName: z5.string().min(1, `${valueLabel}.displayName must not be empty`),
|
|
1303
|
+
rules: makeBaseReferralProgramRulesSchema(`${valueLabel}.rules`)
|
|
1304
|
+
});
|
|
1305
|
+
var makeReferralProgramEditionConfigSchema = (valueLabel = "ReferralProgramEditionConfig") => makeReferralProgramEditionConfigBaseSchema(valueLabel).safeExtend({
|
|
1306
|
+
rules: makeReferralProgramRulesSchema(`${valueLabel}.rules`)
|
|
1307
|
+
});
|
|
1308
|
+
var makeReferralProgramEditionConfigSetArraySchema = (valueLabel = "ReferralProgramEditionConfigSetArray") => {
|
|
1309
|
+
const knownAwardModels = Object.values(ReferralProgramAwardModels).filter(
|
|
1310
|
+
(m) => m !== ReferralProgramAwardModels.Unrecognized
|
|
1311
|
+
);
|
|
1312
|
+
const configSchema = makeReferralProgramEditionConfigSchema(`${valueLabel}[edition]`);
|
|
1313
|
+
const looseItemSchema = z5.looseObject({
|
|
1314
|
+
rules: z5.looseObject({ awardModel: z5.string() })
|
|
1315
|
+
});
|
|
1316
|
+
const unrecognizedBaseSchema = makeReferralProgramEditionConfigBaseSchema(
|
|
1317
|
+
`${valueLabel}[edition]`
|
|
1318
|
+
);
|
|
1319
|
+
return z5.array(looseItemSchema).transform((items, ctx) => {
|
|
1320
|
+
const result = [];
|
|
1321
|
+
for (let i = 0; i < items.length; i++) {
|
|
1322
|
+
const item = items[i];
|
|
1323
|
+
if (knownAwardModels.includes(item.rules.awardModel)) {
|
|
1324
|
+
const parsed = configSchema.safeParse(item);
|
|
1325
|
+
if (!parsed.success) {
|
|
1326
|
+
reemitIssues(ctx, parsed.error.issues, [i]);
|
|
1327
|
+
} else {
|
|
1328
|
+
result.push(parsed.data);
|
|
1329
|
+
}
|
|
1330
|
+
} else {
|
|
1331
|
+
const parsed = unrecognizedBaseSchema.safeParse(item);
|
|
1332
|
+
if (!parsed.success) {
|
|
1333
|
+
reemitIssues(ctx, parsed.error.issues, [i]);
|
|
1334
|
+
continue;
|
|
1335
|
+
}
|
|
1336
|
+
result.push({
|
|
1337
|
+
...parsed.data,
|
|
1338
|
+
rules: {
|
|
1339
|
+
...parsed.data.rules,
|
|
1340
|
+
awardModel: ReferralProgramAwardModels.Unrecognized,
|
|
1341
|
+
originalAwardModel: item.rules.awardModel
|
|
1342
|
+
}
|
|
1343
|
+
});
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
const slugs = /* @__PURE__ */ new Set();
|
|
1347
|
+
for (const edition of result) {
|
|
1348
|
+
if (slugs.has(edition.slug)) {
|
|
1349
|
+
ctx.addIssue({
|
|
1350
|
+
code: "custom",
|
|
1351
|
+
message: `${valueLabel} must not contain duplicate edition slugs`
|
|
1352
|
+
});
|
|
1353
|
+
return [];
|
|
1354
|
+
}
|
|
1355
|
+
slugs.add(edition.slug);
|
|
1356
|
+
}
|
|
1357
|
+
return result;
|
|
1358
|
+
});
|
|
1359
|
+
};
|
|
1360
|
+
var makeReferralProgramEditionSummarySchema = (valueLabel = "ReferralProgramEditionSummary") => {
|
|
1361
|
+
const knownAwardModels = Object.values(ReferralProgramAwardModels).filter(
|
|
1362
|
+
(m) => m !== ReferralProgramAwardModels.Unrecognized
|
|
1363
|
+
);
|
|
1364
|
+
const looseSchema = z5.looseObject({ awardModel: z5.string() });
|
|
1365
|
+
const knownSchema = z5.discriminatedUnion("awardModel", [
|
|
1366
|
+
makeReferralProgramEditionSummaryPieSplitSchema(valueLabel),
|
|
1367
|
+
makeReferralProgramEditionSummaryRevShareCapSchema(valueLabel)
|
|
1368
|
+
]);
|
|
1369
|
+
const baseSchema = makeBaseReferralProgramEditionSummarySchema(valueLabel);
|
|
1370
|
+
return looseSchema.transform((data, ctx) => {
|
|
1371
|
+
if (knownAwardModels.includes(data.awardModel)) {
|
|
1372
|
+
const parsed2 = knownSchema.safeParse(data);
|
|
1373
|
+
if (!parsed2.success) {
|
|
1374
|
+
reemitIssues(ctx, parsed2.error.issues);
|
|
1375
|
+
return z5.NEVER;
|
|
1376
|
+
}
|
|
1377
|
+
return parsed2.data;
|
|
1378
|
+
}
|
|
1379
|
+
const parsed = baseSchema.safeParse(data);
|
|
1380
|
+
if (!parsed.success) {
|
|
1381
|
+
reemitIssues(ctx, parsed.error.issues);
|
|
1382
|
+
return z5.NEVER;
|
|
1383
|
+
}
|
|
1384
|
+
return {
|
|
1385
|
+
...parsed.data,
|
|
1386
|
+
awardModel: ReferralProgramAwardModels.Unrecognized,
|
|
1387
|
+
rules: {
|
|
1388
|
+
...parsed.data.rules,
|
|
1389
|
+
awardModel: ReferralProgramAwardModels.Unrecognized,
|
|
1390
|
+
originalAwardModel: data.awardModel
|
|
1391
|
+
}
|
|
1392
|
+
};
|
|
1393
|
+
});
|
|
1394
|
+
};
|
|
1395
|
+
var makeReferralProgramEditionSummariesDataSchema = (valueLabel = "ReferralProgramEditionSummariesData") => z5.object({
|
|
1396
|
+
editions: z5.array(makeReferralProgramEditionSummarySchema(`${valueLabel}.editions[edition]`))
|
|
1397
|
+
});
|
|
1398
|
+
var makeReferralProgramEditionSummariesResponseOkSchema = (valueLabel = "ReferralProgramEditionSummariesResponseOk") => z5.object({
|
|
1399
|
+
responseCode: z5.literal(ReferralProgramEditionSummariesResponseCodes.Ok),
|
|
1400
|
+
data: makeReferralProgramEditionSummariesDataSchema(`${valueLabel}.data`)
|
|
1401
|
+
});
|
|
1402
|
+
var makeReferralProgramEditionSummariesResponseErrorSchema = (_valueLabel = "ReferralProgramEditionSummariesResponseError") => z5.object({
|
|
1403
|
+
responseCode: z5.literal(ReferralProgramEditionSummariesResponseCodes.Error),
|
|
1404
|
+
error: z5.string(),
|
|
1405
|
+
errorMessage: z5.string()
|
|
1406
|
+
});
|
|
1407
|
+
var makeReferralProgramEditionSummariesResponseSchema = (valueLabel = "ReferralProgramEditionSummariesResponse") => z5.discriminatedUnion("responseCode", [
|
|
1408
|
+
makeReferralProgramEditionSummariesResponseOkSchema(valueLabel),
|
|
1409
|
+
makeReferralProgramEditionSummariesResponseErrorSchema(valueLabel)
|
|
1410
|
+
]);
|
|
1411
|
+
|
|
1412
|
+
// src/api/deserialize.ts
|
|
1413
|
+
function deserializeReferrerLeaderboardPageResponse(maybeResponse, valueLabel) {
|
|
1414
|
+
const schema = makeReferrerLeaderboardPageResponseSchema(valueLabel);
|
|
1415
|
+
const parsed = schema.safeParse(maybeResponse);
|
|
1416
|
+
if (parsed.error) {
|
|
1417
|
+
throw new Error(
|
|
1418
|
+
`Cannot deserialize SerializedReferrerLeaderboardPageResponse:
|
|
1419
|
+
${prettifyError(parsed.error)}
|
|
1420
|
+
`
|
|
1421
|
+
);
|
|
1422
|
+
}
|
|
1423
|
+
return parsed.data;
|
|
1424
|
+
}
|
|
1425
|
+
function deserializeReferrerMetricsEditionsResponse(maybeResponse, valueLabel) {
|
|
1426
|
+
const schema = makeReferrerMetricsEditionsResponseSchema(valueLabel);
|
|
1427
|
+
const parsed = schema.safeParse(maybeResponse);
|
|
1428
|
+
if (parsed.error) {
|
|
1429
|
+
throw new Error(
|
|
1430
|
+
`Cannot deserialize ReferrerMetricsEditionsResponse:
|
|
1431
|
+
${prettifyError(parsed.error)}
|
|
1432
|
+
`
|
|
1433
|
+
);
|
|
1434
|
+
}
|
|
1435
|
+
return parsed.data;
|
|
1436
|
+
}
|
|
1437
|
+
function deserializeReferralProgramEditionConfigSetArray(maybeArray, valueLabel) {
|
|
1438
|
+
const schema = makeReferralProgramEditionConfigSetArraySchema(valueLabel);
|
|
1439
|
+
const parsed = schema.safeParse(maybeArray);
|
|
1440
|
+
if (parsed.error) {
|
|
1441
|
+
throw new Error(
|
|
1442
|
+
`Cannot deserialize ReferralProgramEditionConfigSetArray:
|
|
1443
|
+
${prettifyError(parsed.error)}
|
|
1444
|
+
`
|
|
1445
|
+
);
|
|
1446
|
+
}
|
|
1447
|
+
return parsed.data;
|
|
1448
|
+
}
|
|
1449
|
+
function deserializeReferralProgramEditionSummariesResponse(maybeResponse, valueLabel) {
|
|
1450
|
+
const schema = makeReferralProgramEditionSummariesResponseSchema(valueLabel);
|
|
1451
|
+
const parsed = schema.safeParse(maybeResponse);
|
|
1452
|
+
if (parsed.error) {
|
|
1453
|
+
throw new Error(
|
|
1454
|
+
`Cannot deserialize ReferralProgramEditionSummariesResponse:
|
|
1455
|
+
${prettifyError(parsed.error)}
|
|
1456
|
+
`
|
|
1457
|
+
);
|
|
1458
|
+
}
|
|
1459
|
+
return parsed.data;
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
// src/award-models/pie-split/api/serialize.ts
|
|
1463
|
+
function serializeReferralProgramRulesPieSplit(rules) {
|
|
1464
|
+
return {
|
|
1465
|
+
awardModel: rules.awardModel,
|
|
1466
|
+
awardPool: serializePriceUsdc(rules.awardPool),
|
|
1467
|
+
maxQualifiedReferrers: rules.maxQualifiedReferrers,
|
|
1468
|
+
startTime: rules.startTime,
|
|
1469
|
+
endTime: rules.endTime,
|
|
1470
|
+
subregistryId: rules.subregistryId,
|
|
1471
|
+
rulesUrl: rules.rulesUrl.toString(),
|
|
1472
|
+
areAwardsDistributed: rules.areAwardsDistributed
|
|
1473
|
+
};
|
|
1474
|
+
}
|
|
1475
|
+
function serializeAggregatedReferrerMetricsPieSplit(metrics) {
|
|
1476
|
+
return {
|
|
1477
|
+
grandTotalReferrals: metrics.grandTotalReferrals,
|
|
1478
|
+
grandTotalIncrementalDuration: metrics.grandTotalIncrementalDuration,
|
|
1479
|
+
grandTotalRevenueContribution: serializePriceEth(metrics.grandTotalRevenueContribution),
|
|
1480
|
+
grandTotalQualifiedReferrersFinalScore: metrics.grandTotalQualifiedReferrersFinalScore,
|
|
1481
|
+
minFinalScoreToQualify: metrics.minFinalScoreToQualify
|
|
1482
|
+
};
|
|
1483
|
+
}
|
|
1484
|
+
function serializeAwardedReferrerMetricsPieSplit(metrics) {
|
|
1485
|
+
return {
|
|
1486
|
+
referrer: metrics.referrer,
|
|
1487
|
+
totalReferrals: metrics.totalReferrals,
|
|
1488
|
+
totalIncrementalDuration: metrics.totalIncrementalDuration,
|
|
1489
|
+
totalRevenueContribution: serializePriceEth(metrics.totalRevenueContribution),
|
|
1490
|
+
score: metrics.score,
|
|
1491
|
+
rank: metrics.rank,
|
|
1492
|
+
isQualified: metrics.isQualified,
|
|
1493
|
+
finalScoreBoost: metrics.finalScoreBoost,
|
|
1494
|
+
finalScore: metrics.finalScore,
|
|
1495
|
+
awardPoolShare: metrics.awardPoolShare,
|
|
1496
|
+
awardPoolApproxValue: serializePriceUsdc(metrics.awardPoolApproxValue)
|
|
1497
|
+
};
|
|
1498
|
+
}
|
|
1499
|
+
function serializeUnrankedReferrerMetricsPieSplit(metrics) {
|
|
1500
|
+
return {
|
|
1501
|
+
referrer: metrics.referrer,
|
|
1502
|
+
totalReferrals: metrics.totalReferrals,
|
|
1503
|
+
totalIncrementalDuration: metrics.totalIncrementalDuration,
|
|
1504
|
+
totalRevenueContribution: serializePriceEth(metrics.totalRevenueContribution),
|
|
1505
|
+
score: metrics.score,
|
|
1506
|
+
rank: metrics.rank,
|
|
1507
|
+
isQualified: metrics.isQualified,
|
|
1508
|
+
finalScoreBoost: metrics.finalScoreBoost,
|
|
1509
|
+
finalScore: metrics.finalScore,
|
|
1510
|
+
awardPoolShare: metrics.awardPoolShare,
|
|
1511
|
+
awardPoolApproxValue: serializePriceUsdc(metrics.awardPoolApproxValue)
|
|
1512
|
+
};
|
|
1513
|
+
}
|
|
1514
|
+
function serializeReferrerEditionMetricsRankedPieSplit(detail) {
|
|
1515
|
+
return {
|
|
1516
|
+
awardModel: detail.awardModel,
|
|
1517
|
+
type: detail.type,
|
|
1518
|
+
rules: serializeReferralProgramRulesPieSplit(detail.rules),
|
|
1519
|
+
referrer: serializeAwardedReferrerMetricsPieSplit(detail.referrer),
|
|
1520
|
+
aggregatedMetrics: serializeAggregatedReferrerMetricsPieSplit(detail.aggregatedMetrics),
|
|
1521
|
+
status: detail.status,
|
|
1522
|
+
accurateAsOf: detail.accurateAsOf
|
|
1523
|
+
};
|
|
1524
|
+
}
|
|
1525
|
+
function serializeReferrerEditionMetricsUnrankedPieSplit(detail) {
|
|
1526
|
+
return {
|
|
1527
|
+
awardModel: detail.awardModel,
|
|
1528
|
+
type: detail.type,
|
|
1529
|
+
rules: serializeReferralProgramRulesPieSplit(detail.rules),
|
|
1530
|
+
referrer: serializeUnrankedReferrerMetricsPieSplit(detail.referrer),
|
|
1531
|
+
aggregatedMetrics: serializeAggregatedReferrerMetricsPieSplit(detail.aggregatedMetrics),
|
|
1532
|
+
status: detail.status,
|
|
1533
|
+
accurateAsOf: detail.accurateAsOf
|
|
1534
|
+
};
|
|
1535
|
+
}
|
|
1536
|
+
function serializeReferrerEditionMetricsPieSplit(detail) {
|
|
1537
|
+
switch (detail.type) {
|
|
1538
|
+
case ReferrerEditionMetricsTypeIds.Ranked:
|
|
1539
|
+
return serializeReferrerEditionMetricsRankedPieSplit(detail);
|
|
1540
|
+
case ReferrerEditionMetricsTypeIds.Unranked:
|
|
1541
|
+
return serializeReferrerEditionMetricsUnrankedPieSplit(detail);
|
|
1542
|
+
default: {
|
|
1543
|
+
const _exhaustiveCheck = detail;
|
|
1544
|
+
throw new Error(`Unknown type: ${_exhaustiveCheck.type}`);
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
function serializeReferrerLeaderboardPagePieSplit(page) {
|
|
1549
|
+
return {
|
|
1550
|
+
awardModel: page.awardModel,
|
|
1551
|
+
rules: serializeReferralProgramRulesPieSplit(page.rules),
|
|
1552
|
+
referrers: page.referrers.map(serializeAwardedReferrerMetricsPieSplit),
|
|
1553
|
+
aggregatedMetrics: serializeAggregatedReferrerMetricsPieSplit(page.aggregatedMetrics),
|
|
1554
|
+
pageContext: page.pageContext,
|
|
1555
|
+
status: page.status,
|
|
1556
|
+
accurateAsOf: page.accurateAsOf
|
|
1557
|
+
};
|
|
1558
|
+
}
|
|
1559
|
+
function serializeReferralProgramEditionSummaryPieSplit(summary) {
|
|
1560
|
+
return {
|
|
1561
|
+
awardModel: summary.awardModel,
|
|
1562
|
+
slug: summary.slug,
|
|
1563
|
+
displayName: summary.displayName,
|
|
1564
|
+
status: summary.status,
|
|
1565
|
+
rules: serializeReferralProgramRulesPieSplit(summary.rules)
|
|
1566
|
+
};
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
// src/award-models/rev-share-cap/api/serialize.ts
|
|
1570
|
+
function serializeReferralProgramRulesRevShareCap(rules) {
|
|
1571
|
+
return {
|
|
1572
|
+
awardModel: rules.awardModel,
|
|
1573
|
+
awardPool: serializePriceUsdc(rules.awardPool),
|
|
1574
|
+
minBaseRevenueContribution: serializePriceUsdc(rules.minBaseRevenueContribution),
|
|
1575
|
+
baseAnnualRevenueContribution: serializePriceUsdc(rules.baseAnnualRevenueContribution),
|
|
1576
|
+
maxBaseRevenueShare: rules.maxBaseRevenueShare,
|
|
1577
|
+
startTime: rules.startTime,
|
|
1578
|
+
endTime: rules.endTime,
|
|
1579
|
+
subregistryId: rules.subregistryId,
|
|
1580
|
+
rulesUrl: rules.rulesUrl.toString(),
|
|
1581
|
+
areAwardsDistributed: rules.areAwardsDistributed,
|
|
1582
|
+
adminActions: rules.adminActions
|
|
1583
|
+
};
|
|
1584
|
+
}
|
|
1585
|
+
function serializeAggregatedReferrerMetricsRevShareCap(metrics) {
|
|
1586
|
+
return {
|
|
1587
|
+
grandTotalReferrals: metrics.grandTotalReferrals,
|
|
1588
|
+
grandTotalIncrementalDuration: metrics.grandTotalIncrementalDuration,
|
|
1589
|
+
grandTotalRevenueContribution: serializePriceEth(metrics.grandTotalRevenueContribution),
|
|
1590
|
+
awardPoolRemaining: serializePriceUsdc(metrics.awardPoolRemaining)
|
|
1591
|
+
};
|
|
1592
|
+
}
|
|
1593
|
+
function serializeAwardedReferrerMetricsRevShareCap(metrics) {
|
|
1594
|
+
return {
|
|
1595
|
+
referrer: metrics.referrer,
|
|
1596
|
+
totalReferrals: metrics.totalReferrals,
|
|
1597
|
+
totalIncrementalDuration: metrics.totalIncrementalDuration,
|
|
1598
|
+
totalRevenueContribution: serializePriceEth(metrics.totalRevenueContribution),
|
|
1599
|
+
totalBaseRevenueContribution: serializePriceUsdc(metrics.totalBaseRevenueContribution),
|
|
1600
|
+
rank: metrics.rank,
|
|
1601
|
+
isQualified: metrics.isQualified,
|
|
1602
|
+
uncappedAward: serializePriceUsdc(metrics.uncappedAward),
|
|
1603
|
+
cappedAward: serializePriceUsdc(metrics.cappedAward),
|
|
1604
|
+
adminAction: metrics.adminAction
|
|
1605
|
+
};
|
|
1606
|
+
}
|
|
1607
|
+
function serializeUnrankedReferrerMetricsRevShareCap(metrics) {
|
|
1608
|
+
return {
|
|
1609
|
+
referrer: metrics.referrer,
|
|
1610
|
+
totalReferrals: metrics.totalReferrals,
|
|
1611
|
+
totalIncrementalDuration: metrics.totalIncrementalDuration,
|
|
1612
|
+
totalRevenueContribution: serializePriceEth(metrics.totalRevenueContribution),
|
|
1613
|
+
totalBaseRevenueContribution: serializePriceUsdc(metrics.totalBaseRevenueContribution),
|
|
1614
|
+
rank: metrics.rank,
|
|
1615
|
+
isQualified: metrics.isQualified,
|
|
1616
|
+
uncappedAward: serializePriceUsdc(metrics.uncappedAward),
|
|
1617
|
+
cappedAward: serializePriceUsdc(metrics.cappedAward),
|
|
1618
|
+
adminAction: metrics.adminAction
|
|
1619
|
+
};
|
|
1620
|
+
}
|
|
1621
|
+
function serializeReferrerEditionMetricsRankedRevShareCap(detail) {
|
|
1622
|
+
return {
|
|
1623
|
+
awardModel: detail.awardModel,
|
|
1624
|
+
type: detail.type,
|
|
1625
|
+
rules: serializeReferralProgramRulesRevShareCap(detail.rules),
|
|
1626
|
+
referrer: serializeAwardedReferrerMetricsRevShareCap(detail.referrer),
|
|
1627
|
+
aggregatedMetrics: serializeAggregatedReferrerMetricsRevShareCap(detail.aggregatedMetrics),
|
|
1628
|
+
status: detail.status,
|
|
1629
|
+
accurateAsOf: detail.accurateAsOf
|
|
1630
|
+
};
|
|
1631
|
+
}
|
|
1632
|
+
function serializeReferrerEditionMetricsUnrankedRevShareCap(detail) {
|
|
1633
|
+
return {
|
|
1634
|
+
awardModel: detail.awardModel,
|
|
1635
|
+
type: detail.type,
|
|
1636
|
+
rules: serializeReferralProgramRulesRevShareCap(detail.rules),
|
|
1637
|
+
referrer: serializeUnrankedReferrerMetricsRevShareCap(detail.referrer),
|
|
1638
|
+
aggregatedMetrics: serializeAggregatedReferrerMetricsRevShareCap(detail.aggregatedMetrics),
|
|
1639
|
+
status: detail.status,
|
|
1640
|
+
accurateAsOf: detail.accurateAsOf
|
|
1641
|
+
};
|
|
1642
|
+
}
|
|
1643
|
+
function serializeReferrerEditionMetricsRevShareCap(detail) {
|
|
1644
|
+
switch (detail.type) {
|
|
1645
|
+
case ReferrerEditionMetricsTypeIds.Ranked:
|
|
1646
|
+
return serializeReferrerEditionMetricsRankedRevShareCap(detail);
|
|
1647
|
+
case ReferrerEditionMetricsTypeIds.Unranked:
|
|
1648
|
+
return serializeReferrerEditionMetricsUnrankedRevShareCap(detail);
|
|
1649
|
+
default: {
|
|
1650
|
+
const _exhaustiveCheck = detail;
|
|
1651
|
+
throw new Error(
|
|
1652
|
+
`Unknown type: ${_exhaustiveCheck.type}`
|
|
1653
|
+
);
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
function serializeReferrerLeaderboardPageRevShareCap(page) {
|
|
1658
|
+
return {
|
|
1659
|
+
awardModel: page.awardModel,
|
|
1660
|
+
rules: serializeReferralProgramRulesRevShareCap(page.rules),
|
|
1661
|
+
referrers: page.referrers.map(serializeAwardedReferrerMetricsRevShareCap),
|
|
1662
|
+
aggregatedMetrics: serializeAggregatedReferrerMetricsRevShareCap(page.aggregatedMetrics),
|
|
1663
|
+
pageContext: page.pageContext,
|
|
1664
|
+
status: page.status,
|
|
1665
|
+
accurateAsOf: page.accurateAsOf
|
|
1666
|
+
};
|
|
1667
|
+
}
|
|
1668
|
+
function serializeReferralProgramEditionSummaryRevShareCap(summary) {
|
|
1669
|
+
return {
|
|
1670
|
+
awardModel: summary.awardModel,
|
|
1671
|
+
slug: summary.slug,
|
|
1672
|
+
displayName: summary.displayName,
|
|
1673
|
+
status: summary.status,
|
|
1674
|
+
rules: serializeReferralProgramRulesRevShareCap(summary.rules),
|
|
1675
|
+
awardPoolRemaining: serializePriceUsdc(summary.awardPoolRemaining)
|
|
1676
|
+
};
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
// src/api/serialize.ts
|
|
1680
|
+
function serializeReferralProgramRules(rules) {
|
|
1681
|
+
switch (rules.awardModel) {
|
|
1682
|
+
case ReferralProgramAwardModels.PieSplit:
|
|
1683
|
+
return serializeReferralProgramRulesPieSplit(rules);
|
|
1684
|
+
case ReferralProgramAwardModels.RevShareCap:
|
|
1685
|
+
return serializeReferralProgramRulesRevShareCap(rules);
|
|
1686
|
+
case ReferralProgramAwardModels.Unrecognized: {
|
|
1687
|
+
const unrecognized = rules;
|
|
1688
|
+
throw new Error(
|
|
1689
|
+
`ReferralProgramRulesUnrecognized (originalAwardModel: '${unrecognized.originalAwardModel}') must not be serialized \u2014 it is a client-side forward-compatibility placeholder only.`
|
|
1690
|
+
);
|
|
1691
|
+
}
|
|
1692
|
+
default: {
|
|
1693
|
+
const _exhaustiveCheck = rules;
|
|
1694
|
+
throw new Error(
|
|
1695
|
+
`Unknown award model: ${_exhaustiveCheck.awardModel}`
|
|
1696
|
+
);
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
function serializeReferrerLeaderboardPage(page) {
|
|
1701
|
+
switch (page.awardModel) {
|
|
1702
|
+
case ReferralProgramAwardModels.PieSplit:
|
|
1703
|
+
return serializeReferrerLeaderboardPagePieSplit(page);
|
|
1704
|
+
case ReferralProgramAwardModels.RevShareCap:
|
|
1705
|
+
return serializeReferrerLeaderboardPageRevShareCap(page);
|
|
1706
|
+
case ReferralProgramAwardModels.Unrecognized: {
|
|
1707
|
+
const unrecognized = page;
|
|
1708
|
+
throw new Error(
|
|
1709
|
+
`ReferrerLeaderboardPageUnrecognized (originalAwardModel: '${unrecognized.originalAwardModel}') must not be serialized \u2014 it is a client-side forward-compatibility placeholder only.`
|
|
1710
|
+
);
|
|
1711
|
+
}
|
|
1712
|
+
default: {
|
|
1713
|
+
const _exhaustiveCheck = page;
|
|
1714
|
+
throw new Error(
|
|
1715
|
+
`Unknown award model: ${_exhaustiveCheck.awardModel}`
|
|
1716
|
+
);
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
function serializeReferrerEditionMetrics(detail) {
|
|
1721
|
+
switch (detail.awardModel) {
|
|
1722
|
+
case ReferralProgramAwardModels.PieSplit:
|
|
1723
|
+
return serializeReferrerEditionMetricsPieSplit(detail);
|
|
1724
|
+
case ReferralProgramAwardModels.RevShareCap:
|
|
1725
|
+
return serializeReferrerEditionMetricsRevShareCap(detail);
|
|
1726
|
+
case ReferralProgramAwardModels.Unrecognized: {
|
|
1727
|
+
const unrecognized = detail;
|
|
1728
|
+
throw new Error(
|
|
1729
|
+
`ReferrerEditionMetricsUnrecognized (originalAwardModel: '${unrecognized.originalAwardModel}') must not be serialized \u2014 it is a client-side forward-compatibility placeholder only.`
|
|
1730
|
+
);
|
|
1731
|
+
}
|
|
1732
|
+
default: {
|
|
1733
|
+
const _exhaustiveCheck = detail;
|
|
1734
|
+
throw new Error(
|
|
1735
|
+
`Unknown award model: ${_exhaustiveCheck.awardModel}`
|
|
1736
|
+
);
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
function serializeReferralProgramEditionSummary(summary) {
|
|
1741
|
+
switch (summary.awardModel) {
|
|
1742
|
+
case ReferralProgramAwardModels.PieSplit:
|
|
1743
|
+
return serializeReferralProgramEditionSummaryPieSplit(summary);
|
|
1744
|
+
case ReferralProgramAwardModels.RevShareCap:
|
|
1745
|
+
return serializeReferralProgramEditionSummaryRevShareCap(summary);
|
|
1746
|
+
case ReferralProgramAwardModels.Unrecognized: {
|
|
1747
|
+
const unrecognized = summary;
|
|
1748
|
+
throw new Error(
|
|
1749
|
+
`ReferralProgramEditionSummaryUnrecognized (originalAwardModel: '${unrecognized.rules.originalAwardModel}') must not be serialized \u2014 it is a client-side forward-compatibility placeholder only.`
|
|
1750
|
+
);
|
|
1751
|
+
}
|
|
1752
|
+
default: {
|
|
1753
|
+
const _exhaustiveCheck = summary;
|
|
1754
|
+
throw new Error(
|
|
1755
|
+
`Unknown award model: ${_exhaustiveCheck.awardModel}`
|
|
1756
|
+
);
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
function serializeReferrerLeaderboardPageResponse(response) {
|
|
1761
|
+
switch (response.responseCode) {
|
|
1762
|
+
case ReferrerLeaderboardPageResponseCodes.Ok:
|
|
1763
|
+
return {
|
|
1764
|
+
responseCode: response.responseCode,
|
|
1765
|
+
data: serializeReferrerLeaderboardPage(response.data)
|
|
1766
|
+
};
|
|
1767
|
+
case ReferrerLeaderboardPageResponseCodes.Error:
|
|
1768
|
+
return response;
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
function serializeReferrerMetricsEditionsResponse(response) {
|
|
1772
|
+
switch (response.responseCode) {
|
|
1773
|
+
case ReferrerMetricsEditionsResponseCodes.Ok: {
|
|
1774
|
+
const serializedData = Object.fromEntries(
|
|
1775
|
+
Object.entries(response.data).map(([editionSlug, detail]) => [
|
|
1776
|
+
editionSlug,
|
|
1777
|
+
serializeReferrerEditionMetrics(detail)
|
|
1778
|
+
])
|
|
1779
|
+
);
|
|
1780
|
+
return {
|
|
1781
|
+
responseCode: response.responseCode,
|
|
1782
|
+
data: serializedData
|
|
1783
|
+
};
|
|
1784
|
+
}
|
|
1785
|
+
case ReferrerMetricsEditionsResponseCodes.Error:
|
|
1786
|
+
return response;
|
|
1787
|
+
default: {
|
|
1788
|
+
const _exhaustiveCheck = response;
|
|
1789
|
+
throw new Error(
|
|
1790
|
+
`Unknown response code: ${_exhaustiveCheck.responseCode}`
|
|
1791
|
+
);
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
function serializeReferralProgramEditionSummariesResponse(response) {
|
|
1796
|
+
switch (response.responseCode) {
|
|
1797
|
+
case ReferralProgramEditionSummariesResponseCodes.Ok:
|
|
1798
|
+
return {
|
|
1799
|
+
responseCode: response.responseCode,
|
|
1800
|
+
data: {
|
|
1801
|
+
editions: response.data.editions.map(serializeReferralProgramEditionSummary)
|
|
1802
|
+
}
|
|
1803
|
+
};
|
|
1804
|
+
case ReferralProgramEditionSummariesResponseCodes.Error:
|
|
1805
|
+
return response;
|
|
1806
|
+
default: {
|
|
1807
|
+
const _exhaustiveCheck = response;
|
|
1808
|
+
throw new Error(
|
|
1809
|
+
`Unknown response code: ${_exhaustiveCheck.responseCode}`
|
|
1810
|
+
);
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
// src/award-models/shared/score.ts
|
|
1816
|
+
var isValidReferrerScore = (score) => {
|
|
1817
|
+
return score >= 0 && Number.isFinite(score);
|
|
1818
|
+
};
|
|
1819
|
+
var validateReferrerScore = (score) => {
|
|
1820
|
+
if (!isValidReferrerScore(score)) {
|
|
1821
|
+
throw new Error(
|
|
1822
|
+
`Invalid referrer score: ${score}. Referrer score must be a finite non-negative number.`
|
|
1823
|
+
);
|
|
1824
|
+
}
|
|
1825
|
+
};
|
|
1826
|
+
|
|
1827
|
+
// src/award-models/pie-split/aggregations.ts
|
|
1828
|
+
var validateAggregatedReferrerMetricsPieSplit = (metrics) => {
|
|
1829
|
+
validateNonNegativeInteger(metrics.grandTotalReferrals);
|
|
1830
|
+
validateDuration(metrics.grandTotalIncrementalDuration);
|
|
1831
|
+
makePriceEthSchema("AggregatedReferrerMetricsPieSplit.grandTotalRevenueContribution").parse(
|
|
1832
|
+
metrics.grandTotalRevenueContribution
|
|
1833
|
+
);
|
|
1834
|
+
validateReferrerScore(metrics.grandTotalQualifiedReferrersFinalScore);
|
|
1835
|
+
validateReferrerScore(metrics.minFinalScoreToQualify);
|
|
1836
|
+
};
|
|
1837
|
+
var buildAggregatedReferrerMetricsPieSplit = (referrers, rules) => {
|
|
1838
|
+
let grandTotalReferrals = 0;
|
|
1839
|
+
let grandTotalIncrementalDuration = 0;
|
|
1840
|
+
let grandTotalRevenueContributionAmount = 0n;
|
|
1841
|
+
let grandTotalQualifiedReferrersFinalScore = 0;
|
|
1842
|
+
let minFinalScoreToQualify = Number.MAX_SAFE_INTEGER;
|
|
1843
|
+
for (const referrer of referrers) {
|
|
1844
|
+
grandTotalReferrals += referrer.totalReferrals;
|
|
1845
|
+
grandTotalIncrementalDuration += referrer.totalIncrementalDuration;
|
|
1846
|
+
grandTotalRevenueContributionAmount += referrer.totalRevenueContribution.amount;
|
|
1847
|
+
if (referrer.isQualified) {
|
|
1848
|
+
grandTotalQualifiedReferrersFinalScore += referrer.finalScore;
|
|
1849
|
+
if (referrer.finalScore < minFinalScoreToQualify) {
|
|
1850
|
+
minFinalScoreToQualify = referrer.finalScore;
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
if (minFinalScoreToQualify === Number.MAX_SAFE_INTEGER) {
|
|
1855
|
+
if (rules.maxQualifiedReferrers === 0) {
|
|
1856
|
+
} else {
|
|
1857
|
+
if (referrers.length !== 0) {
|
|
1858
|
+
throw new Error(
|
|
1859
|
+
"AggregatedReferrerMetricsPieSplit: There are referrers on the leaderboard, and the rules allow for qualified referrers, but no qualified referrers."
|
|
1860
|
+
);
|
|
1861
|
+
}
|
|
1862
|
+
minFinalScoreToQualify = 0;
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
const result = {
|
|
1866
|
+
grandTotalReferrals,
|
|
1867
|
+
grandTotalIncrementalDuration,
|
|
1868
|
+
grandTotalRevenueContribution: priceEth(grandTotalRevenueContributionAmount),
|
|
1869
|
+
grandTotalQualifiedReferrersFinalScore,
|
|
1870
|
+
minFinalScoreToQualify
|
|
1871
|
+
};
|
|
1872
|
+
validateAggregatedReferrerMetricsPieSplit(result);
|
|
1873
|
+
return result;
|
|
1874
|
+
};
|
|
1875
|
+
|
|
1876
|
+
// src/edition.ts
|
|
1877
|
+
var REFERRAL_PROGRAM_EDITION_SLUG_PATTERN = /^[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
1878
|
+
function validateReferralProgramEditionConfigSet(configSet) {
|
|
1879
|
+
const violation = Array.from(configSet.entries()).find(([key, config]) => key !== config.slug);
|
|
1880
|
+
if (violation) {
|
|
1881
|
+
const [key, config] = violation;
|
|
1882
|
+
throw new Error(
|
|
1883
|
+
`Edition config set invariant violation: map key "${key}" does not match config.slug "${config.slug}"`
|
|
1884
|
+
);
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
function buildReferralProgramEditionConfigSet(configs) {
|
|
1888
|
+
const slugCounts = configs.reduce((counts, config) => {
|
|
1889
|
+
counts.set(config.slug, (counts.get(config.slug) || 0) + 1);
|
|
1890
|
+
return counts;
|
|
1891
|
+
}, /* @__PURE__ */ new Map());
|
|
1892
|
+
const duplicates = Array.from(slugCounts.entries()).filter(([_, count]) => count > 1).map(([slug, count]) => `"${slug}" (${count} occurrences)`);
|
|
1893
|
+
if (duplicates.length > 0) {
|
|
1894
|
+
throw new Error(`Duplicate edition config slugs detected: ${duplicates.join(", ")}`);
|
|
1895
|
+
}
|
|
1896
|
+
const configSet = new Map(configs.map((config) => [config.slug, config]));
|
|
1897
|
+
validateReferralProgramEditionConfigSet(configSet);
|
|
1898
|
+
return configSet;
|
|
1899
|
+
}
|
|
1900
|
+
|
|
1901
|
+
// src/award-models/shared/edition-summary.ts
|
|
1902
|
+
var validateBaseReferralProgramEditionSummary = (summary) => {
|
|
1903
|
+
if (!REFERRAL_PROGRAM_EDITION_SLUG_PATTERN.test(summary.slug)) {
|
|
1904
|
+
throw new Error(
|
|
1905
|
+
`BaseReferralProgramEditionSummary: slug "${summary.slug}" does not match required pattern ${REFERRAL_PROGRAM_EDITION_SLUG_PATTERN}.`
|
|
1906
|
+
);
|
|
1907
|
+
}
|
|
1908
|
+
if (summary.displayName.length === 0) {
|
|
1909
|
+
throw new Error("BaseReferralProgramEditionSummary: displayName must not be empty.");
|
|
1910
|
+
}
|
|
1911
|
+
if (summary.awardModel !== summary.rules.awardModel) {
|
|
1912
|
+
throw new Error(
|
|
1913
|
+
`BaseReferralProgramEditionSummary: awardModel (${summary.awardModel}) must equal rules.awardModel (${summary.rules.awardModel}).`
|
|
1914
|
+
);
|
|
1915
|
+
}
|
|
1916
|
+
};
|
|
1917
|
+
|
|
1918
|
+
// src/award-models/pie-split/rules.ts
|
|
1919
|
+
var validateReferralProgramRulesPieSplit = (rules) => {
|
|
1920
|
+
makePriceUsdcSchema("ReferralProgramRulesPieSplit.awardPool").parse(rules.awardPool);
|
|
1921
|
+
validateNonNegativeInteger(rules.maxQualifiedReferrers);
|
|
1922
|
+
validateBaseReferralProgramRules(rules);
|
|
1923
|
+
};
|
|
1924
|
+
var buildReferralProgramRulesPieSplit = (awardPool, maxQualifiedReferrers, startTime, endTime, subregistryId, rulesUrl, areAwardsDistributed) => {
|
|
1925
|
+
const result = {
|
|
1926
|
+
awardModel: ReferralProgramAwardModels.PieSplit,
|
|
1927
|
+
awardPool,
|
|
1928
|
+
maxQualifiedReferrers,
|
|
1929
|
+
startTime,
|
|
1930
|
+
endTime,
|
|
1931
|
+
subregistryId,
|
|
1932
|
+
rulesUrl,
|
|
1933
|
+
areAwardsDistributed
|
|
1934
|
+
};
|
|
1935
|
+
validateReferralProgramRulesPieSplit(result);
|
|
1936
|
+
return result;
|
|
1937
|
+
};
|
|
1938
|
+
|
|
1939
|
+
// src/award-models/pie-split/status.ts
|
|
1940
|
+
var calcReferralProgramEditionStatusPieSplit = (rules, now) => calcBaseReferralProgramEditionStatus(rules, now);
|
|
1941
|
+
|
|
1942
|
+
// src/award-models/pie-split/edition-summary.ts
|
|
1943
|
+
var validateEditionSummaryPieSplit = (summary) => {
|
|
1944
|
+
validateReferralProgramRulesPieSplit(summary.rules);
|
|
1945
|
+
validateBaseReferralProgramEditionSummary(summary);
|
|
1946
|
+
};
|
|
1947
|
+
function buildEditionSummaryPieSplit(slug, displayName, rules, leaderboard) {
|
|
1948
|
+
const status = calcReferralProgramEditionStatusPieSplit(rules, leaderboard.accurateAsOf);
|
|
1949
|
+
const result = { awardModel: rules.awardModel, slug, displayName, status, rules };
|
|
1950
|
+
validateEditionSummaryPieSplit(result);
|
|
1951
|
+
return result;
|
|
1952
|
+
}
|
|
1953
|
+
|
|
1954
|
+
// src/award-models/shared/leaderboard-guards.ts
|
|
1955
|
+
var assertLeaderboardInputs = (allReferrers, rules, accurateAsOf) => {
|
|
1956
|
+
const uniqueReferrers = new Set(allReferrers.map((r) => r.referrer));
|
|
1957
|
+
if (uniqueReferrers.size !== allReferrers.length) {
|
|
1958
|
+
throw new Error(
|
|
1959
|
+
"ReferrerLeaderboard: Cannot build a leaderboard containing duplicate referrers"
|
|
1960
|
+
);
|
|
1961
|
+
}
|
|
1962
|
+
if (accurateAsOf < rules.startTime && allReferrers.length > 0) {
|
|
1963
|
+
throw new Error(
|
|
1964
|
+
`ReferrerLeaderboard: accurateAsOf (${accurateAsOf}) is before startTime (${rules.startTime}) which indicates allReferrers should be empty, but allReferrers is not empty.`
|
|
1965
|
+
);
|
|
1966
|
+
}
|
|
1967
|
+
};
|
|
1968
|
+
|
|
1969
|
+
// src/award-models/shared/rank.ts
|
|
1970
|
+
var validateReferrerRank = (rank) => {
|
|
1971
|
+
if (!isPositiveInteger(rank)) {
|
|
1972
|
+
throw new Error(`Invalid ReferrerRank: ${rank}. ReferrerRank must be a positive integer.`);
|
|
1973
|
+
}
|
|
1974
|
+
};
|
|
1975
|
+
var compareReferrerMetrics = (a, b) => {
|
|
1976
|
+
if (a.totalIncrementalDuration !== b.totalIncrementalDuration) {
|
|
1977
|
+
return b.totalIncrementalDuration - a.totalIncrementalDuration;
|
|
1978
|
+
}
|
|
1979
|
+
if (b.referrer > a.referrer) return 1;
|
|
1980
|
+
if (b.referrer < a.referrer) return -1;
|
|
1981
|
+
return 0;
|
|
1982
|
+
};
|
|
1983
|
+
var sortReferrerMetrics = (referrers) => {
|
|
1984
|
+
return [...referrers].sort(compareReferrerMetrics);
|
|
1985
|
+
};
|
|
1986
|
+
|
|
1987
|
+
// src/referrer-metrics.ts
|
|
1988
|
+
var buildReferrerMetrics = (referrer, totalReferrals, totalIncrementalDuration, totalRevenueContribution) => {
|
|
1989
|
+
const result = {
|
|
1990
|
+
referrer,
|
|
1991
|
+
totalReferrals,
|
|
622
1992
|
totalIncrementalDuration,
|
|
623
1993
|
totalRevenueContribution
|
|
624
1994
|
};
|
|
@@ -626,153 +1996,189 @@ var buildReferrerMetrics = (referrer, totalReferrals, totalIncrementalDuration,
|
|
|
626
1996
|
return result;
|
|
627
1997
|
};
|
|
628
1998
|
var validateReferrerMetrics = (metrics) => {
|
|
629
|
-
|
|
1999
|
+
validateNormalizedAddress(metrics.referrer);
|
|
630
2000
|
validateNonNegativeInteger(metrics.totalReferrals);
|
|
631
2001
|
validateDuration(metrics.totalIncrementalDuration);
|
|
632
|
-
|
|
2002
|
+
makePriceEthSchema("ReferrerMetrics.totalRevenueContribution").parse(
|
|
2003
|
+
metrics.totalRevenueContribution
|
|
2004
|
+
);
|
|
633
2005
|
};
|
|
634
|
-
|
|
635
|
-
|
|
2006
|
+
|
|
2007
|
+
// src/award-models/pie-split/score.ts
|
|
2008
|
+
var calcReferrerScorePieSplit = (totalIncrementalDuration) => {
|
|
2009
|
+
return totalIncrementalDuration / SECONDS_PER_YEAR;
|
|
636
2010
|
};
|
|
637
|
-
|
|
2011
|
+
|
|
2012
|
+
// src/award-models/pie-split/rank.ts
|
|
2013
|
+
function isReferrerQualifiedPieSplit(rank, rules) {
|
|
2014
|
+
return rank <= rules.maxQualifiedReferrers;
|
|
2015
|
+
}
|
|
2016
|
+
function calcReferrerFinalScoreBoostPieSplit(rank, rules) {
|
|
2017
|
+
if (!isReferrerQualifiedPieSplit(rank, rules)) return 0;
|
|
2018
|
+
if (rules.maxQualifiedReferrers === 1) return 1;
|
|
2019
|
+
return 1 - (rank - 1) / (rules.maxQualifiedReferrers - 1);
|
|
2020
|
+
}
|
|
2021
|
+
function calcReferrerFinalScoreMultiplierPieSplit(rank, rules) {
|
|
2022
|
+
return 1 + calcReferrerFinalScoreBoostPieSplit(rank, rules);
|
|
2023
|
+
}
|
|
2024
|
+
function calcReferrerFinalScorePieSplit(rank, totalIncrementalDuration, rules) {
|
|
2025
|
+
return calcReferrerScorePieSplit(totalIncrementalDuration) * calcReferrerFinalScoreMultiplierPieSplit(rank, rules);
|
|
2026
|
+
}
|
|
2027
|
+
|
|
2028
|
+
// src/award-models/pie-split/metrics.ts
|
|
2029
|
+
var buildScoredReferrerMetricsPieSplit = (referrer) => {
|
|
638
2030
|
const result = {
|
|
639
2031
|
...referrer,
|
|
640
|
-
score:
|
|
2032
|
+
score: calcReferrerScorePieSplit(referrer.totalIncrementalDuration)
|
|
641
2033
|
};
|
|
642
|
-
|
|
2034
|
+
validateScoredReferrerMetricsPieSplit(result);
|
|
643
2035
|
return result;
|
|
644
2036
|
};
|
|
645
|
-
var
|
|
2037
|
+
var validateScoredReferrerMetricsPieSplit = (metrics) => {
|
|
646
2038
|
validateReferrerMetrics(metrics);
|
|
647
2039
|
validateReferrerScore(metrics.score);
|
|
648
|
-
const expectedScore =
|
|
2040
|
+
const expectedScore = calcReferrerScorePieSplit(metrics.totalIncrementalDuration);
|
|
649
2041
|
if (metrics.score !== expectedScore) {
|
|
650
2042
|
throw new Error(`Referrer: Invalid score: ${metrics.score}, expected: ${expectedScore}.`);
|
|
651
2043
|
}
|
|
652
2044
|
};
|
|
653
|
-
var
|
|
654
|
-
|
|
2045
|
+
var validateRankedReferrerMetricsPieSplit = (metrics, rules) => {
|
|
2046
|
+
validateScoredReferrerMetricsPieSplit(metrics);
|
|
655
2047
|
validateReferrerRank(metrics.rank);
|
|
656
2048
|
if (metrics.finalScoreBoost < 0 || metrics.finalScoreBoost > 1) {
|
|
657
2049
|
throw new Error(
|
|
658
|
-
`Invalid
|
|
2050
|
+
`Invalid RankedReferrerMetricsPieSplit: Invalid finalScoreBoost: ${metrics.finalScoreBoost}. finalScoreBoost must be between 0 and 1 (inclusive).`
|
|
659
2051
|
);
|
|
660
2052
|
}
|
|
661
2053
|
validateReferrerScore(metrics.finalScore);
|
|
662
|
-
const expectedIsQualified =
|
|
2054
|
+
const expectedIsQualified = isReferrerQualifiedPieSplit(metrics.rank, rules);
|
|
663
2055
|
if (metrics.isQualified !== expectedIsQualified) {
|
|
664
2056
|
throw new Error(
|
|
665
|
-
`
|
|
2057
|
+
`RankedReferrerMetricsPieSplit: Invalid isQualified: ${metrics.isQualified}, expected: ${expectedIsQualified}.`
|
|
666
2058
|
);
|
|
667
2059
|
}
|
|
668
|
-
const expectedFinalScoreBoost =
|
|
2060
|
+
const expectedFinalScoreBoost = calcReferrerFinalScoreBoostPieSplit(metrics.rank, rules);
|
|
669
2061
|
if (metrics.finalScoreBoost !== expectedFinalScoreBoost) {
|
|
670
2062
|
throw new Error(
|
|
671
|
-
`
|
|
2063
|
+
`RankedReferrerMetricsPieSplit: Invalid finalScoreBoost: ${metrics.finalScoreBoost}, expected: ${expectedFinalScoreBoost}.`
|
|
672
2064
|
);
|
|
673
2065
|
}
|
|
674
|
-
const expectedFinalScore =
|
|
2066
|
+
const expectedFinalScore = calcReferrerFinalScorePieSplit(
|
|
675
2067
|
metrics.rank,
|
|
676
2068
|
metrics.totalIncrementalDuration,
|
|
677
2069
|
rules
|
|
678
2070
|
);
|
|
679
2071
|
if (metrics.finalScore !== expectedFinalScore) {
|
|
680
2072
|
throw new Error(
|
|
681
|
-
`
|
|
2073
|
+
`RankedReferrerMetricsPieSplit: Invalid finalScore: ${metrics.finalScore}, expected: ${expectedFinalScore}.`
|
|
682
2074
|
);
|
|
683
2075
|
}
|
|
684
2076
|
};
|
|
685
|
-
var
|
|
2077
|
+
var buildRankedReferrerMetricsPieSplit = (referrer, rank, rules) => {
|
|
686
2078
|
const result = {
|
|
687
2079
|
...referrer,
|
|
688
2080
|
rank,
|
|
689
|
-
isQualified:
|
|
690
|
-
finalScoreBoost:
|
|
691
|
-
finalScore:
|
|
2081
|
+
isQualified: isReferrerQualifiedPieSplit(rank, rules),
|
|
2082
|
+
finalScoreBoost: calcReferrerFinalScoreBoostPieSplit(rank, rules),
|
|
2083
|
+
finalScore: calcReferrerFinalScorePieSplit(rank, referrer.totalIncrementalDuration, rules)
|
|
692
2084
|
};
|
|
693
|
-
|
|
2085
|
+
validateRankedReferrerMetricsPieSplit(result, rules);
|
|
694
2086
|
return result;
|
|
695
2087
|
};
|
|
696
|
-
var
|
|
697
|
-
if (!
|
|
2088
|
+
var calcReferrerAwardPoolSharePieSplit = (referrer, aggregatedMetrics) => {
|
|
2089
|
+
if (!referrer.isQualified) return 0;
|
|
698
2090
|
if (aggregatedMetrics.grandTotalQualifiedReferrersFinalScore === 0) return 0;
|
|
699
|
-
return
|
|
2091
|
+
return referrer.finalScore / aggregatedMetrics.grandTotalQualifiedReferrersFinalScore;
|
|
700
2092
|
};
|
|
701
|
-
var
|
|
702
|
-
|
|
2093
|
+
var validateAwardedReferrerMetricsPieSplit = (referrer, rules) => {
|
|
2094
|
+
validateRankedReferrerMetricsPieSplit(referrer, rules);
|
|
703
2095
|
if (referrer.awardPoolShare < 0 || referrer.awardPoolShare > 1) {
|
|
704
2096
|
throw new Error(
|
|
705
|
-
`Invalid
|
|
2097
|
+
`Invalid AwardedReferrerMetricsPieSplit: ${referrer.awardPoolShare}. awardPoolShare must be between 0 and 1 (inclusive).`
|
|
706
2098
|
);
|
|
707
2099
|
}
|
|
708
|
-
|
|
2100
|
+
makePriceUsdcSchema("AwardedReferrerMetricsPieSplit.awardPoolApproxValue").parse(
|
|
2101
|
+
referrer.awardPoolApproxValue
|
|
2102
|
+
);
|
|
2103
|
+
if (referrer.awardPoolApproxValue.amount > rules.awardPool.amount) {
|
|
709
2104
|
throw new Error(
|
|
710
|
-
`
|
|
2105
|
+
`AwardedReferrerMetricsPieSplit: awardPoolApproxValue.amount ${referrer.awardPoolApproxValue.amount.toString()} exceeds awardPool.amount ${rules.awardPool.amount.toString()}.`
|
|
711
2106
|
);
|
|
712
2107
|
}
|
|
713
2108
|
};
|
|
714
|
-
var
|
|
715
|
-
const awardPoolShare =
|
|
2109
|
+
var buildAwardedReferrerMetricsPieSplit = (referrer, aggregatedMetrics, rules) => {
|
|
2110
|
+
const awardPoolShare = calcReferrerAwardPoolSharePieSplit(referrer, aggregatedMetrics);
|
|
2111
|
+
const awardPoolApproxValue = scalePrice(rules.awardPool, awardPoolShare);
|
|
716
2112
|
const result = {
|
|
717
2113
|
...referrer,
|
|
718
2114
|
awardPoolShare,
|
|
719
|
-
awardPoolApproxValue
|
|
2115
|
+
awardPoolApproxValue
|
|
720
2116
|
};
|
|
721
|
-
|
|
2117
|
+
validateAwardedReferrerMetricsPieSplit(result, rules);
|
|
722
2118
|
return result;
|
|
723
2119
|
};
|
|
724
|
-
var
|
|
725
|
-
|
|
2120
|
+
var validateUnrankedReferrerMetricsPieSplit = (metrics) => {
|
|
2121
|
+
validateScoredReferrerMetricsPieSplit(metrics);
|
|
726
2122
|
if (metrics.rank !== null) {
|
|
727
|
-
throw new Error(
|
|
2123
|
+
throw new Error(
|
|
2124
|
+
`Invalid UnrankedReferrerMetricsPieSplit: rank must be null, got: ${metrics.rank}.`
|
|
2125
|
+
);
|
|
728
2126
|
}
|
|
729
2127
|
if (metrics.isQualified !== false) {
|
|
730
2128
|
throw new Error(
|
|
731
|
-
`Invalid
|
|
2129
|
+
`Invalid UnrankedReferrerMetricsPieSplit: isQualified must be false, got: ${metrics.isQualified}.`
|
|
732
2130
|
);
|
|
733
2131
|
}
|
|
734
2132
|
if (metrics.totalReferrals !== 0) {
|
|
735
2133
|
throw new Error(
|
|
736
|
-
`Invalid
|
|
2134
|
+
`Invalid UnrankedReferrerMetricsPieSplit: totalReferrals must be 0, got: ${metrics.totalReferrals}.`
|
|
737
2135
|
);
|
|
738
2136
|
}
|
|
739
2137
|
if (metrics.totalIncrementalDuration !== 0) {
|
|
740
2138
|
throw new Error(
|
|
741
|
-
`Invalid
|
|
2139
|
+
`Invalid UnrankedReferrerMetricsPieSplit: totalIncrementalDuration must be 0, got: ${metrics.totalIncrementalDuration}.`
|
|
742
2140
|
);
|
|
743
2141
|
}
|
|
744
|
-
|
|
2142
|
+
makePriceEthSchema("UnrankedReferrerMetricsPieSplit.totalRevenueContribution").parse(
|
|
2143
|
+
metrics.totalRevenueContribution
|
|
2144
|
+
);
|
|
2145
|
+
if (metrics.totalRevenueContribution.amount !== 0n) {
|
|
745
2146
|
throw new Error(
|
|
746
|
-
`Invalid
|
|
2147
|
+
`Invalid UnrankedReferrerMetricsPieSplit: totalRevenueContribution.amount must be 0n, got: ${metrics.totalRevenueContribution.amount.toString()}.`
|
|
747
2148
|
);
|
|
748
2149
|
}
|
|
749
2150
|
if (metrics.score !== 0) {
|
|
750
|
-
throw new Error(
|
|
2151
|
+
throw new Error(
|
|
2152
|
+
`Invalid UnrankedReferrerMetricsPieSplit: score must be 0, got: ${metrics.score}.`
|
|
2153
|
+
);
|
|
751
2154
|
}
|
|
752
2155
|
if (metrics.finalScoreBoost !== 0) {
|
|
753
2156
|
throw new Error(
|
|
754
|
-
`Invalid
|
|
2157
|
+
`Invalid UnrankedReferrerMetricsPieSplit: finalScoreBoost must be 0, got: ${metrics.finalScoreBoost}.`
|
|
755
2158
|
);
|
|
756
2159
|
}
|
|
757
2160
|
if (metrics.finalScore !== 0) {
|
|
758
2161
|
throw new Error(
|
|
759
|
-
`Invalid
|
|
2162
|
+
`Invalid UnrankedReferrerMetricsPieSplit: finalScore must be 0, got: ${metrics.finalScore}.`
|
|
760
2163
|
);
|
|
761
2164
|
}
|
|
762
2165
|
if (metrics.awardPoolShare !== 0) {
|
|
763
2166
|
throw new Error(
|
|
764
|
-
`Invalid
|
|
2167
|
+
`Invalid UnrankedReferrerMetricsPieSplit: awardPoolShare must be 0, got: ${metrics.awardPoolShare}.`
|
|
765
2168
|
);
|
|
766
2169
|
}
|
|
767
|
-
|
|
2170
|
+
makePriceUsdcSchema("UnrankedReferrerMetricsPieSplit.awardPoolApproxValue").parse(
|
|
2171
|
+
metrics.awardPoolApproxValue
|
|
2172
|
+
);
|
|
2173
|
+
if (metrics.awardPoolApproxValue.amount !== 0n) {
|
|
768
2174
|
throw new Error(
|
|
769
|
-
`Invalid
|
|
2175
|
+
`Invalid UnrankedReferrerMetricsPieSplit: awardPoolApproxValue must be 0n, got: ${metrics.awardPoolApproxValue.amount.toString()}.`
|
|
770
2176
|
);
|
|
771
2177
|
}
|
|
772
2178
|
};
|
|
773
|
-
var
|
|
774
|
-
const
|
|
775
|
-
const scoredMetrics =
|
|
2179
|
+
var buildUnrankedReferrerMetricsPieSplit = (referrer) => {
|
|
2180
|
+
const metrics = buildReferrerMetrics(referrer, 0, 0, priceEth(0n));
|
|
2181
|
+
const scoredMetrics = buildScoredReferrerMetricsPieSplit(metrics);
|
|
776
2182
|
const result = {
|
|
777
2183
|
...scoredMetrics,
|
|
778
2184
|
rank: null,
|
|
@@ -780,438 +2186,409 @@ var buildUnrankedReferrerMetrics = (referrer) => {
|
|
|
780
2186
|
finalScoreBoost: 0,
|
|
781
2187
|
finalScore: 0,
|
|
782
2188
|
awardPoolShare: 0,
|
|
783
|
-
awardPoolApproxValue:
|
|
2189
|
+
awardPoolApproxValue: priceUsdc(0n)
|
|
784
2190
|
};
|
|
785
|
-
|
|
2191
|
+
validateUnrankedReferrerMetricsPieSplit(result);
|
|
786
2192
|
return result;
|
|
787
2193
|
};
|
|
788
2194
|
|
|
789
|
-
// src/
|
|
790
|
-
var
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
2195
|
+
// src/award-models/pie-split/leaderboard.ts
|
|
2196
|
+
var buildReferrerLeaderboardPieSplit = (allReferrers, rules, accurateAsOf) => {
|
|
2197
|
+
assertLeaderboardInputs(allReferrers, rules, accurateAsOf);
|
|
2198
|
+
const sortedReferrers = sortReferrerMetrics(allReferrers);
|
|
2199
|
+
const scoredReferrers = sortedReferrers.map((r) => buildScoredReferrerMetricsPieSplit(r));
|
|
2200
|
+
const rankedReferrers = scoredReferrers.map(
|
|
2201
|
+
(r, index) => buildRankedReferrerMetricsPieSplit(r, index + 1, rules)
|
|
2202
|
+
);
|
|
2203
|
+
const aggregatedMetrics = buildAggregatedReferrerMetricsPieSplit(rankedReferrers, rules);
|
|
2204
|
+
const awardedReferrers = rankedReferrers.map(
|
|
2205
|
+
(r) => buildAwardedReferrerMetricsPieSplit(r, aggregatedMetrics, rules)
|
|
2206
|
+
);
|
|
2207
|
+
const referrers = new Map(awardedReferrers.map((r) => [r.referrer, r]));
|
|
2208
|
+
return { awardModel: rules.awardModel, rules, aggregatedMetrics, referrers, accurateAsOf };
|
|
799
2209
|
};
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
aggregatedMetrics: leaderboard.aggregatedMetrics,
|
|
808
|
-
accurateAsOf: leaderboard.accurateAsOf
|
|
809
|
-
};
|
|
810
|
-
}
|
|
2210
|
+
|
|
2211
|
+
// src/award-models/pie-split/leaderboard-page.ts
|
|
2212
|
+
function buildLeaderboardPagePieSplit(pageContext, leaderboard) {
|
|
2213
|
+
const status = calcReferralProgramEditionStatusPieSplit(
|
|
2214
|
+
leaderboard.rules,
|
|
2215
|
+
leaderboard.accurateAsOf
|
|
2216
|
+
);
|
|
811
2217
|
return {
|
|
812
|
-
|
|
2218
|
+
awardModel: leaderboard.awardModel,
|
|
813
2219
|
rules: leaderboard.rules,
|
|
814
|
-
|
|
2220
|
+
referrers: sliceReferrers(leaderboard.referrers, pageContext),
|
|
815
2221
|
aggregatedMetrics: leaderboard.aggregatedMetrics,
|
|
2222
|
+
pageContext,
|
|
2223
|
+
status,
|
|
816
2224
|
accurateAsOf: leaderboard.accurateAsOf
|
|
817
2225
|
};
|
|
818
|
-
}
|
|
2226
|
+
}
|
|
819
2227
|
|
|
820
|
-
// src/
|
|
821
|
-
var
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
2228
|
+
// src/award-models/rev-share-cap/aggregations.ts
|
|
2229
|
+
var validateAggregatedReferrerMetricsRevShareCap = (metrics) => {
|
|
2230
|
+
validateNonNegativeInteger(metrics.grandTotalReferrals);
|
|
2231
|
+
validateDuration(metrics.grandTotalIncrementalDuration);
|
|
2232
|
+
makePriceEthSchema("AggregatedReferrerMetricsRevShareCap.grandTotalRevenueContribution").parse(
|
|
2233
|
+
metrics.grandTotalRevenueContribution
|
|
2234
|
+
);
|
|
2235
|
+
makePriceUsdcSchema("AggregatedReferrerMetricsRevShareCap.awardPoolRemaining").parse(
|
|
2236
|
+
metrics.awardPoolRemaining
|
|
2237
|
+
);
|
|
830
2238
|
};
|
|
831
|
-
var
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
2239
|
+
var buildAggregatedReferrerMetricsRevShareCap = (referrers, awardPoolRemaining) => {
|
|
2240
|
+
let grandTotalReferrals = 0;
|
|
2241
|
+
let grandTotalIncrementalDuration = 0;
|
|
2242
|
+
let grandTotalRevenueContributionAmount = 0n;
|
|
2243
|
+
for (const referrer of referrers) {
|
|
2244
|
+
grandTotalReferrals += referrer.totalReferrals;
|
|
2245
|
+
grandTotalIncrementalDuration += referrer.totalIncrementalDuration;
|
|
2246
|
+
grandTotalRevenueContributionAmount += referrer.totalRevenueContribution.amount;
|
|
2247
|
+
}
|
|
2248
|
+
const aggregatedMetrics = {
|
|
2249
|
+
grandTotalReferrals,
|
|
2250
|
+
grandTotalIncrementalDuration,
|
|
2251
|
+
grandTotalRevenueContribution: priceEth(grandTotalRevenueContributionAmount),
|
|
2252
|
+
awardPoolRemaining
|
|
2253
|
+
};
|
|
2254
|
+
validateAggregatedReferrerMetricsRevShareCap(aggregatedMetrics);
|
|
2255
|
+
return aggregatedMetrics;
|
|
840
2256
|
};
|
|
841
2257
|
|
|
842
|
-
// src/
|
|
843
|
-
var
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
maxQualifiedReferrers: makeNonNegativeIntegerSchema(`${valueLabel}.maxQualifiedReferrers`),
|
|
851
|
-
startTime: makeUnixTimestampSchema(`${valueLabel}.startTime`),
|
|
852
|
-
endTime: makeUnixTimestampSchema(`${valueLabel}.endTime`),
|
|
853
|
-
subregistryId: makeAccountIdSchema(`${valueLabel}.subregistryId`)
|
|
854
|
-
});
|
|
855
|
-
var makeAwardedReferrerMetricsSchema = (valueLabel = "AwardedReferrerMetrics") => z2.object({
|
|
856
|
-
referrer: makeLowercaseAddressSchema(`${valueLabel}.referrer`),
|
|
857
|
-
totalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.totalReferrals`),
|
|
858
|
-
totalIncrementalDuration: makeDurationSchema(`${valueLabel}.totalIncrementalDuration`),
|
|
859
|
-
totalRevenueContribution: makeRevenueContributionSchema(
|
|
860
|
-
`${valueLabel}.totalRevenueContribution`
|
|
861
|
-
),
|
|
862
|
-
score: makeFiniteNonNegativeNumberSchema(`${valueLabel}.score`),
|
|
863
|
-
rank: makePositiveIntegerSchema(`${valueLabel}.rank`),
|
|
864
|
-
isQualified: z2.boolean(),
|
|
865
|
-
finalScoreBoost: makeFiniteNonNegativeNumberSchema(`${valueLabel}.finalScoreBoost`).max(
|
|
866
|
-
1,
|
|
867
|
-
`${valueLabel}.finalScoreBoost must be <= 1`
|
|
868
|
-
),
|
|
869
|
-
finalScore: makeFiniteNonNegativeNumberSchema(`${valueLabel}.finalScore`),
|
|
870
|
-
awardPoolShare: makeFiniteNonNegativeNumberSchema(`${valueLabel}.awardPoolShare`).max(
|
|
871
|
-
1,
|
|
872
|
-
`${valueLabel}.awardPoolShare must be <= 1`
|
|
873
|
-
),
|
|
874
|
-
awardPoolApproxValue: makeFiniteNonNegativeNumberSchema(`${valueLabel}.awardPoolApproxValue`)
|
|
875
|
-
});
|
|
876
|
-
var makeUnrankedReferrerMetricsSchema = (valueLabel = "UnrankedReferrerMetrics") => z2.object({
|
|
877
|
-
referrer: makeLowercaseAddressSchema(`${valueLabel}.referrer`),
|
|
878
|
-
totalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.totalReferrals`),
|
|
879
|
-
totalIncrementalDuration: makeDurationSchema(`${valueLabel}.totalIncrementalDuration`),
|
|
880
|
-
totalRevenueContribution: makeRevenueContributionSchema(
|
|
881
|
-
`${valueLabel}.totalRevenueContribution`
|
|
882
|
-
),
|
|
883
|
-
score: makeFiniteNonNegativeNumberSchema(`${valueLabel}.score`),
|
|
884
|
-
rank: z2.null(),
|
|
885
|
-
isQualified: z2.literal(false),
|
|
886
|
-
finalScoreBoost: makeFiniteNonNegativeNumberSchema(`${valueLabel}.finalScoreBoost`).max(
|
|
887
|
-
1,
|
|
888
|
-
`${valueLabel}.finalScoreBoost must be <= 1`
|
|
889
|
-
),
|
|
890
|
-
finalScore: makeFiniteNonNegativeNumberSchema(`${valueLabel}.finalScore`),
|
|
891
|
-
awardPoolShare: makeFiniteNonNegativeNumberSchema(`${valueLabel}.awardPoolShare`).max(
|
|
892
|
-
1,
|
|
893
|
-
`${valueLabel}.awardPoolShare must be <= 1`
|
|
894
|
-
),
|
|
895
|
-
awardPoolApproxValue: makeFiniteNonNegativeNumberSchema(`${valueLabel}.awardPoolApproxValue`)
|
|
896
|
-
});
|
|
897
|
-
var makeAggregatedReferrerMetricsSchema = (valueLabel = "AggregatedReferrerMetrics") => z2.object({
|
|
898
|
-
grandTotalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.grandTotalReferrals`),
|
|
899
|
-
grandTotalIncrementalDuration: makeDurationSchema(
|
|
900
|
-
`${valueLabel}.grandTotalIncrementalDuration`
|
|
901
|
-
),
|
|
902
|
-
grandTotalRevenueContribution: makeRevenueContributionSchema(
|
|
903
|
-
`${valueLabel}.grandTotalRevenueContribution`
|
|
904
|
-
),
|
|
905
|
-
grandTotalQualifiedReferrersFinalScore: makeFiniteNonNegativeNumberSchema(
|
|
906
|
-
`${valueLabel}.grandTotalQualifiedReferrersFinalScore`
|
|
907
|
-
),
|
|
908
|
-
minFinalScoreToQualify: makeFiniteNonNegativeNumberSchema(
|
|
909
|
-
`${valueLabel}.minFinalScoreToQualify`
|
|
910
|
-
)
|
|
911
|
-
});
|
|
912
|
-
var makeReferrerLeaderboardPageContextSchema = (valueLabel = "ReferrerLeaderboardPageContext") => z2.object({
|
|
913
|
-
page: makePositiveIntegerSchema(`${valueLabel}.page`),
|
|
914
|
-
recordsPerPage: makePositiveIntegerSchema(`${valueLabel}.recordsPerPage`).max(
|
|
915
|
-
REFERRERS_PER_LEADERBOARD_PAGE_MAX,
|
|
916
|
-
`${valueLabel}.recordsPerPage must not exceed ${REFERRERS_PER_LEADERBOARD_PAGE_MAX}`
|
|
917
|
-
),
|
|
918
|
-
totalRecords: makeNonNegativeIntegerSchema(`${valueLabel}.totalRecords`),
|
|
919
|
-
totalPages: makePositiveIntegerSchema(`${valueLabel}.totalPages`),
|
|
920
|
-
hasNext: z2.boolean(),
|
|
921
|
-
hasPrev: z2.boolean(),
|
|
922
|
-
startIndex: z2.optional(makeNonNegativeIntegerSchema(`${valueLabel}.startIndex`)),
|
|
923
|
-
endIndex: z2.optional(makeNonNegativeIntegerSchema(`${valueLabel}.endIndex`))
|
|
924
|
-
});
|
|
925
|
-
var makeReferrerLeaderboardPageSchema = (valueLabel = "ReferrerLeaderboardPage") => z2.object({
|
|
926
|
-
rules: makeReferralProgramRulesSchema(`${valueLabel}.rules`),
|
|
927
|
-
referrers: z2.array(makeAwardedReferrerMetricsSchema(`${valueLabel}.referrers[record]`)),
|
|
928
|
-
aggregatedMetrics: makeAggregatedReferrerMetricsSchema(`${valueLabel}.aggregatedMetrics`),
|
|
929
|
-
pageContext: makeReferrerLeaderboardPageContextSchema(`${valueLabel}.pageContext`),
|
|
930
|
-
accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
|
|
931
|
-
});
|
|
932
|
-
var makeReferrerLeaderboardPageResponseOkSchema = (valueLabel = "ReferrerLeaderboardPageResponseOk") => z2.object({
|
|
933
|
-
responseCode: z2.literal(ReferrerLeaderboardPageResponseCodes.Ok),
|
|
934
|
-
data: makeReferrerLeaderboardPageSchema(`${valueLabel}.data`)
|
|
935
|
-
});
|
|
936
|
-
var makeReferrerLeaderboardPageResponseErrorSchema = (_valueLabel = "ReferrerLeaderboardPageResponseError") => z2.object({
|
|
937
|
-
responseCode: z2.literal(ReferrerLeaderboardPageResponseCodes.Error),
|
|
938
|
-
error: z2.string(),
|
|
939
|
-
errorMessage: z2.string()
|
|
940
|
-
});
|
|
941
|
-
var makeReferrerLeaderboardPageResponseSchema = (valueLabel = "ReferrerLeaderboardPageResponse") => z2.union([
|
|
942
|
-
makeReferrerLeaderboardPageResponseOkSchema(valueLabel),
|
|
943
|
-
makeReferrerLeaderboardPageResponseErrorSchema(valueLabel)
|
|
944
|
-
]);
|
|
945
|
-
var makeReferrerDetailRankedSchema = (valueLabel = "ReferrerDetailRanked") => z2.object({
|
|
946
|
-
type: z2.literal(ReferrerDetailTypeIds.Ranked),
|
|
947
|
-
rules: makeReferralProgramRulesSchema(`${valueLabel}.rules`),
|
|
948
|
-
referrer: makeAwardedReferrerMetricsSchema(`${valueLabel}.referrer`),
|
|
949
|
-
aggregatedMetrics: makeAggregatedReferrerMetricsSchema(`${valueLabel}.aggregatedMetrics`),
|
|
950
|
-
accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
|
|
951
|
-
});
|
|
952
|
-
var makeReferrerDetailUnrankedSchema = (valueLabel = "ReferrerDetailUnranked") => z2.object({
|
|
953
|
-
type: z2.literal(ReferrerDetailTypeIds.Unranked),
|
|
954
|
-
rules: makeReferralProgramRulesSchema(`${valueLabel}.rules`),
|
|
955
|
-
referrer: makeUnrankedReferrerMetricsSchema(`${valueLabel}.referrer`),
|
|
956
|
-
aggregatedMetrics: makeAggregatedReferrerMetricsSchema(`${valueLabel}.aggregatedMetrics`),
|
|
957
|
-
accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
|
|
958
|
-
});
|
|
959
|
-
var makeReferrerDetailResponseOkSchema = (valueLabel = "ReferrerDetailResponse") => z2.object({
|
|
960
|
-
responseCode: z2.literal(ReferrerDetailResponseCodes.Ok),
|
|
961
|
-
data: z2.union([
|
|
962
|
-
makeReferrerDetailRankedSchema(`${valueLabel}.data`),
|
|
963
|
-
makeReferrerDetailUnrankedSchema(`${valueLabel}.data`)
|
|
964
|
-
])
|
|
965
|
-
});
|
|
966
|
-
var makeReferrerDetailResponseErrorSchema = (_valueLabel = "ReferrerDetailResponse") => z2.object({
|
|
967
|
-
responseCode: z2.literal(ReferrerDetailResponseCodes.Error),
|
|
968
|
-
error: z2.string(),
|
|
969
|
-
errorMessage: z2.string()
|
|
970
|
-
});
|
|
971
|
-
var makeReferrerDetailResponseSchema = (valueLabel = "ReferrerDetailResponse") => z2.union([
|
|
972
|
-
makeReferrerDetailResponseOkSchema(valueLabel),
|
|
973
|
-
makeReferrerDetailResponseErrorSchema(valueLabel)
|
|
974
|
-
]);
|
|
2258
|
+
// src/award-models/rev-share-cap/status.ts
|
|
2259
|
+
var calcReferralProgramEditionStatusRevShareCap = (rules, now, aggregatedMetrics) => {
|
|
2260
|
+
const base = calcBaseReferralProgramEditionStatus(rules, now);
|
|
2261
|
+
if (base === ReferralProgramEditionStatuses.Active && aggregatedMetrics.awardPoolRemaining.amount === 0n) {
|
|
2262
|
+
return ReferralProgramEditionStatuses.Exhausted;
|
|
2263
|
+
}
|
|
2264
|
+
return base;
|
|
2265
|
+
};
|
|
975
2266
|
|
|
976
|
-
// src/
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
2267
|
+
// src/award-models/rev-share-cap/edition-summary.ts
|
|
2268
|
+
var validateEditionSummaryRevShareCap = (summary) => {
|
|
2269
|
+
validateReferralProgramRulesRevShareCap(summary.rules);
|
|
2270
|
+
makePriceUsdcSchema("ReferralProgramEditionSummaryRevShareCap.awardPoolRemaining").parse(
|
|
2271
|
+
summary.awardPoolRemaining
|
|
2272
|
+
);
|
|
2273
|
+
validateBaseReferralProgramEditionSummary(summary);
|
|
2274
|
+
};
|
|
2275
|
+
function buildEditionSummaryRevShareCap(slug, displayName, rules, leaderboard) {
|
|
2276
|
+
const status = calcReferralProgramEditionStatusRevShareCap(
|
|
2277
|
+
rules,
|
|
2278
|
+
leaderboard.accurateAsOf,
|
|
2279
|
+
leaderboard.aggregatedMetrics
|
|
2280
|
+
);
|
|
2281
|
+
const result = {
|
|
2282
|
+
awardModel: rules.awardModel,
|
|
2283
|
+
slug,
|
|
2284
|
+
displayName,
|
|
2285
|
+
status,
|
|
2286
|
+
rules,
|
|
2287
|
+
awardPoolRemaining: leaderboard.aggregatedMetrics.awardPoolRemaining
|
|
996
2288
|
};
|
|
2289
|
+
validateEditionSummaryRevShareCap(result);
|
|
2290
|
+
return result;
|
|
997
2291
|
}
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
2292
|
+
|
|
2293
|
+
// src/award-models/rev-share-cap/metrics.ts
|
|
2294
|
+
var validateReferrerMetricsRevShareCap = (metrics, rules) => {
|
|
2295
|
+
validateReferrerMetrics(metrics);
|
|
2296
|
+
makePriceUsdcSchema("ReferrerMetricsRevShareCap.totalBaseRevenueContribution").parse(
|
|
2297
|
+
metrics.totalBaseRevenueContribution
|
|
2298
|
+
);
|
|
2299
|
+
const expectedTotalBaseRevenueContribution = priceUsdc(
|
|
2300
|
+
rules.baseAnnualRevenueContribution.amount * BigInt(metrics.totalIncrementalDuration) / BigInt(SECONDS_PER_YEAR)
|
|
2301
|
+
);
|
|
2302
|
+
if (metrics.totalBaseRevenueContribution.amount !== expectedTotalBaseRevenueContribution.amount) {
|
|
2303
|
+
throw new Error(
|
|
2304
|
+
`ReferrerMetricsRevShareCap: Invalid totalBaseRevenueContribution: ${metrics.totalBaseRevenueContribution.amount.toString()}, expected: ${expectedTotalBaseRevenueContribution.amount.toString()}.`
|
|
2305
|
+
);
|
|
2306
|
+
}
|
|
2307
|
+
};
|
|
2308
|
+
var buildReferrerMetricsRevShareCap = (metrics, rules) => {
|
|
2309
|
+
const totalBaseRevenueContribution = priceUsdc(
|
|
2310
|
+
rules.baseAnnualRevenueContribution.amount * BigInt(metrics.totalIncrementalDuration) / BigInt(SECONDS_PER_YEAR)
|
|
2311
|
+
);
|
|
2312
|
+
const result = {
|
|
2313
|
+
...metrics,
|
|
2314
|
+
totalBaseRevenueContribution
|
|
1011
2315
|
};
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
2316
|
+
validateReferrerMetricsRevShareCap(result, rules);
|
|
2317
|
+
return result;
|
|
2318
|
+
};
|
|
2319
|
+
var validateAdminActionConsistency = (metricsAdminAction, referrer, rules, context) => {
|
|
2320
|
+
const expected = rules.adminActions.find((a) => a.referrer === referrer) ?? null;
|
|
2321
|
+
if (expected === null && metricsAdminAction !== null) {
|
|
2322
|
+
throw new Error(
|
|
2323
|
+
`${context}: expected null, got actionType="${metricsAdminAction.actionType}".`
|
|
2324
|
+
);
|
|
2325
|
+
}
|
|
2326
|
+
if (expected !== null) {
|
|
2327
|
+
if (metricsAdminAction === null || metricsAdminAction.actionType !== expected.actionType || metricsAdminAction.referrer !== expected.referrer || metricsAdminAction.reason !== expected.reason) {
|
|
2328
|
+
throw new Error(`${context}: does not match expected action from rules.`);
|
|
2329
|
+
}
|
|
2330
|
+
}
|
|
2331
|
+
};
|
|
2332
|
+
var validateRankedReferrerMetricsRevShareCap = (metrics, rules) => {
|
|
2333
|
+
validateReferrerMetricsRevShareCap(metrics, rules);
|
|
2334
|
+
validateReferrerRank(metrics.rank);
|
|
2335
|
+
const expectedIsQualified = isReferrerQualifiedRevShareCap(
|
|
2336
|
+
metrics.referrer,
|
|
2337
|
+
metrics.totalBaseRevenueContribution,
|
|
2338
|
+
rules
|
|
2339
|
+
);
|
|
2340
|
+
if (metrics.isQualified !== expectedIsQualified) {
|
|
2341
|
+
throw new Error(
|
|
2342
|
+
`RankedReferrerMetricsRevShareCap: Invalid isQualified: ${metrics.isQualified}, expected: ${expectedIsQualified}.`
|
|
2343
|
+
);
|
|
2344
|
+
}
|
|
2345
|
+
validateAdminActionConsistency(
|
|
2346
|
+
metrics.adminAction,
|
|
2347
|
+
metrics.referrer,
|
|
2348
|
+
rules,
|
|
2349
|
+
"RankedReferrerMetricsRevShareCap: Invalid adminAction"
|
|
2350
|
+
);
|
|
2351
|
+
};
|
|
2352
|
+
var buildRankedReferrerMetricsRevShareCap = (referrer, rank, rules) => {
|
|
2353
|
+
const adminAction = rules.adminActions.find((a) => a.referrer === referrer.referrer) ?? null;
|
|
2354
|
+
const result = {
|
|
2355
|
+
...referrer,
|
|
2356
|
+
rank,
|
|
2357
|
+
isQualified: isReferrerQualifiedRevShareCap(
|
|
2358
|
+
referrer.referrer,
|
|
2359
|
+
referrer.totalBaseRevenueContribution,
|
|
2360
|
+
rules
|
|
1019
2361
|
),
|
|
1020
|
-
|
|
1021
|
-
minFinalScoreToQualify: metrics.minFinalScoreToQualify
|
|
1022
|
-
};
|
|
1023
|
-
}
|
|
1024
|
-
function deserializeReferrerLeaderboardPage(page) {
|
|
1025
|
-
return {
|
|
1026
|
-
rules: deserializeReferralProgramRules(page.rules),
|
|
1027
|
-
referrers: page.referrers.map(deserializeAwardedReferrerMetrics),
|
|
1028
|
-
aggregatedMetrics: deserializeAggregatedReferrerMetrics(page.aggregatedMetrics),
|
|
1029
|
-
pageContext: page.pageContext,
|
|
1030
|
-
accurateAsOf: page.accurateAsOf
|
|
1031
|
-
};
|
|
1032
|
-
}
|
|
1033
|
-
function deserializeReferrerDetailRanked(detail) {
|
|
1034
|
-
return {
|
|
1035
|
-
type: detail.type,
|
|
1036
|
-
rules: deserializeReferralProgramRules(detail.rules),
|
|
1037
|
-
referrer: deserializeAwardedReferrerMetrics(detail.referrer),
|
|
1038
|
-
aggregatedMetrics: deserializeAggregatedReferrerMetrics(detail.aggregatedMetrics),
|
|
1039
|
-
accurateAsOf: detail.accurateAsOf
|
|
2362
|
+
adminAction
|
|
1040
2363
|
};
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
2364
|
+
validateRankedReferrerMetricsRevShareCap(result, rules);
|
|
2365
|
+
return result;
|
|
2366
|
+
};
|
|
2367
|
+
var validateAwardedReferrerMetricsRevShareCap = (metrics, rules) => {
|
|
2368
|
+
validateRankedReferrerMetricsRevShareCap(metrics, rules);
|
|
2369
|
+
makePriceUsdcSchema("AwardedReferrerMetricsRevShareCap.uncappedAward").parse(
|
|
2370
|
+
metrics.uncappedAward
|
|
2371
|
+
);
|
|
2372
|
+
makePriceUsdcSchema("AwardedReferrerMetricsRevShareCap.cappedAward").parse(metrics.cappedAward);
|
|
2373
|
+
if (metrics.adminAction?.actionType === AdminActionTypes.Disqualification && metrics.cappedAward.amount !== 0n) {
|
|
2374
|
+
throw new Error(
|
|
2375
|
+
`AwardedReferrerMetricsRevShareCap: cappedAward.amount must be 0n for admin-disqualified referrers, got ${metrics.cappedAward.amount.toString()}.`
|
|
2376
|
+
);
|
|
2377
|
+
}
|
|
2378
|
+
if (!metrics.isQualified && metrics.cappedAward.amount !== 0n) {
|
|
2379
|
+
throw new Error(
|
|
2380
|
+
`AwardedReferrerMetricsRevShareCap: cappedAward.amount must be 0n for unqualified referrers, got ${metrics.cappedAward.amount.toString()}.`
|
|
2381
|
+
);
|
|
2382
|
+
}
|
|
2383
|
+
if (metrics.cappedAward.amount > rules.awardPool.amount) {
|
|
2384
|
+
throw new Error(
|
|
2385
|
+
`AwardedReferrerMetricsRevShareCap: cappedAward.amount ${metrics.cappedAward.amount.toString()} exceeds awardPool.amount ${rules.awardPool.amount.toString()}.`
|
|
2386
|
+
);
|
|
2387
|
+
}
|
|
2388
|
+
if (metrics.cappedAward.amount > metrics.uncappedAward.amount) {
|
|
2389
|
+
throw new Error(
|
|
2390
|
+
`AwardedReferrerMetricsRevShareCap: cappedAward.amount ${metrics.cappedAward.amount.toString()} exceeds uncappedAward.amount ${metrics.uncappedAward.amount.toString()}.`
|
|
2391
|
+
);
|
|
2392
|
+
}
|
|
2393
|
+
};
|
|
2394
|
+
var buildAwardedReferrerMetricsRevShareCap = (referrer, uncappedAward, cappedAward, rules) => {
|
|
2395
|
+
const result = {
|
|
2396
|
+
...referrer,
|
|
2397
|
+
uncappedAward,
|
|
2398
|
+
cappedAward
|
|
1049
2399
|
};
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
break;
|
|
1060
|
-
}
|
|
1061
|
-
case "error":
|
|
1062
|
-
deserialized = maybeResponse;
|
|
1063
|
-
break;
|
|
2400
|
+
validateAwardedReferrerMetricsRevShareCap(result, rules);
|
|
2401
|
+
return result;
|
|
2402
|
+
};
|
|
2403
|
+
var validateUnrankedReferrerMetricsRevShareCap = (metrics, rules) => {
|
|
2404
|
+
validateReferrerMetrics(metrics);
|
|
2405
|
+
if (metrics.rank !== null) {
|
|
2406
|
+
throw new Error(
|
|
2407
|
+
`Invalid UnrankedReferrerMetricsRevShareCap: rank must be null, got: ${metrics.rank}.`
|
|
2408
|
+
);
|
|
1064
2409
|
}
|
|
1065
|
-
|
|
1066
|
-
const parsed = schema.safeParse(deserialized);
|
|
1067
|
-
if (parsed.error) {
|
|
2410
|
+
if (metrics.isQualified !== false) {
|
|
1068
2411
|
throw new Error(
|
|
1069
|
-
`
|
|
1070
|
-
${prettifyError(parsed.error)}
|
|
1071
|
-
`
|
|
2412
|
+
`Invalid UnrankedReferrerMetricsRevShareCap: isQualified must be false, got: ${metrics.isQualified}.`
|
|
1072
2413
|
);
|
|
1073
2414
|
}
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
data: deserializeReferrerDetailRanked(maybeResponse.data)
|
|
1085
|
-
};
|
|
1086
|
-
break;
|
|
1087
|
-
case "unranked":
|
|
1088
|
-
deserialized = {
|
|
1089
|
-
responseCode: maybeResponse.responseCode,
|
|
1090
|
-
data: deserializeReferrerDetailUnranked(maybeResponse.data)
|
|
1091
|
-
};
|
|
1092
|
-
break;
|
|
1093
|
-
}
|
|
1094
|
-
break;
|
|
1095
|
-
}
|
|
1096
|
-
case "error":
|
|
1097
|
-
deserialized = maybeResponse;
|
|
1098
|
-
break;
|
|
2415
|
+
validateAdminActionConsistency(
|
|
2416
|
+
metrics.adminAction,
|
|
2417
|
+
metrics.referrer,
|
|
2418
|
+
rules,
|
|
2419
|
+
"Invalid UnrankedReferrerMetricsRevShareCap: adminAction"
|
|
2420
|
+
);
|
|
2421
|
+
if (metrics.totalReferrals !== 0) {
|
|
2422
|
+
throw new Error(
|
|
2423
|
+
`Invalid UnrankedReferrerMetricsRevShareCap: totalReferrals must be 0, got: ${metrics.totalReferrals}.`
|
|
2424
|
+
);
|
|
1099
2425
|
}
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
${prettifyError(parsed.error)}
|
|
1105
|
-
`);
|
|
2426
|
+
if (metrics.totalIncrementalDuration !== 0) {
|
|
2427
|
+
throw new Error(
|
|
2428
|
+
`Invalid UnrankedReferrerMetricsRevShareCap: totalIncrementalDuration must be 0, got: ${metrics.totalIncrementalDuration}.`
|
|
2429
|
+
);
|
|
1106
2430
|
}
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
}
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
grandTotalReferrals: metrics.grandTotalReferrals,
|
|
1150
|
-
grandTotalIncrementalDuration: metrics.grandTotalIncrementalDuration,
|
|
1151
|
-
grandTotalRevenueContribution: serializeRevenueContribution(
|
|
1152
|
-
metrics.grandTotalRevenueContribution
|
|
1153
|
-
),
|
|
1154
|
-
grandTotalQualifiedReferrersFinalScore: metrics.grandTotalQualifiedReferrersFinalScore,
|
|
1155
|
-
minFinalScoreToQualify: metrics.minFinalScoreToQualify
|
|
1156
|
-
};
|
|
1157
|
-
}
|
|
1158
|
-
function serializeReferrerLeaderboardPage(page) {
|
|
1159
|
-
return {
|
|
1160
|
-
rules: serializeReferralProgramRules(page.rules),
|
|
1161
|
-
referrers: page.referrers.map(serializeAwardedReferrerMetrics),
|
|
1162
|
-
aggregatedMetrics: serializeAggregatedReferrerMetrics(page.aggregatedMetrics),
|
|
1163
|
-
pageContext: page.pageContext,
|
|
1164
|
-
accurateAsOf: page.accurateAsOf
|
|
1165
|
-
};
|
|
1166
|
-
}
|
|
1167
|
-
function serializeReferrerDetailRanked(detail) {
|
|
1168
|
-
return {
|
|
1169
|
-
type: detail.type,
|
|
1170
|
-
rules: serializeReferralProgramRules(detail.rules),
|
|
1171
|
-
referrer: serializeAwardedReferrerMetrics(detail.referrer),
|
|
1172
|
-
aggregatedMetrics: serializeAggregatedReferrerMetrics(detail.aggregatedMetrics),
|
|
1173
|
-
accurateAsOf: detail.accurateAsOf
|
|
1174
|
-
};
|
|
1175
|
-
}
|
|
1176
|
-
function serializeReferrerDetailUnranked(detail) {
|
|
1177
|
-
return {
|
|
1178
|
-
type: detail.type,
|
|
1179
|
-
rules: serializeReferralProgramRules(detail.rules),
|
|
1180
|
-
referrer: serializeUnrankedReferrerMetrics(detail.referrer),
|
|
1181
|
-
aggregatedMetrics: serializeAggregatedReferrerMetrics(detail.aggregatedMetrics),
|
|
1182
|
-
accurateAsOf: detail.accurateAsOf
|
|
2431
|
+
makePriceEthSchema("UnrankedReferrerMetricsRevShareCap.totalRevenueContribution").parse(
|
|
2432
|
+
metrics.totalRevenueContribution
|
|
2433
|
+
);
|
|
2434
|
+
if (metrics.totalRevenueContribution.amount !== 0n) {
|
|
2435
|
+
throw new Error(
|
|
2436
|
+
`Invalid UnrankedReferrerMetricsRevShareCap: totalRevenueContribution.amount must be 0n, got: ${metrics.totalRevenueContribution.amount.toString()}.`
|
|
2437
|
+
);
|
|
2438
|
+
}
|
|
2439
|
+
makePriceUsdcSchema("UnrankedReferrerMetricsRevShareCap.totalBaseRevenueContribution").parse(
|
|
2440
|
+
metrics.totalBaseRevenueContribution
|
|
2441
|
+
);
|
|
2442
|
+
if (metrics.totalBaseRevenueContribution.amount !== 0n) {
|
|
2443
|
+
throw new Error(
|
|
2444
|
+
`Invalid UnrankedReferrerMetricsRevShareCap: totalBaseRevenueContribution.amount must be 0n, got: ${metrics.totalBaseRevenueContribution.amount.toString()}.`
|
|
2445
|
+
);
|
|
2446
|
+
}
|
|
2447
|
+
makePriceUsdcSchema("UnrankedReferrerMetricsRevShareCap.uncappedAward").parse(
|
|
2448
|
+
metrics.uncappedAward
|
|
2449
|
+
);
|
|
2450
|
+
if (metrics.uncappedAward.amount !== 0n) {
|
|
2451
|
+
throw new Error(
|
|
2452
|
+
`Invalid UnrankedReferrerMetricsRevShareCap: uncappedAward.amount must be 0n, got: ${metrics.uncappedAward.amount.toString()}.`
|
|
2453
|
+
);
|
|
2454
|
+
}
|
|
2455
|
+
makePriceUsdcSchema("UnrankedReferrerMetricsRevShareCap.cappedAward").parse(metrics.cappedAward);
|
|
2456
|
+
if (metrics.cappedAward.amount !== 0n) {
|
|
2457
|
+
throw new Error(
|
|
2458
|
+
`Invalid UnrankedReferrerMetricsRevShareCap: cappedAward.amount must be 0n, got: ${metrics.cappedAward.amount.toString()}.`
|
|
2459
|
+
);
|
|
2460
|
+
}
|
|
2461
|
+
};
|
|
2462
|
+
var buildUnrankedReferrerMetricsRevShareCap = (referrer, rules) => {
|
|
2463
|
+
const metrics = buildReferrerMetrics(referrer, 0, 0, priceEth(0n));
|
|
2464
|
+
const adminAction = rules.adminActions.find((a) => a.referrer === metrics.referrer) ?? null;
|
|
2465
|
+
const result = {
|
|
2466
|
+
...metrics,
|
|
2467
|
+
totalBaseRevenueContribution: priceUsdc(0n),
|
|
2468
|
+
rank: null,
|
|
2469
|
+
isQualified: false,
|
|
2470
|
+
uncappedAward: priceUsdc(0n),
|
|
2471
|
+
cappedAward: priceUsdc(0n),
|
|
2472
|
+
adminAction
|
|
1183
2473
|
};
|
|
2474
|
+
validateUnrankedReferrerMetricsRevShareCap(result, rules);
|
|
2475
|
+
return result;
|
|
2476
|
+
};
|
|
2477
|
+
|
|
2478
|
+
// src/award-models/rev-share-cap/sort-referral-events.ts
|
|
2479
|
+
function sortReferralEvents(events) {
|
|
2480
|
+
return [...events].sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
|
|
1184
2481
|
}
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
2482
|
+
|
|
2483
|
+
// src/award-models/rev-share-cap/leaderboard.ts
|
|
2484
|
+
var bigintMin = (a, b) => a < b ? a : b;
|
|
2485
|
+
var buildReferrerLeaderboardRevShareCap = (events, rules, accurateAsOf) => {
|
|
2486
|
+
const sortedEvents = sortReferralEvents(events);
|
|
2487
|
+
const referrerStates = /* @__PURE__ */ new Map();
|
|
2488
|
+
let awardPoolRemaining = rules.awardPool.amount;
|
|
2489
|
+
for (const event of sortedEvents) {
|
|
2490
|
+
const referrer = event.referrer;
|
|
2491
|
+
let state = referrerStates.get(referrer);
|
|
2492
|
+
if (!state) {
|
|
2493
|
+
state = {
|
|
2494
|
+
totalReferrals: 0,
|
|
2495
|
+
totalIncrementalDuration: 0,
|
|
2496
|
+
totalRevenueContributionAmount: 0n,
|
|
2497
|
+
wasQualified: false,
|
|
2498
|
+
cappedAwardAmount: 0n
|
|
1191
2499
|
};
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
2500
|
+
referrerStates.set(referrer, state);
|
|
2501
|
+
}
|
|
2502
|
+
state.totalReferrals += 1;
|
|
2503
|
+
state.totalIncrementalDuration += event.incrementalDuration;
|
|
2504
|
+
state.totalRevenueContributionAmount += event.incrementalRevenueContribution.amount;
|
|
2505
|
+
const totalBaseRevenueAmount = rules.baseAnnualRevenueContribution.amount * BigInt(state.totalIncrementalDuration) / BigInt(SECONDS_PER_YEAR);
|
|
2506
|
+
const isNowQualified = isReferrerQualifiedRevShareCap(
|
|
2507
|
+
referrer,
|
|
2508
|
+
priceUsdc(totalBaseRevenueAmount),
|
|
2509
|
+
rules
|
|
2510
|
+
);
|
|
2511
|
+
if (isNowQualified && !state.wasQualified) {
|
|
2512
|
+
const accumulatedUncappedAward = scalePrice(
|
|
2513
|
+
priceUsdc(totalBaseRevenueAmount),
|
|
2514
|
+
rules.maxBaseRevenueShare
|
|
2515
|
+
).amount;
|
|
2516
|
+
const incrementalCappedAward = bigintMin(accumulatedUncappedAward, awardPoolRemaining);
|
|
2517
|
+
state.cappedAwardAmount += incrementalCappedAward;
|
|
2518
|
+
awardPoolRemaining -= incrementalCappedAward;
|
|
2519
|
+
state.wasQualified = true;
|
|
2520
|
+
} else if (state.wasQualified) {
|
|
2521
|
+
const incrementalBaseRevenueAmount = rules.baseAnnualRevenueContribution.amount * BigInt(event.incrementalDuration) / BigInt(SECONDS_PER_YEAR);
|
|
2522
|
+
const incrementalUncappedAward = scalePrice(
|
|
2523
|
+
priceUsdc(incrementalBaseRevenueAmount),
|
|
2524
|
+
rules.maxBaseRevenueShare
|
|
2525
|
+
).amount;
|
|
2526
|
+
const incrementalCappedAward = bigintMin(incrementalUncappedAward, awardPoolRemaining);
|
|
2527
|
+
state.cappedAwardAmount += incrementalCappedAward;
|
|
2528
|
+
awardPoolRemaining -= incrementalCappedAward;
|
|
2529
|
+
}
|
|
1214
2530
|
}
|
|
2531
|
+
const sortedEntries = [...referrerStates.entries()].sort(([a, stateA], [b, stateB]) => {
|
|
2532
|
+
if (stateB.cappedAwardAmount !== stateA.cappedAwardAmount) {
|
|
2533
|
+
return stateB.cappedAwardAmount > stateA.cappedAwardAmount ? 1 : -1;
|
|
2534
|
+
}
|
|
2535
|
+
if (stateB.totalIncrementalDuration !== stateA.totalIncrementalDuration) {
|
|
2536
|
+
return stateB.totalIncrementalDuration - stateA.totalIncrementalDuration;
|
|
2537
|
+
}
|
|
2538
|
+
if (b > a) return 1;
|
|
2539
|
+
if (b < a) return -1;
|
|
2540
|
+
return 0;
|
|
2541
|
+
});
|
|
2542
|
+
const awardedReferrers = sortedEntries.map(
|
|
2543
|
+
([referrerAddr, state], index) => {
|
|
2544
|
+
const baseMetrics = buildReferrerMetrics(
|
|
2545
|
+
referrerAddr,
|
|
2546
|
+
state.totalReferrals,
|
|
2547
|
+
state.totalIncrementalDuration,
|
|
2548
|
+
priceEth(state.totalRevenueContributionAmount)
|
|
2549
|
+
);
|
|
2550
|
+
const revShareMetrics = buildReferrerMetricsRevShareCap(baseMetrics, rules);
|
|
2551
|
+
const rankedMetrics = buildRankedReferrerMetricsRevShareCap(
|
|
2552
|
+
revShareMetrics,
|
|
2553
|
+
index + 1,
|
|
2554
|
+
rules
|
|
2555
|
+
);
|
|
2556
|
+
const uncappedAward = scalePrice(
|
|
2557
|
+
revShareMetrics.totalBaseRevenueContribution,
|
|
2558
|
+
rules.maxBaseRevenueShare
|
|
2559
|
+
);
|
|
2560
|
+
return buildAwardedReferrerMetricsRevShareCap(
|
|
2561
|
+
rankedMetrics,
|
|
2562
|
+
uncappedAward,
|
|
2563
|
+
priceUsdc(state.cappedAwardAmount),
|
|
2564
|
+
rules
|
|
2565
|
+
);
|
|
2566
|
+
}
|
|
2567
|
+
);
|
|
2568
|
+
const aggregatedMetrics = buildAggregatedReferrerMetricsRevShareCap(
|
|
2569
|
+
awardedReferrers,
|
|
2570
|
+
priceUsdc(awardPoolRemaining)
|
|
2571
|
+
);
|
|
2572
|
+
const referrers = new Map(awardedReferrers.map((r) => [r.referrer, r]));
|
|
2573
|
+
return { awardModel: rules.awardModel, rules, aggregatedMetrics, referrers, accurateAsOf };
|
|
2574
|
+
};
|
|
2575
|
+
|
|
2576
|
+
// src/award-models/rev-share-cap/leaderboard-page.ts
|
|
2577
|
+
function buildLeaderboardPageRevShareCap(pageContext, leaderboard) {
|
|
2578
|
+
const status = calcReferralProgramEditionStatusRevShareCap(
|
|
2579
|
+
leaderboard.rules,
|
|
2580
|
+
leaderboard.accurateAsOf,
|
|
2581
|
+
leaderboard.aggregatedMetrics
|
|
2582
|
+
);
|
|
2583
|
+
return {
|
|
2584
|
+
awardModel: leaderboard.awardModel,
|
|
2585
|
+
rules: leaderboard.rules,
|
|
2586
|
+
referrers: sliceReferrers(leaderboard.referrers, pageContext),
|
|
2587
|
+
aggregatedMetrics: leaderboard.aggregatedMetrics,
|
|
2588
|
+
pageContext,
|
|
2589
|
+
status,
|
|
2590
|
+
accurateAsOf: leaderboard.accurateAsOf
|
|
2591
|
+
};
|
|
1215
2592
|
}
|
|
1216
2593
|
|
|
1217
2594
|
// src/client.ts
|
|
@@ -1234,51 +2611,96 @@ var ENSReferralsClient = class _ENSReferralsClient {
|
|
|
1234
2611
|
url: new URL(this.options.url.href)
|
|
1235
2612
|
});
|
|
1236
2613
|
}
|
|
2614
|
+
/**
|
|
2615
|
+
* Get Referral Program Edition Config Set
|
|
2616
|
+
*
|
|
2617
|
+
* Fetches and deserializes a referral program edition config set from a remote URL.
|
|
2618
|
+
*
|
|
2619
|
+
* @param url - The URL to fetch the edition config set from
|
|
2620
|
+
* @returns A ReferralProgramEditionConfigSet (Map of edition slugs to edition configurations)
|
|
2621
|
+
*
|
|
2622
|
+
* @remarks Editions whose `rules.awardModel` is not recognized by this client version are
|
|
2623
|
+
* preserved as {@link ReferralProgramRulesUnrecognized}. The returned map includes all
|
|
2624
|
+
* editions — recognized and unrecognized alike. Callers should check `editionConfig.rules.awardModel`
|
|
2625
|
+
* and skip editions with `"unrecognized"` as appropriate. The returned map may be empty.
|
|
2626
|
+
*
|
|
2627
|
+
* @throws if the fetch fails
|
|
2628
|
+
* @throws if the response is not valid JSON
|
|
2629
|
+
* @throws if the data doesn't match the expected schema
|
|
2630
|
+
*
|
|
2631
|
+
* @example
|
|
2632
|
+
* ```typescript
|
|
2633
|
+
* const url = new URL("https://example.com/editions.json");
|
|
2634
|
+
* const editionConfigSet = await ENSReferralsClient.getReferralProgramEditionConfigSet(url);
|
|
2635
|
+
* console.log(`Loaded ${editionConfigSet.size} editions`);
|
|
2636
|
+
* ```
|
|
2637
|
+
*/
|
|
2638
|
+
static async getReferralProgramEditionConfigSet(url) {
|
|
2639
|
+
const response = await fetch(url);
|
|
2640
|
+
if (!response.ok) {
|
|
2641
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
2642
|
+
}
|
|
2643
|
+
let json;
|
|
2644
|
+
try {
|
|
2645
|
+
json = await response.json();
|
|
2646
|
+
} catch {
|
|
2647
|
+
throw new Error("Malformed response data: invalid JSON");
|
|
2648
|
+
}
|
|
2649
|
+
const editionConfigs = deserializeReferralProgramEditionConfigSetArray(json);
|
|
2650
|
+
return buildReferralProgramEditionConfigSet(editionConfigs);
|
|
2651
|
+
}
|
|
1237
2652
|
/**
|
|
1238
2653
|
* Fetch Referrer Leaderboard Page
|
|
1239
2654
|
*
|
|
1240
|
-
* Retrieves a paginated list of referrer leaderboard metrics
|
|
1241
|
-
* Each referrer's contribution is calculated as a percentage of the grand totals across all referrers.
|
|
2655
|
+
* Retrieves a paginated list of referrer leaderboard metrics for a specific referral program edition.
|
|
1242
2656
|
*
|
|
1243
|
-
* @param request -
|
|
2657
|
+
* @param request - Request parameters including edition and pagination
|
|
2658
|
+
* @param request.edition - The referral program edition slug (e.g., "2025-12", "2026-03", or any other configured edition slug)
|
|
1244
2659
|
* @param request.page - The page number to retrieve (1-indexed, default: 1)
|
|
1245
2660
|
* @param request.recordsPerPage - Number of records per page (default: 25, max: 100)
|
|
1246
2661
|
* @returns {ReferrerLeaderboardPageResponse}
|
|
1247
2662
|
*
|
|
2663
|
+
* @remarks If the server returns a leaderboard page whose `awardModel` is not recognized by
|
|
2664
|
+
* this client version, it is preserved as {@link ReferrerLeaderboardPageUnrecognized}. Callers
|
|
2665
|
+
* should check `response.data.awardModel` and handle the `"unrecognized"` case accordingly.
|
|
2666
|
+
*
|
|
1248
2667
|
* @throws if the ENSNode request fails
|
|
1249
2668
|
* @throws if the ENSNode API returns an error response
|
|
1250
2669
|
* @throws if the ENSNode response breaks required invariants
|
|
1251
2670
|
*
|
|
1252
2671
|
* @example
|
|
1253
2672
|
* ```typescript
|
|
1254
|
-
* // Get first page with default page size (25 records)
|
|
1255
|
-
* const
|
|
2673
|
+
* // Get first page of 2025-12 leaderboard with default page size (25 records)
|
|
2674
|
+
* const editionSlug = "2025-12";
|
|
2675
|
+
* const response = await client.getReferrerLeaderboardPage({ edition: editionSlug });
|
|
1256
2676
|
* if (response.responseCode === ReferrerLeaderboardPageResponseCodes.Ok) {
|
|
1257
|
-
* const {
|
|
1258
|
-
*
|
|
1259
|
-
*
|
|
1260
|
-
*
|
|
1261
|
-
*
|
|
1262
|
-
*
|
|
1263
|
-
*
|
|
1264
|
-
*
|
|
1265
|
-
*
|
|
1266
|
-
*
|
|
1267
|
-
* console.log(updatedAt);
|
|
1268
|
-
* console.log(`Page ${pageContext.page} of ${pageContext.totalPages}`);
|
|
2677
|
+
* const { awardModel, pageContext, accurateAsOf } = response.data;
|
|
2678
|
+
* if (awardModel === ReferralProgramAwardModels.Unrecognized) {
|
|
2679
|
+
* console.log(`Unrecognized award model: ${response.data.originalAwardModel} — skipping`);
|
|
2680
|
+
* } else {
|
|
2681
|
+
* const { aggregatedMetrics, referrers, rules } = response.data;
|
|
2682
|
+
* console.log(`Edition: ${editionSlug}`);
|
|
2683
|
+
* console.log(`Subregistry: ${rules.subregistryId}`);
|
|
2684
|
+
* console.log(`Total Referrers: ${pageContext.totalRecords}`);
|
|
2685
|
+
* console.log(`Page ${pageContext.page} of ${pageContext.totalPages}`);
|
|
2686
|
+
* }
|
|
1269
2687
|
* }
|
|
1270
2688
|
* ```
|
|
1271
2689
|
*
|
|
1272
2690
|
* @example
|
|
1273
2691
|
* ```typescript
|
|
1274
|
-
* // Get second page with 50 records per page
|
|
1275
|
-
* const response = await client.getReferrerLeaderboardPage({
|
|
2692
|
+
* // Get second page of 2026-03 with 50 records per page
|
|
2693
|
+
* const response = await client.getReferrerLeaderboardPage({
|
|
2694
|
+
* edition: "2026-03",
|
|
2695
|
+
* page: 2,
|
|
2696
|
+
* recordsPerPage: 50
|
|
2697
|
+
* });
|
|
1276
2698
|
* ```
|
|
1277
2699
|
*
|
|
1278
2700
|
* @example
|
|
1279
2701
|
* ```typescript
|
|
1280
|
-
* // Handle error response
|
|
1281
|
-
* const response = await client.getReferrerLeaderboardPage();
|
|
2702
|
+
* // Handle error response (e.g., unknown edition or data not available)
|
|
2703
|
+
* const response = await client.getReferrerLeaderboardPage({ edition: "2025-12" });
|
|
1282
2704
|
*
|
|
1283
2705
|
* if (response.responseCode === ReferrerLeaderboardPageResponseCodes.Error) {
|
|
1284
2706
|
* console.error(response.error);
|
|
@@ -1287,9 +2709,10 @@ var ENSReferralsClient = class _ENSReferralsClient {
|
|
|
1287
2709
|
* ```
|
|
1288
2710
|
*/
|
|
1289
2711
|
async getReferrerLeaderboardPage(request) {
|
|
1290
|
-
const url = new URL(`/ensanalytics/
|
|
1291
|
-
|
|
1292
|
-
if (request
|
|
2712
|
+
const url = new URL(`/v1/ensanalytics/referral-leaderboard`, this.options.url);
|
|
2713
|
+
url.searchParams.set("edition", request.edition);
|
|
2714
|
+
if (request.page !== void 0) url.searchParams.set("page", request.page.toString());
|
|
2715
|
+
if (request.recordsPerPage !== void 0)
|
|
1293
2716
|
url.searchParams.set("recordsPerPage", request.recordsPerPage.toString());
|
|
1294
2717
|
const response = await fetch(url);
|
|
1295
2718
|
let responseData;
|
|
@@ -1303,86 +2726,151 @@ var ENSReferralsClient = class _ENSReferralsClient {
|
|
|
1303
2726
|
);
|
|
1304
2727
|
}
|
|
1305
2728
|
/**
|
|
1306
|
-
* Fetch Referrer
|
|
2729
|
+
* Fetch Referrer Metrics for Specific Editions
|
|
1307
2730
|
*
|
|
1308
|
-
* Retrieves detailed information about a specific referrer
|
|
1309
|
-
*
|
|
2731
|
+
* Retrieves detailed information about a specific referrer for the requested
|
|
2732
|
+
* referral program editions. Returns a record mapping each requested edition slug
|
|
2733
|
+
* to the referrer's metrics for that edition.
|
|
1310
2734
|
*
|
|
1311
|
-
* The response data
|
|
2735
|
+
* The response data maps edition slugs to referrer metrics. Each edition's entry is a
|
|
2736
|
+
* {@link ReferrerEditionMetrics} discriminated union. Narrow on `awardModel` first to
|
|
2737
|
+
* exclude unrecognized models, then on `type` to distinguish ranked from unranked:
|
|
1312
2738
|
*
|
|
1313
|
-
*
|
|
1314
|
-
*
|
|
1315
|
-
* -
|
|
1316
|
-
* - `
|
|
1317
|
-
*
|
|
1318
|
-
* - `
|
|
2739
|
+
* - `awardModel: "unrecognized"` ({@link ReferrerEditionMetricsUnrecognized}): the server
|
|
2740
|
+
* returned an award model this client does not recognize. Only `originalAwardModel` is
|
|
2741
|
+
* available; no model-specific fields are present.
|
|
2742
|
+
* - `type: "ranked"` ({@link ReferrerEditionMetricsTypeIds.Ranked}): the referrer appears on
|
|
2743
|
+
* the leaderboard. `referrer` contains rank, qualification status, and award share.
|
|
2744
|
+
* - `type: "unranked"` ({@link ReferrerEditionMetricsTypeIds.Unranked}): the referrer has no
|
|
2745
|
+
* activity in this edition. `referrer` contains zero-value placeholders.
|
|
1319
2746
|
*
|
|
1320
|
-
* **
|
|
1321
|
-
*
|
|
1322
|
-
*
|
|
1323
|
-
* - `rules`: The referral program rules
|
|
1324
|
-
* - `aggregatedMetrics`: Aggregated metrics for all referrers on the leaderboard
|
|
1325
|
-
* - `accurateAsOf`: Unix timestamp indicating when the data was last updated
|
|
2747
|
+
* **Note:** This endpoint does not allow partial success. When `responseCode === Ok`,
|
|
2748
|
+
* all requested editions are guaranteed to be present in the response data. If any
|
|
2749
|
+
* requested edition cannot be returned, the entire request fails with an error.
|
|
1326
2750
|
*
|
|
1327
2751
|
* @see {@link https://www.npmjs.com/package/@namehash/ens-referrals|@namehash/ens-referrals} for calculation details
|
|
1328
2752
|
*
|
|
1329
|
-
* @param request The referrer address to query
|
|
1330
|
-
* @returns {
|
|
2753
|
+
* @param request The referrer address and edition slugs to query
|
|
2754
|
+
* @returns {ReferrerMetricsEditionsResponse} Returns the referrer metrics for requested editions
|
|
2755
|
+
*
|
|
2756
|
+
* @remarks If the server returns metrics for an edition whose `awardModel` is not recognized by
|
|
2757
|
+
* this client version, that edition's entry in `response.data` is preserved as
|
|
2758
|
+
* {@link ReferrerEditionMetricsUnrecognized}. Callers should check each edition's `awardModel`
|
|
2759
|
+
* and handle the `"unrecognized"` case accordingly.
|
|
1331
2760
|
*
|
|
1332
2761
|
* @throws if the ENSNode request fails
|
|
1333
2762
|
* @throws if the response data is malformed
|
|
1334
2763
|
*
|
|
1335
2764
|
* @example
|
|
1336
2765
|
* ```typescript
|
|
1337
|
-
* // Get referrer
|
|
1338
|
-
* const response = await client.
|
|
1339
|
-
* referrer: "0x1234567890123456789012345678901234567890"
|
|
2766
|
+
* // Get referrer metrics for specific editions
|
|
2767
|
+
* const response = await client.getReferrerMetricsEditions({
|
|
2768
|
+
* referrer: "0x1234567890123456789012345678901234567890",
|
|
2769
|
+
* editions: ["2025-12", "2026-01"]
|
|
1340
2770
|
* });
|
|
1341
|
-
* if (response.responseCode ===
|
|
1342
|
-
*
|
|
1343
|
-
*
|
|
1344
|
-
*
|
|
1345
|
-
*
|
|
2771
|
+
* if (response.responseCode === ReferrerMetricsEditionsResponseCodes.Ok) {
|
|
2772
|
+
* // All requested editions are present in response.data
|
|
2773
|
+
* for (const [editionSlug, detail] of Object.entries(response.data)) {
|
|
2774
|
+
* console.log(`Edition: ${editionSlug}`);
|
|
2775
|
+
* if (detail.awardModel === ReferralProgramAwardModels.Unrecognized) {
|
|
2776
|
+
* console.log(`Unrecognized award model: ${detail.originalAwardModel} — skipping`);
|
|
2777
|
+
* continue;
|
|
2778
|
+
* }
|
|
2779
|
+
* console.log(`Type: ${detail.type}`);
|
|
2780
|
+
* if (detail.type === ReferrerEditionMetricsTypeIds.Ranked) {
|
|
2781
|
+
* console.log(`Rank: ${detail.referrer.rank}`);
|
|
2782
|
+
* console.log(`Award Share: ${detail.referrer.awardPoolShare * 100}%`);
|
|
2783
|
+
* }
|
|
2784
|
+
* }
|
|
1346
2785
|
* }
|
|
1347
2786
|
* ```
|
|
1348
2787
|
*
|
|
1349
2788
|
* @example
|
|
1350
2789
|
* ```typescript
|
|
1351
|
-
* //
|
|
1352
|
-
* const response = await client.
|
|
1353
|
-
* referrer: "0x1234567890123456789012345678901234567890"
|
|
2790
|
+
* // Access specific edition data directly (edition is guaranteed to exist when OK)
|
|
2791
|
+
* const response = await client.getReferrerMetricsEditions({
|
|
2792
|
+
* referrer: "0x1234567890123456789012345678901234567890",
|
|
2793
|
+
* editions: ["2025-12"]
|
|
1354
2794
|
* });
|
|
1355
|
-
* if (response.responseCode ===
|
|
1356
|
-
*
|
|
1357
|
-
*
|
|
1358
|
-
* console.log(`
|
|
1359
|
-
*
|
|
1360
|
-
* console.log(`
|
|
1361
|
-
* } else {
|
|
1362
|
-
*
|
|
1363
|
-
* console.log("Referrer is not on the leaderboard (no referrals yet)");
|
|
2795
|
+
* if (response.responseCode === ReferrerMetricsEditionsResponseCodes.Ok) {
|
|
2796
|
+
* const detail = response.data["2025-12"];
|
|
2797
|
+
* if (detail && detail.awardModel === ReferralProgramAwardModels.Unrecognized) {
|
|
2798
|
+
* console.log(`Unrecognized award model: ${detail.originalAwardModel} — skipping`);
|
|
2799
|
+
* } else if (detail && detail.type === ReferrerEditionMetricsTypeIds.Ranked) {
|
|
2800
|
+
* console.log(`Edition 2025-12 Rank: ${detail.referrer.rank}`);
|
|
2801
|
+
* } else if (detail) {
|
|
2802
|
+
* console.log("Referrer is not on the leaderboard for 2025-12");
|
|
1364
2803
|
* }
|
|
1365
2804
|
* }
|
|
1366
2805
|
* ```
|
|
1367
2806
|
*
|
|
1368
2807
|
* @example
|
|
1369
2808
|
* ```typescript
|
|
1370
|
-
* // Handle error response
|
|
1371
|
-
* const response = await client.
|
|
1372
|
-
* referrer: "0x1234567890123456789012345678901234567890"
|
|
2809
|
+
* // Handle error response (e.g., unknown edition or data not available)
|
|
2810
|
+
* const response = await client.getReferrerMetricsEditions({
|
|
2811
|
+
* referrer: "0x1234567890123456789012345678901234567890",
|
|
2812
|
+
* editions: ["2025-12", "invalid-edition"]
|
|
1373
2813
|
* });
|
|
1374
2814
|
*
|
|
1375
|
-
* if (response.responseCode ===
|
|
2815
|
+
* if (response.responseCode === ReferrerMetricsEditionsResponseCodes.Error) {
|
|
1376
2816
|
* console.error(response.error);
|
|
1377
2817
|
* console.error(response.errorMessage);
|
|
1378
2818
|
* }
|
|
1379
2819
|
* ```
|
|
1380
2820
|
*/
|
|
1381
|
-
async
|
|
2821
|
+
async getReferrerMetricsEditions(request) {
|
|
1382
2822
|
const url = new URL(
|
|
1383
|
-
`/ensanalytics/
|
|
2823
|
+
`/v1/ensanalytics/referrer/${encodeURIComponent(request.referrer)}`,
|
|
1384
2824
|
this.options.url
|
|
1385
2825
|
);
|
|
2826
|
+
url.searchParams.set("editions", request.editions.join(","));
|
|
2827
|
+
const response = await fetch(url);
|
|
2828
|
+
let responseData;
|
|
2829
|
+
try {
|
|
2830
|
+
responseData = await response.json();
|
|
2831
|
+
} catch {
|
|
2832
|
+
throw new Error("Malformed response data: invalid JSON");
|
|
2833
|
+
}
|
|
2834
|
+
return deserializeReferrerMetricsEditionsResponse(
|
|
2835
|
+
responseData
|
|
2836
|
+
);
|
|
2837
|
+
}
|
|
2838
|
+
/**
|
|
2839
|
+
* Get the currently configured referral program edition summaries.
|
|
2840
|
+
* Editions are sorted in descending order by start timestamp (most recent first).
|
|
2841
|
+
*
|
|
2842
|
+
* @returns A response containing edition summaries, or an error response if unavailable.
|
|
2843
|
+
*
|
|
2844
|
+
* @remarks Editions whose `rules.awardModel` is not recognized by this client version are
|
|
2845
|
+
* preserved as {@link ReferralProgramEditionSummaryUnrecognized}. The returned response includes all
|
|
2846
|
+
* editions — recognized and unrecognized alike. Callers should check `edition.awardModel`
|
|
2847
|
+
* and skip editions with `"unrecognized"` as appropriate. The returned editions list may be empty.
|
|
2848
|
+
*
|
|
2849
|
+
* @example
|
|
2850
|
+
* ```typescript
|
|
2851
|
+
* const response = await client.getEditionSummaries();
|
|
2852
|
+
*
|
|
2853
|
+
* if (response.responseCode === ReferralProgramEditionSummariesResponseCodes.Ok) {
|
|
2854
|
+
* console.log(`Found ${response.data.editions.length} editions`);
|
|
2855
|
+
* for (const edition of response.data.editions) {
|
|
2856
|
+
* console.log(`${edition.slug}: ${edition.displayName}`);
|
|
2857
|
+
* }
|
|
2858
|
+
* }
|
|
2859
|
+
* ```
|
|
2860
|
+
*
|
|
2861
|
+
* @example
|
|
2862
|
+
* ```typescript
|
|
2863
|
+
* // Handle error response
|
|
2864
|
+
* const response = await client.getEditionSummaries();
|
|
2865
|
+
*
|
|
2866
|
+
* if (response.responseCode === ReferralProgramEditionSummariesResponseCodes.Error) {
|
|
2867
|
+
* console.error(response.error);
|
|
2868
|
+
* console.error(response.errorMessage);
|
|
2869
|
+
* }
|
|
2870
|
+
* ```
|
|
2871
|
+
*/
|
|
2872
|
+
async getEditionSummaries() {
|
|
2873
|
+
const url = new URL(`/v1/ensanalytics/editions`, this.options.url);
|
|
1386
2874
|
const response = await fetch(url);
|
|
1387
2875
|
let responseData;
|
|
1388
2876
|
try {
|
|
@@ -1390,53 +2878,111 @@ var ENSReferralsClient = class _ENSReferralsClient {
|
|
|
1390
2878
|
} catch {
|
|
1391
2879
|
throw new Error("Malformed response data: invalid JSON");
|
|
1392
2880
|
}
|
|
1393
|
-
return
|
|
2881
|
+
return deserializeReferralProgramEditionSummariesResponse(
|
|
2882
|
+
responseData
|
|
2883
|
+
);
|
|
1394
2884
|
}
|
|
1395
2885
|
};
|
|
1396
2886
|
|
|
1397
|
-
// src/
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
2887
|
+
// src/edition-metrics.ts
|
|
2888
|
+
var getReferrerEditionMetrics = (referrer, leaderboard) => {
|
|
2889
|
+
switch (leaderboard.awardModel) {
|
|
2890
|
+
case ReferralProgramAwardModels.PieSplit: {
|
|
2891
|
+
const status = calcReferralProgramEditionStatusPieSplit(
|
|
2892
|
+
leaderboard.rules,
|
|
2893
|
+
leaderboard.accurateAsOf
|
|
2894
|
+
);
|
|
2895
|
+
const awardedReferrerMetrics = leaderboard.referrers.get(referrer);
|
|
2896
|
+
if (awardedReferrerMetrics) {
|
|
2897
|
+
return {
|
|
2898
|
+
awardModel: leaderboard.awardModel,
|
|
2899
|
+
type: ReferrerEditionMetricsTypeIds.Ranked,
|
|
2900
|
+
rules: leaderboard.rules,
|
|
2901
|
+
referrer: awardedReferrerMetrics,
|
|
2902
|
+
aggregatedMetrics: leaderboard.aggregatedMetrics,
|
|
2903
|
+
status,
|
|
2904
|
+
accurateAsOf: leaderboard.accurateAsOf
|
|
2905
|
+
};
|
|
2906
|
+
}
|
|
2907
|
+
return {
|
|
2908
|
+
awardModel: leaderboard.awardModel,
|
|
2909
|
+
type: ReferrerEditionMetricsTypeIds.Unranked,
|
|
2910
|
+
rules: leaderboard.rules,
|
|
2911
|
+
referrer: buildUnrankedReferrerMetricsPieSplit(referrer),
|
|
2912
|
+
aggregatedMetrics: leaderboard.aggregatedMetrics,
|
|
2913
|
+
status,
|
|
2914
|
+
accurateAsOf: leaderboard.accurateAsOf
|
|
2915
|
+
};
|
|
2916
|
+
}
|
|
2917
|
+
case ReferralProgramAwardModels.RevShareCap: {
|
|
2918
|
+
const status = calcReferralProgramEditionStatusRevShareCap(
|
|
2919
|
+
leaderboard.rules,
|
|
2920
|
+
leaderboard.accurateAsOf,
|
|
2921
|
+
leaderboard.aggregatedMetrics
|
|
2922
|
+
);
|
|
2923
|
+
const awardedReferrerMetrics = leaderboard.referrers.get(referrer);
|
|
2924
|
+
if (awardedReferrerMetrics) {
|
|
2925
|
+
return {
|
|
2926
|
+
awardModel: leaderboard.awardModel,
|
|
2927
|
+
type: ReferrerEditionMetricsTypeIds.Ranked,
|
|
2928
|
+
rules: leaderboard.rules,
|
|
2929
|
+
referrer: awardedReferrerMetrics,
|
|
2930
|
+
aggregatedMetrics: leaderboard.aggregatedMetrics,
|
|
2931
|
+
status,
|
|
2932
|
+
accurateAsOf: leaderboard.accurateAsOf
|
|
2933
|
+
};
|
|
2934
|
+
}
|
|
2935
|
+
return {
|
|
2936
|
+
awardModel: leaderboard.awardModel,
|
|
2937
|
+
type: ReferrerEditionMetricsTypeIds.Unranked,
|
|
2938
|
+
rules: leaderboard.rules,
|
|
2939
|
+
referrer: buildUnrankedReferrerMetricsRevShareCap(referrer, leaderboard.rules),
|
|
2940
|
+
aggregatedMetrics: leaderboard.aggregatedMetrics,
|
|
2941
|
+
status,
|
|
2942
|
+
accurateAsOf: leaderboard.accurateAsOf
|
|
2943
|
+
};
|
|
2944
|
+
}
|
|
2945
|
+
default: {
|
|
2946
|
+
const _exhaustiveCheck = leaderboard;
|
|
2947
|
+
throw new Error(
|
|
2948
|
+
`Unknown award model: ${_exhaustiveCheck.awardModel}`
|
|
2949
|
+
);
|
|
2950
|
+
}
|
|
1404
2951
|
}
|
|
1405
|
-
}
|
|
2952
|
+
};
|
|
1406
2953
|
|
|
1407
|
-
// src/
|
|
1408
|
-
|
|
1409
|
-
const
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
2954
|
+
// src/edition-summary.ts
|
|
2955
|
+
function buildEditionSummary(config, leaderboard) {
|
|
2956
|
+
const { slug, displayName } = config;
|
|
2957
|
+
switch (leaderboard.awardModel) {
|
|
2958
|
+
case ReferralProgramAwardModels.PieSplit:
|
|
2959
|
+
return buildEditionSummaryPieSplit(slug, displayName, leaderboard.rules, leaderboard);
|
|
2960
|
+
case ReferralProgramAwardModels.RevShareCap:
|
|
2961
|
+
return buildEditionSummaryRevShareCap(slug, displayName, leaderboard.rules, leaderboard);
|
|
2962
|
+
default: {
|
|
2963
|
+
const _exhaustiveCheck = leaderboard;
|
|
2964
|
+
throw new Error(
|
|
2965
|
+
`Unknown award model: ${_exhaustiveCheck.awardModel}`
|
|
2966
|
+
);
|
|
2967
|
+
}
|
|
1414
2968
|
}
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
2969
|
+
}
|
|
2970
|
+
|
|
2971
|
+
// src/leaderboard-page.ts
|
|
2972
|
+
var getReferrerLeaderboardPage = (pageParams, leaderboard) => {
|
|
2973
|
+
const pageContext = buildReferrerLeaderboardPageContext(pageParams, leaderboard);
|
|
2974
|
+
switch (leaderboard.awardModel) {
|
|
2975
|
+
case ReferralProgramAwardModels.PieSplit:
|
|
2976
|
+
return buildLeaderboardPagePieSplit(pageContext, leaderboard);
|
|
2977
|
+
case ReferralProgramAwardModels.RevShareCap:
|
|
2978
|
+
return buildLeaderboardPageRevShareCap(pageContext, leaderboard);
|
|
2979
|
+
default: {
|
|
2980
|
+
const _exhaustiveCheck = leaderboard;
|
|
2981
|
+
throw new Error(
|
|
2982
|
+
`Unknown award model: ${_exhaustiveCheck.awardModel}`
|
|
2983
|
+
);
|
|
2984
|
+
}
|
|
1419
2985
|
}
|
|
1420
|
-
const sortedReferrers = sortReferrerMetrics(allReferrers);
|
|
1421
|
-
const scoredReferrers = sortedReferrers.map((referrer) => buildScoredReferrerMetrics(referrer));
|
|
1422
|
-
const rankedReferrers = scoredReferrers.map((referrer, index) => {
|
|
1423
|
-
return buildRankedReferrerMetrics(referrer, index + 1, rules);
|
|
1424
|
-
});
|
|
1425
|
-
const aggregatedMetrics = buildAggregatedReferrerMetrics(rankedReferrers, rules);
|
|
1426
|
-
const awardedReferrers = rankedReferrers.map((referrer) => {
|
|
1427
|
-
return buildAwardedReferrerMetrics(referrer, aggregatedMetrics, rules);
|
|
1428
|
-
});
|
|
1429
|
-
const referrers = new Map(
|
|
1430
|
-
awardedReferrers.map((referrer) => {
|
|
1431
|
-
return [referrer.referrer, referrer];
|
|
1432
|
-
})
|
|
1433
|
-
);
|
|
1434
|
-
return {
|
|
1435
|
-
rules,
|
|
1436
|
-
aggregatedMetrics,
|
|
1437
|
-
referrers,
|
|
1438
|
-
accurateAsOf
|
|
1439
|
-
};
|
|
1440
2986
|
};
|
|
1441
2987
|
|
|
1442
2988
|
// src/link.ts
|
|
@@ -1446,119 +2992,95 @@ function buildEnsReferralUrl(address) {
|
|
|
1446
2992
|
ensAppUrl.searchParams.set("referrer", getAddress(address));
|
|
1447
2993
|
return ensAppUrl;
|
|
1448
2994
|
}
|
|
1449
|
-
|
|
1450
|
-
// src/rules.ts
|
|
1451
|
-
var ENS_HOLIDAY_AWARDS_START_DATE = 1764547200;
|
|
1452
|
-
var ENS_HOLIDAY_AWARDS_END_DATE = 1767225599;
|
|
1453
|
-
var ENS_HOLIDAY_AWARDS_MAX_QUALIFIED_REFERRERS = 10;
|
|
1454
|
-
var ENS_HOLIDAY_AWARDS_TOTAL_AWARD_POOL_VALUE = 1e4;
|
|
1455
|
-
var validateReferralProgramRules = (rules) => {
|
|
1456
|
-
validateUSDQuantity(rules.totalAwardPoolValue);
|
|
1457
|
-
validateNonNegativeInteger(rules.maxQualifiedReferrers);
|
|
1458
|
-
validateUnixTimestamp(rules.startTime);
|
|
1459
|
-
validateUnixTimestamp(rules.endTime);
|
|
1460
|
-
if (rules.endTime < rules.startTime) {
|
|
1461
|
-
throw new Error(
|
|
1462
|
-
`ReferralProgramRules: startTime: ${rules.startTime} is after endTime: ${rules.endTime}.`
|
|
1463
|
-
);
|
|
1464
|
-
}
|
|
1465
|
-
};
|
|
1466
|
-
var buildReferralProgramRules = (totalAwardPoolValue, maxQualifiedReferrers, startTime, endTime, subregistryId) => {
|
|
1467
|
-
const result = {
|
|
1468
|
-
totalAwardPoolValue,
|
|
1469
|
-
maxQualifiedReferrers,
|
|
1470
|
-
startTime,
|
|
1471
|
-
endTime,
|
|
1472
|
-
subregistryId
|
|
1473
|
-
};
|
|
1474
|
-
validateReferralProgramRules(result);
|
|
1475
|
-
return result;
|
|
1476
|
-
};
|
|
1477
|
-
|
|
1478
|
-
// src/status.ts
|
|
1479
|
-
var ReferralProgramStatuses = {
|
|
1480
|
-
/**
|
|
1481
|
-
* Represents a referral program that has been announced, but hasn't started yet.
|
|
1482
|
-
*/
|
|
1483
|
-
Scheduled: "Scheduled",
|
|
1484
|
-
/**
|
|
1485
|
-
* Represents a currently ongoing referral program.
|
|
1486
|
-
*/
|
|
1487
|
-
Active: "Active",
|
|
1488
|
-
/**
|
|
1489
|
-
* Represents a referral program that has already ended.
|
|
1490
|
-
*/
|
|
1491
|
-
Closed: "Closed"
|
|
1492
|
-
};
|
|
1493
|
-
var calcReferralProgramStatus = (referralProgramRules, now) => {
|
|
1494
|
-
if (now < referralProgramRules.startTime) return ReferralProgramStatuses.Scheduled;
|
|
1495
|
-
if (now > referralProgramRules.endTime) return ReferralProgramStatuses.Closed;
|
|
1496
|
-
return ReferralProgramStatuses.Active;
|
|
1497
|
-
};
|
|
1498
2995
|
export {
|
|
2996
|
+
AdminActionTypes,
|
|
1499
2997
|
DEFAULT_ENSNODE_API_URL,
|
|
1500
2998
|
ENSReferralsClient,
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
ENS_HOLIDAY_AWARDS_START_DATE,
|
|
1504
|
-
ENS_HOLIDAY_AWARDS_TOTAL_AWARD_POOL_VALUE,
|
|
2999
|
+
MAX_EDITIONS_PER_REQUEST,
|
|
3000
|
+
REFERRAL_PROGRAM_EDITION_SLUG_PATTERN,
|
|
1505
3001
|
REFERRERS_PER_LEADERBOARD_PAGE_DEFAULT,
|
|
1506
3002
|
REFERRERS_PER_LEADERBOARD_PAGE_MAX,
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
3003
|
+
ReferralProgramAwardModels,
|
|
3004
|
+
ReferralProgramEditionStatuses,
|
|
3005
|
+
ReferralProgramEditionSummariesResponseCodes,
|
|
3006
|
+
ReferrerEditionMetricsTypeIds,
|
|
1510
3007
|
ReferrerLeaderboardPageResponseCodes,
|
|
3008
|
+
ReferrerMetricsEditionsResponseCodes,
|
|
1511
3009
|
SECONDS_PER_YEAR,
|
|
1512
|
-
|
|
1513
|
-
|
|
3010
|
+
buildAggregatedReferrerMetricsPieSplit,
|
|
3011
|
+
buildAggregatedReferrerMetricsRevShareCap,
|
|
3012
|
+
buildAwardedReferrerMetricsPieSplit,
|
|
3013
|
+
buildAwardedReferrerMetricsRevShareCap,
|
|
3014
|
+
buildEditionSummary,
|
|
3015
|
+
buildEditionSummaryPieSplit,
|
|
3016
|
+
buildEditionSummaryRevShareCap,
|
|
1514
3017
|
buildEnsReferralUrl,
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
3018
|
+
buildLeaderboardPagePieSplit,
|
|
3019
|
+
buildLeaderboardPageRevShareCap,
|
|
3020
|
+
buildRankedReferrerMetricsPieSplit,
|
|
3021
|
+
buildRankedReferrerMetricsRevShareCap,
|
|
3022
|
+
buildReferralProgramEditionConfigSet,
|
|
3023
|
+
buildReferralProgramRulesPieSplit,
|
|
3024
|
+
buildReferralProgramRulesRevShareCap,
|
|
1518
3025
|
buildReferrerLeaderboardPageContext,
|
|
1519
3026
|
buildReferrerLeaderboardPageParams,
|
|
3027
|
+
buildReferrerLeaderboardPieSplit,
|
|
3028
|
+
buildReferrerLeaderboardRevShareCap,
|
|
1520
3029
|
buildReferrerMetrics,
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
3030
|
+
buildReferrerMetricsRevShareCap,
|
|
3031
|
+
buildScoredReferrerMetricsPieSplit,
|
|
3032
|
+
buildUnrankedReferrerMetricsPieSplit,
|
|
3033
|
+
buildUnrankedReferrerMetricsRevShareCap,
|
|
3034
|
+
calcBaseReferralProgramEditionStatus,
|
|
3035
|
+
calcReferralProgramEditionStatusPieSplit,
|
|
3036
|
+
calcReferralProgramEditionStatusRevShareCap,
|
|
3037
|
+
calcReferrerAwardPoolSharePieSplit,
|
|
3038
|
+
calcReferrerScorePieSplit,
|
|
1529
3039
|
compareReferrerMetrics,
|
|
1530
|
-
|
|
3040
|
+
deserializeReferralProgramEditionConfigSetArray,
|
|
3041
|
+
deserializeReferralProgramEditionSummariesResponse,
|
|
1531
3042
|
deserializeReferrerLeaderboardPageResponse,
|
|
1532
|
-
|
|
3043
|
+
deserializeReferrerMetricsEditionsResponse,
|
|
3044
|
+
getReferrerEditionMetrics,
|
|
1533
3045
|
getReferrerLeaderboardPage,
|
|
1534
3046
|
isFiniteNonNegativeNumber,
|
|
1535
3047
|
isInteger,
|
|
1536
3048
|
isNonNegativeInteger,
|
|
1537
3049
|
isPositiveInteger,
|
|
1538
|
-
|
|
3050
|
+
isReferrerQualifiedRevShareCap,
|
|
1539
3051
|
isValidDuration,
|
|
1540
3052
|
isValidReferrerScore,
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
serializeReferrerDetailResponse,
|
|
3053
|
+
serializeReferralProgramEditionSummariesResponse,
|
|
3054
|
+
serializeReferralProgramEditionSummary,
|
|
3055
|
+
serializeReferralProgramRules,
|
|
1545
3056
|
serializeReferrerLeaderboardPageResponse,
|
|
3057
|
+
serializeReferrerMetricsEditionsResponse,
|
|
3058
|
+
sliceReferrers,
|
|
1546
3059
|
sortReferrerMetrics,
|
|
1547
|
-
|
|
1548
|
-
|
|
3060
|
+
validateAggregatedReferrerMetricsPieSplit,
|
|
3061
|
+
validateAggregatedReferrerMetricsRevShareCap,
|
|
3062
|
+
validateAwardedReferrerMetricsPieSplit,
|
|
3063
|
+
validateAwardedReferrerMetricsRevShareCap,
|
|
3064
|
+
validateBaseReferralProgramEditionSummary,
|
|
3065
|
+
validateBaseReferralProgramRules,
|
|
1549
3066
|
validateDuration,
|
|
1550
|
-
|
|
3067
|
+
validateEditionSummaryPieSplit,
|
|
3068
|
+
validateEditionSummaryRevShareCap,
|
|
1551
3069
|
validateNonNegativeInteger,
|
|
1552
|
-
|
|
1553
|
-
|
|
3070
|
+
validateNormalizedAddress,
|
|
3071
|
+
validateRankedReferrerMetricsPieSplit,
|
|
3072
|
+
validateRankedReferrerMetricsRevShareCap,
|
|
3073
|
+
validateReferralProgramEditionConfigSet,
|
|
3074
|
+
validateReferralProgramRulesPieSplit,
|
|
3075
|
+
validateReferralProgramRulesRevShareCap,
|
|
1554
3076
|
validateReferrerLeaderboardPageContext,
|
|
1555
3077
|
validateReferrerMetrics,
|
|
3078
|
+
validateReferrerMetricsRevShareCap,
|
|
1556
3079
|
validateReferrerRank,
|
|
1557
3080
|
validateReferrerScore,
|
|
1558
|
-
|
|
1559
|
-
validateScoredReferrerMetrics,
|
|
1560
|
-
validateUSDQuantity,
|
|
3081
|
+
validateScoredReferrerMetricsPieSplit,
|
|
1561
3082
|
validateUnixTimestamp,
|
|
1562
|
-
|
|
3083
|
+
validateUnrankedReferrerMetricsPieSplit,
|
|
3084
|
+
validateUnrankedReferrerMetricsRevShareCap
|
|
1563
3085
|
};
|
|
1564
3086
|
//# sourceMappingURL=index.js.map
|