diff --git a/lib/entities/QuoteRequest.ts b/lib/entities/QuoteRequest.ts index b26bf923..e96fb21a 100644 --- a/lib/entities/QuoteRequest.ts +++ b/lib/entities/QuoteRequest.ts @@ -89,6 +89,15 @@ export class QuoteRequest { ...(this.quoteId && { quoteId: this.quoteId }), }; } + + public toOpposingRequest(): QuoteRequest { + const opposingJSON = this.toOpposingCleanJSON(); + return new QuoteRequest({ + ...opposingJSON, + amount: BigNumber.from(opposingJSON.amount), + type: TradeType[opposingJSON.type as keyof typeof TradeType], + }); +} public get requestId(): string { return this.data.requestId; diff --git a/lib/quoters/WebhookQuoter.ts b/lib/quoters/WebhookQuoter.ts index 98dbb393..4d78fa20 100644 --- a/lib/quoters/WebhookQuoter.ts +++ b/lib/quoters/WebhookQuoter.ts @@ -96,7 +96,7 @@ export class WebhookQuoter implements Quoter { ...(!!headers && { headers }), }; - const [hookResponse] = await Promise.all([ + const [hookResponse, opposite] = await Promise.all([ axios.post(endpoint, cleanRequest, axiosConfig), axios.post(endpoint, opposingCleanRequest, axiosConfig), ]); @@ -170,6 +170,15 @@ export class WebhookQuoter implements Quoter { request.requestId } for endpoint ${endpoint} successful quote: ${request.amount.toString()} -> ${quote.toString()}}` ); + + //iff valid quote, log the opposing side as well + const opposingRequest = request.toOpposingRequest(); + const opposingResponse = QuoteResponse.fromRFQ(opposingRequest, opposite.data, opposingRequest.type).response; + this.log.info({ + eventType: 'QuoteResponse', + body: { ...opposingResponse.toLog(), offerer: opposingResponse.swapper }, + }); + return response; } catch (e) { metric.putMetric(Metric.RFQ_FAIL_ERROR, 1, MetricLoggerUnit.Count); diff --git a/test/handlers/quote/handler.test.ts b/test/handlers/quote/handler.test.ts index 49c3923b..08e46e6b 100644 --- a/test/handlers/quote/handler.test.ts +++ b/test/handlers/quote/handler.test.ts @@ -229,6 +229,19 @@ describe('Quote handler', () => { quoteId: QUOTE_ID, }, }); + }).mockImplementationOnce((_endpoint, _req, _options) => { + return Promise.resolve({ + data: { + amountOut: amountIn.mul(3).toString(), + requestId: request.requestId, + tokenIn: request.tokenOut, + tokenOut: request.tokenIn, + amountIn: request.amount, + swapper: request.swapper, + chainId: request.tokenInChainId, + quoteId: QUOTE_ID, + }, + }); }); const response: APIGatewayProxyResult = await getQuoteHandler(quoters).handler( @@ -274,6 +287,16 @@ describe('Quote handler', () => { ...responseFromRequest(request, { amountOut: amountIn.mul(2).toString() }), }, }); + }).mockImplementationOnce((_endpoint, _req, options: any) => { + expect(options.headers['X-Authentication']).toEqual('1234'); + const res = responseFromRequest(request, { amountOut: amountIn.mul(3).toString() }); + return Promise.resolve({ + data: { + ...res, + tokenIn: res.tokenOut, + tokenOut: res.tokenIn, + }, + }); }); const response: APIGatewayProxyResult = await getQuoteHandler(quoters).handler( @@ -404,6 +427,19 @@ describe('Quote handler', () => { quoteId: QUOTE_ID, }, }); + }).mockImplementationOnce((_endpoint, _req, _options) => { + return Promise.resolve({ + data: { + amountOut: amountIn.div(2).toString(), + tokenIn: request.tokenOut, + tokenOut: request.tokenIn, + amountIn: request.amount, + swapper: request.swapper, + chainId: request.tokenInChainId, + requestId: request.requestId, + quoteId: QUOTE_ID, + }, + }); }); const response: APIGatewayProxyResult = await getQuoteHandler(quoters).handler(