React-native Solana

import Web3Auth from '@web3auth/modal';
import { CHAIN_NAMESPACES, IProvider, WEB3AUTH_NETWORK } from '@web3auth/base';
import SolanaPrivateKeyProvider from '@web3auth/solana-provider';

whenever I put this in code, it pops out

Error: undefined Unable to resolve module crypto from /Users/jhinresh/Desktop/Recivo_wallet/node_modules/@web3auth/base-provider/node_modules/@toruslabs/eccrypto/dist/eccrypto.cjs.js: crypto could not be found within the project or in these directories:
  node_modules/@web3auth/base-provider/node_modules
  node_modules
  ../../node_modules

Especially

import Web3Auth from '@web3auth/modal';
import SolanaPrivateKeyProvider from '@web3auth/solana-provider';

I have taken a look into the troubleshooting, put polyfills file, adjusted metro.config.js and add globals.js, still not sure what i missed.

Hi @mynameisjerry870203,

I hope you are doing okay! Did you follow our guide to add polyfills? Bundler Polyfill Issues - React Native Metro | Documentation | Web3Auth

Also, you can check out our React Native examples: web3auth-pnp-examples/react-native at main · Web3Auth/web3auth-pnp-examples · GitHub.

Please contact me again if the problem persists.

'"@web3auth/react-native-sdk"' has no exported member named 'Web3Auth'.
Did you mean ‘IWeb3Auth’?
Is this even a normal problem

I’m trying to put it in my login screen, and this is my codes look like.

import 'react-native-get-random-values';
import './polyfills'; 

import React, { useEffect, useState } from 'react';
import { Button, View, Text, StyleSheet, Alert } from 'react-native';
import { Web3Auth } from '@web3auth/react-native-sdk';
import { Connection, PublicKey, clusterApiUrl } from '@solana/web3.js';
import { Buffer } from 'buffer';

global.Buffer = Buffer;

const clientId = 'BA4vkq_c_YC6o9F6hRkEnipqI2hk8LM5rHhTjApkCIzw3VE6hEwxbhdjLybHVLHTLa_3RZzsZpgZ5phhHx25rGk'; // 替換成你的 Web3Auth 客戶端 ID

const App: React.FC = () => {
  const [user, setUser] = useState<any>(null);
  const [balance, setBalance] = useState<number | null>(null);
  const [web3auth, setWeb3auth] = useState<Web3Auth | null>(null);

  useEffect(() => {
    const initWeb3Auth = async () => {
      try {
        const web3auth = new Web3Auth({
          clientId: clientId,
          chainConfig: { chainNamespace: 'solana' },
        });
        await web3auth.initModal();
        setWeb3auth(web3auth);
      } catch (error) {
        console.error('Web3Auth Initialization Error:', error);
      }
    };

    initWeb3Auth();
  }, []);

  const login = async () => {
    if (!web3auth) return;
    try {
      const provider = await web3auth.connect();
      setUser(provider);
      fetchBalance(provider.publicKey);
      Alert.alert('Login Successful');
    } catch (error) {
      console.error('Login Error:', error);
    }
  };

  const fetchBalance = async (publicKeyString: string) => {
    const connection = new Connection(clusterApiUrl('testnet'), 'confirmed');
    const publicKey = new PublicKey(publicKeyString);
    const balance = await connection.getBalance(publicKey);
    setBalance(balance / 1e9); 
  };

  // const logout = async () => {
  //   if (!web3auth) return;
  //   try {
  //     await web3auth.logout();
  //     setUser(null);
  //     setBalance(null);
  //     Alert.alert('Logout Successful');
  //   } catch (error) {
  //     console.error('Logout Error:', error);
  //   }
  // };

  return (
    <View style={styles.container}>
      {user ? (
        <>
          <Text>Logged in as: {user.userInfo.email}</Text>
          <Text>Public Key: {user.publicKey}</Text>
          <Text>Balance: {balance} SOL</Text>
          {/* <Button title="Logout" onPress={logout} /> */}
        </>
      ) : (
        <Button title="Login" onPress={login} />
      )}
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    padding: 20,
  },
});

export default App;

Hey @mynameisjerry870203,

I don’t think you need to import a polyfill file directly in App.tsx. Instead, we handle polyfilling within the metro.config.js file and use a globals.js file, which is imported into App.tsx. Here’s how your metro.config.js should look, assuming you are working on a Bare React Native App:

const { getDefaultConfig, mergeConfig } = require("@react-native/metro-config");

const defaultConfig = getDefaultConfig(__dirname);

const config = {
  resolver: {
    extraNodeModules: {
      assert: require.resolve("empty-module"), // assert can be polyfilled here if needed
      http: require.resolve("empty-module"), // stream-http can be polyfilled here if needed
      https: require.resolve("empty-module"), // https-browserify can be polyfilled here if needed
      os: require.resolve("empty-module"), // os-browserify can be polyfilled here if needed
      url: require.resolve("empty-module"), // url can be polyfilled here if needed
      zlib: require.resolve("empty-module"), // browserify-zlib can be polyfilled here if needed
      path: require.resolve("empty-module"),
      crypto: require.resolve("crypto-browserify"),
      stream: require.resolve("readable-stream"),
    },
    sourceExts: [...defaultConfig.resolver.sourceExts, "svg"],
  },
};

module.exports = mergeConfig(defaultConfig, config);

Please make sure to follow this setup. If you have any issues, check the troubleshooting guide for further details.

@mynameisjerry870203 Do you need any further help ?