Ethers BigNumber to USD conversion - javascript

I'm trying to convert an Ethereum value to its retrospective fiat value. The final value of USD seems wrong, and I wonder if it's how it's calculated with big numbers.
I've attached a sandbox for convenience.
https://codesandbox.io/s/autumn-sun-0k02d5?file=/src/index.js
Attempt
const one = parseUnits("1");
const price = parseUnits("0.1");
const _rate = "1563.48";
const rate = parseUnits(_rate, 2);
const usdPrice = price.lt(one) ? rate.mul(price) : rate.div(price);
Expectation: usdPrice = 156.348
Actual: usdPrice = 15634.8

Try this code:
import { formatEther, parseEther } from "#ethersproject/units";
// const price = parseUnits("0.00000000000000001");
// const price = parseUnits("0.00000001000000000");
const price = parseEther("0.1");
const _rate = "1563.48";
const rate = parseFloat(_rate);
const usdPrice = rate * price;
document.getElementById("app").innerHTML = `
<p>Price in Eth ${formatEther(price)}</p>
<p>Price in USD ${formatEther(usdPrice.toString())}</p>
<p>1 ETH = ${rate}</p>
<p>Balance: ${formatEther(price)} Rate: ${rate}</p>
`;
Since the rate is in dollars, you should parse it to a float, not to gwai.

Related

I need function that calculates amount of games required to reach certain rating with defined winrate

function ChangePts(pts) {
this.pts = pts;
this.win = function() {
console.log(this.pts + 30)
return this.pts += 30
}
this.lose = function() {
console.log(this.pts - 30)
return this.pts -= 30;
}
};
I made it to calculate how many games you need to lose, to get certain ratingw with while loop. This implies that win% is 0%, how do I calculate amount of games if we declare starting pts for example 5000, how many games it takes to get to 1000 pts if your winrate is 27%
P.S.: For this case I need only negative amount of win%.
You can just calculate it like this (variables should be explanation enough). There is no real coding necessary for it, just math calculations
const winRate = 0.27
const loseRate = 1-winRate
const pointsWin = 30
const pointsLose = 30
const startingPoints = 5000
const targetPoints = 1000
const pointsGainedOnAverage = pointsWin*winRate - pointsLose*loseRate
const pointsDistance = targetPoints - startingPoints
const games = pointsDistance / pointsGainedOnAverage
console.log('games', games)

Jquery Adding tax to price with commas

I am having trouble calculating with commas in my price what would be de best solution to solve this?
I am console log the right price and want to get the tax.
example console log: "€1.652,89"
$(document).ajaxSuccess(function() {
var price = $('.yith_wcp_group_final_total').text();
console.log(price);
var tax = 21
var total = (price * tax) / 100;
$('#B_subtotal').html(total);
console.log(total);
});
//EDIT
$(document).ajaxSuccess(function() {
var price = $('.yith_wcp_group_final_total').text();
price = Number(price.replace(/[^0-9\.-]+/g,""));
console.log(price)
var tax = 21
var total = price * (100 + tax) / 100;
var roundup = total.toFixed(2);
$('#B_subtotal').html(roundup);
console.log(total);
console.log(roundup);
});
So i get 1.900,83
and after the calculation i get 2.3000043
How could I get the comma and dots back on the right place?
You are getting values in a string. Just convert the string into a float as we have a decimal point and apply regex as we have a currency sign in it. Regex will check the value and we will get the value in float which can be used with tax multiplication.
var price = $('.yith_wcp_group_final_total').text();
price = Number(price.replace(/[^0-9\.-]+/g,""));
console.log(price)
var tax = 21
var total = (price * tax) / 100;
$('#B_subtotal').html(total);
total = price + total
console.log(total.toLocaleString());
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
First you need to convert "€1.652,89" from "currency" to float. In this example I used the parseLocaleNumber function (https://stackoverflow.com/a/29273131/5334486).
This gives you float 1652.89 which can be correctly used to compute taxes and total.
You can then format total back to currency using Intl.NumberFormat() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat
let price = "€1.652,89"
const taxPercent = 21
// REMOVE THE EURO SYMBOL FROM PRICE
price = price.substring(1)
// CONVERT LOCALIZED NUMBER TO FLOAT
const priceAsNumber = parseLocaleNumber(price, 'nl')
console.log(priceAsNumber) // 1652.89
// GET TAXES
const taxAmount = priceAsNumber * taxPercent / 100
console.log(taxAmount) // 347.1069
// GET TOTAL
const total = priceAsNumber + taxAmount
console.log(total) // 1999.9969
// FORMAT TOTAL TO CURRENCY
const totalRounded = new Intl.NumberFormat('nl-NL', { style: 'currency', currency: 'EUR' }).format(total)
console.log(totalRounded) // "€ 2.000,00"
//
// HELPER FUNCTION
//
// https://stackoverflow.com/a/29273131/5334486
//
function parseLocaleNumber(stringNumber, locale) {
var thousandSeparator = Intl.NumberFormat(locale).format(11111).replace(/\p{Number}/gu, '');
var decimalSeparator = Intl.NumberFormat(locale).format(1.1).replace(/\p{Number}/gu, '');
return parseFloat(stringNumber
.replace(new RegExp('\\' + thousandSeparator, 'g'), '')
.replace(new RegExp('\\' + decimalSeparator), '.')
);
}

Normalize numbers for stats

I'm trying to make a simple daily follower stats like the screenshot below.
And here's the code I'm using.
const normalize = ({ min, max, number }) => {
return parseFloat((((number - min) / (max - min)) * 100).toFixed(2))
}
const followers = {
'03-23-2022': 2115,
'03-24-2022': 2128,
'03-25-2022': 2175,
'03-26-2022': 2195,
'03-27-2022': 2215,
'03-28-2022': 2206,
'03-29-2022': 2258
}
const numbers = []
for (const day in followers) {
const stats = followers[day]
numbers.push(stats)
}
const min = Math.min.apply(null, numbers)
const max = Math.max.apply(null, numbers)
for (const day in followers) {
const activity = followers[day]
const percent = normalize({ min, max, number: activity })
console.log({ day, activity, percent })
}
As you can see on the console log the normalize function returns 0 for the minimum number and that's why nothing is visible on the site.
What I'd like to do is I want to get some meaningful numbers from the normalize function to be able to show the stats in a more readable style. How do I do that?

[NodeJS]Get not repeated numbers from a range

I am trying to update via API some of my arts on a NFT test over OpenSea, now he updates but the problem is that he is repeating the numbers, is it possible to choose a number in a range but that never repeat?
My actual code:
const opensea = require("opensea-js");
const OpenSeaPort = opensea.OpenSeaPort;
const Network = opensea.Network;
const MnemonicWalletSubprovider = require("#0x/subproviders")
.MnemonicWalletSubprovider;
const RPCSubprovider = require("web3-provider-engine/subproviders/rpc");
const Web3ProviderEngine = require("web3-provider-engine");
const MNEMONIC = 'SECRET';
const NODE_API_KEY = 'MyKEY';
const isInfura = true;
const FACTORY_CONTRACT_ADDRESS = '0x745e6b0CAd1eDc72647B9fFec5C69e4608f73ab2';
const NFT_CONTRACT_ADDRESS = '0x745e6b0CAd1eDc72647B9fFec5C69e4608f73ab2';
const OWNER_ADDRESS = '0xaEBB892210eB23C47b1e710561c7BC4CFA63A62e';
const NETWORK = 'rinkeby';
const API_KEY = ""; // API key is optional but useful if you're doing a high volume of requests.
if (!MNEMONIC || !NODE_API_KEY || !NETWORK || !OWNER_ADDRESS) {
console.error(
"Please set a mnemonic, Alchemy/Infura key, owner, network, API key, nft contract, and factory contract address."
);
return;
}
if (!FACTORY_CONTRACT_ADDRESS && !NFT_CONTRACT_ADDRESS) {
console.error("Please either set a factory or NFT contract address.");
return;
}
const BASE_DERIVATION_PATH = `44'/60'/0'/0`;
const mnemonicWalletSubprovider = new MnemonicWalletSubprovider({
mnemonic: MNEMONIC,
baseDerivationPath: BASE_DERIVATION_PATH,
});
const network =
NETWORK === "mainnet" || NETWORK === "live" ? "mainnet" : "rinkeby";
const infuraRpcSubprovider = new RPCSubprovider({
rpcUrl: isInfura
? "https://" + network + ".infura.io/v3/" + NODE_API_KEY
: "https://eth-" + network + ".alchemyapi.io/v2/" + NODE_API_KEY,
});
const providerEngine = new Web3ProviderEngine();
providerEngine.addProvider(mnemonicWalletSubprovider);
providerEngine.addProvider(infuraRpcSubprovider);
providerEngine.start();
const seaport = new OpenSeaPort(
providerEngine,
{
networkName:
NETWORK === "mainnet" || NETWORK === "live"
? Network.Main
: Network.Rinkeby,
apiKey: API_KEY,
},
(arg) => console.log(arg)
);
async function sellTheItems() {
// Example: simple fixed-price sale of an item owned by a user.
console.log("Auctioning an item for a fixed price...");
//Get a number in a range and return as a string
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min; //The maximum is exclusive and the minimum is inclusive
}
const fixedPriceSellOrder = await seaport.createSellOrder({
asset: {
tokenId: getRandomInt(0, 500).toString(),
//tokenId: "0",
tokenAddress: NFT_CONTRACT_ADDRESS,
},
startAmount: 0.36,
expirationTime: 0,
accountAddress: OWNER_ADDRESS,
});
console.log(
`Successfully created a fixed-price sell order! ${fixedPriceSellOrder.asset.openseaLink}\n`
);
}
async function doItAgain() {
sellTheItems();
}
//Repeat doItAgain() every 5 seconds
setInterval(doItAgain, 5000);
What I want to do is get a number between 0 and 500 but never repeat a number that I used before, my intention is get a number to 'tokenId' everytime.
With respect, it's a bad idea to use 3-digit "random" tokens. Partly because you get duplicates and you need some sort of storage to avoid that. Partly because they're easy to brute-force.
Use the uuid Universal Unique IDentifier package to generate 128-bit uuidv4 tokens of which 60 bits are random, using a crypographically secure pseudo-random number generator. All uuids, not just the uuidv4 random ones, are constructed to avoid duplicates. But the uuidv4 tokens have the advantage that they're very hard for cybercreeps to guess.
const { v4: uuidv4 } = require('uuid');
...
tokenId: uuidv4(), // ⇨ '1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed'

Math method that does not send negative numbers

I'm currently making a Discord bot using JavaScript, the bot features many commands, but I just came across this flaw, the flaw concerns the Math.Random() object, except it sometimes returns negative numbers, does anyone have a solution to this using one of the methods?
Here's the code::
let db = require(`quick.db`)
module.exports = {
name: "rob",
description: "Rob your friends to get money",
category: "economy",
usage: "rob [member]",
timeout: "1 minute",
run: async (client, message, args) => {
let victim = message.mentions.members.first()
if(!victim) {
return message.channel.send(`:x: Please specify a member to rob!`)
}
let victimW = await db.get(`wallet_${victim.id}`)
if(victimW === null) {
message.channel.send(`:x: That user doesn't have money in his wallet, are you sure you want to rob him?`)
}
let random = Math.floor(Math.random() * 100);
if(random < 30) {
let victimWallet = await db.get(`wallet_${victim.id}`)
let userWallet = await db.get(`wallet_${message.author.id}`)
let amount = Math.floor(Math.random() * victimWallet);
const messages = [`POG! You robbed **${victim.username}** and got **${amount}** :coin:!`, `oo seems like you robbed **${victim.displayName}** and got **${amount}** :coin:!`]
const randomMessage = messages[Math.floor(Math.random() * messages.length)];
message.channel.send(randomMessage)
await db.set(`wallet_${victim.id}`, amount - victimWallet)
await db.set(`wallet_${message.author.id}`, userWallet + amount)
} else if(random > 30) {
let authorWallet = await db.get(`wallet_${message.author.id}`)
let wallet1 = await db.get(`wallet_${victim.id}`)
let amountPaid = Math.floor(Math.random() * authorWallet);
const message1 = [`Pfft noob, you got caught and paid **${victim.displayName} ${amountPaid}** :coin: lol!`, `lel ure such a noob, you paid **${victim.displayName} ${amountPaid}** :coin:!`, `u suck and you paid **${amountPaid}** :coin: to **${victim.displayName}**, such a noob lol!`]
const randomMessage1 = message1[Math.floor(Math.random() * message1.length)];
return message.channel.send(randomMessage1)
await db.set(`wallet_${message.author.id}`, (amountPaid - authorWallet));
await db.set(`wallet_${message.author.id}`, (amountPaid + wallet1));
}
}
}
It all works except sometimes it just sends a negative number, can anyone tell me a math method that make sure the number isn't a negative?
Thanks.
You should verify the amount to steal before stealing it
if (random < 30) {
let victimWallet = await db.get(`wallet_${victim.id}`)
let userWallet = await db.get(`wallet_${message.author.id}`)
let amount = Math.floor(Math.random() * victimWallet);
//Check the amount of victim wallet, return if not enough coins to steal
if (amount > victimwallet) {
console.log("Not enough coins to steal") return;
}
const messages = [`POG! You robbed **${victim.username}** and got **${amount}** :coin:!`, `oo seems like you robbed **${victim.displayName}** and got **${amount}** :coin:!`]
const randomMessage = messages[Math.floor(Math.random() * messages.length)];
message.channel.send(randomMessage)
await db.set(`wallet_${victim.id}`, amount - victimWallet)
await db.set(`wallet_${message.author.id}`, userWallet + amount)
}
If the point is just to make the output to always positive, you can try this "if condition"
var x = -10 //change it with any number
if (x < 0){
x = x * -1
}
console.log(x) //it should will always show positive number
alternatively you can always use Match.abs(x)
var x = -10;
console.log(Math.abs(x));

Categories