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

React Native fetch JSONRPC throw error "response.arrayBuffer is not a function" #1995

Closed
joshuajiangdev opened this issue Sep 2, 2021 · 6 comments

Comments

@joshuajiangdev
Copy link

joshuajiangdev commented Sep 2, 2021

Note: Not all sections may be relevant, but please be as thorough while remaining concise as possible. Remove this Notice and any sections that don't feel pertinent.

If you are unsure if something is a bug, start a thread in the "discussions" tab above..

Describe the bug
When I try to call getBalance with InfuraProvider in react native, I get error

{
  "reason": "missing response",
  "code": "SERVER_ERROR",
  "requestBody": "{\"method\":\"eth_getBalance\",\"params\":[\"0xac8448bfa4a7c83f2406555a3e0f6c9c340d9daf\",\"latest\"],\"id\":42,\"jsonrpc\":\"2.0\"}",
  "requestMethod": "POST",
  "serverError": {},
  "url": "https://rinkeby.infura.io/v3/xxxxx"
}

More detailed error is:

TypeError: response.arrayBuffer is not a function
    at Object.<anonymous> (browser-geturl.js:63)
    at step (browser-geturl.js:33)
    at Object.next (browser-geturl.js:14)
    at fulfilled (browser-geturl.js:5)
    at tryCallOne (core.js:37)
    at core.js:123
    at JSTimers.js:241
    at _callTimer (JSTimers.js:112)
    at _callImmediatesPass (JSTimers.js:166)
    at MessageQueue.callImmediates [as _immediatesCallback] (JSTimers.js:411)

The response from infura node:

{
   "method":"eth_getBalance",
   "params":[
      "0xac8448bfa4a7c83f2406555a3e0f6c9c340d9daf",
      "latest"
   ],
   "id":42,
   "jsonrpc":"2.0"
}

Reproduction steps

// Import the crypto getRandomValues shim (**BEFORE** the shims)
import 'react-native-get-random-values';

// Import the the ethers shims (**BEFORE** ethers)
import '@ethersproject/shims';

import {ethers} from 'ethers';

const currentProvider = new ethers.providers.StaticJsonRpcProvider(
 'https://rinkeby.infura.io/v3/xxxxxx',
  4,
);

currentProvider.on('debug', e => {
  console.log(e);
});

try {
  const currentBalance = await currentProvider.getBalance(
    '0xAC8448bfA4a7C83f2406555a3E0f6C9c340d9DaF',
  );

  if (currentBalance) {
    console.log(utils.formatEther(currentBalance));
  }
} catch (e) {
  console.log(e);
}

Environment:

"react-native": "0.65.1"
"@ethersproject/shims": "^5.4.0"
"ethers": "^5.4.5"

I'm not using Expo.

The provider is connected to Infura Rinkeby.

Search Terms
#993

@joshuajiangdev joshuajiangdev added the investigate Under investigation and may be a bug. label Sep 2, 2021
@joshuajiangdev
Copy link
Author

Found the issue, it is because "Network inspector" in "React Native Debugger"

@ricmoo ricmoo removed the investigate Under investigation and may be a bug. label Oct 20, 2021
@abdelshok
Copy link

@joshuajiangdev What do you mean "Network inspector" in "React Native Debugger"? My app is running in the simulator without any Debugger and I still seem to get the same error.

[Error: missing response ( requestBody="{\" method\":\"eth_getBlockByNumber\", "params":["latest",false], "id":43, "jsonrpc":"2.0" }", requestMethod="POST", serverError={}, url="https://eth-mainnet.alchemyapi.io/v2/xxx", code=SERVER_ERROR, version=web/5.6.1 )]

@ricmoo
Copy link
Member

ricmoo commented Jun 28, 2022

Make sure you follow the instructions regarding React Native in the docs, as the shims include that object.

https://docs.ethers.io/v5/cookbook/react-native/

@abdelshok
Copy link

@ricmoo ... I'm honestly embarrassed. I spent 7 hours yesterday scouring through 100+ websites and forums implementing various hacks and solutions, including rn-nodeify, various alternatives to the crypto module, and more. Installing @ethersproject/shims solved it in 45 seconds. I owe you much saved time Richard and in a way, since life is only composed of time, I really owe you my life. I have now decided to name my children after you and you shall now be referred to as Richard, the knight from the legends. Farewell my friend.

@ricmoo
Copy link
Member

ricmoo commented Jun 29, 2022

@abdelshok lol! I’m quite flattered, but please check with your partner first; I certainly do not consider such a debugging-frustration-inspired proclamation to be binding. Also, a day of your life is but a mere fraction of your life. I’m sure there are quite a few others that you owe far more than a day of your life to. ;)

But glad I could help.

@nezort11
Copy link

nezort11 commented May 8, 2024

Also had same error response.arrayBuffer is not a function from browser-geturl.js resulting in could not detect network (event="noNetwork", code=NETWORK_ERROR, version=providers/5.0.5) #1316 error , though rpc response is 200.

Importing @ethersproject/shims (using this guide https://docs.ethers.org/v5/cookbook/react-native/#cookbook-reactnative-shims) doesn't solve the issue for me.

  • Android, API 33 (exact same code WORKS on iOS)
  • "react-native": "0.66.0",
  • "ethers": "^5.7.2",
  • "@ethersproject/shims": "^5.7.0",

Minimal code:

import 'react-native-get-random-values';
import '@ethersproject/shims';
import {BigNumber, ethers, utils} from 'ethers';

      const signer = new ethers.Wallet(
        privateKey,
        new ethers.providers.JsonRpcProvider(
          {
            url: 'https://polygon-pokt.nodies.app',
            skipFetchSetup: true,
          },
          {
            name: 'Polygon Mainnet',
            chainId: 137,
          },
        ),
      );

      const address = await signer.getAddress();
      console.log('address', address);

      const balance = await signer.getBalance(); // THROWS ERROR
      console.log('balance', balance);

Working solution:

patch node_modules/@ethersproject/web/lib/browser-geturl.js

// ...
-var bytes_1 = require("@ethersproject/bytes");
+var strings_1 = require("@ethersproject/strings");
// ...
                case 1:
                    response = _a.sent();
-                    return [4 /*yield*/, response.arrayBuffer()];
+                    return [4 /*yield*/, response.text()];
                case 2:
                    body = _a.sent();
                    headers = {};
                    if (response.headers.forEach) {
                        response.headers.forEach(function (value, key) {
                            headers[key.toLowerCase()] = value;
                        });
                    }
                    else {
                        ((response.headers).keys)().forEach(function (key) {
                            headers[key.toLowerCase()] = response.headers.get(key);
                        });
                    }
                    return [2 /*return*/, {
                            headers: headers,
                            statusCode: response.status,
                            statusMessage: response.statusText,
-                            body: (0, bytes_1.arrayify)(new Uint8Array(body)),
+                            body: strings_1.toUtf8Bytes(body),
                        }];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants