From c57dd55b035eabe3b961fc997ccbec3d0d18cfc4 Mon Sep 17 00:00:00 2001 From: Vijay Jagannathan Date: Wed, 24 Dec 2025 21:13:01 +0530 Subject: [PATCH 1/2] fix(sdk-coin-vet): invalid id for vet validation regn txn Ticket: SC-4409 --- .../src/lib/transaction/transaction.ts | 3 +- modules/sdk-coin-vet/test/resources/vet.ts | 1 + .../sdk-coin-vet/test/unit/stakingFlowE2E.ts | 83 ++++++++++++++++++- 3 files changed, 85 insertions(+), 2 deletions(-) diff --git a/modules/sdk-coin-vet/src/lib/transaction/transaction.ts b/modules/sdk-coin-vet/src/lib/transaction/transaction.ts index 962438ca85..b6d56e0600 100644 --- a/modules/sdk-coin-vet/src/lib/transaction/transaction.ts +++ b/modules/sdk-coin-vet/src/lib/transaction/transaction.ts @@ -393,7 +393,8 @@ export class Transaction extends BaseTransaction { this.type === TransactionType.StakingDelegate || this.type === TransactionType.StakingUnlock || this.type === TransactionType.StakingWithdraw || - this.type === TransactionType.StakingClaim + this.type === TransactionType.StakingClaim || + this.type === TransactionType.StakingLock ) { transactionBody.reserved = { features: 1, // mark transaction as delegated i.e. will use gas payer diff --git a/modules/sdk-coin-vet/test/resources/vet.ts b/modules/sdk-coin-vet/test/resources/vet.ts index bff3738c73..1c1e6c4ec9 100644 --- a/modules/sdk-coin-vet/test/resources/vet.ts +++ b/modules/sdk-coin-vet/test/resources/vet.ts @@ -35,6 +35,7 @@ export const CLAIM_REWARDS_TRANSACTION = export const STAKING_LEVEL_ID = 8; export const STAKING_AUTORENEW = true; export const STAKING_CONTRACT_ADDRESS = '0x1e02b2953adefec225cf0ec49805b1146a4429c1'; +export const BUILT_IN_STAKER_CONTRACT_ADDRESS = '0x00000000000000000000000000005374616b6572'; export const VALID_TOKEN_SIGNABLE_PAYLOAD = 'f8762788014ead140e77bbc140f85ef85c940000000000000000000000000000456e6572677980b844a9059cbb000000000000000000000000e59f1cea4e0fef511e3d0f4eec44adf19c4cbeec000000000000000000000000000000000000000000000000016345785d8a000081808252088082faf8c101'; diff --git a/modules/sdk-coin-vet/test/unit/stakingFlowE2E.ts b/modules/sdk-coin-vet/test/unit/stakingFlowE2E.ts index ce6c00784c..2f25a349f4 100644 --- a/modules/sdk-coin-vet/test/unit/stakingFlowE2E.ts +++ b/modules/sdk-coin-vet/test/unit/stakingFlowE2E.ts @@ -1,7 +1,7 @@ import should from 'should'; import { coins } from '@bitgo/statics'; import { TransactionType } from '@bitgo/sdk-core'; -import { TransactionBuilderFactory, StakeClauseTransaction } from '../../src/lib'; +import { TransactionBuilderFactory, StakeClauseTransaction, ValidatorRegistrationTransaction } from '../../src/lib'; import * as testData from '../resources/vet'; describe('VET Staking Flow - End-to-End Test', function () { @@ -10,7 +10,10 @@ describe('VET Staking Flow - End-to-End Test', function () { // Test data const stakingContractAddress = testData.STAKING_CONTRACT_ADDRESS; + const builtInStakerContractAddress = testData.BUILT_IN_STAKER_CONTRACT_ADDRESS; const amountToStake = '1000000000000000000'; // 1 VET in wei + const stakingPeriod = 60480; + const validatorAddress = '0x9a7afcacc88c106f3bbd6b213cd0821d9224d945'; const levelId = testData.STAKING_LEVEL_ID; const senderAddress = '0x9378c12BD7502A11F770a5C1F223c959B2805dA9'; const feePayerAddress = '0xdc9fef0b84a0ccf3f1bd4b84e41743e3e051a083'; @@ -99,6 +102,84 @@ describe('VET Staking Flow - End-to-End Test', function () { jsonOutput.should.have.property('levelId', levelId); }); + it('should build, sign, and serialize a complete validator registration transaction with fee delegation', async function () { + // Step 1: Build the staking transaction + const validatorRegistrationBuilder = factory.getValidatorRegistrationBuilder(); + + validatorRegistrationBuilder + .stakingContractAddress(builtInStakerContractAddress) + .stakingPeriod(60480) + .validator(validatorAddress) + .sender(senderAddress) + .chainTag(0x27) // Testnet chain tag + .blockRef('0x014ead140e77bbc1') + .expiration(64) + .gas(100000) + .gasPriceCoef(128) + .nonce('12345'); + + validatorRegistrationBuilder.addFeePayerAddress(feePayerAddress); + + const unsignedTx = await validatorRegistrationBuilder.build(); + should.exist(unsignedTx); + unsignedTx.should.be.instanceof(ValidatorRegistrationTransaction); + + const validatorRegistrationTx = unsignedTx as ValidatorRegistrationTransaction; + + // Verify transaction structure + validatorRegistrationTx.type.should.equal(TransactionType.StakingLock); + validatorRegistrationTx.stakingContractAddress.should.equal(builtInStakerContractAddress); + validatorRegistrationTx.stakingPeriod.should.equal(stakingPeriod); + validatorRegistrationTx.validator.should.equal(validatorAddress); + + should.exist(validatorRegistrationTx.rawTransaction); + should.exist(validatorRegistrationTx.rawTransaction.body); + + // This is the critical test - ensure reserved.features = 1 + should.exist(validatorRegistrationTx.rawTransaction.body.reserved); + validatorRegistrationTx.rawTransaction.body.reserved!.should.have.property('features', 1); + + // Step 3: Add sender signature + validatorRegistrationTx.addSenderSignature(mockSenderSignature); + should.exist(validatorRegistrationTx.senderSignature); + Buffer.from(validatorRegistrationTx.senderSignature!).should.eql(mockSenderSignature); + + // Step 4: Add fee payer signature + validatorRegistrationTx.addFeePayerSignature(mockFeePayerSignature); + should.exist(validatorRegistrationTx.feePayerSignature); + Buffer.from(validatorRegistrationTx.feePayerSignature!).should.eql(mockFeePayerSignature); + + // Step 5: Generate transaction ID + + // This should NOT throw "not signed transaction: id unavailable" error anymore + const transactionId = validatorRegistrationTx.id; + should.exist(transactionId); + transactionId.should.not.equal('UNAVAILABLE'); + + // Step 6: Serialize the fully signed transaction + const serializedTx = validatorRegistrationTx.toBroadcastFormat(); + should.exist(serializedTx); + serializedTx.should.be.type('string'); + serializedTx.should.startWith('0x'); + + // Step 7: Verify transaction can be deserialized + const deserializedBuilder = factory.from(serializedTx); + const deserializedTx = deserializedBuilder.transaction as ValidatorRegistrationTransaction; + + deserializedTx.should.be.instanceof(ValidatorRegistrationTransaction); + deserializedTx.stakingContractAddress.should.equal(builtInStakerContractAddress); + deserializedTx.stakingPeriod.should.equal(stakingPeriod); + deserializedTx.validator.should.equal(validatorAddress); + + // Step 8: Verify toJson output + const jsonOutput = validatorRegistrationTx.toJson(); + should.exist(jsonOutput); + jsonOutput.should.have.property('id', transactionId); + jsonOutput.should.have.property('stakingContractAddress', builtInStakerContractAddress); + jsonOutput.should.have.property('stakingPeriod', stakingPeriod); + jsonOutput.should.have.property('validatorAddress', validatorAddress); + }); + it('should handle signature combination in the correct order', async function () { // This test specifically validates the signature combination flow that was failing const stakingBuilder = factory.getStakingActivateBuilder(); From 93ff3b5170a322d334f5ad05253f28463c00c75c Mon Sep 17 00:00:00 2001 From: Vijay Jagannathan Date: Thu, 25 Dec 2025 11:20:48 +0530 Subject: [PATCH 2/2] fix(sdk-coin-vet): add stake amount in the validator registration txn Ticket: SC-4409 --- .../validatorRegistrationTransaction.ts | 22 +++++++--- .../validatorRegistrationBuilder.ts | 21 +++++++++- modules/sdk-coin-vet/test/resources/vet.ts | 3 +- .../validatorRegistrationTxnBuilder.ts | 42 +++++++++++++++++++ .../sdk-coin-vet/test/unit/stakingFlowE2E.ts | 5 +++ 5 files changed, 86 insertions(+), 7 deletions(-) diff --git a/modules/sdk-coin-vet/src/lib/transaction/validatorRegistrationTransaction.ts b/modules/sdk-coin-vet/src/lib/transaction/validatorRegistrationTransaction.ts index 858d26fcdc..4e7497a459 100644 --- a/modules/sdk-coin-vet/src/lib/transaction/validatorRegistrationTransaction.ts +++ b/modules/sdk-coin-vet/src/lib/transaction/validatorRegistrationTransaction.ts @@ -7,12 +7,12 @@ import EthereumAbi from 'ethereumjs-abi'; import utils from '../utils'; import BigNumber from 'bignumber.js'; import { addHexPrefix, BN } from 'ethereumjs-util'; -import { ZERO_VALUE_AMOUNT } from '../constants'; export class ValidatorRegistrationTransaction extends Transaction { private _stakingContractAddress: string; private _validator: string; private _stakingPeriod: number; + private _amountToStake: string; constructor(_coinConfig: Readonly) { super(_coinConfig); @@ -35,6 +35,14 @@ export class ValidatorRegistrationTransaction extends Transaction { this._stakingPeriod = period; } + get amountToStake(): string { + return this._amountToStake; + } + + set amountToStake(amount: string) { + this._amountToStake = amount; + } + get stakingContractAddress(): string { return this._stakingContractAddress; } @@ -63,7 +71,7 @@ export class ValidatorRegistrationTransaction extends Transaction { this._clauses = [ { to: this.stakingContractAddress, - value: ZERO_VALUE_AMOUNT, + value: this.amountToStake, data: addValidationData, }, ]; @@ -72,7 +80,7 @@ export class ValidatorRegistrationTransaction extends Transaction { this._recipients = [ { address: this.stakingContractAddress, - amount: ZERO_VALUE_AMOUNT, + amount: this.amountToStake, }, ]; } @@ -107,11 +115,11 @@ locking their VET into the built-in staker contract. Allowed values are 60480 (7 dependsOn: this.dependsOn, nonce: this.nonce, data: this.transactionData, - value: ZERO_VALUE_AMOUNT, + value: this.amountToStake, sender: this.sender, to: this.stakingContractAddress, stakingContractAddress: this.stakingContractAddress, - amountToStake: ZERO_VALUE_AMOUNT, + amountToStake: this.amountToStake, validatorAddress: this.validator, stakingPeriod: this.stakingPeriod, }; @@ -147,6 +155,10 @@ locking their VET into the built-in staker contract. Allowed values are 60480 (7 this.stakingContractAddress = addValidationClause.to; } + if (addValidationClause.value) { + this.amountToStake = new BigNumber(addValidationClause.value).toFixed(); + } + // Extract validator and period from addValidation data if (addValidationClause.data) { this.transactionData = addValidationClause.data; diff --git a/modules/sdk-coin-vet/src/lib/transactionBuilder/validatorRegistrationBuilder.ts b/modules/sdk-coin-vet/src/lib/transactionBuilder/validatorRegistrationBuilder.ts index 30dee610d6..4d41571f66 100644 --- a/modules/sdk-coin-vet/src/lib/transactionBuilder/validatorRegistrationBuilder.ts +++ b/modules/sdk-coin-vet/src/lib/transactionBuilder/validatorRegistrationBuilder.ts @@ -2,6 +2,7 @@ import assert from 'assert'; import { BaseCoin as CoinConfig } from '@bitgo/statics'; import { TransactionType } from '@bitgo/sdk-core'; import { TransactionClause } from '@vechain/sdk-core'; +import BigNumber from 'bignumber.js'; import { TransactionBuilder } from './transactionBuilder'; import { Transaction } from '../transaction/transaction'; @@ -96,6 +97,17 @@ export class ValidatorRegistrationBuilder extends TransactionBuilder { return this; } + /** + * Sets the amount to stake for this validator registration tx (VET amount being sent). + * + * @param {string} amount - The amount to stake in wei + * @returns {ValidatorRegistrationBuilder} This transaction builder + */ + amountToStake(amount: string): this { + this.validatorRegistrationTransaction.amountToStake = amount; + return this; + } + /** * Sets the validator address for this validator registration tx. * @param {string} address - The validator address @@ -127,9 +139,16 @@ export class ValidatorRegistrationBuilder extends TransactionBuilder { throw new Error('transaction not defined'); } assert(transaction.stakingContractAddress, 'Staking contract address is required'); - assert(transaction.stakingPeriod, 'Staking period is required'); assert(transaction.validator, 'Validator address is required'); + assert(transaction.amountToStake, 'Staking amount is required'); + + // Validate staking amount is within allowed range + const amountInVET = new BigNumber(transaction.amountToStake).dividedBy(new BigNumber(10).pow(18)); + if (amountInVET.isLessThan(25_000_000) || amountInVET.isGreaterThan(600_000_000)) { + throw new Error('Staking amount must be between 25M and 600M VET'); + } + this.validateAddress({ address: transaction.stakingContractAddress }); } diff --git a/modules/sdk-coin-vet/test/resources/vet.ts b/modules/sdk-coin-vet/test/resources/vet.ts index 1c1e6c4ec9..f3c0554be6 100644 --- a/modules/sdk-coin-vet/test/resources/vet.ts +++ b/modules/sdk-coin-vet/test/resources/vet.ts @@ -21,7 +21,7 @@ export const DELEGATION_TRANSACTION = '0xf9010327880166f0952a071e2a820190f85ef85c941e02b2953adefec225cf0ec49805b1146a4429c180b84408bbb8240000000000000000000000000000000000000000000000000000000000003d4500000000000000000000000000000021cbe0de65ea10f7658effeea70727154a81808303b46c8088f341b4c6b5ff5294c101b8829f5d674b8b043e95907b544b16a2c399bc04c7ebfcb9fa49956e050c59bbd5a510c57c6c135a3f03b12fe388409216809124a06d3c4ce797b5d97c5cd899d73d01dc4b66e63aade59b67639e44caedd5783a8e4d4f3c224f911acc5f43c387b54d22b2332172363a48e186d3bd52abec67d84e3d9e8c9696b241d29810a4e14e5801'; export const VALIDATOR_REGISTRATION_TRANSACTION = - '0xf8fb2788016754d8d0e8099340f85ef85c9400000000000000000000000000005374616b657280b844c3c4b13800000000000000000000000059b67d37be55997c96ea6f1890f08f825a41203c000000000000000000000000000000000000000000000000000000000000ec40818082b4ae808301bc4ec101b882ad3cef39b277cdb926f50ac04cbf11a68cf4a30b13311605978d57d92e92ee171a8bb734676cad0f7cdcdd935cf78b71b02e2193390ab752b032a6219131bf230119acb7f53ca1cf868a05f5c7b841e7052c8d779f876e6a6a6e5aa3daf0cd82dc6842d5fa276d4abc950b686e3d685261cae290dd20a13223a832e1b88be9ff0500'; + '0xf90106278801690812847d899f40f869f8679400000000000000000000000000005374616b65728b14adf4b7320334b9000000b844c3c4b13800000000000000000000000059b67d37be55997c96ea6f1890f08f825a41203c000000000000000000000000000000000000000000000000000000000000ec408180826b84808303576bc101b8825600996530a8204d10944b52b933e1ce57744793eaaa93922d6b6cfbf53759ce6bd8c55bdafd06ef8c30b9549747008c5d4caad226d712710825d88271164acf00b6519806de49deacbf8079c8fd8698216289946988ea6c1bf86cf73740e1a8b620c75392c2d8cb5b9e608301303435d7174e70f627e37cd59d94644e35468cca01'; export const EXIT_DELEGATION_TRANSACTION = '0xf8db278801640bf461bc7e1840f83df83b941e02b2953adefec225cf0ec49805b1146a4429c180a469e79b7d0000000000000000000000000000000000000000000000000000000000003d2d81808303525f808305f65ac101b8820cb393317793011b0a205973c77761f5c5c8652c21fe0115f527d2e2f2c1b5fc72a048107b263764312e9323f2ace9f30ce0beed873d7ef7f5432943330d2d5000a4a5f6439503f235ac6a5e17b47ac26c9e0c9e3be9dbd4cec3266fea324eb9bf5f806cedca59ff4144deb0ca18c41d9d6d600a86bf3d4e7b930bcec9b04c2e7301'; @@ -228,6 +228,7 @@ export const DELEGATE_TOKEN_ID = '15685'; export const STAKING_PERIOD = 259200; export const DELEGATE_VALIDATOR = '0xae99cb89767a09d53e589a40cb4016974aba4b94'; export const VALIDATOR_REGISTRATION_VALIDATOR = '0x59b67d37be55997c96ea6f1890f08f825a41203c'; +export const VALIDATOR_REGISTRATION_AMOUNT = '25000000000000000000000000'; export const SIGNED_DELEGATE_RAW_HEX = '0xf8fa278801671187de8af70440f85ef85c941e02b2953adefec225cf0ec49805b1146a4429c180b84408bbb8240000000000000000000000000000000000000000000000000000000000003d2d00000000000000000000000000563ec3cafbbe7e60b04b3190e6eca66579706d818082cb5680820190c101b882313e783169eae670b1210e65f59b7c30cfd6c140c377257413fef378f70549f738a22a172ccc4ac7854ebc9952845fa90f7a676e5e9d9e277724ef3968e32e8a00f05ddf913b2b8fb884dbd5d5133217666ec4a68d077dce1537d270f25caf440e0f11232ecc4a5859ab49b2442cc0b0c0c1488302556e6323eec0498f1a42e17301'; diff --git a/modules/sdk-coin-vet/test/transactionBuilder/validatorRegistrationTxnBuilder.ts b/modules/sdk-coin-vet/test/transactionBuilder/validatorRegistrationTxnBuilder.ts index 786bd9bbfb..e1789fc0ef 100644 --- a/modules/sdk-coin-vet/test/transactionBuilder/validatorRegistrationTxnBuilder.ts +++ b/modules/sdk-coin-vet/test/transactionBuilder/validatorRegistrationTxnBuilder.ts @@ -14,6 +14,9 @@ describe('VET Validator Registration Transaction', function () { const factory = new TransactionBuilderFactory(coins.get('tvet')); const stakingPeriod = 60480; const validatorAddress = '0x9a7aFCACc88c106f3bbD6B213CD0821D9224d945'; + const amountToStake = '25000000000000000000000000'; // 25000000 VET + const amountLessThanMinStake = '24000000000000000000000000'; // 24000000 VET + const amountGreaterThanMaxStake = '650000000000000000000000000'; // 650000000 VET // Helper function to create a basic transaction builder with common properties const createBasicTxBuilder = () => { @@ -32,6 +35,7 @@ describe('VET Validator Registration Transaction', function () { const txBuilder = factory.getValidatorRegistrationBuilder(); txBuilder.stakingContractAddress(VALIDATOR_REGISTRATION_STAKER_CONTRACT_ADDRESS_TESTNET); txBuilder.stakingPeriod(stakingPeriod); + txBuilder.amountToStake(amountToStake); txBuilder.sender('0x9378c12BD7502A11F770a5C1F223c959B2805dA9'); txBuilder.chainTag(0x27); // Testnet chain tag txBuilder.blockRef('0x0000000000000000'); @@ -52,13 +56,16 @@ describe('VET Validator Registration Transaction', function () { ); validatorRegistrationTransaction.stakingPeriod.should.equal(stakingPeriod); validatorRegistrationTransaction.validator.should.equal(validatorAddress); + validatorRegistrationTransaction.amountToStake.should.equal(amountToStake); // Verify clauses validatorRegistrationTransaction.clauses.length.should.equal(1); should.exist(validatorRegistrationTransaction.clauses[0].to); + should.exist(validatorRegistrationTransaction.clauses[0].value); validatorRegistrationTransaction.clauses[0].to?.should.equal( VALIDATOR_REGISTRATION_STAKER_CONTRACT_ADDRESS_TESTNET ); + validatorRegistrationTransaction.clauses[0].value?.should.equal(amountToStake); // Verify transaction data is correctly encoded using ethereumABI should.exist(validatorRegistrationTransaction.clauses[0].data); @@ -88,6 +95,7 @@ describe('VET Validator Registration Transaction', function () { const txBuilder = createBasicTxBuilder(); txBuilder.stakingPeriod(stakingPeriod); txBuilder.validator(validatorAddress); + txBuilder.amountToStake(amountToStake); await txBuilder.build().should.be.rejectedWith('Staking contract address is required'); }); @@ -96,6 +104,7 @@ describe('VET Validator Registration Transaction', function () { const txBuilder = createBasicTxBuilder(); txBuilder.stakingContractAddress(VALIDATOR_REGISTRATION_STAKER_CONTRACT_ADDRESS_TESTNET); txBuilder.validator(validatorAddress); + txBuilder.amountToStake(amountToStake); await txBuilder.build().should.be.rejectedWith('Staking period is required'); }); @@ -104,10 +113,40 @@ describe('VET Validator Registration Transaction', function () { const txBuilder = createBasicTxBuilder(); txBuilder.stakingContractAddress(VALIDATOR_REGISTRATION_STAKER_CONTRACT_ADDRESS_TESTNET); txBuilder.stakingPeriod(stakingPeriod); + txBuilder.amountToStake(amountToStake); await txBuilder.build().should.be.rejectedWith('Validator address is required'); }); + it('should throw error when amount is missing', async function () { + const txBuilder = createBasicTxBuilder(); + txBuilder.stakingContractAddress(VALIDATOR_REGISTRATION_STAKER_CONTRACT_ADDRESS_TESTNET); + txBuilder.stakingPeriod(stakingPeriod); + txBuilder.validator(validatorAddress); + + await txBuilder.build().should.be.rejectedWith('Staking amount is required'); + }); + + it('should throw error when amount is less than minimum stake', async function () { + const txBuilder = createBasicTxBuilder(); + txBuilder.stakingContractAddress(VALIDATOR_REGISTRATION_STAKER_CONTRACT_ADDRESS_TESTNET); + txBuilder.stakingPeriod(stakingPeriod); + txBuilder.validator(validatorAddress); + txBuilder.amountToStake(amountLessThanMinStake); + + await txBuilder.build().should.be.rejectedWith('Staking amount must be between 25M and 600M VET'); + }); + + it('should throw error when amount is greater than maximum stake', async function () { + const txBuilder = createBasicTxBuilder(); + txBuilder.stakingContractAddress(VALIDATOR_REGISTRATION_STAKER_CONTRACT_ADDRESS_TESTNET); + txBuilder.stakingPeriod(stakingPeriod); + txBuilder.validator(validatorAddress); + txBuilder.amountToStake(amountGreaterThanMaxStake); + + await txBuilder.build().should.be.rejectedWith('Staking amount must be between 25M and 600M VET'); + }); + it('should throw error when stakingContractAddress is invalid', async function () { const txBuilder = createBasicTxBuilder(); @@ -121,6 +160,7 @@ describe('VET Validator Registration Transaction', function () { const txBuilder = factory.getValidatorRegistrationBuilder(); txBuilder.stakingContractAddress(VALIDATOR_REGISTRATION_STAKER_CONTRACT_ADDRESS_TESTNET); txBuilder.stakingPeriod(stakingPeriod); + txBuilder.amountToStake(amountToStake); txBuilder.chainTag(0x27); txBuilder.blockRef('0x0000000000000000'); txBuilder.expiration(64); @@ -151,6 +191,7 @@ describe('VET Validator Registration Transaction', function () { txBuilder.stakingPeriod(stakingPeriod); // Not setting chainTag txBuilder.blockRef('0x0000000000000000'); + txBuilder.amountToStake(amountToStake); txBuilder.expiration(64); txBuilder.gas(100000); txBuilder.gasPriceCoef(0); @@ -184,6 +225,7 @@ describe('VET Validator Registration Transaction', function () { tx.stakingContractAddress.should.equal(testData.VALIDATOR_REGISTRATION_STAKER_CONTRACT); tx.stakingPeriod.should.equal(testData.VALIDATOR_REGISTRATION_STAKING_PERIOD); tx.validator.should.equal(testData.VALIDATOR_REGISTRATION_VALIDATOR); + tx.amountToStake.should.equal(testData.VALIDATOR_REGISTRATION_AMOUNT); tx.validator.should.startWith('0x'); tx.validator.should.equal(tx.validator.toLowerCase()); should.exist(tx.inputs); diff --git a/modules/sdk-coin-vet/test/unit/stakingFlowE2E.ts b/modules/sdk-coin-vet/test/unit/stakingFlowE2E.ts index 2f25a349f4..4add1b3fb9 100644 --- a/modules/sdk-coin-vet/test/unit/stakingFlowE2E.ts +++ b/modules/sdk-coin-vet/test/unit/stakingFlowE2E.ts @@ -12,6 +12,7 @@ describe('VET Staking Flow - End-to-End Test', function () { const stakingContractAddress = testData.STAKING_CONTRACT_ADDRESS; const builtInStakerContractAddress = testData.BUILT_IN_STAKER_CONTRACT_ADDRESS; const amountToStake = '1000000000000000000'; // 1 VET in wei + const amountToStakeForValidatorRegistration = '25000000000000000000000000'; // 25M VET in wei const stakingPeriod = 60480; const validatorAddress = '0x9a7afcacc88c106f3bbd6b213cd0821d9224d945'; const levelId = testData.STAKING_LEVEL_ID; @@ -110,6 +111,7 @@ describe('VET Staking Flow - End-to-End Test', function () { .stakingContractAddress(builtInStakerContractAddress) .stakingPeriod(60480) .validator(validatorAddress) + .amountToStake(amountToStakeForValidatorRegistration) .sender(senderAddress) .chainTag(0x27) // Testnet chain tag .blockRef('0x014ead140e77bbc1') @@ -131,6 +133,7 @@ describe('VET Staking Flow - End-to-End Test', function () { validatorRegistrationTx.stakingContractAddress.should.equal(builtInStakerContractAddress); validatorRegistrationTx.stakingPeriod.should.equal(stakingPeriod); validatorRegistrationTx.validator.should.equal(validatorAddress); + validatorRegistrationTx.amountToStake.should.equal(amountToStakeForValidatorRegistration); should.exist(validatorRegistrationTx.rawTransaction); should.exist(validatorRegistrationTx.rawTransaction.body); @@ -170,6 +173,7 @@ describe('VET Staking Flow - End-to-End Test', function () { deserializedTx.stakingContractAddress.should.equal(builtInStakerContractAddress); deserializedTx.stakingPeriod.should.equal(stakingPeriod); deserializedTx.validator.should.equal(validatorAddress); + deserializedTx.amountToStake.should.equal(amountToStakeForValidatorRegistration); // Step 8: Verify toJson output const jsonOutput = validatorRegistrationTx.toJson(); @@ -178,6 +182,7 @@ describe('VET Staking Flow - End-to-End Test', function () { jsonOutput.should.have.property('stakingContractAddress', builtInStakerContractAddress); jsonOutput.should.have.property('stakingPeriod', stakingPeriod); jsonOutput.should.have.property('validatorAddress', validatorAddress); + jsonOutput.should.have.property('amountToStake', amountToStakeForValidatorRegistration); }); it('should handle signature combination in the correct order', async function () {