Issue with crypto library with Next.Js
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?
@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() ?
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.
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 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 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.
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.
Yes, the *-target-bundler package doesn't expose init, assuming that the build system will handle .wasm file via its plugins.
I shall check the compatibility of the latest https://jsr.io/@iroha/[email protected] with Next.js.