Show wallet address after connecting Metamask with Web3.js - javascript

I got this code off github which allows you to connect to MetaMask using web3.js and also to make payment. I then modified it to
Display a Connect Button when user is not logged in by checking if the content of an element is empty and if it is not empty, the connect button is hidden.
Retrieve the connected wallet address which is in the element that hides the button.
I want the connected wallet to show up and hide the Connect button as soon as MetaMask is connected but it does not do that until i manually reload the page
Below is my code
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://unpkg.com/#metamask/legacy-web3#latest/dist/metamask.web3.min.js"></script>
</head>
<body>
<div>
<div id="selected-account"></div>
<button class="pay-button">Pay</button>
<div id="status"></div>
<div id="accTabs"></div>
</div>
<script type="text/javascript">
async function initWeb3() {
if (window.ethereum) {
window.web3 = new Web3(ethereum);
try {
await ethereum.enable();
window.location.reload();
} catch (err) {
$("#status").html("User denied account access", err);
}
} else if (window.web3) {
return (window.web3 = new Web3(web3.currentProvider));
} else {
return $("#status").html("No Metamask (or other Web3 Provider) installed");
}
}
selectedAccount = ethereum.selectedAddress;
document.querySelector("#selected-account").textContent = selectedAccount;
$(".pay-button").click(async () => {
await initWeb3();
// paymentAddress is where funds will be send to
const paymentAddress = "0x192c96bfee59158441f26101b2db1af3b07feb40";
const amountEth = "1";
web3.eth.sendTransaction(
{
to: paymentAddress,
value: web3.toWei(amountEth, 'ether')
},
(err, transactionId) => {
if (err) {
console.log("Payment failed", err);
$("#status").html("Payment failed");
} else {
console.log("Payment successful", transactionId);
$("#status").html("Payment successful");
}
}
);
});
</script>
<script>
if ($('#selected-account').text() == '') {
document.getElementById("accTabs").innerHTML = '<button onclick="initWeb3()">Connect Ethereum</button>';
} else {
}
</script>
</body>
</html>
Your help will be appreciated!
Thanks for your assistance.

you should use onload function like this window.onload = async function () { when it works you need to verify if window have ethereum if everything is ok then connect to a provider using new Web3.providers.HttpProvider
window.onload = async function () {
const detectMM = () => typeof window.ethereum !== "undefined";
if (detectMM) {
document.getElementById("enableMM").getAttribute("disabled", false);
try {
const provider = new Web3.providers.HttpProvider(
"HTTP://127.0.0.1:7545"
);
web3 = new Web3(window.ethereum);
web3Host = new Web3(provider);
await connect();
await web3.eth.net
.isListening()
.then(
() =>
(document.getElementById(
"network"
).innerHTML = `available network`)
)
.catch(
(e) =>
(document.getElementById(
"network"
).innerHTML = `Something went wrong: ${e}`)
);
} catch (error) {
alert(error);
}
} else {
document.getElementById("enableMM").getAttribute("disabled", true);
}

Related

the notification push up of my website does not display when my website is not focused

The notification push up of my website does not display when my website is not focused. And when browser closed the notification will display:
This is my code:
firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();
const { REACT_APP_VAPID_KEY } = process.env;
const publicKey = REACT_APP_VAPID_KEY;
export const getToken = async (setTokenFound) => {
let currentToken = "";
try {
currentToken = await messaging.getToken({ vapidKey: publicKey });
if (currentToken) {
setTokenFound(true);
} else {
setTokenFound(false);
}
} catch (error) {
console.log("An error occurred while retrieving token. ", error);
}
return currentToken;
};
export const onMessageListener = (callback) =>
new Promise((resolve) => {
messaging.onBackgroundMessage((payload) => {
const data=(JSON.parse(payload.data.data))
const description=()=>{
if(data?.type===STRANGE_DETECTION){
return "Strange Detection"
}else if(data?.type===ENROLL_FACE_DETECTION){
return "Detected a person:"
}else if(data?.type===MOTION_DETECTION){
return "Motion Detection"
}
else if(data?.type===FIRMWARE_UPDATE){
return "Firmware Update "
}
else if(data?.type===lOCATION_SHARING){
return "Location Sharing "
}
else if(data?.type===DEVICE_SHARING){
return "Device Sharing"
}
else if(data?.type===DEVICE_REGISTER){
return "Device Register"
}
else if(data?.type===DEVICE_DISCONNECT){
return "Device Disconnection"
}
}
const notificationTitle ="INFINITY"
const notifycationOption ={
body:`${data?.content?.device_name}: ${description()} ${data?.content?.face_name}`,
icon:icon
};
self.registration.showNotification(notificationTitle,
notifycationOption);
resolve(payload);
callback(payload);
});
});
And i want to know how to display notification pop up when your web site is not focused.

Why Stripe 3ds popup closes automaticly?

I'm trying to intigrate Stripe 3ds flow to the project. Everything goes ok, but when you do nothing after pop-up appearing for about 5 seconds it closes automaticly.
Here is a part of my code:
const sendServerReq = async (id) {
const { status, {data: payment_intent_secret} } = await purchaseRequest(id);
if (status === 'requires_action' && payment_intent_secret) {
const {
error: errorAction,
paymentIntent
} = await stripe.confirmCardPayment(payment_intent_secret);
if (errorAction) {
onError(errorAction.message);
return;
}
await sendServerReq(paymentIntent.id);
} else {
return onSuccess();
}
}

How to connect Metamask based on the input wallet adress

When I type a wallet address and press the Save button I want to show a Metamask sign in popup to that wallet.
for now, It's just randomly connects with the selected wallet. Basically, I want to be able to connect wallets with just wallet address.
profile.jsx
import React from "react";
import { useContext, MainContext } from "../hook/Context";
import Web3 from "web3";
const Profile = () => {
const { data, setData } = useContext(MainContext);
const detectCurrentProvider = () => {
let provider;
if (window.ethereum) {
provider = window.ethereum;
} else if (window.web3) {
provider = window.web3.currentProvider;
} else {
alert(
"Non-Ethereum browser detected. You should consider trying MetaMask!"
);
}
return provider;
};
const onConnect = async (e) => {
e.preventDefault();
try {
const currentProvider = detectCurrentProvider();
if (currentProvider) {
if (currentProvider !== window.ethereum) {
alert(
"Non-Ethereum browser detected. You should consider trying MetaMask!"
);
}
await currentProvider.request({ method: "eth_requestAccounts" });
const web3 = new Web3(currentProvider);
const userAccount = await web3.eth.getAccounts();
const chainId = await web3.eth.getChainId();
const account = userAccount[0];
let ethBalance = await web3.eth.getBalance(account); // Get wallet balance
ethBalance = web3.utils.fromWei(ethBalance, "ether"); //Convert balance to wei
setData(ethBalance, account, chainId);
if (userAccount.length === 0) {
console.log("Please connect to meta mask");
}
}
} catch (err) {
alert(
"There was an error fetching your accounts. Make sure your Ethereum client is configured correctly."
);
}
};
return (
<div className="container-fluid">
<div className="wallets__wrapper">
Your wallets:
{data.account}
</div>
<form className="token__form" onSubmit={onConnect}>
<input type="text" placeholder="Account Name" />
<input type="text" placeholder="Wallet Adress" />
<button className="add__btn">SAVE</button>
</form>
</div>
);
};
export default Profile;
try to load web3 in this way, this will ask you to connect to metamask first(pop-up)
const getWeb3 = () => {
return new Promise((resolve, reject) => {
// Wait for loading completion to avoid race conditions with web3 injection timing.
window.addEventListener("load", async () => {
// Modern dapp browsers...
if (window.ethereum) {
const web3 = new Web3(window.ethereum);
try {
// Request account access if needed
await window.ethereum.enable();
// Acccounts now exposed
resolve(web3);
} catch (error) {
reject(error);
}
}
// Legacy dapp browsers...
else if (window.web3) {
// Use Mist/MetaMask's provider.
const web3 = window.web3;
console.log("Injected web3 detected.");
resolve(web3);
}
// Fallback to localhost; use dev console port by default...
else {
const provider = new Web3.providers.HttpProvider(
"http://localhost:9545"
);
const web3 = new Web3(provider);
console.log("No web3 instance injected, using Local web3.");
resolve(web3);
}
});
});
};
load this in your useEffect:
useEffect(() => {
const init = async () => {
const web3 = await getWeb3();
//set accounts ,etc to state from web3 by awaiting them
const accounts = await web3.eth.getAccounts();
}
init();
}

Metamask returns RPC Error: Error: [ethjs-rpc] rpc error with payload {"id":5715960965837,"jsonrpc":"2.0","params":

I have this code that allows me to make a purchase of tokens with web3, apparently if the transaction is validated but when I click confirm, the following error appears:
inpage.js:1 MetaMask - RPC Error: Error: [ethjs-rpc] rpc error with payload {"id":5715960965839,"jsonrpc":"2.0","params":["0xf8ac178504a817c8008301022794cfeb869f69431e42cdb54a4f4f105c19c080a60180b844095ea7b3000000000000000000000000c89ce4735882c9f0f0fe26686c53074e09b0d55000000000000000000000000000000000000000000000000000000000000f4240820557a07ff18aba5ab0a8080f4a4b29e8736c4ded84e09cec8f66eba186995a6b22261fa041fd2e3351985a3b0a4e1ec9ef1be79c3513170810569b78ba9f238d36e781fa"],"method":"eth_sendRawTransaction"} [object Object]
try to uninstall the extension and reinstall it as mentioned in other places, but without getting any results
this is my code
/* 'metamask': */
const web3 = new Web3(window["ethereum"]);
const USDT_ADDRESS = "XxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
const ORION_SALE_ADDRESS = "XxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
const usdtContract = new web3.eth.Contract(IRC20_JSON.abi, USDT_ADDRESS);
const saleContract = new web3.eth.Contract(
ORION_SALE_JSON.abi,
ORION_SALE_ADDRESS
);
let userWallet;
const getAddress = async () => {
try {
const accounts = await window.ethereum.enable();
userWallet = accounts[0];
console.log(accounts, ORION_SALE_JSON);
if (!userWallet) {
document.getElementById("msg").innerHTML =
"Oops, we can't seem to find the address of your wallet. Please, log in into your metamask account using the chrome extension and then refresh the page";
} else {
document.getElementById("msg").innerHTML =
"Your wallet have been successfully added";
}
} catch (error) {
console.log(error);
}
};
getAddress();
//buyTokenFunction
const myfunction = async () => {
let inputVal = document.getElementById("myInput").value;
if (inputVal !== "") {
usdtContract.methods
.approve(ORION_SALE_ADDRESS, (inputVal * 1e6).toFixed(0))
.send({ from: userWallet })
.once("transactionHash", (hash) => {
saleContract.methods
.buyTokens(userWallet, USDT_ADDRESS, (inputVal * 1e6).toFixed(0))
.send({ from: userWallet, gas: 10000000 }, (_) => {
// Waiting for the transaction to be mined
})
.then((_) => {
// Success
});
});
}
};
Trace inputVal (or output to the console). Or even better is the whole expression:
(inputVal * 1e6).toFixed(0)
Determine in which method the error occurs: approve or buyToken.

Always throws registration failed error while subscribing push notifications

I am working on solutions using which i can send desktop push notification to subscribed clients.
I have created basic solution in where whenever user click on button i ask user for whether they want to allow notifications for my app or not!
I am getting an error of "Registration failed - permission denied" whenever i click on button for first time.
So that i am not able to get required endpoints to save at backend
Here is my code
index.html
<html>
<head>
<title>PUSH NOT</title>
<script src="index.js"></script>
</head>
<body>
<button onclick="main()">Ask Permission</button>
</body>
</html>
index.js
const check = () => {
if (!("serviceWorker" in navigator)) {
throw new Error("No Service Worker support!");
} else {
console.log("service worker supported")
}
if (!("PushManager" in window)) {
throw new Error("No Push API Support!");
} else {
console.log("PushManager worker supported")
}
};
const registerServiceWorker = async () => {
const swRegistration = await navigator.serviceWorker.register("/service.js?"+Math.random());
return swRegistration;
};
const requestNotificationPermission = async () => {
const permission = await window.Notification.requestPermission();
// value of permission can be 'granted', 'default', 'denied'
// granted: user has accepted the request
// default: user has dismissed the notification permission popup by clicking on x
// denied: user has denied the request.
if (permission !== "granted") {
throw new Error("Permission not granted for Notification");
}
};
const main = async () => {
check();
const swRegistration = await registerServiceWorker();
const permission = await requestNotificationPermission();
};
// main(); we will not call main in the beginning.
service.js
// urlB64ToUint8Array is a magic function that will encode the base64 public key
// to Array buffer which is needed by the subscription option
const urlB64ToUint8Array = base64String => {
const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, "+")
.replace(/_/g, "/");
const rawData = atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
};
const saveSubscription = async subscription => {
console.log("Save Sub")
const SERVER_URL = "http://localhost:4000/save-subscription";
const response = await fetch(SERVER_URL, {
method: "post",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(subscription)
});
return response.json();
};
self.addEventListener("activate", async () => {
try {
const applicationServerKey = urlB64ToUint8Array(
"BFPtpIVOcn2y25il322-bHQIqXXm-OACBtFLdo0EnzGfs-jIGXgAzjY6vNapPb4MM1Z1WuTBUo0wcIpQznLhVGM"
);
const options = { applicationServerKey, userVisibleOnly: true };
const subscription = await self.registration.pushManager.subscribe(options);
console.log(JSON.stringify(subscription))
const response = await saveSubscription(subscription);
} catch (err) {
console.log(err.code)
console.log(err.message)
console.log(err.name)
console.log('Error', err)
}
});
self.addEventListener("push", function(event) {
if (event.data) {
console.log("Push event!! ", event.data.text());
} else {
console.log("Push event but no data");
}
});
Also i have created a bit of backend as well
const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const webpush = require('web-push')
const app = express();
app.use(cors());
app.use(bodyParser.json());
const port = 4000;
app.get("/", (req, res) => res.send("Hello World!"));
const dummyDb = { subscription: null }; //dummy in memory store
const saveToDatabase = async subscription => {
// Since this is a demo app, I am going to save this in a dummy in memory store. Do not do this in your apps.
// Here you should be writing your db logic to save it.
dummyDb.subscription = subscription;
};
// The new /save-subscription endpoint
app.post("/save-subscription", async (req, res) => {
const subscription = req.body;
await saveToDatabase(subscription); //Method to save the subscription to Database
res.json({ message: "success" });
});
const vapidKeys = {
publicKey:
'BFPtpIVOcn2y25il322-bHQIqXXm-OACBtFLdo0EnzGfs-jIGXgAzjY6vNapPb4MM1Z1WuTBUo0wcIpQznLhVGM',
privateKey: 'mHSKS-uwqAiaiOgt4NMbzYUb7bseXydmKObi4v4bN6U',
}
webpush.setVapidDetails(
'mailto:janakprajapati90#email.com',
vapidKeys.publicKey,
vapidKeys.privateKey
)
const sendNotification = (subscription, dataToSend='') => {
webpush.sendNotification(subscription, dataToSend)
}
app.get('/send-notification', (req, res) => {
const subscription = {endpoint:"https://fcm.googleapis.com/fcm/send/dLjyDYvI8yo:APA91bErM4sn_wRIW6xCievhRZeJcIxTiH4r_oa58JG9PHUaHwX7hQlhMqp32xEKUrMFJpBTi14DeOlECrTsYduvHTTnb8lHVUv3DkS1FOT41hMK6zwMvlRvgWU_QDDS_GBYIMRbzjhg",expirationTime:null,keys:{"p256dh":"BE6kUQ4WTx6v8H-wtChgKAxh3hTiZhpfi4DqACBgNRoJHt44XymOWFkQTvRPnS_S9kmcOoDSgOVD4Wo8qDQzsS0",auth:"CfO4rOsisyA6axdxeFgI_g"}} //get subscription from your databse here.
const message = 'Hello World'
sendNotification(subscription, message)
res.json({ message: 'message sent' })
})
app.listen(port, () => console.log(`Example app listening on port ${port}!`));
Please help me
Try the following code:
index.js
const check = () => {
if (!("serviceWorker" in navigator)) {
throw new Error("No Service Worker support!");
} else {
console.log("service worker supported")
}
if (!("PushManager" in window)) {
throw new Error("No Push API Support!");
} else {
console.log("PushManager worker supported")
}
};
const saveSubscription = async subscription => {
console.log("Save Sub")
const SERVER_URL = "http://localhost:4000/save-subscription";
const response = await fetch(SERVER_URL, {
method: "post",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(subscription)
});
return response.json();
};
const urlB64ToUint8Array = base64String => {
const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, "+")
.replace(/_/g, "/");
const rawData = atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
};
const registerServiceWorker = async () => {
return navigator.serviceWorker.register("service.js?"+Math.random()).then((swRegistration) => {
console.log(swRegistration);
return swRegistration;
});
};
const requestNotificationPermission = async (swRegistration) => {
return window.Notification.requestPermission().then(() => {
const applicationServerKey = urlB64ToUint8Array(
"BFPtpIVOcn2y25il322-bHQIqXXm-OACBtFLdo0EnzGfs-jIGXgAzjY6vNapPb4MM1Z1WuTBUo0wcIpQznLhVGM"
);
const options = { applicationServerKey, userVisibleOnly: true };
return swRegistration.pushManager.subscribe(options).then((pushSubscription) => {
console.log(pushSubscription);
return pushSubscription;
});
});
};
const main = async () => {
check();
const swRegistration = await registerServiceWorker();
const subscription = await requestNotificationPermission(swRegistration);
// saveSubscription(subscription);
};
service.js
self.addEventListener("push", function(event) {
if (event.data) {
console.log("Push event!! ", event.data.text());
} else {
console.log("Push event but no data");
}
});
I can think of three reasons that the permission is denied
1) your site is not on https (including localhost that is not on https), the default behaviour from chrome as far as i know is to block notifications on http sites. If that's the case, click on the info icon near the url, then click on site settings, then change notifications to ask
2) if you are on Safari, then safari is using the deprecated interface of the Request permission, that is to say the value is not returned through the promise but through a callback so instead of
Notification.requestPermission().then(res => console.log(res))
it is
Notification.requestPermission(res => console.log(res))
3) Your browser settings are blocking the notifications request globally, to ensure that this is not your problem run the following code in the console (on a secured https site)
Notification.requestPermission().then(res => console.log(res))
if you receive the alert box then the problem is something else, if you don't then make sure that the browser is not blocking notifications requests

Categories