How do I know which network currently connected in MetaMask by WalletConnet react native? - react-native

I am developing react native mobile application where user can connect their crypto wallet(MetaMask, Rainbow, etc.) to mobile application. Everything is working well. I have used this (#walletconnect/react-native-dapp) react-native package to achieve this requirement.
After connected the external wallet (MetaMask), later I have to do some transaction by my app.
To do transaction I have to get know which network currently set in MetaMask wallet.
Is there any way to know the current connected network(chainId)to Metamask by this react-native package.
To do the transaction I am using this code.
try {
let dataa = await contract.methods
.transfer(toAddress, value.toString())
.encodeABI();
let txObj = {
// gas: Web3js.utils.toHex(100000),
data: Web3js.utils.toHex(dataa),
from: userWallet,
to: POZ_TOKEN, // Contractor token address
};
try {
const transactionHash = await connector
.sendTransaction(txObj)
.catch((_err: any) => {
Toast.show({
autoHide: true,
text1: t('topUpPoz.transactionFailed'),
type: 'error',
});
});
console.log('transactionHash is =', transactionHash);
Please suggest me anyone.

With #walletconnect/react-native-dapp we can fetch chain ID using connector, sample code is given below.
Note: checkNetworkIdHandler is a custom user defined function to check chainId connected is valid or not.
import {useWalletConnect} from '#walletconnect/react-native-dapp';
//creating a wallet connect connector
const connector = useWalletConnect();
const connectExternalWallet = React.useCallback(() => {
return connector.connect();
}, [connector]);
//below code snippet to be called on wallet connect button click
async function connectWallet(){
try {
let connection = await connectExternalWallet();
let networkStatus = checkNetworkIdHandler(connection.chainId);
}catch (exception) {
console.log("Exception occurred while connecting to metamask");
}
}

Related

How to login using microsoft account in react-native

I want to log in to my app using a Microsoft account in react native when a "Login with Microsoft" button is clicked.
I had used a component called react-native-msal but I am getting errors (as shown in the below image). Can anyone help me on this code or any other component where I can log in using Microsoft account using react native
My code:
const config: MSALConfiguration = {
auth: {
clientId: (i have written my client id here in my code),
authority: 'https://login.microsoftonline.com/common'
},
};
const scopes = ['openid', 'profile','user.Read'];
const pca = new PublicClientApplication(config);
console.log(pca);
try {
await pca.init();
} catch (error) {
console.error('Error initializing the pca, check your config.', error);
}
const params: MSALInteractiveParams = { scopes };
const result: MSALResult = await pca.acquireToken(params);
Error:
use AzureInstance, AzureLoginView
What the other answer mean with
use AzureInstance, AzureLoginView
is probably the views exported by this package:
https://github.com/shedaltd/react-native-azure-ad-2

Save payment for later option, Stripe, React Native, Expo

I'm trying to setup a way to setup a payment for later with a prebuilt Stripe component in a React Native Expo Project.
I'm following along with this project: https://snack.expo.dev/#charliecruzan/stripe-react-native-example?platform=mydevice
If you go to PaymentsUICustomScreen.tsx, you can see that there is an option to save payments for later when the option is rendered on the screen.
When I implement the same code, I do not get that same option.
I'm using the useStripe function.
This is the flow:
import { useStripe } from '#stripe/stripe-react-native'
...
const { initPaymentSheet, presentPaymentSheet } = useStripe();
...
await initPaymentSheet({
customerId: 'customerID',
// customerEphemeralKeySecret: ephemeralKey,
paymentIntentClientSecret: clientSecret,
customFlow: false,
merchantDisplayName: 'Example Inc.',
applePay: true,
merchantCountryCode: 'US',
style: 'alwaysDark',
googlePay: true,
testEnv: true,
});
My question is, why do I not get the save payment methods for later option?
You should use the ephemeralKeys in your Frontend and as well as in your backend so that after successful payment of the user, the payment details such as card details will be saved securely in stripe.
You need to put clientSecret inside the function presentPaymentSheet as an object property, like this:
const openPaymentSheet = async () => {
if (!clientSecret) {
return;
}
setLoadng(true);
const { error } = await presentPaymentSheet({
clientSecret,
});
if (error) {
Alert.alert(`Error code: ${error.code}`, error.message);
} else {
Alert.alert('Success', 'The payment was confirmed successfully');
}
setPaymentSheetEnabled(false);
setLoadng(false);
};
Here, clientSecret is also a paymentIntent. For details, check how it was used in your example project.

Client app calling Stripe API after card form exit, for future payment

I am adding Stripe 3D secure to a React-Native app, following the document at https://stripe.com/docs/payments/save-and-reuse
-- save the card, and charge off-session later when the service is completed.
For saving card, my app uses a WebView component to load a HTML, using <script src="https://js.stripe.com/v3/"></script> .
It successfully saved the client secret and exited the card form.
Question: At payment time later, in case next action for strong customer authentication is required, how to get a stripe object again so as to call stripe.confirmCardPayment()?
I tried below but failed -- catch(error), and error is empty.
import {loadStripe} from '#stripe/stripe-js';
confirmPayment = async () => {
try {
const stripe = await loadStripe("pk_test_...");
// stripe
// .confirmPaymentIntent('{PAYMENT_INTENT_CLIENT_SECRET}', {
// payment_method: '{PAYMENT_METHOD_ID}',
// return_url: 'https://example.com/return_url',
// })
// .then(function(result) {
//
// });
} catch(error) {
console.error(`failed to load stripe ${JSON.stringify(error)}`);
}
You can use stripe.confirmCardPayment in a variety of ways. In your case you probably already have a PaymentMethod ID, meaning you can confirm the PaymentIntent client side with that PaymentMethod ID instead of an Elements object:
stripe
.confirmCardPayment('{PAYMENT_INTENT_CLIENT_SECRET}', {
payment_method: '{PAYMENT_METHOD_ID}',
})
.then(function(result) {
// Handle result.error or result.paymentIntent
});

React native firebase - facebook sign-in not triggering onAuthStateChanged listener

this is the second problem Im having with RNFB facebook login.
Im following the official code sample provided by RNFB....code below
Problem is with the line firebase().signInWithCredential(facebookCredential);....its not triggering the firebase listener auth().onAuthStateChanged
All other code is running as it should and facebookCredential variable is populated correctly
import { firebase } from '#react-native-firebase/auth';
onFacebookButtonPress = async () => {
// Attempt login with permissions
const result = await LoginManager.logInWithPermissions([
'public_profile',
'email',
]);
if (result.isCancelled) {
throw 'User cancelled the login process';
}
// Once signed in, get the users AccesToken
const data = await AccessToken.getCurrentAccessToken();
if (!data) {
throw 'Something went wrong obtaining access token';
}
// Create a Firebase credential with the AccessToken
//const facebookCredential = firebase.FacebookAuthProvider.credential(data.accessToken);
const facebookCredential = firebase.auth.FacebookAuthProvider.credential(
data.accessToken,
);
// Sign-in the user with the credential
firebase().signInWithCredential(facebookCredential);
};
I figured it out by putting a try/catch around the problematic line. Turned out was because I had already once signed in using Google.
An account already exists with the same email address but different sign-in credentials. Sign in using a provider associated with this email address
You shouldn't wait till something goes wrong before you add try/ catch's. signInWithCredential returns many different types of errors, which you handle. From the docs:
firebase.auth().signInWithCredential(credential).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// The email of the user's account used.
var email = error.email;
// The firebase.auth.AuthCredential type that was used.
var credential = error.credential;
if (errorCode === 'auth/account-exists-with-different-credential') {
alert('Email already associated with another account.');
// Handle account linking here, if using.
} else {
console.error(error);
}
});
Please handle the other error cases too 🙂:
auth/account-exists-with-different-credential
auth/invalid-credential
auth/operation-not-allowed
auth/user-disabled
and more.

Redux + Rest API + Realm JS in React Native

I am developing an app that controls IOT devices via REST API.
I am using Realm database inside the app to keep historical data captured by IOT sensors. I also decided to use it to persist information about user and devices. redux-persist didn't seem like the best choice since the app will eventually deal with big tables of data of historical data.
I am now building my Redux actions with Redux-Thunk and I am in doubt about what would be the ideal workflow/data flow. I am currently calling realm inside redux actions like this:
function addNew(deviceIp) {
const request = () => { return { type: c.ADD_REQUEST } };
const success = (payload) => { return { type: c.ADD_SUCCESS, payload} };
const failure = (payload) => { return { type: c.ADD_FAILURE, payload } };
return async (dispatch,getState) => {
dispatch(request());
try {
const res = await apiService.getIt(deviceIp + urls.general);
// Convert responses to date before Realm Insertion
const newDevice = {
...res.deviceInfo[0],
host: deviceIp,
manufacturingDate: new Date(res.deviceInfo[0].manufacturingDate),
lastFwUpdateDate: new Date(res.deviceInfo[0].lastFwUpdateDate),
firstLaunchDate: new Date(res.deviceInfo[0].firstLaunchDate),
lastResetDate: new Date(res.deviceInfo[0].lastResetDate)
};
const addedDevice = await realmActions.createNew('Device',newDevice);
dispatch(success(addedDevice));
}
catch (error)
{
dispatch(failure(error));
}
};
}
realmActions.createNew(collectionName, newEntry) is a method I have created to add new entries to the specified collection in Realm DB. I have one main concern about this methodology.:
It seems to me a bit of an overkill to write objects to both Realm and Redux. But Realm will be useful to persist this data in case the user closes and re-opens the app. What do you think about the approach I am taking. Would you suggest anything cleaner or smarter?