Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Could not detect network" error on Next.js 14 API endpoint with JsonRpcProvider #4469

Open
DavNej opened this issue Nov 17, 2023 · 21 comments
Assignees
Labels
investigate Under investigation and may be a bug. v5 Issues regarding legacy-v5

Comments

@DavNej
Copy link

DavNej commented Nov 17, 2023

Ethers Version

5.7.2

Search Terms

NETWORK_ERROR, next 14, JsonRpcProvider, next api endpoint

Describe the Problem

Issue:

I am encountering what I think is a compatibility issue between Next.js 14 and ethers@5.7.2 . When attempting to instantiate a JsonRpcProvider on an API endpoint, I consistently receive a could not detect network error.

Steps to Reproduce:

- Upgrade Next.js to version 14.
- Use ethers.js version 5.7.2.
- Instantiate on a Next API endpoint a `JsonRpcProvider` with a valid RPC URL .

Expected Behavior:

The JsonRpcProvider should be successfully instantiated without any "could not detect network" errors.

Actual Behavior:

Encountering a "could not detect network" error when attempting to instantiate a JSONRPCProvider.

Additional Information:

The issue is not present when using Next.js 13.
Downgrading to Next.js 13 resolves the problem, but a solution for Next.js 14 compatibility is desired.

Environment:

Next.js version: 14
ethers.js version: 5.7.2
Provider: JSONRPCProvider with a valid RPC URL

Note:

Any guidance or workaround to make ethers.js version 5.7.2, specifically with JSONRPCProvider, compatible with Next.js 14 would be highly appreciated.

Code Snippet

import { NextResponse } from 'next/server'
import { ethers, type BigNumber } from 'ethers'
import abi from 'abi.json'

const contractInterface = new ethers.utils.Interface(abi)

export async function GET(request: Request) {
  const provider = new ethers.providers.JsonRpcProvider(<RPC_TARGET>)

  const wallet = new ethers.Wallet(<PRIVATE_KEY>, provider)
  const contract = new ethers.Contract(
    <CONTRACT_ADDRESS>,
    contractInterface,
    wallet
  )

  try {
    const handlePrice: BigNumber = await contract.getHandlePrice(handle)
    return NextResponse.json<{ handlePrice: BigNumber }>({ handlePrice })
  } catch (err) {
    console.error('💥', err)
    return NextResponse.json(err, { status: 500 })
  }
}

Contract ABI

[
  {
    "inputs": [],
    "stateMutability": "nonpayable",
    "type": "constructor"
  },
  {
    "inputs": [],
    "name": "HandleContainsInvalidCharacters",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "HandleFirstCharInvalid",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "HandleLengthInvalid",
    "type": "error"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "address",
        "name": "previousAdmin",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "address",
        "name": "newAdmin",
        "type": "address"
      }
    ],
    "name": "AdminChanged",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "owner",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "approved",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "Approval",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "owner",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "operator",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "bool",
        "name": "approved",
        "type": "bool"
      }
    ],
    "name": "ApprovalForAll",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "beacon",
        "type": "address"
      }
    ],
    "name": "BeaconUpgraded",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "uint256",
        "name": "profileId",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "string",
        "name": "newCid",
        "type": "string"
      }
    ],
    "name": "CidUpdated",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "profileId",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "address",
        "name": "delegate",
        "type": "address"
      }
    ],
    "name": "DelegateAdded",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "profileId",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "address",
        "name": "delegate",
        "type": "address"
      }
    ],
    "name": "DelegateRemoved",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "uint8",
        "name": "version",
        "type": "uint8"
      }
    ],
    "name": "Initialized",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "user",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "profileId",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "string",
        "name": "handle",
        "type": "string"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "platformId",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "fee",
        "type": "uint256"
      }
    ],
    "name": "Mint",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "mintFee",
        "type": "uint256"
      }
    ],
    "name": "MintFeeUpdated",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "enum TalentLayerID.MintStatus",
        "name": "mintStatus",
        "type": "uint8"
      }
    ],
    "name": "MintStatusUpdated",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "previousOwner",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "newOwner",
        "type": "address"
      }
    ],
    "name": "OwnershipTransferred",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "price",
        "type": "uint256"
      }
    ],
    "name": "ShortHandlesMaxPriceUpdated",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "from",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "Transfer",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "address",
        "name": "forwarder",
        "type": "address"
      }
    ],
    "name": "TrustedForwarderAdded",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "address",
        "name": "forwarder",
        "type": "address"
      }
    ],
    "name": "TrustedForwarderRemoved",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "implementation",
        "type": "address"
      }
    ],
    "name": "Upgraded",
    "type": "event"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "_profileId",
        "type": "uint256"
      },
      {
        "internalType": "address",
        "name": "_delegate",
        "type": "address"
      }
    ],
    "name": "addDelegate",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "_forwarder",
        "type": "address"
      }
    ],
    "name": "addTrustedForwarder",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "approve",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "owner",
        "type": "address"
      }
    ],
    "name": "balanceOf",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "_platformId",
        "type": "uint256"
      },
      {
        "internalType": "address",
        "name": "_userAddress",
        "type": "address"
      },
      {
        "internalType": "string",
        "name": "_handle",
        "type": "string"
      }
    ],
    "name": "freeMint",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "getApproved",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "string",
        "name": "_handle",
        "type": "string"
      }
    ],
    "name": "getHandlePrice",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "_address",
        "type": "address"
      }
    ],
    "name": "getOriginatorPlatformIdByAddress",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "name": "hasActivity",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "name": "ids",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "_talentLayerPlatformIdAddress",
        "type": "address"
      }
    ],
    "name": "initialize",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "owner",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "operator",
        "type": "address"
      }
    ],
    "name": "isApprovedForAll",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "_profileId",
        "type": "uint256"
      },
      {
        "internalType": "address",
        "name": "_address",
        "type": "address"
      }
    ],
    "name": "isDelegate",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "_profileId",
        "type": "uint256"
      },
      {
        "internalType": "address",
        "name": "_address",
        "type": "address"
      }
    ],
    "name": "isOwnerOrDelegate",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "name": "isServiceContract",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "forwarder",
        "type": "address"
      }
    ],
    "name": "isTrustedForwarder",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "_profileId",
        "type": "uint256"
      }
    ],
    "name": "isValid",
    "outputs": [],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "_address",
        "type": "address"
      },
      {
        "internalType": "string",
        "name": "_handle",
        "type": "string"
      },
      {
        "internalType": "bytes32[]",
        "name": "_proof",
        "type": "bytes32[]"
      }
    ],
    "name": "isWhitelisted",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "_platformId",
        "type": "uint256"
      },
      {
        "internalType": "string",
        "name": "_handle",
        "type": "string"
      }
    ],
    "name": "mint",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "payable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "mintFee",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "_address",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "_platformId",
        "type": "uint256"
      },
      {
        "internalType": "string",
        "name": "_handle",
        "type": "string"
      }
    ],
    "name": "mintForAddress",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "payable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "mintStatus",
    "outputs": [
      {
        "internalType": "enum TalentLayerID.MintStatus",
        "name": "",
        "type": "uint8"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "name",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "owner",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "ownerOf",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "_tokenId1",
        "type": "uint256"
      },
      {
        "internalType": "uint256",
        "name": "_tokenId2",
        "type": "uint256"
      }
    ],
    "name": "ownersOf",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "name": "profiles",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "id",
        "type": "uint256"
      },
      {
        "internalType": "string",
        "name": "handle",
        "type": "string"
      },
      {
        "internalType": "uint256",
        "name": "platformId",
        "type": "uint256"
      },
      {
        "internalType": "string",
        "name": "dataUri",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "proxiableUUID",
    "outputs": [
      {
        "internalType": "bytes32",
        "name": "",
        "type": "bytes32"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "_profileId",
        "type": "uint256"
      },
      {
        "internalType": "address",
        "name": "_delegate",
        "type": "address"
      }
    ],
    "name": "removeDelegate",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "_forwarder",
        "type": "address"
      }
    ],
    "name": "removeTrustedForwarder",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "renounceOwnership",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "from",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "safeTransferFrom",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "from",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      },
      {
        "internalType": "bytes",
        "name": "data",
        "type": "bytes"
      }
    ],
    "name": "safeTransferFrom",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "operator",
        "type": "address"
      },
      {
        "internalType": "bool",
        "name": "approved",
        "type": "bool"
      }
    ],
    "name": "setApprovalForAll",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "_profileId",
        "type": "uint256"
      }
    ],
    "name": "setHasActivity",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "_address",
        "type": "address"
      },
      {
        "internalType": "bool",
        "name": "_isServiceContract",
        "type": "bool"
      }
    ],
    "name": "setIsServiceContract",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "bytes32",
        "name": "root",
        "type": "bytes32"
      }
    ],
    "name": "setWhitelistMerkleRoot",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "bytes4",
        "name": "interfaceId",
        "type": "bytes4"
      }
    ],
    "name": "supportsInterface",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "symbol",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "name": "takenHandles",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "talentLayerPlatformIdContract",
    "outputs": [
      {
        "internalType": "contract ITalentLayerPlatformID",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "tokenURI",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "totalSupply",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "from",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "transferFrom",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "newOwner",
        "type": "address"
      }
    ],
    "name": "transferOwnership",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "_mintFee",
        "type": "uint256"
      }
    ],
    "name": "updateMintFee",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "enum TalentLayerID.MintStatus",
        "name": "_mintStatus",
        "type": "uint8"
      }
    ],
    "name": "updateMintStatus",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "_profileId",
        "type": "uint256"
      },
      {
        "internalType": "string",
        "name": "_newCid",
        "type": "string"
      }
    ],
    "name": "updateProfileData",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "_shortHandlesMaxPrice",
        "type": "uint256"
      }
    ],
    "name": "updateShortHandlesMaxPrice",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "newImplementation",
        "type": "address"
      }
    ],
    "name": "upgradeTo",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "newImplementation",
        "type": "address"
      },
      {
        "internalType": "bytes",
        "name": "data",
        "type": "bytes"
      }
    ],
    "name": "upgradeToAndCall",
    "outputs": [],
    "stateMutability": "payable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "_platformId",
        "type": "uint256"
      },
      {
        "internalType": "string",
        "name": "_handle",
        "type": "string"
      },
      {
        "internalType": "bytes32[]",
        "name": "_proof",
        "type": "bytes32[]"
      }
    ],
    "name": "whitelistMint",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "payable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "withdraw",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  }
]

Errors

could not detect network (event="noNetwork", code=NETWORK_ERROR, version=providers/5.7.2)
    at Logger.makeError (webpack-internal:///(rsc)/./node_modules/@ethersproject/logger/lib.esm/index.js:240:23)
    at Logger.throwError (webpack-internal:///(rsc)/./node_modules/@ethersproject/logger/lib.esm/index.js:249:20)
    at JsonRpcProvider.eval (webpack-internal:///(rsc)/./node_modules/@ethersproject/providers/lib.esm/json-rpc-provider.js:513:27)
    at Generator.throw (<anonymous>)
    at rejected (webpack-internal:///(rsc)/./node_modules/@ethersproject/providers/lib.esm/json-rpc-provider.js:34:40)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:538:9)
    at process.processTimers (node:internal/timers:512:7) {
  reason: 'could not detect network',
  code: 'NETWORK_ERROR',
  event: 'noNetwork'
}

Environment

Other (please specify)

Environment (Other)

NextJS 14

@DavNej DavNej added investigate Under investigation and may be a bug. v5 Issues regarding legacy-v5 labels Nov 17, 2023
@HansBhatia
Copy link

HansBhatia commented Dec 20, 2023

Just got the same issue on my side. Viem worked, but of course .. that isn't very assuring. Instead, I added v6 to my project using npm package aliasing which works.
ni ethers-latest@npm:ethers@v6

@remibeaufils
Copy link

👋 Hello, I'm also encountering the same issue when upgrading from Next.js 13 to 14 with Ethers 5.7.2.

I want to add my voice to highlight its impact. If there are any updates or workarounds, I'd greatly appreciate it. Thanks!

@dsimmons
Copy link

dsimmons commented Jan 5, 2024

Just got bitten by this in production via a silent failure by a dependency (itself using Ethers). Manifested as a promise that never resolved and resulted in a lot of user confusion until we arrived at the root cause!

@ricmoo
Copy link
Member

ricmoo commented Jan 5, 2024

@dsimmons Are you using v5 or v6? In v6, you can detect this error using provider.on("error", …), which you can either wait for the link to come back up or use provider.destroy() and use whatever recovery method you use, depending on why the network isn’t detectable (i.e. the node is failing to reply to eth_chainId.

If connecting to a static network, specifying that network will also skip this problem. You will likely still get an error, but it will be something you can trap using try…catch on the calls.

This isn’t generally trappable because it happens in the constructor, and we don’t have async constructors. :(

@dsimmons
Copy link

dsimmons commented Jan 6, 2024

@ricmoo Actually, neither! 😅

I am however using Irys via their JS SDK, which itself uses v5, so I don't have a lot of control over this issue unfortunately (transitive dependency).

@tazous
Copy link

tazous commented Jan 10, 2024

I do encounter the same issue... I think no provider are working anymore with next 14 and to complete this thread, I will add that AlchemyProvider is also failing which i think is linked. The error is totally different ('Referrer "client" is not a valid URL') but I put the stacktrace here if it can help to find and solve the problem:

Error: missing revert data in call exception; Transaction reverted without a reason string [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (data="0x", transaction={"to":"0xzzzzzzzzzzzzzzzzzzzzzzzzzzzz","data":"0xzzzzzzzzzzzzzzzzzzzzzzzzzzzzz","accessList":null}, error={"reason":"missing response","code":"SERVER_ERROR","requestBody":"{\"method\":\"eth_call\",\"params\":[{\"to\":\"0xzzzzzzzzzzzzzzzzzzzzzzzzzzzz\",\"data\":\"0xzzzzzzzzzzzzzzzzzzzzzzzzzzzzz\"},\"latest\"],\"id\":42,\"jsonrpc\":\"2.0\"}","requestMethod":"POST","serverError":{},"url":"https://polygon-mumbai.g.alchemy.com/v2/abcabcabcabcabcabc"}, code=CALL_EXCEPTION, version=providers/5.7.0) at Logger.makeError (webpack-internal:///(rsc)/./node_modules/@ethersproject/logger/lib.esm/index.js:240:23) at Logger.throwError (webpack-internal:///(rsc)/./node_modules/@ethersproject/logger/lib.esm/index.js:249:20) at checkError (webpack-internal:///(rsc)/./node_modules/@ethersproject/providers/lib.esm/json-rpc-provider.js:103:16) at AlchemyProvider.eval (webpack-internal:///(rsc)/./node_modules/@ethersproject/providers/lib.esm/json-rpc-provider.js:729:24) at Generator.throw (<anonymous>) at rejected (webpack-internal:///(rsc)/./node_modules/@ethersproject/providers/lib.esm/json-rpc-provider.js:34:40) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) { reason: 'missing revert data in call exception; Transaction reverted without a reason string', code: 'CALL_EXCEPTION', data: '0x', transaction: { to: '0xzzzzzzzzzzzzzzzzzzzzzzzzzzzz', data: '0xzzzzzzzzzzzzzzzzzzzzzzzzzzzzz', accessList: null }, error: Error: missing response (requestBody="{\"method\":\"eth_call\",\"params\":[{\"to\":\"0xzzzzzzzzzzzzzzzzzzzzzzzzzzzz\",\"data\":\"0xzzzzzzzzzzzzzzzzzzzzzzzzzzzzz\"},\"latest\"],\"id\":42,\"jsonrpc\":\"2.0\"}", requestMethod="POST", serverError={}, url="https://polygon-mumbai.g.alchemy.com/v2/abcabcabcabcabcabc", code=SERVER_ERROR, version=web/5.7.0) at Logger.makeError (webpack-internal:///(rsc)/./node_modules/@ethersproject/logger/lib.esm/index.js:240:23) at Logger.throwError (webpack-internal:///(rsc)/./node_modules/@ethersproject/logger/lib.esm/index.js:249:20) at eval (webpack-internal:///(rsc)/./node_modules/@ethersproject/web/lib.esm/index.js:259:32) at Generator.throw (<anonymous>) at rejected (webpack-internal:///(rsc)/./node_modules/@ethersproject/web/lib.esm/index.js:31:40) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) { reason: 'missing response', code: 'SERVER_ERROR', requestBody: '{"method":"eth_call","params":[{"to":"0xzzzzzzzzzzzzzzzzzzzzzzzzzzzz","data":"0xzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"},"latest"],"id":42,"jsonrpc":"2.0"}', requestMethod: 'POST', serverError: TypeError: Referrer "client" is not a valid URL. at new Request (node:internal/deps/undici/undici:5361:21) at R (C:\Users\emeri\Documents\GITHUB\JARVIX\jvx-template\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:342062) ... 42 lines matching cause stack trace ... at process.processTicksAndRejections (node:internal/process/task_queues:95:5) { [cause]: [TypeError] }, url: 'https://polygon-mumbai.g.alchemy.com/v2/abcabcabcabcabcabc' } }

@freeslugs
Copy link

here's a simple example of a server method:

export async function GET() {
  const provider = new ethers.providers.JsonRpcProvider(`https://polygon-mumbai.infura.io/v3/${process.env.INFURA_API_KEY}`);
  const price = await provider.getGasPrice();
  return NextResponse.json({ message: 'we are live.' });
}

throws an error

Error: could not detect network (event="noNetwork", code=NETWORK_ERROR, version=providers/5.7.2)
    at Logger.makeError (webpack-internal:///(rsc)/./node_modules/@ethersproject/logger/lib.esm/index.js:240:23)
    at Logger.throwError (webpack-internal:///(rsc)/./node_modules/@ethersproject/logger/lib.esm/index.js:249:20)
    at JsonRpcProvider.eval (webpack-internal:///(rsc)/./node_modules/@ethersproject/providers/lib.esm/json-rpc-provider.js:513:27)
    at Generator.throw (<anonymous>)
    at rejected (webpack-internal:///(rsc)/./node_modules/@ethersproject/providers/lib.esm/json-rpc-provider.js:34:40)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:538:9)
    at process.processTimers (node:internal/timers:512:7) {
  reason: 'could not detect network',
  code: 'NETWORK_ERROR',
  event: 'noNetwork'

using ethers 5.7.2

@ricmoo
Copy link
Member

ricmoo commented Jan 15, 2024

@tazous Yoir error seems unrelated. The contract you are calling returned 0x which means the service is working fine, but the call returned bad data. This most often happens when the the contract address is incorrect, the contract isn’t deployed yet (such as calling a method before waiting for the contract in a test case before waiting for the deployment tx to be mined) or the correct address is used, but on the wrong chain.

There can be other reasons you get this, but those are the most common.

@ricmoo
Copy link
Member

ricmoo commented Jan 15, 2024

@freeslugs can you verify using console.log(process.env.INFURA_API_KEY) that your environment variable is correct?

I see this type of problem often, which is that the dotenv (or such) is not being configured in the environment correctly, which results in the URL becoming malformed.

@tazous
Copy link

tazous commented Jan 15, 2024

@ricmoo
On my side, the contract call is working fine when using nextjs 13 and once switching to nextjs 14, I get this error with the exact same call, that's why I suspect it to be a related error... (I get the 'no network' error when using jsonrcp as the others, and the 'Referrer "client" is not a valid URL' error when using alchemy provider and everything is back to normal if I switch back to nextjs13)

And to go further in that direction, after upgrading to ethers v6+ (with all the migration implied), my same code is finally working fine on nextjs 14... I think all this points to a compatibility issue between ethers 5.7 and nextjs 14

@freeslugs
Copy link

@freeslugs can you verify using console.log(process.env.INFURA_API_KEY) that your environment variable is correct?

I see this type of problem often, which is that the dotenv (or such) is not being configured in the environment correctly, which results in the URL becoming malformed.

Yah it works. My solution was to switch to viem. API is relatively similar :)

const provider = createPublicClient({
      chain: polygonMumbai,
      transport: http(`https://polygon-mumbai.infura.io/v3/${process.env.INFURA_API_KEY}`),
    });

@ricmoo
Copy link
Member

ricmoo commented Jan 15, 2024

@tazous Thanks for the info! Glad to hear NextJS 14 works fine with v6.

If you figure out any extra info on why v5 is affected, let me know as I am planning a small number of changes to port back to v5. :)

@mrbasado
Copy link

I'm affected by this as well. next@14 leads to the no network error w/ ethers5 when called serverside in app/api/**/*.ts
const provider = new ethers.providers.JsonRpcBatchProvider(RPC_URL); console.log(await provider.getNetwork()); . next@13.5 downgrade allows it to work with ethers5

@ricmoo
Copy link
Member

ricmoo commented Jan 15, 2024

@mrbasado Can you provide any additional details? Can someone provide me a minimal NextJS 14 and ethers v5 reproduction steps? Like possibly a single page app?

@freeslugs
Copy link

@mrbasado Can you provide any additional details? Can someone provide me a minimal NextJS 14 and ethers v5 reproduction steps? Like possibly a single page app?

Try mine :) #4469 (comment)

@mrbasado
Copy link

@ricmoo Thank you for looking. here is a quick demo: https://github.com/mrbasado/next14-ethers5
@freeslugs let me know if this covers your use-case as well.

@mrbasado
Copy link

@ricmoo We are still impacted by this issue. let me know if you need any clarification on the example - hopefully the readme covers it!

@MichaelBorde
Copy link

MichaelBorde commented Feb 7, 2024

If you have a direct access to JsonRpcProvider construction you can pass an instance of ConnectionInfo.
Then you can either use skipFetchSetup to avoid setting referrer to "client" or provide your own referrer with fetchOptions.

new JsonRpcProvider({
      fetchOptions: {
        referrer: "https://myapp.xyz",
      },
      url: 'rpcurl'
    })

new JsonRpcProvider({
      skipFetchSetup: true,
      url: 'rpcurl'
    })

The related code is here: https://github.com/ethers-io/ethers.js/blob/v5.7.2/packages/web/lib.esm/geturl.js#L22

@Man-Jain
Copy link

Man-Jain commented Feb 9, 2024

Happened to me as well setting the referrer seems to be the solution. Thanks to @MichaelBorde

@ChiuMungZitAlexander
Copy link

ChiuMungZitAlexander commented Feb 20, 2024

This error only occurs using nextjs14 but not nextjs13 page route, despite ethers.js version.

@vincent38wargnier
Copy link

vincent38wargnier commented Feb 20, 2024

Ether v6 has more issues like [TypeError: Cannot read properties of undefined (reading 'JsonRpcProvider')](https://ethereum.stackexchange.com/questions/144451/typeerror-cannot-read-properties-of-undefined-reading-jsonrpcprovider)

How do you manage that with nextjs 14?

I tried to run it with nextjs13 with AppDir, still the same error. It only works in server side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
investigate Under investigation and may be a bug. v5 Issues regarding legacy-v5
Projects
None yet
Development

No branches or pull requests