taquito icon indicating copy to clipboard operation
taquito copied to clipboard

sodium.randombytes_buf is not a function

Open mattdesl opened this issue 3 years ago • 32 comments

Description When trying to use the wallet in the frontend with a bundler (tested: parcel, browserify) I can't get the app to work at all. It seems like it's an issue with the way __importStar is working in the ES5/CJS build from beacon-sdk module; it does not pull in the entire libsodium object, but a clone of it with less functions.

Steps To Reproduce Paste this in a new main.js file:

import { TezosToolkit } from "@taquito/taquito";
import { BeaconWallet } from "@taquito/beacon-wallet";

const provider = "https://mainnet.smartpy.io";
const NETWORK = "mainnet";

sync();

async function sync() {
  const wallet = new BeaconWallet({
    name: "MyAwesomeDapp",
  });
}

And create an index.html file:

<body><script src="./main.js"></script></body>

Now run from terminal:

npx parcel main.js --open

In console you will get an error:

TypeError: sodium.crypto_generichash is not a function

EDIT: This is fixed with parcel by adding the following in your app's package.json (not sure if browserslist is really needed, but the rest resolves to ES Module imports instead of CJS outputs).

...
  "browserslist": "last 2 Chrome versions",
  "alias": {
    "@airgap/beacon-sdk": "./node_modules/@airgap/beacon-sdk/dist/esm/index.js",
    "@taquito/beacon-wallet": "./node_modules/@taquito/beacon-wallet/dist/taquito-beacon-wallet.es5.js",
    "@taquito/signer": "./node_modules/@taquito/signer/dist/taquito-signer.es5.js",
    "@taquito/taquito": "./node_modules/@taquito/taquito/dist/taquito.es5.js"
  }
...

mattdesl avatar May 20 '21 08:05 mattdesl

This is most likely related to https://github.com/airgap-it/beacon-sdk/issues/138

Innkst avatar May 20 '21 21:05 Innkst

Confirming that this appears to be a beacon-sdk issue as I get the same results with the taquito-less version (beacon-sdk 2.2.9):

import { DAppClient } from "@airgap/beacon-sdk";

const dAppClient = new DAppClient({ name: "Beacon Docs" });

sync();

async function sync() {
  try {
    console.log("Requesting permissions...");
    const permissions = await dAppClient.requestPermissions();
    console.log("Got permissions:", permissions.address);
  } catch (error) {
    console.log("Got error:", error);
  }
}

I wasn't able to get the package.json aliases to work for me either, so my only solution for now is to roll back taquito to 6.x as that was the last version without this issue:

    "@taquito/beacon-wallet": "^6.4.0-ledger.0",
    "@taquito/taquito": "^6.4.0-ledger.0",

dribnet avatar Jun 17 '21 16:06 dribnet

Just a remark:

  "browserslist": "last 2 Chrome versions",
  "alias": {
    "@airgap/beacon-sdk": "./node_modules/@airgap/beacon-sdk/dist/esm/index.js",
    "@taquito/beacon-wallet": "./node_modules/@taquito/beacon-wallet/dist/taquito-beacon-wallet.es5.js",
    "@taquito/signer": "./node_modules/@taquito/signer/dist/taquito-signer.es5.js",
    "@taquito/taquito": "./node_modules/@taquito/taquito/dist/taquito.es5.js"
  }

did not fix the problem for me ("@taquito/taquito": "^9.2.0", "@taquito/beacon-wallet": "^9.2.0").

This bug should be a failing test and a showstopper.

crcdng avatar Jul 22 '21 21:07 crcdng

same issue with vitejs / sveltekit here

clemsos avatar Oct 13 '21 21:10 clemsos

same issue in a clojurescript project using shadow-cljs build system.

BerkeleyTrue avatar Nov 19 '21 01:11 BerkeleyTrue

Any news ?

CoffeeW-1337 avatar Dec 18 '21 07:12 CoffeeW-1337

Same with vue2 + vite

souljorje avatar Dec 21 '21 18:12 souljorje

I was able to get it to build correctly using the following

    "@airgap/beacon-sdk": "^2.4.0-beta.2",
    "@taquito/beacon-wallet": "^10.2.1",
    "@taquito/taquito": "^10.2.1",

BerkeleyTrue avatar Dec 21 '21 18:12 BerkeleyTrue

@BerkeleyTrue, how did you override @airgap/beacon-sdk version used by @taquito?

souljorje avatar Dec 21 '21 18:12 souljorje

@souljorje I don't remember that being an issue. Here is a link to the code where I create the client and wallet. (warning: clojure ahead)

https://github.com/Trewaters/ACDao/blob/feat-init-app/src/tequito/core.cljs

It worked fine. Although, I didn't get further than connecting a wallet.

BerkeleyTrue avatar Dec 21 '21 19:12 BerkeleyTrue

Vite solution

Setup

"vite": "^2.7.6"
"vue": "^2.6.14"
"@taquito/beacon-wallet": "^9.1.0"
"@taquito/taquito": "^9.1.0"
"@airgap/beacon-sdk": "2.4.0-beta.2"

Also works with @taquito/beacon-wallet@11 & @taquito/taquito@11, but bundles: @taquito/taquito@9: 382.79 KiB @taquito/taquito@11: 560.05 KiB @taquito/beacon-wallet is same.

Steps

  1. Install @airgap/[email protected], and for node polyfills vite-compatible-readable-stream and buffer.

npm i @airgap/[email protected] vite-compatible-readable-stream buffer

  1. Adjust build config and add aliases to vite.config.js
import { defineConfig, mergeConfig } from 'vite';

export default ({ command }) => {
    const isBuild = command === 'build';
	return defineConfig({
		  build: {
            	target: 'esnext',
            	commonjsOptions: {
                	transformMixedEsModules: true,
            	},
          },
		  resolve: {
			  alias: {
				  // dedupe @airgap/beacon-sdk
				  // I almost have no idea why it needs `cjs` on dev and `esm` on build, but this is how it works 🤷‍♂️
				  '@airgap/beacon-sdk': path.resolve(__dirname, `./node_modules/@airgap/beacon-sdk/dist/${isBuild ? 'esm' : 'cjs'}/index.js`),
				  // polyfills
				  'readable-stream': 'vite-compatible-readable-stream',
	               stream: 'vite-compatible-readable-stream',
			  },
		  },
	});
}
  1. Polyfill global & Buffer in index.html
<html>
    <head>
		<script>
            const global = globalThis;
        </script>
        <script type="module">
            import { Buffer } from 'buffer';
            window.Buffer = Buffer;
        </script>
	</head>
	<!-- ... -->
</html>

Voila!

Why da hell it it needs cjs on dev and esm on build... Seems like it's Vite issue, gotta open one there.

P.S. I advice to use dynamic imports for @airgap/beacon-sdk & @taquito stuff to care about your bundle.

Related https://github.com/airgap-it/beacon-sdk/issues/138#issuecomment-974860143 - @airgap/[email protected] https://github.com/vitejs/vite/issues/3817#issuecomment-864450199 - polyfills https://github.com/nodejs/readable-stream/issues/439#issuecomment-940643578 - vite-compatible-readable-stream https://github.com/originjs/vite-plugins/issues/9 - transformMixedEsModules: true

souljorje avatar Dec 22 '21 17:12 souljorje

yes, works on dev but throws on build for me as well. > Uncaught TypeError: Cannot read properties of undefined (reading 'TRANSPORT_P2P_PEERS_DAPP')

clemsos avatar Dec 22 '21 23:12 clemsos

@clemsos check update, now it works 100%!

souljorje avatar Dec 23 '21 07:12 souljorje

@souljorje yes it works ! lifesaver, thx

clemsos avatar Dec 23 '21 14:12 clemsos

@souljorje A lifesaver. I'm getting a isBuild is not defined over here.

kevinelliott avatar Jan 07 '22 22:01 kevinelliott

@souljorje Oops, my error, I didn't see your const definition above. Thanks!

kevinelliott avatar Jan 07 '22 22:01 kevinelliott

Hi, I had same issue. Solution in https://github.com/ecadlabs/taquito/issues/882#issuecomment-999753605 works well, but in case you would like to use stable version of beacon-sdk instead of beta, it can be done as follows:

  1. Install vite-compatible-readable-stream as mentioned in https://github.com/ecadlabs/taquito/issues/882#issuecomment-999753605
  2. download browserified version of from unpkg. For latest it is [email protected].
  3. place it somewhere whitin your project. For me it was src/vendor/walletbeacon.min.js
  4. add resolves to vite.config.js as follows:
import { defineConfig, mergeConfig } from 'vite';

export default ({ command }) => {
	const isBuild = env.command === 'build';
	const devOnlyResolve = isBuild ? {} : {
		"@airgap/beacon-dapp": `./src/vendor/walletbeacon.dapp.min.js`,
	}
	return defineConfig({
                  // ... 
		  resolve: {
			  alias: {
                                  ...devOnlyResolve,
				  // polyfills
				  'readable-stream': 'vite-compatible-readable-stream',
	                           stream: 'vite-compatible-readable-stream',
			  },
		  },
		  // ... 
	});
}

This fixed vite dev setup for me. Build works out of box for me so the resolve is applied only to for dev.

cryi avatar Mar 22 '22 12:03 cryi

I have a working app with Svelte, Vitejs, Taquito, and the Beacon wallet at this address => https://github.com/claudebarde/taquito-bundlers-testing/tree/main/vitejs If you check the repo, you will see that I am still trying to make it work with SvelteKit 😅 I'll post an update here when I manage to make it work!

claudebarde avatar Mar 29 '22 10:03 claudebarde

It looks like I made SvelteKit work! The @airgap/beacon-sdk/ package contains a minified version of the code, so I am using this one in the svelte.config.js file:

import adapter from "@sveltejs/adapter-auto";
import preprocess from "svelte-preprocess";
import path from "path";

/** @type {import('@sveltejs/kit').Config} */
const config = {
  // Consult https://github.com/sveltejs/svelte-preprocess
  // for more information about preprocessors
  preprocess: preprocess(),

  kit: {
    adapter: adapter(),
    vite: {
      resolve: {
        alias: {
          "@airgap/beacon-sdk": path.resolve(
            path.resolve(),
	   `./node_modules/@airgap/beacon-sdk/dist/walletbeacon.min.js`
          ),
          // polyfills
          "readable-stream": "vite-compatible-readable-stream",
          stream: "vite-compatible-readable-stream"
        }
      }
    }
  }
};

export default config;

The dapp builds in dev mode (haven't tested in prod for now) and I was able to send a transaction to a contract on Hangzhounet with this config. If anyone wants to give it a try and report any issue, that would be awesome!

claudebarde avatar Mar 29 '22 10:03 claudebarde

If anyone wants to give it a try and report any issue, that would be awesome!

Yes!! This is the most straight forward way, I can confirm it works in svelte kit!

melMass avatar Apr 05 '22 02:04 melMass

@melMass Have you been able to build the app? I posted my comment before trying to build the app and it doesn't build 😅 First, I get this error message:
SyntaxError: Illegal 'use strict' directive in function with non-simple parameter list (32034:11)
It looks like an issue coming from the Beacon SDK. When I try to remove all the "use strict" from the walletbeacon.min.js file, I get this error: 'DAppClient' is not exported by src/walletbeacon.min.js, imported by node_modules/@taquito/beacon-wallet/dist/taquito-beacon-wallet.es6.js (maybe because the BeaconWallet library doesn't use the minified file but the Node module?) It's very frustrating to be stuck with Webpack or old versions of Svelte to make the Beacon SDK work.

claudebarde avatar Apr 07 '22 08:04 claudebarde

Hi Claude!

It does work indeed! I'm using SvelteKit (no webpack)


import adapter from '@sveltejs/adapter-auto';
import preprocess from 'svelte-preprocess';
import path, { dirname } from 'path'
import { fileURLToPath } from 'url'

const filePath = dirname(fileURLToPath(import.meta.url))
const sassPath = `${filePath}/src/styles/`


/** @type {import('@sveltejs/kit').Config} */
const config = {
	// Consult https://github.com/sveltejs/svelte-preprocess
	// for more information about preprocessors
	preprocess: preprocess({

	}),

	kit: {
		adapter: adapter(),
		vite: {
			resolve: {
				alias: {
					"$styles": path.resolve("./src/styles"),
					"@airgap/beacon-sdk": path.resolve(
						path.resolve(),
						`./node_modules/@airgap/beacon-sdk/dist/walletbeacon.min.js`
					),
					// polyfills
					"readable-stream": "vite-compatible-readable-stream",
					stream: "vite-compatible-readable-stream"
				},
			},
				optimizeDeps: {
					esbuildOptions: {
						define: {
							global: 'globalThis',
							'process': JSON.stringify({
								env: {
									NODE_DEBUG: '',
								}
							}),
						}
					}
				}
			}
		}
	};

	export default config;

melMass avatar Apr 07 '22 10:04 melMass

Right, I added the adapter for Netlify and that's when things went sideways! It looks like it builds properly with the auto adapter, thanks!

claudebarde avatar Apr 07 '22 10:04 claudebarde

Version 3 of the Beacon SDK broke all the workarounds that were found on my side 😬 Anybody noticed the same problem coming back after updating the version of the Beacon SDK/Taquito for Svelte/SvelteKit/ViteJs?

claudebarde avatar May 09 '22 09:05 claudebarde

@claudebarde check my older comment. I edited the code to work with version 3. Or at least it works for me 😄

Just copy walletbeacon.dapp.min.js from @airgap/beacon-dapp/dist/ to your src/vendor and adjust vite config as mentioned in the comment.

cryi avatar May 09 '22 21:05 cryi

@claudebarde some additions to my last https://github.com/ecadlabs/taquito/issues/882#issuecomment-999753605 and it works:

"vite": "^2.9.8"
"@taquito/beacon-wallet": "^13.0.1"
"@taquito/taquito": "^13.0.1"
"@airgap/beacon-sdk": "^3.1.3"
// vite.config.js

import replace from 'rollup-plugin-re';

import { defineConfig, mergeConfig } from 'vite';

export default ({ command }) => {
    const isBuild = command === 'build';
	return defineConfig({
        plugins: [
          {
          ...replace({
            include: ['node_modules/@airgap/**'],
            replaces: {
              /**
               * damn curcus with this beacon-sdk...
               * qr doesn't work on dev, but at least the whole wallet works
               */
              ...isBuild
                ? {
                  "import * as qrcode from 'qrcode-generator';": "import qrcode from 'qrcode-generator';",
                }
                : {
                  'var libsodium_wrappers_1 = require("libsodium-wrappers")': 'var libsodium_wrappers_1 = require("libsodium-wrappers").default',
                },
            },
          }),
          enforce: 'pre',
        },
    ],
	optimizeDeps: {
      include: [
        '@airgap/beacon-sdk',
        '@taquito/beacon-wallet',
        '@taquito/taquito',
      ]
	}
};

related https://github.com/airgap-it/beacon-sdk/pull/345

souljorje avatar Jul 07 '22 18:07 souljorje

@claudebarde some additions to my last #882 (comment) and it works:

"vite": "^2.9.8"
"@taquito/beacon-wallet": "^13.0.1"
"@taquito/taquito": "^13.0.1"
"@airgap/beacon-sdk": "^3.1.3"
// vite.config.js

import replace from 'rollup-plugin-re';

import { defineConfig, mergeConfig } from 'vite';

export default ({ command }) => {
    const isBuild = command === 'build';
	return defineConfig({
        plugins: [
          {
          ...replace({
            include: ['node_modules/@airgap/**'],
            replaces: {
              /**
               * damn curcus with this beacon-sdk...
               * qr doesn't work on dev, but at least the whole wallet works
               */
              ...isBuild
                ? {
                  "import * as qrcode from 'qrcode-generator';": "import qrcode from 'qrcode-generator';",
                }
                : {
                  'var libsodium_wrappers_1 = require("libsodium-wrappers")': 'var libsodium_wrappers_1 = require("libsodium-wrappers").default',
                },
            },
          }),
          enforce: 'pre',
        },
    ],
	optimizeDeps: {
      include: [
        '@airgap/beacon-sdk',
        '@taquito/beacon-wallet',
        '@taquito/taquito',
      ]
	}
};

related airgap-it/beacon-sdk#345

This made wallet work on build, but still can't use it on dev Can you help me out on #1729

itsnamangoyal avatar Jul 08 '22 05:07 itsnamangoyal

I had the same problem in a Remix codebase. Got it working by using require instead of import and by polyfilling Buffer in the client code:

import { Buffer } from 'buffer';

if (typeof document !== 'undefined' && !window.Buffer) {
  window.Buffer = Buffer;
}

const { DAppClient, NetworkType, PermissionScope } = require('@airgap/beacon-sdk');
const { BeaconWallet } = require('@taquito/beacon-wallet');

By using require, the CJS build of beacon-sdk is used, instead of the ESM build.

xat avatar Jul 11 '22 08:07 xat

@xat That looks like a good idea, I will try it with other projects I had problems with, thanks!

claudebarde avatar Jul 11 '22 14:07 claudebarde

@xat In svelte we can't "require" AFAIK 🥲

melMass avatar Jul 11 '22 14:07 melMass