Skip to content
This repository was archived by the owner on Oct 29, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 137 additions & 42 deletions demo/sfarndemo/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,41 +11,69 @@ import {
import RPC from './ethersRPC'; // for using ethers.js
import auth from '@react-native-firebase/auth';
import EncryptedStorage from 'react-native-encrypted-storage';
// @ts-ignore
import {decode as atob} from 'base-64';
import {decode} from 'base-64';
import {Auth0Provider, useAuth0} from 'react-native-auth0';

import Web3Auth from '@web3auth/single-factor-auth-react-native';
import {EthereumPrivateKeyProvider} from '@web3auth/ethereum-provider';
import {IProvider} from '@web3auth/base';
import {PasskeysPlugin} from './passkey/passkey';
import {ADAPTER_EVENTS} from '@web3auth/single-factor-auth';

async function signInWithEmailPassword() {
try {
const res = await auth().signInWithEmailAndPassword(
'custom+jwt@firebase.login',
'Testing@123',
);
return res;
} catch (error) {
console.error(error);
}
}

export default function App() {
function AppScreen() {
const [privateKey, setPrivateKey] = useState<string | null>();
const [loading, setLoading] = useState<boolean>(false);
const [userInfo, setUserInfo] = useState<string>('');
const [consoleUI, setConsoleUI] = useState<string>('');
const [web3auth, setWeb3Auth] = useState<Web3Auth | null>(null);
const [provider, setProvider] = useState<IProvider>();
const {authorize, getCredentials} = useAuth0();
const [passkeyPlugin, setPasskeyPlugin] = useState<PasskeysPlugin | null>(
null,
);
const clientId =
'BPi5PB_UiIZ-cPz1GtV5i1I2iOSOHuimiXBI0e-Oe_u6X3oVAbCiAZOTEBtTXw4tsluTITPqA8zMsfxIKMjiqNQ'; // get from https://dashboard.web3auth.io

useEffect(() => {
async function init() {
try {
const authProvider = new Web3Auth(EncryptedStorage, {
clientId:
'BEglQSgt4cUWcj6SKRdu5QkOXTsePmMcusG5EAoyjyOYKlVRjIF1iCNnMOTfpzCiunHRrMui8TIwQPXdkQ8Yxuk', // Get your Client ID from Web3Auth Dashboard
web3AuthNetwork: 'cyan',
clientId,
web3AuthNetwork: 'sapphire_devnet', // ["cyan", "testnet"]
usePnPKey: false, // By default, this sdk returns CoreKitKey
metadataHost: 'https://metadata-testing.tor.us',
});

const plugin = new PasskeysPlugin({
buildEnv: 'local',
metadataHost: 'https://metadata-testing.tor.us',
passkeyEndpoints: {
// replace this authentication server
register: {
options:
'https://wildcat-endless-basically.ngrok-free.app/api/v1/passkey/generate-registration-options',
verify:
'https://wildcat-endless-basically.ngrok-free.app/api/v1/passkey/verify-registration',
},
authenticate: {
options:
'https://wildcat-endless-basically.ngrok-free.app/api/v1/passkey/generate-authentication-options',
verify:
'https://wildcat-endless-basically.ngrok-free.app/api/v1/passkey/verify-authentication',
},
crud: {
list: 'https://wildcat-endless-basically.ngrok-free.app/api/v1/passkey/list',
},
},
// should this be app url or backend url
rpID: 'wildcat-endless-basically.ngrok-free.app',
rpName: 'SFARNDemo',
rpOrigin: 'https://wildcat-endless-basically.ngrok-free.app',
verifier: '',
serverTimeOffset: 60,
});
authProvider.addPlugin(plugin);
setPasskeyPlugin(plugin);
const privateKeyProvider = new EthereumPrivateKeyProvider({
config: {
/*
Expand All @@ -62,17 +90,17 @@ export default function App() {
},
},
});
setWeb3Auth(authProvider);
await authProvider.init(privateKeyProvider);
await authProvider.init(privateKeyProvider as any);

if (authProvider.connected) {
const finalPrivateKey = await authProvider.provider!.request({
method: 'eth_private_key',
});
// if (authProvider.connected) {
const finalPrivateKey = await authProvider.provider!.request({
method: 'eth_private_key',
});

setPrivateKey(finalPrivateKey as string);
uiConsole('Private Key: ' + finalPrivateKey);
}
setPrivateKey(finalPrivateKey as string);
uiConsole('Private Key: ' + finalPrivateKey);
setWeb3Auth(authProvider);
setProvider(authProvider.provider!);
} catch (error) {
uiConsole(error, 'mounted caught');
}
Expand All @@ -84,39 +112,55 @@ export default function App() {
try {
const base64Url = token.split('.')[1];
const base64 = base64Url.replace('-', '+').replace('_', '/');
return JSON.parse(atob(base64 || ''));
return JSON.parse(decode(base64 || ''));
} catch (err) {
uiConsole(err);
return null;
}
};

const signInWithAuth0 = async (method: string) => {
try {
//@ts-ignore
const credentials = await authorize({
scope: 'openid profile email',
// connection: method,
});
// const credentials = await getCredentials();
console.log({credentials});
return credentials?.idToken;
} catch (error) {
console.error({'error while sign with auth0': error});
}
};

const login = async () => {
try {
setConsoleUI('Logging in');
setLoading(true);
const loginRes = await signInWithEmailPassword();
uiConsole('Login success', loginRes);
const idToken = await loginRes!.user.getIdToken(true);
uiConsole('idToken', idToken);
const idToken = await signInWithAuth0('google');
console.log({idToken});
const parsedToken = parseToken(idToken);
setUserInfo(parsedToken);

const verifier = 'web3auth-firebase-examples';
const verifierId = parsedToken.sub;
const provider = await web3auth!.connect({
const verifier = 'w3a-auth0-demo';
// const currentVerifierId = parsedToken.sub;
const currentVerifierId = parsedToken.sub;
const currentProvider = await web3auth!.connect({
verifier, // e.g. `web3auth-sfa-verifier` replace with your verifier name, and it has to be on the same network passed in init().
verifierId, // e.g. `Yux1873xnibdui` or `name@email.com` replace with your verifier id(sub or email)'s value.
idToken,
verifierId: currentVerifierId, // e.g. `Yux1873xnibdui` or `name@email.com` replace with your verifier id(sub or email)'s value.
idToken: idToken || '',
});
const finalPrivateKey = await provider!.request({
console.log({currentVerifierId});
// setVerifierId(currentVerifierId);
setProvider(currentProvider);

setLoading(false);
const finalPrivateKey = await currentProvider!.request({
method: 'eth_private_key',
});

setPrivateKey(finalPrivateKey as string);
uiConsole('Private Key: ' + finalPrivateKey);

setLoading(false);
uiConsole('Logged In');
} catch (e) {
uiConsole(e);
Expand All @@ -135,6 +179,44 @@ export default function App() {
const address = await RPC.getAccounts(privateKey as string);
uiConsole(address);
};

const registerPasskeyV2 = async () => {
setConsoleUI('registerPasskey account');
try {
console.log({passkeyPlugin});
if (!passkeyPlugin) {
throw new Error('Passkey plugin not initialized');
}

await passkeyPlugin.registerPasskey({
username: `Passkey - ${new Date(Date.now()).toUTCString()}`,
});
setConsoleUI('Passkey registered successfully');
} catch (error: unknown) {
setConsoleUI(`error registering user ${error}`);
throw error;
}
};

const loginPasskeyV2 = async () => {
if (!passkeyPlugin) {
throw new Error('Passkey plugin not initialized');
}
await passkeyPlugin.loginWithPasskey();
console.log('Passkey loginWithPasskey successfully', web3auth?.provider);
// const sfaProvider = new ethers.providers.Web3Provider(web3auth?.provider as any);
// const sfaAddress = await sfaProvider.getSigner().getAddress();
// console.log('sfaAddress', sfaAddress);
// setWalletAddress(sfaAddress);
const finalPrivateKey = await web3auth?.provider!.request({
method: 'eth_private_key',
});

setPrivateKey(finalPrivateKey as string);
setProvider(web3auth?.provider as any);
uiConsole('Passkey logged in successfully');
};

const getBalance = async () => {
setConsoleUI('Fetching balance');
const balance = await RPC.getBalance(privateKey as string);
Expand Down Expand Up @@ -169,22 +251,25 @@ export default function App() {
};

const loggedInView = (
<View style={styles.buttonArea}>
<View style={{}}>
<Button title="Get User Info" onPress={() => uiConsole(userInfo)} />
<Button title="Get Chain ID" onPress={() => getChainId()} />
<Button title="Get Accounts" onPress={() => getAccounts()} />
<Button title="Get Accounts" onPress={() => getAccounts()} />
<Button title="Get Balance" onPress={() => getBalance()} />
<Button title="Send Transaction" onPress={() => sendTransaction()} />
<Button title="Sign Message" onPress={() => signMessage()} />
<Button title="Get Private Key" onPress={() => uiConsole(privateKey)} />
<Button title="Authenticate user" onPress={authenticateUser} />
<Button title="Register Passkey" onPress={() => registerPasskeyV2()} />
<Button title="Log Out" onPress={logout} />
</View>
);

const unloggedInView = (
<View style={styles.buttonArea}>
<Button title="Login with Web3Auth" onPress={login} />
<Button title="Login with Passkey" onPress={() => loginPasskeyV2()} />
{loading && <ActivityIndicator />}
</View>
);
Expand All @@ -202,6 +287,16 @@ export default function App() {
);
}

export default function App() {
return (
<Auth0Provider
domain={'https://web3auth.au.auth0.com'}
clientId={'hUVVf4SEsZT7syOiL0gLU9hFEtm2gQ6O'}>
<AppScreen />
</Auth0Provider>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
Expand Down
8 changes: 7 additions & 1 deletion demo/sfarndemo/babel.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
presets: ['module:@react-native/babel-preset'],
overrides: [
{
test: './node_modules/ethers',
plugins: [['@babel/plugin-transform-private-methods', {loose: true}]],
},
],
};
9 changes: 9 additions & 0 deletions demo/sfarndemo/global.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
import {decode, encode} from 'base-64';
global.Buffer = require('buffer').Buffer;
global.process.browser = true;

if (!global.btoa) {
global.btoa = encode;
}

if (!global.atob) {
global.atob = decode;
}
7 changes: 1 addition & 6 deletions demo/sfarndemo/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
/**
* @format
*/

import {AppRegistry} from 'react-native';
import './global';
import 'react-native-get-random-values';
import './global';
import {name as appName} from './app.json';

import App from './App';

AppRegistry.registerComponent(appName, () => App);
3 changes: 1 addition & 2 deletions demo/sfarndemo/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ require Pod::Executable.execute_command('node', ['-p',
{paths: [process.argv[1]]},
)', __dir__]).strip

platform :ios, min_ios_version_supported
platform :ios, '13.0'
prepare_react_native_project!

# If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set.
# because `react-native-flipper` depends on (FlipperKit,...) that will be excluded
#
Expand Down
Loading