This repository has been archived by the owner on Oct 10, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 118
/
Copy pathfill_0x_api_swap.ts
152 lines (125 loc) · 5.83 KB
/
fill_0x_api_swap.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import { ContractWrappers } from '@0x/contract-wrappers';
import { BigNumber } from '@0x/utils';
import { Web3Wrapper } from '@0x/web3-wrapper';
import axios from 'axios';
import { NETWORK_CONFIGS, TX_DEFAULTS } from '../configs';
import { DECIMALS, MOCK_0x_API_BASE_URL, UNLIMITED_ALLOWANCE_IN_BASE_UNITS } from '../constants';
import { setUpMock0xApiResponsesAsync } from '../mock_0x_api_response_utils';
import { PrintUtils } from '../print_utils';
import { providerEngine } from '../provider_engine';
import { runMigrationsOnceIfRequiredAsync } from '../utils';
/**
* In this scenario, the taker grabs a swap quote from 0x API
* and fills it on-chain.
*
* The taker wants to buy 5 ZRX
*/
export async function scenarioAsync(): Promise<void> {
await runMigrationsOnceIfRequiredAsync();
PrintUtils.printScenario('Fill a 0x API Swap Quote');
// Taker wishes to buy 5 ZRX with WETH
const buyAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(5), DECIMALS);
// SETUP
// create an axios instance for http requests
const axiosInstance = axios.create();
// Initialize the ContractWrappers for setting up our taker's token balance
const contractWrappers = new ContractWrappers(providerEngine, { chainId: NETWORK_CONFIGS.chainId });
// Initialize the Web3Wrapper, this provides helper functions around fetching
// account information, balances, general contract logs
const web3Wrapper = new Web3Wrapper(providerEngine);
// Grabbing a maker address as well for setting up our mock API response
const [maker, taker] = await web3Wrapper.getAvailableAddressesAsync();
// Call util for mocking an API responses
await setUpMock0xApiResponsesAsync(axiosInstance, maker, taker, providerEngine);
const exchangeProxyAddress = contractWrappers.contractAddresses.exchangeProxy;
const zrxTokenAddress = contractWrappers.contractAddresses.zrxToken;
const wethTokenAddress = contractWrappers.contractAddresses.etherToken;
const printUtils = new PrintUtils(
web3Wrapper,
contractWrappers,
{ taker },
{ WETH: wethTokenAddress, ZRX: zrxTokenAddress },
);
printUtils.printAccounts();
// Allow the 0x Exchange Proxy to move WETH on behalf of the taker
const etherToken = contractWrappers.weth9;
const takerWETHApprovalTxHash = await etherToken
.approve(exchangeProxyAddress, UNLIMITED_ALLOWANCE_IN_BASE_UNITS)
.sendTransactionAsync({ from: taker, ...TX_DEFAULTS });
await printUtils.awaitTransactionMinedSpinnerAsync('Taker WETH Approval', takerWETHApprovalTxHash);
// Convert ETH into WETH for taker by depositing ETH into the WETH contract
const takerAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(0.1), DECIMALS);
const takerWETHDepositTxHash = await etherToken.deposit().sendTransactionAsync({
from: taker,
value: takerAmount,
});
await printUtils.awaitTransactionMinedSpinnerAsync('Taker WETH Deposit', takerWETHDepositTxHash);
PrintUtils.printData('Setup', [
['Taker WETH Approval', takerWETHApprovalTxHash],
['Taker WETH Deposit', takerWETHDepositTxHash],
]);
// CREATE REQUEST FOR 0x API
// An API key in the header gives access to RFQ liqudity
// Ask the 0x labs team for RFQ access for your application
const quoteRequestHeaders = {
'0x-api-key': 'a-dope-api-key',
};
const quoteRequestParams = {
// REQUIRED PARAMETERS //
// token address the taker wants to buy
buyToken: zrxTokenAddress,
// token address the taker wants to sell
sellToken: wethTokenAddress,
// here we specify the amount of the buy token, since
// the taker is requesting to buy 5 ZRX
buyAmount: buyAmount.toString(),
// alternatively the taker could have asked to sell a certain
// amount of WETH for ZRX
// sellAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(0.1), DECIMALS)
// OPTIONAL PARAMETERS //
// Not all parameters are listed here
// see https://0x.org/docs/api#get-swapv1quote
// The maximum acceptable slippage from the quoted price to execution price.
// E.g 0.03 for 3% slippage allowed.
slippagePercentage: 0.01,
// The address which will fill the quote.
// When provided the gas will be estimated and returned and the
// entire transaction will be validated for success.
// If the validation fails a Revert Error will be returned
// in the response.
// Required for RFQ liquidity
takerAddress: taker,
// Required for RFQ liquidity,
// see https://0x.org/docs/guides/rfqt-in-the-0x-api#maker-endpoint-interactions
intentOnFilling: true,
};
// Make the request to 0x API
const swapResponse = await axiosInstance.get(`${MOCK_0x_API_BASE_URL}/swap/v1/quote`, {
params: quoteRequestParams,
headers: quoteRequestHeaders,
});
// Grab necessary data for the transaction
// from the response from 0x API
const { data, to, value, gas, gasPrice } = swapResponse.data;
// Send the swap quote in a transaction
// This example is using 0x's web3wrapper, but this could be done
// with ethers or web3.js as well.
const swapTxHash = await web3Wrapper.sendTransactionAsync({ from: taker, to, data, value, gas, gasPrice });
const txReceipt = await printUtils.awaitTransactionMinedSpinnerAsync('fill 0x API swap', swapTxHash);
printUtils.printTransaction('fill 0x API swap', txReceipt);
// Print the Balances
await printUtils.fetchAndPrintContractBalancesAsync();
// Stop the Provider Engine
providerEngine.stop();
}
void (async () => {
try {
if (!module.parent) {
await scenarioAsync();
}
} catch (e) {
console.log(e);
providerEngine.stop();
process.exit(1);
}
})();