Skip to content

Commit

Permalink
Return validator addresses in staking entities (safe-global#1964)
Browse files Browse the repository at this point in the history
Returns the validators under a new `validators` property for all staking entities (apart from pre-executed deposits):

- Add `validators` property to:
  - Confirmation view: exit requests and withdrawals
  - Transaction info: deposits (after execution), exit requests and withdrawals
  • Loading branch information
iamacook authored and DenSmolonski committed Oct 24, 2024
1 parent 466599c commit c247fbb
Show file tree
Hide file tree
Showing 9 changed files with 295 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ export class NativeStakingDepositTransactionInfo
@ApiProperty()
tokenInfo: TokenInfo;

@ApiProperty({
description: 'Populated after transaction has been executed',
})
validators: Array<`0x${string}`> | null;

constructor(args: {
status: StakingStatus;
estimatedEntryTime: number;
Expand All @@ -76,6 +81,7 @@ export class NativeStakingDepositTransactionInfo
expectedFiatAnnualReward: number;
expectedFiatMonthlyReward: number;
tokenInfo: TokenInfo;
validators: Array<`0x${string}`> | null;
}) {
super(TransactionInfoType.NativeStakingDeposit, null, null);
this.status = args.status;
Expand All @@ -92,5 +98,6 @@ export class NativeStakingDepositTransactionInfo
this.expectedFiatAnnualReward = args.expectedFiatAnnualReward;
this.expectedFiatMonthlyReward = args.expectedFiatMonthlyReward;
this.tokenInfo = args.tokenInfo;
this.validators = args.validators;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ export class NativeStakingValidatorsExitConfirmationView implements Baseline {
@ApiProperty()
tokenInfo: TokenInfo;

@ApiProperty()
validators: Array<`0x${string}`>;

constructor(args: {
method: string;
parameters: DataDecodedParameter[] | null;
Expand All @@ -48,6 +51,7 @@ export class NativeStakingValidatorsExitConfirmationView implements Baseline {
value: string;
numValidators: number;
tokenInfo: TokenInfo;
validators: Array<`0x${string}`>;
}) {
this.method = args.method;
this.parameters = args.parameters;
Expand All @@ -57,5 +61,6 @@ export class NativeStakingValidatorsExitConfirmationView implements Baseline {
this.value = args.value;
this.numValidators = args.numValidators;
this.tokenInfo = args.tokenInfo;
this.validators = args.validators;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,23 @@ export class NativeStakingValidatorsExitTransactionInfo extends TransactionInfo
@ApiProperty()
tokenInfo: TokenInfo;

@ApiProperty()
validators: Array<`0x${string}`>;

constructor(args: {
status: StakingStatus;
estimatedExitTime: number;
estimatedWithdrawalTime: number;
numValidators: number;
tokenInfo: TokenInfo;
validators: Array<`0x${string}`>;
}) {
super(TransactionInfoType.NativeStakingValidatorsExit, null, null);
this.status = args.status;
this.estimatedExitTime = args.estimatedExitTime;
this.estimatedWithdrawalTime = args.estimatedWithdrawalTime;
this.numValidators = args.numValidators;
this.tokenInfo = args.tokenInfo;
this.validators = args.validators;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,20 @@ export class NativeStakingWithdrawConfirmationView implements Baseline {
@ApiProperty()
tokenInfo: TokenInfo;

@ApiProperty()
validators: Array<`0x${string}`>;

constructor(args: {
method: string;
parameters: DataDecodedParameter[] | null;
value: string;
tokenInfo: TokenInfo;
validators: Array<`0x${string}`>;
}) {
this.method = args.method;
this.parameters = args.parameters;
this.value = args.value;
this.tokenInfo = args.tokenInfo;
this.validators = args.validators;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,17 @@ export class NativeStakingWithdrawTransactionInfo extends TransactionInfo {
@ApiProperty()
tokenInfo: TokenInfo;

constructor(args: { value: string; tokenInfo: TokenInfo }) {
@ApiProperty()
validators: Array<`0x${string}`>;

constructor(args: {
value: string;
tokenInfo: TokenInfo;
validators: Array<`0x${string}`>;
}) {
super(TransactionInfoType.NativeStakingWithdraw, null, null);
this.value = args.value;
this.tokenInfo = args.tokenInfo;
this.validators = args.validators;
}
}
71 changes: 51 additions & 20 deletions src/routes/transactions/helpers/kiln-native-staking.helper.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { StakingRepository } from '@/domain/staking/staking.repository';
import { KilnNativeStakingHelper } from '@/routes/transactions/helpers/kiln-native-staking.helper';
import { TransactionFinder } from '@/routes/transactions/helpers/transaction-finder.helper';
import { faker } from '@faker-js/faker';
import { getAddress } from 'viem';
import { concat, getAddress } from 'viem';

const mockStakingRepository = jest.mocked({
getStakes: jest.fn(),
Expand Down Expand Up @@ -134,9 +134,22 @@ describe('KilnNativeStakingHelper', () => {
'requestValidatorsExit',
'batchWithdrawCLFee',
]);
const _publicKeys = faker.string.hexadecimal({
length: KilnDecoder.KilnPublicKeyLength * 3,
}) as `0x${string}`; // 3 validators
const validators = [
faker.string.hexadecimal({
length: KilnDecoder.KilnPublicKeyLength,
// Transaction Service returns _publicKeys lowercase
casing: 'lower',
}),
faker.string.hexadecimal({
length: KilnDecoder.KilnPublicKeyLength,
casing: 'lower',
}),
faker.string.hexadecimal({
length: KilnDecoder.KilnPublicKeyLength,
casing: 'lower',
}),
] as Array<`0x${string}`>;
const _publicKeys = concat(validators);
const dataDecoded = dataDecodedBuilder()
.with('method', method)
.with('parameters', [
Expand Down Expand Up @@ -201,9 +214,22 @@ describe('KilnNativeStakingHelper', () => {
'requestValidatorsExit',
'batchWithdrawCLFee',
]);
const _publicKeys = faker.string.hexadecimal({
length: KilnDecoder.KilnPublicKeyLength * 3,
}) as `0x${string}`; // 3 validators
const validators = [
faker.string.hexadecimal({
length: KilnDecoder.KilnPublicKeyLength,
// Transaction Service returns _publicKeys lowercase
casing: 'lower',
}),
faker.string.hexadecimal({
length: KilnDecoder.KilnPublicKeyLength,
casing: 'lower',
}),
faker.string.hexadecimal({
length: KilnDecoder.KilnPublicKeyLength,
casing: 'lower',
}),
] as Array<`0x${string}`>;
const _publicKeys = concat(validators);
const dataDecoded = dataDecodedBuilder()
.with('method', method)
.with('parameters', [
Expand All @@ -218,11 +244,7 @@ describe('KilnNativeStakingHelper', () => {

const result = target.getPublicKeysFromDataDecoded(dataDecoded);

expect(result).toStrictEqual([
`0x${_publicKeys.slice(2, 2 + KilnDecoder.KilnPublicKeyLength)}`,
`0x${_publicKeys.slice(2 + KilnDecoder.KilnPublicKeyLength, 2 + KilnDecoder.KilnPublicKeyLength * 2)}`,
`0x${_publicKeys.slice(2 + KilnDecoder.KilnPublicKeyLength * 2, 2 + KilnDecoder.KilnPublicKeyLength * 3)}`,
]);
expect(result).toStrictEqual(validators);
});

it('should return an empty array if non-hex _publicKeys is found', () => {
Expand Down Expand Up @@ -253,17 +275,26 @@ describe('KilnNativeStakingHelper', () => {

describe('splitPublicKeys', () => {
it('should split the _publicKeys into an array of strings of correct length', () => {
const _publicKeys = faker.string.hexadecimal({
length: KilnDecoder.KilnPublicKeyLength * 3,
}) as `0x${string}`;
const validators = [
faker.string.hexadecimal({
length: KilnDecoder.KilnPublicKeyLength,
// Transaction Service returns _publicKeys lowercase
casing: 'lower',
}),
faker.string.hexadecimal({
length: KilnDecoder.KilnPublicKeyLength,
casing: 'lower',
}),
faker.string.hexadecimal({
length: KilnDecoder.KilnPublicKeyLength,
casing: 'lower',
}),
] as Array<`0x${string}`>;
const _publicKeys = concat(validators);

const result = target.splitPublicKeys(_publicKeys);

expect(result).toStrictEqual([
`0x${_publicKeys.slice(2, 2 + KilnDecoder.KilnPublicKeyLength)}`,
`0x${_publicKeys.slice(2 + KilnDecoder.KilnPublicKeyLength, 2 + KilnDecoder.KilnPublicKeyLength * 2)}`,
`0x${_publicKeys.slice(2 + KilnDecoder.KilnPublicKeyLength * 2, 2 + KilnDecoder.KilnPublicKeyLength * 3)}`,
]);
expect(result).toStrictEqual(validators);
});
});
});
Loading

0 comments on commit c247fbb

Please sign in to comment.