Estimating gas cost programmatically while minting NFT in web3.js - javascript

I am building an NFT minting dapp, I used a template and it seems like the gas limit is fixed in the configuration file, however, I want to be able to estimate the fee on the go. I found .estimategas() but I am not sure how to incorporate it into my function. Here is my mint function:
const claimNFTs = () => {
let cost = CONFIG.WEI_COST;
let gasLimit = CONFIG.GAS_LIMIT;
let totalCostWei = String(cost * mintAmount);
let totalGasLimit = String(gasLimit * mintAmount);
console.log("Cost: ", totalCostWei);
console.log("Gas limit: ", totalGasLimit);
setFeedback(`Minting your ${CONFIG.NFT_NAME}...`);
setClaimingNft(true);
blockchain.smartContract.methods
.mint(blockchain.account, mintAmount)
.send({
gasLimit: String(totalGasLimit),
to: CONFIG.CONTRACT_ADDRESS,
from: blockchain.account,
value: totalCostWei,
})
.once("error", (err) => {
console.log(err);
setFeedback("Sorry, something went wrong please try again later.");
setClaimingNft(false);
})
.then((receipt) => {
console.log(receipt);
setFeedback(
`WOW, the ${CONFIG.NFT_NAME} is yours! go visit Opensea.io to view it.`
);
setClaimingNft(false);
dispatch(fetchData(blockchain.account));
});
With this code, the gas fees seem to be very high, I just want to make sure I am not missing anything that may be driving the gas fee so high.

Related

Evaporate.js upload file with x-amz-security-token: SignatureDoesNotMatch

I want upload a file with evaporate.js and crypto-js using x-amz-security-token:
import * as Evaporate from 'evaporate';
import * as crypto from "crypto-js";
Evaporate.create({
aws_key: <ACCESS_KEY>,
bucket: 'my-bucket',
awsRegion: 'eu-west',
computeContentMd5: true,
cryptoMd5Method: data => crypto.algo.MD5.create().update(String.fromCharCode.apply(null, new Uint32Array(data))).finalize().toString(crypto.enc.Base64),
cryptoHexEncodedHash256: (data) => crypto.algo.SHA256.create().update(data as string).finalize().toString(crypto.enc.Hex),
logging: true,
maxConcurrentParts: 5,
customAuthMethod: (signParams: object, signHeaders: object, stringToSign: string, signatureDateTime: string, canonicalRequest: string): Promise<string> => {
const stringToSignDecoded = decodeURIComponent(stringToSign)
const requestScope = stringToSignDecoded.split("\n")[2];
const [date, region, service, signatureType] = requestScope.split("/");
const round1 = crypto.HmacSHA256(`AWS4${signParams['secret_key']}`, date);
const round2 = crypto.HmacSHA256(round1, region);
const round3 = crypto.HmacSHA256(round2, service);
const round4 = crypto.HmacSHA256(round3, signatureType);
const final = crypto.HmacSHA256(round4, stringToSignDecoded);
return Promise.resolve(final.toString(crypto.enc.Hex));
},
signParams: { secretKey: <SECRET_KEY> },
partSize: 1024 * 1024 * 6
}).then((evaporate) => {
evaporate.add({
name: 'my-key',
file: file, // file from <input type="file" />
xAmzHeadersCommon: { 'x-amz-security-token': <SECURITY_TOKEN> },
xAmzHeadersAtInitiate: { 'x-amz-security-token': <SECURITY_TOKEN> },
}).then(() => console.log('complete'));
},
(error) => console.error(error)
);
but it produce this output
AWS Code: SignatureDoesNotMatch, Message:The request signature we calculated does not match the signature you provided. Check your key and signing method.status:403
What I'm doing wrong
SIDE NOTE
This is the versione I'm using on browser side:
{
"crypto-js": "^4.1.1",
"evaporate": "^2.1.4"
}
You have your crypto.HmacSHA256 parameters reversed. They should all be the other way around. I've been bashing my head against a wall trying to get evaporate 2.x to work for the last week, it's been very frustrating.
I tried your code above and looked over all the docs and forum posts related to this, and I think using Cognito for this auth just doesn't work or isn't obvious how it's supposed to work, even though the AWS docs suggest it's possible.
In the end I went with using Lambda authentication and finally got it working after seeing much misinformation about how to use various crypto libraries to sign this stuff. I got it working last night after rigorously examining every bit of what was going on. Reading the docs also helped get me on the right path as to how the crypto needs to work, it gives example inputs and outputs so you can test for sure that your crypto methods are working as AWS expects them to work:
https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html
Tasks 1, 2 and 3 are especially important to read and understand.

Automated github issue bot?

I would like to make a discord bot that creates an issue based on user input from discord. Any idea how I would do this? I am using JavaScript and would like to integrate it into an existing bot. Thanks!
You can take ideas from the LeagueSandbox/IssueBot (Typescript), which does create issues.
It does use npmjs.com/package/github-api, from github-tools/github
export class IssueCommand extends Command {
execute() {
if(!this.args) {
return
}
let issueBody = ISSUE_TEMPLATE
.replace("{PLACEHOLDER}", this.args[2] || "_No content_")
.replace("{CHANNEL}", this.message.channel.name)
.replace("{USER}", this.message.author.username)
Bot.gitHub.api.issues.create({
owner: config.githubName,
repo: this.args[0],
title: this.args[1],
body: <any>issueBody // Typings for the `github` package are incorrect, so we have to cast to any here.
},
(error, response) => this.handleGithubResponse(error, response)
)
}
handleGithubResponse(error, response) {
if(error) {
let formattedError = JSON.stringify(error, null, 4)
let reply = ERROR_TEMPLATE.replace('{PLACEHOLDER}', formattedError)
this.message.reply(reply)
return
}
let reply = SUCCESS_TEMPLATE.replace('{PLACEHOLDER}', response.html_url)
this.message.reply(reply)
}
}
You have to set up that bot in your Discord application.
Maybe see the GitHub API docs for Creating Issues
You might need to create an app for it.

Need some help regarding the Elasticsearch engine and react js

I hope you are doing well, I need some help regarding the Elasticsearch engine. what I am doing is I am trying to create a search engine I have successfully post my data through kibana to elasticsearch engine. but "but how can I add the search component of elastyicsearch to my react app", I have like 4 million records into the kibana index, when I try to search directly from react it take a long time to display records into my frontapp app with nodejs api. below is the code with nodejs but the problem with this code it just gives me 10 records only.
router.get('/tweets', (req, res)=>{
let query = {
index: 'tweets',
// size: 10000
}
if(req.query.tweets) query.q = `*${req.query.tweets}*`;
client.search(query)
.then(resp => {
return res.status(200).json({
tweets: resp.body.hits.hits
});
})
.catch(err=>{
console.log(err);
return res.status(500).json({
err
});
});
});
Is there any way to impliment elasticsearch component directly to my reactjs app. like with the localhost:9200/index.. directly from the elasticsearch api?
Your request to Elasticsearch looks a bit strange to me, have you tried to search using a body like in the documentation? This line:
if(req.query.tweets) query.q = `*${req.query.tweets}*`;
doesn't seem like a correct way to write a query. Which field do you want to search for?
I saw that you tried to use the size field, which should be correct. You can also try the following:
client.search({
index: 'tweets',
body: {
size: 1000, // You can put the size here to get more than 10 results
query: {
wildcard: { yourfield: `*${req.query.tweets}*` }
}
}
}, (err, result) => {
if (err) console.log(err)
})
You could use SearchKit to directly query elasticsearch from you react app. But be aware that exposing DB services outside of your own infrastructure is bad practice.
You can use the component like this:
import {
SearchkitManager,
SearchkitProvider,
SearchkitComponent
} from 'searchkit'
const searchkit = new SearchkitManager(host)
class Render extends SearchkitComponent {
render(){
let results = await this.searchkit.reloadSearch()
return <div>{results}</div>
}
}
function table(){
return <SearchkitProvider searchkit={searchkit}>
<Render />
</SearchkitProvider>
}

MS teams bot JS - create conversation

I need to proactivly create conversation on channel in msteams. So i looked for examples but didn't find any examples of realy proactive conversation creation. All examples include first of all handling message, and creating conversation using context.
To be more accurate i have facebook, whatsapp, and web widget. Users write for example from facebook, i get message through fb webhook and i need to create new thread ( block with replies inside channel ) and only after that, someone who will answer in channel using thread block and i'll get message.
As i understood i need to bootstrap conversation object and use adapter.createConversation({ ...convFields }), but for example i don't have serviceUrl.
// i am using adapter from examples
new BotFrameworkAdapter({
appId: id,
appPassword: password
});
// then i have something like that in examples
const conversationParameters = {
isGroup: true,
channelData: {
channel: {
id: 'msteams'
}
},
activity: 'dsada'
};
const connectorClient = this.adapter.createConnectorClient(
context.activity.serviceUrl // i don't have context to get that serviceUrl, because i must do it first, not handle message and create thread after that.
);
const conversationResourceResponse = await connectorClient.conversations.createConversation(
conversationParameters as any
);
const conversationReference = TurnContext.getConversationReference(
context.activity // same here, i don't have context
);
conversationReference.conversation.id = conversationResourceResponse.id;
return [conversationReference, conversationResourceResponse.activityId];
In order to prevent (or at least hinder) spam, your bot can only send proactive messages to channels or group chats where it is already installed. In that instance you'll need to store the necessary information from the conversationUpdate membersAdded event you'll receive.
For 1:1 chats, it is possible to create a new conversation with a user, however your bot needs to know the Id of the user in order to do so. Typically this is achieved by retrieving the roster of a group chat or team where your bot is installed.
Essentially, it isn't possible to send a completely proactive message - the bot needs to be installed and/or have some amount of information about where it is sending the message previously.
Assuming you can achieve the correct permissions, it is possible to proactively install your bot. See this article for more details on that approach: https://learn.microsoft.com/en-us/graph/teams-proactive-messaging
Even though it is in C#, you may find this sample helpful as it demonstrates the minimal amount of information required in order to send proactive messages to each type of destination (which is the same across languages): https://github.com/clearab/teamsProactiveMessaging.
The relevant file is below:
public class MessageSender : IMessageSender
{
private ConnectorClient conClient;
private string serviceUrl;
public MessageSender(string serviceUrl, string id, string password)
{
MicrosoftAppCredentials.TrustServiceUrl(serviceUrl);
conClient = new ConnectorClient(new Uri(serviceUrl), id, password);
}
public async Task<ResourceResponse> SendOneToOneMessage(string conversationId, Activity activity)
{
return await conClient.Conversations.SendToConversationAsync(conversationId, activity);
}
public async Task<ConversationResourceResponse> CreateOneToOneConversation(string userId, string tenantId)
{
var members = new List<ChannelAccount>()
{
new ChannelAccount
{
Id = userId
}
};
ConversationParameters conParams = new ConversationParameters
{
Members = members,
TenantId = tenantId
};
return await this.conClient.Conversations.CreateConversationAsync(conParams);
}
public async Task<ConversationResourceResponse> CreateAndSendChannelMessage(string channelId, Activity activity)
{
ConversationParameters conParams = new ConversationParameters
{
ChannelData = new TeamsChannelData
{
Channel = new ChannelInfo(channelId)
},
Activity = activity
};
ConversationResourceResponse response = await this.conClient.Conversations.CreateConversationAsync(conParams);
return response;
}
public async Task<ResourceResponse> SendReplyToConversationThread(string threadId, Activity activity)
{
return await this.conClient.Conversations.SendToConversationAsync(threadId, activity);
}
}

How to make a bot delete messages after a certain time period

I'm trying to make my bot delete the 4 messages after 15 seconds, but I don't know how to make it do that.
const commando = require('discord.js-commando');
class HitOrMissCommand extends commando.Command
{
constructor(client)
{
super(client,{
name: 'hitormiss',
group: 'simple',
memberName: 'hitormiss',
description: 'i bet he doesnt kiss yah!'
});
}
async run(message, args)
{
message.reply("I guess they never miss, huh?")
message.reply("you got a boyfriend i bet he doesnt kiss yah!, MWAH!")
message.reply("He gon find another girl and he wont miss yah")
message.reply("He gon skirt and hit the dab like wiz khalifa")
}
}
module.exports = HitOrMissCommand;
if (message.content.startsWith(`!test`)) {
await message.channel.send('Hello').then(r => r.delete({ timeout: 5000 }))
console.log("test");
}
Might want to check out this question here.
As answered in that post the best way to do that is by deleting the message after x amount of seconds.
message.reply('Hit or miss.')
.then(msg => {
msg.delete(10000)
})
.catch(); /*Used for error handling*/
Proper credit should go to user LW001 who answered the question on the post I referred to.
Since this question is similar, you could use the same technique - adding a deletion timout. After you reply, .then() delete the message with your 15 second timer (15000 milliseconds):
message.reply("I guess they never miss, huh?").then(message => message.delete(15000)).catch(err => throw err);
Or if you can't use arrow syntax:
message.reply("I guess they never miss, huh?").then(function(message) {
message.delete(15000);
}).catch(function(err) {
throw err;
});
It could be done like this.
var replyM = message.reply("I guess they never miss, huh?")
setTimeout(function(){
replyM.delete
}, 1000);

Categories

Resources