@namehash/ens-referrals 1.11.0 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -490,6 +490,34 @@ var makeAccountIdSchema = (valueLabel = "AccountId") => z.strictObject({
490
490
  address: makeNormalizedAddressSchema(`${valueLabel} address`)
491
491
  });
492
492
 
493
+ // ../ensnode-sdk/src/indexing-status/omnichain-indexing-status-snapshot.ts
494
+ var OmnichainIndexingStatusIds = {
495
+ /**
496
+ * Represents that omnichain indexing is not ready to begin yet because
497
+ * ENSIndexer is in its initialization phase and the data to build a "true"
498
+ * {@link OmnichainIndexingStatusSnapshot} is still being loaded.
499
+ */
500
+ Unstarted: "omnichain-unstarted",
501
+ /**
502
+ * Represents that omnichain indexing is in an overall "backfill" status because
503
+ * - At least one indexed chain has a `chainStatus` of
504
+ * {@link ChainIndexingStatusIds.Backfill}; and
505
+ * - No indexed chain has a `chainStatus` of {@link ChainIndexingStatusIds.Following}.
506
+ */
507
+ Backfill: "omnichain-backfill",
508
+ /**
509
+ * Represents that omnichain indexing is in an overall "following" status because
510
+ * at least one indexed chain has a `chainStatus` of
511
+ * {@link ChainIndexingStatusIds.Following}.
512
+ */
513
+ Following: "omnichain-following",
514
+ /**
515
+ * Represents that omnichain indexing has completed because all indexed chains have
516
+ * a `chainStatus` of {@link ChainIndexingStatusIds.Completed}.
517
+ */
518
+ Completed: "omnichain-completed"
519
+ };
520
+
493
521
  // ../ensnode-sdk/src/shared/serialize.ts
494
522
  function serializePrice(price) {
495
523
  return {
@@ -1580,6 +1608,36 @@ ${prettifyError(parsed.error)}
1580
1608
  return parsed.data;
1581
1609
  }
1582
1610
 
1611
+ // src/api/prerequisites.ts
1612
+ var ensAnalyticsRequiredPlugins = [
1613
+ "subgraph" /* Subgraph */,
1614
+ "basenames" /* Basenames */,
1615
+ "lineanames" /* Lineanames */,
1616
+ "registrars" /* Registrars */
1617
+ ];
1618
+ function hasEnsAnalyticsConfigSupport(config) {
1619
+ const supported = ensAnalyticsRequiredPlugins.every((plugin) => config.plugins.includes(plugin));
1620
+ if (supported) return { supported };
1621
+ return {
1622
+ supported: false,
1623
+ reason: `The ENSAnalytics API requires all of the following plugins to be activated in the connected ENSNode's Config: ${ensAnalyticsRequiredPlugins.map((plugin) => `'${plugin}'`).join(", ")}.`
1624
+ };
1625
+ }
1626
+ var ensAnalyticsSupportedIndexingStatusIds = [
1627
+ OmnichainIndexingStatusIds.Completed,
1628
+ OmnichainIndexingStatusIds.Following
1629
+ ];
1630
+ function hasEnsAnalyticsIndexingStatusSupport(omnichainIndexingStatusId) {
1631
+ const supported = ensAnalyticsSupportedIndexingStatusIds.some(
1632
+ (supportedIndexingStatusId) => supportedIndexingStatusId === omnichainIndexingStatusId
1633
+ );
1634
+ if (supported) return { supported };
1635
+ return {
1636
+ supported: false,
1637
+ reason: `The ENSAnalytics API requires the connected ENSNode's Indexing Status to be one of the following: ${ensAnalyticsSupportedIndexingStatusIds.join(", ")}.`
1638
+ };
1639
+ }
1640
+
1583
1641
  // src/award-models/pie-split/api/serialize.ts
1584
1642
  function serializeReferralProgramRulesPieSplit(rules) {
1585
1643
  return {
@@ -2289,7 +2347,7 @@ var buildUnrankedReferrerMetricsPieSplit = (referrer) => {
2289
2347
  };
2290
2348
 
2291
2349
  // src/award-models/pie-split/leaderboard.ts
2292
- var buildReferrerLeaderboardPieSplit = (allReferrers, rules, accurateAsOf) => {
2350
+ var buildReferralEditionSnapshotPieSplit = (allReferrers, rules, accurateAsOf) => {
2293
2351
  assertLeaderboardInputs(allReferrers, rules, accurateAsOf);
2294
2352
  const sortedReferrers = sortReferrerMetrics(allReferrers);
2295
2353
  const scoredReferrers = sortedReferrers.map((r) => buildScoredReferrerMetricsPieSplit(r));
@@ -2301,7 +2359,14 @@ var buildReferrerLeaderboardPieSplit = (allReferrers, rules, accurateAsOf) => {
2301
2359
  (r) => buildAwardedReferrerMetricsPieSplit(r, aggregatedMetrics, rules)
2302
2360
  );
2303
2361
  const referrers = new Map(awardedReferrers.map((r) => [r.referrer, r]));
2304
- return { awardModel: rules.awardModel, rules, aggregatedMetrics, referrers, accurateAsOf };
2362
+ const leaderboard = {
2363
+ awardModel: rules.awardModel,
2364
+ rules,
2365
+ aggregatedMetrics,
2366
+ referrers,
2367
+ accurateAsOf
2368
+ };
2369
+ return { awardModel: rules.awardModel, leaderboard };
2305
2370
  };
2306
2371
 
2307
2372
  // src/award-models/pie-split/leaderboard-page.ts
@@ -2579,9 +2644,14 @@ function sortReferralEvents(events) {
2579
2644
  }
2580
2645
 
2581
2646
  // src/award-models/rev-share-cap/leaderboard.ts
2582
- var buildReferrerLeaderboardRevShareCap = (events, rules, accurateAsOf) => {
2647
+ var buildReferralEditionSnapshotRevShareCap = (events, rules, accurateAsOf) => {
2583
2648
  const sortedEvents = sortReferralEvents(events);
2649
+ const adminActionByReferrer = /* @__PURE__ */ new Map();
2650
+ for (const action of rules.adminActions) {
2651
+ adminActionByReferrer.set(action.referrer, action);
2652
+ }
2584
2653
  const referrerStates = /* @__PURE__ */ new Map();
2654
+ const accountingRecords = [];
2585
2655
  let awardPoolRemaining = rules.awardPool;
2586
2656
  for (const event of sortedEvents) {
2587
2657
  const referrerId = event.referrer;
@@ -2602,27 +2672,65 @@ var buildReferrerLeaderboardRevShareCap = (events, rules, accurateAsOf) => {
2602
2672
  referrerState.totalRevenueContribution,
2603
2673
  event.incrementalRevenueContribution
2604
2674
  );
2605
- const totalBaseRevenue = calcBaseRevenueContribution(
2675
+ const hasQualifiedBefore = referrerState.hasQualified;
2676
+ const awardPoolRemainingBefore = awardPoolRemaining;
2677
+ const adminAction = adminActionByReferrer.get(referrerId);
2678
+ const adminDisqualification = adminAction?.actionType === AdminActionTypes.Disqualification ? adminAction : null;
2679
+ const accumulatedBaseRevenueContribution = calcBaseRevenueContribution(
2606
2680
  rules,
2607
2681
  referrerState.totalIncrementalDuration
2608
2682
  );
2609
- const isNowQualified = isReferrerQualifiedRevShareCap(referrerId, totalBaseRevenue, rules);
2610
- if (isNowQualified && !referrerState.hasQualified) {
2611
- const accumulatedUncappedAward = scalePrice(totalBaseRevenue, rules.maxBaseRevenueShare);
2612
- const incrementalCappedAward = minPrice(accumulatedUncappedAward, awardPoolRemaining);
2613
- referrerState.cappedAward = addPrices(referrerState.cappedAward, incrementalCappedAward);
2614
- awardPoolRemaining = subtractPrice(awardPoolRemaining, incrementalCappedAward);
2683
+ const incrementalBaseRevenueContribution = calcBaseRevenueContribution(
2684
+ rules,
2685
+ event.incrementalDuration
2686
+ );
2687
+ const isNowQualified = isReferrerQualifiedRevShareCap(
2688
+ referrerId,
2689
+ accumulatedBaseRevenueContribution,
2690
+ rules
2691
+ );
2692
+ let incrementalTentativeAward = priceUsdc(0n);
2693
+ if (isNowQualified && !hasQualifiedBefore) {
2694
+ const accumulatedUncappedAward = scalePrice(
2695
+ accumulatedBaseRevenueContribution,
2696
+ rules.maxBaseRevenueShare
2697
+ );
2698
+ incrementalTentativeAward = minPrice(accumulatedUncappedAward, awardPoolRemainingBefore);
2615
2699
  referrerState.hasQualified = true;
2616
- } else if (referrerState.hasQualified) {
2617
- const incrementalBaseRevenue = calcBaseRevenueContribution(rules, event.incrementalDuration);
2700
+ } else if (hasQualifiedBefore) {
2618
2701
  const incrementalUncappedAward = scalePrice(
2619
- incrementalBaseRevenue,
2702
+ incrementalBaseRevenueContribution,
2620
2703
  rules.maxBaseRevenueShare
2621
2704
  );
2622
- const incrementalCappedAward = minPrice(incrementalUncappedAward, awardPoolRemaining);
2623
- referrerState.cappedAward = addPrices(referrerState.cappedAward, incrementalCappedAward);
2624
- awardPoolRemaining = subtractPrice(awardPoolRemaining, incrementalCappedAward);
2625
- }
2705
+ incrementalTentativeAward = minPrice(incrementalUncappedAward, awardPoolRemainingBefore);
2706
+ }
2707
+ referrerState.cappedAward = addPrices(referrerState.cappedAward, incrementalTentativeAward);
2708
+ awardPoolRemaining = subtractPrice(awardPoolRemaining, incrementalTentativeAward);
2709
+ const tentativeAward = {
2710
+ incrementalRevenueContribution: event.incrementalRevenueContribution,
2711
+ accumulatedRevenueContribution: referrerState.totalRevenueContribution,
2712
+ incrementalBaseRevenueContribution,
2713
+ accumulatedBaseRevenueContribution,
2714
+ awardPoolRemaining: awardPoolRemainingBefore,
2715
+ disqualified: adminDisqualification !== null,
2716
+ ...adminDisqualification !== null && {
2717
+ disqualificationReason: adminDisqualification.reason
2718
+ },
2719
+ maxRevShare: rules.maxBaseRevenueShare,
2720
+ effectiveBaseRevShare: incrementalBaseRevenueContribution.amount === 0n ? 0 : Number(incrementalTentativeAward.amount) / Number(incrementalBaseRevenueContribution.amount),
2721
+ incrementalTentativeAward
2722
+ };
2723
+ accountingRecords.push({
2724
+ registrarActionId: event.id,
2725
+ timestamp: event.timestamp,
2726
+ name: event.name,
2727
+ actionType: event.actionType,
2728
+ transactionHash: event.transactionHash,
2729
+ registrant: event.registrant,
2730
+ referrer: referrerId,
2731
+ incrementalDuration: event.incrementalDuration,
2732
+ tentativeAward
2733
+ });
2626
2734
  }
2627
2735
  const sortedEntries = [...referrerStates.entries()].sort(
2628
2736
  ([referrerIdA, referrerStateA], [referrerIdB, referrerStateB]) => {
@@ -2668,7 +2776,17 @@ var buildReferrerLeaderboardRevShareCap = (events, rules, accurateAsOf) => {
2668
2776
  awardPoolRemaining
2669
2777
  );
2670
2778
  const referrers = new Map(awardedReferrers.map((r) => [r.referrer, r]));
2671
- return { awardModel: rules.awardModel, rules, aggregatedMetrics, referrers, accurateAsOf };
2779
+ return {
2780
+ awardModel: rules.awardModel,
2781
+ leaderboard: {
2782
+ awardModel: rules.awardModel,
2783
+ rules,
2784
+ aggregatedMetrics,
2785
+ referrers,
2786
+ accurateAsOf
2787
+ },
2788
+ accountingRecords
2789
+ };
2672
2790
  };
2673
2791
 
2674
2792
  // src/award-models/rev-share-cap/leaderboard-page.ts
@@ -3117,13 +3235,13 @@ export {
3117
3235
  buildLeaderboardPageRevShareCap,
3118
3236
  buildRankedReferrerMetricsPieSplit,
3119
3237
  buildRankedReferrerMetricsRevShareCap,
3238
+ buildReferralEditionSnapshotPieSplit,
3239
+ buildReferralEditionSnapshotRevShareCap,
3120
3240
  buildReferralProgramEditionConfigSet,
3121
3241
  buildReferralProgramRulesPieSplit,
3122
3242
  buildReferralProgramRulesRevShareCap,
3123
3243
  buildReferrerLeaderboardPageContext,
3124
3244
  buildReferrerLeaderboardPageParams,
3125
- buildReferrerLeaderboardPieSplit,
3126
- buildReferrerLeaderboardRevShareCap,
3127
3245
  buildReferrerMetrics,
3128
3246
  buildReferrerMetricsRevShareCap,
3129
3247
  buildScoredReferrerMetricsPieSplit,
@@ -3143,6 +3261,8 @@ export {
3143
3261
  findOverlappingEditionPair,
3144
3262
  getReferrerEditionMetrics,
3145
3263
  getReferrerLeaderboardPage,
3264
+ hasEnsAnalyticsConfigSupport,
3265
+ hasEnsAnalyticsIndexingStatusSupport,
3146
3266
  isFiniteNonNegativeNumber,
3147
3267
  isInteger,
3148
3268
  isNonNegativeInteger,