Error: no secure random source avaialble (crypto.getRandomValues)
Hi and thank you for the wonderful project!
Trying to compile the following:
import { Wallet } from "https://cdn.skypack.dev/@ethersproject/wallet";
const w = Wallet.createRandom();
// ...
Compilation will work but execution will fail because this NPM library attempts to detect whether window.crypto.getRandomBytes() or require("crypto").randomBytes is to be used and freaks out.
# Executing the artifact with Node
> node npm/script/mod.js
WARNING: Missing strong random number source
Generating wallet
/var/home/user/dev/tests/dnt/npm/script/deps/cdn.skypack.dev/-/@ethersproject/[email protected]/dist=es2019,mode=imports/optimized/@ethersproject/logger.js:175
throw this.makeError(message, code, params);
^
Error: no secure random source avaialble (operation="crypto.getRandomValues", code=UNSUPPORTED_OPERATION, version=random/5.6.1)
at Logger.makeError (/var/home/user/dev/tests/dnt/npm/script/deps/cdn.skypack.dev/-/@ethersproject/[email protected]/dist=es2019,mode=imports/optimized/@ethersproject/logger.js:166:23)
at Logger.throwError (/var/home/user/dev/tests/dnt/npm/script/deps/cdn.skypack.dev/-/@ethersproject/[email protected]/dist=es2019,mode=imports/optimized/@ethersproject/logger.js:175:20)
at Object.getRandomValues (/var/home/user/dev/tests/dnt/npm/script/deps/cdn.skypack.dev/-/@ethersproject/[email protected]/dist=es2019,mode=imports/optimized/@ethersproject/random.js:51:28)
at randomBytes (/var/home/user/dev/tests/dnt/npm/script/deps/cdn.skypack.dev/-/@ethersproject/[email protected]/dist=es2019,mode=imports/optimized/@ethersproject/random.js:62:12)
at Function.createRandom (/var/home/user/dev/tests/dnt/npm/script/deps/cdn.skypack.dev/-/@ethersproject/[email protected]/dist=es2019,mode=imports/optimized/@ethersproject/wallet.js:166:51)
at Object.<anonymous> (/var/home/user/dev/tests/dnt/npm/script/mod.js:30:30)
at Module._compile (node:internal/modules/cjs/loader:1105:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12) {
reason: 'no secure random source avaialble',
code: 'UNSUPPORTED_OPERATION',
operation: 'crypto.getRandomValues'
}
Thank you!
For reference, the build config is:
await build({
entryPoints: ["./mod.ts"],
outDir: "./npm",
shims: {
deno: true,
},
package: {
name: "eth-test",
version: Deno.args[0],
...
},
});
Can you try to add:
{
shims: {
custom: {
package: "crypto/webcrypto",
globalNames: ["crypto. getRandomValues"]
}
}
}
I am not entirely sure it will work, but it would be a start in the right direction.
@brickpop in this scenario, you could use a "specifier to npm package" mapping.
https://github.com/denoland/dnt#specifier-to-npm-package-mappings
That said, since this is using skypack, I believe changing the specifier https://cdn.skypack.dev/@ethersproject/wallet to include the version (ex. https://cdn.skypack.dev/@ethersproject/[email protected]) will cause that to happen automatically.
I looked at the source that was causing the issue and I believe it would be hard for dnt to figure out how to handle that.
@kitsonk didn't work. Tried several variants but compilation kept failing, didn't recognize package, etc.
Adding the Skypack explicit version to the URL as suggested by @dsherret did the trick, thank you! :sparkle:
import { Wallet } from "https://cdn.skypack.dev/@ethersproject/[email protected]";
I wonder if it would be useful to have a section on the readme including common workarounds for Node/Browser quirks without an explicit shim?
I'm still facing another error, but I assume this should land on a different issue?
- Running the original file with Deno works as expected.
- Running the compiled
scriptcode from Node works too. - However, running the ESM artifact (
npm/esm/mod.js) with Deno fails:
> deno run npm/esm/mod.js
error: Relative import path "@deno/shim-deno" not prefixed with / or ./ or ../
at file:///home/user/dev/tests/dnt/npm/esm/_dnt.shims.js:2:22
The head of the offending file looks like:
import { Deno } from "@deno/shim-deno";
export { Deno } from "@deno/shim-deno"; // << Fails here
import { TextEncoder, TextDecoder } from "util";
export { TextEncoder, TextDecoder } from "util";
I can create a separate issue if this is unrelated Thank you!
Why do you expect the npm/esm/mod.js to run under Deno? It has been transformed to work under Node.js, not under Deno.
@kitsonk the script build folder definitely works with Node, but the esm build folder is meant to work on ESM compatible environments like web browsers or Deno itself.
It's not a big deal, on Deno you can always target the original URL but NPM packages are meant to bundle both Node and ESM versions of the same codebase.
But npm/esm/mod.js does work under esm compatible environments which support Node.js module resolution (which is basically Node.js). In order to get it work again in Deno (or a browser for example), you would need to use an import map, or using a further bundling tool (which is usually what is done to get ESM Node.js code to run in a browser or Deno).