Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/spotty-peas-run.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@namehash/ens-referrals": minor
"ensapi": minor
Comment thread
Goader marked this conversation as resolved.
---

Rename `BaseReferralProgramRules.subregistryId` to `registryId` everywhere across ENS referrals logic to align with the new ENSv2 terminology. This affects the `ReferralProgramEditionConfig` JSON format consumed via `CUSTOM_REFERRAL_PROGRAM_EDITIONS` and all v1 ENSAnalytics responses that embed referral program rules.
Comment thread
Goader marked this conversation as resolved.
4 changes: 2 additions & 2 deletions apps/ensapi/src/cache/referral-edition-snapshots.cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,11 @@ function createEditionSnapshotBuilder(

const latestIndexedBlockRef = getLatestIndexedBlockRef(
indexingStatus,
editionConfig.rules.subregistryId.chainId,
editionConfig.rules.registryId.chainId,
);
if (latestIndexedBlockRef === null) {
throw new Error(
`Unable to generate edition snapshot for ${editionSlug}. Latest indexed block ref for chain ${editionConfig.rules.subregistryId.chainId} is null.`,
`Unable to generate edition snapshot for ${editionSlug}. Latest indexed block ref for chain ${editionConfig.rules.registryId.chainId} is null.`,
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const getReferrerMetrics = async (
* Step 1: Filter for referrals matching the provided rules:
* - timestamp is between startDate and endDate (inclusive)
* - decodedReferrer is not null and not the zero address
* - subregistryId matches the provided subregistryId
* - registrarActions.subregistryId matches rules.registryId
*
* Step 2: Group by decodedReferrer and calculate:
* - Sum total incrementalDuration for each decodedReferrer
Expand Down Expand Up @@ -68,11 +68,8 @@ export const getReferrerMetrics = async (
isNotNull(ensIndexerSchema.registrarActions.decodedReferrer),
// Filter by decodedReferrer not zero address
ne(ensIndexerSchema.registrarActions.decodedReferrer, zeroAddress),
// Filter by subregistryId matching the provided subregistryId
eq(
ensIndexerSchema.registrarActions.subregistryId,
stringifyAccountId(rules.subregistryId),
),
// Filter by registrarActions.subregistryId matching rules.registryId
eq(ensIndexerSchema.registrarActions.subregistryId, stringifyAccountId(rules.registryId)),
),
)
.groupBy(ensIndexerSchema.registrarActions.decodedReferrer)
Expand All @@ -91,7 +88,7 @@ export const getReferrerMetrics = async (

return (records as NonNullRecord[]).map((record) => {
return buildReferrerMetrics(
{ chainId: rules.subregistryId.chainId, address: record.referrer },
{ chainId: rules.registryId.chainId, address: record.referrer },
record.totalReferrals,
deserializeDuration(record.totalIncrementalDuration),
priceEth(BigInt(record.totalRevenueContribution)),
Expand Down Expand Up @@ -160,11 +157,8 @@ export const getReferralEvents = async (rules: ReferralProgramRules): Promise<Re
isNotNull(ensIndexerSchema.registrarActions.decodedReferrer),
// Filter by decodedReferrer not zero address
ne(ensIndexerSchema.registrarActions.decodedReferrer, zeroAddress),
// Filter by subregistryId matching the provided subregistryId
eq(
ensIndexerSchema.registrarActions.subregistryId,
stringifyAccountId(rules.subregistryId),
),
// Filter by registrarActions.subregistryId matching rules.registryId
eq(ensIndexerSchema.registrarActions.subregistryId, stringifyAccountId(rules.registryId)),
),
)
.orderBy(asc(ensIndexerSchema.registrarActions.id));
Expand Down Expand Up @@ -212,7 +206,7 @@ export const getReferralEvents = async (rules: ReferralProgramRules): Promise<Re
return {
id: record.id,
referrer: {
chainId: rules.subregistryId.chainId,
chainId: rules.registryId.chainId,
address: record.referrer as NormalizedAddress,
},
timestamp: Number(record.timestamp),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {

import { parseEth, parseUsdc } from "@ensnode/ensnode-sdk";

// All mocks live on the pieSplit edition's subregistry chain (Ethereum mainnet).
// All mocks live on the pieSplit edition's registry chain (Ethereum mainnet).
const MOCK_CHAIN_ID = 1;
const acct = (address: Address): AccountId => ({
chainId: MOCK_CHAIN_ID,
Expand All @@ -32,7 +32,7 @@ const pieSplitRules: ReferralProgramRulesPieSplit = {
maxQualifiedReferrers: 10,
startTime: 1735689600,
endTime: 1767225599,
subregistryId: acct("0xd8da6bf26964af9d7eed9e03e53415d37aa96045"),
registryId: acct("0xd8da6bf26964af9d7eed9e03e53415d37aa96045"),
rulesUrl: new URL("https://example.com/rules"),
areAwardsDistributed: false,
};
Expand Down
2 changes: 1 addition & 1 deletion packages/ens-referrals/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ if (response.responseCode === ReferrerLeaderboardPageResponseCodes.Ok) {
console.log(`Unrecognized award model: ${leaderboardPage.originalAwardModel} - skipping`);
} else {
console.log(`Edition: ${editionSlug}`);
console.log(`Subregistry: ${leaderboardPage.rules.subregistryId}`);
console.log(`Registry: ${leaderboardPage.rules.registryId}`);
console.log(`Total Referrers: ${leaderboardPage.pageContext.totalRecords}`);
Comment on lines 72 to 74
console.log(
`Page ${leaderboardPage.pageContext.page} of ${leaderboardPage.pageContext.totalPages}`,
Expand Down
2 changes: 1 addition & 1 deletion packages/ens-referrals/src/api/prerequisites.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
* the `subgraph_domain` table is populated for the names associated with
* each registrar action — read to look up `name` for each row.
*
* Each ENSAnalytics edition is scoped to a single `subregistryId`, so any one
* Each ENSAnalytics edition is scoped to a single `registryId`, so any one
* edition only joins against rows from its own namespace's `subgraph_domain`.
* In theory not all of `subgraph` / `basenames` / `lineanames` are required
* for any single edition. In practice we require all three so that no edition
Expand Down
68 changes: 34 additions & 34 deletions packages/ens-referrals/src/api/zod-schemas.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ import {
describe("makeReferralProgramEditionConfigSetArraySchema", () => {
const schema = makeReferralProgramEditionConfigSetArraySchema();

const subregistryId = {
const registryId = {
chainId: 1,
address: "0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85",
};

// Fixtures share a subregistryId, so their time ranges are chosen to be disjoint
// Fixtures share a registryId, so their time ranges are chosen to be disjoint
// (startTime and endTime are inclusive — abutting ranges count as overlapping).
const pieSplitEdition = {
slug: "2025-12",
Expand All @@ -36,7 +36,7 @@ describe("makeReferralProgramEditionConfigSetArraySchema", () => {
maxQualifiedReferrers: 100,
startTime: 1000000,
endTime: 1999999,
subregistryId,
registryId,
rulesUrl: "https://ensawards.org/rules",
areAwardsDistributed: false,
},
Expand All @@ -53,7 +53,7 @@ describe("makeReferralProgramEditionConfigSetArraySchema", () => {
maxBaseRevenueShare: 0.5,
startTime: 2000000,
endTime: 2500000,
subregistryId,
registryId,
rulesUrl: "https://ensawards.org/rules",
areAwardsDistributed: false,
},
Expand All @@ -66,7 +66,7 @@ describe("makeReferralProgramEditionConfigSetArraySchema", () => {
awardModel: "future-model",
startTime: 2500001,
endTime: 3000000,
subregistryId,
registryId,
rulesUrl: "https://ensawards.org/rules",
areAwardsDistributed: false,
someNewField: "extra-data",
Expand Down Expand Up @@ -143,7 +143,7 @@ describe("makeReferralProgramEditionConfigSetArraySchema", () => {
rules: {
awardModel: "future-model",
// startTime missing, endTime missing
subregistryId,
registryId,
rulesUrl: "https://ensawards.org/rules",
areAwardsDistributed: false,
},
Expand Down Expand Up @@ -180,8 +180,8 @@ describe("makeReferralProgramEditionConfigSetArraySchema", () => {
expect(() => schema.parse([pieSplitEdition, duplicateUnrecognized])).toThrow();
});

describe("non-overlapping time invariant (per subregistryId)", () => {
it("accepts editions for the same subregistry with disjoint time ranges", () => {
describe("non-overlapping time invariant (per registryId)", () => {
it("accepts editions for the same registry with disjoint time ranges", () => {
const earlier = {
...pieSplitEdition,
slug: "2025-12",
Expand All @@ -197,7 +197,7 @@ describe("makeReferralProgramEditionConfigSetArraySchema", () => {
expect(result).toHaveLength(2);
});

it("rejects editions for the same subregistry whose ranges interior-overlap", () => {
it("rejects editions for the same registry whose ranges interior-overlap", () => {
const a = {
...pieSplitEdition,
slug: "a",
Expand Down Expand Up @@ -227,15 +227,15 @@ describe("makeReferralProgramEditionConfigSetArraySchema", () => {
expect(() => schema.parse([a, b])).toThrow(/overlapping time ranges/i);
});

it("accepts overlapping editions when subregistries differ by chainId", () => {
it("accepts overlapping editions when registries differ by chainId", () => {
const a = {
...pieSplitEdition,
slug: "a",
rules: {
...pieSplitEdition.rules,
startTime: 1000,
endTime: 2000,
subregistryId: { ...subregistryId, chainId: 1 },
registryId: { ...registryId, chainId: 1 },
},
};
const b = {
Expand All @@ -245,23 +245,23 @@ describe("makeReferralProgramEditionConfigSetArraySchema", () => {
...revShareCapEdition.rules,
startTime: 1000,
endTime: 2000,
subregistryId: { ...subregistryId, chainId: 8453 },
registryId: { ...registryId, chainId: 8453 },
},
};

const result = schema.parse([a, b]);
expect(result).toHaveLength(2);
});

it("accepts overlapping editions when subregistries differ by address", () => {
it("accepts overlapping editions when registries differ by address", () => {
const a = {
...pieSplitEdition,
slug: "a",
rules: {
...pieSplitEdition.rules,
startTime: 1000,
endTime: 2000,
subregistryId: {
registryId: {
chainId: 1,
address: "0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85",
},
Expand All @@ -274,7 +274,7 @@ describe("makeReferralProgramEditionConfigSetArraySchema", () => {
...revShareCapEdition.rules,
startTime: 1000,
endTime: 2000,
subregistryId: {
registryId: {
chainId: 1,
address: "0x0635513f179d50a207757e05759cbd106d7dfce8",
},
Expand All @@ -285,7 +285,7 @@ describe("makeReferralProgramEditionConfigSetArraySchema", () => {
expect(result).toHaveLength(2);
});

it("rejects an unrecognized edition that overlaps a recognized edition on the same subregistry", () => {
it("rejects an unrecognized edition that overlaps a recognized edition on the same registry", () => {
const recognized = {
...pieSplitEdition,
slug: "recognized",
Expand All @@ -305,7 +305,7 @@ describe("makeReferralProgramEditionConfigSetArraySchema", () => {
describe("makeReferrerLeaderboardPageSchema", () => {
const schema = makeReferrerLeaderboardPageSchema();

const subregistryId = {
const registryId = {
chainId: 1,
address: "0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85",
};
Expand All @@ -327,7 +327,7 @@ describe("makeReferrerLeaderboardPageSchema", () => {
maxQualifiedReferrers: 100,
startTime: 1000000,
endTime: 2000000,
subregistryId,
registryId,
rulesUrl: "https://ensawards.org/rules",
areAwardsDistributed: false,
},
Expand All @@ -354,7 +354,7 @@ describe("makeReferrerLeaderboardPageSchema", () => {
maxBaseRevenueShare: 0.5,
startTime: 1000000,
endTime: 2000000,
subregistryId,
registryId,
rulesUrl: "https://ensawards.org/rules",
areAwardsDistributed: false,
},
Expand Down Expand Up @@ -430,7 +430,7 @@ describe("makeReferrerLeaderboardPageSchema", () => {
describe("makeReferralProgramEditionSummarySchema", () => {
const schema = makeReferralProgramEditionSummarySchema();

const subregistryId = {
const registryId = {
chainId: 1,
address: "0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85",
};
Expand All @@ -446,7 +446,7 @@ describe("makeReferralProgramEditionSummarySchema", () => {
maxQualifiedReferrers: 100,
startTime: 1000000,
endTime: 2000000,
subregistryId,
registryId,
rulesUrl: "https://ensawards.org/rules",
areAwardsDistributed: false,
},
Expand All @@ -465,7 +465,7 @@ describe("makeReferralProgramEditionSummarySchema", () => {
maxBaseRevenueShare: 0.5,
startTime: 1000000,
endTime: 2000000,
subregistryId,
registryId,
rulesUrl: "https://ensawards.org/rules",
areAwardsDistributed: false,
},
Expand Down Expand Up @@ -510,7 +510,7 @@ describe("makeReferralProgramEditionSummarySchema", () => {
awardModel: "future-model",
startTime: 2000000,
endTime: 3000000,
subregistryId,
registryId,
rulesUrl: "https://ensawards.org/rules",
areAwardsDistributed: false,
someNewField: "extra-data",
Expand Down Expand Up @@ -552,7 +552,7 @@ describe("makeReferralProgramEditionSummarySchema", () => {
describe("makeReferralProgramEditionSummariesDataSchema — non-overlapping time invariant", () => {
const schema = makeReferralProgramEditionSummariesDataSchema();

const subregistryId = {
const registryId = {
chainId: 1,
address: "0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85",
};
Expand All @@ -561,7 +561,7 @@ describe("makeReferralProgramEditionSummariesDataSchema — non-overlapping time
slug: string,
startTime: number,
endTime: number,
registry = subregistryId,
registry = registryId,
) => ({
awardModel: ReferralProgramAwardModels.PieSplit,
slug,
Expand All @@ -573,20 +573,20 @@ describe("makeReferralProgramEditionSummariesDataSchema — non-overlapping time
maxQualifiedReferrers: 100,
startTime,
endTime,
subregistryId: registry,
registryId: registry,
rulesUrl: "https://ensawards.org/rules",
areAwardsDistributed: false,
},
});

it("accepts summaries for the same subregistry with disjoint time ranges", () => {
it("accepts summaries for the same registry with disjoint time ranges", () => {
const result = schema.parse({
editions: [makePieSplitSummary("a", 1000, 1999), makePieSplitSummary("b", 2000, 3000)],
});
expect(result.editions).toHaveLength(2);
});

it("rejects summaries for the same subregistry whose ranges interior-overlap", () => {
it("rejects summaries for the same registry whose ranges interior-overlap", () => {
expect(() =>
schema.parse({
editions: [makePieSplitSummary("a", 1000, 2500), makePieSplitSummary("b", 2000, 3000)],
Expand All @@ -602,11 +602,11 @@ describe("makeReferralProgramEditionSummariesDataSchema — non-overlapping time
).toThrow(/overlapping time ranges/i);
});

it("accepts overlapping summaries when subregistries differ", () => {
it("accepts overlapping summaries when registries differ", () => {
const result = schema.parse({
editions: [
makePieSplitSummary("a", 1000, 2000, { ...subregistryId, chainId: 1 }),
makePieSplitSummary("b", 1000, 2000, { ...subregistryId, chainId: 8453 }),
makePieSplitSummary("a", 1000, 2000, { ...registryId, chainId: 1 }),
makePieSplitSummary("b", 1000, 2000, { ...registryId, chainId: 8453 }),
],
});
expect(result.editions).toHaveLength(2);
Expand All @@ -620,7 +620,7 @@ describe("makeReferralProgramEditionSummariesDataSchema — non-overlapping time
describe("makeReferrerEditionMetricsSchema", () => {
const schema = makeReferrerEditionMetricsSchema();

const subregistryId = {
const registryId = {
chainId: 1,
address: "0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85",
};
Expand All @@ -631,7 +631,7 @@ describe("makeReferrerEditionMetricsSchema", () => {
maxQualifiedReferrers: 100,
startTime: 1000000,
endTime: 2000000,
subregistryId,
registryId,
rulesUrl: "https://ensawards.org/rules",
areAwardsDistributed: false,
};
Expand All @@ -657,7 +657,7 @@ describe("makeReferrerEditionMetricsSchema", () => {
maxBaseRevenueShare: 0.5,
startTime: 1000000,
endTime: 2000000,
subregistryId,
registryId,
rulesUrl: "https://ensawards.org/rules",
areAwardsDistributed: false,
};
Expand Down
Loading
Loading