Skip to content

Commit 5754ae1

Browse files
fix(sdk-coin-vet): update stake and delegate builders for hayabusa
Ticket: SC-3989
1 parent c82d952 commit 5754ae1

File tree

9 files changed

+90
-55
lines changed

9 files changed

+90
-55
lines changed

modules/sdk-coin-vet/src/lib/constants.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export const ZERO_VALUE_AMOUNT = '0';
66
export const TRANSFER_TOKEN_METHOD_ID = '0xa9059cbb';
77
export const STAKING_METHOD_ID = '0xd8da3bbf';
88
export const STAKE_CLAUSE_METHOD_ID = '0x604f2177';
9-
export const DELEGATE_CLAUSE_METHOD_ID = '0x3207555d';
9+
export const DELEGATE_CLAUSE_METHOD_ID = '0x08bbb824';
1010
export const EXIT_DELEGATION_METHOD_ID = '0x69e79b7d';
1111
export const BURN_NFT_METHOD_ID = '0x2e17de78';
1212
export const TRANSFER_NFT_METHOD_ID = '0x23b872dd';
@@ -17,7 +17,7 @@ export const STARGATE_NFT_ADDRESS = '0x1856c533ac2d94340aaa8544d35a5c1d4a21dee7'
1717
export const STARGATE_DELEGATION_ADDRESS = '0x4cb1c9ef05b529c093371264fab2c93cc6cddb0e';
1818

1919
export const STARGATE_NFT_ADDRESS_TESTNET = '0x1ec1d168574603ec35b9d229843b7c2b44bcb770';
20-
export const STARGATE_DELEGATION_ADDRESS_TESTNET = '0x7240e3bc0d26431512d5b67dbd26d199205bffe8';
20+
export const STARGATE_CONTRACT_ADDRESS_TESTNET = '0x1E02B2953AdEfEC225cF0Ec49805b1146a4429C1';
2121

2222
export const AVG_GAS_UNITS = '21000';
2323
export const EXPIRATION = 400;

modules/sdk-coin-vet/src/lib/iface.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ export interface VetTransactionData {
2828
tokenId?: string; // Added for unstaking and burn NFT transactions
2929
stakingContractAddress?: string;
3030
amountToStake?: string;
31+
levelId?: number; // NFT tier level
3132
nftTokenId?: number; // Used as tier level (levelId) for stakeAndDelegate method (not the actual NFT token ID)
3233
autorenew?: boolean; // Autorenew flag for stakeAndDelegate method
3334
nftCollectionId?: string;
3435
claimRewardsData?: ClaimRewardsData;
36+
validatorAddress?: string;
3537
}
3638

3739
export interface VetTransactionExplanation extends BaseTransactionExplanation {

modules/sdk-coin-vet/src/lib/transaction/delegateClauseTransaction.ts

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,27 @@ import { VetTransactionData } from '../iface';
66
import EthereumAbi from 'ethereumjs-abi';
77
import utils from '../utils';
88
import BigNumber from 'bignumber.js';
9-
import { addHexPrefix } from 'ethereumjs-util';
9+
import { addHexPrefix, BN } from 'ethereumjs-util';
1010
import { ZERO_VALUE_AMOUNT } from '../constants';
1111

1212
export class DelegateClauseTransaction extends Transaction {
1313
private _stakingContractAddress: string;
14-
private _tokenId: number;
15-
private _delegateForever = true;
14+
private _tokenId: string;
15+
private _validator: string;
1616

1717
constructor(_coinConfig: Readonly<CoinConfig>) {
1818
super(_coinConfig);
1919
this._type = TransactionType.StakingDelegate;
2020
}
2121

22+
get validator(): string {
23+
return this._validator;
24+
}
25+
26+
set validator(address: string) {
27+
this._validator = address;
28+
}
29+
2230
get stakingContractAddress(): string {
2331
return this._stakingContractAddress;
2432
}
@@ -27,22 +35,14 @@ export class DelegateClauseTransaction extends Transaction {
2735
this._stakingContractAddress = address;
2836
}
2937

30-
get tokenId(): number {
38+
get tokenId(): string {
3139
return this._tokenId;
3240
}
3341

34-
set tokenId(tokenId: number) {
42+
set tokenId(tokenId: string) {
3543
this._tokenId = tokenId;
3644
}
3745

38-
get delegateForever(): boolean {
39-
return this._delegateForever;
40-
}
41-
42-
set delegateForever(delegateForever: boolean) {
43-
this._delegateForever = delegateForever;
44-
}
45-
4646
buildClauses(): void {
4747
if (!this.stakingContractAddress) {
4848
throw new Error('Staking contract address is not set');
@@ -54,7 +54,11 @@ export class DelegateClauseTransaction extends Transaction {
5454
throw new Error('Token ID is not set');
5555
}
5656

57-
const data = this.getDelegateData(this.tokenId, this.delegateForever);
57+
if (this.validator === undefined || this.validator === null) {
58+
throw new Error('Validator address is not set');
59+
}
60+
61+
const data = this.getDelegateData(this.tokenId, this.validator);
5862
this._transactionData = data;
5963

6064
// Create the clause for delegation
@@ -80,10 +84,10 @@ export class DelegateClauseTransaction extends Transaction {
8084
* @param {number} tokenId - The Token ID for delegation
8185
* @returns {string} - The encoded transaction data
8286
*/
83-
getDelegateData(levelId: number, delegateForever = true): string {
87+
getDelegateData(tokenId: string, validatorAddress: string): string {
8488
const methodName = 'delegate';
85-
const types = ['uint256', 'bool'];
86-
const params = [levelId, delegateForever];
89+
const types = ['uint256', 'address'];
90+
const params = [new BN(tokenId), validatorAddress];
8791

8892
const method = EthereumAbi.methodID(methodName, types);
8993
const args = EthereumAbi.rawEncode(types, params);
@@ -107,8 +111,8 @@ export class DelegateClauseTransaction extends Transaction {
107111
to: this.stakingContractAddress,
108112
stakingContractAddress: this.stakingContractAddress,
109113
amountToStake: ZERO_VALUE_AMOUNT,
110-
nftTokenId: this.tokenId,
111-
autorenew: this.delegateForever,
114+
tokenId: this.tokenId,
115+
validatorAddress: this.validator,
112116
};
113117

114118
return json;
@@ -144,7 +148,7 @@ export class DelegateClauseTransaction extends Transaction {
144148
this.transactionData = clause.data;
145149
const decoded = utils.decodeDelegateClauseData(clause.data);
146150
this.tokenId = decoded.tokenId;
147-
this.delegateForever = decoded.delegateForever;
151+
this.validator = decoded.validator;
148152
}
149153
}
150154

modules/sdk-coin-vet/src/lib/transaction/stakeClauseTransaction.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ export class StakeClauseTransaction extends Transaction {
110110
to: this.stakingContractAddress,
111111
stakingContractAddress: this.stakingContractAddress,
112112
amountToStake: this.amountToStake,
113-
nftTokenId: this.levelId,
113+
levelId: this.levelId,
114114
};
115115

116116
return json;

modules/sdk-coin-vet/src/lib/transactionBuilder/delegateTxnBuilder.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,28 @@ export class DelegateTxnBuilder extends TransactionBuilder {
8888
/**
8989
* Sets the token ID for this delegate tx.
9090
*
91-
* @param {number} levelId - The level ID for staking
91+
* @param {number} levelId - The NFT token ID
9292
* @returns {DelegateTxnBuilder} This transaction builder
9393
*/
94-
tokenId(tokenId: number): this {
94+
tokenId(tokenId: string): this {
9595
this.delegateTransaction.tokenId = tokenId;
9696
return this;
9797
}
9898

99+
/**
100+
* Sets the validator address for this delegate tx.
101+
* @param {string} address - The validator address
102+
* @returns {DelegateTxnBuilder} This transaction builder
103+
*/
104+
validator(address: string): this {
105+
if (!address) {
106+
throw new Error('Validator address is required');
107+
}
108+
this.validateAddress({ address });
109+
this.delegateTransaction.validator = address;
110+
return this;
111+
}
112+
99113
/**
100114
* Sets the transaction data for this delegate tx.
101115
*
@@ -115,7 +129,7 @@ export class DelegateTxnBuilder extends TransactionBuilder {
115129
assert(transaction.stakingContractAddress, 'Staking contract address is required');
116130

117131
assert(transaction.tokenId, 'Token ID is required');
118-
assert(transaction.delegateForever, 'delegate forever flag is required');
132+
assert(transaction.validator, 'validator address is required');
119133
this.validateAddress({ address: transaction.stakingContractAddress });
120134
}
121135

modules/sdk-coin-vet/src/lib/utils.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ import {
2323
STARGATE_NFT_ADDRESS,
2424
STARGATE_NFT_ADDRESS_TESTNET,
2525
STARGATE_DELEGATION_ADDRESS,
26-
STARGATE_DELEGATION_ADDRESS_TESTNET,
2726
DELEGATE_CLAUSE_METHOD_ID,
27+
STARGATE_CONTRACT_ADDRESS_TESTNET,
2828
} from './constants';
2929
import { KeyPair } from './keyPair';
3030
import { BaseCoin as CoinConfig } from '@bitgo/statics';
@@ -179,21 +179,21 @@ export class Utils implements BaseUtils {
179179
}
180180

181181
/**
182-
* Decodes delegate transaction data to extract tokenId and delegateForever
182+
* Decodes delegate transaction data to extract tokenId and validatorAddress
183183
*
184184
* @param {string} data - The encoded transaction data
185-
* @returns {object} - Object containing tokenId and delegateForever
185+
* @returns {object} - Object containing levelId and validator address
186186
*/
187-
decodeDelegateClauseData(data: string): { tokenId: number; delegateForever: boolean } {
187+
decodeDelegateClauseData(data: string): { tokenId: string; validator: string } {
188188
try {
189189
const parameters = data.slice(10);
190190

191191
// Decode using ethereumjs-abi directly
192-
const decoded = EthereumAbi.rawDecode(['uint256', 'bool'], Buffer.from(parameters, 'hex'));
192+
const decoded = EthereumAbi.rawDecode(['uint256', 'address'], Buffer.from(parameters, 'hex'));
193193

194194
return {
195-
tokenId: Number(decoded[0]),
196-
delegateForever: Boolean(decoded[1]),
195+
tokenId: String(decoded[0]),
196+
validator: String(decoded[1]),
197197
};
198198
} catch (error) {
199199
throw new Error(`Failed to decode delegation data: ${error.message}`);
@@ -298,13 +298,13 @@ export class Utils implements BaseUtils {
298298
}
299299

300300
/**
301-
* Get the network-appropriate delegation contract address
301+
* Get the network-appropriate stargate contract address
302302
* @param {CoinConfig} coinConfig - The coin configuration object
303303
* @returns {string} The delegation contract address for the network
304304
*/
305305
getDefaultDelegationAddress(coinConfig: Readonly<CoinConfig>): string {
306306
const isTestnet = coinConfig.network.type === 'testnet';
307-
return isTestnet ? STARGATE_DELEGATION_ADDRESS_TESTNET : STARGATE_DELEGATION_ADDRESS;
307+
return isTestnet ? STARGATE_CONTRACT_ADDRESS_TESTNET : STARGATE_DELEGATION_ADDRESS;
308308
}
309309

310310
/**
@@ -358,7 +358,7 @@ export class Utils implements BaseUtils {
358358
}
359359

360360
/**
361-
* Validate that a contract address matches the expected delegation contract for the network
361+
* Validate that a contract address matches the expected stargate contract for the network
362362
* @param {string} address - The contract address to validate
363363
* @param {CoinConfig} coinConfig - The coin configuration object
364364
* @throws {Error} If the address doesn't match the expected delegation contract address

modules/sdk-coin-vet/test/resources/vet.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const STAKING_TRANSACTION =
1515
'0xf901032788015d55fcf2457e7c40f866f864941856c533ac2d94340aaa8544d35a5c1d4a21dee7880de0b6b3a7640000b844d8da3bbf0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000181808265848083094c53c101b882efcb9ea88e908d1a142db96c1b44dd056ea194f1ad45670c100a8c52348cc7b20387741260ebe7fe9b7594f96693c88662fa60edba5992332728222b0bdd8a30008535368bd901319eb4513d16bebc428dc8454d32a19eeb76372849a6134ebbba79f1eeceea1f6546574b945c05489222cb451f5b0e2901b0c687b750e833aeb800';
1616

1717
export const STAKE_CLAUSE_TRANSACTION =
18-
'0xf8e3278801618b7b1354c4ca40f845f843941ec1d168574603ec35b9d229843b7c2b44bcb770880de0b6b3a7640000a4604f2177000000000000000000000000000000000000000000000000000000000000000881808305fd5a808307b278c101b882b380970580d957b8e7989aa9aa9281e57245fa3835cb2aaae6475b4062bb4f1c2dd2ca694df6503d5dfd654579130b3484bee75420247cf8f6b6b4b76b7939f101db6e6cef5a27375274741f3c0aba4be13a9e086337c3290866afe049efcdaa2d3227c9e12b52627c4d71f5b667821f9d33adcc4c97fdc28b93c34013d32e242300';
18+
'0xf8e5278801638298c53767ac40f847f845941e02b2953adefec225cf0ec49805b1146a4429c18a021e19e0c9bab2400000a4604f2177000000000000000000000000000000000000000000000000000000000000000881808306338a80830f340bc101b882b4970b0c160552162de719b9ed1fa6268bbfe9b36fd4e4a5c13e956cf539e60478f69179e8db4a3106fdbe775e3d923510b16f48da56c66076d1f66ffd822abf01ebc040c795b1e17cb0ca5ba747e3a181b4eefea7db5378f64f82361bdb7745da45aba2ace3db9822b675474552f13849052987c431cd4867813c2cf635302b1101';
1919

2020
export const DELEGATION_TRANSACTION =
2121
'0xf8fb278801618aa3e0a55fc940f85ef85c947240e3bc0d26431512d5b67dbd26d199205bffe880b8443207555d00000000000000000000000000000000000000000000000000000000000187690000000000000000000000000000000000000000000000000000000000000001818082e43a808306af07c101b882fb8030f6e2ef6563ff3b0e7e2a2292c1db5fc41c7ab9f598bad370c5cfd3dc32286ae8d709e941c0312c8cd33a3505156b44d1639c73980ffa66bc72f37820f2001c0e6b6e76a6a4d806c377a0a279053eb6ea4356bd235f4396585bb071d70f992c639d45c53431a3c1493a52a136203905e42c671dd384ee5f5ead0a70cb607001';

0 commit comments

Comments
 (0)