diff --git a/modules/sdk-coin-vet/src/lib/utils.ts b/modules/sdk-coin-vet/src/lib/utils.ts index 448961d795..8b797cff69 100644 --- a/modules/sdk-coin-vet/src/lib/utils.ts +++ b/modules/sdk-coin-vet/src/lib/utils.ts @@ -461,6 +461,14 @@ export class Utils implements BaseUtils { validateStakingContractAddress(address: string, coinConfig: Readonly): void { const expectedAddress = this.getDefaultStakingAddress(coinConfig); if (address.toLowerCase() !== expectedAddress.toLowerCase()) { + const validatorRegistrationAddress = this.getContractAddressForValidatorRegistration(coinConfig); + if (address.toLowerCase() === validatorRegistrationAddress.toLowerCase()) { + throw new Error( + 'Delegation is not supported for wallets with an active validator registration. ' + + 'A wallet can either delegate or register as a validator, but not both. ' + + 'Please use a wallet without an existing validator registration to perform delegation.' + ); + } throw new Error( `Invalid staking contract address. Expected ${expectedAddress} for ${coinConfig.network.type}, got ${address}` ); @@ -476,6 +484,14 @@ export class Utils implements BaseUtils { validateContractAddressForValidatorRegistration(address: string, coinConfig: Readonly): void { const expectedAddress = this.getContractAddressForValidatorRegistration(coinConfig); if (address.toLowerCase() !== expectedAddress.toLowerCase()) { + const stakingContractAddress = this.getDefaultStakingAddress(coinConfig); + if (address.toLowerCase() === stakingContractAddress.toLowerCase()) { + throw new Error( + 'Validator registration is not supported for wallets with an active delegation. ' + + 'A wallet can either register as a validator or delegate, but not both. ' + + 'Please use a wallet without an existing delegation to perform validator registration.' + ); + } throw new Error( `Invalid contract address for validator registration. Expected ${expectedAddress} for ${coinConfig.network.type}, got ${address}` ); diff --git a/modules/sdk-coin-vet/test/transactionBuilder/delegateClauseTxnBuilder.ts b/modules/sdk-coin-vet/test/transactionBuilder/delegateClauseTxnBuilder.ts index 7d46aecfd1..0063f6b10e 100644 --- a/modules/sdk-coin-vet/test/transactionBuilder/delegateClauseTxnBuilder.ts +++ b/modules/sdk-coin-vet/test/transactionBuilder/delegateClauseTxnBuilder.ts @@ -1,7 +1,11 @@ import { coins } from '@bitgo/statics'; import { TransactionBuilderFactory, Transaction, DelegateClauseTransaction } from '../../src/lib'; import should from 'should'; -import { DELEGATE_CLAUSE_METHOD_ID, STARGATE_CONTRACT_ADDRESS_TESTNET } from '../../src/lib/constants'; +import { + DELEGATE_CLAUSE_METHOD_ID, + STARGATE_CONTRACT_ADDRESS_TESTNET, + VALIDATOR_REGISTRATION_STAKER_CONTRACT_ADDRESS_TESTNET, +} from '../../src/lib/constants'; import EthereumAbi from 'ethereumjs-abi'; import * as testData from '../resources/vet'; import { BN } from 'ethereumjs-util'; @@ -107,6 +111,21 @@ describe('VET Delegation Transaction', function () { }).throw(/Invalid address/); }); + it('should throw descriptive error when validator registration contract is used for delegation', async function () { + const txBuilder = createBasicTxBuilder(); + txBuilder.stakingContractAddress(VALIDATOR_REGISTRATION_STAKER_CONTRACT_ADDRESS_TESTNET); + txBuilder.tokenId(tokenId); + txBuilder.validator(validatorAddress); + + await txBuilder + .build() + .should.be.rejectedWith( + 'Delegation is not supported for wallets with an active validator registration. ' + + 'A wallet can either delegate or register as a validator, but not both. ' + + 'Please use a wallet without an existing validator registration to perform delegation.' + ); + }); + it('should build transaction with undefined sender but include it in inputs', async function () { const txBuilder = factory.getStakingDelegateBuilder(); txBuilder.stakingContractAddress(STARGATE_CONTRACT_ADDRESS_TESTNET); diff --git a/modules/sdk-coin-vet/test/transactionBuilder/validatorRegistrationTxnBuilder.ts b/modules/sdk-coin-vet/test/transactionBuilder/validatorRegistrationTxnBuilder.ts index e1789fc0ef..e0147b3554 100644 --- a/modules/sdk-coin-vet/test/transactionBuilder/validatorRegistrationTxnBuilder.ts +++ b/modules/sdk-coin-vet/test/transactionBuilder/validatorRegistrationTxnBuilder.ts @@ -3,6 +3,7 @@ import { TransactionBuilderFactory, Transaction, ValidatorRegistrationTransactio import should from 'should'; import { ADD_VALIDATION_METHOD_ID, + STARGATE_CONTRACT_ADDRESS_TESTNET, VALIDATOR_REGISTRATION_STAKER_CONTRACT_ADDRESS_TESTNET, } from '../../src/lib/constants'; import EthereumAbi from 'ethereumjs-abi'; @@ -156,6 +157,22 @@ describe('VET Validator Registration Transaction', function () { }).throw(/Invalid address/); }); + it('should throw descriptive error when delegation contract is used for validator registration', async function () { + const txBuilder = createBasicTxBuilder(); + txBuilder.stakingContractAddress(STARGATE_CONTRACT_ADDRESS_TESTNET); + txBuilder.stakingPeriod(stakingPeriod); + txBuilder.validator(validatorAddress); + txBuilder.amountToStake(amountToStake); + + await txBuilder + .build() + .should.be.rejectedWith( + 'Validator registration is not supported for wallets with an active delegation. ' + + 'A wallet can either register as a validator or delegate, but not both. ' + + 'Please use a wallet without an existing delegation to perform validator registration.' + ); + }); + it('should build transaction with undefined sender but include it in inputs', async function () { const txBuilder = factory.getValidatorRegistrationBuilder(); txBuilder.stakingContractAddress(VALIDATOR_REGISTRATION_STAKER_CONTRACT_ADDRESS_TESTNET);