diff --git a/.changeset/early-geckos-rescue.md b/.changeset/early-geckos-rescue.md new file mode 100644 index 000000000..f631ce993 --- /dev/null +++ b/.changeset/early-geckos-rescue.md @@ -0,0 +1,5 @@ +--- +'@celo/celocli': minor +--- + +feat: Running celocli lockedgold:lock will now automatically register the eoa as an account if needed before locking diff --git a/packages/cli/src/commands/lockedgold/lock.test.ts b/packages/cli/src/commands/lockedgold/lock.test.ts index 4c3b5c6a2..7e0ca1018 100644 --- a/packages/cli/src/commands/lockedgold/lock.test.ts +++ b/packages/cli/src/commands/lockedgold/lock.test.ts @@ -1,7 +1,13 @@ import { newKitFromWeb3 } from '@celo/contractkit' import { testWithGanache } from '@celo/dev-utils/lib/ganache-test' +import { ux } from '@oclif/core' +import BigNumber from 'bignumber.js' import Web3 from 'web3' -import { LONG_TIMEOUT_MS, testLocally } from '../../test-utils/cliUtils' +import { + LONG_TIMEOUT_MS, + stripAnsiCodesFromNestedArray, + testLocally, +} from '../../test-utils/cliUtils' import Register from '../account/register' import Lock from './lock' import Unlock from './unlock' @@ -27,4 +33,72 @@ testWithGanache('lockedgold:lock cmd', (web3: Web3) => { }, LONG_TIMEOUT_MS ) + describe('when EOA is not yet an account', () => { + it('performs the registration and locks the value', async () => { + const eoaAddresses = await web3.eth.getAccounts() + const eoa = eoaAddresses[1] + const kit = newKitFromWeb3(web3) + const accountsContract = await kit.contracts.getAccounts() + const lockedGoldContract = await kit.contracts.getLockedGold() + + const logSpy = jest.spyOn(console, 'log') + const actionSpy = jest.spyOn(ux.action, 'stop') + + // pre check + expect(await accountsContract.isAccount(eoa)).toBe(false) + + await testLocally(Lock, ['--from', eoa, '--value', '100']) + + expect(stripAnsiCodesFromNestedArray(logSpy.mock.calls)).toMatchInlineSnapshot(` + [ + [ + "Running Checks:", + ], + [ + " ✔ Value [100] is > 0 ", + ], + [ + "All checks passed", + ], + [ + "Address will be registered with Account contract to enable locking.", + ], + [ + "SendTransaction: register", + ], + [ + "txHash: 0x9322aba7cf28f466f1377b1da9a1e7ed94c3109aa5fd2f4ea23caab371f1cb0f", + ], + [ + "Running Checks:", + ], + [ + " ✔ Account has at least 0.0000000000000001 CELO ", + ], + [ + "All checks passed", + ], + [ + "SendTransaction: lock", + ], + [ + "txHash: 0x947e5f8c97fdfabf688b3879f5856e1165c3578f2741d2481c3c961aa83bba51", + ], + ] + `) + + expect(actionSpy.mock.calls).toMatchInlineSnapshot(` + [ + [], + [], + ] + `) + + expect(await accountsContract.isAccount(eoa)).toBe(true) + + expect(await lockedGoldContract.getAccountTotalLockedGold(eoa)).toEqBigNumber( + new BigNumber('100') + ) + }) + }) }) diff --git a/packages/cli/src/commands/lockedgold/lock.ts b/packages/cli/src/commands/lockedgold/lock.ts index bc6102db3..f4b6f9a0d 100644 --- a/packages/cli/src/commands/lockedgold/lock.ts +++ b/packages/cli/src/commands/lockedgold/lock.ts @@ -32,10 +32,20 @@ export default class Lock extends BaseCommand { await newCheckBuilder(this) .addCheck(`Value [${value.toFixed()}] is > 0`, () => value.gt(0)) - .isAccount(address) .runChecks() - const lockedGold = await kit.contracts.getLockedGold() + const [lockedGold, accountsContract] = await Promise.all([ + kit.contracts.getLockedGold(), + kit.contracts.getAccounts(), + ]) + + const isAccount = await accountsContract.isAccount(address) + + if (!isAccount) { + console.log('Address will be registered with Account contract to enable locking.') + await displaySendTx('register', accountsContract.createAccount()) + } + const pendingWithdrawalsValue = await lockedGold.getPendingWithdrawalsTotalValue(address) const relockValue = BigNumber.minimum(pendingWithdrawalsValue, value) const lockValue = value.minus(relockValue)