From 5ac7118c7a6f97756778a63dc5205303f1de905b Mon Sep 17 00:00:00 2001 From: Emre Kanatli Date: Thu, 23 Sep 2021 23:06:18 +0300 Subject: [PATCH 1/3] Move number utils to new file Add stringToBN function Add tests to stringToBN --- src/History/history.ts | 2 +- src/Wallet/MnemonicWallet.ts | 2 +- src/Wallet/Wallet.ts | 2 +- src/utils/index.ts | 1 + src/utils/number_utils.ts | 187 ++++++++++++++++++++++++++++++++ src/utils/utils.ts | 171 +---------------------------- test/utils/number_utils.test.ts | 51 +++++++++ 7 files changed, 243 insertions(+), 173 deletions(-) create mode 100644 src/utils/number_utils.ts create mode 100644 test/utils/number_utils.test.ts diff --git a/src/History/history.ts b/src/History/history.ts index e47752a6..99b94ea6 100644 --- a/src/History/history.ts +++ b/src/History/history.ts @@ -21,7 +21,7 @@ import { activeNetwork, explorer_api, xChain } from '@/Network/network'; import { BN } from 'avalanche'; import { ChainIdType } from '@/types'; import { AVMConstants } from 'avalanche/dist/apis/avm'; -import { bnToAvaxC, bnToAvaxP, bnToAvaxX, bnToLocaleString, parseNftPayload } from '@/utils/utils'; +import { bnToAvaxC, bnToAvaxP, bnToAvaxX, bnToLocaleString, parseNftPayload } from '@/utils'; import * as Assets from '@/Asset/Assets'; import { NO_EXPLORER_API } from '@/errors'; diff --git a/src/Wallet/MnemonicWallet.ts b/src/Wallet/MnemonicWallet.ts index 5ebe7d72..0a49855f 100644 --- a/src/Wallet/MnemonicWallet.ts +++ b/src/Wallet/MnemonicWallet.ts @@ -16,7 +16,7 @@ import { KeyPair as EVMKeyPair, } from 'avalanche/dist/apis/evm'; import { avalanche } from '@/Network/network'; -import { digestMessage } from '@/utils/utils'; +import { digestMessage } from '@/utils'; import { HDWalletAbstract } from '@/Wallet/HDWalletAbstract'; import { bintools } from '@/common'; diff --git a/src/Wallet/Wallet.ts b/src/Wallet/Wallet.ts index 856e61fe..5c096a9d 100644 --- a/src/Wallet/Wallet.ts +++ b/src/Wallet/Wallet.ts @@ -57,7 +57,7 @@ import { PayloadBase, UnixNow } from 'avalanche/dist/utils'; import { getAssetDescription } from '@/Asset/Assets'; import { getErc20Token } from '@/Asset/Erc20'; import { NO_NETWORK } from '@/errors'; -import { avaxCtoX, bnToLocaleString, waitTxC, waitTxEvm, waitTxP, waitTxX } from '@/utils/utils'; +import { avaxCtoX, bnToLocaleString, waitTxC, waitTxEvm, waitTxP, waitTxX } from '@/utils'; import EvmWalletReadonly from '@/Wallet/EvmWalletReadonly'; import EventEmitter from 'events'; import { diff --git a/src/utils/index.ts b/src/utils/index.ts index 04bca77e..05f4666d 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1 +1,2 @@ export * from './utils'; +export * from './number_utils'; diff --git a/src/utils/number_utils.ts b/src/utils/number_utils.ts new file mode 100644 index 00000000..656dcc68 --- /dev/null +++ b/src/utils/number_utils.ts @@ -0,0 +1,187 @@ +import { BN } from 'avalanche'; +import Big from 'big.js'; + +declare module 'big.js' { + interface Big { + toLocaleString(toFixed?: number): string; + } +} + +Big.prototype.toLocaleString = function (toFixed: number = 9) { + let fixedStr = this.toFixed(toFixed); + let split = fixedStr.split('.'); + let wholeStr = parseInt(split[0]).toLocaleString('en-US'); + + if (split.length === 1) { + return wholeStr; + } else { + let remainderStr = split[1]; + + // remove trailing 0s + let lastChar = remainderStr.charAt(remainderStr.length - 1); + while (lastChar === '0') { + remainderStr = remainderStr.substring(0, remainderStr.length - 1); + lastChar = remainderStr.charAt(remainderStr.length - 1); + } + + let trimmed = remainderStr.substring(0, toFixed); + if (!trimmed) return wholeStr; + return `${wholeStr}.${trimmed}`; + } +}; + +/** + * @param val the amount to parse + * @param denomination number of decimal places to parse with + */ +export function bnToBig(val: BN, denomination = 0): Big { + return new Big(val.toString()).div(Math.pow(10, denomination)); +} + +/** + * Converts a BN amount of 18 decimals to 9. + * Used for AVAX C <-> X,P conversions + * @param amount + */ +export function avaxCtoX(amount: BN) { + let tens = new BN(10).pow(new BN(9)); + return amount.div(tens); +} + +export function avaxXtoC(amount: BN) { + let tens = new BN(10).pow(new BN(9)); + return amount.mul(tens); +} + +export function avaxPtoC(amount: BN) { + return avaxXtoC(amount); +} + +export function bnToBigAvaxX(val: BN): Big { + return bnToBig(val, 9); +} + +export function bnToBigAvaxP(val: BN): Big { + return bnToBigAvaxX(val); +} + +export function bnToBigAvaxC(val: BN): Big { + return bnToBig(val, 18); +} + +/** + * Parses the value using a denomination of 18 + * + * @param val the amount to parse given in WEI + * + * @example + * ``` + * bnToAvaxC(new BN('22500000000000000000') + * // will return 22.5 + *``` + * + */ +export function bnToAvaxC(val: BN): string { + return bnToLocaleString(val, 18); +} + +/** + * Parses the value using a denomination of 9 + * + * @param val the amount to parse given in nAVAX + */ +export function bnToAvaxX(val: BN): string { + return bnToLocaleString(val, 9); +} + +/** + * Parses the value using a denomination of 9 + * + * @param val the amount to parse given in nAVAX + */ +export function bnToAvaxP(val: BN): string { + return bnToAvaxX(val); +} + +/** + * + * @param val the number to parse + * @param decimals number of decimal places used to parse the number + */ +export function numberToBN(val: number | string, decimals: number): BN { + let valBig = Big(val); + let tens = Big(10).pow(decimals); + let valBN = new BN(valBig.times(tens).toFixed(0)); + return valBN; +} + +export function numberToBNAvaxX(val: number | string) { + return numberToBN(val, 9); +} + +export function numberToBNAvaxP(val: number | string) { + return numberToBNAvaxX(val); +} + +export function numberToBNAvaxC(val: number | string) { + return numberToBN(val, 18); +} + +/** + * @Remarks + * A helper method to convert BN numbers to human readable strings. + * + * @param val The amount to convert + * @param decimals Number of decimal places to parse the amount with + * + * @example + * ``` + * bnToLocaleString(new BN(100095),2) + * // will return '1,000.95' + * ``` + */ +export function bnToLocaleString(val: BN, decimals = 9): string { + let bigVal = bnToBig(val, decimals); + return bigToLocaleString(bigVal, decimals); +} + +export function bigToLocaleString(bigVal: Big, decimals: number = 9): string { + let fixedStr = bigVal.toFixed(decimals); + let split = fixedStr.split('.'); + let wholeStr = parseInt(split[0]).toLocaleString('en-US'); + + if (split.length === 1) { + return wholeStr; + } else { + let remainderStr = split[1]; + + // remove trailing 0s + let lastChar = remainderStr.charAt(remainderStr.length - 1); + while (lastChar === '0') { + remainderStr = remainderStr.substring(0, remainderStr.length - 1); + lastChar = remainderStr.charAt(remainderStr.length - 1); + } + + let trimmed = remainderStr.substring(0, decimals); + if (!trimmed) return wholeStr; + return `${wholeStr}.${trimmed}`; + } +} + +/** + * Converts a string to a BN value of the given denomination. + * @param value The string value of the + * @param decimals + * + * @example + * ``` + * stringToBN('1.32', 5) // is same as BN(132000) + * ``` + */ +export function stringToBN(value: string, decimals: number) { + let big = Big(value); + let tens = Big(10).pow(decimals); + let mult = big.times(tens); + let rawStr = mult.toFixed(0); + return new BN(rawStr); +} diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 75b2f0b2..89057a37 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -1,6 +1,4 @@ -// Extending Big.js with a helper function -import Big from 'big.js'; -import { BN, Buffer as BufferAvalanche } from 'avalanche'; +import { Buffer as BufferAvalanche } from 'avalanche'; import { validateAddress } from '@/helpers/address_helper'; import createHash from 'create-hash'; import axios from 'axios'; @@ -15,173 +13,6 @@ import { } from '@/utils/types'; import { PayloadBase, PayloadTypes } from 'avalanche/dist/utils'; -declare module 'big.js' { - interface Big { - toLocaleString(toFixed?: number): string; - } -} - -Big.prototype.toLocaleString = function (toFixed: number = 9) { - let fixedStr = this.toFixed(toFixed); - let split = fixedStr.split('.'); - let wholeStr = parseInt(split[0]).toLocaleString('en-US'); - - if (split.length === 1) { - return wholeStr; - } else { - let remainderStr = split[1]; - - // remove trailing 0s - let lastChar = remainderStr.charAt(remainderStr.length - 1); - while (lastChar === '0') { - remainderStr = remainderStr.substring(0, remainderStr.length - 1); - lastChar = remainderStr.charAt(remainderStr.length - 1); - } - - let trimmed = remainderStr.substring(0, toFixed); - if (!trimmed) return wholeStr; - return `${wholeStr}.${trimmed}`; - } -}; - -/** - * @param val the amount to parse - * @param denomination number of decimal places to parse with - */ -export function bnToBig(val: BN, denomination = 0): Big { - return new Big(val.toString()).div(Math.pow(10, denomination)); -} - -/** - * Converts a BN amount of 18 decimals to 9. - * Used for AVAX C <-> X,P conversions - * @param amount - */ -export function avaxCtoX(amount: BN) { - let tens = new BN(10).pow(new BN(9)); - return amount.div(tens); -} - -export function avaxXtoC(amount: BN) { - let tens = new BN(10).pow(new BN(9)); - return amount.mul(tens); -} - -export function avaxPtoC(amount: BN) { - return avaxXtoC(amount); -} - -export function bnToBigAvaxX(val: BN): Big { - return bnToBig(val, 9); -} - -export function bnToBigAvaxP(val: BN): Big { - return bnToBigAvaxX(val); -} - -export function bnToBigAvaxC(val: BN): Big { - return bnToBig(val, 18); -} - -/** - * Parses the value using a denomination of 18 - * - * @param val the amount to parse given in WEI - * - * @example - * ``` - * bnToAvaxC(new BN('22500000000000000000') - * // will return 22.5 - *``` - * - */ -export function bnToAvaxC(val: BN): string { - return bnToLocaleString(val, 18); -} - -/** - * Parses the value using a denomination of 9 - * - * @param val the amount to parse given in nAVAX - */ -export function bnToAvaxX(val: BN): string { - return bnToLocaleString(val, 9); -} - -/** - * Parses the value using a denomination of 9 - * - * @param val the amount to parse given in nAVAX - */ -export function bnToAvaxP(val: BN): string { - return bnToAvaxX(val); -} - -/** - * - * @param val the number to parse - * @param decimals number of decimal places used to parse the number - */ -export function numberToBN(val: number | string, decimals: number): BN { - let valBig = Big(val); - let tens = Big(10).pow(decimals); - let valBN = new BN(valBig.times(tens).toFixed(0)); - return valBN; -} - -export function numberToBNAvaxX(val: number | string) { - return numberToBN(val, 9); -} - -export function numberToBNAvaxP(val: number | string) { - return numberToBNAvaxX(val); -} - -export function numberToBNAvaxC(val: number | string) { - return numberToBN(val, 18); -} - -/** - * @Remarks - * A helper method to convert BN numbers to human readable strings. - * - * @param val The amount to convert - * @param decimals Number of decimal places to parse the amount with - * - * @example - * ``` - * bnToLocaleString(new BN(100095),2) - * // will return '1,000.95' - * ``` - */ -export function bnToLocaleString(val: BN, decimals = 9): string { - let bigVal = bnToBig(val, decimals); - return bigToLocaleString(bigVal, decimals); -} - -export function bigToLocaleString(bigVal: Big, decimals: number = 9): string { - let fixedStr = bigVal.toFixed(decimals); - let split = fixedStr.split('.'); - let wholeStr = parseInt(split[0]).toLocaleString('en-US'); - - if (split.length === 1) { - return wholeStr; - } else { - let remainderStr = split[1]; - - // remove trailing 0s - let lastChar = remainderStr.charAt(remainderStr.length - 1); - while (lastChar === '0') { - remainderStr = remainderStr.substring(0, remainderStr.length - 1); - lastChar = remainderStr.charAt(remainderStr.length - 1); - } - - let trimmed = remainderStr.substring(0, decimals); - if (!trimmed) return wholeStr; - return `${wholeStr}.${trimmed}`; - } -} - const COINGECKO_URL = 'https://api.coingecko.com/api/v3/simple/price?ids=avalanche-2&vs_currencies=usd'; /** diff --git a/test/utils/number_utils.test.ts b/test/utils/number_utils.test.ts new file mode 100644 index 00000000..45cf471d --- /dev/null +++ b/test/utils/number_utils.test.ts @@ -0,0 +1,51 @@ +import * as Utils from '@/utils'; +import { BN } from 'avalanche'; + +describe('stringToBN', () => { + it('no decimals', () => { + let val = Utils.stringToBN('10', 0); + expect(val).toEqual(new BN(10)); + }); + + it('string has decimal point, but value doesnt', () => { + let val = Utils.stringToBN('10.0', 0); + expect(val).toEqual(new BN(10)); + }); + + it('should be 0', () => { + let val = Utils.stringToBN('0', 0); + let valPoint = Utils.stringToBN('0.0', 0); + expect(val).toEqual(new BN(0)); + expect(valPoint).toEqual(new BN(0)); + }); + + it('has decimal values', () => { + let val = Utils.stringToBN('1.12', 5); + expect(val).toEqual(new BN(112000)); + }); + + it('has decimal values with extra 0s', () => { + let val = Utils.stringToBN('1.12000', 5); + expect(val).toEqual(new BN(112000)); + }); + + it('decimals has extra 0, higher than the denomination', () => { + let val = Utils.stringToBN('1.1232', 2); + expect(val).toEqual(new BN(112)); + }); + + it('decimals values are higher than the denomination allows', () => { + let val = Utils.stringToBN('1.1232', 2); + expect(val).toEqual(new BN(112)); + }); + + it('Million AVAX 9 decimals', () => { + let val = Utils.stringToBN('360123900', 9); + expect(val).toEqual(new BN('360123900000000000')); + }); + + it('Million AVAX 18 decimals', () => { + let val = Utils.stringToBN('360123900', 18); + expect(val).toEqual(new BN('360123900000000000000000000')); + }); +}); From c9d769d6a7ba82d7b87dc0c50daf8141906ca562 Mon Sep 17 00:00:00 2001 From: Emre Kanatli Date: Thu, 23 Sep 2021 23:12:07 +0300 Subject: [PATCH 2/3] increase max gas to 1000 nAVAX --- src/helpers/gas_helper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/gas_helper.ts b/src/helpers/gas_helper.ts index 75927255..fbd4f1a7 100644 --- a/src/helpers/gas_helper.ts +++ b/src/helpers/gas_helper.ts @@ -1,7 +1,7 @@ import { web3 } from '@/Network/network'; import { BN } from 'avalanche'; -const MAX_GAS = new BN(235000000000); +const MAX_GAS = new BN(1000_000_000_000); /** * Returns the current gas price in WEI from the network From 7bededb784cb9e03cdaa397b7a5380d9859a8ebc Mon Sep 17 00:00:00 2001 From: Emre Kanatli Date: Thu, 23 Sep 2021 23:21:00 +0300 Subject: [PATCH 3/3] changelog --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d295f864..17ba7a0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # CHANGELOG +## v0.9.7 + +#### Added + +- `Utils.stringToBN` convert string to BN directly + +#### Changed + +- Max gas price increased to 1000 nAVAX + ## v0.9.5 #### Added