diff --git a/biome.json b/biome.json index fbad6e3..6fadca9 100644 --- a/biome.json +++ b/biome.json @@ -29,8 +29,7 @@ "maxAllowedComplexity": 16 } }, - "noUselessTernary": "error", - "useSimplifiedLogicExpression": "error" + "noUselessTernary": "error" }, "correctness": { "useHookAtTopLevel": "error", diff --git a/packages/ponder/src/api/index.ts b/packages/ponder/src/api/index.ts index f520dfd..95951f9 100644 --- a/packages/ponder/src/api/index.ts +++ b/packages/ponder/src/api/index.ts @@ -1,7 +1 @@ -import { ponder } from "@/generated"; -import { graphql } from "@ponder/core"; - // todo: api key middleware - -// This is the entry point for the Graphql api -ponder.use("/graphql", graphql()); diff --git a/packages/ponder/src/api/members.ts b/packages/ponder/src/api/members.ts index 2dd42b6..55458fe 100644 --- a/packages/ponder/src/api/members.ts +++ b/packages/ponder/src/api/members.ts @@ -87,6 +87,11 @@ ponder.post("/members/:productAdmin", async (ctx) => { .innerJoin(Product, eq(ProductAdministrator.productId, Product.id)) .where(eq(ProductAdministrator.user, wallet)); + // If no product found, early exit + if (!productIds.length) { + return ctx.json({ totalResult: 0, members: [], users: [] }); + } + const { whereClauses, havingClauses } = getFilterClauses({ tables: ctx.tables, filter, diff --git a/packages/ponder/src/api/products.ts b/packages/ponder/src/api/products.ts index 570ddda..9d5f9c5 100644 --- a/packages/ponder/src/api/products.ts +++ b/packages/ponder/src/api/products.ts @@ -1,6 +1,6 @@ import { ponder } from "@/generated"; -import { eq } from "@ponder/core"; -import { type Hex, isHex } from "viem"; +import { eq, inArray } from "@ponder/core"; +import { type Hex, isHex, keccak256, toHex } from "viem"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: Unreachable code error @@ -71,3 +71,82 @@ ponder.get("/products/:id/banks", async (ctx) => { // Return the result as json return ctx.json(administrators); }); + +/** + * Get the overall product info + */ +ponder.get("/products/info", async ({ req, db, tables, json }) => { + // Extract the product id + const domain = req.query("domain"); + let productId = req.query("id") as Hex | undefined; + + // If no id provided, recompute it from the domain + if (!productId && domain) { + productId = keccak256(toHex(domain)); + } + + if (!productId || !isHex(productId)) { + return json({ msg: "Invalid product id", productId, domain }); + } + + // Get the product from the db + const products = await db + .select() + .from(tables.Product) + .where(eq(tables.Product.id, BigInt(productId))); + const product = products?.[0]; + + // If not found, early exit + if (!product) { + return json({ msg: "Product not found", productId, domain }); + } + + // Get all the admninistrators + const administrators = await db + .select() + .from(tables.ProductAdministrator) + .where(eq(tables.ProductAdministrator.productId, BigInt(productId))); + + // Get all the banks + const banks = await db + .select() + .from(tables.BankingContract) + .where(eq(tables.BankingContract.productId, BigInt(productId))); + + // Get the interaction contracts + const interactionContracts = await db + .select() + .from(tables.ProductInteractionContract) + .where( + eq(tables.ProductInteractionContract.productId, BigInt(productId)) + ); + + // Get the campaigns + const campaigns = await db + .select() + .from(tables.Campaign) + .where(eq(tables.Campaign.productId, BigInt(productId))); + + // Get the campaigns tats + const campaignStats = campaigns.length + ? await db + .select() + .from(tables.ReferralCampaignStats) + .where( + inArray( + tables.ReferralCampaignStats.campaignId, + campaigns.map((c) => c.id) + ) + ) + : []; + + // Return all the data related to the product + return json({ + product, + banks, + interactionContracts, + administrators, + campaigns, + campaignStats, + }); +});