From 34a1d6b7e8184aac95b232532f499e9dd6b415dc Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Tue, 12 Nov 2024 19:53:54 -0600 Subject: [PATCH 1/7] [NayNay] Updating Units within Entropy - it had come to our attn that we were using the wrong units for the tokens display - we were under the impression that bits were the smallest unit of the entropy token, that was a mistake - updated all mentions of tokens and bits to match their respective definition - updated return of balance to the human readable format, using BITS - added new method to grab token details from chain --- src/balance/command.ts | 10 ++++++---- src/balance/interaction.ts | 9 ++++++--- src/common/constants.ts | 9 --------- src/common/utils.ts | 23 +++++++++++++++++++++++ src/faucet/interaction.ts | 4 +++- src/transfer/command.ts | 8 +++++--- src/transfer/constants.ts | 2 +- src/transfer/interaction.ts | 5 +++-- src/transfer/main.ts | 15 ++++++++------- src/transfer/types.ts | 2 +- tests/faucet.test.ts | 3 ++- tests/testing-utils/constants.mjs | 4 +++- tests/transfer.test.ts | 8 ++++---- 13 files changed, 65 insertions(+), 37 deletions(-) diff --git a/src/balance/command.ts b/src/balance/command.ts index d99ba2e2..fd5cdefa 100644 --- a/src/balance/command.ts +++ b/src/balance/command.ts @@ -3,7 +3,7 @@ import Entropy from "@entropyxyz/sdk"; import { EntropyBalance } from "./main"; import { endpointOption, cliWrite, loadEntropy } from "../common/utils-cli"; -import { findAccountByAddressOrName } from "../common/utils"; +import { findAccountByAddressOrName, getTokenDetails, tokensToBits } from "../common/utils"; import * as config from "../config"; export function entropyBalanceCommand () { @@ -17,13 +17,15 @@ export function entropyBalanceCommand () { .addOption(endpointOption()) .action(async (account, opts) => { const entropy: Entropy = await loadEntropy(account, opts.endpoint) - const BalanceService = new EntropyBalance(entropy, opts.endpoint) + const balanceService = new EntropyBalance(entropy, opts.endpoint) + const { decimals, symbol } = await getTokenDetails(entropy) const { accounts } = await config.get() const address = findAccountByAddressOrName(accounts, account)?.address - const balance = await BalanceService.getBalance(address) - cliWrite(`${balance.toLocaleString('en-US')} BITS`) + const tokensBalance = await balanceService.getBalance(address) + const balance = tokensToBits(tokensBalance, decimals) + cliWrite(`${balance} ${symbol}`) process.exit(0) }) diff --git a/src/balance/interaction.ts b/src/balance/interaction.ts index 334c00c7..c4742c6e 100644 --- a/src/balance/interaction.ts +++ b/src/balance/interaction.ts @@ -1,12 +1,15 @@ -import { findAccountByAddressOrName, print } from "src/common/utils" +import { findAccountByAddressOrName, getTokenDetails, print, tokensToBits } from "src/common/utils" import { EntropyBalance } from "./main" export async function entropyBalance (entropy, endpoint, storedConfig) { try { + // grabbing decimals from chain spec as that is the source of truth for the value + const { decimals, symbol } = await getTokenDetails(entropy) const balanceService = new EntropyBalance(entropy, endpoint) const address = findAccountByAddressOrName(storedConfig.accounts, storedConfig.selectedAccount)?.address - const balance = await balanceService.getBalance(address) - print(`Entropy Account [${storedConfig.selectedAccount}] (${address}) has a balance of: ${balance.toLocaleString('en-US')} BITS`) + const tokensBalance = await balanceService.getBalance(address) + const balance = tokensToBits(tokensBalance, decimals) + print(`Entropy Account [${storedConfig.selectedAccount}] (${address}) has a balance of: ${balance} ${symbol}`) } catch (error) { console.error('There was an error retrieving balance', error) } diff --git a/src/common/constants.ts b/src/common/constants.ts index a6121b60..5c78824b 100644 --- a/src/common/constants.ts +++ b/src/common/constants.ts @@ -1,12 +1,3 @@ -/* - A "bit" is the smallest indivisible unit of account value we track. - A "token" is the human readable unit of value value - This constant is then "the number of bits that make up 1 token", or said differently - "how many decimal places our token has". -*/ -export const BITS_PER_TOKEN = 1e10 - - // ASCII Colors for Logging to Console export const ERROR_RED = '\u001b[31m' export const SUCCESS_GREEN = '\u001b[32m' diff --git a/src/common/utils.ts b/src/common/utils.ts index 3dd1f639..331b955b 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -113,3 +113,26 @@ export async function jumpStartNetwork (entropy, endpoint): Promise { }) }) } + +export async function getTokenDetails (entropy): Promise<{ decimals: number, symbol: string }> { + const chainProperties = await entropy.substrate.rpc.system.properties() + const decimals = chainProperties.tokenDecimals.toHuman()[0] + const symbol = chainProperties.tokenSymbol.toHuman()[0] + + return { decimals: parseInt(decimals), symbol } +} + +/* + A "token" is the smallest indivisible unit of account value we track. + A "BIT" is the human readable unit of value value + This constant is then "the number of tokens that make up 1 BITS", or said differently + "how many decimal places our BITS has". +*/ +export const TOKENS_PER_BITS = (decimals: number): number => { + return Math.pow(10, decimals) + +} + +export function tokensToBits (numOfTokens: number, decimals: number) { + return parseFloat((numOfTokens / TOKENS_PER_BITS(decimals)).toFixed(4)) +} \ No newline at end of file diff --git a/src/faucet/interaction.ts b/src/faucet/interaction.ts index fa76a9a3..89fce14a 100644 --- a/src/faucet/interaction.ts +++ b/src/faucet/interaction.ts @@ -6,9 +6,11 @@ import { EntropyFaucet } from "./main" import { print } from "src/common/utils" let chosenVerifyingKeys = [] -// Sending only 1e10 BITS does not allow user's to register after receiving funds +// Sending only 1e10 TOKENS does not allow user's to register after receiving funds // there are limits in place to ensure user's are leftover with a certain balance in their accounts // increasing amount send here, will allow user's to register right away + +// 2 BITS const amount = "20000000000" // context for logging file const FLOW_CONTEXT = 'ENTROPY_FAUCET_INTERACTION' diff --git a/src/transfer/command.ts b/src/transfer/command.ts index 0cdfe6fe..e892d72a 100644 --- a/src/transfer/command.ts +++ b/src/transfer/command.ts @@ -1,23 +1,25 @@ import { Command } from "commander" -import { accountOption, endpointOption, loadEntropy } from "src/common/utils-cli" +import { accountOption, cliWrite, endpointOption, loadEntropy } from "src/common/utils-cli" import { EntropyTransfer } from "./main" +import { getTokenDetails } from "src/common/utils" export function entropyTransferCommand () { const transferCommand = new Command('transfer') transferCommand .description('Transfer funds between two Entropy accounts.') // TODO: name the output .argument('', 'Account address funds will be sent to') - .argument('', 'Amount of funds to be moved (in "tokens")') + .argument('', 'Amount of funds to be moved (in "BITS")') .addOption(accountOption()) .addOption(endpointOption()) .action(async (destination, amount, opts) => { // TODO: destination as ? const entropy = await loadEntropy(opts.account, opts.endpoint) const transferService = new EntropyTransfer(entropy, opts.endpoint) + const { symbol } = await getTokenDetails(entropy) await transferService.transfer(destination, amount) - // cliWrite(??) // TODO: write the output + cliWrite(`Transaction successful: Sent ${amount} ${symbol} to ${destination}`) process.exit(0) }) return transferCommand diff --git a/src/transfer/constants.ts b/src/transfer/constants.ts index 5529b5be..9d48bef7 100644 --- a/src/transfer/constants.ts +++ b/src/transfer/constants.ts @@ -1,7 +1,7 @@ export const TRANSFER_CONTENT = { amount: { name: 'amount', - message: 'Input amount to transfer:', + message: 'Input amount of BITS to transfer:', default: '1', invalidError: 'Please enter a value greater than 0', }, diff --git a/src/transfer/interaction.ts b/src/transfer/interaction.ts index e0e43097..74bba17a 100644 --- a/src/transfer/interaction.ts +++ b/src/transfer/interaction.ts @@ -1,16 +1,17 @@ import inquirer from "inquirer" -import { print } from "../common/utils" +import { getTokenDetails, print } from "../common/utils" import { EntropyTransfer } from "./main" import { transferInputQuestions } from "./utils" import { setupProgress } from "src/common/progress" export async function entropyTransfer (entropy, endpoint) { const progressTracker = setupProgress('Transferring Funds') + const { symbol } = await getTokenDetails(entropy) const transferService = new EntropyTransfer(entropy, endpoint) const { amount, recipientAddress } = await inquirer.prompt(transferInputQuestions) await transferService.transfer(recipientAddress, amount, progressTracker) print('') - print(`Transaction successful: Sent ${amount} to ${recipientAddress}`) + print(`Transaction successful: Sent ${amount} ${symbol} to ${recipientAddress}`) print('') print('Press enter to return to main menu') } diff --git a/src/transfer/main.ts b/src/transfer/main.ts index e796fec4..8fb83f15 100644 --- a/src/transfer/main.ts +++ b/src/transfer/main.ts @@ -1,8 +1,8 @@ import Entropy from "@entropyxyz/sdk"; import { EntropyBase } from "../common/entropy-base"; -import { formatDispatchError } from "../common/utils"; -import { BITS_PER_TOKEN } from "../common/constants"; +import { formatDispatchError, getTokenDetails } from "../common/utils"; +import { TOKENS_PER_BITS } from "../common/utils"; import { TransferOptions } from "./types"; const FLOW_CONTEXT = 'ENTROPY_TRANSFER' @@ -17,15 +17,16 @@ export class EntropyTransfer extends EntropyBase { // - converting `amount` (string => BigInt) // - progress callbacks (optional) - async transfer (toAddress: string, amount: string, progress?: { start: ()=>void, stop: ()=>void }) { - const formattedAmount = BigInt(Number(amount) * BITS_PER_TOKEN) + async transfer (toAddress: string, amountInBits: string, progress?: { start: ()=>void, stop: ()=>void }) { + const { decimals } = await getTokenDetails(this.entropy) + const tokens = BigInt(Number(amountInBits) * TOKENS_PER_BITS(decimals)) if (progress) progress.start() try { await this.rawTransfer({ from: this.entropy.keyring.accounts.registration.pair, to: toAddress, - amount: formattedAmount + tokens }) if (progress) return progress.stop() } catch (error) { @@ -35,13 +36,13 @@ export class EntropyTransfer extends EntropyBase { } private async rawTransfer (payload: TransferOptions): Promise { - const { from, to, amount } = payload + const { from, to, tokens } = payload return new Promise((resolve, reject) => { // WARN: await signAndSend is dangerous as it does not resolve // after transaction is complete :melt: this.entropy.substrate.tx.balances - .transferAllowDeath(to, amount) + .transferAllowDeath(to, tokens) // @ts-ignore .signAndSend(from, ({ status, dispatchError }) => { if (dispatchError) { diff --git a/src/transfer/types.ts b/src/transfer/types.ts index 365cdaac..c0b48f54 100644 --- a/src/transfer/types.ts +++ b/src/transfer/types.ts @@ -4,5 +4,5 @@ import { Pair } from '@entropyxyz/sdk/keys' export interface TransferOptions { from: Pair to: string - amount: bigint + tokens: bigint } diff --git a/tests/faucet.test.ts b/tests/faucet.test.ts index 398a4fa6..61941cb6 100644 --- a/tests/faucet.test.ts +++ b/tests/faucet.test.ts @@ -82,6 +82,7 @@ test('Faucet Tests: Successfully send funds and register', async t => { let naynayBalance = await balance.getBalance(naynayAddress) t.equal(naynayBalance, 0, 'Naynay is broke af') + // 2 BITS const amount = 20000000000 const transferStatus = await run( 'Sending faucet funds to account', @@ -109,7 +110,7 @@ test('Faucet Tests: Successfully send funds and register', async t => { t.end() }) -// TODO: @naynay fix below test for register failing when only sending 1e10 bits +// TODO: @naynay fix below test for register failing when only sending 1e10 tokens // test('Faucet Tests: Successfully send funds but cannot register', async t => { // const { run, endpoint, entropy: naynayEntropy } = await setupTest(t) diff --git a/tests/testing-utils/constants.mjs b/tests/testing-utils/constants.mjs index 53090266..37017526 100644 --- a/tests/testing-utils/constants.mjs +++ b/tests/testing-utils/constants.mjs @@ -8,4 +8,6 @@ export const charlieAddress = '5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y' export const eveSeed = '0x786ad0e2df456fe43dd1f91ebca22e235bc162e0bb8d53c633e8c85b2af68b7a' -export const eveAddress = '5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw' \ No newline at end of file +export const eveAddress = '5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw' + +export const DEFAULT_TOKEN_DECIMALS = 10 \ No newline at end of file diff --git a/tests/transfer.test.ts b/tests/transfer.test.ts index c7caf218..2cc86317 100644 --- a/tests/transfer.test.ts +++ b/tests/transfer.test.ts @@ -1,10 +1,10 @@ import test from 'tape' -import { BITS_PER_TOKEN } from "../src/common/constants"; +import { TOKENS_PER_BITS } from "../src/common/utils"; import { EntropyTransfer } from '../src/transfer/main' import { EntropyBalance } from '../src/balance/main' import { promiseRunner, setupTest } from './testing-utils' -import { charlieStashAddress, charlieStashSeed } from './testing-utils/constants.mjs' +import { charlieStashAddress, charlieStashSeed, DEFAULT_TOKEN_DECIMALS } from './testing-utils/constants.mjs' const endpoint = 'ws://127.0.0.1:9944' @@ -44,8 +44,8 @@ test('Transfer', async (t) => { 'getBalance (naynay)', balanceService.getBalance(naynayAddress) ) - const expected = Number(inputAmount) * BITS_PER_TOKEN - t.equal(naynayBalance, expected,'naynay is rolling in it!') + const expected = Number(inputAmount) * TOKENS_PER_BITS(DEFAULT_TOKEN_DECIMALS) + t.equal(naynayBalance, expected, 'naynay is rolling in it!') t.end() }) From 39cf37a11552dc45d416ee952c9f685333ea5a27 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Wed, 13 Nov 2024 16:51:32 -0600 Subject: [PATCH 2/7] updated methods and flows based on pr suggestions, added changelog) --- CHANGELOG.md | 18 ++++++++++++++++-- src/balance/interaction.ts | 4 ++-- src/common/utils.ts | 25 ++++++++++++++++++------- src/transfer/command.ts | 2 +- src/transfer/main.ts | 5 ++--- src/types/index.ts | 5 +++++ tests/transfer.test.ts | 4 ++-- 7 files changed, 46 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e99fc27..80b1310d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,15 +14,29 @@ Version header format: `[version] Name - year-month-day (entropy-core compatibil ### Fixed -- programmatic CLI +- Shared + - amount units are now correct! [#306](https://github.com/entropyxyz/cli/pull/306) + - 1 token = 0.00000000001 BITS + - 1 BITS = 10000000000 tokens +- Programmatic CLI - `entropy program list` now prints output! [#298](https://github.com/entropyxyz/cli/pull/298) -### Added +### Added +- Shared + - new methods for conversion and other math operations [#306](https://github.com/entropyxyz/cli/pull/306) + - BITS => tokens + - Tokens => BITS + - rounding to a specific number of decimal places + - tokens per bits calculation + - new method to pull token details from chain, and cache the results [#306](https://github.com/entropyxyz/cli/pull/306) - TUI - animation on tui load (while entropy loads) [#288](https://github.com/entropyxyz/cli/pull/288) +### Changed +- Shared + - Balance now displays the number of BITS to the nearest 4 decimal places [#306](https://github.com/entropyxyz/cli/pull/306) ## [0.1.1] Deadpool - 2024-11-06 (entropy-core compatibility: 0.3.0) diff --git a/src/balance/interaction.ts b/src/balance/interaction.ts index c4742c6e..ad0615f4 100644 --- a/src/balance/interaction.ts +++ b/src/balance/interaction.ts @@ -1,4 +1,4 @@ -import { findAccountByAddressOrName, getTokenDetails, print, tokensToBits } from "src/common/utils" +import { findAccountByAddressOrName, getTokenDetails, print, round, tokensToBits } from "src/common/utils" import { EntropyBalance } from "./main" export async function entropyBalance (entropy, endpoint, storedConfig) { @@ -8,7 +8,7 @@ export async function entropyBalance (entropy, endpoint, storedConfig) { const balanceService = new EntropyBalance(entropy, endpoint) const address = findAccountByAddressOrName(storedConfig.accounts, storedConfig.selectedAccount)?.address const tokensBalance = await balanceService.getBalance(address) - const balance = tokensToBits(tokensBalance, decimals) + const balance = round(tokensToBits(tokensBalance, decimals)) print(`Entropy Account [${storedConfig.selectedAccount}] (${address}) has a balance of: ${balance} ${symbol}`) } catch (error) { console.error('There was an error retrieving balance', error) diff --git a/src/common/utils.ts b/src/common/utils.ts index 331b955b..419fde8d 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -2,6 +2,7 @@ import { Entropy } from '@entropyxyz/sdk' import { Buffer } from 'buffer' import { EntropyAccountConfig } from "../config/types" import { EntropyLogger } from './logger' +import { TokenDetails } from 'src/types' export function stripHexPrefix (str: string): string { if (str.startsWith('0x')) return str.slice(2) @@ -114,12 +115,15 @@ export async function jumpStartNetwork (entropy, endpoint): Promise { }) } -export async function getTokenDetails (entropy): Promise<{ decimals: number, symbol: string }> { +// caching details to reduce number of calls made to the rpc endpoint +let tokenDetails: TokenDetails +export async function getTokenDetails (entropy): Promise { + if (tokenDetails) return tokenDetails const chainProperties = await entropy.substrate.rpc.system.properties() const decimals = chainProperties.tokenDecimals.toHuman()[0] const symbol = chainProperties.tokenSymbol.toHuman()[0] - - return { decimals: parseInt(decimals), symbol } + tokenDetails = { decimals: parseInt(decimals), symbol } + return tokenDetails } /* @@ -128,11 +132,18 @@ export async function getTokenDetails (entropy): Promise<{ decimals: number, sym This constant is then "the number of tokens that make up 1 BITS", or said differently "how many decimal places our BITS has". */ -export const TOKENS_PER_BITS = (decimals: number): number => { - return Math.pow(10, decimals) - +export const tokensPerBits = (decimals: number): number => { + return Math.pow(10, decimals) } export function tokensToBits (numOfTokens: number, decimals: number) { - return parseFloat((numOfTokens / TOKENS_PER_BITS(decimals)).toFixed(4)) + return numOfTokens / tokensPerBits(decimals) +} + +export function bitsToTokens (numOfBits: number, decimals: number): bigint { + return BigInt(numOfBits * tokensPerBits(decimals)) +} + +export function round (num: number, decimals: number = 4): number { + return parseFloat(num.toFixed(decimals)) } \ No newline at end of file diff --git a/src/transfer/command.ts b/src/transfer/command.ts index e892d72a..930502c9 100644 --- a/src/transfer/command.ts +++ b/src/transfer/command.ts @@ -8,7 +8,7 @@ export function entropyTransferCommand () { transferCommand .description('Transfer funds between two Entropy accounts.') // TODO: name the output .argument('', 'Account address funds will be sent to') - .argument('', 'Amount of funds to be moved (in "BITS")') + .argument('', 'Amount of funds (in "BITS") to be moved') .addOption(accountOption()) .addOption(endpointOption()) .action(async (destination, amount, opts) => { diff --git a/src/transfer/main.ts b/src/transfer/main.ts index 8fb83f15..b3a97deb 100644 --- a/src/transfer/main.ts +++ b/src/transfer/main.ts @@ -1,8 +1,7 @@ import Entropy from "@entropyxyz/sdk"; import { EntropyBase } from "../common/entropy-base"; -import { formatDispatchError, getTokenDetails } from "../common/utils"; -import { TOKENS_PER_BITS } from "../common/utils"; +import { bitsToTokens, formatDispatchError, getTokenDetails } from "../common/utils"; import { TransferOptions } from "./types"; const FLOW_CONTEXT = 'ENTROPY_TRANSFER' @@ -19,7 +18,7 @@ export class EntropyTransfer extends EntropyBase { async transfer (toAddress: string, amountInBits: string, progress?: { start: ()=>void, stop: ()=>void }) { const { decimals } = await getTokenDetails(this.entropy) - const tokens = BigInt(Number(amountInBits) * TOKENS_PER_BITS(decimals)) + const tokens = bitsToTokens(Number(amountInBits), decimals) if (progress) progress.start() try { diff --git a/src/types/index.ts b/src/types/index.ts index 81d3df79..139c5c31 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -13,3 +13,8 @@ export interface EntropyLoggerOptions { level?: EntropyLoggerLogLevel isTesting?: boolean } + +export type TokenDetails = { + decimals: number + symbol: string +} \ No newline at end of file diff --git a/tests/transfer.test.ts b/tests/transfer.test.ts index 2cc86317..3da47e5b 100644 --- a/tests/transfer.test.ts +++ b/tests/transfer.test.ts @@ -1,6 +1,6 @@ import test from 'tape' -import { TOKENS_PER_BITS } from "../src/common/utils"; +import { tokensPerBits } from "../src/common/utils"; import { EntropyTransfer } from '../src/transfer/main' import { EntropyBalance } from '../src/balance/main' import { promiseRunner, setupTest } from './testing-utils' @@ -44,7 +44,7 @@ test('Transfer', async (t) => { 'getBalance (naynay)', balanceService.getBalance(naynayAddress) ) - const expected = Number(inputAmount) * TOKENS_PER_BITS(DEFAULT_TOKEN_DECIMALS) + const expected = Number(inputAmount) * tokensPerBits(DEFAULT_TOKEN_DECIMALS) t.equal(naynayBalance, expected, 'naynay is rolling in it!') t.end() From a4c1abdf062a03fe7303b51d1366990dbc4661b8 Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Wed, 13 Nov 2024 16:55:38 -0600 Subject: [PATCH 3/7] git weirdness --- src/transfer/command.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transfer/command.ts b/src/transfer/command.ts index 930502c9..e892d72a 100644 --- a/src/transfer/command.ts +++ b/src/transfer/command.ts @@ -8,7 +8,7 @@ export function entropyTransferCommand () { transferCommand .description('Transfer funds between two Entropy accounts.') // TODO: name the output .argument('', 'Account address funds will be sent to') - .argument('', 'Amount of funds (in "BITS") to be moved') + .argument('', 'Amount of funds to be moved (in "BITS")') .addOption(accountOption()) .addOption(endpointOption()) .action(async (destination, amount, opts) => { From f6852c6b7ca51adeddabd33676ccb494bef9e9ed Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Wed, 13 Nov 2024 16:56:03 -0600 Subject: [PATCH 4/7] git weirdness part ii --- src/transfer/command.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transfer/command.ts b/src/transfer/command.ts index e892d72a..930502c9 100644 --- a/src/transfer/command.ts +++ b/src/transfer/command.ts @@ -8,7 +8,7 @@ export function entropyTransferCommand () { transferCommand .description('Transfer funds between two Entropy accounts.') // TODO: name the output .argument('', 'Account address funds will be sent to') - .argument('', 'Amount of funds to be moved (in "BITS")') + .argument('', 'Amount of funds (in "BITS") to be moved') .addOption(accountOption()) .addOption(endpointOption()) .action(async (destination, amount, opts) => { From 8f80f5c1d09797f1876f76426f4338f119de4ffe Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Mon, 18 Nov 2024 08:16:29 -0600 Subject: [PATCH 5/7] updated nomenclature for the base unit of BITS to nanoBITS --- CHANGELOG.md | 12 ++++++------ src/balance/command.ts | 6 +++--- src/balance/interaction.ts | 6 +++--- src/common/utils.ts | 16 ++++++++-------- src/faucet/interaction.ts | 4 ++-- src/transfer/main.ts | 10 +++++----- src/transfer/types.ts | 2 +- tests/transfer.test.ts | 4 ++-- 8 files changed, 30 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80b1310d..8176cc9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,8 +16,8 @@ Version header format: `[version] Name - year-month-day (entropy-core compatibil - Shared - amount units are now correct! [#306](https://github.com/entropyxyz/cli/pull/306) - - 1 token = 0.00000000001 BITS - - 1 BITS = 10000000000 tokens + - 1 nanoBITS = 0.00000000001 BITS + - 1 BITS = 10000000000 nanoBITS - Programmatic CLI - `entropy program list` now prints output! [#298](https://github.com/entropyxyz/cli/pull/298) @@ -25,11 +25,11 @@ Version header format: `[version] Name - year-month-day (entropy-core compatibil - Shared - new methods for conversion and other math operations [#306](https://github.com/entropyxyz/cli/pull/306) - - BITS => tokens - - Tokens => BITS + - BITS => nanoBITS + - nanoBITS => BITS - rounding to a specific number of decimal places - - tokens per bits calculation - - new method to pull token details from chain, and cache the results [#306](https://github.com/entropyxyz/cli/pull/306) + - nanoBITS per bits calculation + - new method to pull entropy token details from chain, and cache the results [#306](https://github.com/entropyxyz/cli/pull/306) - TUI - animation on tui load (while entropy loads) [#288](https://github.com/entropyxyz/cli/pull/288) diff --git a/src/balance/command.ts b/src/balance/command.ts index fd5cdefa..760d018d 100644 --- a/src/balance/command.ts +++ b/src/balance/command.ts @@ -3,7 +3,7 @@ import Entropy from "@entropyxyz/sdk"; import { EntropyBalance } from "./main"; import { endpointOption, cliWrite, loadEntropy } from "../common/utils-cli"; -import { findAccountByAddressOrName, getTokenDetails, tokensToBits } from "../common/utils"; +import { findAccountByAddressOrName, getTokenDetails, nanoBitsToBits } from "../common/utils"; import * as config from "../config"; export function entropyBalanceCommand () { @@ -23,8 +23,8 @@ export function entropyBalanceCommand () { const { accounts } = await config.get() const address = findAccountByAddressOrName(accounts, account)?.address - const tokensBalance = await balanceService.getBalance(address) - const balance = tokensToBits(tokensBalance, decimals) + const nanoBalance = await balanceService.getBalance(address) + const balance = nanoBitsToBits(nanoBalance, decimals) cliWrite(`${balance} ${symbol}`) process.exit(0) }) diff --git a/src/balance/interaction.ts b/src/balance/interaction.ts index ad0615f4..c37aa312 100644 --- a/src/balance/interaction.ts +++ b/src/balance/interaction.ts @@ -1,4 +1,4 @@ -import { findAccountByAddressOrName, getTokenDetails, print, round, tokensToBits } from "src/common/utils" +import { findAccountByAddressOrName, getTokenDetails, print, round, nanoBitsToBits } from "src/common/utils" import { EntropyBalance } from "./main" export async function entropyBalance (entropy, endpoint, storedConfig) { @@ -7,8 +7,8 @@ export async function entropyBalance (entropy, endpoint, storedConfig) { const { decimals, symbol } = await getTokenDetails(entropy) const balanceService = new EntropyBalance(entropy, endpoint) const address = findAccountByAddressOrName(storedConfig.accounts, storedConfig.selectedAccount)?.address - const tokensBalance = await balanceService.getBalance(address) - const balance = round(tokensToBits(tokensBalance, decimals)) + const nanoBalance = await balanceService.getBalance(address) + const balance = round(nanoBitsToBits(nanoBalance, decimals)) print(`Entropy Account [${storedConfig.selectedAccount}] (${address}) has a balance of: ${balance} ${symbol}`) } catch (error) { console.error('There was an error retrieving balance', error) diff --git a/src/common/utils.ts b/src/common/utils.ts index 419fde8d..a51ed102 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -127,21 +127,21 @@ export async function getTokenDetails (entropy): Promise { } /* - A "token" is the smallest indivisible unit of account value we track. - A "BIT" is the human readable unit of value value - This constant is then "the number of tokens that make up 1 BITS", or said differently + A "nanoBITS" is the smallest indivisible unit of account value we track. + A "BITS" is the human readable unit of value value + This constant is then "the number of nanoBITS that make up 1 BITS", or said differently "how many decimal places our BITS has". */ -export const tokensPerBits = (decimals: number): number => { +export const nanoBitsPerBits = (decimals: number): number => { return Math.pow(10, decimals) } -export function tokensToBits (numOfTokens: number, decimals: number) { - return numOfTokens / tokensPerBits(decimals) +export function nanoBitsToBits (numOfNanoBits: number, decimals: number) { + return numOfNanoBits / nanoBitsPerBits(decimals) } -export function bitsToTokens (numOfBits: number, decimals: number): bigint { - return BigInt(numOfBits * tokensPerBits(decimals)) +export function bitsToNanoBits (numOfBits: number, decimals: number): bigint { + return BigInt(numOfBits * nanoBitsPerBits(decimals)) } export function round (num: number, decimals: number = 4): number { diff --git a/src/faucet/interaction.ts b/src/faucet/interaction.ts index 89fce14a..e7b6b1b8 100644 --- a/src/faucet/interaction.ts +++ b/src/faucet/interaction.ts @@ -6,11 +6,11 @@ import { EntropyFaucet } from "./main" import { print } from "src/common/utils" let chosenVerifyingKeys = [] -// Sending only 1e10 TOKENS does not allow user's to register after receiving funds +// Sending only 1e10 nanoBITS does not allow user's to register after receiving funds // there are limits in place to ensure user's are leftover with a certain balance in their accounts // increasing amount send here, will allow user's to register right away -// 2 BITS +// 2 BITS = 2e10 nanoBITS const amount = "20000000000" // context for logging file const FLOW_CONTEXT = 'ENTROPY_FAUCET_INTERACTION' diff --git a/src/transfer/main.ts b/src/transfer/main.ts index b3a97deb..aa58b097 100644 --- a/src/transfer/main.ts +++ b/src/transfer/main.ts @@ -1,7 +1,7 @@ import Entropy from "@entropyxyz/sdk"; import { EntropyBase } from "../common/entropy-base"; -import { bitsToTokens, formatDispatchError, getTokenDetails } from "../common/utils"; +import { bitsToNanoBits, formatDispatchError, getTokenDetails } from "../common/utils"; import { TransferOptions } from "./types"; const FLOW_CONTEXT = 'ENTROPY_TRANSFER' @@ -18,14 +18,14 @@ export class EntropyTransfer extends EntropyBase { async transfer (toAddress: string, amountInBits: string, progress?: { start: ()=>void, stop: ()=>void }) { const { decimals } = await getTokenDetails(this.entropy) - const tokens = bitsToTokens(Number(amountInBits), decimals) + const nanoBits = bitsToNanoBits(Number(amountInBits), decimals) if (progress) progress.start() try { await this.rawTransfer({ from: this.entropy.keyring.accounts.registration.pair, to: toAddress, - tokens + nanoBits }) if (progress) return progress.stop() } catch (error) { @@ -35,13 +35,13 @@ export class EntropyTransfer extends EntropyBase { } private async rawTransfer (payload: TransferOptions): Promise { - const { from, to, tokens } = payload + const { from, to, nanoBits } = payload return new Promise((resolve, reject) => { // WARN: await signAndSend is dangerous as it does not resolve // after transaction is complete :melt: this.entropy.substrate.tx.balances - .transferAllowDeath(to, tokens) + .transferAllowDeath(to, nanoBits) // @ts-ignore .signAndSend(from, ({ status, dispatchError }) => { if (dispatchError) { diff --git a/src/transfer/types.ts b/src/transfer/types.ts index c0b48f54..f2827432 100644 --- a/src/transfer/types.ts +++ b/src/transfer/types.ts @@ -4,5 +4,5 @@ import { Pair } from '@entropyxyz/sdk/keys' export interface TransferOptions { from: Pair to: string - tokens: bigint + nanoBits: bigint } diff --git a/tests/transfer.test.ts b/tests/transfer.test.ts index 3da47e5b..95e24ad0 100644 --- a/tests/transfer.test.ts +++ b/tests/transfer.test.ts @@ -1,6 +1,6 @@ import test from 'tape' -import { tokensPerBits } from "../src/common/utils"; +import { nanoBitsPerBits } from "../src/common/utils"; import { EntropyTransfer } from '../src/transfer/main' import { EntropyBalance } from '../src/balance/main' import { promiseRunner, setupTest } from './testing-utils' @@ -44,7 +44,7 @@ test('Transfer', async (t) => { 'getBalance (naynay)', balanceService.getBalance(naynayAddress) ) - const expected = Number(inputAmount) * tokensPerBits(DEFAULT_TOKEN_DECIMALS) + const expected = Number(inputAmount) * nanoBitsPerBits(DEFAULT_TOKEN_DECIMALS) t.equal(naynayBalance, expected, 'naynay is rolling in it!') t.end() From ffe03c94ad25238637102811e7c024a29d69cbce Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Thu, 21 Nov 2024 14:29:43 -0500 Subject: [PATCH 6/7] weird leftover conflict resolution --- CHANGELOG.md | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6623c5c7..53a347d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,13 +14,10 @@ Version header format: `[version] Name - year-month-day (entropy-core compatibil ### Fixed -<<<<<<< HEAD - Shared - amount units are now correct! [#306](https://github.com/entropyxyz/cli/pull/306) - 1 nanoBITS = 0.00000000001 BITS - 1 BITS = 10000000000 nanoBITS -======= ->>>>>>> dev - Programmatic CLI - `entropy program list` now prints output! [#298](https://github.com/entropyxyz/cli/pull/298) @@ -33,19 +30,14 @@ Version header format: `[version] Name - year-month-day (entropy-core compatibil - rounding to a specific number of decimal places - nanoBITS per bits calculation - new method to pull entropy token details from chain, and cache the results [#306](https://github.com/entropyxyz/cli/pull/306) + - TUI - animation on tui load (while entropy loads) [#288](https://github.com/entropyxyz/cli/pull/288) -<<<<<<< HEAD ### Changed -======= -### Changes - Shared - updated return data displayed to user on account creation (create or import) [#311](https://github.com/entropyxyz/cli/pull/311) ->>>>>>> dev - -- Shared - Balance now displays the number of BITS to the nearest 4 decimal places [#306](https://github.com/entropyxyz/cli/pull/306) ## [0.1.1] Deadpool - 2024-11-06 (entropy-core compatibility: 0.3.0) From 21d7a90e2090af663697ed556b2397fbb773f9fb Mon Sep 17 00:00:00 2001 From: Nayyir Jutha Date: Thu, 21 Nov 2024 14:42:15 -0500 Subject: [PATCH 7/7] updated cli output to be more programmatic and not human sentences, updated amount for faucet to send two whole BITS, rather than a hardcoded string --- src/balance/command.ts | 6 +++--- src/faucet/interaction.ts | 13 +++++++------ src/transfer/command.ts | 7 ++++++- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/balance/command.ts b/src/balance/command.ts index 760d018d..15e799d4 100644 --- a/src/balance/command.ts +++ b/src/balance/command.ts @@ -3,7 +3,7 @@ import Entropy from "@entropyxyz/sdk"; import { EntropyBalance } from "./main"; import { endpointOption, cliWrite, loadEntropy } from "../common/utils-cli"; -import { findAccountByAddressOrName, getTokenDetails, nanoBitsToBits } from "../common/utils"; +import { findAccountByAddressOrName, getTokenDetails, nanoBitsToBits, round } from "../common/utils"; import * as config from "../config"; export function entropyBalanceCommand () { @@ -24,8 +24,8 @@ export function entropyBalanceCommand () { const address = findAccountByAddressOrName(accounts, account)?.address const nanoBalance = await balanceService.getBalance(address) - const balance = nanoBitsToBits(nanoBalance, decimals) - cliWrite(`${balance} ${symbol}`) + const balance = round(nanoBitsToBits(nanoBalance, decimals)) + cliWrite({ balance, symbol }) process.exit(0) }) diff --git a/src/faucet/interaction.ts b/src/faucet/interaction.ts index e7b6b1b8..2791aea5 100644 --- a/src/faucet/interaction.ts +++ b/src/faucet/interaction.ts @@ -3,15 +3,13 @@ import yoctoSpinner from 'yocto-spinner'; import { EntropyLogger } from '../common/logger' import { FAUCET_PROGRAM_POINTER } from "./utils" import { EntropyFaucet } from "./main" -import { print } from "src/common/utils" +import { bitsToNanoBits, getTokenDetails, print } from "src/common/utils" let chosenVerifyingKeys = [] // Sending only 1e10 nanoBITS does not allow user's to register after receiving funds // there are limits in place to ensure user's are leftover with a certain balance in their accounts // increasing amount send here, will allow user's to register right away -// 2 BITS = 2e10 nanoBITS -const amount = "20000000000" // context for logging file const FLOW_CONTEXT = 'ENTROPY_FAUCET_INTERACTION' const SPINNER_TEXT = 'Funding account…' @@ -25,15 +23,18 @@ export async function entropyFaucet (entropy: Entropy, options, logger: EntropyL if (!entropy.registrationManager.signer.pair) { throw new Error("Keys are undefined") } + + const { decimals } = await getTokenDetails(entropy) + const amount = bitsToNanoBits(2, decimals) const faucetService = new EntropyFaucet(entropy, endpoint) const verifyingKeys = await faucetService.getAllFaucetVerifyingKeys() // @ts-expect-error - return sendMoneyFromRandomFaucet(entropy, options.endpoint, verifyingKeys, logger) + return sendMoneyFromRandomFaucet(entropy, options.endpoint, verifyingKeys, amount.toString(), logger) } // Method that takes in the initial list of verifying keys (to avoid multiple calls to the rpc) and recursively retries each faucet until // a successful transfer is made -async function sendMoneyFromRandomFaucet (entropy: Entropy, endpoint: string, verifyingKeys: string[], logger: EntropyLogger) { +async function sendMoneyFromRandomFaucet (entropy: Entropy, endpoint: string, verifyingKeys: string[], amount: string, logger: EntropyLogger) { if (!faucetSpinner.isSpinning) { faucetSpinner.start() } @@ -61,7 +62,7 @@ async function sendMoneyFromRandomFaucet (entropy: Entropy, endpoint: string, ve return } else { // Check for non faucet errors (FaucetError) and retry faucet - await sendMoneyFromRandomFaucet(entropy, endpoint, verifyingKeys, logger) + await sendMoneyFromRandomFaucet(entropy, endpoint, verifyingKeys, amount, logger) } } } \ No newline at end of file diff --git a/src/transfer/command.ts b/src/transfer/command.ts index 930502c9..98945102 100644 --- a/src/transfer/command.ts +++ b/src/transfer/command.ts @@ -19,7 +19,12 @@ export function entropyTransferCommand () { await transferService.transfer(destination, amount) - cliWrite(`Transaction successful: Sent ${amount} ${symbol} to ${destination}`) + cliWrite({ + source: opts.account, + destination, + amount, + symbol + }) process.exit(0) }) return transferCommand