diff --git a/.changeset/every-areas-draw.md b/.changeset/every-areas-draw.md new file mode 100644 index 000000000..8c6b9fa03 --- /dev/null +++ b/.changeset/every-areas-draw.md @@ -0,0 +1,5 @@ +--- +"@namehash/ens-referrals": patch +--- + +Tighten referral program types to use `NormalizedAddress` instead of `Address` in internal leaderboard map keys (pie-split, shared `sliceReferrers`) and related JSDoc. No runtime behavior change. diff --git a/packages/ens-referrals/README.md b/packages/ens-referrals/README.md index b0f584d30..394acad87 100644 --- a/packages/ens-referrals/README.md +++ b/packages/ens-referrals/README.md @@ -158,7 +158,7 @@ The package also includes helpers for building referral links. ```typescript import { buildEnsReferralUrl } from "@namehash/ens-referrals"; -import type { Address } from "viem"; +import type { Address } from "enssdk"; const referrerAddress: Address = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045"; diff --git a/packages/ens-referrals/src/address.ts b/packages/ens-referrals/src/address.ts index 2580243b7..fb8f6fe04 100644 --- a/packages/ens-referrals/src/address.ts +++ b/packages/ens-referrals/src/address.ts @@ -1,7 +1,7 @@ import type { NormalizedAddress } from "enssdk"; import { isNormalizedAddress } from "enssdk"; -export const validateAddress = (address: NormalizedAddress): void => { +export const validateNormalizedAddress = (address: NormalizedAddress): void => { if (!isNormalizedAddress(address)) { throw new Error(`Invalid address: '${address}'. Address must be a lowercase EVM Address.`); } diff --git a/packages/ens-referrals/src/award-models/pie-split/leaderboard.ts b/packages/ens-referrals/src/award-models/pie-split/leaderboard.ts index 236894a58..d1cfb40f6 100644 --- a/packages/ens-referrals/src/award-models/pie-split/leaderboard.ts +++ b/packages/ens-referrals/src/award-models/pie-split/leaderboard.ts @@ -1,4 +1,4 @@ -import type { Address, UnixTimestamp } from "enssdk"; +import type { NormalizedAddress, UnixTimestamp } from "enssdk"; import type { ReferrerMetrics } from "../../referrer-metrics"; import { assertLeaderboardInputs } from "../shared/leaderboard-guards"; @@ -42,13 +42,13 @@ export interface ReferrerLeaderboardPieSplit { * @invariant Map entries are ordered by `rank` (ascending). * @invariant Map is empty if there are no referrers with 1 or more `totalReferrals` * within the `rules` as of `accurateAsOf`. - * @invariant If a fully-lowercase `Address` is not a key in this map then that `Address` had + * @invariant If a `NormalizedAddress` is not a key in this map then that `NormalizedAddress` had * 0 `totalReferrals`, `totalIncrementalDuration`, and `score` within the * `rules` as of `accurateAsOf`. * @invariant Each value in this map is guaranteed to have a non-zero * `totalReferrals`, `totalIncrementalDuration`, and `score`. */ - referrers: Map; + referrers: Map; /** * The {@link UnixTimestamp} of when the data used to build the {@link ReferrerLeaderboardPieSplit} was accurate as of. diff --git a/packages/ens-referrals/src/award-models/rev-share-cap/leaderboard.ts b/packages/ens-referrals/src/award-models/rev-share-cap/leaderboard.ts index 04fdf86a1..e6e0537e2 100644 --- a/packages/ens-referrals/src/award-models/rev-share-cap/leaderboard.ts +++ b/packages/ens-referrals/src/award-models/rev-share-cap/leaderboard.ts @@ -47,7 +47,7 @@ export interface ReferrerLeaderboardRevShareCap { * @invariant Map entries are ordered by `rank` (ascending). * @invariant Map is empty if there are no referrers with 1 or more `totalReferrals` * within the `rules` as of `accurateAsOf`. - * @invariant If a fully-lowercase `Address` is not a key in this map then that `Address` had + * @invariant If a `NormalizedAddress` is not a key in this map then that `NormalizedAddress` had * 0 `totalReferrals`, `totalIncrementalDuration`, and `totalRevenueContribution` within the * `rules` as of `accurateAsOf`. * @invariant Each value in this map is guaranteed to have a non-zero diff --git a/packages/ens-referrals/src/award-models/rev-share-cap/rules.ts b/packages/ens-referrals/src/award-models/rev-share-cap/rules.ts index 2781a15cc..d78e34d34 100644 --- a/packages/ens-referrals/src/award-models/rev-share-cap/rules.ts +++ b/packages/ens-referrals/src/award-models/rev-share-cap/rules.ts @@ -3,7 +3,7 @@ import type { AccountId, NormalizedAddress, UnixTimestamp } from "enssdk"; import type { PriceUsdc } from "@ensnode/ensnode-sdk"; import { makePriceUsdcSchema } from "@ensnode/ensnode-sdk/internal"; -import { validateAddress } from "../../address"; +import { validateNormalizedAddress } from "../../address"; import { type BaseReferralProgramRules, ReferralProgramAwardModels, @@ -102,7 +102,7 @@ export const validateReferralProgramRulesRevShareCap = ( } for (const d of rules.disqualifications) { - validateAddress(d.referrer); + validateNormalizedAddress(d.referrer); if (d.reason.trim().length === 0) { throw new Error( "ReferralProgramRulesRevShareCap: disqualification reason must not be empty.", diff --git a/packages/ens-referrals/src/award-models/shared/leaderboard-page.ts b/packages/ens-referrals/src/award-models/shared/leaderboard-page.ts index da5fb662e..72a436223 100644 --- a/packages/ens-referrals/src/award-models/shared/leaderboard-page.ts +++ b/packages/ens-referrals/src/award-models/shared/leaderboard-page.ts @@ -1,4 +1,4 @@ -import type { Address, UnixTimestamp } from "enssdk"; +import type { NormalizedAddress, UnixTimestamp } from "enssdk"; import type { ReferrerLeaderboard } from "../../leaderboard"; import { isNonNegativeInteger, isPositiveInteger } from "../../number"; @@ -309,7 +309,7 @@ export interface ReferrerLeaderboardPageUnrecognized extends BaseReferrerLeaderb * Generic over the referrer type so each model variant retains its specific type. */ export function sliceReferrers( - referrers: Map, + referrers: Map, pageContext: ReferrerLeaderboardPageContext, ): T[] { // pageContext invariants: startIndex and endIndex are defined iff totalRecords > 0 diff --git a/packages/ens-referrals/src/leaderboard-page.test.ts b/packages/ens-referrals/src/leaderboard-page.test.ts index 98c71e724..df902cc16 100644 --- a/packages/ens-referrals/src/leaderboard-page.test.ts +++ b/packages/ens-referrals/src/leaderboard-page.test.ts @@ -1,4 +1,4 @@ -import type { Address } from "enssdk"; +import type { NormalizedAddress } from "enssdk"; import { describe, expect, it, vi } from "vitest"; import { priceEth, priceUsdc } from "@ensnode/ensnode-sdk"; @@ -41,7 +41,7 @@ describe("buildReferrerLeaderboardPageContext", () => { grandTotalQualifiedReferrersFinalScore: 28.05273061366773, minFinalScoreToQualify: 0, }, - referrers: new Map([ + referrers: new Map([ [ "0x03c098d2bed4609e6ed9beb2c4877741f45f290d", { @@ -130,7 +130,7 @@ describe("buildReferrerLeaderboardPageContext", () => { grandTotalQualifiedReferrersFinalScore: 28.05273061366773, minFinalScoreToQualify: 0, }, - referrers: new Map(), + referrers: new Map(), accurateAsOf: 1764580368, }; diff --git a/packages/ens-referrals/src/referrer-metrics.ts b/packages/ens-referrals/src/referrer-metrics.ts index 56cd2381e..111e09916 100644 --- a/packages/ens-referrals/src/referrer-metrics.ts +++ b/packages/ens-referrals/src/referrer-metrics.ts @@ -3,7 +3,7 @@ import type { Duration, NormalizedAddress } from "enssdk"; import type { PriceEth } from "@ensnode/ensnode-sdk"; import { makePriceEthSchema } from "@ensnode/ensnode-sdk/internal"; -import { validateAddress } from "./address"; +import { validateNormalizedAddress } from "./address"; import { validateNonNegativeInteger } from "./number"; import { ReferralProgramRules } from "./rules"; import { validateDuration } from "./time"; @@ -60,7 +60,7 @@ export const buildReferrerMetrics = ( }; export const validateReferrerMetrics = (metrics: ReferrerMetrics): void => { - validateAddress(metrics.referrer); + validateNormalizedAddress(metrics.referrer); validateNonNegativeInteger(metrics.totalReferrals); validateDuration(metrics.totalIncrementalDuration);