Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NayNay] File Restructure: Base Class + Balance Restructure #207

Merged
merged 16 commits into from
Aug 5, 2024
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/balance/command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Entropy from "@entropyxyz/sdk"
import { Base } from "../common/base"
import { BalanceUtils } from "./utils"
import { FLOW_CONTEXT } from "./constants"

export class BalanceCommand extends Base {
private readonly balanceService: BalanceUtils

constructor (entropy: Entropy, endpoint: string) {
super(entropy, endpoint, FLOW_CONTEXT)
this.balanceService = new BalanceUtils(this.entropy, endpoint)
}

public async getBalance (address: string) {
const balance = await this.balanceService.getBalance(address)

this.logger.log(`Current balance of ${address}: ${balance}`, `${BalanceCommand.name}`)

return `${balance.toLocaleString('en-US')} BITS`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't think this should have BITS, I don't even know about the tolocaleString.
We want this to be CLI first, so just raw JSON friendly formats like numbers, objects, not sentences (number + unit).

I could be wrong!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the utils method is the pure function that returns a number, my vision was that the controller/command file will handle how we want the data to be presented

}
}
1 change: 1 addition & 0 deletions src/balance/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const FLOW_CONTEXT = 'ENTROPY-BALANCE'
File renamed without changes.
44 changes: 44 additions & 0 deletions src/balance/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import Entropy from "@entropyxyz/sdk";
import { Base } from "../common/base";
import { BalanceInfo } from "./types";
import { FLOW_CONTEXT } from "./constants";

const hexToBigInt = (hexString: string) => BigInt(hexString)

export class BalanceUtils extends Base {
constructor (entropy: Entropy, endpoint: string) {
super(entropy, endpoint, FLOW_CONTEXT)
}

public async getBalance (address: string): Promise<number> {
try {
const accountInfo = (await this.entropy.substrate.query.system.account(address)) as any

return parseInt(hexToBigInt(accountInfo.data.free).toString())
} catch (error) {
this.logger.error(`There was an error getting balance for [acct = ${address}]`, error);
throw new Error(error.message)
}
}

public async getBalances (addresses: string[]): Promise<BalanceInfo> {
const balanceInfo: BalanceInfo = {}
try {
await Promise.all(addresses.map(async address => {
try {
const balance = await this.getBalance(address)

balanceInfo[address] = { balance }
} catch (error) {
this.logger.error(`Error retrieving balance for ${address}`, error);
balanceInfo[address] = { error: error.message }
}
}))

return balanceInfo
} catch (error) {
this.logger.error(`There was an error getting balances for [${addresses}]`, error);
throw new Error(error.message)
}
}
}
12 changes: 12 additions & 0 deletions src/common/base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import Entropy from "@entropyxyz/sdk";
import { EntropyLogger } from "./logger";

export abstract class Base {
protected logger: EntropyLogger
protected entropy: Entropy

constructor (entropy: Entropy, endpoint: string, flowContext: string) {
this.logger = new EntropyLogger(flowContext, endpoint)
this.entropy = entropy
}
}
2 changes: 1 addition & 1 deletion src/common/logger.ts
Original file line number Diff line number Diff line change
@@ -117,7 +117,7 @@ export class EntropyLogger {
this.winstonLogger.log({
level,
message: maskPayload(message),
context: context || this.context,
context: context ? `${this.context}:${context}` : this.context,
endpoint: this.endpoint,
description,
stack,
36 changes: 0 additions & 36 deletions src/flows/balance/balance.ts

This file was deleted.

9 changes: 6 additions & 3 deletions src/flows/balance/cli.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { BalanceCommand } from 'src/balance/command'
import { initializeEntropy } from '../../common/initializeEntropy'
import * as config from '../../config'
import { getBalance } from './balance'
import { EntropyLogger } from 'src/common/logger'

// TO-DO: move entropy initialization and account retrieval to a shared container
// should remove the need to initialize entropy every time
export async function cliGetBalance ({ address, password, endpoint }) {
const logger = new EntropyLogger('CLI::CHECK_BALANCE', endpoint)
const storedConfig = await config.get()
@@ -17,8 +19,9 @@ export async function cliGetBalance ({ address, password, endpoint }) {
}

const entropy = await initializeEntropy({ keyMaterial: account.data, password, endpoint })
const balance = await getBalance(entropy, address)
const balanceController = new BalanceCommand(entropy, endpoint)
const balance = await balanceController.getBalance(address)

return `${balance.toLocaleString('en-US')} BITS`
return balance
}

11 changes: 7 additions & 4 deletions src/flows/balance/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { EntropyLogger } from "src/common/logger";
import { initializeEntropy } from "../../common/initializeEntropy"
import { print, getSelectedAccount } from "../../common/utils"
import { getBalance } from "./balance";
import { BalanceCommand } from "src/balance/command";

// TO-DO setup flow method to provide options to allow users to select account,
// TO-DO: setup flow method to provide options to allow users to select account,
// use external address, or get balances for all accounts in config
// TO-DO: move entropy initialization and account retrieval to a shared container
// should remove the need to initialize entropy every time
export async function checkBalance ({ accounts, selectedAccount: selectedAccountAddress }, options, logger: EntropyLogger) {
const FLOW_CONTEXT = 'CHECK_BALANCE'
const { endpoint } = options
@@ -13,7 +15,8 @@ export async function checkBalance ({ accounts, selectedAccount: selectedAccount
const selectedAccount = getSelectedAccount(accounts, selectedAccountAddress)
logger.log(selectedAccount, FLOW_CONTEXT)
const entropy = await initializeEntropy({ keyMaterial: selectedAccount.data, endpoint });
const balanceController = new BalanceCommand(entropy, endpoint)
const accountAddress = selectedAccountAddress
const freeBalance = await getBalance(entropy, accountAddress)
print(`Address ${accountAddress} has a balance of: ${freeBalance.toLocaleString('en-US')} BITS`)
const freeBalanceString = await balanceController.getBalance(accountAddress)
print(`Address ${accountAddress} has a balance of: ${freeBalanceString}`)
}
14 changes: 7 additions & 7 deletions tests/balance.test.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
import test from 'tape'

import { getBalance, getBalances } from '../src/flows/balance/balance'
import { setupTest, charlieStashAddress as richAddress } from './testing-utils'
import { BalanceUtils } from 'src/balance/utils'

const networkType = 'two-nodes'

test('getBalance + getBalances', async (t) => {
const { run, entropy } = await setupTest(t, { networkType })

const { run, entropy, endpoint } = await setupTest(t, { networkType })
const balanceUtils = new BalanceUtils(entropy, endpoint)
const newAddress = entropy.keyring.accounts.registration.address

/* getBalance */
const newAddressBalance = await run(
'getBalance (newSeed)',
getBalance(entropy, newAddress)
balanceUtils.getBalance(newAddress)
)
t.equal(newAddressBalance, 0, 'newSeed balance = 0')

const richAddressBalance = await run(
'getBalance (richAddress)',
getBalance(entropy, richAddress)
balanceUtils.getBalance(richAddress)
)
t.true(richAddressBalance > BigInt(10e10), 'richAddress balance >>> 0')

/* getBalances */
const balances = await run(
'getBalances',
getBalances(entropy, [newAddress, richAddress])
balanceUtils.getBalances([newAddress, richAddress])
)
t.deepEqual(
balances,
@@ -40,7 +40,7 @@ test('getBalance + getBalances', async (t) => {
const badAddresses = ['5Cz6BfUaxxXCA3jninzxdan4JdmC1NVpgkiRPYhXbhr', '5Cz6BfUaxxXCA3jninzxdan4JdmC1NVpgkiRPYhXbhrfnD']
const balancesWithNoGoodAddress = await run(
'getBalances::one good address',
getBalances(entropy, badAddresses)
balanceUtils.getBalances(badAddresses)
)

badAddresses.forEach(addr => {
12 changes: 7 additions & 5 deletions tests/testing-utils/setup-test.ts
Original file line number Diff line number Diff line change
@@ -12,16 +12,18 @@ import { makeSeed, promiseRunner, sleep } from './'
interface SetupTestOpts {
configPath?: string
networkType?: string
seed?: string,
seed?: string
endpoint?: string
}
const NETWORK_TYPE_DEFAULT = 'two-nodes'
let counter = 0

export async function setupTest (t: Test, opts?: SetupTestOpts): Promise<{ entropy: Entropy; run: any }> {
export async function setupTest (t: Test, opts?: SetupTestOpts): Promise<{ entropy: Entropy; run: any; endpoint: string }> {
const {
configPath = `/tmp/entropy-cli-${Date.now()}_${counter++}.json`,
networkType = NETWORK_TYPE_DEFAULT,
seed = makeSeed()
seed = makeSeed(),
endpoint = 'ws://127.0.0.1:9944',
} = opts || {}

const run = promiseRunner(t)
@@ -45,11 +47,11 @@ export async function setupTest (t: Test, opts?: SetupTestOpts): Promise<{ entro
const keyring = new Keyring({ seed, debug: true })
const entropy = await initializeEntropy({
keyMaterial: keyring.getAccount(),
endpoint: 'ws://127.0.0.1:9944',
endpoint,
configPath
})

await run('entropy ready', entropy.ready)

return { entropy, run }
return { entropy, run, endpoint }
}
14 changes: 8 additions & 6 deletions tests/transfer.test.ts
Original file line number Diff line number Diff line change
@@ -11,12 +11,13 @@ import {
spinNetworkDown
} from './testing-utils'

import { getBalance } from '../src/flows/balance/balance'
import { initializeEntropy } from 'src/common/initializeEntropy'
import { charlieStashAddress, charlieStashSeed } from './testing-utils/constants'
import { transfer } from 'src/flows/entropyTransfer/transfer'
import { BalanceUtils } from 'src/balance/utils'

const networkType = 'two-nodes'
const endpoint = 'ws://127.0.0.1:9944'

test('Transfer', async (t) => {
/* Setup */
@@ -37,8 +38,9 @@ test('Transfer', async (t) => {
const naynayKeyring = new Keyring({ seed: naynaySeed, debug: true })
const charlieKeyring = new Keyring({ seed: charlieStashSeed, debug: true })

const entropy = await initializeEntropy({ keyMaterial: naynayKeyring.getAccount(), endpoint: 'ws://127.0.0.1:9944', })
const charlieEntropy = await initializeEntropy({ keyMaterial: charlieKeyring.getAccount(), endpoint: 'ws://127.0.0.1:9944', })
const entropy = await initializeEntropy({ keyMaterial: naynayKeyring.getAccount(), endpoint, })
const charlieEntropy = await initializeEntropy({ keyMaterial: charlieKeyring.getAccount(), endpoint, })
const balanceUtils = new BalanceUtils(entropy, endpoint)
await run('entropy ready', entropy.ready)
await run('charlie ready', charlieEntropy.ready)

@@ -47,14 +49,14 @@ test('Transfer', async (t) => {
// Check Balance of new account
let naynayBalance = await run(
'getBalance (naynay)',
getBalance(entropy, recipientAddress)
balanceUtils.getBalance(recipientAddress)
)

t.equal(naynayBalance, 0, 'naynay is broke')

let charlieBalance = await run(
'getBalance (charlieStash)',
getBalance(entropy, charlieStashAddress)
balanceUtils.getBalance(charlieStashAddress)
)

t.equal(charlieBalance, 1e17, 'charlie got bank')
@@ -73,7 +75,7 @@ test('Transfer', async (t) => {
// Re-Check Balance of new account
naynayBalance = await run(
'getBalance (naynay)',
getBalance(entropy, recipientAddress)
balanceUtils.getBalance(recipientAddress)
)

t.equal(naynayBalance, 1000 * 10e10, 'naynay is rolling in it!')