diff --git a/lib/entities/HardQuoteResponse.ts b/lib/entities/HardQuoteResponse.ts index 656976a..3f084c8 100644 --- a/lib/entities/HardQuoteResponse.ts +++ b/lib/entities/HardQuoteResponse.ts @@ -1,5 +1,4 @@ -import { CosignedV2DutchOrder } from '@uniswap/uniswapx-sdk'; -import { BigNumber } from 'ethers'; +import { CosignedV2DutchOrder, CosignedV3DutchOrder } from '@uniswap/uniswapx-sdk'; import { v4 as uuidv4 } from 'uuid'; import { HardQuoteRequest } from '.'; @@ -7,12 +6,12 @@ import { HardQuoteResponseData } from '../handlers/hard-quote/schema'; import { currentTimestampInMs, timestampInMstoSeconds } from '../util/time'; // data class for hard quote response helpers and conversions -export class HardQuoteResponse { +export abstract class HardQuoteResponse { public createdAt: string; constructor( public request: HardQuoteRequest, - public order: CosignedV2DutchOrder, + public order: T, public createdAtMs = currentTimestampInMs() ) { this.createdAt = timestampInMstoSeconds(parseInt(this.createdAtMs)); @@ -29,23 +28,7 @@ export class HardQuoteResponse { }; } - public toLog() { - return { - quoteId: this.quoteId, - requestId: this.requestId, - tokenInChainId: this.chainId, - tokenOutChainId: this.chainId, - tokenIn: this.tokenIn, - amountIn: this.amountIn.toString(), - tokenOut: this.tokenOut, - amountOut: this.amountOut.toString(), - swapper: this.swapper, - filler: this.filler, - orderHash: this.order.hash(), - createdAt: this.createdAt, - createdAtMs: this.createdAtMs, - }; - } + public abstract toLog(): any; public get quoteId(): string { return this.request.quoteId ?? uuidv4(); @@ -67,25 +50,6 @@ export class HardQuoteResponse { return this.request.tokenIn; } - public get amountOut(): BigNumber { - const resolved = this.order.resolve({ - timestamp: this.order.info.cosignerData.decayStartTime, - }); - let amount = BigNumber.from(0); - for (const output of resolved.outputs) { - amount = amount.add(output.amount); - } - - return amount; - } - - public get amountIn(): BigNumber { - const resolved = this.order.resolve({ - timestamp: this.order.info.cosignerData.decayStartTime, - }); - return resolved.input.amount; - } - public get tokenOut(): string { return this.request.tokenOut; } diff --git a/lib/entities/V2HardQuoteResponse.ts b/lib/entities/V2HardQuoteResponse.ts new file mode 100644 index 0000000..aceb897 --- /dev/null +++ b/lib/entities/V2HardQuoteResponse.ts @@ -0,0 +1,42 @@ +import { BigNumber } from "ethers"; +import { HardQuoteResponse } from "./HardQuoteResponse"; +import { CosignedV2DutchOrder } from "@uniswap/uniswapx-sdk"; + +export class V2HardQuoteResponse extends HardQuoteResponse { + public toLog() { + return { + quoteId: this.quoteId, + requestId: this.requestId, + tokenInChainId: this.chainId, + tokenOutChainId: this.chainId, + tokenIn: this.tokenIn, + amountIn: this.amountIn.toString(), + tokenOut: this.tokenOut, + amountOut: this.amountOut.toString(), + swapper: this.swapper, + filler: this.filler, + orderHash: this.order.hash(), + createdAt: this.createdAt, + createdAtMs: this.createdAtMs, + }; + } + + public get amountOut(): BigNumber { + const resolved = this.order.resolve({ + timestamp: this.order.info.cosignerData.decayStartTime, + }); + let amount = BigNumber.from(0); + for (const output of resolved.outputs) { + amount = amount.add(output.amount); + } + + return amount; + } + + public get amountIn(): BigNumber { + const resolved = this.order.resolve({ + timestamp: this.order.info.cosignerData.decayStartTime, + }); + return resolved.input.amount; + } +} \ No newline at end of file diff --git a/lib/entities/V3HardQuoteResponse.ts b/lib/entities/V3HardQuoteResponse.ts new file mode 100644 index 0000000..df2edd9 --- /dev/null +++ b/lib/entities/V3HardQuoteResponse.ts @@ -0,0 +1,48 @@ +import { CosignedV3DutchOrder } from "@uniswap/uniswapx-sdk"; +import { HardQuoteResponse } from "./HardQuoteResponse"; + +export class V3HardQuoteResponse extends HardQuoteResponse { + public toLog() { + return { + quoteId: this.quoteId, + requestId: this.requestId, + tokenInChainId: this.chainId, + tokenOutChainId: this.chainId, + tokenIn: this.tokenIn, + input: this.input, + tokenOut: this.tokenOut, + outputs: this.outputs, + swapper: this.swapper, + filler: this.filler, + orderHash: this.order.hash(), + createdAt: this.createdAt, + createdAtMs: this.createdAtMs, + }; + } + + get input() { + const input = this.order.info.input; + const relativeAmounts = input.curve.relativeAmounts.map((amount) => amount.toString()); + + return { + ...input, + curve: { + ...input.curve, + relativeAmounts, + }, + } + } + + get outputs() { + const processedOutputs = this.order.info.outputs.map((output) => { + return { + ...output, + curve: { + ...output.curve, + relativeAmounts: output.curve.relativeAmounts.map((amount) => amount.toString()), + } + } + }); + return processedOutputs; + } +} \ No newline at end of file diff --git a/lib/handlers/hard-quote/handler.ts b/lib/handlers/hard-quote/handler.ts index cf39aa7..61b631c 100644 --- a/lib/handlers/hard-quote/handler.ts +++ b/lib/handlers/hard-quote/handler.ts @@ -7,7 +7,7 @@ import { BigNumber, ethers } from 'ethers'; import Joi from 'joi'; import { POST_ORDER_ERROR_REASON } from '../../constants'; -import { HardQuoteRequest, HardQuoteResponse, Metric, QuoteResponse } from '../../entities'; +import { HardQuoteRequest, Metric, QuoteResponse } from '../../entities'; import { checkDefined } from '../../preconditions/preconditions'; import { ChainId } from '../../util/chains'; import { NoQuotesAvailable, OrderPostError, UnknownOrderCosignerError } from '../../util/errors'; @@ -22,6 +22,7 @@ import { HardQuoteResponseData, HardQuoteResponseDataJoi, } from './schema'; +import { V2HardQuoteResponse } from '../../entities/V2HardQuoteResponse'; const DEFAULT_EXCLUSIVITY_OVERRIDE_BPS = BigNumber.from(100); // non-exclusive fillers must override price by this much const RESPONSE_LOG_TYPE = 'HardResponse'; @@ -113,7 +114,7 @@ export class QuoteHandler extends APIGLambdaHandler< if (response.statusCode == 200 || response.statusCode == 201) { metric.putMetric(Metric.QUOTE_200, 1, MetricLoggerUnit.Count); metric.putMetric(Metric.QUOTE_LATENCY, Date.now() - start, MetricLoggerUnit.Milliseconds); - const hardResponse = new HardQuoteResponse(request, cosignedOrder); + const hardResponse = new V2HardQuoteResponse(request, cosignedOrder); if (!bestQuote) { // The RFQ responses are logged in getBestQuote() // we log the Open Orders here diff --git a/package.json b/package.json index 0ca3d6a..859e709 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@uniswap/signer": "0.0.3-beta.4", "@uniswap/smart-order-router": "^3.3.0", "@uniswap/token-lists": "^1.0.0-beta.31", - "@uniswap/uniswapx-sdk": "2.1.0-beta.4", + "@uniswap/uniswapx-sdk": "2.1.0-beta.20", "@uniswap/v3-sdk": "^3.9.0", "aws-cdk-lib": "2.85.0", "aws-embedded-metrics": "^4.1.0", diff --git a/test/entities/HardQuoteResponse.test.ts b/test/entities/HardQuoteResponse.test.ts index c3c4618..4489792 100644 --- a/test/entities/HardQuoteResponse.test.ts +++ b/test/entities/HardQuoteResponse.test.ts @@ -7,9 +7,10 @@ import { import { ethers, Wallet } from 'ethers'; import { parseEther } from 'ethers/lib/utils'; -import { HardQuoteRequest, HardQuoteResponse } from '../../lib/entities'; +import { HardQuoteRequest } from '../../lib/entities'; import { HardQuoteRequestBody } from '../../lib/handlers/hard-quote'; import { getOrder } from '../handlers/hard-quote/handler.test'; +import { V2HardQuoteResponse } from '../../lib/entities/V2HardQuoteResponse'; const QUOTE_ID = 'a83f397c-8ef4-4801-a9b7-6e79155049f6'; const REQUEST_ID = 'a83f397c-8ef4-4801-a9b7-6e79155049f7'; @@ -51,7 +52,7 @@ describe('HardQuoteResponse', () => { cosignerData, ethers.utils.joinSignature(cosignature) ); - return new HardQuoteResponse(new HardQuoteRequest(await getRequest(unsigned)), order); + return new V2HardQuoteResponse(new HardQuoteRequest(await getRequest(unsigned)), order); }; it('toResponseJSON', async () => {