Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // using node 14.21.12
- // don't forget to install ts-node and tslib
- import ethers from 'ethers'
- import Web3 from 'web3';
- import dotenv from 'dotenv'
- dotenv.config()
- import {
- limitOrderProtocolAddresses, // deliberately misspelled
- seriesNonceManagerContractAddresses,
- ChainId,
- Erc20Facade,
- LimitOrderBuilder,
- LimitOrderProtocolFacade,
- LimitOrderPredicateBuilder,
- NonceSeriesV2,
- SeriesNonceManagerFacade,
- SeriesNonceManagerPredicateBuilder,
- Web3ProviderConnector, // used for interfaces
- PrivateKeyProviderConnector
- } from '@1inch/limit-order-protocol-utils';
- let rpc_url = process.env.RPC_URL
- let pkey = process.env.ACCOUNT_PKEY
- let account = process.env.ACCOUNT_ADDR
- const web3 = new Web3(rpc_url); // can use any web3 RPC provider
- const connector = new PrivateKeyProviderConnector(pkey, web3); //it's usually best not to store the private key in the code as plain text, encrypting/decrypting it is a good practice
- const walletAddress = account
- const chainId = 42161; // suggested, or use your own number
- const contractAddress = limitOrderProtocolAddresses[chainId];
- const seriesContractAddress = seriesNonceManagerContractAddresses[chainId];
- const fromToken = '0xFa7F8980b0f1E64A2062791cc3b0871572f1F7f0'; //uni //this is the token address that you want to sell
- const toToken = '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8';//usdc //this is the token address that you want to buy
- let fromAmount = '2000000000000000000'; // 0.2 UNI
- let toAmount = '2000000'; // 2 USDC (6 decimal places)//ethers.utils.parseUnits("0.1", 6) //usdc //this is how much of the to token you want to buy. make sure it's in minimum divisible units
- const seconds = 60;
- //1st must approve 1inch to spend
- const broadcastApiUrl = 'https://tx-gateway.1inch.io/v1.1/' + chainId + '/broadcast';
- const apiBaseUrl = 'https://api.1inch.io/v5.0/' + chainId;
- function apiRequestUrl(methodName, queryParams) {
- return apiBaseUrl + methodName + '?' + (new URLSearchParams(queryParams)).toString();
- }
- async function broadCastRawTransaction(rawTransaction) {
- return fetch(broadcastApiUrl, {
- method: 'post',
- body: JSON.stringify({rawTransaction}),
- headers: {'Content-Type': 'application/json'}
- })
- .then(res => res.json())
- .then(res => {
- return res.transactionHash;
- });
- }
- async function signAndSendTransaction(transaction) {
- const {rawTransaction} = await web3.eth.accounts.signTransaction(transaction, pkey);
- return await broadCastRawTransaction(rawTransaction);
- }
- async function buildTxForApproveTradeWithRouter(tokenAddress, amount) {
- const url = apiRequestUrl(
- '/approve/transaction',
- amount ? {tokenAddress, amount} : {tokenAddress}
- );
- const transaction = await fetch(url).then(res => res.json());
- const gasLimit = await web3.eth.estimateGas({
- ...transaction,
- from: walletAddress
- });
- return {
- ...transaction,
- gas: gasLimit
- };
- }
- // First, let's build the body of the transaction
- const transactionForSign = await buildTxForApproveTradeWithRouter(fromToken, fromAmount);
- const approveTxHash = await signAndSendTransaction(transactionForSign);
- const limitOrderProtocolFacade = new LimitOrderProtocolFacade(contractAddress, chainId, connector);
- const seriesNonceManagerFacade = new SeriesNonceManagerFacade(seriesContractAddress, chainId, connector);
- const seriesNonceManagerPredicateBuilder = new SeriesNonceManagerPredicateBuilder(seriesNonceManagerFacade);
- const limitOrderPredicateBuilder = new LimitOrderPredicateBuilder(limitOrderProtocolFacade);
- const erc20Facade = new Erc20Facade(connector);
- const limitOrderBuilder = new LimitOrderBuilder(contractAddress, chainId, connector);
- const expiration = Math.floor(Date.now() / 1000) + seconds; // expiration in seconds
- // const nonce = seriesNonceManagerFacade.getNonce(NonceSeriesV2.LimitOrderV3, walletAddress).then((nonce) => nonce.toNumber());
- // above doesn't work without an await so we'll temporarily hardcode the nonce
- const nonce = 0;
- // Creates predicate that restricts Limit Order invalidation conditions
- // Because timestampBelowAndNonceEquals is method of another contract arbitraryStaticCall() is necessary
- const simpleLimitOrderPredicate = limitOrderPredicateBuilder.arbitraryStaticCall( // is type LimitOrderPredicateCallData
- seriesNonceManagerPredicateBuilder.facade,
- seriesNonceManagerPredicateBuilder.timestampBelowAndNonceEquals(
- NonceSeriesV2.LimitOrderV3,
- expiration,
- nonce,
- walletAddress,
- ),
- );
- const limitOrder = limitOrderBuilder.buildLimitOrder({
- makerAssetAddress: fromToken,
- takerAssetAddress: toToken,
- makerAddress: walletAddress,
- makingAmount: fromAmount,
- takingAmount: toAmount,
- predicate: simpleLimitOrderPredicate,
- salt: (Math.floor(Math.random()*100000000)).toString(),
- });
- console.log(limitOrder)
- async function getSignatureAndHash() {
- try {
- const limitOrderTypedData = limitOrderBuilder.buildLimitOrderTypedData(
- limitOrder,
- );
- const limitOrderSignature = await limitOrderBuilder.buildOrderSignature(
- walletAddress,
- limitOrderTypedData,
- );
- const limitOrderHash = await limitOrderBuilder.buildLimitOrderHash(
- limitOrderTypedData
- );
- return [limitOrderSignature, limitOrderHash];
- }catch(e) {
- console.log(e)
- }
- }
- /*
- * The following code is for placing the order with a call to the 1inch API
- * this can be modified to take in the data, for now the data is hardcoded above
- @param limitOrderData: untyped data of the limit order (all are strings)
- @param limitOrderSignature: signature of the limit order
- @param limitOrderHash: hash of the limit order
- */
- async function orderPlace() {
- const [limitOrderSignature, limitOrderHash] = await getSignatureAndHash();
- const signature = await limitOrderSignature;
- const data = {
- "orderHash": limitOrderHash,
- "signature": signature,
- "data": limitOrder // defined outside the scope of this function (above)
- }
- console.log(JSON.stringify(data, null, 2));
- let fetchPromise = await fetch("https://limit-orders.1inch.io/v3.0/42161/limit-order", {
- "headers": {
- "accept": "application/json, text/plain, */*",
- "content-type": "application/json",
- },
- "data": JSON.stringify(data),
- "method": "POST"
- }).then((res) => {
- return res.json()
- }).then((jsonData => {
- console.log(jsonData);
- }));
- console.log(fetchPromise)
- try {
- console.log("\n\n" + (fetchPromise.data));
- } catch (e) { }
- }
- orderPlace();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement