From df6813e7368fa50e62aa6329bf9fc8283fa4ce99 Mon Sep 17 00:00:00 2001 From: KONFeature Date: Fri, 13 Dec 2024 18:25:42 +0100 Subject: [PATCH 01/11] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Upgrade=20ponder=20t?= =?UTF-8?q?o=20v0.8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bun.lockb | Bin 280629 -> 280612 bytes infra/utils.ts | 2 ++ packages/ponder/config/configBuilder.ts | 15 ++++---- packages/ponder/package.json | 2 +- packages/ponder/ponder-env.d.ts | 34 ++++++------------ packages/ponder/ponder.schema.ts | 2 +- packages/ponder/src/api/admin.ts | 8 ++--- packages/ponder/src/api/campaign.ts | 6 ++-- packages/ponder/src/api/index.ts | 2 +- packages/ponder/src/api/interactions.ts | 8 ++--- packages/ponder/src/api/members.ts | 20 +++++------ packages/ponder/src/api/products.ts | 8 ++--- packages/ponder/src/api/rewards.ts | 8 ++--- packages/ponder/src/api/stats.ts | 6 ++-- packages/ponder/src/api/tokens.ts | 6 ++-- packages/ponder/src/campaign/campaignBank.ts | 4 +-- .../ponder/src/campaign/campaignCreation.ts | 4 +-- .../src/campaign/campaignInteractionLink.ts | 7 ++-- packages/ponder/src/campaign/campaignReset.ts | 4 +-- .../ponder/src/campaign/campaignReward.ts | 8 ++--- packages/ponder/src/interactionDeployments.ts | 4 +-- .../src/interactions/pressInteractions.ts | 4 +-- .../src/interactions/purchaseInteractions.ts | 4 +-- .../src/interactions/referralInteractions.ts | 4 +-- packages/ponder/src/interactions/stats.ts | 10 +++--- .../src/interactions/webshopInteractions.ts | 4 +-- packages/ponder/src/product.ts | 4 +-- packages/ponder/src/productAdministrator.ts | 4 +-- packages/ponder/src/token.ts | 4 +-- 29 files changed, 92 insertions(+), 104 deletions(-) diff --git a/bun.lockb b/bun.lockb index 8430dfad10b1ae31e3b77bba069c40b718f71623..830c6d676509c5921877b59fac6fe097f4c4fe82 100755 GIT binary patch delta 25369 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 referralFeatureFacetAbi, purchaseFeatureFacetAbi, ]), - factory: { + address: factory({ address: deployedAddresses.productInteractionManager as Address, event: parseAbiItem( "event InteractionContractDeployed(uint256 indexed productId, address interactionContract)" ), parameter: "interactionContract", - }, + }), network: contractNetworkConfig, }, // The campaign factory @@ -236,13 +237,13 @@ export function createEnvConfig({ // Every campaigns Campaigns: { abi: mergeAbis([interactionCampaignAbi, referralCampaignAbi]), - factory: { + address: factory({ address: deployedAddresses.campaignFactory as Address, event: parseAbiItem( "event CampaignCreated(address campaign)" ), parameter: "campaign", - }, + }), network: contractNetworkConfig, }, // The campaign banks factory @@ -254,13 +255,13 @@ export function createEnvConfig({ // Every campaign banks CampaignBanks: { abi: campaignBankAbi, - factory: { + address: factory({ address: deployedAddresses.campaignBankFactory as Address, event: parseAbiItem( "event CampaignBankCreated(address campaignBank)" ), parameter: "campaignBank", - }, + }), network: contractNetworkConfig, }, }, diff --git a/packages/ponder/package.json b/packages/ponder/package.json index 4af5b27..f538ee1 100644 --- a/packages/ponder/package.json +++ b/packages/ponder/package.json @@ -21,9 +21,9 @@ "docker:run": "docker run -P ponder-dev" }, "dependencies": { - "@ponder/core": "0.7.17", "drizzle-orm": "0.36.4", "hono": "4.6.13", + "ponder": "^0.8.2", "viem": "^2.21.54" }, "devDependencies": { diff --git a/packages/ponder/ponder-env.d.ts b/packages/ponder/ponder-env.d.ts index e7f3009..b8c6a63 100644 --- a/packages/ponder/ponder-env.d.ts +++ b/packages/ponder/ponder-env.d.ts @@ -1,27 +1,15 @@ +/// + +declare module "ponder:internal" { + const config: typeof import("./ponder.config.ts"); + const schema: typeof import("./ponder.schema.ts"); +} + +declare module "ponder:schema" { + export * from "./ponder.schema.ts"; +} + // This file enables type checking and editor autocomplete for this Ponder project. // After upgrading, you may find that changes have been made to this file. // If this happens, please commit the changes. Do not manually edit this file. // See https://ponder.sh/docs/getting-started/installation#typescript for more information. - -declare module "@/generated" { - import type { Virtual } from "@ponder/core"; - - type config = typeof import("./ponder.config.ts").default; - type schema = typeof import("./ponder.schema.ts"); - - export const ponder: Virtual.Registry; - - export type EventNames = Virtual.EventNames; - export type Event = Virtual.Event< - config, - name - >; - export type Context = Virtual.Context< - config, - schema, - name - >; - export type ApiContext = Virtual.ApiContext; - export type IndexingFunctionArgs = - Virtual.IndexingFunctionArgs; -} diff --git a/packages/ponder/ponder.schema.ts b/packages/ponder/ponder.schema.ts index 945e692..8102538 100644 --- a/packages/ponder/ponder.schema.ts +++ b/packages/ponder/ponder.schema.ts @@ -1,4 +1,4 @@ -import { index, onchainEnum, onchainTable, primaryKey } from "@ponder/core"; +import { index, onchainEnum, onchainTable, primaryKey } from "ponder"; /* -------------------------------------------------------------------------- */ /* Product related stuff */ diff --git a/packages/ponder/src/api/admin.ts b/packages/ponder/src/api/admin.ts index 1b8e3aa..38d89ac 100644 --- a/packages/ponder/src/api/admin.ts +++ b/packages/ponder/src/api/admin.ts @@ -1,6 +1,4 @@ -import { ponder } from "@/generated"; -import { countDistinct, eq, inArray } from "@ponder/core"; -import { type Address, isAddress } from "viem"; +import { ponder } from "ponder:registry"; import { campaignTable, interactionEventTable, @@ -8,7 +6,9 @@ import { productInteractionContractTable, productTable, referralCampaignStatsTable, -} from "../../ponder.schema"; +} from "ponder:schema"; +import { countDistinct, eq, inArray } from "ponder"; +import { type Address, isAddress } from "viem"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: Unreachable code error diff --git a/packages/ponder/src/api/campaign.ts b/packages/ponder/src/api/campaign.ts index d7e9da3..1c3797e 100644 --- a/packages/ponder/src/api/campaign.ts +++ b/packages/ponder/src/api/campaign.ts @@ -1,7 +1,7 @@ -import { ponder } from "@/generated"; -import { eq } from "@ponder/core"; +import { ponder } from "ponder:registry"; +import { bankingContractTable, campaignTable } from "ponder:schema"; +import { eq } from "ponder"; import { type Address, type Hex, isAddress, isHex } from "viem"; -import { bankingContractTable, campaignTable } from "../../ponder.schema"; import { getTokens } from "./tokens"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment diff --git a/packages/ponder/src/api/index.ts b/packages/ponder/src/api/index.ts index c402444..9fa0fa9 100644 --- a/packages/ponder/src/api/index.ts +++ b/packages/ponder/src/api/index.ts @@ -1,4 +1,4 @@ -import { ponder } from "@/generated"; +import { ponder } from "ponder:registry"; ponder.get("/hello", async ({ text }) => { return text("Hello!"); diff --git a/packages/ponder/src/api/interactions.ts b/packages/ponder/src/api/interactions.ts index a31b58f..fc81031 100644 --- a/packages/ponder/src/api/interactions.ts +++ b/packages/ponder/src/api/interactions.ts @@ -1,11 +1,11 @@ -import { ponder } from "@/generated"; -import { desc, eq } from "@ponder/core"; -import { type Address, isAddress } from "viem"; +import { ponder } from "ponder:registry"; import { interactionEventTable, productInteractionContractTable, productTable, -} from "../../ponder.schema"; +} from "ponder:schema"; +import { desc, eq } from "ponder"; +import { type Address, isAddress } from "viem"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: Unreachable code error diff --git a/packages/ponder/src/api/members.ts b/packages/ponder/src/api/members.ts index c3332c3..6bf2310 100644 --- a/packages/ponder/src/api/members.ts +++ b/packages/ponder/src/api/members.ts @@ -1,4 +1,12 @@ -import { ponder } from "@/generated"; +import { ponder } from "ponder:registry"; +import { + interactionEventTable, + productAdministratorTable, + productInteractionContractTable, + productTable, + rewardTable, +} from "ponder:schema"; +import type { SQL } from "drizzle-orm"; import { and, asc, @@ -12,16 +20,8 @@ import { min, sql, sum, -} from "@ponder/core"; -import type { SQL } from "drizzle-orm"; +} from "ponder"; import { type Address, type Hex, isAddress } from "viem"; -import { - interactionEventTable, - productAdministratorTable, - productInteractionContractTable, - productTable, - rewardTable, -} from "../../ponder.schema"; /** * Params for the members fetching diff --git a/packages/ponder/src/api/products.ts b/packages/ponder/src/api/products.ts index 5ae470a..9da7ab7 100644 --- a/packages/ponder/src/api/products.ts +++ b/packages/ponder/src/api/products.ts @@ -1,6 +1,4 @@ -import { ponder } from "@/generated"; -import { eq, inArray } from "@ponder/core"; -import { type Hex, isHex, keccak256, toHex } from "viem"; +import { ponder } from "ponder:registry"; import { bankingContractTable, campaignTable, @@ -9,7 +7,9 @@ import { productTable, referralCampaignStatsTable, tokenTable, -} from "../../ponder.schema"; +} from "ponder:schema"; +import { eq, inArray } from "ponder"; +import { type Hex, isHex, keccak256, toHex } from "viem"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: Unreachable code error diff --git a/packages/ponder/src/api/rewards.ts b/packages/ponder/src/api/rewards.ts index 393f3f0..c316619 100644 --- a/packages/ponder/src/api/rewards.ts +++ b/packages/ponder/src/api/rewards.ts @@ -1,13 +1,13 @@ -import { ponder } from "@/generated"; -import { and, desc, eq, not } from "@ponder/core"; -import { type Address, isAddress } from "viem"; +import { ponder } from "ponder:registry"; import { bankingContractTable, productTable, rewardAddedEventTable, rewardClaimedEventTable, rewardTable, -} from "../../ponder.schema"; +} from "ponder:schema"; +import { and, desc, eq, not } from "ponder"; +import { type Address, isAddress } from "viem"; import { getTokens } from "./tokens"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment diff --git a/packages/ponder/src/api/stats.ts b/packages/ponder/src/api/stats.ts index 909bed2..97c0695 100644 --- a/packages/ponder/src/api/stats.ts +++ b/packages/ponder/src/api/stats.ts @@ -1,10 +1,10 @@ -import { ponder } from "@/generated"; -import { count, countDistinct, eq, gte } from "@ponder/core"; +import { ponder } from "ponder:registry"; import { interactionEventTable, productInteractionContractTable, productTable, -} from "../../ponder.schema"; +} from "ponder:schema"; +import { count, countDistinct, eq, gte } from "ponder"; /** * Get the overall system stats diff --git a/packages/ponder/src/api/tokens.ts b/packages/ponder/src/api/tokens.ts index 8a399ec..2f3b699 100644 --- a/packages/ponder/src/api/tokens.ts +++ b/packages/ponder/src/api/tokens.ts @@ -1,7 +1,7 @@ -import { type ApiContext, ponder } from "@/generated"; -import { eq, inArray } from "@ponder/core"; +import { type ApiContext, ponder } from "ponder:registry"; +import { tokenTable } from "ponder:schema"; +import { eq, inArray } from "ponder"; import { type Address, isAddress } from "viem"; -import { tokenTable } from "../../ponder.schema"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: Unreachable code error diff --git a/packages/ponder/src/campaign/campaignBank.ts b/packages/ponder/src/campaign/campaignBank.ts index f23406b..67c590b 100644 --- a/packages/ponder/src/campaign/campaignBank.ts +++ b/packages/ponder/src/campaign/campaignBank.ts @@ -1,8 +1,8 @@ import * as console from "node:console"; -import { type Context, ponder } from "@/generated"; +import { type Context, ponder } from "ponder:registry"; +import { bankingContractTable, campaignTable } from "ponder:schema"; import { type Address, isAddressEqual } from "viem"; import { campaignBankAbi } from "../../abis/campaignAbis"; -import { bankingContractTable, campaignTable } from "../../ponder.schema"; import { upsertTokenIfNeeded } from "../token"; ponder.on( diff --git a/packages/ponder/src/campaign/campaignCreation.ts b/packages/ponder/src/campaign/campaignCreation.ts index 35577c6..2c655cf 100644 --- a/packages/ponder/src/campaign/campaignCreation.ts +++ b/packages/ponder/src/campaign/campaignCreation.ts @@ -1,10 +1,10 @@ -import { type Context, ponder } from "@/generated"; +import { type Context, ponder } from "ponder:registry"; +import { campaignTable, referralCampaignStatsTable } from "ponder:schema"; import type { Address } from "viem"; import { interactionCampaignAbi, referralCampaignAbi, } from "../../abis/campaignAbis"; -import { campaignTable, referralCampaignStatsTable } from "../../ponder.schema"; import { emptyCampaignStats } from "../interactions/stats"; import { bytesToString } from "../utils/format"; diff --git a/packages/ponder/src/campaign/campaignInteractionLink.ts b/packages/ponder/src/campaign/campaignInteractionLink.ts index 1af7bbb..3b28d9b 100644 --- a/packages/ponder/src/campaign/campaignInteractionLink.ts +++ b/packages/ponder/src/campaign/campaignInteractionLink.ts @@ -1,8 +1,5 @@ -import { ponder } from "@/generated"; -import { - campaignTable, - productInteractionContractTable, -} from "../../ponder.schema"; +import { ponder } from "ponder:registry"; +import { campaignTable, productInteractionContractTable } from "ponder:schema"; import { upsertNewCampaign } from "./campaignCreation"; ponder.on("ProductInteraction:CampaignAttached", async ({ event, context }) => { diff --git a/packages/ponder/src/campaign/campaignReset.ts b/packages/ponder/src/campaign/campaignReset.ts index eb997a9..9ab33e2 100644 --- a/packages/ponder/src/campaign/campaignReset.ts +++ b/packages/ponder/src/campaign/campaignReset.ts @@ -1,5 +1,5 @@ -import { ponder } from "@/generated"; -import { campaignCapResetTable } from "../../ponder.schema"; +import { ponder } from "ponder:registry"; +import { campaignCapResetTable } from "ponder:schema"; ponder.on( "Campaigns:DistributionCapReset", diff --git a/packages/ponder/src/campaign/campaignReward.ts b/packages/ponder/src/campaign/campaignReward.ts index 4825719..f697b22 100644 --- a/packages/ponder/src/campaign/campaignReward.ts +++ b/packages/ponder/src/campaign/campaignReward.ts @@ -1,10 +1,10 @@ -import { ponder } from "@/generated"; +import { ponder } from "ponder:registry"; import { bankingContractTable, rewardAddedEventTable, rewardClaimedEventTable, rewardTable, -} from "../../ponder.schema"; +} from "ponder:schema"; import { safeIncreaseCampaignsStats } from "../interactions/stats"; ponder.on("CampaignBanks:RewardAdded", async ({ event, context }) => { @@ -49,7 +49,7 @@ ponder.on("CampaignBanks:RewardAdded", async ({ event, context }) => { user: event.args.user, emitter: event.args.emitter, amount: event.args.amount, - txHash: event.log.transactionHash, + txHash: event.transaction.hash, timestamp: event.block.timestamp, }); @@ -104,7 +104,7 @@ ponder.on("CampaignBanks:RewardClaimed", async ({ event, context: { db } }) => { contractId: bankingContract.id, user: event.args.user, amount: event.args.amount, - txHash: event.log.transactionHash, + txHash: event.transaction.hash, timestamp: event.block.timestamp, }); }); diff --git a/packages/ponder/src/interactionDeployments.ts b/packages/ponder/src/interactionDeployments.ts index 4c24e46..1821543 100644 --- a/packages/ponder/src/interactionDeployments.ts +++ b/packages/ponder/src/interactionDeployments.ts @@ -1,6 +1,6 @@ -import { ponder } from "@/generated"; +import { ponder } from "ponder:registry"; +import { productInteractionContractTable } from "ponder:schema"; import { productInteractionDiamondAbi } from "../abis/interactionAbis"; -import { productInteractionContractTable } from "../ponder.schema"; ponder.on( "ProductInteractionManager:InteractionContractDeployed", diff --git a/packages/ponder/src/interactions/pressInteractions.ts b/packages/ponder/src/interactions/pressInteractions.ts index 01940d0..fc716e8 100644 --- a/packages/ponder/src/interactions/pressInteractions.ts +++ b/packages/ponder/src/interactions/pressInteractions.ts @@ -1,5 +1,5 @@ -import { ponder } from "@/generated"; -import { interactionEventTable } from "../../ponder.schema"; +import { ponder } from "ponder:registry"; +import { interactionEventTable } from "ponder:schema"; import { safeIncreaseCampaignsStats } from "./stats"; ponder.on("ProductInteraction:ArticleRead", async ({ event, context }) => { diff --git a/packages/ponder/src/interactions/purchaseInteractions.ts b/packages/ponder/src/interactions/purchaseInteractions.ts index 1ecc377..c2dbb6a 100644 --- a/packages/ponder/src/interactions/purchaseInteractions.ts +++ b/packages/ponder/src/interactions/purchaseInteractions.ts @@ -1,5 +1,5 @@ -import { ponder } from "@/generated"; -import { interactionEventTable } from "../../ponder.schema"; +import { ponder } from "ponder:registry"; +import { interactionEventTable } from "ponder:schema"; import { safeIncreaseCampaignsStats } from "./stats"; ponder.on("ProductInteraction:PurchaseStarted", async ({ event, context }) => { diff --git a/packages/ponder/src/interactions/referralInteractions.ts b/packages/ponder/src/interactions/referralInteractions.ts index e8a4478..5a560ae 100644 --- a/packages/ponder/src/interactions/referralInteractions.ts +++ b/packages/ponder/src/interactions/referralInteractions.ts @@ -1,5 +1,5 @@ -import { ponder } from "@/generated"; -import { interactionEventTable } from "../../ponder.schema"; +import { ponder } from "ponder:registry"; +import { interactionEventTable } from "ponder:schema"; import { safeIncreaseCampaignsStats } from "./stats"; ponder.on( diff --git a/packages/ponder/src/interactions/stats.ts b/packages/ponder/src/interactions/stats.ts index 5015a71..b7544b6 100644 --- a/packages/ponder/src/interactions/stats.ts +++ b/packages/ponder/src/interactions/stats.ts @@ -1,12 +1,12 @@ -import type { Context } from "@/generated"; -import { and, desc, eq } from "@ponder/core"; -import type { Address } from "viem"; -import { interactionCampaignAbi } from "../../abis/campaignAbis"; +import type { Context } from "ponder:registry"; import { campaignTable, productInteractionContractTable, referralCampaignStatsTable, -} from "../../ponder.schema"; +} from "ponder:schema"; +import { and, desc, eq } from "ponder"; +import type { Address } from "viem"; +import { interactionCampaignAbi } from "../../abis/campaignAbis"; /** * Default campaign stats diff --git a/packages/ponder/src/interactions/webshopInteractions.ts b/packages/ponder/src/interactions/webshopInteractions.ts index 4720fa8..880ebf7 100644 --- a/packages/ponder/src/interactions/webshopInteractions.ts +++ b/packages/ponder/src/interactions/webshopInteractions.ts @@ -1,5 +1,5 @@ -import { ponder } from "@/generated"; -import { interactionEventTable } from "../../ponder.schema"; +import { ponder } from "ponder:registry"; +import { interactionEventTable } from "ponder:schema"; import { safeIncreaseCampaignsStats } from "./stats"; ponder.on("ProductInteraction:WebShopOpenned", async ({ event, context }) => { diff --git a/packages/ponder/src/product.ts b/packages/ponder/src/product.ts index 4e30820..d21e95c 100644 --- a/packages/ponder/src/product.ts +++ b/packages/ponder/src/product.ts @@ -1,6 +1,6 @@ -import { ponder } from "@/generated"; +import { ponder } from "ponder:registry"; +import { productTable } from "ponder:schema"; import { productRegistryAbi } from "../abis/registryAbis"; -import { productTable } from "../ponder.schema"; import { bytesToString } from "./utils/format"; ponder.on("ProductRegistry:ProductMinted", async ({ event, context }) => { diff --git a/packages/ponder/src/productAdministrator.ts b/packages/ponder/src/productAdministrator.ts index 1d293ab..8bcb663 100644 --- a/packages/ponder/src/productAdministrator.ts +++ b/packages/ponder/src/productAdministrator.ts @@ -1,6 +1,6 @@ -import { type Context, ponder } from "@/generated"; +import { type Context, ponder } from "ponder:registry"; +import { productAdministratorTable } from "ponder:schema"; import { isAddressEqual, zeroAddress } from "viem"; -import { productAdministratorTable } from "../ponder.schema"; /* * Handle transfer stuff diff --git a/packages/ponder/src/token.ts b/packages/ponder/src/token.ts index e1180f9..f049b72 100644 --- a/packages/ponder/src/token.ts +++ b/packages/ponder/src/token.ts @@ -1,7 +1,7 @@ import console from "node:console"; -import type { Context } from "@/generated"; +import type { Context } from "ponder:registry"; +import { tokenTable } from "ponder:schema"; import { type Address, erc20Abi } from "viem"; -import { tokenTable } from "../ponder.schema"; export async function upsertTokenIfNeeded({ address, From 1bfa6922e8a51cf2ea2d45436cc80c33f3158a7b Mon Sep 17 00:00:00 2001 From: KONFeature Date: Sat, 14 Dec 2024 20:36:16 +0100 Subject: [PATCH 02/11] =?UTF-8?q?Revert=20"=E2=AC=86=EF=B8=8F=20Upgrade=20?= =?UTF-8?q?ponder=20to=20v0.8"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit df6813e7368fa50e62aa6329bf9fc8283fa4ce99. --- bun.lockb | Bin 280612 -> 280629 bytes infra/utils.ts | 2 -- packages/ponder/config/configBuilder.ts | 15 ++++---- packages/ponder/package.json | 2 +- packages/ponder/ponder-env.d.ts | 34 ++++++++++++------ packages/ponder/ponder.schema.ts | 2 +- packages/ponder/src/api/admin.ts | 8 ++--- packages/ponder/src/api/campaign.ts | 6 ++-- packages/ponder/src/api/index.ts | 2 +- packages/ponder/src/api/interactions.ts | 8 ++--- packages/ponder/src/api/members.ts | 20 +++++------ packages/ponder/src/api/products.ts | 8 ++--- packages/ponder/src/api/rewards.ts | 8 ++--- packages/ponder/src/api/stats.ts | 6 ++-- packages/ponder/src/api/tokens.ts | 6 ++-- packages/ponder/src/campaign/campaignBank.ts | 4 +-- .../ponder/src/campaign/campaignCreation.ts | 4 +-- .../src/campaign/campaignInteractionLink.ts | 7 ++-- packages/ponder/src/campaign/campaignReset.ts | 4 +-- .../ponder/src/campaign/campaignReward.ts | 8 ++--- packages/ponder/src/interactionDeployments.ts | 4 +-- .../src/interactions/pressInteractions.ts | 4 +-- .../src/interactions/purchaseInteractions.ts | 4 +-- .../src/interactions/referralInteractions.ts | 4 +-- packages/ponder/src/interactions/stats.ts | 10 +++--- .../src/interactions/webshopInteractions.ts | 4 +-- packages/ponder/src/product.ts | 4 +-- packages/ponder/src/productAdministrator.ts | 4 +-- packages/ponder/src/token.ts | 4 +-- 29 files changed, 104 insertions(+), 92 deletions(-) diff --git a/bun.lockb b/bun.lockb index 830c6d676509c5921877b59fac6fe097f4c4fe82..8430dfad10b1ae31e3b77bba069c40b718f71623 100755 GIT binary patch delta 24014 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 ycIuV({ referralFeatureFacetAbi, purchaseFeatureFacetAbi, ]), - address: factory({ + factory: { address: deployedAddresses.productInteractionManager as Address, event: parseAbiItem( "event InteractionContractDeployed(uint256 indexed productId, address interactionContract)" ), parameter: "interactionContract", - }), + }, network: contractNetworkConfig, }, // The campaign factory @@ -237,13 +236,13 @@ export function createEnvConfig({ // Every campaigns Campaigns: { abi: mergeAbis([interactionCampaignAbi, referralCampaignAbi]), - address: factory({ + factory: { address: deployedAddresses.campaignFactory as Address, event: parseAbiItem( "event CampaignCreated(address campaign)" ), parameter: "campaign", - }), + }, network: contractNetworkConfig, }, // The campaign banks factory @@ -255,13 +254,13 @@ export function createEnvConfig({ // Every campaign banks CampaignBanks: { abi: campaignBankAbi, - address: factory({ + factory: { address: deployedAddresses.campaignBankFactory as Address, event: parseAbiItem( "event CampaignBankCreated(address campaignBank)" ), parameter: "campaignBank", - }), + }, network: contractNetworkConfig, }, }, diff --git a/packages/ponder/package.json b/packages/ponder/package.json index f538ee1..4af5b27 100644 --- a/packages/ponder/package.json +++ b/packages/ponder/package.json @@ -21,9 +21,9 @@ "docker:run": "docker run -P ponder-dev" }, "dependencies": { + "@ponder/core": "0.7.17", "drizzle-orm": "0.36.4", "hono": "4.6.13", - "ponder": "^0.8.2", "viem": "^2.21.54" }, "devDependencies": { diff --git a/packages/ponder/ponder-env.d.ts b/packages/ponder/ponder-env.d.ts index b8c6a63..e7f3009 100644 --- a/packages/ponder/ponder-env.d.ts +++ b/packages/ponder/ponder-env.d.ts @@ -1,15 +1,27 @@ -/// - -declare module "ponder:internal" { - const config: typeof import("./ponder.config.ts"); - const schema: typeof import("./ponder.schema.ts"); -} - -declare module "ponder:schema" { - export * from "./ponder.schema.ts"; -} - // This file enables type checking and editor autocomplete for this Ponder project. // After upgrading, you may find that changes have been made to this file. // If this happens, please commit the changes. Do not manually edit this file. // See https://ponder.sh/docs/getting-started/installation#typescript for more information. + +declare module "@/generated" { + import type { Virtual } from "@ponder/core"; + + type config = typeof import("./ponder.config.ts").default; + type schema = typeof import("./ponder.schema.ts"); + + export const ponder: Virtual.Registry; + + export type EventNames = Virtual.EventNames; + export type Event = Virtual.Event< + config, + name + >; + export type Context = Virtual.Context< + config, + schema, + name + >; + export type ApiContext = Virtual.ApiContext; + export type IndexingFunctionArgs = + Virtual.IndexingFunctionArgs; +} diff --git a/packages/ponder/ponder.schema.ts b/packages/ponder/ponder.schema.ts index 8102538..945e692 100644 --- a/packages/ponder/ponder.schema.ts +++ b/packages/ponder/ponder.schema.ts @@ -1,4 +1,4 @@ -import { index, onchainEnum, onchainTable, primaryKey } from "ponder"; +import { index, onchainEnum, onchainTable, primaryKey } from "@ponder/core"; /* -------------------------------------------------------------------------- */ /* Product related stuff */ diff --git a/packages/ponder/src/api/admin.ts b/packages/ponder/src/api/admin.ts index 38d89ac..1b8e3aa 100644 --- a/packages/ponder/src/api/admin.ts +++ b/packages/ponder/src/api/admin.ts @@ -1,4 +1,6 @@ -import { ponder } from "ponder:registry"; +import { ponder } from "@/generated"; +import { countDistinct, eq, inArray } from "@ponder/core"; +import { type Address, isAddress } from "viem"; import { campaignTable, interactionEventTable, @@ -6,9 +8,7 @@ import { productInteractionContractTable, productTable, referralCampaignStatsTable, -} from "ponder:schema"; -import { countDistinct, eq, inArray } from "ponder"; -import { type Address, isAddress } from "viem"; +} from "../../ponder.schema"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: Unreachable code error diff --git a/packages/ponder/src/api/campaign.ts b/packages/ponder/src/api/campaign.ts index 1c3797e..d7e9da3 100644 --- a/packages/ponder/src/api/campaign.ts +++ b/packages/ponder/src/api/campaign.ts @@ -1,7 +1,7 @@ -import { ponder } from "ponder:registry"; -import { bankingContractTable, campaignTable } from "ponder:schema"; -import { eq } from "ponder"; +import { ponder } from "@/generated"; +import { eq } from "@ponder/core"; import { type Address, type Hex, isAddress, isHex } from "viem"; +import { bankingContractTable, campaignTable } from "../../ponder.schema"; import { getTokens } from "./tokens"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment diff --git a/packages/ponder/src/api/index.ts b/packages/ponder/src/api/index.ts index 9fa0fa9..c402444 100644 --- a/packages/ponder/src/api/index.ts +++ b/packages/ponder/src/api/index.ts @@ -1,4 +1,4 @@ -import { ponder } from "ponder:registry"; +import { ponder } from "@/generated"; ponder.get("/hello", async ({ text }) => { return text("Hello!"); diff --git a/packages/ponder/src/api/interactions.ts b/packages/ponder/src/api/interactions.ts index fc81031..a31b58f 100644 --- a/packages/ponder/src/api/interactions.ts +++ b/packages/ponder/src/api/interactions.ts @@ -1,11 +1,11 @@ -import { ponder } from "ponder:registry"; +import { ponder } from "@/generated"; +import { desc, eq } from "@ponder/core"; +import { type Address, isAddress } from "viem"; import { interactionEventTable, productInteractionContractTable, productTable, -} from "ponder:schema"; -import { desc, eq } from "ponder"; -import { type Address, isAddress } from "viem"; +} from "../../ponder.schema"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: Unreachable code error diff --git a/packages/ponder/src/api/members.ts b/packages/ponder/src/api/members.ts index 6bf2310..c3332c3 100644 --- a/packages/ponder/src/api/members.ts +++ b/packages/ponder/src/api/members.ts @@ -1,12 +1,4 @@ -import { ponder } from "ponder:registry"; -import { - interactionEventTable, - productAdministratorTable, - productInteractionContractTable, - productTable, - rewardTable, -} from "ponder:schema"; -import type { SQL } from "drizzle-orm"; +import { ponder } from "@/generated"; import { and, asc, @@ -20,8 +12,16 @@ import { min, sql, sum, -} from "ponder"; +} from "@ponder/core"; +import type { SQL } from "drizzle-orm"; import { type Address, type Hex, isAddress } from "viem"; +import { + interactionEventTable, + productAdministratorTable, + productInteractionContractTable, + productTable, + rewardTable, +} from "../../ponder.schema"; /** * Params for the members fetching diff --git a/packages/ponder/src/api/products.ts b/packages/ponder/src/api/products.ts index 9da7ab7..5ae470a 100644 --- a/packages/ponder/src/api/products.ts +++ b/packages/ponder/src/api/products.ts @@ -1,4 +1,6 @@ -import { ponder } from "ponder:registry"; +import { ponder } from "@/generated"; +import { eq, inArray } from "@ponder/core"; +import { type Hex, isHex, keccak256, toHex } from "viem"; import { bankingContractTable, campaignTable, @@ -7,9 +9,7 @@ import { productTable, referralCampaignStatsTable, tokenTable, -} from "ponder:schema"; -import { eq, inArray } from "ponder"; -import { type Hex, isHex, keccak256, toHex } from "viem"; +} from "../../ponder.schema"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: Unreachable code error diff --git a/packages/ponder/src/api/rewards.ts b/packages/ponder/src/api/rewards.ts index c316619..393f3f0 100644 --- a/packages/ponder/src/api/rewards.ts +++ b/packages/ponder/src/api/rewards.ts @@ -1,13 +1,13 @@ -import { ponder } from "ponder:registry"; +import { ponder } from "@/generated"; +import { and, desc, eq, not } from "@ponder/core"; +import { type Address, isAddress } from "viem"; import { bankingContractTable, productTable, rewardAddedEventTable, rewardClaimedEventTable, rewardTable, -} from "ponder:schema"; -import { and, desc, eq, not } from "ponder"; -import { type Address, isAddress } from "viem"; +} from "../../ponder.schema"; import { getTokens } from "./tokens"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment diff --git a/packages/ponder/src/api/stats.ts b/packages/ponder/src/api/stats.ts index 97c0695..909bed2 100644 --- a/packages/ponder/src/api/stats.ts +++ b/packages/ponder/src/api/stats.ts @@ -1,10 +1,10 @@ -import { ponder } from "ponder:registry"; +import { ponder } from "@/generated"; +import { count, countDistinct, eq, gte } from "@ponder/core"; import { interactionEventTable, productInteractionContractTable, productTable, -} from "ponder:schema"; -import { count, countDistinct, eq, gte } from "ponder"; +} from "../../ponder.schema"; /** * Get the overall system stats diff --git a/packages/ponder/src/api/tokens.ts b/packages/ponder/src/api/tokens.ts index 2f3b699..8a399ec 100644 --- a/packages/ponder/src/api/tokens.ts +++ b/packages/ponder/src/api/tokens.ts @@ -1,7 +1,7 @@ -import { type ApiContext, ponder } from "ponder:registry"; -import { tokenTable } from "ponder:schema"; -import { eq, inArray } from "ponder"; +import { type ApiContext, ponder } from "@/generated"; +import { eq, inArray } from "@ponder/core"; import { type Address, isAddress } from "viem"; +import { tokenTable } from "../../ponder.schema"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: Unreachable code error diff --git a/packages/ponder/src/campaign/campaignBank.ts b/packages/ponder/src/campaign/campaignBank.ts index 67c590b..f23406b 100644 --- a/packages/ponder/src/campaign/campaignBank.ts +++ b/packages/ponder/src/campaign/campaignBank.ts @@ -1,8 +1,8 @@ import * as console from "node:console"; -import { type Context, ponder } from "ponder:registry"; -import { bankingContractTable, campaignTable } from "ponder:schema"; +import { type Context, ponder } from "@/generated"; import { type Address, isAddressEqual } from "viem"; import { campaignBankAbi } from "../../abis/campaignAbis"; +import { bankingContractTable, campaignTable } from "../../ponder.schema"; import { upsertTokenIfNeeded } from "../token"; ponder.on( diff --git a/packages/ponder/src/campaign/campaignCreation.ts b/packages/ponder/src/campaign/campaignCreation.ts index 2c655cf..35577c6 100644 --- a/packages/ponder/src/campaign/campaignCreation.ts +++ b/packages/ponder/src/campaign/campaignCreation.ts @@ -1,10 +1,10 @@ -import { type Context, ponder } from "ponder:registry"; -import { campaignTable, referralCampaignStatsTable } from "ponder:schema"; +import { type Context, ponder } from "@/generated"; import type { Address } from "viem"; import { interactionCampaignAbi, referralCampaignAbi, } from "../../abis/campaignAbis"; +import { campaignTable, referralCampaignStatsTable } from "../../ponder.schema"; import { emptyCampaignStats } from "../interactions/stats"; import { bytesToString } from "../utils/format"; diff --git a/packages/ponder/src/campaign/campaignInteractionLink.ts b/packages/ponder/src/campaign/campaignInteractionLink.ts index 3b28d9b..1af7bbb 100644 --- a/packages/ponder/src/campaign/campaignInteractionLink.ts +++ b/packages/ponder/src/campaign/campaignInteractionLink.ts @@ -1,5 +1,8 @@ -import { ponder } from "ponder:registry"; -import { campaignTable, productInteractionContractTable } from "ponder:schema"; +import { ponder } from "@/generated"; +import { + campaignTable, + productInteractionContractTable, +} from "../../ponder.schema"; import { upsertNewCampaign } from "./campaignCreation"; ponder.on("ProductInteraction:CampaignAttached", async ({ event, context }) => { diff --git a/packages/ponder/src/campaign/campaignReset.ts b/packages/ponder/src/campaign/campaignReset.ts index 9ab33e2..eb997a9 100644 --- a/packages/ponder/src/campaign/campaignReset.ts +++ b/packages/ponder/src/campaign/campaignReset.ts @@ -1,5 +1,5 @@ -import { ponder } from "ponder:registry"; -import { campaignCapResetTable } from "ponder:schema"; +import { ponder } from "@/generated"; +import { campaignCapResetTable } from "../../ponder.schema"; ponder.on( "Campaigns:DistributionCapReset", diff --git a/packages/ponder/src/campaign/campaignReward.ts b/packages/ponder/src/campaign/campaignReward.ts index f697b22..4825719 100644 --- a/packages/ponder/src/campaign/campaignReward.ts +++ b/packages/ponder/src/campaign/campaignReward.ts @@ -1,10 +1,10 @@ -import { ponder } from "ponder:registry"; +import { ponder } from "@/generated"; import { bankingContractTable, rewardAddedEventTable, rewardClaimedEventTable, rewardTable, -} from "ponder:schema"; +} from "../../ponder.schema"; import { safeIncreaseCampaignsStats } from "../interactions/stats"; ponder.on("CampaignBanks:RewardAdded", async ({ event, context }) => { @@ -49,7 +49,7 @@ ponder.on("CampaignBanks:RewardAdded", async ({ event, context }) => { user: event.args.user, emitter: event.args.emitter, amount: event.args.amount, - txHash: event.transaction.hash, + txHash: event.log.transactionHash, timestamp: event.block.timestamp, }); @@ -104,7 +104,7 @@ ponder.on("CampaignBanks:RewardClaimed", async ({ event, context: { db } }) => { contractId: bankingContract.id, user: event.args.user, amount: event.args.amount, - txHash: event.transaction.hash, + txHash: event.log.transactionHash, timestamp: event.block.timestamp, }); }); diff --git a/packages/ponder/src/interactionDeployments.ts b/packages/ponder/src/interactionDeployments.ts index 1821543..4c24e46 100644 --- a/packages/ponder/src/interactionDeployments.ts +++ b/packages/ponder/src/interactionDeployments.ts @@ -1,6 +1,6 @@ -import { ponder } from "ponder:registry"; -import { productInteractionContractTable } from "ponder:schema"; +import { ponder } from "@/generated"; import { productInteractionDiamondAbi } from "../abis/interactionAbis"; +import { productInteractionContractTable } from "../ponder.schema"; ponder.on( "ProductInteractionManager:InteractionContractDeployed", diff --git a/packages/ponder/src/interactions/pressInteractions.ts b/packages/ponder/src/interactions/pressInteractions.ts index fc716e8..01940d0 100644 --- a/packages/ponder/src/interactions/pressInteractions.ts +++ b/packages/ponder/src/interactions/pressInteractions.ts @@ -1,5 +1,5 @@ -import { ponder } from "ponder:registry"; -import { interactionEventTable } from "ponder:schema"; +import { ponder } from "@/generated"; +import { interactionEventTable } from "../../ponder.schema"; import { safeIncreaseCampaignsStats } from "./stats"; ponder.on("ProductInteraction:ArticleRead", async ({ event, context }) => { diff --git a/packages/ponder/src/interactions/purchaseInteractions.ts b/packages/ponder/src/interactions/purchaseInteractions.ts index c2dbb6a..1ecc377 100644 --- a/packages/ponder/src/interactions/purchaseInteractions.ts +++ b/packages/ponder/src/interactions/purchaseInteractions.ts @@ -1,5 +1,5 @@ -import { ponder } from "ponder:registry"; -import { interactionEventTable } from "ponder:schema"; +import { ponder } from "@/generated"; +import { interactionEventTable } from "../../ponder.schema"; import { safeIncreaseCampaignsStats } from "./stats"; ponder.on("ProductInteraction:PurchaseStarted", async ({ event, context }) => { diff --git a/packages/ponder/src/interactions/referralInteractions.ts b/packages/ponder/src/interactions/referralInteractions.ts index 5a560ae..e8a4478 100644 --- a/packages/ponder/src/interactions/referralInteractions.ts +++ b/packages/ponder/src/interactions/referralInteractions.ts @@ -1,5 +1,5 @@ -import { ponder } from "ponder:registry"; -import { interactionEventTable } from "ponder:schema"; +import { ponder } from "@/generated"; +import { interactionEventTable } from "../../ponder.schema"; import { safeIncreaseCampaignsStats } from "./stats"; ponder.on( diff --git a/packages/ponder/src/interactions/stats.ts b/packages/ponder/src/interactions/stats.ts index b7544b6..5015a71 100644 --- a/packages/ponder/src/interactions/stats.ts +++ b/packages/ponder/src/interactions/stats.ts @@ -1,12 +1,12 @@ -import type { Context } from "ponder:registry"; +import type { Context } from "@/generated"; +import { and, desc, eq } from "@ponder/core"; +import type { Address } from "viem"; +import { interactionCampaignAbi } from "../../abis/campaignAbis"; import { campaignTable, productInteractionContractTable, referralCampaignStatsTable, -} from "ponder:schema"; -import { and, desc, eq } from "ponder"; -import type { Address } from "viem"; -import { interactionCampaignAbi } from "../../abis/campaignAbis"; +} from "../../ponder.schema"; /** * Default campaign stats diff --git a/packages/ponder/src/interactions/webshopInteractions.ts b/packages/ponder/src/interactions/webshopInteractions.ts index 880ebf7..4720fa8 100644 --- a/packages/ponder/src/interactions/webshopInteractions.ts +++ b/packages/ponder/src/interactions/webshopInteractions.ts @@ -1,5 +1,5 @@ -import { ponder } from "ponder:registry"; -import { interactionEventTable } from "ponder:schema"; +import { ponder } from "@/generated"; +import { interactionEventTable } from "../../ponder.schema"; import { safeIncreaseCampaignsStats } from "./stats"; ponder.on("ProductInteraction:WebShopOpenned", async ({ event, context }) => { diff --git a/packages/ponder/src/product.ts b/packages/ponder/src/product.ts index d21e95c..4e30820 100644 --- a/packages/ponder/src/product.ts +++ b/packages/ponder/src/product.ts @@ -1,6 +1,6 @@ -import { ponder } from "ponder:registry"; -import { productTable } from "ponder:schema"; +import { ponder } from "@/generated"; import { productRegistryAbi } from "../abis/registryAbis"; +import { productTable } from "../ponder.schema"; import { bytesToString } from "./utils/format"; ponder.on("ProductRegistry:ProductMinted", async ({ event, context }) => { diff --git a/packages/ponder/src/productAdministrator.ts b/packages/ponder/src/productAdministrator.ts index 8bcb663..1d293ab 100644 --- a/packages/ponder/src/productAdministrator.ts +++ b/packages/ponder/src/productAdministrator.ts @@ -1,6 +1,6 @@ -import { type Context, ponder } from "ponder:registry"; -import { productAdministratorTable } from "ponder:schema"; +import { type Context, ponder } from "@/generated"; import { isAddressEqual, zeroAddress } from "viem"; +import { productAdministratorTable } from "../ponder.schema"; /* * Handle transfer stuff diff --git a/packages/ponder/src/token.ts b/packages/ponder/src/token.ts index f049b72..e1180f9 100644 --- a/packages/ponder/src/token.ts +++ b/packages/ponder/src/token.ts @@ -1,7 +1,7 @@ import console from "node:console"; -import type { Context } from "ponder:registry"; -import { tokenTable } from "ponder:schema"; +import type { Context } from "@/generated"; import { type Address, erc20Abi } from "viem"; +import { tokenTable } from "../ponder.schema"; export async function upsertTokenIfNeeded({ address, From 6e662e06f344fb323bf62a4373bd4524825153e6 Mon Sep 17 00:00:00 2001 From: KONFeature Date: Tue, 17 Dec 2024 12:14:49 +0100 Subject: [PATCH 03/11] =?UTF-8?q?=F0=9F=93=9D=20Review=20readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 35 +++++------------------------------ 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 341dd5d..8d339be 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,16 @@ -# Frak Indexer +# Infra blockchain -Frak Indexer is an open-source project designed to index events from Frak smart contracts on the Arbitrum network. It combines the power of Ponder for building robust crypto apps with eRPC for efficient RPC caching and load balancing, all deployed using SST (Serverless Stack) on AWS infrastructure. +This repository contain all the blockchain related infra code for the [Frak](https://frak.id) project. ## Architecture Overview The Frak Indexer consists of two main components: -1. **Ponder Service**: An open-source backend framework for building robust, performant, and maintainable crypto apps. In this project, it's used for indexing blockchain events from Frak smart contracts. +1.**[eRPC](https://github.com/erpc/erpc)**: RPC request caching and load balancing across multiple node providers -2. **eRPC Service**: A fault-tolerant EVM RPC load balancer with reorg-aware permanent caching and auto-discovery of node providers. It provides a layer of caching on top of other RPCs, enhancing performance and reliability. +2.**[Ponder](https://github.com/ponder-sh/ponder)**: Indexing blockchain events from Frak smart contracts. -Both services are deployed as containerized applications on AWS ECS (Elastic Container Service) using Fargate, with an Application Load Balancer (ALB) routing traffic between them. - -## Deployment Architecture - -- **VPC**: A dedicated VPC is created to house all components. -- **ECS Cluster**: Both Ponder and eRPC services run in the same ECS cluster. -- **Application Load Balancer**: - - Listens on port 80 - - Routes traffic based on path patterns: - - `/rpc-main/*` -> eRPC service (for cached RPC requests) - - `/*` (all other paths) -> Ponder service (for indexed data access) -- **CloudFront Distribution**: Sits in front of the ALB to provide additional caching and global content delivery. - -## Key Features - -- **Efficient Indexing**: Utilizes Ponder to create a robust and maintainable indexing solution for Frak smart contract events. -- **Optimized RPC Access**: eRPC provides caching and load balancing across multiple RPC providers, improving performance and reliability. -- **Scalable**: Utilizes AWS Fargate for serverless container management. -- **High Availability**: Deployed across multiple availability zones. -- **Secure**: Uses AWS security groups and VPC for network isolation. -- **Observable**: Includes CloudWatch logs and metrics for monitoring. -- **Maintainable**: Infrastructure as Code (IaC) using SST for easy updates and version control. - -## Contributing - -We welcome contributions to the Frak Indexer project! +Both services are deployed as containerized applications on AWS ECS (Elastic Container Service) using Fargate, with a master Application Load Balancer (ALB) routing traffic between them. ## License From 4866132c0a2e13c2b7d0fd965787c3e990370255 Mon Sep 17 00:00:00 2001 From: KONFeature Date: Tue, 17 Dec 2024 12:23:58 +0100 Subject: [PATCH 04/11] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Upgrade=20to=20ponde?= =?UTF-8?q?r=200.8.6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bun.lockb | Bin 280629 -> 280981 bytes infra/utils.ts | 2 ++ packages/ponder/config/configBuilder.ts | 15 ++++---- packages/ponder/package.json | 10 +++--- packages/ponder/ponder-env.d.ts | 34 ++++++------------ packages/ponder/ponder.schema.ts | 2 +- packages/ponder/src/api/admin.ts | 8 ++--- packages/ponder/src/api/campaign.ts | 6 ++-- packages/ponder/src/api/index.ts | 2 +- packages/ponder/src/api/interactions.ts | 8 ++--- packages/ponder/src/api/members.ts | 20 +++++------ packages/ponder/src/api/products.ts | 8 ++--- packages/ponder/src/api/rewards.ts | 8 ++--- packages/ponder/src/api/stats.ts | 6 ++-- packages/ponder/src/api/tokens.ts | 6 ++-- packages/ponder/src/campaign/campaignBank.ts | 4 +-- .../ponder/src/campaign/campaignCreation.ts | 4 +-- .../src/campaign/campaignInteractionLink.ts | 7 ++-- packages/ponder/src/campaign/campaignReset.ts | 4 +-- .../ponder/src/campaign/campaignReward.ts | 8 ++--- packages/ponder/src/interactionDeployments.ts | 4 +-- .../src/interactions/pressInteractions.ts | 4 +-- .../src/interactions/purchaseInteractions.ts | 4 +-- .../src/interactions/referralInteractions.ts | 4 +-- packages/ponder/src/interactions/stats.ts | 10 +++--- .../src/interactions/webshopInteractions.ts | 4 +-- packages/ponder/src/product.ts | 4 +-- packages/ponder/src/productAdministrator.ts | 4 +-- packages/ponder/src/token.ts | 4 +-- 29 files changed, 96 insertions(+), 108 deletions(-) diff --git a/bun.lockb b/bun.lockb index 8430dfad10b1ae31e3b77bba069c40b718f71623..17e3894b557108bd4bd71ab921987506d1bcdee8 100755 GIT binary patch delta 31136 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 z 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 z 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 delta 29457 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 diff --git a/infra/utils.ts b/infra/utils.ts index db6ed05..3585840 100644 --- a/infra/utils.ts +++ b/infra/utils.ts @@ -36,6 +36,8 @@ export function getPonderEntrypoint(type: "indexer" | "reader") { "--config", configPath, command, + "--schema", + $app.stage, ]; } diff --git a/packages/ponder/config/configBuilder.ts b/packages/ponder/config/configBuilder.ts index 02d7644..7b2126c 100644 --- a/packages/ponder/config/configBuilder.ts +++ b/packages/ponder/config/configBuilder.ts @@ -1,4 +1,5 @@ -import { createConfig, mergeAbis } from "@ponder/core"; +import { createConfig, mergeAbis } from "ponder"; +import { factory } from "ponder"; import { http, type Address, @@ -217,14 +218,14 @@ export function createEnvConfig({ referralFeatureFacetAbi, purchaseFeatureFacetAbi, ]), - factory: { + address: factory({ address: deployedAddresses.productInteractionManager as Address, event: parseAbiItem( "event InteractionContractDeployed(uint256 indexed productId, address interactionContract)" ), parameter: "interactionContract", - }, + }), network: contractNetworkConfig, }, // The campaign factory @@ -236,13 +237,13 @@ export function createEnvConfig({ // Every campaigns Campaigns: { abi: mergeAbis([interactionCampaignAbi, referralCampaignAbi]), - factory: { + address: factory({ address: deployedAddresses.campaignFactory as Address, event: parseAbiItem( "event CampaignCreated(address campaign)" ), parameter: "campaign", - }, + }), network: contractNetworkConfig, }, // The campaign banks factory @@ -254,13 +255,13 @@ export function createEnvConfig({ // Every campaign banks CampaignBanks: { abi: campaignBankAbi, - factory: { + address: factory({ address: deployedAddresses.campaignBankFactory as Address, event: parseAbiItem( "event CampaignBankCreated(address campaignBank)" ), parameter: "campaignBank", - }, + }), network: contractNetworkConfig, }, }, diff --git a/packages/ponder/package.json b/packages/ponder/package.json index 4af5b27..f97de61 100644 --- a/packages/ponder/package.json +++ b/packages/ponder/package.json @@ -13,22 +13,22 @@ "serve:prod": "ponder --config config/config-prod.ts serve", "serve:dev": "ponder --config config/config-dev.ts serve", "start": "ponder --config config/config-local.ts start", - "start:dev": "ponder --config config/config-dev.ts start", - "start:prod": "ponder --config config/config-prod.ts start", + "start:dev": "ponder --config config/config-dev.ts start --schema dev", + "start:prod": "ponder --config config/config-prod.ts start --schema prod", "typecheck": "tsc", "docker": "bun docker:build && bun docker:run", "docker:build": "docker build --tag ponder-dev .", "docker:run": "docker run -P ponder-dev" }, "dependencies": { - "@ponder/core": "0.7.17", "drizzle-orm": "0.36.4", - "hono": "4.6.13", + "hono": "4.6.14", + "ponder": "^0.8.6", "viem": "^2.21.54" }, "devDependencies": { "@biomejs/biome": "1.9.4", - "@types/node": "^22.10.1", + "@types/node": "^22.10.2", "typescript": "^5.7.2" }, "engines": { diff --git a/packages/ponder/ponder-env.d.ts b/packages/ponder/ponder-env.d.ts index e7f3009..b8c6a63 100644 --- a/packages/ponder/ponder-env.d.ts +++ b/packages/ponder/ponder-env.d.ts @@ -1,27 +1,15 @@ +/// + +declare module "ponder:internal" { + const config: typeof import("./ponder.config.ts"); + const schema: typeof import("./ponder.schema.ts"); +} + +declare module "ponder:schema" { + export * from "./ponder.schema.ts"; +} + // This file enables type checking and editor autocomplete for this Ponder project. // After upgrading, you may find that changes have been made to this file. // If this happens, please commit the changes. Do not manually edit this file. // See https://ponder.sh/docs/getting-started/installation#typescript for more information. - -declare module "@/generated" { - import type { Virtual } from "@ponder/core"; - - type config = typeof import("./ponder.config.ts").default; - type schema = typeof import("./ponder.schema.ts"); - - export const ponder: Virtual.Registry; - - export type EventNames = Virtual.EventNames; - export type Event = Virtual.Event< - config, - name - >; - export type Context = Virtual.Context< - config, - schema, - name - >; - export type ApiContext = Virtual.ApiContext; - export type IndexingFunctionArgs = - Virtual.IndexingFunctionArgs; -} diff --git a/packages/ponder/ponder.schema.ts b/packages/ponder/ponder.schema.ts index 945e692..8102538 100644 --- a/packages/ponder/ponder.schema.ts +++ b/packages/ponder/ponder.schema.ts @@ -1,4 +1,4 @@ -import { index, onchainEnum, onchainTable, primaryKey } from "@ponder/core"; +import { index, onchainEnum, onchainTable, primaryKey } from "ponder"; /* -------------------------------------------------------------------------- */ /* Product related stuff */ diff --git a/packages/ponder/src/api/admin.ts b/packages/ponder/src/api/admin.ts index 1b8e3aa..38d89ac 100644 --- a/packages/ponder/src/api/admin.ts +++ b/packages/ponder/src/api/admin.ts @@ -1,6 +1,4 @@ -import { ponder } from "@/generated"; -import { countDistinct, eq, inArray } from "@ponder/core"; -import { type Address, isAddress } from "viem"; +import { ponder } from "ponder:registry"; import { campaignTable, interactionEventTable, @@ -8,7 +6,9 @@ import { productInteractionContractTable, productTable, referralCampaignStatsTable, -} from "../../ponder.schema"; +} from "ponder:schema"; +import { countDistinct, eq, inArray } from "ponder"; +import { type Address, isAddress } from "viem"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: Unreachable code error diff --git a/packages/ponder/src/api/campaign.ts b/packages/ponder/src/api/campaign.ts index d7e9da3..1c3797e 100644 --- a/packages/ponder/src/api/campaign.ts +++ b/packages/ponder/src/api/campaign.ts @@ -1,7 +1,7 @@ -import { ponder } from "@/generated"; -import { eq } from "@ponder/core"; +import { ponder } from "ponder:registry"; +import { bankingContractTable, campaignTable } from "ponder:schema"; +import { eq } from "ponder"; import { type Address, type Hex, isAddress, isHex } from "viem"; -import { bankingContractTable, campaignTable } from "../../ponder.schema"; import { getTokens } from "./tokens"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment diff --git a/packages/ponder/src/api/index.ts b/packages/ponder/src/api/index.ts index c402444..9fa0fa9 100644 --- a/packages/ponder/src/api/index.ts +++ b/packages/ponder/src/api/index.ts @@ -1,4 +1,4 @@ -import { ponder } from "@/generated"; +import { ponder } from "ponder:registry"; ponder.get("/hello", async ({ text }) => { return text("Hello!"); diff --git a/packages/ponder/src/api/interactions.ts b/packages/ponder/src/api/interactions.ts index a31b58f..fc81031 100644 --- a/packages/ponder/src/api/interactions.ts +++ b/packages/ponder/src/api/interactions.ts @@ -1,11 +1,11 @@ -import { ponder } from "@/generated"; -import { desc, eq } from "@ponder/core"; -import { type Address, isAddress } from "viem"; +import { ponder } from "ponder:registry"; import { interactionEventTable, productInteractionContractTable, productTable, -} from "../../ponder.schema"; +} from "ponder:schema"; +import { desc, eq } from "ponder"; +import { type Address, isAddress } from "viem"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: Unreachable code error diff --git a/packages/ponder/src/api/members.ts b/packages/ponder/src/api/members.ts index c3332c3..6bf2310 100644 --- a/packages/ponder/src/api/members.ts +++ b/packages/ponder/src/api/members.ts @@ -1,4 +1,12 @@ -import { ponder } from "@/generated"; +import { ponder } from "ponder:registry"; +import { + interactionEventTable, + productAdministratorTable, + productInteractionContractTable, + productTable, + rewardTable, +} from "ponder:schema"; +import type { SQL } from "drizzle-orm"; import { and, asc, @@ -12,16 +20,8 @@ import { min, sql, sum, -} from "@ponder/core"; -import type { SQL } from "drizzle-orm"; +} from "ponder"; import { type Address, type Hex, isAddress } from "viem"; -import { - interactionEventTable, - productAdministratorTable, - productInteractionContractTable, - productTable, - rewardTable, -} from "../../ponder.schema"; /** * Params for the members fetching diff --git a/packages/ponder/src/api/products.ts b/packages/ponder/src/api/products.ts index 5ae470a..9da7ab7 100644 --- a/packages/ponder/src/api/products.ts +++ b/packages/ponder/src/api/products.ts @@ -1,6 +1,4 @@ -import { ponder } from "@/generated"; -import { eq, inArray } from "@ponder/core"; -import { type Hex, isHex, keccak256, toHex } from "viem"; +import { ponder } from "ponder:registry"; import { bankingContractTable, campaignTable, @@ -9,7 +7,9 @@ import { productTable, referralCampaignStatsTable, tokenTable, -} from "../../ponder.schema"; +} from "ponder:schema"; +import { eq, inArray } from "ponder"; +import { type Hex, isHex, keccak256, toHex } from "viem"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: Unreachable code error diff --git a/packages/ponder/src/api/rewards.ts b/packages/ponder/src/api/rewards.ts index 393f3f0..c316619 100644 --- a/packages/ponder/src/api/rewards.ts +++ b/packages/ponder/src/api/rewards.ts @@ -1,13 +1,13 @@ -import { ponder } from "@/generated"; -import { and, desc, eq, not } from "@ponder/core"; -import { type Address, isAddress } from "viem"; +import { ponder } from "ponder:registry"; import { bankingContractTable, productTable, rewardAddedEventTable, rewardClaimedEventTable, rewardTable, -} from "../../ponder.schema"; +} from "ponder:schema"; +import { and, desc, eq, not } from "ponder"; +import { type Address, isAddress } from "viem"; import { getTokens } from "./tokens"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment diff --git a/packages/ponder/src/api/stats.ts b/packages/ponder/src/api/stats.ts index 909bed2..97c0695 100644 --- a/packages/ponder/src/api/stats.ts +++ b/packages/ponder/src/api/stats.ts @@ -1,10 +1,10 @@ -import { ponder } from "@/generated"; -import { count, countDistinct, eq, gte } from "@ponder/core"; +import { ponder } from "ponder:registry"; import { interactionEventTable, productInteractionContractTable, productTable, -} from "../../ponder.schema"; +} from "ponder:schema"; +import { count, countDistinct, eq, gte } from "ponder"; /** * Get the overall system stats diff --git a/packages/ponder/src/api/tokens.ts b/packages/ponder/src/api/tokens.ts index 8a399ec..2f3b699 100644 --- a/packages/ponder/src/api/tokens.ts +++ b/packages/ponder/src/api/tokens.ts @@ -1,7 +1,7 @@ -import { type ApiContext, ponder } from "@/generated"; -import { eq, inArray } from "@ponder/core"; +import { type ApiContext, ponder } from "ponder:registry"; +import { tokenTable } from "ponder:schema"; +import { eq, inArray } from "ponder"; import { type Address, isAddress } from "viem"; -import { tokenTable } from "../../ponder.schema"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: Unreachable code error diff --git a/packages/ponder/src/campaign/campaignBank.ts b/packages/ponder/src/campaign/campaignBank.ts index f23406b..67c590b 100644 --- a/packages/ponder/src/campaign/campaignBank.ts +++ b/packages/ponder/src/campaign/campaignBank.ts @@ -1,8 +1,8 @@ import * as console from "node:console"; -import { type Context, ponder } from "@/generated"; +import { type Context, ponder } from "ponder:registry"; +import { bankingContractTable, campaignTable } from "ponder:schema"; import { type Address, isAddressEqual } from "viem"; import { campaignBankAbi } from "../../abis/campaignAbis"; -import { bankingContractTable, campaignTable } from "../../ponder.schema"; import { upsertTokenIfNeeded } from "../token"; ponder.on( diff --git a/packages/ponder/src/campaign/campaignCreation.ts b/packages/ponder/src/campaign/campaignCreation.ts index 35577c6..2c655cf 100644 --- a/packages/ponder/src/campaign/campaignCreation.ts +++ b/packages/ponder/src/campaign/campaignCreation.ts @@ -1,10 +1,10 @@ -import { type Context, ponder } from "@/generated"; +import { type Context, ponder } from "ponder:registry"; +import { campaignTable, referralCampaignStatsTable } from "ponder:schema"; import type { Address } from "viem"; import { interactionCampaignAbi, referralCampaignAbi, } from "../../abis/campaignAbis"; -import { campaignTable, referralCampaignStatsTable } from "../../ponder.schema"; import { emptyCampaignStats } from "../interactions/stats"; import { bytesToString } from "../utils/format"; diff --git a/packages/ponder/src/campaign/campaignInteractionLink.ts b/packages/ponder/src/campaign/campaignInteractionLink.ts index 1af7bbb..3b28d9b 100644 --- a/packages/ponder/src/campaign/campaignInteractionLink.ts +++ b/packages/ponder/src/campaign/campaignInteractionLink.ts @@ -1,8 +1,5 @@ -import { ponder } from "@/generated"; -import { - campaignTable, - productInteractionContractTable, -} from "../../ponder.schema"; +import { ponder } from "ponder:registry"; +import { campaignTable, productInteractionContractTable } from "ponder:schema"; import { upsertNewCampaign } from "./campaignCreation"; ponder.on("ProductInteraction:CampaignAttached", async ({ event, context }) => { diff --git a/packages/ponder/src/campaign/campaignReset.ts b/packages/ponder/src/campaign/campaignReset.ts index eb997a9..9ab33e2 100644 --- a/packages/ponder/src/campaign/campaignReset.ts +++ b/packages/ponder/src/campaign/campaignReset.ts @@ -1,5 +1,5 @@ -import { ponder } from "@/generated"; -import { campaignCapResetTable } from "../../ponder.schema"; +import { ponder } from "ponder:registry"; +import { campaignCapResetTable } from "ponder:schema"; ponder.on( "Campaigns:DistributionCapReset", diff --git a/packages/ponder/src/campaign/campaignReward.ts b/packages/ponder/src/campaign/campaignReward.ts index 4825719..f697b22 100644 --- a/packages/ponder/src/campaign/campaignReward.ts +++ b/packages/ponder/src/campaign/campaignReward.ts @@ -1,10 +1,10 @@ -import { ponder } from "@/generated"; +import { ponder } from "ponder:registry"; import { bankingContractTable, rewardAddedEventTable, rewardClaimedEventTable, rewardTable, -} from "../../ponder.schema"; +} from "ponder:schema"; import { safeIncreaseCampaignsStats } from "../interactions/stats"; ponder.on("CampaignBanks:RewardAdded", async ({ event, context }) => { @@ -49,7 +49,7 @@ ponder.on("CampaignBanks:RewardAdded", async ({ event, context }) => { user: event.args.user, emitter: event.args.emitter, amount: event.args.amount, - txHash: event.log.transactionHash, + txHash: event.transaction.hash, timestamp: event.block.timestamp, }); @@ -104,7 +104,7 @@ ponder.on("CampaignBanks:RewardClaimed", async ({ event, context: { db } }) => { contractId: bankingContract.id, user: event.args.user, amount: event.args.amount, - txHash: event.log.transactionHash, + txHash: event.transaction.hash, timestamp: event.block.timestamp, }); }); diff --git a/packages/ponder/src/interactionDeployments.ts b/packages/ponder/src/interactionDeployments.ts index 4c24e46..1821543 100644 --- a/packages/ponder/src/interactionDeployments.ts +++ b/packages/ponder/src/interactionDeployments.ts @@ -1,6 +1,6 @@ -import { ponder } from "@/generated"; +import { ponder } from "ponder:registry"; +import { productInteractionContractTable } from "ponder:schema"; import { productInteractionDiamondAbi } from "../abis/interactionAbis"; -import { productInteractionContractTable } from "../ponder.schema"; ponder.on( "ProductInteractionManager:InteractionContractDeployed", diff --git a/packages/ponder/src/interactions/pressInteractions.ts b/packages/ponder/src/interactions/pressInteractions.ts index 01940d0..fc716e8 100644 --- a/packages/ponder/src/interactions/pressInteractions.ts +++ b/packages/ponder/src/interactions/pressInteractions.ts @@ -1,5 +1,5 @@ -import { ponder } from "@/generated"; -import { interactionEventTable } from "../../ponder.schema"; +import { ponder } from "ponder:registry"; +import { interactionEventTable } from "ponder:schema"; import { safeIncreaseCampaignsStats } from "./stats"; ponder.on("ProductInteraction:ArticleRead", async ({ event, context }) => { diff --git a/packages/ponder/src/interactions/purchaseInteractions.ts b/packages/ponder/src/interactions/purchaseInteractions.ts index 1ecc377..c2dbb6a 100644 --- a/packages/ponder/src/interactions/purchaseInteractions.ts +++ b/packages/ponder/src/interactions/purchaseInteractions.ts @@ -1,5 +1,5 @@ -import { ponder } from "@/generated"; -import { interactionEventTable } from "../../ponder.schema"; +import { ponder } from "ponder:registry"; +import { interactionEventTable } from "ponder:schema"; import { safeIncreaseCampaignsStats } from "./stats"; ponder.on("ProductInteraction:PurchaseStarted", async ({ event, context }) => { diff --git a/packages/ponder/src/interactions/referralInteractions.ts b/packages/ponder/src/interactions/referralInteractions.ts index e8a4478..5a560ae 100644 --- a/packages/ponder/src/interactions/referralInteractions.ts +++ b/packages/ponder/src/interactions/referralInteractions.ts @@ -1,5 +1,5 @@ -import { ponder } from "@/generated"; -import { interactionEventTable } from "../../ponder.schema"; +import { ponder } from "ponder:registry"; +import { interactionEventTable } from "ponder:schema"; import { safeIncreaseCampaignsStats } from "./stats"; ponder.on( diff --git a/packages/ponder/src/interactions/stats.ts b/packages/ponder/src/interactions/stats.ts index 5015a71..b7544b6 100644 --- a/packages/ponder/src/interactions/stats.ts +++ b/packages/ponder/src/interactions/stats.ts @@ -1,12 +1,12 @@ -import type { Context } from "@/generated"; -import { and, desc, eq } from "@ponder/core"; -import type { Address } from "viem"; -import { interactionCampaignAbi } from "../../abis/campaignAbis"; +import type { Context } from "ponder:registry"; import { campaignTable, productInteractionContractTable, referralCampaignStatsTable, -} from "../../ponder.schema"; +} from "ponder:schema"; +import { and, desc, eq } from "ponder"; +import type { Address } from "viem"; +import { interactionCampaignAbi } from "../../abis/campaignAbis"; /** * Default campaign stats diff --git a/packages/ponder/src/interactions/webshopInteractions.ts b/packages/ponder/src/interactions/webshopInteractions.ts index 4720fa8..880ebf7 100644 --- a/packages/ponder/src/interactions/webshopInteractions.ts +++ b/packages/ponder/src/interactions/webshopInteractions.ts @@ -1,5 +1,5 @@ -import { ponder } from "@/generated"; -import { interactionEventTable } from "../../ponder.schema"; +import { ponder } from "ponder:registry"; +import { interactionEventTable } from "ponder:schema"; import { safeIncreaseCampaignsStats } from "./stats"; ponder.on("ProductInteraction:WebShopOpenned", async ({ event, context }) => { diff --git a/packages/ponder/src/product.ts b/packages/ponder/src/product.ts index 4e30820..d21e95c 100644 --- a/packages/ponder/src/product.ts +++ b/packages/ponder/src/product.ts @@ -1,6 +1,6 @@ -import { ponder } from "@/generated"; +import { ponder } from "ponder:registry"; +import { productTable } from "ponder:schema"; import { productRegistryAbi } from "../abis/registryAbis"; -import { productTable } from "../ponder.schema"; import { bytesToString } from "./utils/format"; ponder.on("ProductRegistry:ProductMinted", async ({ event, context }) => { diff --git a/packages/ponder/src/productAdministrator.ts b/packages/ponder/src/productAdministrator.ts index 1d293ab..8bcb663 100644 --- a/packages/ponder/src/productAdministrator.ts +++ b/packages/ponder/src/productAdministrator.ts @@ -1,6 +1,6 @@ -import { type Context, ponder } from "@/generated"; +import { type Context, ponder } from "ponder:registry"; +import { productAdministratorTable } from "ponder:schema"; import { isAddressEqual, zeroAddress } from "viem"; -import { productAdministratorTable } from "../ponder.schema"; /* * Handle transfer stuff diff --git a/packages/ponder/src/token.ts b/packages/ponder/src/token.ts index e1180f9..f049b72 100644 --- a/packages/ponder/src/token.ts +++ b/packages/ponder/src/token.ts @@ -1,7 +1,7 @@ import console from "node:console"; -import type { Context } from "@/generated"; +import type { Context } from "ponder:registry"; +import { tokenTable } from "ponder:schema"; import { type Address, erc20Abi } from "viem"; -import { tokenTable } from "../ponder.schema"; export async function upsertTokenIfNeeded({ address, From 162d15efa7c5eeaed1ab551fb291709cfe07a04a Mon Sep 17 00:00:00 2001 From: KONFeature Date: Tue, 17 Dec 2024 12:50:04 +0100 Subject: [PATCH 05/11] =?UTF-8?q?Revert=20"=E2=AC=86=EF=B8=8F=20Upgrade=20?= =?UTF-8?q?to=20ponder=200.8.6"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 4866132c0a2e13c2b7d0fd965787c3e990370255. Because of the error `no schema has been selected to create in` from `Object.createTriggers` --- bun.lockb | Bin 280981 -> 280629 bytes infra/utils.ts | 2 -- packages/ponder/config/configBuilder.ts | 15 ++++---- packages/ponder/package.json | 10 +++--- packages/ponder/ponder-env.d.ts | 34 ++++++++++++------ packages/ponder/ponder.schema.ts | 2 +- packages/ponder/src/api/admin.ts | 8 ++--- packages/ponder/src/api/campaign.ts | 6 ++-- packages/ponder/src/api/index.ts | 2 +- packages/ponder/src/api/interactions.ts | 8 ++--- packages/ponder/src/api/members.ts | 20 +++++------ packages/ponder/src/api/products.ts | 8 ++--- packages/ponder/src/api/rewards.ts | 8 ++--- packages/ponder/src/api/stats.ts | 6 ++-- packages/ponder/src/api/tokens.ts | 6 ++-- packages/ponder/src/campaign/campaignBank.ts | 4 +-- .../ponder/src/campaign/campaignCreation.ts | 4 +-- .../src/campaign/campaignInteractionLink.ts | 7 ++-- packages/ponder/src/campaign/campaignReset.ts | 4 +-- .../ponder/src/campaign/campaignReward.ts | 8 ++--- packages/ponder/src/interactionDeployments.ts | 4 +-- .../src/interactions/pressInteractions.ts | 4 +-- .../src/interactions/purchaseInteractions.ts | 4 +-- .../src/interactions/referralInteractions.ts | 4 +-- packages/ponder/src/interactions/stats.ts | 10 +++--- .../src/interactions/webshopInteractions.ts | 4 +-- packages/ponder/src/product.ts | 4 +-- packages/ponder/src/productAdministrator.ts | 4 +-- packages/ponder/src/token.ts | 4 +-- 29 files changed, 108 insertions(+), 96 deletions(-) diff --git a/bun.lockb b/bun.lockb index 17e3894b557108bd4bd71ab921987506d1bcdee8..8430dfad10b1ae31e3b77bba069c40b718f71623 100755 GIT binary patch delta 29457 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 delta 31136 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 z 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 z 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 diff --git a/infra/utils.ts b/infra/utils.ts index 3585840..db6ed05 100644 --- a/infra/utils.ts +++ b/infra/utils.ts @@ -36,8 +36,6 @@ export function getPonderEntrypoint(type: "indexer" | "reader") { "--config", configPath, command, - "--schema", - $app.stage, ]; } diff --git a/packages/ponder/config/configBuilder.ts b/packages/ponder/config/configBuilder.ts index 7b2126c..02d7644 100644 --- a/packages/ponder/config/configBuilder.ts +++ b/packages/ponder/config/configBuilder.ts @@ -1,5 +1,4 @@ -import { createConfig, mergeAbis } from "ponder"; -import { factory } from "ponder"; +import { createConfig, mergeAbis } from "@ponder/core"; import { http, type Address, @@ -218,14 +217,14 @@ export function createEnvConfig({ referralFeatureFacetAbi, purchaseFeatureFacetAbi, ]), - address: factory({ + factory: { address: deployedAddresses.productInteractionManager as Address, event: parseAbiItem( "event InteractionContractDeployed(uint256 indexed productId, address interactionContract)" ), parameter: "interactionContract", - }), + }, network: contractNetworkConfig, }, // The campaign factory @@ -237,13 +236,13 @@ export function createEnvConfig({ // Every campaigns Campaigns: { abi: mergeAbis([interactionCampaignAbi, referralCampaignAbi]), - address: factory({ + factory: { address: deployedAddresses.campaignFactory as Address, event: parseAbiItem( "event CampaignCreated(address campaign)" ), parameter: "campaign", - }), + }, network: contractNetworkConfig, }, // The campaign banks factory @@ -255,13 +254,13 @@ export function createEnvConfig({ // Every campaign banks CampaignBanks: { abi: campaignBankAbi, - address: factory({ + factory: { address: deployedAddresses.campaignBankFactory as Address, event: parseAbiItem( "event CampaignBankCreated(address campaignBank)" ), parameter: "campaignBank", - }), + }, network: contractNetworkConfig, }, }, diff --git a/packages/ponder/package.json b/packages/ponder/package.json index f97de61..4af5b27 100644 --- a/packages/ponder/package.json +++ b/packages/ponder/package.json @@ -13,22 +13,22 @@ "serve:prod": "ponder --config config/config-prod.ts serve", "serve:dev": "ponder --config config/config-dev.ts serve", "start": "ponder --config config/config-local.ts start", - "start:dev": "ponder --config config/config-dev.ts start --schema dev", - "start:prod": "ponder --config config/config-prod.ts start --schema prod", + "start:dev": "ponder --config config/config-dev.ts start", + "start:prod": "ponder --config config/config-prod.ts start", "typecheck": "tsc", "docker": "bun docker:build && bun docker:run", "docker:build": "docker build --tag ponder-dev .", "docker:run": "docker run -P ponder-dev" }, "dependencies": { + "@ponder/core": "0.7.17", "drizzle-orm": "0.36.4", - "hono": "4.6.14", - "ponder": "^0.8.6", + "hono": "4.6.13", "viem": "^2.21.54" }, "devDependencies": { "@biomejs/biome": "1.9.4", - "@types/node": "^22.10.2", + "@types/node": "^22.10.1", "typescript": "^5.7.2" }, "engines": { diff --git a/packages/ponder/ponder-env.d.ts b/packages/ponder/ponder-env.d.ts index b8c6a63..e7f3009 100644 --- a/packages/ponder/ponder-env.d.ts +++ b/packages/ponder/ponder-env.d.ts @@ -1,15 +1,27 @@ -/// - -declare module "ponder:internal" { - const config: typeof import("./ponder.config.ts"); - const schema: typeof import("./ponder.schema.ts"); -} - -declare module "ponder:schema" { - export * from "./ponder.schema.ts"; -} - // This file enables type checking and editor autocomplete for this Ponder project. // After upgrading, you may find that changes have been made to this file. // If this happens, please commit the changes. Do not manually edit this file. // See https://ponder.sh/docs/getting-started/installation#typescript for more information. + +declare module "@/generated" { + import type { Virtual } from "@ponder/core"; + + type config = typeof import("./ponder.config.ts").default; + type schema = typeof import("./ponder.schema.ts"); + + export const ponder: Virtual.Registry; + + export type EventNames = Virtual.EventNames; + export type Event = Virtual.Event< + config, + name + >; + export type Context = Virtual.Context< + config, + schema, + name + >; + export type ApiContext = Virtual.ApiContext; + export type IndexingFunctionArgs = + Virtual.IndexingFunctionArgs; +} diff --git a/packages/ponder/ponder.schema.ts b/packages/ponder/ponder.schema.ts index 8102538..945e692 100644 --- a/packages/ponder/ponder.schema.ts +++ b/packages/ponder/ponder.schema.ts @@ -1,4 +1,4 @@ -import { index, onchainEnum, onchainTable, primaryKey } from "ponder"; +import { index, onchainEnum, onchainTable, primaryKey } from "@ponder/core"; /* -------------------------------------------------------------------------- */ /* Product related stuff */ diff --git a/packages/ponder/src/api/admin.ts b/packages/ponder/src/api/admin.ts index 38d89ac..1b8e3aa 100644 --- a/packages/ponder/src/api/admin.ts +++ b/packages/ponder/src/api/admin.ts @@ -1,4 +1,6 @@ -import { ponder } from "ponder:registry"; +import { ponder } from "@/generated"; +import { countDistinct, eq, inArray } from "@ponder/core"; +import { type Address, isAddress } from "viem"; import { campaignTable, interactionEventTable, @@ -6,9 +8,7 @@ import { productInteractionContractTable, productTable, referralCampaignStatsTable, -} from "ponder:schema"; -import { countDistinct, eq, inArray } from "ponder"; -import { type Address, isAddress } from "viem"; +} from "../../ponder.schema"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: Unreachable code error diff --git a/packages/ponder/src/api/campaign.ts b/packages/ponder/src/api/campaign.ts index 1c3797e..d7e9da3 100644 --- a/packages/ponder/src/api/campaign.ts +++ b/packages/ponder/src/api/campaign.ts @@ -1,7 +1,7 @@ -import { ponder } from "ponder:registry"; -import { bankingContractTable, campaignTable } from "ponder:schema"; -import { eq } from "ponder"; +import { ponder } from "@/generated"; +import { eq } from "@ponder/core"; import { type Address, type Hex, isAddress, isHex } from "viem"; +import { bankingContractTable, campaignTable } from "../../ponder.schema"; import { getTokens } from "./tokens"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment diff --git a/packages/ponder/src/api/index.ts b/packages/ponder/src/api/index.ts index 9fa0fa9..c402444 100644 --- a/packages/ponder/src/api/index.ts +++ b/packages/ponder/src/api/index.ts @@ -1,4 +1,4 @@ -import { ponder } from "ponder:registry"; +import { ponder } from "@/generated"; ponder.get("/hello", async ({ text }) => { return text("Hello!"); diff --git a/packages/ponder/src/api/interactions.ts b/packages/ponder/src/api/interactions.ts index fc81031..a31b58f 100644 --- a/packages/ponder/src/api/interactions.ts +++ b/packages/ponder/src/api/interactions.ts @@ -1,11 +1,11 @@ -import { ponder } from "ponder:registry"; +import { ponder } from "@/generated"; +import { desc, eq } from "@ponder/core"; +import { type Address, isAddress } from "viem"; import { interactionEventTable, productInteractionContractTable, productTable, -} from "ponder:schema"; -import { desc, eq } from "ponder"; -import { type Address, isAddress } from "viem"; +} from "../../ponder.schema"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: Unreachable code error diff --git a/packages/ponder/src/api/members.ts b/packages/ponder/src/api/members.ts index 6bf2310..c3332c3 100644 --- a/packages/ponder/src/api/members.ts +++ b/packages/ponder/src/api/members.ts @@ -1,12 +1,4 @@ -import { ponder } from "ponder:registry"; -import { - interactionEventTable, - productAdministratorTable, - productInteractionContractTable, - productTable, - rewardTable, -} from "ponder:schema"; -import type { SQL } from "drizzle-orm"; +import { ponder } from "@/generated"; import { and, asc, @@ -20,8 +12,16 @@ import { min, sql, sum, -} from "ponder"; +} from "@ponder/core"; +import type { SQL } from "drizzle-orm"; import { type Address, type Hex, isAddress } from "viem"; +import { + interactionEventTable, + productAdministratorTable, + productInteractionContractTable, + productTable, + rewardTable, +} from "../../ponder.schema"; /** * Params for the members fetching diff --git a/packages/ponder/src/api/products.ts b/packages/ponder/src/api/products.ts index 9da7ab7..5ae470a 100644 --- a/packages/ponder/src/api/products.ts +++ b/packages/ponder/src/api/products.ts @@ -1,4 +1,6 @@ -import { ponder } from "ponder:registry"; +import { ponder } from "@/generated"; +import { eq, inArray } from "@ponder/core"; +import { type Hex, isHex, keccak256, toHex } from "viem"; import { bankingContractTable, campaignTable, @@ -7,9 +9,7 @@ import { productTable, referralCampaignStatsTable, tokenTable, -} from "ponder:schema"; -import { eq, inArray } from "ponder"; -import { type Hex, isHex, keccak256, toHex } from "viem"; +} from "../../ponder.schema"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: Unreachable code error diff --git a/packages/ponder/src/api/rewards.ts b/packages/ponder/src/api/rewards.ts index c316619..393f3f0 100644 --- a/packages/ponder/src/api/rewards.ts +++ b/packages/ponder/src/api/rewards.ts @@ -1,13 +1,13 @@ -import { ponder } from "ponder:registry"; +import { ponder } from "@/generated"; +import { and, desc, eq, not } from "@ponder/core"; +import { type Address, isAddress } from "viem"; import { bankingContractTable, productTable, rewardAddedEventTable, rewardClaimedEventTable, rewardTable, -} from "ponder:schema"; -import { and, desc, eq, not } from "ponder"; -import { type Address, isAddress } from "viem"; +} from "../../ponder.schema"; import { getTokens } from "./tokens"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment diff --git a/packages/ponder/src/api/stats.ts b/packages/ponder/src/api/stats.ts index 97c0695..909bed2 100644 --- a/packages/ponder/src/api/stats.ts +++ b/packages/ponder/src/api/stats.ts @@ -1,10 +1,10 @@ -import { ponder } from "ponder:registry"; +import { ponder } from "@/generated"; +import { count, countDistinct, eq, gte } from "@ponder/core"; import { interactionEventTable, productInteractionContractTable, productTable, -} from "ponder:schema"; -import { count, countDistinct, eq, gte } from "ponder"; +} from "../../ponder.schema"; /** * Get the overall system stats diff --git a/packages/ponder/src/api/tokens.ts b/packages/ponder/src/api/tokens.ts index 2f3b699..8a399ec 100644 --- a/packages/ponder/src/api/tokens.ts +++ b/packages/ponder/src/api/tokens.ts @@ -1,7 +1,7 @@ -import { type ApiContext, ponder } from "ponder:registry"; -import { tokenTable } from "ponder:schema"; -import { eq, inArray } from "ponder"; +import { type ApiContext, ponder } from "@/generated"; +import { eq, inArray } from "@ponder/core"; import { type Address, isAddress } from "viem"; +import { tokenTable } from "../../ponder.schema"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: Unreachable code error diff --git a/packages/ponder/src/campaign/campaignBank.ts b/packages/ponder/src/campaign/campaignBank.ts index 67c590b..f23406b 100644 --- a/packages/ponder/src/campaign/campaignBank.ts +++ b/packages/ponder/src/campaign/campaignBank.ts @@ -1,8 +1,8 @@ import * as console from "node:console"; -import { type Context, ponder } from "ponder:registry"; -import { bankingContractTable, campaignTable } from "ponder:schema"; +import { type Context, ponder } from "@/generated"; import { type Address, isAddressEqual } from "viem"; import { campaignBankAbi } from "../../abis/campaignAbis"; +import { bankingContractTable, campaignTable } from "../../ponder.schema"; import { upsertTokenIfNeeded } from "../token"; ponder.on( diff --git a/packages/ponder/src/campaign/campaignCreation.ts b/packages/ponder/src/campaign/campaignCreation.ts index 2c655cf..35577c6 100644 --- a/packages/ponder/src/campaign/campaignCreation.ts +++ b/packages/ponder/src/campaign/campaignCreation.ts @@ -1,10 +1,10 @@ -import { type Context, ponder } from "ponder:registry"; -import { campaignTable, referralCampaignStatsTable } from "ponder:schema"; +import { type Context, ponder } from "@/generated"; import type { Address } from "viem"; import { interactionCampaignAbi, referralCampaignAbi, } from "../../abis/campaignAbis"; +import { campaignTable, referralCampaignStatsTable } from "../../ponder.schema"; import { emptyCampaignStats } from "../interactions/stats"; import { bytesToString } from "../utils/format"; diff --git a/packages/ponder/src/campaign/campaignInteractionLink.ts b/packages/ponder/src/campaign/campaignInteractionLink.ts index 3b28d9b..1af7bbb 100644 --- a/packages/ponder/src/campaign/campaignInteractionLink.ts +++ b/packages/ponder/src/campaign/campaignInteractionLink.ts @@ -1,5 +1,8 @@ -import { ponder } from "ponder:registry"; -import { campaignTable, productInteractionContractTable } from "ponder:schema"; +import { ponder } from "@/generated"; +import { + campaignTable, + productInteractionContractTable, +} from "../../ponder.schema"; import { upsertNewCampaign } from "./campaignCreation"; ponder.on("ProductInteraction:CampaignAttached", async ({ event, context }) => { diff --git a/packages/ponder/src/campaign/campaignReset.ts b/packages/ponder/src/campaign/campaignReset.ts index 9ab33e2..eb997a9 100644 --- a/packages/ponder/src/campaign/campaignReset.ts +++ b/packages/ponder/src/campaign/campaignReset.ts @@ -1,5 +1,5 @@ -import { ponder } from "ponder:registry"; -import { campaignCapResetTable } from "ponder:schema"; +import { ponder } from "@/generated"; +import { campaignCapResetTable } from "../../ponder.schema"; ponder.on( "Campaigns:DistributionCapReset", diff --git a/packages/ponder/src/campaign/campaignReward.ts b/packages/ponder/src/campaign/campaignReward.ts index f697b22..4825719 100644 --- a/packages/ponder/src/campaign/campaignReward.ts +++ b/packages/ponder/src/campaign/campaignReward.ts @@ -1,10 +1,10 @@ -import { ponder } from "ponder:registry"; +import { ponder } from "@/generated"; import { bankingContractTable, rewardAddedEventTable, rewardClaimedEventTable, rewardTable, -} from "ponder:schema"; +} from "../../ponder.schema"; import { safeIncreaseCampaignsStats } from "../interactions/stats"; ponder.on("CampaignBanks:RewardAdded", async ({ event, context }) => { @@ -49,7 +49,7 @@ ponder.on("CampaignBanks:RewardAdded", async ({ event, context }) => { user: event.args.user, emitter: event.args.emitter, amount: event.args.amount, - txHash: event.transaction.hash, + txHash: event.log.transactionHash, timestamp: event.block.timestamp, }); @@ -104,7 +104,7 @@ ponder.on("CampaignBanks:RewardClaimed", async ({ event, context: { db } }) => { contractId: bankingContract.id, user: event.args.user, amount: event.args.amount, - txHash: event.transaction.hash, + txHash: event.log.transactionHash, timestamp: event.block.timestamp, }); }); diff --git a/packages/ponder/src/interactionDeployments.ts b/packages/ponder/src/interactionDeployments.ts index 1821543..4c24e46 100644 --- a/packages/ponder/src/interactionDeployments.ts +++ b/packages/ponder/src/interactionDeployments.ts @@ -1,6 +1,6 @@ -import { ponder } from "ponder:registry"; -import { productInteractionContractTable } from "ponder:schema"; +import { ponder } from "@/generated"; import { productInteractionDiamondAbi } from "../abis/interactionAbis"; +import { productInteractionContractTable } from "../ponder.schema"; ponder.on( "ProductInteractionManager:InteractionContractDeployed", diff --git a/packages/ponder/src/interactions/pressInteractions.ts b/packages/ponder/src/interactions/pressInteractions.ts index fc716e8..01940d0 100644 --- a/packages/ponder/src/interactions/pressInteractions.ts +++ b/packages/ponder/src/interactions/pressInteractions.ts @@ -1,5 +1,5 @@ -import { ponder } from "ponder:registry"; -import { interactionEventTable } from "ponder:schema"; +import { ponder } from "@/generated"; +import { interactionEventTable } from "../../ponder.schema"; import { safeIncreaseCampaignsStats } from "./stats"; ponder.on("ProductInteraction:ArticleRead", async ({ event, context }) => { diff --git a/packages/ponder/src/interactions/purchaseInteractions.ts b/packages/ponder/src/interactions/purchaseInteractions.ts index c2dbb6a..1ecc377 100644 --- a/packages/ponder/src/interactions/purchaseInteractions.ts +++ b/packages/ponder/src/interactions/purchaseInteractions.ts @@ -1,5 +1,5 @@ -import { ponder } from "ponder:registry"; -import { interactionEventTable } from "ponder:schema"; +import { ponder } from "@/generated"; +import { interactionEventTable } from "../../ponder.schema"; import { safeIncreaseCampaignsStats } from "./stats"; ponder.on("ProductInteraction:PurchaseStarted", async ({ event, context }) => { diff --git a/packages/ponder/src/interactions/referralInteractions.ts b/packages/ponder/src/interactions/referralInteractions.ts index 5a560ae..e8a4478 100644 --- a/packages/ponder/src/interactions/referralInteractions.ts +++ b/packages/ponder/src/interactions/referralInteractions.ts @@ -1,5 +1,5 @@ -import { ponder } from "ponder:registry"; -import { interactionEventTable } from "ponder:schema"; +import { ponder } from "@/generated"; +import { interactionEventTable } from "../../ponder.schema"; import { safeIncreaseCampaignsStats } from "./stats"; ponder.on( diff --git a/packages/ponder/src/interactions/stats.ts b/packages/ponder/src/interactions/stats.ts index b7544b6..5015a71 100644 --- a/packages/ponder/src/interactions/stats.ts +++ b/packages/ponder/src/interactions/stats.ts @@ -1,12 +1,12 @@ -import type { Context } from "ponder:registry"; +import type { Context } from "@/generated"; +import { and, desc, eq } from "@ponder/core"; +import type { Address } from "viem"; +import { interactionCampaignAbi } from "../../abis/campaignAbis"; import { campaignTable, productInteractionContractTable, referralCampaignStatsTable, -} from "ponder:schema"; -import { and, desc, eq } from "ponder"; -import type { Address } from "viem"; -import { interactionCampaignAbi } from "../../abis/campaignAbis"; +} from "../../ponder.schema"; /** * Default campaign stats diff --git a/packages/ponder/src/interactions/webshopInteractions.ts b/packages/ponder/src/interactions/webshopInteractions.ts index 880ebf7..4720fa8 100644 --- a/packages/ponder/src/interactions/webshopInteractions.ts +++ b/packages/ponder/src/interactions/webshopInteractions.ts @@ -1,5 +1,5 @@ -import { ponder } from "ponder:registry"; -import { interactionEventTable } from "ponder:schema"; +import { ponder } from "@/generated"; +import { interactionEventTable } from "../../ponder.schema"; import { safeIncreaseCampaignsStats } from "./stats"; ponder.on("ProductInteraction:WebShopOpenned", async ({ event, context }) => { diff --git a/packages/ponder/src/product.ts b/packages/ponder/src/product.ts index d21e95c..4e30820 100644 --- a/packages/ponder/src/product.ts +++ b/packages/ponder/src/product.ts @@ -1,6 +1,6 @@ -import { ponder } from "ponder:registry"; -import { productTable } from "ponder:schema"; +import { ponder } from "@/generated"; import { productRegistryAbi } from "../abis/registryAbis"; +import { productTable } from "../ponder.schema"; import { bytesToString } from "./utils/format"; ponder.on("ProductRegistry:ProductMinted", async ({ event, context }) => { diff --git a/packages/ponder/src/productAdministrator.ts b/packages/ponder/src/productAdministrator.ts index 8bcb663..1d293ab 100644 --- a/packages/ponder/src/productAdministrator.ts +++ b/packages/ponder/src/productAdministrator.ts @@ -1,6 +1,6 @@ -import { type Context, ponder } from "ponder:registry"; -import { productAdministratorTable } from "ponder:schema"; +import { type Context, ponder } from "@/generated"; import { isAddressEqual, zeroAddress } from "viem"; +import { productAdministratorTable } from "../ponder.schema"; /* * Handle transfer stuff diff --git a/packages/ponder/src/token.ts b/packages/ponder/src/token.ts index f049b72..e1180f9 100644 --- a/packages/ponder/src/token.ts +++ b/packages/ponder/src/token.ts @@ -1,7 +1,7 @@ import console from "node:console"; -import type { Context } from "ponder:registry"; -import { tokenTable } from "ponder:schema"; +import type { Context } from "@/generated"; import { type Address, erc20Abi } from "viem"; +import { tokenTable } from "../ponder.schema"; export async function upsertTokenIfNeeded({ address, From 7232270dc128edfc9f78b2379e44ce9268d56044 Mon Sep 17 00:00:00 2001 From: KONFeature Date: Fri, 29 Nov 2024 00:04:16 +0100 Subject: [PATCH 06/11] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Migrate=20to=20erpc?= =?UTF-8?q?=20builder=20pattern?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/erpc/Dockerfile | 19 +- packages/erpc/erpc-config.ts | 310 -------------------------------- packages/erpc/erpc.yaml | 230 ------------------------ packages/erpc/package.json | 12 +- packages/erpc/src/index.ts | 141 +++++++++++++++ packages/erpc/src/networks.ts | 47 +++++ packages/erpc/src/rateLimits.ts | 53 ++++++ packages/erpc/src/storage.ts | 89 +++++++++ packages/erpc/src/upstreams.ts | 112 ++++++++++++ 9 files changed, 462 insertions(+), 551 deletions(-) delete mode 100644 packages/erpc/erpc-config.ts delete mode 100644 packages/erpc/erpc.yaml create mode 100644 packages/erpc/src/index.ts create mode 100644 packages/erpc/src/networks.ts create mode 100644 packages/erpc/src/rateLimits.ts create mode 100644 packages/erpc/src/storage.ts create mode 100644 packages/erpc/src/upstreams.ts diff --git a/packages/erpc/Dockerfile b/packages/erpc/Dockerfile index 8691943..1a2d0ca 100644 --- a/packages/erpc/Dockerfile +++ b/packages/erpc/Dockerfile @@ -1,11 +1,18 @@ -# Base image is erpc -FROM ghcr.io/erpc/erpc:0.0.24 +# Config bundler step +FROM oven/bun:latest AS bundler +RUN mkdir -p /temp/dev -# Copy the config -COPY erpc.yaml /root/erpc.yaml +# Bundle everything in a single erpc.js file +COPY . /temp/dev +RUN cd /temp/dev && bun install --production +RUN cd /temp/dev && bun build --outfile ./erpc.js --minify --target node --external "@erpc-cloud/*" src/index.ts -EXPOSE 8080/tcp -EXPOSE 4001/tcp +# Final image +FROM erpc-dev:latest AS final +#FROM ghcr.io/erpc/erpc:latest AS FINAL + +# Copy the bundled config +COPY --from=bundler ./temp/dev/erpc.js /root/erpc.js # Run the server CMD ["./erpc-server"] \ No newline at end of file diff --git a/packages/erpc/erpc-config.ts b/packages/erpc/erpc-config.ts deleted file mode 100644 index 416baa9..0000000 --- a/packages/erpc/erpc-config.ts +++ /dev/null @@ -1,310 +0,0 @@ -import { - type ProjectConfig, - type UpstreamConfig, - buildAlchemyUpstream, - buildEnvioUpstream, - buildEvmNetworks, - buildEvmUpstream, - buildPimlicoUpstream, - buildProject, - buildRateLimit, - buildSecretAuthStrategy, - bundlersMethods, - envVariable, -} from "@konfeature/erpc-config-generator"; -import { - type RpcMethodWithRegex, - buildErpcConfig, -} from "@konfeature/erpc-config-generator"; -import type { EIP1474Methods } from "viem"; -import { arbitrum, arbitrumSepolia } from "viem/chains"; - -/* -------------------------------------------------------------------------- */ -/* Config generator for the Frak eRPC config */ -/* -------------------------------------------------------------------------- */ - -// Build every rate limits -const envioRateLimits = buildRateLimit({ - id: "envion-rate-limit", - rules: [ - { - method: "*", - maxCount: 400, - period: "1s", - }, - ], -}); -const alchemyRateLimits = buildRateLimit({ - id: "alchemy-rate-limit", - rules: [ - { - method: "*", - maxCount: 200, - period: "1s", - }, - ], -}); -const blockPiRateLimits = buildRateLimit({ - id: "block-pi-rate-limit", - rules: [ - { - method: "*", - maxCount: 250, - period: "1s", - }, - ], -}); -const pimlicoRateLimits = buildRateLimit({ - id: "pimlico-rate-limit", - rules: [ - { - method: "*", - maxCount: 400, - period: "1s", - }, - ], -}); -const drpcRpcRateLimits = buildRateLimit({ - id: "drpc-rate-limit", - rules: [ - { - method: "*", - maxCount: 200, - period: "1s", - }, - ], -}); -const llamaFreeRpcRateLimits = buildRateLimit({ - id: "llama-free-rpc-rate-limit", - rules: [ - { - method: "*", - maxCount: 50, - period: "1s", - }, - ], -}); -const tenderlyFreeRpcRateLimits = buildRateLimit({ - id: "tenderly-free-rpc-rate-limit", - rules: [ - { - method: "*", - maxCount: 50, - period: "1s", - }, - ], -}); - -// Each networks we will use -const mainnetNetworks = buildEvmNetworks({ - chains: [arbitrum], - generic: { - // Some failsafe config - failsafe: { - timeout: { - duration: "30s", - }, - retry: { - maxAttempts: 5, - delay: "500ms", - backoffMaxDelay: "10s", - backoffFactor: 0.5, - jitter: "200ms", - }, - hedge: { - delay: "5s", - maxCount: 2, - }, - }, - }, -}); -const testnetNetworks = buildEvmNetworks({ - chains: [arbitrumSepolia], - generic: { - // Some failsafe config - failsafe: { - hedge: { - delay: "5s", - maxCount: 2, - }, - }, - // Overide finality depth since arb sepolia could have huge reorgs - evm: { - finalityDepth: 2048, - }, - }, -}); -const networks = [...mainnetNetworks, ...testnetNetworks]; - -const pimlicoSpecificMethods: RpcMethodWithRegex[] = [ - ...bundlersMethods, - "pm_*", - "pimlico_*", -]; - -// Build each upstream we will use -// Envio only op for arbitrum sepolia, it's fcked up on arbitrum -// Disabled for now since it's returning incosistant data -const envioUpstream = buildEnvioUpstream({ - rateLimitBudget: envioRateLimits.id, - ignoreMethods: ["*"], - // todo: simple port of the vendors/evio.go stuff hereh - // since ts sdk doesn't support null value if ts definition doesn't give optional stuff - allowMethods: [ - "eth_chainId", - "eth_blockNumber", - "eth_getBlockByNumber", - "eth_getBlockByHash", - "eth_getTransactionByHash", - "eth_getTransactionByBlockHashAndIndex", - "eth_getTransactionByBlockNumberAndIndex", - "eth_getTransactionReceipt", - "eth_getBlockReceipts", - "eth_getLogs", - ], -}); -const alchemyUpstream = buildAlchemyUpstream({ - apiKey: envVariable("ALCHEMY_API_KEY"), - rateLimitBudget: alchemyRateLimits.id, - ignoreMethods: pimlicoSpecificMethods, -}); -const _blockpiArbSepoliaUpstream = buildEvmUpstream({ - id: "blockpi-arbSepolia", - endpoint: `https://arbitrum-sepolia.blockpi.network/v1/rpc/${envVariable("BLOCKPI_API_KEY_ARB_SEPOLIA")}`, - rateLimitBudget: blockPiRateLimits.id, - ignoreMethods: pimlicoSpecificMethods, -}); -const _blockpiArbUpstream = buildEvmUpstream({ - id: "blockpi-arb", - endpoint: `https://arbitrum.blockpi.network/v1/rpc/${envVariable("BLOCKPI_API_KEY_ARB")}`, - rateLimitBudget: blockPiRateLimits.id, - ignoreMethods: pimlicoSpecificMethods, -}); -const pimlicoUpstream = buildPimlicoUpstream({ - apiKey: envVariable("PIMLICO_API_KEY"), - rateLimitBudget: pimlicoRateLimits.id, - ignoreMethods: ["*"], - allowMethods: pimlicoSpecificMethods, -}); -const llamaFreeRpcUpstreamArb = buildEvmUpstream({ - id: "llama-arbitrum-free-rpc", - endpoint: "https://arbitrum.llamarpc.com", - rateLimitBudget: llamaFreeRpcRateLimits.id, - ignoreMethods: ["*"], - allowMethods: ["eth_chainId", "eth_getBlockByNumber"], -}); -const tenderlyFreeRpcUpstreamArbSepolia = buildEvmUpstream({ - id: "tenderly-arbitrum-sepolia-free-rpc", - endpoint: "https://arbitrum-sepolia.gateway.tenderly.co", - rateLimitBudget: tenderlyFreeRpcRateLimits.id, - ignoreMethods: ["*"], - allowMethods: ["eth_chainId", "eth_getBlockByNumber"], -}); -const drpcUpstream: UpstreamConfig = { - id: "drpc-rpc", - type: "evm+drpc", - vendorName: "drpc", - endpoint: `drpc://${envVariable("DRPC_API_KEY")}`, - rateLimitBudget: drpcRpcRateLimits.id, - ignoreMethods: ["*"], - allowMethods: ["eth_chainId", "eth_getBlockByNumber", "eth_getLogs"], -}; - -// Build the ponder indexing project -const ponderProject: ProjectConfig = buildProject({ - id: "ponder-rpc", - networks, - upstreams: [ - alchemyUpstream, - llamaFreeRpcUpstreamArb, - drpcUpstream, - envioUpstream, - ], - auth: { - strategies: [ - buildSecretAuthStrategy({ - secret: { - value: envVariable("PONDER_RPC_SECRET"), - }, - }), - ], - }, -}); - -// Build the ponder indexing project -const ponderDevProject: ProjectConfig = buildProject({ - id: "ponder-dev-rpc", - networks, - upstreams: [tenderlyFreeRpcUpstreamArbSepolia, drpcUpstream, envioUpstream], - auth: { - strategies: [ - buildSecretAuthStrategy({ - secret: { - value: envVariable("PONDER_RPC_SECRET"), - }, - }), - ], - }, -}); - -// Build the nexus rpc project -// todo: add authentication + more restrictie cors origin -const nexusProject: ProjectConfig = buildProject({ - id: "nexus-rpc", - networks, - upstreams: [alchemyUpstream, pimlicoUpstream], - cors: { - allowedOrigins: ["*"], - allowedMethods: ["GET", "POST", "OPTIONS"], - allowedHeaders: ["Content-Type", "Authorization"], - exposedHeaders: ["X-Request-ID"], - allowCredentials: true, - maxAge: 3600, - }, - auth: { - strategies: [ - buildSecretAuthStrategy({ - secret: { - value: envVariable("NEXUS_RPC_SECRET"), - }, - }), - ], - }, -}); - -// Build the global config -export default buildErpcConfig({ - config: { - logLevel: envVariable("ERPC_LOG_LEVEL"), - database: { - evmJsonRpcCache: { - driver: "postgresql", - postgresql: { - connectionUri: envVariable("ERPC_DATABASE_URL"), - table: "rpc_cache", - }, - }, - }, - server: { - httpPort: 8080, - maxTimeout: "60s", - listenV6: false, - }, - metrics: { - enabled: true, - listenV6: false, - }, - projects: [ponderProject, ponderDevProject, nexusProject], - rateLimiters: { - budgets: [ - envioRateLimits, - alchemyRateLimits, - pimlicoRateLimits, - blockPiRateLimits, - drpcRpcRateLimits, - llamaFreeRpcRateLimits, - tenderlyFreeRpcRateLimits, - ], - }, - }, -}); diff --git a/packages/erpc/erpc.yaml b/packages/erpc/erpc.yaml deleted file mode 100644 index 5d099d3..0000000 --- a/packages/erpc/erpc.yaml +++ /dev/null @@ -1,230 +0,0 @@ -# Config generated using: https://github.com/KONFeature/erpc-config-generator -logLevel: ${ERPC_LOG_LEVEL} -server: - httpPort: 8080 - httpHostV4: 0.0.0.0 - httpHostV6: "[::]" - listenV4: true - listenV6: false - maxTimeout: 60s -metrics: - port: 4001 - hostV4: 0.0.0.0 - hostV6: "[::]" - listenV4: true - listenV6: false - enabled: true -database: - evmJsonRpcCache: - driver: postgresql - postgresql: - connectionUri: ${ERPC_DATABASE_URL} - table: rpc_cache -projects: - - rateLimitBudget: "" - id: ponder-rpc - networks: &var1 - - failsafe: - timeout: - duration: 30s - retry: - maxAttempts: 5 - delay: 500ms - backoffMaxDelay: 10s - backoffFactor: 0.5 - jitter: 200ms - hedge: - delay: 5s - maxCount: 2 - architecture: evm - rateLimitBudget: "" - evm: - chainId: 42161 - finalityDepth: 1024 - blockTrackerInterval: "" - - failsafe: - hedge: - delay: 5s - maxCount: 2 - evm: - chainId: 421614 - finalityDepth: 2048 - blockTrackerInterval: "" - architecture: evm - rateLimitBudget: "" - upstreams: - - &var4 - id: alchemy - endpoint: evm+alchemy://${ALCHEMY_API_KEY} - type: evm+alchemy - rateLimitBudget: alchemy-rate-limit - vendorName: Alchemy - ignoreMethods: &var5 - - eth_estimateUserOperationGas - - eth_getUserOperationByHash - - eth_getUserOperationReceipt - - eth_sendUserOperation - - eth_supportedEntryPoints - - pm_* - - pimlico_* - allowMethods: [] - autoIgnoreUnsupportedMethods: true - - id: llama-arbitrum-free-rpc - endpoint: https://arbitrum.llamarpc.com - rateLimitBudget: llama-free-rpc-rate-limit - type: evm - vendorName: Generic Evm - ignoreMethods: - - "*" - allowMethods: - - eth_chainId - - eth_getBlockByNumber - autoIgnoreUnsupportedMethods: true - - &var2 - id: drpc-rpc - type: evm+drpc - vendorName: drpc - endpoint: drpc://${DRPC_API_KEY} - rateLimitBudget: drpc-rate-limit - ignoreMethods: - - "*" - allowMethods: - - eth_chainId - - eth_getBlockByNumber - - eth_getLogs - - &var3 - id: envio - endpoint: evm+envio://rpc.hypersync.xyz - rateLimitBudget: envion-rate-limit - type: evm+envio - vendorName: Envio - ignoreMethods: - - "*" - allowMethods: - - eth_chainId - - eth_blockNumber - - eth_getBlockByNumber - - eth_getBlockByHash - - eth_getTransactionByHash - - eth_getTransactionByBlockHashAndIndex - - eth_getTransactionByBlockNumberAndIndex - - eth_getTransactionReceipt - - eth_getBlockReceipts - - eth_getLogs - autoIgnoreUnsupportedMethods: true - auth: - strategies: - - allowMethods: - - "*" - ignoreMethods: [] - rateLimitBudget: "" - type: secret - secret: - value: ${PONDER_RPC_SECRET} - - rateLimitBudget: "" - id: ponder-dev-rpc - networks: *var1 - upstreams: - - id: tenderly-arbitrum-sepolia-free-rpc - endpoint: https://arbitrum-sepolia.gateway.tenderly.co - rateLimitBudget: tenderly-free-rpc-rate-limit - type: evm - vendorName: Generic Evm - ignoreMethods: - - "*" - allowMethods: - - eth_chainId - - eth_getBlockByNumber - autoIgnoreUnsupportedMethods: true - - *var2 - - *var3 - auth: - strategies: - - allowMethods: - - "*" - ignoreMethods: [] - rateLimitBudget: "" - type: secret - secret: - value: ${PONDER_RPC_SECRET} - - rateLimitBudget: "" - id: nexus-rpc - networks: *var1 - upstreams: - - *var4 - - id: pimlico - endpoint: evm+pimlico://${PIMLICO_API_KEY} - rateLimitBudget: pimlico-rate-limit - type: evm+pimlico - vendorName: Pimlico - ignoreMethods: - - "*" - allowMethods: *var5 - autoIgnoreUnsupportedMethods: true - cors: - allowedOrigins: - - "*" - allowedMethods: - - GET - - POST - - OPTIONS - allowedHeaders: - - Content-Type - - Authorization - exposedHeaders: - - X-Request-ID - allowCredentials: true - maxAge: 3600 - auth: - strategies: - - allowMethods: - - "*" - ignoreMethods: [] - rateLimitBudget: "" - type: secret - secret: - value: ${NEXUS_RPC_SECRET} -rateLimiters: - budgets: - - id: envion-rate-limit - rules: - - method: "*" - maxCount: 400 - period: 1s - waitTime: "" - - id: alchemy-rate-limit - rules: - - method: "*" - maxCount: 200 - period: 1s - waitTime: "" - - id: pimlico-rate-limit - rules: - - method: "*" - maxCount: 400 - period: 1s - waitTime: "" - - id: block-pi-rate-limit - rules: - - method: "*" - maxCount: 250 - period: 1s - waitTime: "" - - id: drpc-rate-limit - rules: - - method: "*" - maxCount: 200 - period: 1s - waitTime: "" - - id: llama-free-rpc-rate-limit - rules: - - method: "*" - maxCount: 50 - period: 1s - waitTime: "" - - id: tenderly-free-rpc-rate-limit - rules: - - method: "*" - maxCount: 50 - period: 1s - waitTime: "" diff --git a/packages/erpc/package.json b/packages/erpc/package.json index 358c760..3319103 100644 --- a/packages/erpc/package.json +++ b/packages/erpc/package.json @@ -8,16 +8,18 @@ "build": "erpc-config", "build:check": "erpc-config validate", "lint": "biome lint .", - "typecheck": "tsc" + "typecheck": "tsc", + "docker:dev": "docker build --tag frak-erpc . && docker run --env-file ./.env.local frak-erpc" }, "devDependencies": { "@biomejs/biome": "1.9.4", "@konfeature/erpc-config-generator": "0.0.13", - "@types/aws-lambda": "8.10.146", - "@types/node": "^22.10.1", - "sst": "3.3.44", - "typescript": "^5.7.2", "viem": "^2.21.54" + "sst": "3.3.29", + "typescript": "^5.7.2" + }, + "dependencies": { + "@erpc-cloud/config": "^0.0.7" }, "engines": { "node": ">=18.14" diff --git a/packages/erpc/src/index.ts b/packages/erpc/src/index.ts new file mode 100644 index 0000000..42c2492 --- /dev/null +++ b/packages/erpc/src/index.ts @@ -0,0 +1,141 @@ +import { type LogLevel, initErpcConfig } from "@erpc-cloud/config"; +import { arbNetwork, arbSepoliaNetwork } from "./networks"; +import { + alchemyRateRules, + blockPiRateRules, + drpcRateRules, + envioRateRules, + llamaFreeRateRules, + pimlicoRateRules, + tenderlyFreeRateRules, +} from "./rateLimits"; +import { cacheConfig } from "./storage"; +import { + alchemyUpstream, + drpcUpstream, + envioUpstream, + llamaFreeUpstreamArb, + pimlicoUpstream, + tenderlyFreeUpstreamArbSepolia, +} from "./upstreams"; + +/** + * Build our top erpc config + */ +export default initErpcConfig({ + logLevel: (process.env.ERPC_LOG_LEVEL ?? "info") as LogLevel, + database: { + evmJsonRpcCache: cacheConfig, + }, + server: { + httpPort: 8080, + maxTimeout: "60s", + listenV6: false, + }, + metrics: { + enabled: true, + listenV6: false, + }, +}) + .addRateLimiters({ + alchemy: alchemyRateRules, + envio: envioRateRules, + pimlico: pimlicoRateRules, + blockPi: blockPiRateRules, + drpc: drpcRateRules, + llamaFree: llamaFreeRateRules, + tenderlyFree: tenderlyFreeRateRules, + }) + // Add networks to the config + .decorate({ + scope: "networks", + value: { + arbitrum: arbNetwork, + arbitrumSepolia: arbSepoliaNetwork, + }, + }) + // Add upstreams to the config + .decorate({ + scope: "upstreams", + value: { + envio: envioUpstream, + alchemy: alchemyUpstream, + pimlico: pimlicoUpstream, + drpc: drpcUpstream, + llamaFree: llamaFreeUpstreamArb, + tenderlyFree: tenderlyFreeUpstreamArbSepolia, + }, + }) + // Add our ponder prod project + .addProject(({ store: { upstreams, networks } }) => ({ + id: "ponder-rpc", + networks: [networks.arbitrum], + upstreams: [ + upstreams.alchemy, + upstreams.envio, + upstreams.drpc, + upstreams.llamaFree, + ], + auth: { + strategies: [ + { + type: "secret", + secret: { + value: process.env.PONDER_RPC_SECRET ?? "a", + }, + }, + ], + }, + })) + // Add our ponder dev project + .addProject(({ store: { upstreams, networks } }) => ({ + id: "ponder-dev-rpc", + networks: [networks.arbitrumSepolia], + upstreams: [ + upstreams.alchemy, + upstreams.envio, + upstreams.drpc, + upstreams.tenderlyFree, + ], + auth: { + strategies: [ + { + type: "secret", + secret: { + value: process.env.PONDER_RPC_SECRET ?? "a", + }, + }, + ], + }, + })) + // Add our wallet project + .addProject(({ store: { upstreams, networks } }) => ({ + id: "nexus-rpc", + networks: [networks.arbitrum, networks.arbitrumSepolia], + upstreams: [ + upstreams.alchemy, + upstreams.drpc, + upstreams.llamaFree, + upstreams.tenderlyFree, + ], + auth: { + strategies: [ + { + type: "secret", + secret: { + value: process.env.NEXUS_RPC_SECRET ?? "a", + }, + }, + ], + }, + cors: { + allowedOrigins: ["*"], + allowedMethods: ["GET", "POST", "OPTIONS"], + allowedHeaders: ["Content-Type", "Authorization"], + exposedHeaders: ["X-Request-ID"], + allowCredentials: true, + maxAge: 3600, + }, + })) + // And bundle it altogether + .build(); diff --git a/packages/erpc/src/networks.ts b/packages/erpc/src/networks.ts new file mode 100644 index 0000000..2a1bd16 --- /dev/null +++ b/packages/erpc/src/networks.ts @@ -0,0 +1,47 @@ +import type { NetworkConfig } from "@erpc-cloud/config"; + +export const arbNetwork = { + architecture: "evm", + failsafe: { + timeout: { + duration: "30s", + }, + retry: { + maxAttempts: 5, + delay: "500ms", + backoffMaxDelay: "10s", + backoffFactor: 0.5, + jitter: "200ms", + }, + hedge: { + delay: "3s", + maxCount: 2, + }, + }, + evm: { + chainId: 42161, + }, +} as const satisfies NetworkConfig; + +export const arbSepoliaNetwork = { + architecture: "evm", + failsafe: { + timeout: { + duration: "120s", + }, + retry: { + maxAttempts: 3, + delay: "1s", + backoffMaxDelay: "30s", + backoffFactor: 0.5, + jitter: "200ms", + }, + hedge: { + delay: "5s", + maxCount: 2, + }, + }, + evm: { + chainId: 421614, + }, +} as const satisfies NetworkConfig; diff --git a/packages/erpc/src/rateLimits.ts b/packages/erpc/src/rateLimits.ts new file mode 100644 index 0000000..5675379 --- /dev/null +++ b/packages/erpc/src/rateLimits.ts @@ -0,0 +1,53 @@ +import type { RateLimitRuleConfig } from "@erpc-cloud/config"; + +/** + * Build a generic rate limits rules, counting on the number of request per minutes + * @param count + */ +function genericRateLimitsRules(count: number): RateLimitRuleConfig { + return { + method: "*", + maxCount: count, + period: "1s", + waitTime: "30s", + }; +} + +export const envioRateRules: RateLimitRuleConfig[] = [ + genericRateLimitsRules(400), + { + method: "eth_getLogs", + maxCount: 150, + period: "1s", + waitTime: "10s", + }, +]; + +export const alchemyRateRules: RateLimitRuleConfig[] = [ + genericRateLimitsRules(200), + { + method: "eth_getLogs", + maxCount: 30, + period: "1s", + waitTime: "10s", + }, +]; + +export const pimlicoRateRules: RateLimitRuleConfig[] = [ + genericRateLimitsRules(400), +]; + +export const blockPiRateRules: RateLimitRuleConfig[] = [ + genericRateLimitsRules(100), +]; + +export const drpcRateRules: RateLimitRuleConfig[] = [ + genericRateLimitsRules(100), +]; + +export const llamaFreeRateRules: RateLimitRuleConfig[] = [ + genericRateLimitsRules(30), +]; +export const tenderlyFreeRateRules: RateLimitRuleConfig[] = [ + genericRateLimitsRules(10), +]; diff --git a/packages/erpc/src/storage.ts b/packages/erpc/src/storage.ts new file mode 100644 index 0000000..4b2f132 --- /dev/null +++ b/packages/erpc/src/storage.ts @@ -0,0 +1,89 @@ +import { + type CacheConfig, + CacheEmptyBehaviorAllow, + CacheEmptyBehaviorIgnore, + type CachePolicyConfig, + type ConnectorConfig, + DataFinalityStateFinalized, + DataFinalityStateRealtime, + DataFinalityStateUnfinalized, +} from "@erpc-cloud/config"; + +if (!process.env.ERPC_DATABASE_URL) { + throw new Error("Missing ERPC_DATABASE_URL environment variable"); +} + +/** + * The connectors we will use + */ +const connectors = [ + { + id: "pg-main", + driver: "postgresql", + postgresql: { + connectionUri: process.env.ERPC_DATABASE_URL as string, + table: "rpc_cache", + }, + }, + { + id: "memory-main", + driver: "memory", + memory: { + maxItems: 65_536, + }, + }, +] as const satisfies ConnectorConfig[]; + +/** + * Define the cache policies we will use + * todo: Should check with 4337 userOpGas price if it play nicely + * todo: Also find a way to cache 4337 related et_getCode method for longer period in memory? Only if non empty maybe? + */ +const cachePolicies = [ + // Cache credits intensive calls on the pg when data are finalised + { + connector: "pg-main", + network: "*", + method: "eth_getLogs | eth_getBlock* | eth_getTransactionBy* | eth_getStorageAt", + finality: DataFinalityStateFinalized, + empty: CacheEmptyBehaviorAllow, + }, + // Cache not finalized data for 2sec in the memory + { + connector: "memory-main", + network: "*", + method: "*", + finality: DataFinalityStateUnfinalized, + empty: CacheEmptyBehaviorIgnore, + // 5sec in nanoseconds + ttl: 2_000_000_000, + }, + // Cache realtime data for 5sec on the memory on arbitrum + { + connector: "memory-main", + network: "evm:42161", + method: "*", + finality: DataFinalityStateRealtime, + empty: CacheEmptyBehaviorIgnore, + // 5sec in nanoseconds + ttl: 5_000_000_000, + }, + // Cache realtime data for 30sec on arbitrum sepolia + { + connector: "memory-main", + network: "evm:421614", + method: "*", + finality: DataFinalityStateRealtime, + empty: CacheEmptyBehaviorIgnore, + // 5sec in nanoseconds + ttl: 30_000_000_000, + }, +] as const satisfies CachePolicyConfig[]; + +/** + * Export our final cache config + */ +export const cacheConfig = { + connectors, + policies: cachePolicies, +} as const satisfies CacheConfig; diff --git a/packages/erpc/src/upstreams.ts b/packages/erpc/src/upstreams.ts new file mode 100644 index 0000000..c2d2ba3 --- /dev/null +++ b/packages/erpc/src/upstreams.ts @@ -0,0 +1,112 @@ +import type { UpstreamConfig } from "@erpc-cloud/config"; + +if (!process.env.ALCHEMY_API_KEY) { + throw new Error("Missing ALCHEMY_API_KEY environment variable"); +} +if (!process.env.PIMLICO_API_KEY) { + throw new Error("Missing PIMLICO_API_KEY environment variable"); +} +if (!process.env.DRPC_API_KEY) { + throw new Error("Missing DRPC_API_KEY environment variable"); +} + +/** + * Method specifics for for the smart wallets + */ +const erc4337Methods = [ + "eth_estimateUserOperationGas", + "eth_getUserOperationByHash", + "eth_getUserOperationReceipt", + "eth_sendUserOperation", + "eth_supportedEntryPoints", + "pm_*", + "pimlico_*", +]; + +const indexingMethods = [ + "eth_chainId", + "eth_blockNumber", + "eth_getLogs", + "eth_getBlock*", + "eth_getTransaction*", +]; + +const freeRpcMethods = [ + "eth_chainId", + "eth_blockNumber", + "eth_call", + "eth_getCode", + "eth_getStorageAt", + "eth_getBlock*", + "eth_getTransaction*", +]; + +// Drpc methods are indexing + free rpc methods deduplicated +const drpcMethods = Array.from( + new Set([...indexingMethods, ...freeRpcMethods]) +); + +export const envioUpstream = { + endpoint: "evm+envio://rpc.hypersync.xyz", + type: "evm+envio", + vendorName: "Envio", + ignoreMethods: ["*"], + // Budget for rate limiting + rateLimitBudget: "envio", + // Only allow getLogs, getBlockBy and getTransactions* + allowMethods: indexingMethods, +} as const satisfies UpstreamConfig; + +export const alchemyUpstream = { + endpoint: `evm+alchemy://${process.env.ALCHEMY_API_KEY}`, + type: "evm+alchemy", + vendorName: "Alchemy", + // Budget for rate limiting + rateLimitBudget: "alchemy", + // Ignore all the pimlico + ignoreMethods: erc4337Methods, +} as const satisfies UpstreamConfig; + +export const pimlicoUpstream = { + endpoint: `evm+pimlico://${process.env.PIMLICO_API_KEY}`, + type: "evm+pimlico", + vendorName: "Pimlico", + // Budget for rate limiting + rateLimitBudget: "pimlico", + // Only allow the 4337 methods + ignoreMethods: ["*"], + allowMethods: erc4337Methods, +} as const satisfies UpstreamConfig; + +export const drpcUpstream = { + endpoint: `drpc://${process.env.DRPC_API_KEY}`, + type: "evm+drpc", + vendorName: "drpc", + // Budget for rate limiting + rateLimitBudget: "drpc", + // Only allow chainId, getBlockBy and getLogs + ignoreMethods: ["*"], + allowMethods: drpcMethods, +} as const satisfies UpstreamConfig; + +export const llamaFreeUpstreamArb = { + endpoint: "https://arbitrum.llamarpc.com", + type: "evm", + vendorName: "LlamaFree", + // Budget for rate limiting + rateLimitBudget: "llamaFree", + // Only allow chainId and getBlockBy + ignoreMethods: ["*"], + allowMethods: freeRpcMethods, +} as const satisfies UpstreamConfig; + +export const tenderlyFreeUpstreamArbSepolia = { + endpoint: "https://arbitrum-sepolia.gateway.tenderly.co", + type: "evm", + vendorName: "TenderlyFree", + // Budget for rate limiting + rateLimitBudget: "tenderlyFree", + // Only allow chainId and getBlockBy + ignoreMethods: ["*"], + allowMethods: freeRpcMethods, +} as const satisfies UpstreamConfig; From 6269e949e6e5f124801f622144829bedb7974e83 Mon Sep 17 00:00:00 2001 From: KONFeature Date: Sun, 1 Dec 2024 18:46:23 +0100 Subject: [PATCH 07/11] =?UTF-8?q?=F0=9F=90=9B=20Switch=20to=20new=20decora?= =?UTF-8?q?tion=20method?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bun.lockb | Bin 280629 -> 283218 bytes packages/erpc/package.json | 4 ++-- packages/erpc/src/index.ts | 28 +++++++++++----------------- packages/erpc/src/rateLimits.ts | 26 +++++++++----------------- packages/erpc/src/storage.ts | 14 +++++++------- 5 files changed, 29 insertions(+), 43 deletions(-) diff --git a/bun.lockb b/bun.lockb index 8430dfad10b1ae31e3b77bba069c40b718f71623..bfa1f4747931a034309b1422145cc3f271438523 100755 GIT binary patch delta 11387 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 CeGnx8 diff --git a/packages/erpc/package.json b/packages/erpc/package.json index 3319103..142f5ad 100644 --- a/packages/erpc/package.json +++ b/packages/erpc/package.json @@ -14,12 +14,12 @@ "devDependencies": { "@biomejs/biome": "1.9.4", "@konfeature/erpc-config-generator": "0.0.13", - "viem": "^2.21.54" + "viem": "^2.21.54", "sst": "3.3.29", "typescript": "^5.7.2" }, "dependencies": { - "@erpc-cloud/config": "^0.0.7" + "@erpc-cloud/config": "^0.0.10" }, "engines": { "node": ">=18.14" diff --git a/packages/erpc/src/index.ts b/packages/erpc/src/index.ts index 42c2492..6200da6 100644 --- a/packages/erpc/src/index.ts +++ b/packages/erpc/src/index.ts @@ -20,7 +20,7 @@ import { } from "./upstreams"; /** - * Build our top erpc config + * Build our top level erpc config */ export default initErpcConfig({ logLevel: (process.env.ERPC_LOG_LEVEL ?? "info") as LogLevel, @@ -47,24 +47,18 @@ export default initErpcConfig({ tenderlyFree: tenderlyFreeRateRules, }) // Add networks to the config - .decorate({ - scope: "networks", - value: { - arbitrum: arbNetwork, - arbitrumSepolia: arbSepoliaNetwork, - }, + .decorate("networks", { + arbitrum: arbNetwork, + arbitrumSepolia: arbSepoliaNetwork, }) // Add upstreams to the config - .decorate({ - scope: "upstreams", - value: { - envio: envioUpstream, - alchemy: alchemyUpstream, - pimlico: pimlicoUpstream, - drpc: drpcUpstream, - llamaFree: llamaFreeUpstreamArb, - tenderlyFree: tenderlyFreeUpstreamArbSepolia, - }, + .decorate("upstreams", { + envio: envioUpstream, + alchemy: alchemyUpstream, + pimlico: pimlicoUpstream, + drpc: drpcUpstream, + llamaFree: llamaFreeUpstreamArb, + tenderlyFree: tenderlyFreeUpstreamArbSepolia, }) // Add our ponder prod project .addProject(({ store: { upstreams, networks } }) => ({ diff --git a/packages/erpc/src/rateLimits.ts b/packages/erpc/src/rateLimits.ts index 5675379..d00d47f 100644 --- a/packages/erpc/src/rateLimits.ts +++ b/packages/erpc/src/rateLimits.ts @@ -13,7 +13,9 @@ function genericRateLimitsRules(count: number): RateLimitRuleConfig { }; } -export const envioRateRules: RateLimitRuleConfig[] = [ +type RuleExport = [RateLimitRuleConfig, ...RateLimitRuleConfig[]]; + +export const envioRateRules: RuleExport = [ genericRateLimitsRules(400), { method: "eth_getLogs", @@ -23,7 +25,7 @@ export const envioRateRules: RateLimitRuleConfig[] = [ }, ]; -export const alchemyRateRules: RateLimitRuleConfig[] = [ +export const alchemyRateRules: RuleExport = [ genericRateLimitsRules(200), { method: "eth_getLogs", @@ -33,21 +35,11 @@ export const alchemyRateRules: RateLimitRuleConfig[] = [ }, ]; -export const pimlicoRateRules: RateLimitRuleConfig[] = [ - genericRateLimitsRules(400), -]; +export const pimlicoRateRules: RuleExport = [genericRateLimitsRules(400)]; -export const blockPiRateRules: RateLimitRuleConfig[] = [ - genericRateLimitsRules(100), -]; +export const blockPiRateRules: RuleExport = [genericRateLimitsRules(100)]; -export const drpcRateRules: RateLimitRuleConfig[] = [ - genericRateLimitsRules(100), -]; +export const drpcRateRules: RuleExport = [genericRateLimitsRules(100)]; -export const llamaFreeRateRules: RateLimitRuleConfig[] = [ - genericRateLimitsRules(30), -]; -export const tenderlyFreeRateRules: RateLimitRuleConfig[] = [ - genericRateLimitsRules(10), -]; +export const llamaFreeRateRules: RuleExport = [genericRateLimitsRules(30)]; +export const tenderlyFreeRateRules: RuleExport = [genericRateLimitsRules(10)]; diff --git a/packages/erpc/src/storage.ts b/packages/erpc/src/storage.ts index 4b2f132..729b917 100644 --- a/packages/erpc/src/storage.ts +++ b/packages/erpc/src/storage.ts @@ -40,11 +40,11 @@ const connectors = [ * todo: Also find a way to cache 4337 related et_getCode method for longer period in memory? Only if non empty maybe? */ const cachePolicies = [ - // Cache credits intensive calls on the pg when data are finalised + // Cache all finalized data in the pg database { connector: "pg-main", network: "*", - method: "eth_getLogs | eth_getBlock* | eth_getTransactionBy* | eth_getStorageAt", + method: "*", finality: DataFinalityStateFinalized, empty: CacheEmptyBehaviorAllow, }, @@ -55,18 +55,18 @@ const cachePolicies = [ method: "*", finality: DataFinalityStateUnfinalized, empty: CacheEmptyBehaviorIgnore, - // 5sec in nanoseconds + // 2sec in nanoseconds ttl: 2_000_000_000, }, - // Cache realtime data for 5sec on the memory on arbitrum + // Cache realtime data for 2sec on the memory on arbitrum { connector: "memory-main", network: "evm:42161", method: "*", finality: DataFinalityStateRealtime, empty: CacheEmptyBehaviorIgnore, - // 5sec in nanoseconds - ttl: 5_000_000_000, + // 2sec in nanoseconds + ttl: 2_000_000_000, }, // Cache realtime data for 30sec on arbitrum sepolia { @@ -75,7 +75,7 @@ const cachePolicies = [ method: "*", finality: DataFinalityStateRealtime, empty: CacheEmptyBehaviorIgnore, - // 5sec in nanoseconds + // 30sec in nanoseconds ttl: 30_000_000_000, }, ] as const satisfies CachePolicyConfig[]; From 25233af88e1e5969f47d379cda9a2ff4dea1363b Mon Sep 17 00:00:00 2001 From: KONFeature Date: Tue, 17 Dec 2024 20:59:06 +0100 Subject: [PATCH 08/11] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Upgrade=20erpc=20con?= =?UTF-8?q?fig=20generator=20+=20deploy=20erpc=20on=20dev?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bun.lockb | Bin 283218 -> 272784 bytes infra/erpc.ts | 6 +----- package.json | 1 - packages/erpc/package.json | 9 ++++----- packages/erpc/src/index.ts | 4 +++- packages/ponder/package.json | 3 +-- sst.config.ts | 5 +++-- 7 files changed, 12 insertions(+), 16 deletions(-) diff --git a/bun.lockb b/bun.lockb index bfa1f4747931a034309b1422145cc3f271438523..6f455b16b031d0626439748b87d075e400d2df0d 100755 GIT binary patch delta 13766 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 Y7Kt1EGi}`t2zvIj1JXJVl<1272g@Afng9R* delta 20812 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 M>Srf4(=ZhLFR>DS=18.14" }, - "packageManager": "bun@1.1.38", "workspaces": ["packages/*"] } diff --git a/packages/erpc/package.json b/packages/erpc/package.json index 142f5ad..36349a0 100644 --- a/packages/erpc/package.json +++ b/packages/erpc/package.json @@ -9,20 +9,19 @@ "build:check": "erpc-config validate", "lint": "biome lint .", "typecheck": "tsc", - "docker:dev": "docker build --tag frak-erpc . && docker run --env-file ./.env.local frak-erpc" + "docker:dev": "docker build --tag frak-erpc . && docker run --env-file ./.env.local -P frak-erpc" }, "devDependencies": { "@biomejs/biome": "1.9.4", - "@konfeature/erpc-config-generator": "0.0.13", "viem": "^2.21.54", "sst": "3.3.29", "typescript": "^5.7.2" }, "dependencies": { - "@erpc-cloud/config": "^0.0.10" + "@konfeature/erpc-config-generator": "0.1.0", + "@erpc-cloud/config": "^0.0.11" }, "engines": { "node": ">=18.14" - }, - "packageManager": "bun@1.1.38" + } } \ No newline at end of file diff --git a/packages/erpc/src/index.ts b/packages/erpc/src/index.ts index 6200da6..4f116ba 100644 --- a/packages/erpc/src/index.ts +++ b/packages/erpc/src/index.ts @@ -1,4 +1,5 @@ -import { type LogLevel, initErpcConfig } from "@erpc-cloud/config"; +import type { LogLevel } from "@erpc-cloud/config"; +import { initErpcConfig } from "@konfeature/erpc-config-generator"; import { arbNetwork, arbSepoliaNetwork } from "./networks"; import { alchemyRateRules, @@ -36,6 +37,7 @@ export default initErpcConfig({ enabled: true, listenV6: false, }, + blablou: "test", }) .addRateLimiters({ alchemy: alchemyRateRules, diff --git a/packages/ponder/package.json b/packages/ponder/package.json index 4af5b27..d4113b2 100644 --- a/packages/ponder/package.json +++ b/packages/ponder/package.json @@ -33,6 +33,5 @@ }, "engines": { "node": ">=18.14" - }, - "packageManager": "bun@1.1.38" + } } \ No newline at end of file diff --git a/sst.config.ts b/sst.config.ts index 116f0e6..318e55a 100644 --- a/sst.config.ts +++ b/sst.config.ts @@ -16,9 +16,10 @@ export default $config({ async run() { await import("./infra/common.ts"); + await import("./infra/erpc.ts"); + if ($app.stage === "production") { - // ERPC + ponder deployment on prod - await import("./infra/erpc.ts"); + // Ponder deployment on prod await import("./infra/ponder.prod.ts"); } else { // Only ponder on dev From 1729afe29d1cd7f8221b057d066132ac064593ed Mon Sep 17 00:00:00 2001 From: KONFeature Date: Tue, 17 Dec 2024 21:07:30 +0100 Subject: [PATCH 09/11] =?UTF-8?q?=F0=9F=90=9B=20Remove=20erpc=20from=20dev?= =?UTF-8?q?=20env?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- infra/erpc.ts | 6 +++++- sst.config.ts | 5 ++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/infra/erpc.ts b/infra/erpc.ts index e8fa424..822f85a 100644 --- a/infra/erpc.ts +++ b/infra/erpc.ts @@ -4,6 +4,10 @@ import { cluster, vpc } from "./common.ts"; import { ServiceTargets } from "./components/ServiceTargets.ts"; import { SstService } from "./utils.ts"; +if ($app.stage !== "production") { + throw new Error("eRPC is reserved for production usage"); +} + // Get the image we will deploy const image = await aws.ecr.getImage({ repositoryName: "erpc", @@ -13,7 +17,7 @@ const image = await aws.ecr.getImage({ // Create the service targets const erpcServiceTargets = new ServiceTargets("ErpcServiceDomain", { vpcId: vpc.id, - domain: $app.stage === "production" ? "rpc.frak.id" : "rpc-dev.frak.id", + domain: "rpc.frak.id", ports: [ { listen: "80/http", forward: "8080/http" }, { listen: "443/https", forward: "8080/http" }, diff --git a/sst.config.ts b/sst.config.ts index 318e55a..116f0e6 100644 --- a/sst.config.ts +++ b/sst.config.ts @@ -16,10 +16,9 @@ export default $config({ async run() { await import("./infra/common.ts"); - await import("./infra/erpc.ts"); - if ($app.stage === "production") { - // Ponder deployment on prod + // ERPC + ponder deployment on prod + await import("./infra/erpc.ts"); await import("./infra/ponder.prod.ts"); } else { // Only ponder on dev From d63e998767a8465b662e98b1eca0952df38ef4c1 Mon Sep 17 00:00:00 2001 From: KONFeature Date: Tue, 17 Dec 2024 21:11:25 +0100 Subject: [PATCH 10/11] =?UTF-8?q?=F0=9F=A7=B1=20Add=20a=20shared=20blockch?= =?UTF-8?q?ain=20db=20+=20use=20it=20for=20erpc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- infra/common.ts | 15 +++++++++++++++ infra/erpc.ts | 19 +++++++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/infra/common.ts b/infra/common.ts index cb09669..bdd1b67 100644 --- a/infra/common.ts +++ b/infra/common.ts @@ -1,4 +1,5 @@ import * as aws from "@pulumi/aws"; +import { Output } from "@pulumi/pulumi"; // Get the VPC const { id: vpcId } = await aws.ec2.getVpc({ @@ -10,3 +11,17 @@ export const vpc = sst.aws.Vpc.get("MasterVpc", vpcId); export const cluster = await aws.ecs.getCluster({ clusterName: `master-cluster-${$app.stage}`, }); + +/** + * Build the postgres DB for the current env + */ +export const database = + $app.stage !== "production" + ? sst.aws.Postgres.get("blockchain", { + id: "frak-indexer-production-blockchaininstance", + }) + : new sst.aws.Postgres("blockchain", { + vpc: Output.create(vpc).apply((v) => ({ + subnets: v.privateSubnets, + })), + }); diff --git a/infra/erpc.ts b/infra/erpc.ts index 822f85a..19872e2 100644 --- a/infra/erpc.ts +++ b/infra/erpc.ts @@ -1,6 +1,6 @@ import * as aws from "@pulumi/aws"; import { all } from "@pulumi/pulumi"; -import { cluster, vpc } from "./common.ts"; +import { cluster, database, vpc } from "./common.ts"; import { ServiceTargets } from "./components/ServiceTargets.ts"; import { SstService } from "./utils.ts"; @@ -32,6 +32,19 @@ const erpcServiceTargets = new ServiceTargets("ErpcServiceDomain", { }, }); +/** + * Build the erpc database URL + */ +const dbUrl = all([ + database.host, + database.port, + database.username, + database.password, + database.database, +]).apply(([host, port, username, password, database]) => { + return `postgres://${username}:${password}@${host}:${port}/${database}`; +}); + // Create the erpc service (only on prod stage) export const erpcService = new SstService("Erpc", { vpc, @@ -60,6 +73,7 @@ export const erpcService = new SstService("Erpc", { // Env environment: { ERPC_LOG_LEVEL: "warn", + ERPC_DATABASE_URL: dbUrl, }, // SSM secrets ssm: { @@ -79,9 +93,6 @@ export const erpcService = new SstService("Erpc", { "arn:aws:ssm:eu-west-1:262732185023:parameter/sst/frak-indexer/.fallback/Secret/PONDER_RPC_SECRET/value", NEXUS_RPC_SECRET: "arn:aws:ssm:eu-west-1:262732185023:parameter/sst/frak-indexer/.fallback/Secret/NEXUS_RPC_SECRET/value", - // Postgres db - ERPC_DATABASE_URL: - "arn:aws:ssm:eu-west-1:262732185023:parameter/indexer/sst/Secret/ERPC_DATABASE_URL/value", }, // Tell the service registry to forward requests to the 8080 port serviceRegistry: { From 5c2525582bf51b66aef1ac8804e733c6361d696b Mon Sep 17 00:00:00 2001 From: KONFeature Date: Tue, 17 Dec 2024 22:44:41 +0100 Subject: [PATCH 11/11] =?UTF-8?q?=F0=9F=90=9B=20Use=20latest=20erpc=20imag?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/erpc/Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/erpc/Dockerfile b/packages/erpc/Dockerfile index 1a2d0ca..a5ac687 100644 --- a/packages/erpc/Dockerfile +++ b/packages/erpc/Dockerfile @@ -8,8 +8,7 @@ RUN cd /temp/dev && bun install --production RUN cd /temp/dev && bun build --outfile ./erpc.js --minify --target node --external "@erpc-cloud/*" src/index.ts # Final image -FROM erpc-dev:latest AS final -#FROM ghcr.io/erpc/erpc:latest AS FINAL +FROM ghcr.io/erpc/erpc:main AS FINAL # Copy the bundled config COPY --from=bundler ./temp/dev/erpc.js /root/erpc.js