From 33389950972ca8046675f41ce4d59bf0a6735a63 Mon Sep 17 00:00:00 2001 From: redDwarf03 Date: Mon, 27 Nov 2023 15:49:58 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20a=20flag=20in=20sendTx=20meth?= =?UTF-8?q?od=20to=20add=20encrypted=20seed=20in=20a=20secret?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/domain/rpc/commands/send_transaction.dart | 19 ++++--- .../commands/send_transaction.freezed.dart | 50 +++++++++++++++---- .../rpc/send_transaction/command_handler.dart | 1 + .../send_transaction/command_handler.dart | 38 ++++++++++++++ 4 files changed, 91 insertions(+), 17 deletions(-) diff --git a/lib/domain/rpc/commands/send_transaction.dart b/lib/domain/rpc/commands/send_transaction.dart index 19111ce96..5183c2299 100644 --- a/lib/domain/rpc/commands/send_transaction.dart +++ b/lib/domain/rpc/commands/send_transaction.dart @@ -5,15 +5,18 @@ part 'send_transaction.freezed.dart'; @freezed class RPCSendTransactionCommandData with _$RPCSendTransactionCommandData { - const factory RPCSendTransactionCommandData({ - /// - [Data]: transaction data zone (identity, keychain, smart contract, etc.) - required Data data, + const factory RPCSendTransactionCommandData( + { + /// - [Data]: transaction data zone (identity, keychain, smart contract, etc.) + required Data data, - /// - Type: transaction type - required String type, + /// - Type: transaction type + required String type, - /// - Version: version of the transaction (used for backward compatiblity) - required int version, - }) = _RPCSendTransactionCommandData; + /// - Version: version of the transaction (used for backward compatiblity) + required int version, + + /// - Flag to generate and add the encrypted smart contract's seed in a secret + bool? generateEncryptedSeedSC}) = _RPCSendTransactionCommandData; const RPCSendTransactionCommandData._(); } diff --git a/lib/domain/rpc/commands/send_transaction.freezed.dart b/lib/domain/rpc/commands/send_transaction.freezed.dart index bee9a495a..6bbe7a730 100644 --- a/lib/domain/rpc/commands/send_transaction.freezed.dart +++ b/lib/domain/rpc/commands/send_transaction.freezed.dart @@ -25,6 +25,9 @@ mixin _$RPCSendTransactionCommandData { /// - Version: version of the transaction (used for backward compatiblity) int get version => throw _privateConstructorUsedError; + /// - Flag to generate and add the encrypted smart contract's seed in a secret + bool? get generateEncryptedSeedSC => throw _privateConstructorUsedError; + @JsonKey(ignore: true) $RPCSendTransactionCommandDataCopyWith get copyWith => throw _privateConstructorUsedError; @@ -38,7 +41,8 @@ abstract class $RPCSendTransactionCommandDataCopyWith<$Res> { _$RPCSendTransactionCommandDataCopyWithImpl<$Res, RPCSendTransactionCommandData>; @useResult - $Res call({Data data, String type, int version}); + $Res call( + {Data data, String type, int version, bool? generateEncryptedSeedSC}); $DataCopyWith<$Res> get data; } @@ -60,6 +64,7 @@ class _$RPCSendTransactionCommandDataCopyWithImpl<$Res, Object? data = null, Object? type = null, Object? version = null, + Object? generateEncryptedSeedSC = freezed, }) { return _then(_value.copyWith( data: null == data @@ -74,6 +79,10 @@ class _$RPCSendTransactionCommandDataCopyWithImpl<$Res, ? _value.version : version // ignore: cast_nullable_to_non_nullable as int, + generateEncryptedSeedSC: freezed == generateEncryptedSeedSC + ? _value.generateEncryptedSeedSC + : generateEncryptedSeedSC // ignore: cast_nullable_to_non_nullable + as bool?, ) as $Val); } @@ -95,7 +104,8 @@ abstract class _$$RPCSendTransactionCommandDataImplCopyWith<$Res> __$$RPCSendTransactionCommandDataImplCopyWithImpl<$Res>; @override @useResult - $Res call({Data data, String type, int version}); + $Res call( + {Data data, String type, int version, bool? generateEncryptedSeedSC}); @override $DataCopyWith<$Res> get data; @@ -117,6 +127,7 @@ class __$$RPCSendTransactionCommandDataImplCopyWithImpl<$Res> Object? data = null, Object? type = null, Object? version = null, + Object? generateEncryptedSeedSC = freezed, }) { return _then(_$RPCSendTransactionCommandDataImpl( data: null == data @@ -131,6 +142,10 @@ class __$$RPCSendTransactionCommandDataImplCopyWithImpl<$Res> ? _value.version : version // ignore: cast_nullable_to_non_nullable as int, + generateEncryptedSeedSC: freezed == generateEncryptedSeedSC + ? _value.generateEncryptedSeedSC + : generateEncryptedSeedSC // ignore: cast_nullable_to_non_nullable + as bool?, )); } } @@ -140,7 +155,10 @@ class __$$RPCSendTransactionCommandDataImplCopyWithImpl<$Res> class _$RPCSendTransactionCommandDataImpl extends _RPCSendTransactionCommandData { const _$RPCSendTransactionCommandDataImpl( - {required this.data, required this.type, required this.version}) + {required this.data, + required this.type, + required this.version, + this.generateEncryptedSeedSC}) : super._(); /// - [Data]: transaction data zone (identity, keychain, smart contract, etc.) @@ -155,9 +173,13 @@ class _$RPCSendTransactionCommandDataImpl @override final int version; + /// - Flag to generate and add the encrypted smart contract's seed in a secret + @override + final bool? generateEncryptedSeedSC; + @override String toString() { - return 'RPCSendTransactionCommandData(data: $data, type: $type, version: $version)'; + return 'RPCSendTransactionCommandData(data: $data, type: $type, version: $version, generateEncryptedSeedSC: $generateEncryptedSeedSC)'; } @override @@ -167,11 +189,15 @@ class _$RPCSendTransactionCommandDataImpl other is _$RPCSendTransactionCommandDataImpl && (identical(other.data, data) || other.data == data) && (identical(other.type, type) || other.type == type) && - (identical(other.version, version) || other.version == version)); + (identical(other.version, version) || other.version == version) && + (identical( + other.generateEncryptedSeedSC, generateEncryptedSeedSC) || + other.generateEncryptedSeedSC == generateEncryptedSeedSC)); } @override - int get hashCode => Object.hash(runtimeType, data, type, version); + int get hashCode => + Object.hash(runtimeType, data, type, version, generateEncryptedSeedSC); @JsonKey(ignore: true) @override @@ -185,9 +211,11 @@ class _$RPCSendTransactionCommandDataImpl abstract class _RPCSendTransactionCommandData extends RPCSendTransactionCommandData { const factory _RPCSendTransactionCommandData( - {required final Data data, - required final String type, - required final int version}) = _$RPCSendTransactionCommandDataImpl; + {required final Data data, + required final String type, + required final int version, + final bool? generateEncryptedSeedSC}) = + _$RPCSendTransactionCommandDataImpl; const _RPCSendTransactionCommandData._() : super._(); @override @@ -203,6 +231,10 @@ abstract class _RPCSendTransactionCommandData /// - Version: version of the transaction (used for backward compatiblity) int get version; @override + + /// - Flag to generate and add the encrypted smart contract's seed in a secret + bool? get generateEncryptedSeedSC; + @override @JsonKey(ignore: true) _$$RPCSendTransactionCommandDataImplCopyWith< _$RPCSendTransactionCommandDataImpl> diff --git a/lib/infrastructure/rpc/send_transaction/command_handler.dart b/lib/infrastructure/rpc/send_transaction/command_handler.dart index 0dc30f901..64198ccc6 100644 --- a/lib/infrastructure/rpc/send_transaction/command_handler.dart +++ b/lib/infrastructure/rpc/send_transaction/command_handler.dart @@ -16,6 +16,7 @@ class RPCSendTransactionCommandHandler extends RPCCommandHandler< data: archethic.Data.fromJson(dto.payload['data']), type: dto.payload['type'], version: dto.version, + generateEncryptedSeedSC: dto.payload['generateEncryptedSeedSC'], ), ); diff --git a/lib/ui/views/rpc_command_receiver/send_transaction/command_handler.dart b/lib/ui/views/rpc_command_receiver/send_transaction/command_handler.dart index 94d2b5d57..ca3411bac 100644 --- a/lib/ui/views/rpc_command_receiver/send_transaction/command_handler.dart +++ b/lib/ui/views/rpc_command_receiver/send_transaction/command_handler.dart @@ -5,6 +5,7 @@ import 'package:aewallet/domain/rpc/commands/failure.dart'; import 'package:aewallet/domain/rpc/commands/send_transaction.dart'; import 'package:aewallet/ui/views/rpc_command_receiver/send_transaction/layouts/send_transaction_confirmation_form.dart'; import 'package:aewallet/ui/widgets/components/sheet_util.dart'; +import 'package:aewallet/util/get_it_instance.dart'; import 'package:aewallet/util/notifications_util.dart'; import 'package:archethic_lib_dart/archethic_lib_dart.dart'; import 'package:flutter/material.dart'; @@ -20,6 +21,43 @@ class SendTransactionHandler extends CommandHandler { command is RPCCommand, handle: (command) async { command as RPCCommand; + + if (command.data.generateEncryptedSeedSC != null && + command.data.generateEncryptedSeedSC == true) { + if (command.data.data.code == null || + command.data.data.code!.trim().isEmpty) { + return Result.failure( + RPCFailure.invalidTransaction(), + ); + } + + final apiService = sl.get(); + final storageNoncePublicKey = + await apiService.getStorageNoncePublicKey(); + final seedSC = generateRandomSeed(); + + /// AESKey (32-byte (256-bit) random key) manages SC secrets + final aesKey = generateRandomAESKey(); + + final scAuthorizedKeys = [ + AuthorizedKey( + publicKey: storageNoncePublicKey, + encryptedSecretKey: + uint8ListToHex(ecEncrypt(aesKey, storageNoncePublicKey)), + ), + ]; + + command.data.data.ownerships.insert( + 0, + Ownership( + secret: uint8ListToHex( + aesEncrypt(seedSC, aesKey), + ), + authorizedPublicKeys: scAuthorizedKeys, + ), + ); + } + _showNotification( context: context, ref: ref,