From b1233d3ed71a9c7d2cad7a1bdd4f38d49c94f5f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20G=C3=B3mez?= Date: Mon, 26 Aug 2024 16:44:35 +0200 Subject: [PATCH] Extend Confirmation View with an optional value field (#1851) - Adds `value` optional parameter to `TransactionDataDto`. - Adds `value` field to the `NativeStakingConfirmationView` entity. - Adjusts tests accordingly. --- .../common/entities/transaction-data.dto.entity.ts | 9 ++++++++- .../staking/native-staking-confirmation-view.entity.ts | 5 +++++ .../transactions/transactions-view.controller.spec.ts | 4 ++++ src/routes/transactions/transactions-view.service.ts | 5 ++++- 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/routes/common/entities/transaction-data.dto.entity.ts b/src/routes/common/entities/transaction-data.dto.entity.ts index a7de027dd7..a83aeb95c7 100644 --- a/src/routes/common/entities/transaction-data.dto.entity.ts +++ b/src/routes/common/entities/transaction-data.dto.entity.ts @@ -2,10 +2,12 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { z } from 'zod'; import { HexSchema } from '@/validation/entities/schemas/hex.schema'; import { AddressSchema } from '@/validation/entities/schemas/address.schema'; +import { NumericStringSchema } from '@/validation/entities/schemas/numeric-string.schema'; export const TransactionDataDtoSchema = z.object({ data: HexSchema, to: AddressSchema.optional(), + value: NumericStringSchema.optional(), }); export class TransactionDataDto @@ -15,9 +17,14 @@ export class TransactionDataDto data: `0x${string}`; @ApiPropertyOptional({ description: 'The target Ethereum address' }) to?: `0x${string}`; + @ApiPropertyOptional({ + description: 'The wei amount being sent to a payable function', + }) + value?: string; - constructor(data: `0x${string}`, to: `0x${string}`) { + constructor(data: `0x${string}`, to?: `0x${string}`, value?: string) { this.data = data; this.to = to; + this.value = value; } } diff --git a/src/routes/transactions/entities/staking/native-staking-confirmation-view.entity.ts b/src/routes/transactions/entities/staking/native-staking-confirmation-view.entity.ts index 5e2c345053..ae60e74275 100644 --- a/src/routes/transactions/entities/staking/native-staking-confirmation-view.entity.ts +++ b/src/routes/transactions/entities/staking/native-staking-confirmation-view.entity.ts @@ -44,6 +44,9 @@ export class NativeStakingDepositConfirmationView @ApiProperty() annualNrr: number; + @ApiProperty() + value: number; + constructor(args: { method: string; parameters: DataDecodedParameter[] | null; @@ -54,6 +57,7 @@ export class NativeStakingDepositConfirmationView fee: number; monthlyNrr: number; annualNrr: number; + value: number; }) { this.method = args.method; this.parameters = args.parameters; @@ -64,5 +68,6 @@ export class NativeStakingDepositConfirmationView this.fee = args.fee; this.monthlyNrr = args.monthlyNrr; this.annualNrr = args.annualNrr; + this.value = args.value; } } diff --git a/src/routes/transactions/transactions-view.controller.spec.ts b/src/routes/transactions/transactions-view.controller.spec.ts index 95f4e1b285..9f5b1719ec 100644 --- a/src/routes/transactions/transactions-view.controller.spec.ts +++ b/src/routes/transactions/transactions-view.controller.spec.ts @@ -576,6 +576,7 @@ describe('TransactionsViewController tests', () => { const data = encodeFunctionData({ abi: parseAbi(['function deposit() external payable']), }); + const value = faker.string.numeric(); networkService.get.mockImplementation(({ url }) => { if (url === `${safeConfigUrl}/api/v1/chains/${chain.chainId}`) { return Promise.resolve({ data: chain, status: 200 }); @@ -614,6 +615,7 @@ describe('TransactionsViewController tests', () => { .send({ to: deployment.address, data, + value, }) .expect(200) .expect({ @@ -633,6 +635,7 @@ describe('TransactionsViewController tests', () => { annualNrr: dedicatedStakingStats.gross_apy.last_30d * (1 - +deployment.product_fee!), + value: Number(value), }); }); @@ -721,6 +724,7 @@ describe('TransactionsViewController tests', () => { annualNrr: dedicatedStakingStats.gross_apy.last_30d * (1 - +deployment.product_fee!), + value: 0, // defaults to 0 if not provided in the request }); }); diff --git a/src/routes/transactions/transactions-view.service.ts b/src/routes/transactions/transactions-view.service.ts index 4a2f12a0bd..3b87c59f26 100644 --- a/src/routes/transactions/transactions-view.service.ts +++ b/src/routes/transactions/transactions-view.service.ts @@ -108,9 +108,10 @@ export class TransactionsViewService { }); } else if (nativeStakingTransaction) { return await this.getNativeStakingDepositConfirmationView({ + ...nativeStakingTransaction, chainId: args.chainId, dataDecoded, - ...nativeStakingTransaction, + value: args.transactionDataDto.value, }); } else { // Should not reach here @@ -277,6 +278,7 @@ export class TransactionsViewService { to: `0x${string}`; data: `0x${string}`; dataDecoded: DataDecoded; + value?: string; }): Promise { const depositInfo = await this.nativeStakingMapper.mapDepositInfo({ chainId: args.chainId, @@ -287,6 +289,7 @@ export class TransactionsViewService { return new NativeStakingDepositConfirmationView({ method: args.dataDecoded.method, parameters: args.dataDecoded.parameters, + value: args.value ? Number(args.value) : 0, ...depositInfo, }); }