finished exchange swap quote consumer
This commit is contained in:
parent
4b09204936
commit
ac771e2865
@ -11,16 +11,15 @@ import {
|
|||||||
SmartContractParamsInfo,
|
SmartContractParamsInfo,
|
||||||
SwapQuote,
|
SwapQuote,
|
||||||
SwapQuoteConsumer,
|
SwapQuoteConsumer,
|
||||||
|
SwapQuoteConsumerError,
|
||||||
SwapQuoteConsumerOpts,
|
SwapQuoteConsumerOpts,
|
||||||
SwapQuoteExecutionOpts,
|
SwapQuoteExecutionOpts,
|
||||||
SwapQuoteGetOutputOpts,
|
SwapQuoteGetOutputOpts,
|
||||||
SwapQuoteInfo,
|
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import { assert } from '../utils/assert';
|
import { assert } from '../utils/assert';
|
||||||
|
import { SwapQuoteConsumerUtils } from '../utils/swap_quote_consumer_utils';
|
||||||
import { utils } from '../utils/utils';
|
import { utils } from '../utils/utils';
|
||||||
|
|
||||||
import { assetDataUtils } from '../utils/asset_data_utils';
|
|
||||||
|
|
||||||
export class ExchangeSwapQuoteConsumer implements SwapQuoteConsumer<ExchangeMarketBuySmartContractParams> {
|
export class ExchangeSwapQuoteConsumer implements SwapQuoteConsumer<ExchangeMarketBuySmartContractParams> {
|
||||||
|
|
||||||
public readonly provider: ZeroExProvider;
|
public readonly provider: ZeroExProvider;
|
||||||
@ -28,17 +27,11 @@ export class ExchangeSwapQuoteConsumer implements SwapQuoteConsumer<ExchangeMark
|
|||||||
|
|
||||||
private readonly _contractWrappers: ContractWrappers;
|
private readonly _contractWrappers: ContractWrappers;
|
||||||
|
|
||||||
constructor(
|
constructor(supportedProvider: SupportedProvider, options: Partial<SwapQuoteConsumerOpts> = {}) {
|
||||||
supportedProvider: SupportedProvider,
|
const { networkId } = _.merge({}, constants.DEFAULT_SWAP_QUOTER_OPTS, options);
|
||||||
options: Partial<SwapQuoteConsumerOpts> = {},
|
|
||||||
) {
|
|
||||||
const { networkId } = _.merge(
|
|
||||||
{},
|
|
||||||
constants.DEFAULT_SWAP_QUOTER_OPTS,
|
|
||||||
options,
|
|
||||||
);
|
|
||||||
const provider = providerUtils.standardizeOrThrow(supportedProvider);
|
|
||||||
assert.isNumber('networkId', networkId);
|
assert.isNumber('networkId', networkId);
|
||||||
|
|
||||||
|
const provider = providerUtils.standardizeOrThrow(supportedProvider);
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
this.networkId = networkId;
|
this.networkId = networkId;
|
||||||
this._contractWrappers = new ContractWrappers(this.provider, {
|
this._contractWrappers = new ContractWrappers(this.provider, {
|
||||||
@ -47,14 +40,88 @@ export class ExchangeSwapQuoteConsumer implements SwapQuoteConsumer<ExchangeMark
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getCalldataOrThrow = (quote: SwapQuote, opts: Partial<SwapQuoteGetOutputOpts>): CalldataInfo => {
|
public getCalldataOrThrow = (quote: SwapQuote, opts: Partial<SwapQuoteGetOutputOpts>): CalldataInfo => {
|
||||||
|
assert.isValidSwapQuote('quote', quote);
|
||||||
|
|
||||||
|
const { params, to, ethAmount, methodAbi } = this.getSmartContractParamsOrThrow(quote, opts);
|
||||||
|
const abiEncoder = new AbiEncoder.Method(methodAbi);
|
||||||
|
const args = [
|
||||||
|
params.orders,
|
||||||
|
params.makerAssetFillAmount,
|
||||||
|
params.signatures,
|
||||||
|
];
|
||||||
|
const calldataHexString = abiEncoder.encode(args);
|
||||||
|
return {
|
||||||
|
calldataHexString,
|
||||||
|
methodAbi,
|
||||||
|
to,
|
||||||
|
ethAmount,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public getSmartContractParamsOrThrow = (quote: SwapQuote, opts: Partial<SwapQuoteGetOutputOpts>): SmartContractParamsInfo<ExchangeMarketBuySmartContractParams> => {
|
public getSmartContractParamsOrThrow = (quote: SwapQuote, opts: Partial<SwapQuoteGetOutputOpts>): SmartContractParamsInfo<ExchangeMarketBuySmartContractParams> => {
|
||||||
|
assert.isValidSwapQuote('quote', quote);
|
||||||
|
|
||||||
|
const { orders, makerAssetFillAmount } = quote;
|
||||||
|
|
||||||
|
const signatures = _.map(orders, o => o.signature);
|
||||||
|
|
||||||
|
const params: ExchangeMarketBuySmartContractParams = {
|
||||||
|
orders,
|
||||||
|
signatures,
|
||||||
|
makerAssetFillAmount,
|
||||||
|
};
|
||||||
|
|
||||||
|
const methodAbi = utils.getMethodAbiFromContractAbi(
|
||||||
|
this._contractWrappers.exchange.abi,
|
||||||
|
'marketBuyOrdersNoThrow',
|
||||||
|
) as MethodAbi;
|
||||||
|
|
||||||
|
return {
|
||||||
|
params,
|
||||||
|
to: this._contractWrappers.exchange.address,
|
||||||
|
methodAbi,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public executeSwapQuoteOrThrowAsync = async (quote: SwapQuote, opts: Partial<SwapQuoteExecutionOpts>): Promise<string> => {
|
public executeSwapQuoteOrThrowAsync = async (quote: SwapQuote, opts: Partial<SwapQuoteExecutionOpts>): Promise<string> => {
|
||||||
|
assert.isValidSwapQuote('quote', quote);
|
||||||
|
|
||||||
};
|
const { takerAddress, gasLimit, gasPrice } = opts;
|
||||||
|
|
||||||
|
if (takerAddress !== undefined) {
|
||||||
|
assert.isETHAddressHex('takerAddress', takerAddress);
|
||||||
|
}
|
||||||
|
if (gasLimit !== undefined) {
|
||||||
|
assert.isNumber('gasLimit', gasLimit);
|
||||||
|
}
|
||||||
|
if (gasPrice !== undefined) {
|
||||||
|
assert.isBigNumber('gasPrice', gasPrice);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { orders, makerAssetFillAmount } = quote;
|
||||||
|
|
||||||
|
const finalTakerAddress = await SwapQuoteConsumerUtils.getTakerAddressOrThrowAsync(this.provider, opts);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const txHash = await this._contractWrappers.exchange.marketBuyOrdersNoThrowAsync(
|
||||||
|
orders,
|
||||||
|
makerAssetFillAmount,
|
||||||
|
finalTakerAddress,
|
||||||
|
{
|
||||||
|
gasLimit,
|
||||||
|
gasPrice,
|
||||||
|
shouldValidate: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return txHash;
|
||||||
|
} catch (err) {
|
||||||
|
if (_.includes(err.message, ContractWrappersError.SignatureRequestDenied)) {
|
||||||
|
throw new Error(SwapQuoteConsumerError.SignatureRequestDenied);
|
||||||
|
} else if (_.includes(err.message, ForwarderWrapperError.CompleteFillFailed)) {
|
||||||
|
throw new Error(SwapQuoteConsumerError.TransactionValueTooLow);
|
||||||
|
} else {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ export interface CalldataInfo {
|
|||||||
export interface SmartContractParamsInfo<T> {
|
export interface SmartContractParamsInfo<T> {
|
||||||
params: T;
|
params: T;
|
||||||
to: string;
|
to: string;
|
||||||
ethAmount: BigNumber;
|
ethAmount?: BigNumber;
|
||||||
methodAbi: MethodAbi;
|
methodAbi: MethodAbi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
24
packages/asset-buyer/src/utils/swap_quote_consumer_utils.ts
Normal file
24
packages/asset-buyer/src/utils/swap_quote_consumer_utils.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { SupportedProvider, Web3Wrapper, ZeroExProvider } from '@0x/web3-wrapper';
|
||||||
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
|
import {
|
||||||
|
SwapQuoteConsumerError,
|
||||||
|
SwapQuoteExecutionOpts,
|
||||||
|
} from '../types';
|
||||||
|
|
||||||
|
export const SwapQuoteConsumerUtils = {
|
||||||
|
async getTakerAddressOrThrowAsync(provider: SupportedProvider, opts: Partial<SwapQuoteExecutionOpts>): Promise<string> {
|
||||||
|
if (opts.takerAddress !== undefined) {
|
||||||
|
return opts.takerAddress;
|
||||||
|
} else {
|
||||||
|
const web3Wrapper = new Web3Wrapper(provider);
|
||||||
|
const availableAddresses = await web3Wrapper.getAvailableAddressesAsync();
|
||||||
|
const firstAvailableAddress = _.head(availableAddresses);
|
||||||
|
if (firstAvailableAddress !== undefined) {
|
||||||
|
return firstAvailableAddress;
|
||||||
|
} else {
|
||||||
|
throw new Error(SwapQuoteConsumerError.NoAddressAvailable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user