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

Cosmjs incompatibility with ES2018 #1144

Closed
giorgionocera opened this issue May 13, 2022 · 26 comments
Closed

Cosmjs incompatibility with ES2018 #1144

giorgionocera opened this issue May 13, 2022 · 26 comments

Comments

@giorgionocera
Copy link

Hi everyone, I'm trying to create a new rn project including cosmjs. After the inclusion, if I try to use part of the packages included on cosmjs all works like a charm. However, if I try to import the tendermint-rpc package or the stargate one, the inclusion fails.
Giving a few debugging, I saw that the issue is linked to BigInt, which is on this repo, included as a native call (since it is available from ES10).

ReferenceError: Can't find variable: BigInt

Maybe I'm missing something. Is there anyone who could help in including and using cosmjs (fully) inside a React Native project?


Useful information

React native version: 0.68.2
Tested with both cosmjs version: 0.24.0-alpha.25 and latest

Thank you.

@webmaster128
Copy link
Member

Could you provide all error output you can get using the latest CosmJS release? As far as I can tell, we don't use BigInt/bigint directly. It might be a dependency though.

@EnricoBarbieri1997
Copy link

EnricoBarbieri1997 commented May 13, 2022

I have the same issue. The full error is:

ReferenceError: Can't find variable: BigInt
Android Running app on Android SDK built for x86
Invariant Violation: "main" has not been registered. This can happen if:
* Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
* A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called. 

And I think it could be (but I'm not sure) a dependency because the only place I could find BigInt is the .pnp.cjs file at root generated by yarn.
Maybe the package using it has a fallback compatibility mode and the library just needs to be compiled for both environment (the one supporting BigInt and the one that does not).

@webmaster128
Copy link
Member

Is there a way to get a stacktrace for the error "ReferenceError: Can't find variable: BigInt"?

@EnricoBarbieri1997
Copy link

At least for me that's the full console log from application start. I have to mention that it happens on the stargate branch of the library. proto-sign for examples works (with rn-nodeify) just fine.

@EnricoBarbieri1997
Copy link

I've create a new React Native 0.64.3 project and installed @cosmjs/stargate and @cosmjs/proto-signing (strangely on latest RN version it fails to compile because some dependencies still use compile instead of implements on android). Both cosmjs packages are ^0.28.4 version. By try and catch and printing the exception I managed to get:
[ReferenceError: Can't find variable: BigInt]

{
  "line": 152249,
  "column": 48,
  "sourceURL": "http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true"
}

And finally:

digestInto@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:152249:48
digest@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:152261:24
deriveChecksumBits@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:151444:67
mnemonicToEntropy@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:151507:41
EnglishMnemonic@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:151541:24
fromMnemonic$@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:150634:105
tryCatch@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:7667:23
invoke@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:7837:32
tryCatch@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:7667:23
invoke@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:7739:30
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:7769:19
tryCallTwo@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:28544:9
doResolve@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:28708:25
Promise@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:28567:14
callInvokeWithMethodAndArg@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:7768:33
enqueue@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:7773:157
async@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:7788:69
balance$
tryCatch@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:7667:23
invoke@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:7837:32
tryCatch@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:7667:23
invoke@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:7739:30
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:7769:19
tryCallTwo@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:28544:9
doResolve@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:28708:25
Promise@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:28567:14
callInvokeWithMethodAndArg@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:7768:33
enqueue@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:7773:157
async@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:7788:69
Section
renderWithHooks@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:16433:33
updateFunctionComponent@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:18441:41
beginWork$1@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:23441:29
performUnitOfWork@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:22519:29
workLoopSync@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:22464:28
renderRootSync@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:22437:25
performSyncWorkOnRoot@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:22199:38
performSyncWorkOnRoot@[native code]
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:13473:40
unstable_runWithPriority@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:54359:30
flushSyncCallbackQueueImpl@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:13468:30
flushSyncCallbackQueue@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:13457:35
flushSync@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:22269:35
scheduleRefresh@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:23853:20
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:53293:38
forEach@[native code]
performReactRefresh@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:53285:31
performReactRefresh@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:53090:48
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:503:40
_callTimer@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:29052:17
callTimers@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:29261:19
__callFunction@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:3234:36
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:2958:31
__guard@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:3185:15
callFunctionReturnFlushedQueue@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.flipper_debug&modulesOnly=false&runModule=true:2957:21
callFunctionReturnFlushedQueue@[native code]

@webmaster128
Copy link
Member

webmaster128 commented May 16, 2022

Thanks. I don't see anything helpful in the logs. Don't know where the error is coming from.

Any change you get bigint support in React Native? Looking at #1133 we probably have to use bigint numbers in some APIs soon in order to represent uint64.

@EnricoBarbieri1997
Copy link

I think that we are going to get them eventually so going forward I don't see any problem with starting to use BigInt but as we don't know when we should fix that in this version first. I will investigate the problem further and get back to you

@webmaster128
Copy link
Member

Maybe you can create a Webpack debug bundle, this contains all dependency code in one file. Thenuse text search for bigint/BigInt.

@EnricoBarbieri1997
Copy link

I did a build with this project
BigInt is indeed there. Mostly from @noble/hashes but even in buffer (npm i buffer, not the native node module) and get-intrinsic (which is used in has-property-descriptors <- define-properties <- globalthis).
I will check if there's a way in webpack, babel or directly in this libraries to build with compatibility < ES11

@webmaster128
Copy link
Member

Very interesting, thank you. I was not aware of those usages. Seems like we reached the point where bigint support became a requirement for CosmJS when we migrated to @noble/hashes.

In buffer, this is only needed for the BigInt APIs and is in there for 2 years now: feross/buffer#267. But this code is not necessarily executed.

@EnricoBarbieri1997
Copy link

In which version did that happen?

@giorgionocera
Copy link
Author

@EnricoBarbieri1997
Copy link

I found out that it is being used even in @confio/ics23 as a dependency and @confio/ics23 is a @cosmjs/stargate dependency. I think that part of the code is used as I have the same problem (BigInt variable not defined) in the 0.24.1 version that shouldn't be using @noble/hash directly.
BigInt is used in this commit for the first time cosmos/ics23@ac777dd but not in this one cosmos/ics23@e0d9fa4.
I don't know if the library at that point in time is compatible with comsjs needs. What are you using it for? Can you check?
Using 0.27.1 like @giorgionocera pointed out could be feasible if a @confio/ics23 version previous to the one above match your needs.

@webmaster128
Copy link
Member

Right, I migrated to @noble/hashes in @confio/ics23 because this avoids pulling in all kind of very old node hashing libraries that caused issues with WebPack 5. You can probably pin the version of @confio/ics23 somehow. But this is only a very short term solution.

@EnricoBarbieri1997
Copy link

We could try to build a version of @noble/hashes compatible with ES < 11 using https://www.npmjs.com/package/babel-plugin-transform-bigint and ship them both and so on up until @cosmjs/stargate and @cosmjs/crypto. As in the future we are going to drop ES < 11 compatibility we could:

  1. Fix it in this version and dropping it the next (not that fancy)
  2. Fork the last stable version and keep it there for a React Native compatible version.

Anyway for both we have to test @noble/hashes builded with the above babel transformer

@EnricoBarbieri1997
Copy link

But looking back to cosmjs main page it says "Our current Javascript target standard is ES2018" so we should fix it in the main version. Upgrading the target standard from 2018 to 2020 seems a big jump all together. Either recompile from @noble/hashes up using the babel transform or reverting to the previously used (or a new one) hashing library. This is indeed not even an issue related with React Native itself is just that the supported ES standard is different from the supposed officially supported standard.
Capture

@giorgionocera giorgionocera changed the title Usage of cosmjs in a React Native Project Cosmjs incompatibility with ES2018 May 20, 2022
@webmaster128
Copy link
Member

webmaster128 commented May 23, 2022

The issue with bigint and ES2018 is that TypeScript does not transpile the usage of native bigint to an alternative implementation as it does with other language features. So you either have to provide a polyfill or not use them. We did the later until recently when it slipped in via the new hashing implemention @noble/hashes.

Honestly, bigint is around for 4 years now and I don't think we can go back from here without making significant sacrifices wrt. productivity and code quality.

@WuChenDi
Copy link

@giorgionocera Hello, how to introduce all this package?

@xiaohei-L
Copy link

xiaohei-L commented Jun 10, 2022

@giorgionocera Hey man, could you provide a demo that rn uses part of the packages included on cosmjs and it works well. THX! I cannot run rn with cosmjs.

@giorgionocera
Copy link
Author

Hello, we created a fork of cosmjs called cosmjs-rn that you can find here working with version 0.27.1.
Moreover, we published its build on npm and you can install it by looking for @cosmjs.rn.

To use it, you have to install and run rn-nodeify (https://www.npmjs.com/package/rn-nodeify).
If you are using expo this requires ejecting the android/ios project and in the android project case even running jetifier.
Using expo for this kind of project is not recommended.

To recap:

  1. Install packages from @cosmjs-rn and not @cosmjs
  2. Install rn-nodeify as dev dependency (yarn add -D rn-nodeify or npm i -D rn-nodeify). If you are using expo use yarn (here, if you are using expo, eject native projects and install jetifier)
  3. npx rn-nodeify --install --hack
  4. In App.tsx (or index.tsx) add import "./shim.js"
  5. Uncomment require('crypto') from shim.js
  6. jetify
  7. yarn android / yarn ios

Every time you install a package you have to delete yarn.lock and do

  1. npx rn-nodeify --install --hack
  2. jetify
  3. yarn android or yarn ios

@WuChenDi
Copy link

Hello, we created a fork of cosmjs called cosmjs-rn that you can find here working with version 0.27.1. Moreover, we published its build on npm and you can install it by looking for @cosmjs.rn.

To use it, you have to install and run rn-nodeify (https://www.npmjs.com/package/rn-nodeify). If you are using expo this requires ejecting the android/ios project and in the android project case even running jetifier. Using expo for this kind of project is not recommended.

To recap:

  1. Install packages from @cosmjs-rn and not @cosmjs
  2. Install rn-nodeify as dev dependency (yarn add -D rn-nodeify or npm i -D rn-nodeify). If you are using expo use yarn (here, if you are using expo, eject native projects and install jetifier)
  3. npx rn-nodeify --install --hack
  4. In App.tsx (or index.tsx) add import "./shim.js"
  5. Uncomment require('crypto') from shim.js
  6. jetify
  7. yarn android / yarn ios

Every time you install a package you have to delete yarn.lock and do

  1. npx rn-nodeify --install --hack
  2. jetify
  3. yarn android or yarn ios

@giorgionocera I'll try, thanks for the reply

@webmaster128
Copy link
Member

webmaster128 commented Jun 29, 2022

Starting with CosmJS 0.29, we'll use BigInt in places where values exceed the safe integer range of number (#1187). Soon the generated types from proto files will follow. So all effort towards making BigInt available in your build system is spent well.

@cnotethegr8
Copy link

I encountered this issue as well, but not from React native.

Sentry provided me with an issue from a user on iOS 12. The user accessed my site from Mobile Safari version 12.1. We can see here that Mobile Safari doesn't support BigInt until iOS 14.

To make debugging easier, we can see that Chrome started support on version 67. So I went here and downloaded an older version of Chromium (version 65).

This allowed me to reproduce the issue and get improved logs.

Uncaught ReferenceError: BigInt is not defined
    at eval (VM26465 _u64.js:4)
    at Object../node_modules/@noble/hashes/_u64.js (_app.js?ts=1666241995592:6408)
    at Object.options.factory (webpack.js?ts=1666241995592:698)
    at __webpack_require__ (webpack.js?ts=1666241995592:37)
    at fn (webpack.js?ts=1666241995592:353)
    at eval (VM26463 sha512.js:5)
    at Object../node_modules/@noble/hashes/sha512.js (_app.js?ts=1666241995592:6485)
    at Object.options.factory (webpack.js?ts=1666241995592:698)
    at __webpack_require__ (webpack.js?ts=1666241995592:37)
    at fn (webpack.js?ts=1666241995592:353)
    at eval (VM26450 pbkdf2.js:29)
    at Object../node_modules/@cosmjs/crypto/build/pbkdf2.js (_app.js?ts=1666241995592:150)
    at Object.options.factory (webpack.js?ts=1666241995592:698)
    at __webpack_require__ (webpack.js?ts=1666241995592:37)
    at fn (webpack.js?ts=1666241995592:353)
    at eval (VM26449 bip39.js:5)
    at Object../node_modules/@cosmjs/crypto/build/bip39.js (_app.js?ts=1666241995592:95)
    at Object.options.factory (webpack.js?ts=1666241995592:698)
    at __webpack_require__ (webpack.js?ts=1666241995592:37)
    at fn (webpack.js?ts=1666241995592:353)
    at eval (VM26448 index.js:4)
    at Object../node_modules/@cosmjs/crypto/build/index.js (_app.js?ts=1666241995592:117)
    at Object.options.factory (webpack.js?ts=1666241995592:698)
    at __webpack_require__ (webpack.js?ts=1666241995592:37)
    at fn (webpack.js?ts=1666241995592:353)
    at eval (VM26447 addresses.js:5)

We can see that @cosmjs uses @noble/hashes/_u64.js which sure enough calls BigInt.

The range of users potentially effected by this is far greater than just React native.
Is there any plan to move forward with a fix?

@webmaster128
Copy link
Member

I see, that's unfortunate. But given the resource constraints and the requirement to move forward my the ecosystem, I don't see how we can maintain this library without BigInt mid term. We need integers that exceed the 53 bit range all over the place. The usage of Long causes problems for other users. The migration to @noble/hashes was a great improvement for getting rid of legazy modules.

I think the way to go would be a JavaScript transpiler that replaces the usages of native BigInt with a library that implements it for older systems.

@DavideSegullo
Copy link
Contributor

Hi there,
after the release of RN 0.70.0, they added support to BigInt in Hermes.
Now it is also possible to use the latest releases of CosmJS, to facilitate the creation of an RN project with CosmJS, I have created a template for the react-native CLI.

It is obviously an open source template! You all can use it, and, most importantly, can contribute in improving it!

@webmaster128
Copy link
Member

From CosmJS 0.30.0 onwards we target es2020 and make use of BigInt in more and more places. Happy to hear that there are solutins emerging for the React Native ecosystem.

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

7 participants