I am getting an error while running the command npm start. The file is created in PancakeSwap Frontend and I've been trying to fix this for a while, thanks for your help :)
Here is my App.js code:
import React, { useState, useEffect } from "react";
import SimpleStorageContract from "./contracts/SimpleStorage.json";
import getWeb3 from "./getWeb3";
import BlockchainContext from './BlockchainContext.js';
import "./App.css";
function App() {
const [storageValue, setStorageValue] = useState(undefined);
const [web3, setWeb3] = useState(undefined);
const [accounts, setAccounts] = useState([]);
const [contract, setContract] = useState([]);
useEffect(() => {
try {
// Get network provider and web3 instance.
const web3 = await getWeb3();
// // Use web3 to get the user's accounts.
const accounts = await web3.eth.getAccounts();
// // Get the contract instance.
const networkId = await web3.eth.net.getId();
const deployedNetwork = SimpleStorageContract.networks[networkId];
const contract = new web3.eth.Contract(
SimpleStorageContract.abi,
deployedNetwork && deployedNetwork.address,
);
// Set web3, accounts, and contract to the state, and then proceed with an // example of interacting with the contract's methods.
setWeb3(web3);
setAccounts(accounts);
setContract(contract);;
this.setState({ web3, accounts, contract: instance } catch (error) {
// Catch any errors for any of the above operations.
alert(
`Failed to load web3, accounts, or contract. Check console for details.`,
);
console.error(error);
const init = async() => {
}
init();
}, []);
useEffect(() => {
const load = async () => {
// Stores a given value, 5 by default.
await contract.methods.set(5).send({ from: accounts[0] });
// // Get the value from the contract to prove it worked.
const response = await contract.methods.get().call();
// // Update state with the result.
setStorageValue(response);
}
if(typeof web3 !== 'undefined'
&& typeof account !== 'undefined'
&& typeof contract !== 'undefined'{
load();
}
}, [web3, accounts, contract]);
if(typeof web3 === 'undefined') {
return <div>Loading Web3, account, and contract...</div>;
}
return (
<div className="App">
<BlockchainContext.Provider value={{web3, accounts, contract}}>
<h1>Good to Go!</h1>
<p>Your Truffle Box is installed and ready.</p>
<h2>Smart Contract Example</h2>
<p>
If your contracts compiled and migrated successfully, below will show
a stored value of 5 (by default).
</p>
<p>
Try changing the value stored on <strong>line 42</strong> of App.js.
</p>
<div>The stored value is: {storageValue}</div>
</BlockchainContext.Provider>
</div>
);
}
export default App;
And the error which I am getting is:
Failed to compile.
./src/App.js
Line 17:23: Parsing error: Can not use keyword 'await' outside an async function
15 | try {
16 | // Get network provider and web3 instance.
> 17 | const web3 = await getWeb3();
| ^
18 |
19 | // // Use web3 to get the user's accounts.
20 | const accounts = await web3.eth.getAccounts();
The code provided is pretty messy, but it looks like you are trying to use the await keyword in a synchronous function, specifically the function being passed as an argument into useEffect(). The await keyword can only be used inside asynchronous functions.
If you can, the easiest solution would be to make the function asynchronous by adding the async keyword (demonstrated below).
function App() {
const [storageValue, setStorageValue] = useState(undefined);
const [web3, setWeb3] = useState(undefined);
const [accounts, setAccounts] = useState([]);
const [contract, setContract] = useState([]);
useEffect(async () => {
If that won't work, you could use .then() instead (demonstrated below), however this will require more work.
function App() {
const [storageValue, setStorageValue] = useState(undefined);
const [web3, setWeb3] = useState(undefined);
const [accounts, setAccounts] = useState([]);
const [contract, setContract] = useState([]);
useEffect(() => {
try {
// Get network provider and web3 instance.
getWeb3().then(web3=>{
// code goes here
}).catch(err=>{
// error handling
});
I also recommend reading a little about async/await if you haven't already. This MDN article is a good place to start.
Related
I'm sorry for my English. I'm using a translator. I have the following problem. I'm trying to use a function from another component, but it gives me the following error.
I will leave the code extract:enter image description here
I used useEffect to display the data for an id depending if that id has records:
export async function getOrderByTableApi(idTable, status= "", ordering= ""){
try {
const tableFilter = `table=${idTable}`;
const statusFilter = `status=${status}`;
const closeFilter = "close=false";
const url = `${BASE_API}/api/orders/?${tableFilter}&${statusFilter}&${closeFilter}&${ordering}`;
const response = await fetch(url);
const result = await response.json();
return result;
} catch (error) {
throw error;
}
}
the function comes from another component as follows:
import { getOrderByTableApi } from "../api/orders";
export function useOrder(){
const [setLoading] = useState(true);
const [setError] = useState(false);
const [setOrders] = useState(null);
const getOrderByTable = async (idTable, status, ordering) => {
try {
setLoading(true);
const response = await getOrderByTableApi(idTable, status, ordering);
setLoading(false);
setOrders(response);
} catch (error) {
setLoading(false);
setError(error);
}
};
return{
getOrderByTable,
};
}
and when using it, the console tells me that getOrderByTable is not a function
import { useTables } from "../../hooks";
export function OrdersHistory() {
const [idTable, setIdTable] = useState(null);
const { getOrdersByTable } = useOrder();
const { getTableByNumber } = useTables();
useEffect(() => {
(async () => {
const table = await getTableByNumber(tableNumber);
const idTableTemp = table[0].id;
setIdTable(idTableTemp);
**getOrdersByTable(idTableTemp, "", "ordering=-status,-created_at");**
})();
}, []);
return (
<p>Help please</p>
);
}
adjunto imagen
There is a typing mistake in your code. You're exporting the function as getOrderByTable from your custom hook useOrder but you're importing it as getOrdersByTable instead of getOrderByTable in your OrdersHistory component.
If you want to rename your function, you can do it as below
const { getOrderByTable as getOrdersByTable } = useOrder();
I appreciate the review, due to fatigue I did not notice that the name of the function did not match a letter and that is why it gave me an error, I will take the recommendation to copy and paste the names of the functions in the future, I consider this question closed. Thank you so much.
I am trying to get a cookie from the middleware of Nextjs 13 and I can't find up to date information on this.
My question: is there a way to see the cookie before rendering the html.
window is fined or something?
page.tsx
async function getData() {
const nextCookies = cookies(); // Get cookies object
try {
let cityToken = nextCookies.get('regionCode'); // Find cookie city
return cityToken;
} catch (e) {
console.log(e);
}
}
export default async function Page() {
const nextCookies = cookies(); // Get cookies object
const token = nextCookies.get('new'); // Find cookie for is new user
// const cityToken = await getData();
const cityToken = cookies().get('regionCode')?.value;
console.log(cityToken);
}
middleware.tsx
const myFunction = async () => {
// https://geolocation.onetrust.com/cookieconsentpub/v1/geo/location
// run asynchronous tasks here - ip location
const response = await fetch('https://www.cloudflare.com/cdn-cgi/trace');
const text = await response.text();
const arr = text.split('\n');
const ip = arr.filter((v) => v.includes('ip='))[0].split('=')[1];
// https://stackoverflow.com/questions/65752416/how-can-i-most-easily-parse-this-http-response-into-json-to-then-access-response
// https://stackoverflow.com/questions/64591296/access-to-fetch-at-https-www-cloudflare-com-cdn-cgi-trace-from-origin-http
const ipCity = await fetch(`https://ipapi.co/${ip}/json/`);
const textJson = await ipCity.json();
};
const data = await myFunction();
res.cookies.set('regionCode', 'textJson.region');
I am using web3 function getPastEvents and I am getting error:
Returned error: limit exceeded
I also changed RPC url but same error occured their.
Is there any other way to get event data ?
this is my code:
const http = require("http");
const cron = require('node-cron');
const { randomBytes } = require("crypto");
const web3 = new Web3("https://bsc-dataseed.binance.org/");
//console.log("Hello This",web3);
//console.log("hello");
const dexABI =contractAbi;
const contract_address = "0xd19EA9d72828444BC7bAE231fBa66F8050e72b1b";
const contract = new web3.eth.Contract(dexABI, contract_address);
async function generateEventQuery(result) {
console.log(result);
return ;
}
http
.createServer((req, res) => {
web3.eth
.getBlockNumber()
.then((d) => {
let current_block = d;
console.log(current_block);
contract
.getPastEvents({
fromBlock: Number(23390147),
toBlock: Number(23390147)+100,
})
.then( async(events) => {
let resu = await generateEventQuery(events);
})
.catch((e) => {
console.log("Err",e)
res.write("Err:" + JSON.stringify(e));
res.end();
});
})
.catch((e) => e);
})
.listen(8080);
in the function getPastEvents() you have to take the first parameter as your event name which you want to fetch the data. The name should be as same as in your contract and passed into a string.
Actually, this is an RPC problem. I replaced https://bsc-dataseed.binance.org/ with https://bscrpc.com. Now it works properly.
Public RPC URLs like https://bsc-dataseed.binance.org/ or https://bscrpc.com have rate-limiting to prevent people from over using it.
It's fine for testing but in production you should use your own node or a blockchain API like Infura, Alchemy, QuickNode or any other.
I have a NFT deployed on the mainnet, and I want to listen any mint event by watching the Transfer event via web3js. But unfortunately I am not able to retrieve any Transfer event happening. But the thing is that, when I try to getPastEvents, I successfully retrieve the correct data so it is most likely not due to another part of the code.
Here is my relevant piece of code:
const Web3 = require('web3')
const nodeClient = require('node-rest-client-promise').Client()
const dotenv = require('dotenv')
dotenv.config()
const CONTRACT_ADDRESS = '0x8d4B648F7fAB1c72d1690b42693fb7525ce3025e'
const projectId = process.env.INFURA_KEY
const etherscanKey = process.env.ETHERSCAN_KEY
const etherscan_url = `http://api.etherscan.io/api?module=contract&action=getabi&address=${CONTRACT_ADDRESS}&apikey=${etherscanKey}`
async function getContractAbi() {
const etherscan_response = await nodeClient.getPromise(etherscan_url)
const CONTRACT_ABI = JSON.parse(etherscan_response.data.result);
return CONTRACT_ABI;
}
async function handleTransferEvent(event) {
try{
const fromAddress = event.returnValues.from
const tokenId = event.returnValues.tokenId
console.log("SOMEONE TRANSFERED NFT!")
if(fromAddress == '0x0000000000000000000000000000000000000000') {
console.log("Minted:\n", event.returnValues)
/* Do stuff */
}
}
catch(err) {
console.log(err)
console.log("ERROR WHILE HANDLING TRANSFER EVENT")
}
}
const init = async () => {
var web3 = new Web3('wss://mainnet.infura.io/ws/v3/' + projectId)
console.log("Connected to mainnet")
const CONTRACT_ABI = await getContractAbi()
console.log("Retrieved contract abi")
const contract = new web3.eth.Contract(
CONTRACT_ABI,
CONTRACT_ADDRESS
)
contract.events.Transfer({})
.on('data', handleTransferEvent)
.on('error', console.error)
console.log('Started listening minting events...')
}
init()
You can check the smart contract from https://etherscan.io/address/0x8d4b648f7fab1c72d1690b42693fb7525ce3025e#code
EDIT: I think problem might be related to calling listen event inside a function.
I'm testing Firebase functions using Jest and the emulator, though the tests are flakey presumably from a race condition. By flakey, I mean sometimes they pass and sometimes they don't, even on the same machine.
Tests and functions are written in TypeScript, then transpiled with babel.
Example test/function
Note: This is an example of just one of the flakey tests. Many other tests are flakey. A solution is preferably one that doesn't just solve this one case, but rather the general issue.
The test
import { onProfilesWrite } from '../src/profiles/on-write'
import { initializeAdminApp } from '#firebase/rules-unit-testing'
const admin = initializeAdminApp({ projectId: 'projectId' }).firestore()
const wrappedFunction = testEnvironment.wrap(onProfilesWrite)
const profilePath = `profiles/${uid}`
const customerProfile = {
roles: ['customer'],
slug: 'slug',
image: 'image.png',
fullName: 'John Smith',
}
const publisherRoles = ['customer', 'publisher']
const publisherProfile = {
...customerProfile,
roles: publisherRoles,
}
const createChange = async (
before: Record<string, unknown> | undefined,
changes: Record<string, unknown>
) => {
const publisherStatsRef = admin.doc(profilePath)
if (before) await publisherStatsRef.set(before)
const beforeSnapshot = await publisherStatsRef.get()
await publisherStatsRef.set(changes, { merge: true })
const afterSnapshot = await publisherStatsRef.get()
return testEnvironment.makeChange(beforeSnapshot, afterSnapshot)
}
test('If user profile is created as a publisher, publisherDetails is created', async () => {
const change = await createChange(undefined, publisherProfile)
await wrappedFunction(change)
const snapshot = await admin.doc(`profileDetails/${uid}`).get()
const data = snapshot.data()
expect(data).toBeTruthy()
expect(data?.id).toBeTruthy()
expect(data?.slug).toBe(publisherProfile.slug)
expect(data?.profileImage).toBe(publisherProfile.image)
expect(data?.publisherName).toBe(publisherProfile.fullName)
expect(data?.music).toMatchObject([])
})
Run the test
firebase emulators:exec \"jest functions/__tests__ --detectOpenHandles\" --only firestore
Output
If user profile is created as a publisher, publisherDetails is created
expect(received).toBeTruthy()
Received: undefined
46 | const snapshot = await admin.doc(`profileDetails/${uid}`).get()
47 | const data = snapshot.data()
> 48 | expect(data).toBeTruthy()
| ^
49 | expect(data?.id).toBeTruthy()
50 | expect(data?.slug).toBe(publisherProfile.slug)
51 | expect(data?.profileImage).toBe(publisherProfile.image)
The function
import * as functions from 'firebase-functions'
// initializes the admin app, then exports admin.firestore
import { firestore } from '../admin'
const database = firestore()
const createPublisherId = async (): Promise<string> => {
let id = ''
const MAX_NUMBER = 1000000
while (id === '') {
const temporaryId = String(Math.ceil(Math.random() * MAX_NUMBER))
const snapshot = await firestore()
.collection('publisherDetails')
.where('sku', '==', temporaryId)
.limit(1)
.get()
if (snapshot.empty) id = temporaryId
}
return id
}
export const createPublisherDetails = async (
newData: firestore.DocumentData,
uid: string
): Promise<void> => {
const id = await createPublisherId()
await database.doc(`publisherDetails/${uid}`).set(
{
id,
slug: newData.slug,
publisherName: newData.fullName,
profileImage: newData.image,
music: [],
},
{ merge: true }
)
}
export const onProfilesWrite = functions.firestore.document('profiles/{uid}').onWrite(
async (change): Promise<void> => {
const { id: uid } = change.after
const oldData = change.before.data()
const newData = change.after.data()
if (
newData?.roles?.includes('publisher') &&
(typeof oldData === 'undefined' || !oldData.roles?.includes('publisher'))
)
await createPublisherDetails(newData, uid)
}
)
Debug steps
All promises are awaited in the cloud functions (as affirmed by an ESLint rule #typescript-eslint/no-floating-promises)
Also converted the tests to Mocha (as suggested by the Firebase docs), same errors
Converting async/await in tests to promise.then() syntax
Metadata
OS: macOS 11.2, Ubuntu 18.04
Jest: 26.6.3
Firebase: 8.2.6
Firebase tools: 9.3.0
As comments roll in, with either questions or suggestions, I'll continue to update this post.
Change your test portion to as follows :
test('If user profile is created as a publisher, publisherDetails is created', async () => {
const change = await createChange(undefined, publisherProfile)
await wrappedFunction(change)
const documentObject = await admin.doc(`profileDetails/${uid}`)
const snapshot = await documentObject.get()
const data = snapshot.data()
expect(data).toBeTruthy()
expect(data?.id).toBeTruthy()
expect(data?.slug).toBe(publisherProfile.slug)
expect(data?.profileImage).toBe(publisherProfile.image)
expect(data?.publisherName).toBe(publisherProfile.fullName)
expect(data?.music).toMatchObject([])
})
Reason being that in your test region, your use of await is a bit incorrect (function chaining on an object that is being waited for is a big no-no in the same calling line)