Repository: celo-org/developer-tooling
Pull request #578: Migrate account:balance to viem
Author: login: shazarre
Created: 2025-03-27T10:52:08Z | Merged: 2025-03-28T12:53:02Z

### Description

This PR migrates `account:balance` to viem.

#### Other changes

Adds bigint printing support to cli utils.

### Tested

Ran tests and ran the command vs a local anvil node.

### How to QA

`NO_SYNCCHECK=1 yarn workspace @celo/celocli run dev account:balance 0x5409ED021D9299bf6814279A6A1411A7e866A631 --node http://127.0.0.1:8545`

### Related issues

- Fixes #555

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on adding support for the `celoBaklava` chain to the Celo client, enhancing balance retrieval functionality, and improving the display of balances in the CLI.

### Detailed summary
- Added `celoBaklava` chain definition in `chains.ts`.
- Updated `CeloClient` type to include `celoBaklava`.
- Modified balance retrieval in `Balance` command to use `getTotalBalance`.
- Improved console output for balance display, converting values to wei.
- Refactored tests to align with new balance retrieval logic.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

Linked issue #555: account:balance command to viem
convert the account balance to viem 

Diff:
diff --git a/packages/cli/src/base.ts b/packages/cli/src/base.ts
index 14f1354d94..a73a0ee0b0 100644
--- a/packages/cli/src/base.ts
+++ b/packages/cli/src/base.ts
@@ -14,6 +14,7 @@ import { createPublicClient, extractChain, http } from 'viem'
 import { celo, celoAlfajores } from 'viem/chains'
 import { ipc } from 'viem/node'
 import Web3 from 'web3'
+import { celoBaklava } from './packages-to-be/chains'
 import { CeloClient } from './packages-to-be/client'
 import { CustomFlags } from './utils/command'
 import { getDefaultDerivationPath, getNodeUrl } from './utils/config'
@@ -178,15 +179,32 @@ export abstract class BaseCommand extends Command {
       const intermediateClient = createPublicClient({
         transport,
       })
+      const chainId = await intermediateClient.getChainId()
       const extractedChain = extractChain({
-        chains: [celo, celoAlfajores],
-        id: (await intermediateClient.getChainId()) as 42220 | 44787,
+        chains: [celo, celoAlfajores, celoBaklava],
+        id: chainId as 42_220 | 44_787 | 62_320,
       })
 
-      this.publicClient = createPublicClient({
-        transport,
-        chain: extractedChain ?? celo,
-      })
+      if (extractedChain) {
+        this.publicClient = createPublicClient({
+          transport,
+          chain: extractedChain,
+        })
+      } else {
+        this.publicClient = createPublicClient({
+          transport,
+          chain: {
+            name: 'Custom Chain',
+            id: chainId,
+            nativeCurrency: celo.nativeCurrency,
+            formatters: celo.formatters,
+            serializers: celo.serializers,
+            rpcUrls: {
+              default: { http: [nodeUrl] },
+            },
+          },
+        }) as any as CeloClient
+      }
     }
 
     return this.publicClient
diff --git a/packages/cli/src/commands/account/balance.test.ts b/packages/cli/src/commands/account/balance.test.ts
index f78b65de5f..6859a4034d 100644
--- a/packages/cli/src/commands/account/balance.test.ts
+++ b/packages/cli/src/commands/account/balance.test.ts
@@ -4,11 +4,13 @@ import BigNumber from 'bignumber.js'
 import Web3 from 'web3'
 import { topUpWithToken } from '../../test-utils/chain-setup'
 import { stripAnsiCodesFromNestedArray, testLocallyWithWeb3Node } from '../../test-utils/cliUtils'
+import Lock from '../lockedcelo/lock'
+import Unlock from '../lockedcelo/unlock'
 import Balance from './balance'
 
 process.env.NO_SYNCCHECK = 'true'
 
-testWithAnvilL2('account:set-name cmd', (web3: Web3) => {
+testWithAnvilL2('account:balance cmd', (web3: Web3) => {
   const consoleMock = jest.spyOn(console, 'log')
   let accounts: string[] = []
   let kit: ContractKit
@@ -19,55 +21,61 @@ testWithAnvilL2('account:set-name cmd', (web3: Web3) => {
     consoleMock.mockClear()
   })
 
-  it('shows the balance of the account in several currencies', async () => {
+  it('shows the balance of the account for CELO only', async () => {
+    await testLocallyWithWeb3Node(Lock, ['--from', accounts[0], '--value', '1234567890'], web3)
+    await testLocallyWithWeb3Node(Unlock, ['--from', accounts[0], '--value', '890'], web3)
+
+    consoleMock.mockClear()
+
     await testLocallyWithWeb3Node(Balance, [accounts[0]], web3)
 
     expect(stripAnsiCodesFromNestedArray(consoleMock.mock.calls)).toMatchInlineSnapshot(`
       [
         [
-          "All balances expressed in units of 10^-18.",
+          "All balances expressed in units of wei.",
         ],
         [
-          "lockedCELO: 0
-      pending: 0
-      CELO: 1e+24
-      cUSD: 0
-      cEUR: 0
-      cREAL: 0",
+          "CELO: 999999999153393765432110 (~9.9999999915339376543211e+23)
+      cEUR: 0 
+      cREAL: 0 
+      cUSD: 0 
+      lockedCELO: 1234567000 (~1.234567e+9)
+      pending: 890 ",
         ],
       ]
     `)
   })
 
-  it('shows the balance of the account in given currency', async () => {
-    const amount = new BigNumber('1234567890000000000000')
-    await topUpWithToken(kit, StableToken.cUSD, accounts[0], amount)
+  it('shows the balance of the account for different tokens', async () => {
+    const cUSDAmount = new BigNumber('1234567890000000000000')
+    const cEURAmount = new BigNumber('2345678900000000000000')
+    const cREALAmount = new BigNumber('3456789000000000000000')
+
+    await topUpWithToken(kit, StableToken.cUSD, accounts[0], cUSDAmount)
+    await topUpWithToken(kit, StableToken.cEUR, accounts[0], cEURAmount)
+    await topUpWithToken(kit, StableToken.cREAL, accounts[0], cREALAmount)
 
     await testLocallyWithWeb3Node(
       Balance,
-      [
-        accounts[0],
-        '--erc20Address',
-        (await kit.contracts.getStableToken(StableToken.cUSD)).address,
-      ],
+      [accounts[0], '--erc20Address', (await kit.contracts.getGoldToken()).address],
       web3
     )
 
     expect(stripAnsiCodesFromNestedArray(consoleMock.mock.calls)).toMatchInlineSnapshot(`
       [
         [
-          "All balances expressed in units of 10^-18.",
+          "All balances expressed in units of wei.",
         ],
         [
-          "lockedCELO: 0
-      pending: 0
-      CELO: 1e+24
-      cUSD: ${amount.toExponential()}
-      cEUR: 0
-      cREAL: 0",
+          "CELO: 1000000000000000000000000 (~1e+24)
+      cEUR: 2345678900000000000000 (~2.3456789e+21)
+      cREAL: 3456789000000000000000 (~3.456789e+21)
+      cUSD: 1234567890000000000000 (~1.23456789e+21)
+      lockedCELO: 0 
+      pending: 0 ",
         ],
         [
-          "erc20: ${amount.toExponential()}",
+          "erc20: 1000000000000000000000000 (~1e+24)",
         ],
       ]
     `)
diff --git a/packages/cli/src/commands/account/balance.ts b/packages/cli/src/commands/account/balance.ts
index ca06cfb592..d1b9538a00 100644
--- a/packages/cli/src/commands/account/balance.ts
+++ b/packages/cli/src/commands/account/balance.ts
@@ -1,5 +1,8 @@
+import { StrongAddress } from '@celo/base'
+import { erc20Abi, getContract, PublicClient } from 'viem'
 import { BaseCommand } from '../../base'
-import { failWith, printValueMap } from '../../utils/cli'
+import { getTotalBalance } from '../../packages-to-be/account'
+import { failWith, printValueMapRecursive } from '../../utils/cli'
 import { CustomArgs, CustomFlags } from '../../utils/command'
 import { ViewCommmandFlags } from '../../utils/flags'
 
@@ -23,15 +26,27 @@ export default class Balance extends BaseCommand {
   ]
 
   async run() {
-    const kit = await this.getKit()
+    const client = await this.getPublicClient()
     const { args, flags } = await this.parse(Balance)
 
-    console.log('All balances expressed in units of 10^-18.')
-    printValueMap(await kit.getTotalBalance(args.arg1 as string))
+    console.log('All balances expressed in units of wei.')
+
+    // TODO this typing needs to be handled better...
+    printValueMapRecursive(
+      await getTotalBalance(client as any as PublicClient, args.arg1 as StrongAddress)
+    )
+
     if (flags.erc20Address) {
+      const erc20Contract = getContract({
+        client,
+        address: flags.erc20Address,
+        abi: erc20Abi,
+      })
+
       try {
-        const erc20 = await kit.contracts.getErc20(flags.erc20Address)
-        printValueMap({ erc20: await erc20.balanceOf(args.arg1 as string) })
+        printValueMapRecursive({
+          erc20: await erc20Contract.read.balanceOf([args.arg1 as StrongAddress]),
+        })
       } catch {
         failWith('Invalid erc20 address')
       }
diff --git a/packages/cli/src/packages-to-be/account.ts b/packages/cli/src/packages-to-be/account.ts
index fa164e3160..b910ecf67c 100644
--- a/packages/cli/src/packages-to-be/account.ts
+++ b/packages/cli/src/packages-to-be/account.ts
@@ -1,6 +1,6 @@
-import { accountsABI } from '@celo/abis-12'
+import { accountsABI, lockedGoldABI } from '@celo/abis-12'
 import { StrongAddress } from '@celo/base'
-import { PublicClient } from 'viem'
+import { erc20Abi, PublicClient } from 'viem'
 import { resolveAddress } from './address-resolver'
 
 export const signerToAccount = async (
@@ -14,3 +14,70 @@ export const signerToAccount = async (
     args: [signer],
   })
 }
+
+export const getTotalBalance = async (
+  client: PublicClient,
+  address: StrongAddress
+): Promise<{
+  lockedCELO: bigint
+  pending: bigint
+  CELO: bigint
+  cUSD: bigint
+  cEUR: bigint
+  cREAL: bigint
+}> => {
+  const [lockedCeloAddress, celoTokenAddress, cUSDAddress, cEURAddress, cREALAddress] =
+    await Promise.all(
+      (['LockedGold', 'GoldToken', 'StableToken', 'StableTokenEUR', 'StableTokenBRL'] as const).map(
+        (contractName) => resolveAddress(client, contractName)
+      )
+    )
+
+  const [lockedCELO, pending, CELO, cUSD, cEUR, cREAL] = await Promise.all([
+    client.readContract({
+      address: lockedCeloAddress,
+      abi: lockedGoldABI,
+      functionName: 'getAccountTotalLockedGold',
+      args: [address],
+    }),
+    client.readContract({
+      address: lockedCeloAddress,
+      abi: lockedGoldABI,
+      functionName: 'getTotalPendingWithdrawals',
+      args: [address],
+    }),
+    client.readContract({
+      address: celoTokenAddress,
+      abi: erc20Abi,
+      functionName: 'balanceOf',
+      args: [address],
+    }),
+    client.readContract({
+      address: cUSDAddress,
+      abi: erc20Abi,
+      functionName: 'balanceOf',
+      args: [address],
+    }),
+    client.readContract({
+      address: cEURAddress,
+      abi: erc20Abi,
+      functionName: 'balanceOf',
+      args: [address],
+    }),
+    client.readContract({
+      address: cREALAddress,
+      abi: erc20Abi,
+      functionName: 'balanceOf',
+      args: [address],
+    }),
+  ] as const)
+
+  return {
+    lockedCELO,
+    pending,
+    CELO,
+    cUSD,
+    cEUR,
+    cREAL,
+  }
+}
diff --git a/packages/cli/src/packages-to-be/chains.ts b/packages/cli/src/packages-to-be/chains.ts
new file mode 100644
index 0000000000..1e64e4b108
--- /dev/null
+++ b/packages/cli/src/packages-to-be/chains.ts
@@ -0,0 +1,29 @@
+import { defineChain } from 'viem'
+
+export const celoBaklava = /*#__PURE__*/ defineChain({
+  id: 62_320,
+  name: 'Baklava',
+  nativeCurrency: {
+    decimals: 18,
+    name: 'CELO',
+    symbol: 'B-CELO',
+  },
+  rpcUrls: {
+    default: {
+      http: ['https://baklava-forno.celo-testnet.org'],
+    },
+  },
+  blockExplorers: {
+    default: {
+      name: 'Celo Baklava Explorer',
+      url: 'https://celo-baklava.blockscout.com',
+      apiUrl: 'https://celo-baklava.blockscout.com/api',
+    },
+  },
+  contracts: {
+    multicall3: {
+      address: '0xcA11bde05977b3631167028862bE2a173976CA11',
+    },
+  },
+  testnet: true,
+})
diff --git a/packages/cli/src/packages-to-be/client.ts b/packages/cli/src/packages-to-be/client.ts
index 008ed1412a..8b7a8f1761 100644
--- a/packages/cli/src/packages-to-be/client.ts
+++ b/packages/cli/src/packages-to-be/client.ts
@@ -1,4 +1,8 @@
 import { PublicClient, Transport } from 'viem'
 import { celo, celoAlfajores } from 'viem/chains'
+import { celoBaklava } from './chains'
 
-export type CeloClient = PublicClient<Transport, typeof celo | typeof celoAlfajores>
+export type CeloClient = PublicClient<
+  Transport,
+  typeof celo | typeof celoAlfajores | typeof celoBaklava
+>
diff --git a/packages/cli/src/utils/cli.ts b/packages/cli/src/utils/cli.ts
index 5fabcdc688..c62246493e 100644
--- a/packages/cli/src/utils/cli.ts
+++ b/packages/cli/src/utils/cli.ts
@@ -150,6 +150,13 @@ function toStringValueMapRecursive(valueMap: Record<string, any>, prefix: string
       }
       return '\n' + toStringValueMapRecursive(v, prefix + '  ')
     }
+
+    if (typeof v === 'bigint') {
+      const asSciNotation = v > 1000n ? `(~${bigintToExponential(v)})` : ''
+
+      return `${v} ${asSciNotation}`
+    }
+
     return chalk`${v}`
   }
   return Object.keys(valueMap)
@@ -187,3 +194,9 @@ export function humanizeRequirements(requirements: LockedGoldRequirements) {
   })
   return { requiredCelo, requiredDays }
 }
+
+// TODO this will have to be refactored not to use BigNumber
+// once we drop its usage
+function bigintToExponential(value: bigint) {
+  return new BigNumber(value.toString()).toExponential()
+}


Reviews:
user: login: aaronmgdr
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T10:58:26Z
user: login: aaronmgdr
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T11:10:16Z
user: login: aaronmgdr
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T11:10:55Z
user: login: aaronmgdr
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T11:12:10Z
user: login: aaronmgdr
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T11:13:38Z
user: login: aaronmgdr
body: easy
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T11:16:18Z
user: login: aaronmgdr
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T11:16:47Z
user: login: nicolasbrugneaux
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T12:09:16Z
user: login: nicolasbrugneaux
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T12:10:35Z
user: login: shazarre
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T14:15:18Z
user: login: shazarre
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-28T09:03:59Z
user: login: aaronmgdr
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-28T10:19:26Z

Review comments:
diff_hunk: @@ -4,11 +4,13 @@ import BigNumber from 'bignumber.js'
 import Web3 from 'web3'
 import { topUpWithToken } from '../../test-utils/chain-setup'
 import { stripAnsiCodesFromNestedArray, testLocallyWithWeb3Node } from '../../test-utils/cliUtils'
+import Lock from '../lockedcelo/lock'
+import Unlock from '../lockedcelo/unlock'
 import Balance from './balance'
 
 process.env.NO_SYNCCHECK = 'true'
 
-testWithAnvilL2('account:set-name cmd', (web3: Web3) => {
+testWithAnvilL2('account:balance cmd', (web3: Web3) => {
path: packages/cli/src/commands/account/balance.test.ts
user: login: aaronmgdr
body: nice
created_at: 2025-03-27T10:58:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -23,15 +25,27 @@ export default class Balance extends BaseCommand {
   ]
 
   async run() {
-    const kit = await this.getKit()
+    const client = await this.getPublicClient()
     const { args, flags } = await this.parse(Balance)
 
-    console.log('All balances expressed in units of 10^-18.')
-    printValueMap(await kit.getTotalBalance(args.arg1 as string))
+    console.log('All balances expressed in units of wei.')
path: packages/cli/src/commands/account/balance.ts
user: login: aaronmgdr
body: nit can we use the oclif ux logging tool here? 
created_at: 2025-03-27T11:10:16Z
author_association: CONTRIBUTOR
diff_hunk: @@ -14,3 +14,56 @@ export const signerToAccount = async (
     args: [signer],
   })
 }
+
+export const getTotalBalance = async (
+  client: PublicClient,
+  address: StrongAddress
+): Promise<{
+  lockedCELO: bigint
+  pending: bigint
+  CELO: bigint
+  cUSD: bigint
+  cEUR: bigint
+  cREAL: bigint
+}> => {
+  const lockedCeloAddress = await resolveAddress(client, 'LockedGold')
+
+  return {
path: packages/cli/src/packages-to-be/account.ts
user: login: aaronmgdr
body: nit can we use multicall? 
created_at: 2025-03-27T11:10:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -150,6 +150,13 @@ function toStringValueMapRecursive(valueMap: Record<string, any>, prefix: string
       }
       return '\n' + toStringValueMapRecursive(v, prefix + '  ')
     }
+
+    if (typeof v === 'bigint') {
+      const extra = v > 1000n ? `(~${bigintToExponential(v)})` : ''
+
+      return `${v} ${extra}`
path: packages/cli/src/utils/cli.ts
user: login: aaronmgdr
body: ```suggestion

      const asSciNotation = v > 1000n ? `(~${bigintToExponential(v)})` : ''

      return `${v} ${asSciNotation}`
```
created_at: 2025-03-27T11:12:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -187,3 +194,14 @@ export function humanizeRequirements(requirements: LockedGoldRequirements) {
   })
   return { requiredCelo, requiredDays }
 }
+
+// TODO this will have to be refactored not to use BigNumber
+// once we drop its usage
+function bigintToExponential(value: bigint) {
+  // as per the check in `toStringValueMapRecursive`
+  if (value <= 1000n) {
path: packages/cli/src/utils/cli.ts
user: login: aaronmgdr
body: lets make a const that us shared between the 2 places instead of relying on comments
created_at: 2025-03-27T11:13:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -187,3 +194,14 @@ export function humanizeRequirements(requirements: LockedGoldRequirements) {
   })
   return { requiredCelo, requiredDays }
 }
+
+// TODO this will have to be refactored not to use BigNumber
+// once we drop its usage
+function bigintToExponential(value: bigint) {
+  // as per the check in `toStringValueMapRecursive`
+  if (value <= 1000n) {
path: packages/cli/src/utils/cli.ts
user: login: aaronmgdr
body: actually do we need this if at all?  just have the function always return exponential that simplifiess things
created_at: 2025-03-27T11:15:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -187,3 +194,14 @@ export function humanizeRequirements(requirements: LockedGoldRequirements) {
   })
   return { requiredCelo, requiredDays }
 }
+
+// TODO this will have to be refactored not to use BigNumber
+// once we drop its usage
+function bigintToExponential(value: bigint) {
+  // as per the check in `toStringValueMapRecursive`
+  if (value <= 1000n) {
path: packages/cli/src/utils/cli.ts
user: login: aaronmgdr
body: from what i see its only called if the value is 1000 anyway
created_at: 2025-03-27T11:16:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -23,15 +25,27 @@ export default class Balance extends BaseCommand {
   ]
 
   async run() {
-    const kit = await this.getKit()
+    const client = await this.getPublicClient()
     const { args, flags } = await this.parse(Balance)
 
-    console.log('All balances expressed in units of 10^-18.')
-    printValueMap(await kit.getTotalBalance(args.arg1 as string))
+    console.log('All balances expressed in units of wei.')
+
+    // TODO this typing needs to be handled better...
+    printValueMapRecursive(
+      await getTotalBalance(client as any as PublicClient, args.arg1 as Address)
path: packages/cli/src/commands/account/balance.ts
user: login: nicolasbrugneaux
body: nit: we have now `StrongAddress`, `Address` from celo/base and `Address` from viem, let's stick to celo/base for now no?
created_at: 2025-03-27T12:09:16Z
author_association: CONTRIBUTOR
diff_hunk: @@ -14,3 +14,56 @@ export const signerToAccount = async (
     args: [signer],
   })
 }
+
+export const getTotalBalance = async (
+  client: PublicClient,
+  address: StrongAddress
+): Promise<{
+  lockedCELO: bigint
+  pending: bigint
+  CELO: bigint
+  cUSD: bigint
+  cEUR: bigint
+  cREAL: bigint
+}> => {
+  const lockedCeloAddress = await resolveAddress(client, 'LockedGold')
+
+  return {
path: packages/cli/src/packages-to-be/account.ts
user: login: nicolasbrugneaux
body: and if we don't at least parallelise the calls with Promise.all
created_at: 2025-03-27T12:10:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -187,3 +194,14 @@ export function humanizeRequirements(requirements: LockedGoldRequirements) {
   })
   return { requiredCelo, requiredDays }
 }
+
+// TODO this will have to be refactored not to use BigNumber
+// once we drop its usage
+function bigintToExponential(value: bigint) {
+  // as per the check in `toStringValueMapRecursive`
+  if (value <= 1000n) {
path: packages/cli/src/utils/cli.ts
user: login: shazarre
body: not needed anymore, so I'll remove
created_at: 2025-03-27T14:15:18Z
author_association: CONTRIBUTOR
diff_hunk: @@ -23,15 +25,27 @@ export default class Balance extends BaseCommand {
   ]
 
   async run() {
-    const kit = await this.getKit()
+    const client = await this.getPublicClient()
     const { args, flags } = await this.parse(Balance)
 
-    console.log('All balances expressed in units of 10^-18.')
-    printValueMap(await kit.getTotalBalance(args.arg1 as string))
+    console.log('All balances expressed in units of wei.')
path: packages/cli/src/commands/account/balance.ts
user: login: shazarre
body: decided to leave `console.log`
created_at: 2025-03-28T09:03:59Z
author_association: CONTRIBUTOR

PR comments:
user: login: changeset-bot[bot]
created_at: 2025-03-27T10:52:12Z
body: ###  ⚠️  No Changeset found

Latest commit: f1cffd9ed8ef92980dfea1653cace4ad1fa30bc4

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. **If these changes should result in a version bump, you need to add a changeset.**

<details><summary>This PR includes no changesets</summary>

  When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

</details>

[Click here to learn what changesets are, and how to add one](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add a changeset to this PR](https://github.com/celo-org/developer-tooling/new/shazarre/Migrate_account_balance_to_viem?filename=.changeset/sharp-emus-decide.md&value=---%0A%22%40celo%2Fcelocli%22%3A%20patch%0A---%0A%0AMigrate%20account%3Abalance%20to%20viem%0A)


author_association: NONE
user: login: codecov[bot]
created_at: 2025-03-27T10:58:48Z
body: ## [Codecov](https://app.codecov.io/gh/celo-org/developer-tooling/pull/578?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=celo-org) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 77.44%. Comparing base [(`9fef7c4`)](https://app.codecov.io/gh/celo-org/developer-tooling/commit/9fef7c4f8861f699d8ce172b4275901320d3090c?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=celo-org) to head [(`f1cffd9`)](https://app.codecov.io/gh/celo-org/developer-tooling/commit/f1cffd9ed8ef92980dfea1653cace4ad1fa30bc4?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=celo-org).
> Report is 1 commits behind head on shazarre/Migrate_CheckBuilder_to_viem.

<details><summary>Additional details and impacted files</summary>


```diff
@@                            Coverage Diff                            @@
##           shazarre/Migrate_CheckBuilder_to_viem     #578      +/-   ##
=========================================================================
+ Coverage                                  77.39%   77.44%   +0.04%     
=========================================================================
  Files                                        255      256       +1     
  Lines                                      10867    10887      +20     
  Branches                                    1720     1732      +12     
=========================================================================
+ Hits                                        8411     8431      +20     
+ Misses                                      2361     2355       -6     
- Partials                                      95      101       +6     
```

| [Components](https://app.codecov.io/gh/celo-org/developer-tooling/pull/578/components?src=pr&el=components&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=celo-org) | Coverage Δ | |
|---|---|---|
| [celocli](https://app.codecov.io/gh/celo-org/developer-tooling/pull/578/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=celo-org) | `87.72% <100.00%> (+0.05%)` | :arrow_up: |
| [sdk](https://app.codecov.io/gh/celo-org/developer-tooling/pull/578/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=celo-org) | `69.54% <ø> (ø)` | |
| [wallets](https://app.codecov.io/gh/celo-org/developer-tooling/pull/578/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=celo-org) | `74.36% <ø> (ø)` | |
| [viem-sdks](https://app.codecov.io/gh/celo-org/developer-tooling/pull/578/components?src=pr&el=component&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=celo-org) | `93.01% <ø> (ø)` | |

</details>
<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
- :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
author_association: NONE