From de1e7a76ce8a05e08293f4d45c39309205b536a6 Mon Sep 17 00:00:00 2001 From: danilo neves cruz Date: Fri, 17 Jan 2025 18:31:25 +0700 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20server:=20support=20multiple=20coll?= =?UTF-8?q?ectors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .do/app.yaml | 2 -- server/api/activity.ts | 6 +++--- server/hooks/cryptomate.ts | 15 +++++++++------ server/test/anvil.ts | 1 - server/test/hooks/cryptomate.test.ts | 2 +- server/utils/COLLECTOR.ts | 6 ------ server/utils/collectors.ts | 12 ++++++++++++ server/vitest.config.mts | 2 -- 8 files changed, 25 insertions(+), 21 deletions(-) delete mode 100644 server/utils/COLLECTOR.ts create mode 100644 server/utils/collectors.ts diff --git a/.do/app.yaml b/.do/app.yaml index 11ab8838..5279c08d 100644 --- a/.do/app.yaml +++ b/.do/app.yaml @@ -53,8 +53,6 @@ services: - key: AUTH_SECRET scope: RUN_TIME type: SECRET - - key: COLLECTOR_ADDRESS - scope: RUN_TIME - key: CRYPTOMATE_API_KEY scope: RUN_TIME type: SECRET diff --git a/server/api/activity.ts b/server/api/activity.ts index bb154f58..7bbba0b3 100644 --- a/server/api/activity.ts +++ b/server/api/activity.ts @@ -32,7 +32,7 @@ import { withRetry, zeroAddress } from "viem"; import database, { credentials } from "../database"; import { previewerAbi, marketAbi } from "../generated/contracts"; import auth from "../middleware/auth"; -import COLLECTOR from "../utils/COLLECTOR"; +import collectors from "../utils/collectors"; import publicClient from "../utils/publicClient"; const app = new Hono(); @@ -40,7 +40,7 @@ app.use(auth); const ActivityTypes = picklist(["card", "received", "repay", "sent"]); -const collector = COLLECTOR.toLowerCase(); +const collectorSet = new Set(collectors.map((address) => address.toLowerCase())); export default app.get( "/", @@ -134,7 +134,7 @@ export default app.get( }) .then((logs) => logs - .filter(({ args }) => args.receiver.toLowerCase() !== collector) + .filter(({ args }) => !collectorSet.has(args.receiver.toLowerCase())) .map((log) => parse(WithdrawActivity, { ...log, market: market(log.address) } satisfies InferInput< typeof WithdrawActivity diff --git a/server/hooks/cryptomate.ts b/server/hooks/cryptomate.ts index 92fbc78c..8f921c6f 100644 --- a/server/hooks/cryptomate.ts +++ b/server/hooks/cryptomate.ts @@ -39,7 +39,7 @@ import { privateKeyToAccount } from "viem/accounts"; import database, { cards, transactions } from "../database/index"; import { auditorAbi, issuerCheckerAbi, issuerCheckerAddress, marketAbi } from "../generated/contracts"; -import COLLECTOR from "../utils/COLLECTOR"; +import collectors from "../utils/collectors"; import keeper from "../utils/keeper"; import { sendPushNotification } from "../utils/onesignal"; import publicClient from "../utils/publicClient"; @@ -146,7 +146,7 @@ export default new Hono().post( return c.json({ response_code: "69" }); } if ( - usdcTransfersToCollector(trace).reduce( + usdcTransfersToCollectors(trace).reduce( (total, { topics, data }) => total + decodeEventLog({ abi: erc20Abi, eventName: "Transfer", topics, data }).args.value, 0n, @@ -306,16 +306,19 @@ async function prepareCollection(payload: v.InferOutput) { }; } -const collectorTopic = padHex(COLLECTOR); +const collectorTopics = new Set(collectors.map((address) => padHex(address.toLowerCase() as Hex))); const [transferTopic] = encodeEventTopics({ abi: erc20Abi, eventName: "Transfer" }); const usdcLowercase = usdcAddress.toLowerCase() as Hex; -function usdcTransfersToCollector({ calls, logs }: CallFrame): TransferLog[] { +function usdcTransfersToCollectors({ calls, logs }: CallFrame): TransferLog[] { return [ ...(logs?.filter( (log): log is TransferLog => - log.address === usdcLowercase && log.topics?.[0] === transferTopic && log.topics[2] === collectorTopic, + log.address === usdcLowercase && + log.topics?.[0] === transferTopic && + log.topics[2] !== undefined && + collectorTopics.has(log.topics[2]), ) ?? []), - ...(calls?.flatMap(usdcTransfersToCollector) ?? []), + ...(calls?.flatMap(usdcTransfersToCollectors) ?? []), ]; } diff --git a/server/test/anvil.ts b/server/test/anvil.ts index 5e1e8a66..c0b224aa 100644 --- a/server/test/anvil.ts +++ b/server/test/anvil.ts @@ -29,7 +29,6 @@ export default async function setup({ provide }: GlobalSetupContext) { cwd: "node_modules/@exactly/plugin", env: { OPTIMISM_ETHERSCAN_KEY: "", - COLLECTOR_ADDRESS: privateKeyToAddress(padHex("0x666")), ISSUER_ADDRESS: privateKeyToAddress(padHex("0x420")), KEEPER_ADDRESS: keeper.address, DEPLOYER_ADDRESS: deployer, diff --git a/server/test/hooks/cryptomate.test.ts b/server/test/hooks/cryptomate.test.ts index 30ed8b4a..d313ebe6 100644 --- a/server/test/hooks/cryptomate.test.ts +++ b/server/test/hooks/cryptomate.test.ts @@ -108,7 +108,7 @@ async function collectorBalance() { }, ], functionName: "balanceOf", - args: [process.env.COLLECTOR_ADDRESS], + args: ["0xDb90CDB64CfF03f254e4015C4F705C3F3C834400"], }), }) .then(({ data }) => { diff --git a/server/utils/COLLECTOR.ts b/server/utils/COLLECTOR.ts deleted file mode 100644 index 32bafcfa..00000000 --- a/server/utils/COLLECTOR.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Hex } from "@exactly/common/validation"; -import { parse } from "valibot"; - -if (!process.env.COLLECTOR_ADDRESS) throw new Error("missing collector address"); - -export default parse(Hex, process.env.COLLECTOR_ADDRESS.toLowerCase()); diff --git a/server/utils/collectors.ts b/server/utils/collectors.ts new file mode 100644 index 00000000..5c21bf6d --- /dev/null +++ b/server/utils/collectors.ts @@ -0,0 +1,12 @@ +import chain from "@exactly/common/generated/chain"; +import { Address } from "@exactly/common/validation"; +import { parse } from "valibot"; +import { optimism } from "viem/chains"; + +const collectors: Address[] = ( + { + [optimism.id]: ["0x0f25bA5b8B0BA4Ff4dF645fDE030652da60BabA6", "0x471e5F3428D5C50543072c817a9D0CcBa8ed7D5F"], + }[chain.id] ?? ["0xDb90CDB64CfF03f254e4015C4F705C3F3C834400"] +).map((address) => parse(Address, address)); + +export default collectors; diff --git a/server/vitest.config.mts b/server/vitest.config.mts index ed864063..5a97d3ab 100644 --- a/server/vitest.config.mts +++ b/server/vitest.config.mts @@ -1,5 +1,4 @@ import { padHex } from "viem"; -import { privateKeyToAddress } from "viem/accounts"; import { defineConfig } from "vitest/config"; export default defineConfig({ @@ -10,7 +9,6 @@ export default defineConfig({ ALCHEMY_BLOCK_KEY: "block", ALCHEMY_WEBHOOKS_KEY: "webhooks", AUTH_SECRET: "auth", - COLLECTOR_ADDRESS: privateKeyToAddress(padHex("0x666")), CRYPTOMATE_WEBHOOK_KEY: "cryptomate", EXPO_PUBLIC_ALCHEMY_API_KEY: " ", ISSUER_PRIVATE_KEY: padHex("0x420"),