ethers-io / ethers.js

Complete Ethereum library and wallet implementation in JavaScript.
https://ethers.org/
MIT License
7.87k stars 1.82k forks source link

Cannot use Wallet.createRandom() in my npm package due to crypto package and SystemRandomSource #4646

Open confxsd opened 5 months ago

confxsd commented 5 months ago

Ethers Version

6.11.1

Search Terms

crypto, SystemRandomSource, randomBytes

Describe the Problem

Hello ethers team,

I am encountering an issue when using the ethers library in a UMD environment that targets both browser and server. The issue relates to the crypto functionality used by the ethers library.

The problem occurs when I try to use Wallet.createRandom(); and the ethers library tries to access Node.js's crypto module functionalities.

I tried polyfill in webpack but it didn't work out.

fallback: { crypto: require.resolve("crypto-browserify"),

Webpack version: 5.90.3 TypeScript version: 4.7.2 Node.js version: 20.4.0

webpack.config.js:

library: {
  type: "umd",
  export: "default",
}

tsconfig.json:

"target": "es2020",
"module": "es2020",

Code Snippet

import { Wallet } from "ethers";

const wallet = Wallet.createRandom();

Contract ABI

No response

Errors

Error: System random byte generator is not available.
    at e.SystemRandomSource.randomBytes (/Users/serhat/Code/index/sdk/dist/index.js:2:8715)
    at o (/Users/serhat/Code/index/sdk/dist/index.js:2:6954)
    at Km.authenticate (/Users/serhat/Code/index/sdk/dist/index.js:2:408205)
    at ev (/Users/serhat/Code/index/sdk/dist/index.js:2:417334)
    at fv.authenticate (/Users/serhat/Code/index/sdk/dist/index.js:2:420990)
    at file:///Users/serhat/Code/index/sdk-demo/index.js:9:11
    at ModuleJob.run (node:internal/modules/esm/module_job:192:25)
    at async DefaultModuleLoader.import (node:internal/modules/esm/loader:228:24)
    at async loadESM (node:internal/process/esm_loader:40:7)
    at async handleMainPromise (node:internal/modules/run_main:66:12)

Environment

node.js (v12 or newer), Browser (Chrome, Safari, etc)

Environment (Other)

No response

ricmoo commented 5 months ago

You should never try to generate a private key on an environment that does not have a secure random source, but the source can be modified:

ethers.randomBytes.register((length) => {
    // Return a Uint8Array of length, filled with your random values
});

Alternatively, when building for the browser, make sure your bundler is picking up the browser versions of the files; there is a crypto-browser file pulled in via the package.json when configured in your bundler, which uses the Web crypto API.

Does that make sense?