[Archive] React-native Solana

:classical_building: Archived Content from Web3Auth Community

This topic was originally posted by mynameisjerry870203 on 5/20/2024.
This content has been migrated from our previous community forum to preserve valuable discussions.


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 ?