Unable to query or get any response from BscScan contract - javascript

The following code:
const { JsonRpcProvider } = require("#ethersproject/providers")
const { Contract } = require("ethers")
const { Wallet } = require("#ethersproject/wallet");
const abi = require('./abi.json');
const GLOBAL_CONFIG = {
PPV2_ADDRESS: "0x18B2A687610328590Bc8F2e5fEdDe3b582A49cdA",
PRIVATE_KEY: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
BSC_RPC: "https://bsc-mainnet.public.blastapi.io"
};
const signer = new Wallet(GLOBAL_CONFIG.PRIVATE_KEY, new JsonRpcProvider(GLOBAL_CONFIG.BSC_RPC));
const contract = new Contract(GLOBAL_CONFIG.PPV2_ADDRESS, abi, signer)
const predictionContract = contract.connect(
signer
)
predictionContract.on("StartRound", async (epoch) => {
console.log("\nStarted Epoch", epoch.toString())
});
It has been working perfectly for months. However, last night it stopped. No new builds/code changes on my end. I've been trying everything I can think of but nothing. The signer seems to bring back my wallet details ok. I can also see all the functions on the predictionContract but can't get it to return the current Epoch value etc. As you've probably already noticed, I'm not much of a coder, so any help in understanding this would be amazing.

After some more time thinking, I noticed that the contract seemed pretty busy and decided to try a different RPC (I'd already tried 3 before). Seems to be working now, but not exactly scientific. Is there any way to monitor the time requests take and where the lag is? I had a design idea to test a multiple of RPCs during initiation and then use the fastest / most reliable, but no idea where to start with that!

Related

How to connect to several WebSockets providing the same data for redundancy on Javascript so that if some fail, others will ensure things still work?

The intention is to have several websockets for redundancy of the same data, so that if one fails, the others will still do the job. In particular, a setup where any one websocket is enough to keep the system working, even if all others fail to connect or return errors.
This is the curent setup, but I know it's wrong:
let queue = []
ws = new WebSocket(`wss://firstsource.com/ws/`);
ws2 = new WebSocket(`wss://secondsource.com/ws/`);
ws3 = new WebSocket(`wss://thirdsource.com/ws/`);
ws4 = new WebSocket(`wss://fourthsource.com/ws/`);
ws.onopen = sendIntro;
ws2.onopen = sendIntro;
ws3.onopen = sendIntro;
ws4.onopen = sendIntro;
ws.onmessage = insertQueue;
ws2.onmessage = insertQueue;
ws3.onmessage = insertQueue;
ws4.onmessage = insertQueue;
function sendIntro() {
ws.send('{"config":"2.0"}')
ws2.send('{"config":"2.0"}')
ws3.send('{"config":"2.0"}')
ws4.send('{"config":"2.0"}')
ws5.send('{"config":"2.0"}')
}
function insertQueue(msg) {
//let's just assume all we want is add the data to a queue
queue.push(msg);
}
What's the right way?
Assume the format of the data is identical for all sources.
I considered creating an onError function and use that to connect to the second websocket, and then another onError2 to connect to the third websocket, and so on, but it takes a long time to trigger onError when there is no response, so the complete process of testing a few sources if done in series like that would take far too long.
Found a working solution.
I figured all I needed was to ensure that at least one of them connect, not to ensure that if one of them disconnects the others will be ready to take over.
For this reduced problem, this worked:
//defined higher up
let sucessfulFirstSocketConnection = false
function sendIntro1() {
if(!sucessfulFirstSocketConnection){
sucessfulFirstSocketConnection = true
ws.send(sendString)
ws.onmessage = insertQueue;
ws2.close();
ws3.close();
ws4.close();
ws5.close();
}
}
function sendIntro2() {
if(!sucessfulFirstSocketConnection){
sucessfulFirstSocketConnection = true
ws2.send(sendString)
ws2.onmessage = insertQueue;
ws.close()
ws3.close();
ws4.close();
ws5.close();
}
}
and so on.
I basically let them compete among themselves, and the first one that connects closes the other connections and stops all others from getting in the way. This is achieved very quickly even if only the last WebSocket is the one that is able to connect and all others don't establish a connection.

copy to clipboard from Firestore with Navigator.Clipboard API in ReactJS

I'm new here, and new to coding (started learning when the whole pandemic shenanigans started) right now working on a ReactJS project. one of the element I want my app to do is: on click of button copy text from Cloud Firestore.
How I have my code set up it gets today's timestamp as to when the button was pressed and pushes it to an array pressedOnDates (has dates of all the times the button was pressed) and also updates the date in lastPressedOn (last time it was pressed on) Then using Navigator.Clipboard I copy sampleMessage out of that item's document (why I used it, idk? maybe had something to do with my laziness, and maybe because I saw this feature on home brew's website and they used it, and it worked on there website) Lastly, I have a function call to a function that updates or "repulls" data from Cloud Firestore, and because I get new data fed to my components they redraw in ascending order, component that was just pressed on moves to the bottom and the component that was pressed some time ago moves to the top.
Problem I'm having: this line of code "await navigator.clipboard.writeText(item.sampleMessage);" doesn't work on iPhones or iPads, and because there is no break and it is an await the app is stuck on this broken line of code, and 1. the app never copies the sample message, and 2. (even though it pushes new timestamps to Cloud Firestore) data never gets "repulled" and components never redraw. this code works perfectly fine on MacBook and Android phone (at least as I intended: pushes Timestamp, copies message, and redraws)
Here's my code:
const handleUpdateDate = async (itemID, item) => {
try {
const todayTimestamp = Timestamp.fromDate(new Date());
await db
.collection('sample')
.doc(itemID)
.update({
pressedOnDates: firestore.FieldValue.arrayUnion(todayTimestamp),
lastPressedOn: todayTimestamp,
});
await navigator.clipboard.writeText(item.sampleMessage);
await updateItems();
} catch ({ message }) {
console.error(`Error # handleUpdateDate, Error:${message}`);
}
};
If you can please help me out and point out what's wrong with my code, or suggest a different way to copy to clipboard, I would be more than grateful. Thank you to all of you in advance. May StackOverflow always have an answer to you're question. May the Dark Themes repel all your bugs 🙂. Wish you all the very best.
#jacobvr (good friend) helped me out on Github.
He told me to setup the fn like so:
copy to clipboard (navigator.clipboard)
push to pressedOnDates[] and update lastPressedOn
updateItems
His explanation: "this way you are not waiting for db call to finish to copy to clipboard"
What he proposed:
const handleUpdateDate = async (itemID, item) => {
try {
const todayTimestamp = Timestamp.fromDate(new Date());
await navigator.clipboard.writeText(item.sampleMessage);
await db
.collection('sample')
.doc(itemID)
.update({
pressedOnDates: firestore.FieldValue.arrayUnion(todayTimestamp),
lastPressedOn: todayTimestamp,
});
await updateItems();
} catch ({ message }) {
console.error(`Error # handleUpdateDate, Error:${message}`);
}
};
This is how I set it up ( both ways work on all devices, but copy to clipboard
has to be first action in the fn ):
const copySampleMessage = async (item) => {
try {
await navigator.clipboard.writeText(item.sampleMessage);
} catch ({ message }) {
alert(`Error # copySampleMessage, Error:${message}`);
}
};
const handleUpdatePressedOnDate = async (itemID, item) => {
try {
const todayTimestamp = Timestamp.fromDate(new Date());
await copySampleMessage(item);
await db
.collection('items')
.doc(itemID)
.update({
pressedOnDates: firestore.FieldValue.arrayUnion(todayTimestamp),
lastPressedOn: todayTimestamp,
});
await updateItems();
} catch ({ message }) {
alert(`Error # handleUpdatePressedOnDate, Error:${message}`);
}
};
Thank you to all who responded and helped out with my question, wish y'all the best.

How to resolve an async issue

Firstly, let me preface by saying I am not a developer by any means. I have a tiny coding background which I'm attempting to rely on here, but its failing me.
My problem is as follows:
I have some code which is basically a bot that performs jobs on the ethereum network for smart contracts. The code is entirely in javascript so the blockchain aspect of what I'm attempting to do is immaterial. But basically I am trying to perform an API request which receives a number (called "gas") this number determines how much my bot is willing to pay in order to perform a job on the ethereum network. However, I've learned the default number the API sends is too low. So I've decided to try and increase the gas by multiplying the number gotten from the API request. However when I do that, it seems the code tried multiplying the number before it receives the API request. Consequently, I receive a NaN error. The original code looks like the following:
async work() {
this.txPending = true;
try {
const gas = await this.getGas();
const tx = await this.callWork(gas);
this.log.info(`Transaction hash: ${tx.hash}`);
const receipt = await tx.wait();
this.log.info(`Transaction confirmed in block ${receipt.blockNumber}`);
this.log.info(`Gas used: ${receipt.gasUsed.toString()}`);
} catch (error) {
this.log.error("While working:" + error);
}
this.txPending = false;
}
The changes I make look like the following:
async work() {
this.txPending = true;
try {
let temp_gas = await this.getGas();
const gas = temp_gas * 1.5;
const tx = await this.callWork(gas);
console.log(gas);
console.log('something');
const receipt = await tx.wait();
this.log.info(`Transaction confirmed in block ${receipt.blockNumber}`);
this.log.info(`Gas used: ${receipt.gasUsed.toString()}`);
} catch (error) {
this.log.error("While working:" + error);
}
this.txPending = false;
}
From my research, it seems what I need to do is create a promise function, but I am absolutely lost on how to go about creating this. If anyone could help me, I'd be willing to pay them a bit of ethereum maybe .2 (roughly $150).
Technically, you can not determine the gas cost of the transaction, but immediately set some rather large value for gas, for example, 0x400000. The miner will take from this amount as much as necessary, and leave the excess on your account. This is the difference between Ethereum and Bitcoin - in Bitcoin the entire specified fee will be taken by the miner.

SQLite error "No such column" when I can see that the column exists

The backstory here is that I'm working on a Discord bot. One of the requested functions is having it lob insults. I thought it would be fun to give users the ability to add insults via a SQLite 3 database (specifically, better-sqlite3), and in doing so, I also want to keep track of the most recent use of each insult (this is for future use in an "insultinfo" type command). I added a DATETIME column called "lastUsed". My insultadd command is able to write to this column when new insults are added. The issue is when I call the insult command, it's supposed to say the insult and then update the lastUsed field with the current date. Pasting the code below.
The problem is that I'm getting an error that says "SQLiteError: no such column:" and then it prints the date value even though I'm trying to update the lastUsed column and I can't figure out how to resolve this. The issue has to be in the db.prepare statement, I'm just not seeing what I need to do to fix it.
execute(msg, args) {
const SQLite = require("better-sqlite3");
const db = new SQLite('./userinputs.sqlite');
// Check if the table "userinputs" exists and has content from this guild.
const table = db.prepare(`SELECT count(*) FROM userinputs WHERE (guild = ${msg.guild.id} OR guild = 'Global') AND type = 'insult';`).get();
if (!table['count(*)']) {
return msg.channel.send("I don't have any insults yet");
}
var date = new Date();
const rawInsult = db.prepare(`SELECT * FROM userinputs WHERE type = 'insult' AND (guild = ${msg.guild.id} OR guild = 'Global') ORDER BY RANDOM() LIMIT 1;`).get();
const insult = rawInsult['content'];
const insultID = rawInsult['row'];
if (args[0]) {
var target = args[0];
} else {
var target = msg.author.username;
}
if (insult.includes('{}')) {
var finalInsult = insult.replace('{}', target);
} else {
var finalInsult = target + ' ' + insult;
}
msg.channel.send(finalInsult);
db.prepare(`UPDATE userinputs SET lastUsed = "${date}" WHERE row = ${insultID};`).run();
},
I think I got it. I ended up using date.toString() and it appears to have done the job. The error message I got after updating the db.prepare statement indicated it wasn't viewing that date variable as something it could work with, hence the .toString() workaround. I'll have to test this to see if that impacts my ability to sort on that column, since this is still all a pretty new to me, but at least the command itself is working and the database table is updating.
I'm open to more feedback though if anyone sees the probable folly in my ways here.
UPDATE: Upon further testing, setting date = Math.floor(new Date() / 1000) ended up working better in my case.

Set Timeout not working in React Native - Debug JS Remotely

I drove myself nuts trying to figure out what the problem is with my code. I am building a React Native application and developing in the IOS Simulator after running run-ios. I enabled Debug JS Remotely so I can verify the condition of my tokens returned from the server.
I am attempting to build a simple service that will refresh my tokens using a setTimeout.
let sessionTimeout = null;
export const session = (response) => {
let tokens = response.tokens;
Store.set(tokens);
setSessionTimeout(tokens.access.expiresIn);
};
const setSessionTimeout = (duration) => {
let time = duration - 5000;
clearTimeout(sessionTimeout);
sessionTimeout = setTimeout(() => {
console.log('settimeout called');
refreshToken();
}, 1000);
};
const refreshToken = () => {
let tokens = Store.get();
refresh(tokens)
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error);
});
};
In the above code a began my initial test by hardcoding 1000 and it worked fine. It successfully made the call to my server. I then attempted to implement the proper time duration and found it does not work. Even by replacing the 1000 with 2000 causes it to fail and the call to the backend is never made.
I then tried using the following packages and got the same result:
react-native-timer
react-timer-mixin
After banging my head on the wall for two days and having another attempt on stack shot down because my issue could not be reproduced I disabled the Debug JS Remotely and everything works as expected.
However now I am wondering how I am supposed to debug the frontend portion of my application with out the use of this feature. If anyone has any ideas or advice on issues like this I would appreciate the feedback as this is my first React Native app.

Categories

Resources