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);