dnt icon indicating copy to clipboard operation
dnt copied to clipboard

Error: no secure random source avaialble (crypto.getRandomValues)

Open brickpop opened this issue 3 years ago • 8 comments

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!

brickpop avatar Jul 08 '22 16:07 brickpop

For reference, the build config is:

await build({
  entryPoints: ["./mod.ts"],
  outDir: "./npm",
  shims: {
    deno: true,
  },
  package: {
    name: "eth-test",
    version: Deno.args[0],
    ...
  },
});

brickpop avatar Jul 08 '22 16:07 brickpop

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.

kitsonk avatar Jul 16 '22 22:07 kitsonk

@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.

dsherret avatar Jul 21 '22 16:07 dsherret

@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?

brickpop avatar Jul 23 '22 20:07 brickpop

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 script code 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!

brickpop avatar Jul 23 '22 20:07 brickpop

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 avatar Jul 26 '22 22:07 kitsonk

@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.

brickpop avatar Aug 05 '22 16:08 brickpop

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).

kitsonk avatar Aug 05 '22 22:08 kitsonk