fix: Added fee parameter to Quote Requestor (#235)

* Added changes

* Fixes

* Applied PR feedback

* lint fix
This commit is contained in:
Daniel Pyrathon 2021-05-11 12:57:51 -04:00 committed by GitHub
parent 70d2117470
commit df055e1958
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 75 additions and 27 deletions

View File

@ -67,7 +67,7 @@
"@0x/dev-utils": "^4.2.7", "@0x/dev-utils": "^4.2.7",
"@0x/json-schemas": "^6.1.3", "@0x/json-schemas": "^6.1.3",
"@0x/protocol-utils": "^1.6.0", "@0x/protocol-utils": "^1.6.0",
"@0x/quote-server": "^5.0.0", "@0x/quote-server": "^6.0.2",
"@0x/types": "^3.3.3", "@0x/types": "^3.3.3",
"@0x/typescript-typings": "^5.2.0", "@0x/typescript-typings": "^5.2.0",
"@0x/utils": "^6.4.3", "@0x/utils": "^6.4.3",

View File

@ -5,7 +5,12 @@ export {
SendTransactionOpts, SendTransactionOpts,
} from '@0x/base-contract'; } from '@0x/base-contract';
export { ContractAddresses } from '@0x/contract-addresses'; export { ContractAddresses } from '@0x/contract-addresses';
export { V4RFQFirmQuote, V4RFQIndicativeQuote, V4SignedRfqOrder, TakerRequestQueryParams } from '@0x/quote-server'; export {
V4RFQFirmQuote,
V4RFQIndicativeQuote,
V4SignedRfqOrder,
TakerRequestQueryParamsUnnested as TakerRequestQueryParams,
} from '@0x/quote-server';
export { Asset, AssetPairsItem, DecodedLogEvent, EventCallback, IndexedFilterValues } from '@0x/types'; export { Asset, AssetPairsItem, DecodedLogEvent, EventCallback, IndexedFilterValues } from '@0x/types';
export { BigNumber } from '@0x/utils'; export { BigNumber } from '@0x/utils';
export { export {

View File

@ -7,7 +7,8 @@ import {
RfqOrderFields, RfqOrderFields,
Signature, Signature,
} from '@0x/protocol-utils'; } from '@0x/protocol-utils';
import { TakerRequestQueryParams, V4SignedRfqOrder } from '@0x/quote-server'; import { TakerRequestQueryParamsUnnested, V4SignedRfqOrder } from '@0x/quote-server';
import { Fee } from '@0x/quote-server/lib/src/types';
import { BigNumber } from '@0x/utils'; import { BigNumber } from '@0x/utils';
import { AxiosRequestConfig } from 'axios'; import { AxiosRequestConfig } from 'axios';
@ -232,6 +233,12 @@ export type SwapQuoteOrdersBreakdown = Partial<
* If set to `true` and `ERC20BridgeSource.Native` is part of the `excludedSources` * If set to `true` and `ERC20BridgeSource.Native` is part of the `excludedSources`
* array in `SwapQuoteRequestOpts`, an Error will be raised. * array in `SwapQuoteRequestOpts`, an Error will be raised.
*/ */
export interface RfqmRequestOptions extends RfqRequestOpts {
isLastLook: true;
fee: Fee;
}
export interface RfqRequestOpts { export interface RfqRequestOpts {
takerAddress: string; takerAddress: string;
txOrigin: string; txOrigin: string;
@ -242,6 +249,7 @@ export interface RfqRequestOpts {
nativeExclusivelyRFQ?: boolean; nativeExclusivelyRFQ?: boolean;
altRfqAssetOfferings?: AltRfqMakerAssetOfferings; altRfqAssetOfferings?: AltRfqMakerAssetOfferings;
isLastLook?: boolean; isLastLook?: boolean;
fee?: Fee;
} }
/** /**
@ -366,7 +374,7 @@ export enum OrderPrunerPermittedFeeTypes {
export interface MockedRfqQuoteResponse { export interface MockedRfqQuoteResponse {
endpoint: string; endpoint: string;
requestApiKey: string; requestApiKey: string;
requestParams: TakerRequestQueryParams; requestParams: TakerRequestQueryParamsUnnested;
responseData: any; responseData: any;
responseCode: number; responseCode: number;
callback?: (config: any) => Promise<any>; callback?: (config: any) => Promise<any>;

View File

@ -1,5 +1,5 @@
import { Web3Wrapper } from '@0x/dev-utils'; import { Web3Wrapper } from '@0x/dev-utils';
import { TakerRequestQueryParams, V4RFQFirmQuote, V4RFQIndicativeQuote } from '@0x/quote-server'; import { TakerRequestQueryParamsUnnested, V4RFQFirmQuote, V4RFQIndicativeQuote } from '@0x/quote-server';
import { BigNumber } from '@0x/utils'; import { BigNumber } from '@0x/utils';
import { AxiosInstance, CancelToken } from 'axios'; import { AxiosInstance, CancelToken } from 'axios';
@ -123,7 +123,7 @@ export async function returnQuoteFromAltMMAsync<ResponseT>(
takerToken: string, takerToken: string,
maxResponseTimeMs: number, maxResponseTimeMs: number,
altRfqAssetOfferings: AltRfqMakerAssetOfferings, altRfqAssetOfferings: AltRfqMakerAssetOfferings,
takerRequestQueryParams: TakerRequestQueryParams, takerRequestQueryParams: TakerRequestQueryParamsUnnested,
axiosInstance: AxiosInstance, axiosInstance: AxiosInstance,
warningLogger: LogFunction, warningLogger: LogFunction,
cancelToken: CancelToken, cancelToken: CancelToken,

View File

@ -1,6 +1,12 @@
import { schemas, SchemaValidator } from '@0x/json-schemas'; import { schemas, SchemaValidator } from '@0x/json-schemas';
import { FillQuoteTransformerOrderType, Signature } from '@0x/protocol-utils'; import { FillQuoteTransformerOrderType, Signature } from '@0x/protocol-utils';
import { TakerRequestQueryParams, V4RFQFirmQuote, V4RFQIndicativeQuote, V4SignedRfqOrder } from '@0x/quote-server'; import {
TakerRequestQueryParamsUnnested,
V4RFQFirmQuote,
V4RFQIndicativeQuote,
V4SignedRfqOrder,
} from '@0x/quote-server';
import { Fee } from '@0x/quote-server/lib/src/types';
import { BigNumber, NULL_ADDRESS } from '@0x/utils'; import { BigNumber, NULL_ADDRESS } from '@0x/utils';
import axios, { AxiosInstance } from 'axios'; import axios, { AxiosInstance } from 'axios';
@ -11,6 +17,7 @@ import {
LogFunction, LogFunction,
MarketOperation, MarketOperation,
RfqMakerAssetOfferings, RfqMakerAssetOfferings,
RfqmRequestOptions,
RfqPairType, RfqPairType,
RfqRequestOpts, RfqRequestOpts,
SignedNativeOrder, SignedNativeOrder,
@ -84,7 +91,8 @@ export class QuoteRequestor {
assetFillAmount: BigNumber, assetFillAmount: BigNumber,
comparisonPrice?: BigNumber, comparisonPrice?: BigNumber,
isLastLook?: boolean | undefined, isLastLook?: boolean | undefined,
): TakerRequestQueryParams { fee?: Fee | undefined,
): TakerRequestQueryParamsUnnested {
const { buyAmountBaseUnits, sellAmountBaseUnits } = const { buyAmountBaseUnits, sellAmountBaseUnits } =
marketOperation === MarketOperation.Buy marketOperation === MarketOperation.Buy
? { ? {
@ -97,7 +105,7 @@ export class QuoteRequestor {
}; };
const requestParamsWithBigNumbers: Pick< const requestParamsWithBigNumbers: Pick<
TakerRequestQueryParams, TakerRequestQueryParamsUnnested,
| 'txOrigin' | 'txOrigin'
| 'takerAddress' | 'takerAddress'
| 'buyTokenAddress' | 'buyTokenAddress'
@ -105,6 +113,9 @@ export class QuoteRequestor {
| 'comparisonPrice' | 'comparisonPrice'
| 'isLastLook' | 'isLastLook'
| 'protocolVersion' | 'protocolVersion'
| 'feeAmount'
| 'feeToken'
| 'feeType'
> = { > = {
txOrigin, txOrigin,
takerAddress, takerAddress,
@ -114,7 +125,13 @@ export class QuoteRequestor {
protocolVersion: '4', protocolVersion: '4',
}; };
if (isLastLook) { if (isLastLook) {
if (fee === undefined) {
throw new Error(`isLastLook cannot be passed without a fee parameter`);
}
requestParamsWithBigNumbers.isLastLook = isLastLook.toString(); requestParamsWithBigNumbers.isLastLook = isLastLook.toString();
requestParamsWithBigNumbers.feeAmount = fee.amount.toString();
requestParamsWithBigNumbers.feeToken = fee.token;
requestParamsWithBigNumbers.feeType = fee.type;
} }
// convert BigNumbers to strings // convert BigNumbers to strings
@ -181,12 +198,11 @@ export class QuoteRequestor {
assetFillAmount: BigNumber, assetFillAmount: BigNumber,
marketOperation: MarketOperation, marketOperation: MarketOperation,
comparisonPrice: BigNumber | undefined, comparisonPrice: BigNumber | undefined,
options: RfqRequestOpts, options: RfqmRequestOptions,
): Promise<SignedNativeOrder[]> { ): Promise<SignedNativeOrder[]> {
const _opts: RfqRequestOpts = { const _opts: RfqRequestOpts = {
...constants.DEFAULT_RFQT_REQUEST_OPTS, ...constants.DEFAULT_RFQT_REQUEST_OPTS,
...options, ...options,
isLastLook: true,
}; };
return this._fetchAndValidateFirmQuotesAsync( return this._fetchAndValidateFirmQuotesAsync(
@ -230,12 +246,11 @@ export class QuoteRequestor {
assetFillAmount: BigNumber, assetFillAmount: BigNumber,
marketOperation: MarketOperation, marketOperation: MarketOperation,
comparisonPrice: BigNumber | undefined, comparisonPrice: BigNumber | undefined,
options: RfqRequestOpts, options: RfqmRequestOptions,
): Promise<V4RFQIndicativeQuote[]> { ): Promise<V4RFQIndicativeQuote[]> {
const _opts: RfqRequestOpts = { const _opts: RfqRequestOpts = {
...constants.DEFAULT_RFQT_REQUEST_OPTS, ...constants.DEFAULT_RFQT_REQUEST_OPTS,
...options, ...options,
isLastLook: true,
}; };
return this._fetchAndValidateIndicativeQuotesAsync( return this._fetchAndValidateIndicativeQuotesAsync(
@ -344,6 +359,7 @@ export class QuoteRequestor {
assetFillAmount, assetFillAmount,
comparisonPrice, comparisonPrice,
options.isLastLook, options.isLastLook,
options.fee,
); );
const quotePath = (() => { const quotePath = (() => {

View File

@ -1,6 +1,6 @@
import { tokenUtils } from '@0x/dev-utils'; import { tokenUtils } from '@0x/dev-utils';
import { FillQuoteTransformerOrderType, SignatureType } from '@0x/protocol-utils'; import { ETH_TOKEN_ADDRESS, FillQuoteTransformerOrderType, SignatureType } from '@0x/protocol-utils';
import { TakerRequestQueryParams, V4RFQIndicativeQuote } from '@0x/quote-server'; import { TakerRequestQueryParamsUnnested, V4RFQIndicativeQuote } from '@0x/quote-server';
import { StatusCodes } from '@0x/types'; import { StatusCodes } from '@0x/types';
import { BigNumber, logUtils } from '@0x/utils'; import { BigNumber, logUtils } from '@0x/utils';
import Axios from 'axios'; import Axios from 'axios';
@ -75,7 +75,7 @@ describe('QuoteRequestor', async () => {
const mockedRequests: MockedRfqQuoteResponse[] = []; const mockedRequests: MockedRfqQuoteResponse[] = [];
const altMockedRequests: AltMockedRfqQuoteResponse[] = []; const altMockedRequests: AltMockedRfqQuoteResponse[] = [];
const expectedParams: TakerRequestQueryParams = { const expectedParams: TakerRequestQueryParamsUnnested = {
sellTokenAddress: takerToken, sellTokenAddress: takerToken,
buyTokenAddress: makerToken, buyTokenAddress: makerToken,
sellAmountBaseUnits: '10000', sellAmountBaseUnits: '10000',
@ -84,6 +84,9 @@ describe('QuoteRequestor', async () => {
txOrigin, txOrigin,
isLastLook: 'true', // the major difference between RFQ-T and RFQ-M isLastLook: 'true', // the major difference between RFQ-T and RFQ-M
protocolVersion: '4', protocolVersion: '4',
feeAmount: '1000000000',
feeToken: ETH_TOKEN_ADDRESS,
feeType: 'fixed',
}; };
const mockedDefaults = { const mockedDefaults = {
requestApiKey: apiKey, requestApiKey: apiKey,
@ -242,6 +245,12 @@ describe('QuoteRequestor', async () => {
txOrigin: takerAddress, txOrigin: takerAddress,
intentOnFilling: true, intentOnFilling: true,
altRfqAssetOfferings, altRfqAssetOfferings,
isLastLook: true,
fee: {
amount: new BigNumber('1000000000'),
token: ETH_TOKEN_ADDRESS,
type: 'fixed',
},
}, },
); );
expect(resp).to.deep.eq([ expect(resp).to.deep.eq([
@ -265,7 +274,7 @@ describe('QuoteRequestor', async () => {
const mockedRequests: MockedRfqQuoteResponse[] = []; const mockedRequests: MockedRfqQuoteResponse[] = [];
const altMockedRequests: AltMockedRfqQuoteResponse[] = []; const altMockedRequests: AltMockedRfqQuoteResponse[] = [];
const expectedParams: TakerRequestQueryParams = { const expectedParams: TakerRequestQueryParamsUnnested = {
sellTokenAddress: takerToken, sellTokenAddress: takerToken,
buyTokenAddress: makerToken, buyTokenAddress: makerToken,
sellAmountBaseUnits: '10000', sellAmountBaseUnits: '10000',
@ -451,7 +460,7 @@ describe('QuoteRequestor', async () => {
// Set up RFQ responses // Set up RFQ responses
// tslint:disable-next-line:array-type // tslint:disable-next-line:array-type
const mockedRequests: MockedRfqQuoteResponse[] = []; const mockedRequests: MockedRfqQuoteResponse[] = [];
const expectedParams: TakerRequestQueryParams = { const expectedParams: TakerRequestQueryParamsUnnested = {
sellTokenAddress: takerToken, sellTokenAddress: takerToken,
buyTokenAddress: makerToken, buyTokenAddress: makerToken,
sellAmountBaseUnits: '10000', sellAmountBaseUnits: '10000',
@ -460,6 +469,9 @@ describe('QuoteRequestor', async () => {
txOrigin: takerAddress, txOrigin: takerAddress,
isLastLook: 'true', // the major difference between RFQ-T and RFQ-M isLastLook: 'true', // the major difference between RFQ-T and RFQ-M
protocolVersion: '4', protocolVersion: '4',
feeAmount: '1000000000',
feeToken: ETH_TOKEN_ADDRESS,
feeType: 'fixed',
}; };
const mockedDefaults = { const mockedDefaults = {
requestApiKey: apiKey, requestApiKey: apiKey,
@ -543,6 +555,12 @@ describe('QuoteRequestor', async () => {
takerAddress, takerAddress,
txOrigin: takerAddress, txOrigin: takerAddress,
intentOnFilling: true, intentOnFilling: true,
isLastLook: true,
fee: {
type: 'fixed',
token: ETH_TOKEN_ADDRESS,
amount: new BigNumber('1000000000'),
},
}, },
); );
expect(resp.sort()).to.eql([successfulQuote1, successfulQuote1].sort()); expect(resp.sort()).to.eql([successfulQuote1, successfulQuote1].sort());
@ -571,7 +589,7 @@ describe('QuoteRequestor', async () => {
// Set up RFQT responses // Set up RFQT responses
// tslint:disable-next-line:array-type // tslint:disable-next-line:array-type
const mockedRequests: MockedRfqQuoteResponse[] = []; const mockedRequests: MockedRfqQuoteResponse[] = [];
const expectedParams: TakerRequestQueryParams = { const expectedParams: TakerRequestQueryParamsUnnested = {
sellTokenAddress: takerToken, sellTokenAddress: takerToken,
buyTokenAddress: makerToken, buyTokenAddress: makerToken,
sellAmountBaseUnits: '10000', sellAmountBaseUnits: '10000',
@ -678,7 +696,7 @@ describe('QuoteRequestor', async () => {
// Set up RFQT responses // Set up RFQT responses
// tslint:disable-next-line:array-type // tslint:disable-next-line:array-type
const mockedRequests: MockedRfqQuoteResponse[] = []; const mockedRequests: MockedRfqQuoteResponse[] = [];
const expectedParams: TakerRequestQueryParams = { const expectedParams: TakerRequestQueryParamsUnnested = {
sellTokenAddress: takerToken, sellTokenAddress: takerToken,
buyTokenAddress: makerToken, buyTokenAddress: makerToken,
sellAmountBaseUnits: '10000', sellAmountBaseUnits: '10000',
@ -763,7 +781,7 @@ describe('QuoteRequestor', async () => {
// Set up RFQT responses // Set up RFQT responses
// tslint:disable-next-line:array-type // tslint:disable-next-line:array-type
const mockedRequests: MockedRfqQuoteResponse[] = []; const mockedRequests: MockedRfqQuoteResponse[] = [];
const expectedParams: TakerRequestQueryParams = { const expectedParams: TakerRequestQueryParamsUnnested = {
sellTokenAddress: takerToken, sellTokenAddress: takerToken,
buyTokenAddress: makerToken, buyTokenAddress: makerToken,
buyAmountBaseUnits: '10000', buyAmountBaseUnits: '10000',

View File

@ -783,7 +783,7 @@
lodash "^4.17.11" lodash "^4.17.11"
web3-provider-engine "14.0.6" web3-provider-engine "14.0.6"
"@0x/json-schemas@^5.0.1", "@0x/json-schemas@^5.0.7", "@0x/json-schemas@^5.3.3": "@0x/json-schemas@^5.0.1", "@0x/json-schemas@^5.3.3":
version "5.3.3" version "5.3.3"
resolved "https://registry.yarnpkg.com/@0x/json-schemas/-/json-schemas-5.3.3.tgz#4b9de100385ca23b0cd58a454165df2e9758e453" resolved "https://registry.yarnpkg.com/@0x/json-schemas/-/json-schemas-5.3.3.tgz#4b9de100385ca23b0cd58a454165df2e9758e453"
dependencies: dependencies:
@ -801,7 +801,7 @@
jsonschema "^1.2.0" jsonschema "^1.2.0"
lodash.values "^4.3.0" lodash.values "^4.3.0"
"@0x/json-schemas@^6.1.3": "@0x/json-schemas@^6.0.1", "@0x/json-schemas@^6.1.3":
version "6.1.3" version "6.1.3"
resolved "https://registry.yarnpkg.com/@0x/json-schemas/-/json-schemas-6.1.3.tgz#da71ed2e50ae6813a6d4d0fe5f8ad69b8e6a7435" resolved "https://registry.yarnpkg.com/@0x/json-schemas/-/json-schemas-6.1.3.tgz#da71ed2e50ae6813a6d4d0fe5f8ad69b8e6a7435"
dependencies: dependencies:
@ -850,11 +850,12 @@
typedoc "~0.16.11" typedoc "~0.16.11"
yargs "^10.0.3" yargs "^10.0.3"
"@0x/quote-server@^5.0.0": "@0x/quote-server@^6.0.2":
version "5.0.0" version "6.0.2"
resolved "https://registry.yarnpkg.com/@0x/quote-server/-/quote-server-5.0.0.tgz#15554099bdfdf71e2910430860257d622f24f703" resolved "https://registry.yarnpkg.com/@0x/quote-server/-/quote-server-6.0.2.tgz#cb99e00c737e0f97a2a32bc7e7be6db65243c3af"
integrity sha512-SS5LfAgKSRjEszWVZl5UtRDBkrsqAvYn/lPB4hxtKky8XitClUYFQ2pSnrFuyQSVft3tFxH4p7eC65YQN5wkcA==
dependencies: dependencies:
"@0x/json-schemas" "^5.0.7" "@0x/json-schemas" "^6.0.1"
"@0x/order-utils" "^10.2.4" "@0x/order-utils" "^10.2.4"
"@0x/protocol-utils" "^1.0.1" "@0x/protocol-utils" "^1.0.1"
"@0x/utils" "^5.4.1" "@0x/utils" "^5.4.1"