diff --git a/api/_exclusivity/cache.ts b/api/_exclusivity/cache.ts index d9431c4e1..2aa21b277 100644 --- a/api/_exclusivity/cache.ts +++ b/api/_exclusivity/cache.ts @@ -67,11 +67,19 @@ export async function getCachedRelayerFillLimit( * Sets a series of relayer fill limits in the cache. * * @param {string} relayer - The unique identifier for the relayer. + * @param {originChainId} originChainId - The origin chain of the route. + * @param {inputToken} inputToken - The input token on the origin chain. + * @param {destinationChainId} destinationChainId - The destination chain of the route. + * @param {outputToken} outputToken - The output token on the destination chain. * @param {RelayerFillLimit[]} entries - An array of relayer fill limit entries to store. * @returns {Promise} A promise that resolves when the operation is complete. */ export async function setCachedRelayerFillLimit( relayer: string, + originChainId: number, + inputToken: string, + destinationChainId: number, + outputToken: string, entries: RelayerFillLimit[] ): Promise { // Confirm what we're about to push to the cache is formatted properly @@ -81,13 +89,13 @@ export async function setCachedRelayerFillLimit( redisCache.set( buildRelayerFillLimitCacheKey( relayer, - entry.originChainId, - entry.destinationChainId, - entry.inputToken, - entry.outputToken + originChainId, + destinationChainId, + inputToken, + outputToken ), entry, - 120 + 600 ) ) ); diff --git a/api/_exclusivity/utils.ts b/api/_exclusivity/utils.ts index 1202d7ef7..232878b0c 100644 --- a/api/_exclusivity/utils.ts +++ b/api/_exclusivity/utils.ts @@ -45,6 +45,10 @@ export const isTimestampValid = ( export async function updateLimits( relayer: string, + originChainId: number, + inputToken: string, + destinationChainId: number, + outputToken: string, limits: RelayerFillLimit[] ): Promise { const sortedLimits = limits @@ -70,6 +74,10 @@ export async function updateLimits( await setCachedRelayerFillLimit( relayer, + originChainId, + inputToken, + destinationChainId, + outputToken, sortedLimits.map(({ minOutputAmount, maxOutputAmount, ...rest }) => ({ minOutputAmount: minOutputAmount.toString(), // @todo: Less bodge maxOutputAmount: maxOutputAmount.toString(), // @todo: Less bodge diff --git a/api/_types/exclusivity.types.ts b/api/_types/exclusivity.types.ts index b0bcf631c..6c7a7b745 100644 --- a/api/_types/exclusivity.types.ts +++ b/api/_types/exclusivity.types.ts @@ -7,11 +7,14 @@ import { } from "../_utils"; import { TypedVercelRequest } from "./generic.types"; -export const RelayerFillLimitSchema = object({ +export const RelayerRoute = object({ originChainId: positiveIntStr(), - destinationChainId: positiveIntStr(), inputToken: validAddress(), + destinationChainId: positiveIntStr(), outputToken: validAddress(), +}); + +export const RelayerFillLimitSchema = object({ minOutputAmount: positiveIntStr(), maxOutputAmount: positiveIntStr(), minProfitThreshold: positiveFloatStr(), @@ -21,11 +24,19 @@ export const RelayerFillLimitSchema = object({ }); export const RelayerFillLimitArraySchema = array(RelayerFillLimitSchema); +export const RelayerRouteUpdateSchema = object({ + RelayerRoute, + RelayerFillLimitArraySchema, +}); export type RelayerFillLimit = Infer; export type RelayerConfigUpdate = { timestamp: number; + originChainId: string; + inputToken: string; + destinationChainId: string; + outputToken: string; relayerFillLimits: RelayerFillLimit[]; }; diff --git a/api/relayer-config.ts b/api/relayer-config.ts index af4e9e792..9670c6fad 100644 --- a/api/relayer-config.ts +++ b/api/relayer-config.ts @@ -64,7 +64,14 @@ const handlePost = async ( ) => { const body = request.body as RelayerConfigUpdate; const { authorization } = request.headers; - const { relayerFillLimits, timestamp } = body; + const { + originChainId, + destinationChainId, + inputToken, + outputToken, + relayerFillLimits, + timestamp, + } = body; if (!isTimestampValid(timestamp, MAX_MESSAGE_AGE_SECONDS)) { return response.status(400).json({ message: "Message too old" }); @@ -81,7 +88,14 @@ const handlePost = async ( .json({ message: "Invalid configuration payload" }); } - await updateLimits(relayer, relayerFillLimits); + await updateLimits( + relayer, + Number(originChainId), + inputToken, + Number(destinationChainId), + outputToken, + relayerFillLimits + ); return response.status(200).json({ message: "POST request received" }); }; diff --git a/test/api/relayer-config.test.ts b/test/api/relayer-config.test.ts index 78967aadf..f30d0e508 100644 --- a/test/api/relayer-config.test.ts +++ b/test/api/relayer-config.test.ts @@ -34,12 +34,12 @@ describe("Relayer Config API", () => { test("POST request with valid timestamp", async () => { const message: RelayerConfigUpdate = { timestamp: Math.floor(Date.now() / 1000), + originChainId: "1", + inputToken: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + destinationChainId: "42161", + outputToken: "0x82af49447d8a07e3bd95bd0d56f35241523fbab1", relayerFillLimits: [ { - originChainId: "1", - inputToken: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", - destinationChainId: "42161", - outputToken: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", minOutputAmount: "1", maxOutputAmount: "2", balanceMultiplier: "1", @@ -67,6 +67,10 @@ describe("Relayer Config API", () => { test("POST request with invalid timestamp", async () => { const message: RelayerConfigUpdate = { timestamp: Math.floor(Date.now() / 1000) - MAX_MESSAGE_AGE_SECONDS - 1, + originChainId: "1", + inputToken: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + destinationChainId: "10", + outputToken: "0x82af49447d8a07e3bd95bd0d56f35241523fbab1", relayerFillLimits: [], }; const signature = await whitelistedRelayer.signMessage( @@ -90,6 +94,10 @@ describe("Relayer Config API", () => { test("POST request with invalid signature", async () => { const message: RelayerConfigUpdate = { timestamp: Math.floor(Date.now() / 1000), + originChainId: "1", + inputToken: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + destinationChainId: "10", + outputToken: "0x82af49447d8a07e3bd95bd0d56f35241523fbab1", relayerFillLimits: [], }; const signature = await unauthorizedRelayer.signMessage( @@ -133,10 +141,6 @@ describe("Relayer Config API", () => { // Mock getLimits to return some test data const limits: RelayerFillLimit[] = [ { - originChainId: "1", - destinationChainId: "42161", - inputToken: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", - outputToken: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", minOutputAmount: "1", maxOutputAmount: "2", balanceMultiplier: "1",