I am following the documentation to be able to sign and send a transaction on the Kovan testnet. I am currently getting an undefined value when I console out the txHash.
web3.eth.getTransactionCount(account1, (err, txCount) => {
// 1)Build Transaction
const txObject = {
nonce: web3.utils.toHex(txCount),
to: account2,
value: web3.utils.toHex(web3.utils.toWei('0.05', 'ether')),
gasLimit: web3.utils.toHex(2100),
gasPrice: web3.utils.toHex(web3.utils.toWei('10', 'gwei'))
}
// 2)Sign Transaction
const tx = new Tx(txObject,{'chain':42})
tx.sign(privateKey1)
const serializedTransaction = tx.serialize()
const raw = '0x' + serializedTransaction.toString('hex')
console.log("raw:", raw)
console.log("tx:", serializedTransaction)
// 3)Broadcast Transaction
web3.eth.sendSignedTransaction(raw, (err, txHash) =>{
console.log('txHash:', txHash)
})
// COMMENTED-OUT web3.eth.sendSignedTransaction('0x' + serializedTransaction .toString('hex'))
// .on('receipt', console.log);
})
signTransaction() only performs the signature. It doesn't broadcast the (signed) transaction to the network.
For that, you can use sendSignedTransaction() (docs), which submits the (signed and serialized) tx data to the provider, and the provider broadcasts it to the network.
web3.eth.sendSignedTransaction(signedTx.rawTransaction)
.on('receipt', console.log);
Related
When it goes to transfer, it shows the wrong token in the metamask
(async ()=>{
const contract = new web3.eth.Contract(ABI, contractAddress);
const transfer = await contract.methods.transfer(reciever, 1);
const data = await transfer.encodeABI();
if(window.ethereum.chainId == '0x61'){
ethereum
.request({
method: 'eth_sendTransaction',
params: [
{
from: ethereum.selectedAddress,
to: reciever,
gasPrice: '1000000',
gas: '',
data: data,
},
],
})
.then((txHash) => console.log(txHash))
.catch((error) => console.error);
} else {
ethereum.request({ method: 'wallet_switchEthereumChain', params:[{chainId: '0x61'}]})
}
})()
It should show the token, but it shows differently,
When transferring tokens, the transaction needs to be processed by the contract address (not by the token receiver). Note that the contract receiver is passed as the first argument of the transfer() function.
Solution: Replace to: reciever with to: contractAddress in the params section of your snippet.
I'm trying to send a transaction via bsc using WalletConnect and web3
This is the connection code
const provider = new WalletConnectProvider({
rpc: {
1: "https://bsc-dataseed.binance.org/",
2: "https://bsc-dataseed1.defibit.io/",
3: "https://bsc-dataseed1.ninicoin.io/",
// ...
},
});
async function() {
await provider.enable();
// Get Accounts
web3.eth.getAccounts((error, accounts) => {
if (error) alert(error)
this.account = accounts[0]
});
}
And this is the cransaction call
web3.eth.sendTransaction({
to: '0x...',
from: this.account,
value: 1000000000000, //test value
}, ((error, hash) => {
if (error) alert(error)
else console.log(hash)
}));
The problem is that on my trust wallet the transaction is on the ETH blockchain, even if I can read my bsc token balance correctly.
Any ideas?
I'm using the solana-web3.js but can't find any examples for how to create and mint my own tokens. What's the best way to do this?
For this you'll also need to be using our token program js bindings. You can import them via npm as you can see in the sample code below.
const web3 = require('#solana/web3.js');
const splToken = require('#solana/spl-token');
(async () => {
//create connection to devnet
const connection = new web3.Connection(web3.clusterApiUrl("devnet"));
//generate keypair and airdrop 1000000000 Lamports (1 SOL)
const myKeypair = web3.Keypair.generate();
await connection.requestAirdrop(myKeypair.publicKey, 1000000000);
console.log('solana public address: ' + myKeypair.publicKey.toBase58());
//set timeout to account for airdrop finalization
let mint;
var myToken
setTimeout(async function(){
//create mint
mint = await splToken.Token.createMint(connection, myKeypair, myKeypair.publicKey, null, 9, splToken.TOKEN_PROGRAM_ID)
console.log('mint public address: ' + mint.publicKey.toBase58());
//get the token accont of this solana address, if it does not exist, create it
myToken = await mint.getOrCreateAssociatedAccountInfo(
myKeypair.publicKey
)
console.log('token public address: ' + myToken.address.toBase58());
//minting 100 new tokens to the token address we just created
await mint.mintTo(myToken.address, myKeypair.publicKey, [], 1000000000);
console.log('done');
}, 20000);
})();
Here's an example of how you can do that.
Assumptions:
You (mintRequester) have a Phantom wallet.
The minting will take place from a separate minting wallet, and not your Phantom wallet.
Some SOL is air-dropped into this newly created minting wallet to handle the minting charges.
Your new token has 6 decimal places and you are minting 1 token.
The token(s) are finally transferred from your minting wallet to your Phantom wallet.
Code
import * as web3 from '#solana/web3.js';
import * as splToken from '#solana/spl-token';
const getProvider = async () => {
if ("solana" in window) {
const provider = window.solana;
if (provider.isPhantom) {
console.log("Is Phantom installed? ", provider.isPhantom);
return provider;
}
} else {
window.open("https://www.phantom.app/", "_blank");
}
};
const mintingTest = async () => {
const phantomProvider = await getProvider();
const mintRequester = await phantomProvider.publicKey;
console.log("Public key of the mint Requester: ", mintRequester.toString());
//To connect to the mainnet, write mainnet-beta instead of devnet
const connection = new web3.Connection(
web3.clusterApiUrl('devnet'),
'confirmed',
);
//This fromWallet is your minting wallet, that will actually mint the tokens
var fromWallet = web3.Keypair.generate();
// Associate the mintRequester with this wallet's publicKey and privateKey
// This is basically the credentials that the mintRequester (creator) would require whenever they want to mint some more tokens
// Testing the parameters of the minting wallet
console.log("Creator's Minting wallet public key: ",fromWallet.publicKey.toString());
console.log(fromWallet.secretKey.toString());
// Airdrop 1 SOL to the minting wallet to handle the minting charges
var fromAirDropSignature = await connection.requestAirdrop(
fromWallet.publicKey,
web3.LAMPORTS_PER_SOL,
);
await connection.confirmTransaction(fromAirDropSignature);
console.log("Airdropped (transferred) 1 SOL to the fromWallet to carry out minting operations");
// This createMint function returns a Promise <Token>
let mint = await splToken.Token.createMint(
connection,
fromWallet,
fromWallet.publicKey,
null,
6, // Number of decimal places in your token
splToken.TOKEN_PROGRAM_ID,
);
// getting or creating (if doens't exist) the token address in the fromWallet address
// fromTokenAccount is essentially the account *inside* the fromWallet that will be able to handle the new token that we just minted
let fromTokenAccount = await mint.getOrCreateAssociatedAccountInfo(
fromWallet.publicKey,
);
// getting or creating (if doens't exist) the token address in the toWallet address
// toWallet is the creator: the og mintRequester
// toTokenAmount is essentially the account *inside* the mintRequester's (creator's) wallet that will be able to handle the new token that we just minted
let toTokenAccount = await mint.getOrCreateAssociatedAccountInfo(
mintRequester,
);
// // Minting 1 token
await mint.mintTo(
fromTokenAccount.address,
fromWallet.publicKey,
[],
1000000 // 1 followed by decimals number of 0s // You'll ask the creator ki how many decimals he wants in his token. If he says 4, then 1 token will be represented as 10000
);
console.log("Initial mint successful");
// This transaction is sending of the creator tokens(tokens you just created) from their minting wallet to their Phantom Wallet
var transaction = new web3.Transaction().add(
splToken.Token.createTransferInstruction(
splToken.TOKEN_PROGRAM_ID,
fromTokenAccount.address,
toTokenAccount.address,
fromWallet.publicKey,
[],
1000000, // This is transferring 1 token, not 1000000 tokens
),
);
var signature = await web3.sendAndConfirmTransaction(
connection,
transaction,
[fromWallet],
{commitment: 'confirmed'},
);
const creatorTokenAddress = mint.publicKey;
const creatorTokenAddressString = mint.publicKey.toString();
console.log("SIGNATURE: ", signature); //Signature is basically like the paying party signs a transaction with their key.
console.log("Creator Token Address: ", creatorTokenAddressString);
console.log("Creator Minting Wallet Address: ", mint.payer.publicKey.toString());
let creatorTokenBalance = await toTokenAccount.amount;
console.log("Creator's Token Balance: ", creatorTokenBalance);
};
I am handling a transaction like this:
web3.eth.getTransactionCount(sender_address, (err, txCount) =>{
console.log(txCount)
if(err){
console.log(err);
}else{
const txObject = {
nonce: web3.utils.toHex(txCount),
to: master_address,
value: web3.utils.toHex(web3.utils.toWei("0.1", "ether")),
gasLimit: web3.utils.toHex(21000),
gasPrice: web3.utils.toHex(web3.utils.toWei("10", "gwei"))
}
const tx = new Tx(txObject);
tx.sign(sender_private_key);
const serialized_tx = tx.serialize();
const raw = '0x' + serialized_tx.toString('hex');
web3.eth.sendSignedTransaction(raw, (err, txHash) =>{
if(err){
console.log(err);
}else{
console.log("txHash:", txHash);
}
}).then(function(receipt) {
//Insert amir
if(receipt["status"] == true){
console.log("Tx has been mined")
}else{
}
console.log(receipt)
});
}
});
At the moment this works if the sender makes 1 transaction, but if the sender makes two transactions before they are mined, the nonce is the same, and will therefore cause an error.
I have read in web3js documentation about chaining, but i am not sure if this is what i am looking for.
How would i change my existing code in order to work for multiple transactions before they are mined?
Your app should manage nonce and keep latest value, then use it in send transaction.
But maybe pending transactions count solve your problem
web3.eth.getTransactionCount(sender_address, 'pending', (err, txCount) =>{...
I'm attempting to create a Stripe payment intent in NodeJS with Firebase. Server function receives JSON from my iOS app, retrieves the product correctly and gets the product's price (which is confirmed by the correct values in console), but at the very last step it doesn't pass the price value correctly.
Here's the error I receive in my Firebase console:
Error: Invalid integer: {:domain=>{:domain=>"", :_eventsCount=>"1"}}
at Function.generate (/srv/node_modules/stripe/lib/Error.js:38:16)
at IncomingMessage.res.once (/srv/node_modules/stripe/lib/StripeResource.js:175:33)
at Object.onceWrapper (events.js:313:30)
at emitNone (events.js:111:20)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:139:11)
at process._tickDomainCallback (internal/process/next_tick.js:219:9)
And here's the code:
// New Stripe Payment Intent
const newPaymentIntent = express();
newPaymentIntent.use(bodyParser.urlencoded({ extended: true }));
newPaymentIntent.post('/', (req, res) => { createPaymentIntent(req, res); });
function paymentIntent(req, res) { }
exports.paymentIntent = functions.https.onRequest(newPaymentIntent);
const calculateOrderAmount = items => {
let price = admin.database().ref('/productAds').orderByChild('code').equalTo(items['code']).once('value').then((snapshot) => {
var productPrice = 99;
snapshot.forEach((childSnapshot) => {
var childData = childSnapshot.val();
productPrice += childData.price;
console.log(childData.price);
});
console.log(productPrice);
return productPrice;
});
return price;
};
// Create Stripe Customer
async function createPaymentIntent(req, res) {
const { items, currency } = req.body;
const paymentIntent = await stripe.paymentIntents.create({
amount: calculateOrderAmount(items),
currency: 'aud',
});
const clientSecret = paymentIntent.client_secret
// Send publishable key and PaymentIntent details to client
res.send({
publishableKey: 'pk_test_ikLVo1vJSDi89gcfwMiBTDDw',
clientSecret: clientSecret
});
}
Any suggestions on what I am doing wrong?
Your function calculateOrderAmount doesn't return a number. It returns a promise that will resolve with the value returned by the function you passed to then.
You should use another then to wait for the final value, and only then invoke the stripe API. Or use async. (If you have the capability of using async, you should probably also use it in your calculateOrderAmount function instead of using then, as it will be easier to read and reason about.)
So Doug was correct. I edited the code to include async functions and it works flawlessly now. Here's what the final code looks like:
// Retrieve product code from Firebase
async function getDataFromFirebase(items) {
const objects = await admin.database().ref('/productAds').orderByChild('code').equalTo(items['code'])
const data = await objects.once('value');
return data;
}
async function getPrice(items) {
console.log('Executing getPrice method.');
var resultPrice = 0;
// we wait for the axios.get Promise to be resolved
const objects = await getDataFromFirebase(items);
objects.forEach((childSnapshot) => {
var childData = childSnapshot.val();
resultPrice += childData.price;
});
console.log('Price is: ' + resultPrice);
// we then return the data, just like we did in the callback-based version!
return resultPrice;
}
// Create Stripe Customer
async function createPaymentIntent(req, res) {
const { items, currency } = req.body;
const paymentIntent = await stripe.paymentIntents.create({
amount: await getPrice(items),
currency: 'aud',
});
const clientSecret = paymentIntent.client_secret
// Send publishable key and PaymentIntent details to client
res.send({
publishableKey: 'pk_test_ikLVo1vJSDi89gcfwMiBTDDw',
clientSecret: clientSecret
});
}