Search code examples
servergetcors

The 1inch api im calling is being blocked by a CORS access Control error, im totally lost after trying a few methods to fix the problem


I'm almost finished following a Moralis DEX tutorial, and I've encountered a CORS Access Control error in the console when attempting to call my swap function, which involves making calls to 3 different 1inch APIs to perform a trade.

Just to give some context, my Moralis APIs are functioning correctly and are able to fetch prices consistently whenever the user changes tokens. However, I'm facing an issue specifically with the 1inch API. Interestingly, the tutorial doesn't include the use of a 1inch API key in the axios get request header, nor does it suggest setting one up in a .env file, similar to how the Moralis API is set up. Strangely enough, the tutorial's code works without any issues even without setting up a 1inch API key; it simply uses a plain get request.

Some points to note:

My backend server's index.js showcases the runtime of token prices and is integrated with Moralis code. The call to the 1inch API is made from the swap.js component, and unlike the Moralis API, it doesn't have any code in the backend index.js file, following the tutorial's structure. It seems unnecessary to make changes to the backend code since the tutorial doesn't involve any additional 1inch-specific backend code; only API links are used in the axios.get requests. Here's the function responsible for the problematic API requests when the swap button is clicked, following the tutorial:

async function fetchDexSwap() { const allowance = await axios.get(https://api.1inch.io/v5.0/1/approve/allowance?tokenAddress=${tokenOne.address}&walletAddress=${address}`);

if (allowance.data.allowance === "0") {
    const approve = await axios.get(`https://api.1inch.io/v5.0/1/approve/transaction?tokenAddress=${tokenOne.address}`);
    setTxDetails(approve.data);
    console.log("not approved");
    return;
}

const tx = await axios.get(
    `https://api.1inch.io/v5.0/1/swap?fromTokenAddress=${tokenOne.address}&toTokenAddress=${tokenTwo.address}&amount=${tokenOneAmount.padEnd(tokenOne.decimals + tokenOneAmount.length, '0')}&fromAddress=${address}&slippage=${slippage}`
);

let decimals = Number(`1E${tokenTwo.decimals}`);
setTokenTwoAmount((Number(tx.data.toTokenAmount) / decimals).toFixed(2));
setTxDetails(tx.data.tx);

} `

This code works flawlessly within the tutorial's context. The variables mentioned are all utilized in preceding code. You can find the complete code for the swap.js and the backend index.js files containing Moralis API information can be found at github ( IAmJaysWay ) IN THE DEX FINAL REPO.

I've attempted some solutions, such as switching to the 1inch developer portal and altering the API URL accordingly. I've also tried sending a header in the get request with my API key (following the guidelines outlined in the 1inch documentation), but the error persists. The error message has slightly changed to the following:

"Access to XMLHttpRequest at 'https://api.1inch.dev/swap/v5.2/1/approve/allowance?tokenAddress=0xdac17f958d2ee523a2206206994597c13d831ec7&walletAddress=0x88A3A029E986FD6442c6a652209A5D84D3Fdce2A' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource."

I even tried adding the wildcard Access-Control-Allow-Origin header, but the error remained unchanged.

My attempts at solving this issue can be seen in this code snippet:

async function fetchDexSwap() { try { const allowance = await axios.get( https://api.1inch.dev/swap/v5.2/1/approve/allowance?tokenAddress=${tokenOne.address}&walletAddress=${address}/`, { headers: { Accept: "application/json", Authorization: "MY API KEY", "Access-Control-Allow-Origin": "*", }, } );

    if (allowance.data.allowance === "0") {
        const approve = await axios.get(
            `https://api.1inch.dev/swap/v5.2/1/approve/transaction?tokenAddress=${tokenOne.address}/`,
            {
                headers: {
                    Accept: "application/json",
                    Authorization: "MY API KEY",
                    "Access-Control-Allow-Origin": "*",
                },
            }
        );
        // Rest of the code...
    }
} catch (error) {
    console.error("Error fetching data:", error);
}

} ` I apologize for the lengthy URLs. Any insights into resolving this CORS issue with the 1inch API would be greatly appreciated!


Solution

  • I also struggled with DEX lectures, but this method worked for me.

    To access a server other than localhost, you need to set up a proxy. You can simply add "proxy": "https://api.1inch.dev" to your package.json, but we do not recommend it.

    The recommended method is to first install the necessary dependencies.

    npm i http-proxy-middleware

    Create a file "setupProxy.js" in ./src

    // setupProxy.js
    
    const { createProxyMiddleware } = require("http-proxy-middleware");
    // for your API key in .env
    require("dotenv").config();
    
    module.exports = function (app) {
    
    app.use( "/swap",
    createProxyMiddleware({
      target: "https://api.1inch.dev",
      changeOrigin: true,
      onProxyReq: (proxyReq) => {
        // add API key in Header
        proxyReq.setHeader(
          "Authorization",
          `Bearer ${process.env.REACT_APP_1INCH_KEY}`
          );
        },
      })
     );
    };
    

    Then, in your code, change axios.get() like this

    await axios.get(
        `/swap/v5.2/1/approve/transaction?tokenAddress=${tokenOne.address}`
      );