import { WalletConnectConnector } from "#web3-react/walletconnect-connector";
I have used this for connecting walletconnect through QR code and used useWeb3React for connecting to wallet.
Metamask extension is working fine but not able to use walletconnect for transactions.
const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY;
const { createAlchemyWeb3 } = require("#alch/alchemy-web3");
var web3 = createAlchemyWeb3(alchemyKey);
const transactionParameters = [
{
method: "eth_sendTransaction",
params: [
{
to: contractAddress, // Required except during contract publications.
from: acct, // must match user's active address.
data: window.contract.methods.mintNFT(acct, tokenURI).encodeABI(), //make call to NFT smart contract
},
],
},
];
await web3.eth
.sendTransaction(transactionParameters)
.on("receipt", (receipt) => {
console.log(receipt, "receipt");
})
.on("transactionHash", (hash) => {
console.log(hash, "hash");
})
.on("error", (err) => {
console.log(err, "error");
});
The above works fine with metamask extension but not with Walletconnect.
I think the issue is with your web3 provider. Try to get web3 provider from useWeb3React itself.
eg:
const provider = connector.getProvider();
const web3 = new Web3(provider)
use this web3 to send transaction
Related
I wanted to use web3JS config without using external wallets like metamask. To handle automated functions using cron jobs which are supposed to run every week. Since metamask asks for permission to use send() method to remove that I wanted to use a account where I will upload private key and stuff. I got this code from internet it works for locally/browser wallets dont know where to edit.
import Web3 from "web3";
const getWeb3 = () =>
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();
// Accounts now exposed
resolve(web3);
console.log("enabled", web3);
console.log("MetaMask injected");
} catch (error) {
reject(error);
}
}
// Legacy dapp browsers...
else if (window.web3) {
// Use Mist/MetaMask's provider.
const web3 = window.web3;
// const web3 = window.web3.currentProvider.enable();
console.log("Injected web3 detected.");
resolve(web3);
}
// Fallback to localhost; use dev console port by default...
else {
const provider = new Web3.providers.HttpProvider(
"http://127.0.0.1:7545"
);
const web3 = new Web3(provider);
console.log("No web3 instance injected, using Local web3.");
resolve(web3);
}
});
});
export default getWeb3;
solved it
const Web3 = require("web3");
const WalletProvider = require("#truffle/hdwallet-provider");
let provider = new WalletProvider({
mnemonic: {
phrase:
"*******",
},
providerOrUrl: "https://goerli.infura.io/v3/****************",
});
const web3 = new Web3(provider);
const fetch123 = async () => {
const accounts = await web3.eth.getAccounts();
console.log(accounts);
};
fetch123();
I want to call a payable function in a smart contract I deployed, but it does not work. This is the error I am getting:
Error: Returned error: The method eth_sendTransaction does not exist/is not available
The answer I could find is to just use a private key, because infura does not cater this method, however I want the user to sign the transaction to the smart contract with MetaMask.
This is my code:
export async function helloworld() {
const rpcURL =
"https://ropsten.infura.io/v3/KEY";
const web3 = new Web3(rpcURL);
let provider = window.ethereum;
if (typeof provider !== "undefined") {
provider
.request({ method: "eth_requestAccounts" })
.then((accounts) => {
selectedAccount = accounts[0];
console.log(`Selected account is ${selectedAccount}`);
})
.catch((err) => {
console.log(err);
return;
});
window.ethereum.on("accountsChanged", function (accounts) {
selectedAccount = accounts[0];
console.log(`Selected account changed to ${selectedAccount}`);
});
}
const networkId = await web3.eth.net.getId();
const thecontract = new web3.eth.Contract(
simpleContractAbi,
"0x50A404efF9A057900f87ad0E0dEfA0D485931464"
);
isInitialized = true;
investit(thecontract, selectedAccount);
}
and this is the code that actually throws the error:
export const investit = async (thecontract, selectedAccount) => {
if (!isInitialized) {
await helloworld();
}
thecontract.methods
.invest()
.send({ from: selectedAccount, value: 10000 })
.catch(function (err) {
console.log(err);
});
};
I am completely lost, since if I use the normal window.ethereum.request (https://docs.metamask.io/guide/sending-transactions.html#example) to send a transaction, metamask opens up and I can sign it. With the contract call it simply does not work.
Do you know the reason? How can I fix this?
This must be the issue. you are just passing an url:
const rpcURL ="https://ropsten.infura.io/v3/KEY";
instead:
const web3 = new Web3(new Web3.providers.HttpProvider("https://ropsten.infura.io/v3/KEY"))
eth_sendTransaction requires you holding the private key to sign the transaction before broadcasting it to the network. Infura doesn’t maintain any private keys. In order to send a transaction, you need to sign the transaction on your end with your private key.
The way you check providers is not correct. window.ethereum is also a provider which is provided by metamask. provider itself is meaningless, it has to be injected into the new Web3().
I'm developing a dApp using web3 library. In some case the user has to decide how they want to connect, either MetaMask or WalletConnect.
So, when the user decides to connect with WalletConnect there is no problem with the connection itself but I have an issue when I want to interact with Smart Contract. Suppose I want to approve to user amount for stake or check the balance.
export const schooseProvider = provider => {
// debugger
console.log("schooseProvider: ", provider );
if(provider === "MetaMask"){
console.log("Selected Provider: ", window.ethereum)
W3 = new Web3(window.ethereum)
}
else if(provider === "WalletConnect"){
const provider = new WalletConnectProvider({
infuraId: '20c6beb49cd1402db84120a858bc74af',
bridge: 'https://bridge.walletconnect.org',
supportedChainIds,
rpc: {
3: 'https://ropsten.infura.io/v3/20c6beb49cd1402db84120a858bc74af'
}
})
console.log("Selected Provider: ", provider)
W3 = new Web3(provider)
}
}
export const approve = async (account) => {
try{
store.dispatch(updateAproveButtonsLoader(true))
await contract.methods.approve(stakeAddress,'10000000000000000000000000000000000000000000000000').send({from: account})
.once('receipt', function(receipt){
store.dispatch(updateApproveButtonsLoader(false))
store.dispatch(updateApproved(true))
checkAllowence(account)
})
.on('error', () => {
store.dispatch(updateApproveButtonsLoader(false))
})
}
catch(error){
store.dispatch(updateApproveButtonsLoader(false))
console.log(error)
}
}
Trust Wallet doesn't support testnets for now, however you can add it as custom chain
I'm trying to send USDT (custom token) with the metamask API using web3. I'm developing on ReactJS and I could detected correctly the user account from metamask.
My code:
const web3 = new Web3(window.web3.currentProvider);
const contractInstance = new web3.eth.Contract(abiUSDT, addressUSDT);
const amount = 200;
const tx = {
from: 'PERSON_SENDER',
to: contractInstance._address,
data: contractInstance.methods.transfer('PERSON_RECIPIENT', web3.utils.toWei( amount.toString() ) ).encodeABI(),
}
web3.eth.sendTransaction(tx).then(res => {
console.log("res",res)
}).catch(err => {
console.log("err",err)
});
obviously, I replace the fields called: PERSON_SENDER and PERSON_RECIPIENT with:
PERSON_SENDER: The user account
PERSON_RECIPIENT: My personal account (I want to deposit in this account)
Using this config, the transaction doesn't send to my account when I check in etherscan (and the amount was sent to the address of the contract), and a user communicate that if he uses real values for him real account, metamask doesn't touch his amount.
I made the same code and it works. But check the correct ABI, and adrresses format. The address "FROM" must be tha same address that your metamask is conected.
My code:
var contractABI = [{"YOUR TOKEN ABI HERE"}]
addressUSDT = "0xf80e1C5e28226cAfc7B0Ee6729E553ef54A7774F"; //IT'S OTHER CONTRACT
const web3 = new Web3(window.web3.currentProvider);
const contractInstance = new web3.eth.Contract(contractABI, addressUSDT);
const amount = 200;
const tx = {
from: '0x2acd4F50ee814d5092d9FC892d2BDEab91f5594d',
to: contractInstance._address,
data: contractInstance.methods.transfer('0xe54356F4e1aD4215973E7180BeBb4644a07DF508', web3.utils.toWei( amount.toString() ) ).encodeABI(),
}
web3.eth.sendTransaction(tx).then(res => {
console.log("res",res)
}).catch(err => {
console.log("err",err)
});
I'm trying to send ethereum transaction that sends ERC20 tokens to someone with Ledger Nano S through Node.JS but I'm not able to successfully sign and send this transaction.
First of all, I signed the transaction through the method, signTransaction, of ledgerhq API and then after signing it, I sended it to the main net by using sendSignedTransaction. When I execute below code, Ledger receives request and shows details of a transaction. However, after pressing Ledger's confirm button, the console returns error 'Returned error: Invalid signature: Crypto error (Invalid EC signature)'.
import AppEth from "#ledgerhq/hw-app-eth";
import TransportU2F from "#ledgerhq/hw-transport-u2f";
import TransportNodeHid from "#ledgerhq/hw-transport-node-hid";
import EthereumTx from "ethereumjs-tx"
const Web3 = require('web3');
import { addHexPrefix, bufferToHex, toBuffer } from 'ethereumjs-util';
const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
var destAddresses = ['0xa6acFa18468786473269Dc1521fd4ff40F6481D9'];
var amount = 1000000000000;
var i=0;
var contract = new web3.eth.Contract([token contract ABI... ], '0x74a...');
const data1 = contract.methods.transfer(destAddresses[0], amount).encodeABI();
const exParams = {
gasLimit: 6e6,
gasPrice: 3e9,
from: '0x1A...',
data : data1,
to: '0x74a...',
value: '0x00',
nonce: "0x0",
chainId: 1,
v: "0x01",
r: "0x00",
s: "0x00"
}
async function makeSign(txParams) {
const tx = new EthereumTx(txParams);
const txHex = tx.serialize().toString("hex");
const signedTransaction = '0x' + txHex;
let transport;
try {
transport = await TransportNodeHid.create();
let eth2 = new AppEth(transport);
const result = await eth2.signTransaction("m/44'/60'/0'/0", txHex).then(result => {
web3.eth.sendSignedTransaction('0x' + txHex)
.then(res => {
console.log(res);
}).catch(err => {
console.log('sendSignedTransaction');
console.log(err);
});
}).catch(err => {
console.log('signTransaction');
console.log(err);
});
txParams.r = `0x${result.r, 'hex'}`;
txParams.s = `0x${result.s, 'hex'}`;
txParams.v = `0x${result.v, 'hex'}`;
return result;
} catch (e) {
console.log(e);
}
}
makeSign(exParams).then(function () {
console.log("Promise Resolved2");
}.catch(function () {
console.log("Promise Rejected2");
});
When I only use signTransaction function, I can confirm the transaction in the ledger device and return txhash on the console. However, ultimately I want to broadcast a transaction to the main net. Could you please give me any idea? I want any feedback. Also, if there are any examples of creating and broadcasting a raw transaction by using the ledger, notice me please.
Your code already sends the transaction to the network. However, just awaiting the "send" promise only gives you the transaction hash, not the receipt. You need to treat it as an event emitter and wait for the 'confirmation' event.
const serializedTx = tx.serialize();
web3.eth.sendSignedTransaction(serializedTx.toString('hex'))
.once('transactionHash', hash => console.log('Tx hash', hash))
.on('confirmation', (confNumber, receipt) => {
console.log(`Confirmation #${confNumber}`, receipt);
})
.on('error', console.error);
To send it to mainnet as you mention, you can either run a local geth node on port 8545 and use your code unchanged, or point web3 at infura or similar.