Login via Tron Link in React SPA - javascript

I am making a react app and I need to make it so that the user can log in through the Tron Link browser extension. Now it turned out only to connect the application to the wallet, but now I need to install a new state after the connection. But after the execution of the extension call function, the state changes immediately, without waiting for the connection in the extension to complete.
How can I track if the connection is completed in the extension, and if completed, then change the state?
const getAccount = async () => {
if (window.tronWeb !== undefined) {
if (window.tronWeb.defaultAddress.base58) {
try {
setInstallFlag(true);
setlogInFlag(true);
setAddress(window.tronWeb.defaultAddress.base58); //TR9o7SXc9KqPrAxuBVb1gHMCykybxTK3GR
let instance = await window.tronWeb
.contract()
.at("TAx8Jq65YhvXc5saxFsqfLzKEwbQ1EdK64");
setContract(instance);
const account = await window.tronWeb.trx.getAccount(
window.tronWeb.defaultAddress.base58
);
if (account.assetV2) {
const temBal = account.assetV2.find(
(asset) => asset.key === "1002357"
);
if (temBal) {
setAccountBal(temBal.value / 100);
} else {
setAccountBal(0);
}
} else {
setAccountBal(0);
}
let bal = await instance
.balanceOf(window.tronWeb.defaultAddress.base58)
.call();
setBalance(bal.toNumber() / 100);
let prof = await instance
.rewardscheck(window.tronWeb.defaultAddress.base58)
.call();
setProfit(prof.toNumber() / 100);
let clamt = await instance.checkClaim().call();
setClaim(clamt.toNumber() / 100);
} catch (error) {
const msg = error.message ? error.message : error;
}
} else {
setInstallFlag(true);
setlogInFlag(false);
}
} else {
setInstallFlag(false);
setlogInFlag(false);
}
};
const login = () => {
getAccount();
setState('logged');
}

Related

VueJs Failed to execute 'transaction' on 'IDBDatabase'

I want to save my posts to IndexDB and on client side to list posts even when user offline.
import { openDB } from 'idb'
const dbPromise = () => {
if (!('indexedDB' in window)) {
throw new Error('Browser does not support IndexedDB')
}
return openDB('OfflineDb', 1, upgradeDb => {
if (!upgradeDb.objectStoreNames.contains('posts')) {
upgradeDb.createObjectStore('posts')
}
})
}
const saveToStorage = async (storeName, datas) => {
try {
const db = await dbPromise()
const tx = db.transaction(storeName, 'readwrite')
const store = tx.objectStore(storeName)
store.put(datas, storeName)
return tx.complete
} catch (error) {
return error
}
}
const checkStorage = async storeName => {
try {
const db = await dbPromise()
const tx = db.transaction(storeName, 'readonly')
const store = tx.objectStore(storeName)
return store.get(storeName)
} catch (error) {
return error
}
}
export default {
checkStorage,
saveToStorage
}
Here is my service. When I try to get data;
dbService.checkStorage('posts')
I'm getting error;
DOMException: Failed to execute 'transaction' on 'IDBDatabase': One of the specified object stores was not found.
Why that's happening? I found some solutions but any of them can not solve my problem

Ethereum calculate slippage PancakeSwap EstimateGas always throw TransferHelper: TRANSFER_FROM_FAILED

I have been getting this error for a couple of days. I am trying to calculate the necessary Slippage in PancakeSweap automatically.
For this I am trying different percentages and I call estimateGas to see if the transaction fails. But I only get the error
TransferHelper: TRANSFER_FROM_FAILED
I have tried a lot of methods and none of them work for me.
I'm sure the contract is approved and that it should work in the blockchain side. In pancakeswap it works for me, same wallet, same tokens and same amounts. I do not understand that it can fail.
const Web3 = require("web3");
const abi = require("./abi.json");
const web3 = new Web3("https://bsc-dataseed.binance.org/");
const contract = new web3.eth.Contract(abi, "0x10ed43c718714eb63d5aa57b78b54704e256024e");
function isValid(res) {
return new Promise((resolve, reject) => {
contract.methods.swapExactTokensForTokens(res[0], res[1], ["TOKEN_A", "TOKEN_B" ], "MI_WALLET", 1639969436 ).estimateGas(function(error, result) {
console.log(error.message)
if(error.message.includes("INSUFFICIENT_OUTPUT_AMOUNT")) {
console.log("Bad slippage")
reject()
}
else if(error) {
reject()
}
else {
resolve()
}
});
})
}
(async () => {
contract.methods.getAmountsOut("20000000000", ["TOKEN_A", "TOKEN_B" ]).call().then(async res => {
const data = res;
let slippage = 0;
while (true) {
try {
await isValid(data);
break;
}
catch(e) {
slippage++;
console.log(slippage / 100 * data[1])
let newS = data[1] - (slippage / 100 * data[1])
console.log(slippage, newS);
if(slippage == 20) {
break;
}
}
}
console.log(slippage)
})
})();

How would I set a manual gas limit in web3? To get the smart contract to execute?

I'm having a problem executing my smart contract. From the error code, I figured it is must be a gas limit problem, although I don't know where I would place the code in order for it to execute properly. Any suggestions?
Solidity code:
pragma solidity ^0.8.0;
import 'hardhat/console.sol';
contract WavePort {
//TrackWaves
uint totalWaves; //State Variable, Permanetly Stored In Contract Storage
constructor() {
console.log("Yo, I am I contract");
}
//Function Increments Waves On The Blockchain/ Immutable Never Decreasing
function wave() public {
totalWaves += 1;
console.log("%s has waved!", msg.sender);
}
//Function Returns Us the The Total Waves To Be Viewed
function getTotalWaves()public view returns(uint256) {
console.log("We have %d total waves", totalWaves);
return totalWaves;
}
}
JavaScript code:
const App = () => {
const [currentAccount, setCurrentAccount] = useState("")
const contractAddress = "contractAddress"
const contractABI = abi.abi
const checkIfWalletConnected = async () => {
let web3
try {
const {ethereum} = window;
if(!ethereum) {
window.alert("Make sure you have metamask !");
return;
}else {
web3 = new Web3(window.ethereum)
console.log("We have the ethereum object", ethereum)}
const accounts = await ethereum.request({method: 'eth_accounts'})
if(accounts.length !== 0) {
const account = accounts[0]
console.log("Found an Authorized account:", account, );
setCurrentAccount(account)
} else {
window.alert("NO authorized account found")
}
const EthBalance = await web3.eth.getBalance(accounts[0])
console.log(EthBalance)
}catch(err) {console.log(err)}
}
const connectWallet = async () => {
try {
const {ethereum} = window;
if(!ethereum) {alert("Get Metamask extenstion")
return
} else {
const accounts = await ethereum.request({method: 'eth_accounts'})
console.log("Connected", accounts[0])
window.alert("Wallet is Connected")
setCurrentAccount(accounts[0])
const ethBlance = await Web3.eth.getBalance(currentAccount)
console.log(ethBlance)
}
}catch(err) {
console.log(err)
}
}
const wave = async () => {
try {
const {ethereum} = window;
if(ethereum) {
const provider = new ethers.providers.Web3Provider(ethereum);
const signer = provider.getSigner();
const wavePortalContract = new ethers.Contract(contractAddress, contractABI, signer);
let count = await wavePortalContract.getTotalWaves( );
const waveTxn = await wavePortalContract.wave({gas:10000000 }, {gasPrice:80000000000});
console.log("Mining....", waveTxn.hash)
await waveTxn.wait( );
console.log("Mined-- ", waveTxn.hash)
count = await await wavePortalContract.getTotalWaves( );
console.log("Retrieved total wave count.. ", count.toNumber())
}else {
console.log("Eth Object doesn't exist!")
}
} catch(err) {console.log(`${err} hello world`) }
}
useEffect(() => {
checkIfWalletConnected();
}, [])
The error code I get:
Error: cannot estimate gas; transaction may fail or may require manual gas limit (error={"code":-32000,"message":"execution reverted"}, method="call", transaction={"from":"0xD49a9a33F180D1e35A30F0ae2Dbfe5716a740Ebc","to":"0x5FbDB2315678afecb367f032d93F642f64180aa3","data":"0x9a2cdc08","accessList":null}, code=UNPREDICTABLE_GAS_LIMIT, version=providers/5.5.1)
While calling a contract Abi method, you can pass an object of additional gas-related params in the second argument (or first if you don't have any arguments in your method).
So calling of wave function should looks like following:
const waveTxn = await wavePortalContract.wave({gasLimit:30000});
Check all additional params in the below documentation.
https://docs.ethers.io/v5/api/contract/contract/#contract-functionsSend

Where do i call websocket plugin to keep it always openned?

I am working with websockets on nuxt.js proyect, and i need to keep the connection opened and unique (singleton), but i could not achieve it.
I created a custom plugin where i listen for ws events, and openned the connection (checking if it doesnt exists yet -but sometimes it creates several ws instances-), and im calling this plugin from a middleware, which is using in several layouts.
The problem is:
Sometimes the connection does not establish (on page reload i.e.). How can i make sure it always starts on user login and keep openned till logout?
How do i keep just one instance of my plugin?
This is the plugin file i wrote:
export default ({ store, $axios, app }, inject) => {
class EasyWebsocket {
roomNotifications = ''
isOpen() {
return this.roomNotifications && this.roomNotifications.readyState === 1
}
initRoomNotifications(token) {
// if already open do nothing
if (this.isOpen()) {
return
}
console.log('inicializando notifications websocket')
this.roomNotifications = new WebSocket(
`wss://api/ws/chat/?t=${token}`
)
const self = this
this.roomNotifications.onmessage = async function(event) {
// CAPTURING THE WEBSOCKET NOTIFICATION
const { data } = event
const { event_type, room } = JSON.parse(data)
// TODO FRANCO: VER EL CONTADOR DE UNREADMESSAGES
const count = store.state.dashboard.chat.unreadMessagesCount + 1
store.commit('dashboard/chat/SET_UNREAD_MESSAGES_COUNT', count)
switch (event_type) {
case 'ROOM_UPDATED':
console.log('new message', room) // no borrar
await self.newRoomNotification(room)
break
case 'NEW_INVITATION':
console.log('created room', room) // no borrar
await self.newInvitation(room)
break
case 'NEW_MESSAGES':
console.log('new messages room', room) // no borrar
await self.newRoomNotification(room)
if (
store.getters['dashboard/chat/isActive']({ conversation: room })
)
store.commit('dashboard/chat/ADD_MESSAGE', room.last_message)
break
default:
break
}
}
this.roomNotifications.onopen = function(event) {
console.log('opening NOTIFICATION WEBSOCKET --------------', event) // no borrar
}
this.roomNotifications.onclose = function(event) {
}
this.roomNotifications.onerror = function(event) {
}
}
newInvitation(room) {
const invitations = store.getters['dashboard/chat/invitations']
const newInvitations = [room, ...invitations]
store.commit('dashboard/chat/SET_INVITATIONS', newInvitations)
}
async newRoomNotification(room) {
const { name } = room
// GET ALL CONVERSATIONS
const conversations = store.getters['dashboard/chat/visibleConversations']
// FIND CONVERSATION INDEX
const conversationIndex = conversations.findIndex(
(conv) => conv.name === name
)
const newConversations = [...conversations]
if (conversationIndex === -1) {
const conversation = await $axios.$get(
`v2/chat/rooms/${name}/?archived=false`
)
newConversations.unshift(conversation)
} else {
newConversations[conversationIndex] = {
...newConversations[conversationIndex],
...room
}
}
store.commit('dashboard/chat/SET_CONVERSATIONS', newConversations)
}
}
inject('easyWebsocket', EasyWebsocket)
}
Then in the middleware file:
export default async function({ store, $auth, $easyWebsocket }) {
if (!$auth.$state.loggedIn) return
// calling just on client side (websocket doesnt work on ss)
if (process.client) {
$easyWebsocket.prototype.initRoomNotifications(
//userdata
)
}
try {
await store.dispatch('dashboard/chat/getUnreadMessagesCount')
} catch (error) {}
}

Discord bot post multiple results

First time using stackoverflow. It is a bot made to post result whenever new episode of show in search list gets added on nyaa.si. I want bot to post result only once for every episode but bot post same episode multiple time in different time frames. It gets fixed for while after I restart the bot.
The code to add show to search list.
async addShow(msg) {
const regex = /"(.+?)" "(.+?)"(?: "(.+?)")?/g;
const found = regex.exec(msg.content);
if (found === null) {
await msg.channel.send(`Invalid new syntax:\n${COMMAND_CHARACTER} new \"show search phrase\" \"MALURL\" \"attribute regex\" (optional last)`);
return;
}
let [f, search, url, reg] = found;
let count = await this.db.get('search').last().value();
if (_.isUndefined(count)) {
count = 0;
}
else {
count = count.id;
}
await this.db.get('search').push({id: count + 1, search, url, regex: reg}).write();
logger.info(`New show has been added to the searchlist - ${search} - ${url} for server ${this.guildID}`);
await msg.channel.send("Saved!");
}
The code to search
async searchShow(id, query, channel = null, OG = null) {
const results = await this.nyaa.getResults(query);
if (!results.length) {
return;
}
logger.info(`Results found for ${query}: ${results.length}`);
const embedFunction = this.getRichEmbed.bind(this);
for (let i of results) {
const item = await this.db.get('rss').find({guid: i.guid}).value();
if (!_.isUndefined(item)) {
continue;
}
if (await this.postShow(embedFunction, i, channel, OG)) {
await this.db.get('rss').push({...i, searchID: id}).write();
}
}
}
Code to post result when new episode comes.
async postShow(embedFunc, item, channel = null, og = null, channelType = NYAA_UPDATES) {
if (channel === null) {
channel = await this.getGuildChannel(channelType);
if (!channel) {
return false;
}
}
return new Promise(async (resolve) => {
const title = (og !== null ? og.title ?? item.title : item.title);
const embed = await embedFunc(item, title);
if (og !== null) {
const img = og.image ?? null;
if (img) {
embed.setThumbnail(img);
}
const url = og.url ?? null;
if (url) {
embed.setURL(url);
}
}
let retryCounter = 0;
logger.info(`Posting new result for ${title} with guid ${item.guid} for server ${this.guildID}`);
while (true) {
try {
await channel.send(embed);
setTimeout(() => {
resolve(true);
}, 2000);
break;
}
catch (e) {
logger.warn(`An error has occured while posting: ${e.toString()}, retrying (${++retryCounter} in 5 seconds`);
await new Promise((res) => {
setTimeout(() => {
res();
}, 5000);
});
if (retryCounter > 10) {
resolve(false);
}
}
}
});
}
Also one who wrote most of code was different person and I only added few additional function here and there which doesn't affect the code much. One who wrote most of core code had to leave discord so I was left to host the bot which I am hosting at repl.it. It will be great help to know whether the problem is with the code or not.
As Julian Kleine mentioned above, the most common reason a bot posts multiple times is if you are running multiple instances of the host. Close all instances of command prompt, and check task manager to see if any other hidden instances are running in the background.

Categories

Resources