iroha-javascript icon indicating copy to clipboard operation
iroha-javascript copied to clipboard

Issue with crypto library with Next.Js

Open matisalimbene opened this issue 1 year ago • 7 comments

I'm working on a Next.Js app, trying to display realtime information following the sample in (https://hyperledger.github.io/iroha-2-docs/guide/get-started/javascript.html#_8-visualizing-outputs-in-web-ui).

Im using CommonJS, this is my code to initialize the crypto library:

// lib/crypto.js or lib/crypto.ts
import { crypto, init } from "@iroha2/crypto-target-web";

let isInitialized = false;

async function initCrypto() {
  if (!isInitialized) {
    console.log("initializing crypto...");
    await init();
    isInitialized = true;
  }
}

// Initialize crypto immediately
initCrypto();

export { crypto };

but when start the app, I get this error:

 ⨯ unhandledRejection: TypeError: Failed to parse URL from /_next/static/media/iroha_crypto_bg.8bf5c350.wasm
    at Object.fetch (node:internal/deps/undici/undici:11576:11)
    at async init (webpack-internal:///(ssr)/./node_modules/@iroha2/crypto-target-web/dist/wasm-pkg/iroha_crypto.js:1558:45)
    at async initCrypto (webpack-internal:///(ssr)/./app/src/crypto.js:12:9) {
  [cause]: TypeError [ERR_INVALID_URL]: Invalid URL
      at new NodeError (node:internal/errors:405:5)
      at new URL (node:internal/url:611:13)
      at new Request (node:internal/deps/undici/undici:7132:25)
      at fetch2 (node:internal/deps/undici/undici:10715:25)
      at Object.fetch (node:internal/deps/undici/undici:11574:18)
      at fetch (node:internal/process/pre_execution:229:25)
      at doOriginalFetch (webpack-internal:///(rsc)/./node_modules/next/dist/server/lib/patch-fetch.js:440:24)
      at eval (webpack-internal:///(rsc)/./node_modules/next/dist/server/lib/patch-fetch.js:589:24)
      at async init (webpack-internal:///(ssr)/./node_modules/@iroha2/crypto-target-web/dist/wasm-pkg/iroha_crypto.js:1558:45)
      at async initCrypto (webpack-internal:///(ssr)/./app/src/crypto.js:12:9) {
    input: '/_next/static/media/iroha_crypto_bg.8bf5c350.wasm',
    code: 'ERR_INVALID_URL'
  }
}

The init is failing so the crypto module fails to load. Any ideas?

matisalimbene avatar Jun 28 '24 17:06 matisalimbene

@smooth55dev Now I’m getting:

Error initializing crypto: TypeError: WebAssembly.instantiate(): Argument 0 must be a buffer source
    at load (webpack-internal:///(ssr)/./node_modules/@iroha2/crypto-target-web/dist/wasm-pkg/iroha_crypto.js:1250:44)
    at init (webpack-internal:///(ssr)/./node_modules/@iroha2/crypto-target-web/dist/wasm-pkg/iroha_crypto.js:1558:40)
    at async initCrypto (webpack-internal:///(ssr)/./app/src/crypto.js:14:13)

Is that documented anywhere? I mean, how to pass arguments to init() ?

matisalimbene avatar Jul 01 '24 17:07 matisalimbene

Thanks @smooth55dev for such a thorrow reply. I’ve follow your guidance, but it still doesn’t work. Now with a slightly different message:

Error initializing crypto: TypeError: Failed to parse URL from /wasm/iroha_crypto_bg.8bf5c350.wasm
    at Object.fetch (node:internal/deps/undici/undici:11576:11)
    at async init (webpack-internal:///(ssr)/./node_modules/@iroha2/crypto-target-web/dist/wasm-pkg/iroha_crypto.js:1558:45)
    at async initCrypto (webpack-internal:///(ssr)/./app/src/crypto.js:15:13) {
  [cause]: TypeError [ERR_INVALID_URL]: Invalid URL
      at new NodeError (node:internal/errors:405:5)
      at new URL (node:internal/url:611:13)
      at new Request (node:internal/deps/undici/undici:7132:25)
      at fetch2 (node:internal/deps/undici/undici:10715:25)
      at Object.fetch (node:internal/deps/undici/undici:11574:18)
      at fetch (node:internal/process/pre_execution:229:25)
      at doOriginalFetch (webpack-internal:///(rsc)/./node_modules/next/dist/server/lib/patch-fetch.js:440:24)
      at eval (webpack-internal:///(rsc)/./node_modules/next/dist/server/lib/patch-fetch.js:589:24)
      at async init (webpack-internal:///(ssr)/./node_modules/@iroha2/crypto-target-web/dist/wasm-pkg/iroha_crypto.js:1558:45)
      at async initCrypto (webpack-internal:///(ssr)/./app/src/crypto.js:15:13) {
    input: '/wasm/iroha_crypto_bg.8bf5c350.wasm',
    code: 'ERR_INVALID_URL'
  }
}

I’ve read that for NextJs app, file may not be availble within the .next folder, so I moved the wasm file to the pubic folder. I made sure "/wasm/iroha_crypto_bg.8bf5c350.wasm” is accessible. But it still fails to parse it.

matisalimbene avatar Jul 01 '24 18:07 matisalimbene

Hey @matisalimbene!

That ChatGPT-fellow doesn't have any affiliation with the project.

I have a very limited experience with Next.js, but I guess the issue might be similar to #104. Could you try the workaround mentioned there? (maybe adapting it to Next.js specific syntax).

0x009922 avatar Jul 03 '24 08:07 0x009922

@0x009922 Thanks! I think it may be something related to Next.Js and how it handles WASM. I tried the fix you refer to, but I get:

./app/src/crypto.js
Attempted import error: '@iroha2/crypto-target-web/wasm-pkg/iroha_crypto_bg.wasm?url' does not contain a default export (imported as 'WASM_URL’).

I also tried copying the wasm file in the public next.js folder (used for static assets) and use a relative path to the wasm file, but then I get:

   Creating an optimized production build ...
Failed to compile.

./node_modules/@iroha2/crypto-target-web/dist/wasm-pkg/iroha_crypto_bg.wasm
Module not found: Can't resolve 'wbg'

https://nextjs.org/docs/messages/module-not-found

Import trace for requested module:
./node_modules/@iroha2/crypto-target-web/dist/wasm-pkg/iroha_crypto.js
./node_modules/@iroha2/crypto-target-web/dist/lib.mjs
./app/src/crypto.js
./app/src/client.js
./app/components/StatusComponent.js
./app/page.js


> Build failed because of webpack errors

matisalimbene avatar Jul 03 '24 18:07 matisalimbene

@matisalimbene can you try using @iroha2/crypto-target-bundler instead? It is designed to work with a tool like Webpack, which seems to be used in your case. More on that in wasm-pack docs.

If that doesn't work, then I'll need to investigate and experiment with Nest.js in order to make crypto work.

0x009922 avatar Jul 04 '24 18:07 0x009922

It seems to have different implementation (no init)

npm run build

> [email protected] build
> next build

  ▲ Next.js 14.2.4
  - Environments: .env

   Creating an optimized production build ...
Failed to compile.

./app/src/crypto.js
Attempted import error: 'init' is not exported from '@iroha2/crypto-target-bundler' (imported as 'init').

Import trace for requested module:
./app/src/crypto.js
./app/src/client.js
./app/components/StatusComponent.js
./app/page.js


> Build failed because of webpack errors

i’ll continue to check the link you provided, I’m not that familiar with wasm.

matisalimbene avatar Jul 05 '24 14:07 matisalimbene

Yes, the *-target-bundler package doesn't expose init, assuming that the build system will handle .wasm file via its plugins.

0x009922 avatar Jul 21 '24 22:07 0x009922

I shall check the compatibility of the latest https://jsr.io/@iroha/[email protected] with Next.js.

0x009922 avatar Feb 19 '25 02:02 0x009922