Advertisement
ethdevs

1inch limit order

May 10th, 2023 (edited)
238
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 6.97 KB | Source Code | 0 0
  1. // using node 14.21.12
  2. import fetch from 'node-fetch'; // specifically version [email protected]
  3. // don't forget to install ts-node and tslib
  4. import ethers from 'ethers'
  5. import Web3 from 'web3';
  6. import dotenv from 'dotenv'
  7. dotenv.config()
  8. import {
  9.     limitOrderProtocolAddresses, // deliberately misspelled
  10.     seriesNonceManagerContractAddresses,
  11.     ChainId,
  12.     Erc20Facade,
  13.     LimitOrderBuilder,
  14.     LimitOrderProtocolFacade,
  15.     LimitOrderPredicateBuilder,
  16.     NonceSeriesV2,
  17.     SeriesNonceManagerFacade,
  18.     SeriesNonceManagerPredicateBuilder,
  19.     Web3ProviderConnector, // used for interfaces
  20.     PrivateKeyProviderConnector
  21. } from '@1inch/limit-order-protocol-utils';
  22.  
  23. let rpc_url = process.env.RPC_URL
  24. let pkey = process.env.ACCOUNT_PKEY
  25. let account = process.env.ACCOUNT_ADDR
  26.  
  27.  
  28. const web3 = new Web3(rpc_url); // can use any web3 RPC provider
  29. 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
  30. const walletAddress = account
  31. const chainId = 42161; // suggested, or use your own number
  32. const contractAddress = limitOrderProtocolAddresses[chainId];
  33. const seriesContractAddress = seriesNonceManagerContractAddresses[chainId];
  34.  
  35.  
  36. const fromToken = '0xFa7F8980b0f1E64A2062791cc3b0871572f1F7f0'; //uni                 //this is the token address that you want to sell
  37. const toToken = '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8';//usdc                     //this is the token address that you want to buy
  38. let fromAmount = '2000000000000000000'; // 0.2 UNI
  39. 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
  40. const seconds = 60;              
  41.  
  42. //1st must approve 1inch to spend
  43.  
  44.  
  45. const broadcastApiUrl = 'https://tx-gateway.1inch.io/v1.1/' + chainId + '/broadcast';
  46. const apiBaseUrl = 'https://api.1inch.io/v5.0/' + chainId;
  47.  
  48. function apiRequestUrl(methodName, queryParams) {
  49.     return apiBaseUrl + methodName + '?' + (new URLSearchParams(queryParams)).toString();
  50. }
  51.  
  52. async function broadCastRawTransaction(rawTransaction) {
  53.     return fetch(broadcastApiUrl, {
  54.         method: 'post',
  55.         body: JSON.stringify({rawTransaction}),
  56.         headers: {'Content-Type': 'application/json'}
  57.     })
  58.         .then(res => res.json())
  59.         .then(res => {
  60.             return res.transactionHash;
  61.         });
  62. }
  63.  
  64. async function signAndSendTransaction(transaction) {
  65.     const {rawTransaction} = await web3.eth.accounts.signTransaction(transaction, pkey);
  66.  
  67.     return await broadCastRawTransaction(rawTransaction);
  68. }
  69.  
  70. async function buildTxForApproveTradeWithRouter(tokenAddress, amount) {
  71.     const url = apiRequestUrl(
  72.         '/approve/transaction',
  73.         amount ? {tokenAddress, amount} : {tokenAddress}
  74.     );
  75.  
  76.     const transaction = await fetch(url).then(res => res.json());
  77.  
  78.     const gasLimit = await web3.eth.estimateGas({
  79.         ...transaction,
  80.         from: walletAddress
  81.     });
  82.  
  83.     return {
  84.         ...transaction,
  85.         gas: gasLimit
  86.     };
  87. }
  88.  
  89. // First, let's build the body of the transaction
  90. const transactionForSign = await buildTxForApproveTradeWithRouter(fromToken, fromAmount);
  91. const approveTxHash = await signAndSendTransaction(transactionForSign);
  92.  
  93.  
  94. const limitOrderProtocolFacade = new LimitOrderProtocolFacade(contractAddress, chainId, connector);
  95. const seriesNonceManagerFacade = new SeriesNonceManagerFacade(seriesContractAddress, chainId, connector);
  96. const seriesNonceManagerPredicateBuilder = new SeriesNonceManagerPredicateBuilder(seriesNonceManagerFacade);
  97. const limitOrderPredicateBuilder = new LimitOrderPredicateBuilder(limitOrderProtocolFacade);
  98. const erc20Facade = new Erc20Facade(connector);
  99. const limitOrderBuilder = new LimitOrderBuilder(contractAddress, chainId, connector);
  100.  
  101. const expiration = Math.floor(Date.now() / 1000) + seconds; // expiration in seconds
  102. // const nonce = seriesNonceManagerFacade.getNonce(NonceSeriesV2.LimitOrderV3, walletAddress).then((nonce) => nonce.toNumber());
  103. // above doesn't work without an await so we'll temporarily hardcode the nonce
  104. const nonce = 0;
  105. // Creates predicate that restricts Limit Order invalidation conditions
  106. // Because timestampBelowAndNonceEquals is method of another contract arbitraryStaticCall() is necessary
  107. const simpleLimitOrderPredicate = limitOrderPredicateBuilder.arbitraryStaticCall( // is type LimitOrderPredicateCallData
  108.     seriesNonceManagerPredicateBuilder.facade,
  109.     seriesNonceManagerPredicateBuilder.timestampBelowAndNonceEquals(
  110.         NonceSeriesV2.LimitOrderV3,
  111.         expiration,
  112.         nonce,
  113.         walletAddress,
  114.     ),
  115. );
  116.  
  117. const limitOrder = limitOrderBuilder.buildLimitOrder({
  118.     makerAssetAddress: fromToken,
  119.     takerAssetAddress: toToken,
  120.     makerAddress: walletAddress,
  121.     makingAmount: fromAmount,
  122.     takingAmount: toAmount,
  123.     predicate: simpleLimitOrderPredicate,
  124.     salt: (Math.floor(Math.random()*100000000)).toString(),
  125. });
  126.  
  127. console.log(limitOrder)
  128.  
  129.  
  130. async function getSignatureAndHash() {
  131.     try {
  132.  
  133.  
  134.         const limitOrderTypedData = limitOrderBuilder.buildLimitOrderTypedData(
  135.             limitOrder,
  136.         );
  137.         const limitOrderSignature = await limitOrderBuilder.buildOrderSignature(
  138.             walletAddress,
  139.             limitOrderTypedData,
  140.         );
  141.  
  142.         const limitOrderHash = await limitOrderBuilder.buildLimitOrderHash(
  143.             limitOrderTypedData
  144.         );
  145.        
  146.         return [limitOrderSignature, limitOrderHash];
  147.     }catch(e) {
  148.         console.log(e)
  149.        
  150.     }
  151. }
  152.  
  153. /*
  154.     * The following code is for placing the order with a call to the 1inch API
  155.     * this can be modified to take in the data, for now the data is hardcoded above
  156.     @param limitOrderData: untyped data of the limit order (all are strings)
  157.     @param limitOrderSignature: signature of the limit order
  158.     @param limitOrderHash: hash of the limit order
  159. */
  160.  
  161. async function orderPlace() {
  162.  
  163.     const [limitOrderSignature, limitOrderHash] = await getSignatureAndHash();
  164.  
  165.     const signature = await limitOrderSignature;
  166.     const data = {
  167.         "orderHash": limitOrderHash,
  168.         "signature": signature,
  169.         "data": limitOrder // defined outside the scope of this function (above)
  170.     }
  171.     console.log(JSON.stringify(data, null, 2));
  172.  
  173.     let fetchPromise = await fetch("https://limit-orders.1inch.io/v3.0/42161/limit-order", {
  174.         "headers": {
  175.             "accept": "application/json, text/plain, */*",
  176.             "content-type": "application/json",
  177.         },
  178.         "data": JSON.stringify(data),
  179.         "method": "POST"
  180.     }).then((res) => {
  181.         return res.json()
  182.     }).then((jsonData => {
  183.         console.log(jsonData);
  184.     }));
  185.  
  186.     console.log(fetchPromise)
  187.  
  188.  
  189.     try {
  190.         console.log("\n\n" + (fetchPromise.data));
  191.     } catch (e) { }
  192. }
  193.  
  194. orderPlace();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement