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