diff --git a/.gitignore b/.gitignore index 40dd9e96..8e14ac41 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,9 @@ -#FVM sdk ignore +# Flutter Version Management .fvm/flutter_sdk +.fvm/versions +.fvm/version +.fvm/release +.fvmrc # Miscellaneous *.class diff --git a/lib/blocs/pages/drawer/create_wallet_drawer_page/create_wallet_drawer_page_cubit.dart b/lib/blocs/pages/drawer/create_wallet_drawer_page/create_wallet_drawer_page_cubit.dart index 53311572..a944c5b4 100644 --- a/lib/blocs/pages/drawer/create_wallet_drawer_page/create_wallet_drawer_page_cubit.dart +++ b/lib/blocs/pages/drawer/create_wallet_drawer_page/create_wallet_drawer_page_cubit.dart @@ -24,7 +24,7 @@ class CreateWalletDrawerPageCubit extends Cubit { emit(CreateWalletDrawerPageLoadingState()); await Future.delayed(const Duration(milliseconds: 500)); Mnemonic mnemonic = Mnemonic.random(); - Wallet wallet = Wallet.derive(mnemonic: mnemonic); + Wallet wallet = await Wallet.derive(mnemonic: mnemonic); emit(CreateWalletDrawerPageLoadedState(mnemonic: mnemonic, wallet: wallet)); } diff --git a/lib/blocs/pages/transactions/tx_process_cubit/tx_process_cubit.dart b/lib/blocs/pages/transactions/tx_process_cubit/tx_process_cubit.dart index f312acd0..bb0748b2 100644 --- a/lib/blocs/pages/transactions/tx_process_cubit/tx_process_cubit.dart +++ b/lib/blocs/pages/transactions/tx_process_cubit/tx_process_cubit.dart @@ -20,7 +20,6 @@ import 'package:miro/shared/models/transactions/signed_transaction_model.dart'; import 'package:miro/shared/models/transactions/unsigned_tx_model.dart'; import 'package:miro/shared/models/wallet/wallet.dart'; import 'package:miro/shared/utils/logger/app_logger.dart'; -import 'package:miro/shared/utils/transactions/tx_utils.dart'; class TxProcessCubit extends Cubit { final AuthCubit authCubit = globalLocator(); @@ -128,8 +127,6 @@ class TxProcessCubit extends Cubit { if (wallet == null) { throw Exception('Wallet cannot be null when signing transaction'); } - SignedTxModel signedTxModel = TxUtils.sign(unsignedTxModel: unsignedTxModel, wallet: wallet); - await Future.delayed(const Duration(milliseconds: 100)); - return signedTxModel; + return unsignedTxModel.sign(wallet); } } diff --git a/lib/infra/dto/api_kira/broadcast/request/broadcast_req.dart b/lib/infra/dto/api_kira/broadcast/request/broadcast_req.dart index e38fe56d..6376e762 100644 --- a/lib/infra/dto/api_kira/broadcast/request/broadcast_req.dart +++ b/lib/infra/dto/api_kira/broadcast/request/broadcast_req.dart @@ -1,8 +1,8 @@ +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:equatable/equatable.dart'; -import 'package:miro/infra/dto/api_kira/broadcast/request/transaction/tx.dart'; class BroadcastReq extends Equatable { - final Tx tx; + final CosmosTx tx; final String mode; const BroadcastReq({ @@ -12,7 +12,7 @@ class BroadcastReq extends Equatable { Map toJson() { return { - 'tx': tx.toJson(), + 'tx': tx.toProtoJson(), 'mode': mode, }; } diff --git a/lib/infra/dto/api_kira/broadcast/request/transaction/components/auth_info.dart b/lib/infra/dto/api_kira/broadcast/request/transaction/components/auth_info.dart deleted file mode 100644 index cac50f43..00000000 --- a/lib/infra/dto/api_kira/broadcast/request/transaction/components/auth_info.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:equatable/equatable.dart'; -import 'package:miro/infra/dto/api_kira/broadcast/request/transaction/components/signer_info.dart'; -import 'package:miro/infra/dto/api_kira/broadcast/request/transaction/components/tx_fee.dart'; - -/// Describes the fee and signer modes that are used to sign a transaction. -/// -/// https://docs.cosmos.network/v0.44/core/proto-docs.html#cosmos.tx.v1beta1.AuthInfo -class AuthInfo extends Equatable { - /// Defines the signing modes for the required signers. The number - /// and order of elements must match the required signers from TxBody's messages. - /// The first element is the primary signer and the one which pays the fee. - final List signerInfos; - - /// The fee can be calculated based on the cost of evaluating - /// the body and doing signature verification of the signers. - /// This can be estimated via simulation. - final TxFee fee; - - const AuthInfo({ - required this.fee, - required this.signerInfos, - }); - - Map toJson() => { - 'signer_infos': signerInfos.map((SignerInfo e) => e.toJson()).toList(), - 'fee': fee.toJson(), - }; - - @override - List get props => [fee, signerInfos]; -} diff --git a/lib/infra/dto/api_kira/broadcast/request/transaction/components/mode_info/mode_info.dart b/lib/infra/dto/api_kira/broadcast/request/transaction/components/mode_info/mode_info.dart deleted file mode 100644 index 4c4d7bab..00000000 --- a/lib/infra/dto/api_kira/broadcast/request/transaction/components/mode_info/mode_info.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:equatable/equatable.dart'; -import 'package:miro/infra/dto/api_kira/broadcast/request/transaction/components/mode_info/single_mode_info.dart'; - -/// ModeInfo describes the signing mode of a single or nested multisign signer. -// TODO(dominik): There can be Multi option (https://docs.cosmos.network/v0.44/core/proto-docs.html#cosmos.tx.v1beta1.ModeInfo) -class ModeInfo extends Equatable { - /// Single is the mode info for a single signer. It is structured as a message - /// to allow for additional fields such as locale for SIGN_MODE_TEXTUAL in the future - final SingleModeInfo single; - - const ModeInfo({ - required this.single, - }); - - factory ModeInfo.fromJson(Map json) { - return ModeInfo( - single: SingleModeInfo.fromJson( - json['single'] as Map, - ), - ); - } - - Map toJson() { - return {'single': single.toJson()}; - } - - @override - List get props => [single]; -} diff --git a/lib/infra/dto/api_kira/broadcast/request/transaction/components/mode_info/sign_mode.dart b/lib/infra/dto/api_kira/broadcast/request/transaction/components/mode_info/sign_mode.dart deleted file mode 100644 index 942d5e37..00000000 --- a/lib/infra/dto/api_kira/broadcast/request/transaction/components/mode_info/sign_mode.dart +++ /dev/null @@ -1,19 +0,0 @@ -/// SignMode represents a signing mode with its own security guarantees. -// ignore_for_file: constant_identifier_names -enum SignMode { - /// SIGN_MODE_UNSPECIFIED specifies an unknown signing mode and will be rejected - SIGN_MODE_UNSPECIFIED, - - /// SIGN_MODE_DIRECT specifies a signing mode which uses SignDoc and is - /// verified with raw bytes from Tx - SIGN_MODE_DIRECT, - - /// SIGN_MODE_TEXTUAL is a future signing mode that will verify some - /// human-readable textual representation on top of the binary representation - /// from SIGN_MODE_DIRECT - SIGN_MODE_TEXTUAL, - - /// SIGN_MODE_LEGACY_AMINO_JSON is a backwards compatibility mode which uses - /// Amino JSON and will be removed in the future - SIGN_MODE_LEGACY_AMINO_JSON, -} diff --git a/lib/infra/dto/api_kira/broadcast/request/transaction/components/mode_info/single_mode_info.dart b/lib/infra/dto/api_kira/broadcast/request/transaction/components/mode_info/single_mode_info.dart deleted file mode 100644 index f2d0ccb6..00000000 --- a/lib/infra/dto/api_kira/broadcast/request/transaction/components/mode_info/single_mode_info.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:equatable/equatable.dart'; -import 'package:miro/infra/dto/api_kira/broadcast/request/transaction/components/mode_info/sign_mode.dart'; -import 'package:miro/shared/utils/enum_utils.dart'; - -class SingleModeInfo extends Equatable { - final SignMode mode; - - const SingleModeInfo({ - required this.mode, - }); - - factory SingleModeInfo.fromJson(Map json) { - return SingleModeInfo( - mode: EnumUtils.parseFromString( - SignMode.values, - json['mode'] as String, - ), - ); - } - - Map toJson() => { - 'mode': EnumUtils.parseToString(mode), - }; - - @override - List get props => [mode]; -} diff --git a/lib/infra/dto/api_kira/broadcast/request/transaction/components/signer_info.dart b/lib/infra/dto/api_kira/broadcast/request/transaction/components/signer_info.dart deleted file mode 100644 index 84f8e710..00000000 --- a/lib/infra/dto/api_kira/broadcast/request/transaction/components/signer_info.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:equatable/equatable.dart'; -import 'package:miro/infra/dto/api_kira/broadcast/request/transaction/components/mode_info/mode_info.dart'; -import 'package:miro/infra/dto/api_kira/broadcast/request/transaction/components/tx_pub_key.dart'; - -/// Describes the public key and signing mode of a single top-level signer. -/// -/// https://docs.cosmos.network/v0.44/core/proto-docs.html#cosmos.tx.v1beta1.SignerInfo -class SignerInfo extends Equatable { - /// The public key is optional for accounts that already exist in state. If unset, the - /// verifier can use the required signer address for this position and lookup the public key. - final TxPubKey publicKey; - - /// ModeInfo describes the signing mode of the signer and is a nested - /// structure to support nested multisign pubkey's - final ModeInfo modeInfo; - - /// sequence is the sequence of the account, which describes the - /// number of committed transactions signed by a given address. It is used to prevent - /// replay attacks. - final String sequence; - - const SignerInfo({ - required this.publicKey, - required this.modeInfo, - required this.sequence, - }); - - Map toJson() => { - 'public_key': publicKey.toJson(), - 'mode_info': modeInfo.toJson(), - 'sequence': sequence, - }; - - @override - List get props => [publicKey, modeInfo, sequence]; -} diff --git a/lib/infra/dto/api_kira/broadcast/request/transaction/components/tx_body.dart b/lib/infra/dto/api_kira/broadcast/request/transaction/components/tx_body.dart deleted file mode 100644 index 7e46cddb..00000000 --- a/lib/infra/dto/api_kira/broadcast/request/transaction/components/tx_body.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:equatable/equatable.dart'; -import 'package:miro/infra/dto/shared/messages/a_tx_msg.dart'; - -/// TxBody is the body of a transaction that all signers sign over -/// -/// https://docs.cosmos.network/v0.44/core/proto-docs.html#cosmos.tx.v1beta1.TxBody -class TxBody extends Equatable { - /// A list of messages to be executed. The required signers of those messages define - /// the number and order of elements in AuthInfo's signer_infos and Tx's signatures. - /// Each required signer address is added to the list only the first time it occurs. - /// - /// By convention, the first required signer (usually from the first message) is referred - /// to as the primary signer and pays the fee for the whole transaction. - final List messages; - - /// Arbitrary note/comment to be added to the transaction. - /// - /// WARNING: in clients, any publicly exposed text should not be called memo, - /// but should be called note instead (see https://github.com/cosmos/cosmos-sdk/issues/9122). - final String memo; - - /// Block height after which this transaction will not be processed by the chain - final String timeoutHeight; - - /// Arbitrary options that can be added by chains when the default options are not sufficient. - /// If any of these are present and can't be handled, the transaction will be rejected - final List? extensionOptions; - - /// Arbitrary options that can be added by chains when the default options are not sufficient. - /// If any of these are present and can't be handled, they will be ignored - final List? nonCriticalExtensionOptions; - - const TxBody({ - required this.messages, - required this.memo, - this.timeoutHeight = '0', - this.extensionOptions, - this.nonCriticalExtensionOptions, - }); - - Map toJson() => { - 'messages': messages.map((ATxMsg txMsg) => txMsg.toJsonWithType()).toList(), - 'memo': memo, - 'timeout_height': timeoutHeight, - 'extension_options': extensionOptions ?? [], - 'non_critical_extension_options': nonCriticalExtensionOptions ?? [], - }; - - @override - List get props => [messages, memo, timeoutHeight, extensionOptions, nonCriticalExtensionOptions]; -} diff --git a/lib/infra/dto/api_kira/broadcast/request/transaction/components/tx_fee.dart b/lib/infra/dto/api_kira/broadcast/request/transaction/components/tx_fee.dart deleted file mode 100644 index cba48229..00000000 --- a/lib/infra/dto/api_kira/broadcast/request/transaction/components/tx_fee.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:equatable/equatable.dart'; -import 'package:miro/infra/dto/shared/coin.dart'; - -/// Fee includes the amount of coins paid in fees and the maximum gas to be used by the transaction. -/// The ratio yields an effective "gasprice", which must be above some miminum to be accepted into the mempool. -/// -/// https://docs.cosmos.network/v0.44/core/proto-docs.html#cosmos.tx.v1beta1.Fee -class TxFee extends Equatable { - /// Amount of coins to be paid as a fee - final List amount; - - /// The maximum gas that can be used in transaction processing before an out of gas error occurs - // TODO(dominik): We do not use gas in Kira Network, but the backend requires this variable. Delete when not needed - final String gasLimit; - - const TxFee({ - required this.amount, - this.gasLimit = '999999', - }); - - Map toJson() => { - 'amount': amount.map((Coin e) => e.toJson()).toList(), - 'gas_limit': gasLimit, - }; - - Map toSignatureJson() => { - 'amount': amount.map((Coin e) => e.toJson()).toList(), - 'gas': gasLimit, - }; - - @override - List get props => [amount, gasLimit]; -} diff --git a/lib/infra/dto/api_kira/broadcast/request/transaction/components/tx_pub_key.dart b/lib/infra/dto/api_kira/broadcast/request/transaction/components/tx_pub_key.dart deleted file mode 100644 index 4f6fa561..00000000 --- a/lib/infra/dto/api_kira/broadcast/request/transaction/components/tx_pub_key.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:equatable/equatable.dart'; - -/// PubKey defines a secp256k1 public key Key is the compressed form of the pubkey. -/// The first byte depends is a 0x02 byte if the y-coordinate is the lexicographically -/// largest of the two associated with the x-coordinate. -/// Otherwise the first byte is a 0x03. This prefix is followed with the x-coordinate. -/// -/// https://docs.cosmos.network/v0.44/core/proto-docs.html#cosmos.crypto.secp256k1.PubKey -class TxPubKey extends Equatable { - /// Backend mapping class type - final String type = '/cosmos.crypto.secp256k1.PubKey'; - - /// Public key value - final String key; - - const TxPubKey({ - required this.key, - }); - - Map toJson() { - return { - '@type': type, - 'key': key, - }; - } - - @override - List get props => [type, key]; -} diff --git a/lib/infra/dto/api_kira/broadcast/request/transaction/std_sign_doc.dart b/lib/infra/dto/api_kira/broadcast/request/transaction/std_sign_doc.dart deleted file mode 100644 index 8b059199..00000000 --- a/lib/infra/dto/api_kira/broadcast/request/transaction/std_sign_doc.dart +++ /dev/null @@ -1,72 +0,0 @@ -import 'package:equatable/equatable.dart'; -import 'package:miro/infra/dto/api_kira/broadcast/request/transaction/components/tx_fee.dart'; -import 'package:miro/infra/dto/shared/coin.dart'; -import 'package:miro/infra/dto/shared/messages/a_tx_msg.dart'; -import 'package:miro/shared/models/transactions/tx_local_info_model.dart'; -import 'package:miro/shared/models/transactions/tx_remote_info_model.dart'; -import 'package:miro/shared/models/transactions/unsigned_tx_model.dart'; - -/// StdSignDoc is replay-prevention structure. -/// -/// https://docs.cosmos.network/master/core/transactions.html -class StdSignDoc extends Equatable { - /// The account number of the account in state - final String accountNumber; - - /// Sequence of the account, which describes the number - /// of committed transactions signed by a given address. - /// It is used to prevent replay attacks. - final String sequence; - - /// The unique identifier of the chain this transaction targets. - /// It prevents signed transactions from being used on another chain by an attacker - final String chainId; - - /// Any arbitrary note/comment to be added to the transaction. - final String memo; - - /// Fee includes the amount of coins paid in fees to be used by the transaction. - final TxFee fee; - - /// List of messages to be executed. - final List messages; - - const StdSignDoc({ - required this.accountNumber, - required this.sequence, - required this.chainId, - required this.memo, - required this.fee, - required this.messages, - }); - - factory StdSignDoc.fromUnsignedTxModel(UnsignedTxModel unsignedTxModel) { - TxRemoteInfoModel txRemoteInfoModel = unsignedTxModel.txRemoteInfoModel; - TxLocalInfoModel txLocalInfoModel = unsignedTxModel.txLocalInfoModel; - - return StdSignDoc( - accountNumber: txRemoteInfoModel.accountNumber, - sequence: txRemoteInfoModel.sequence, - chainId: txRemoteInfoModel.chainId, - memo: txLocalInfoModel.replacedMemo, - fee: TxFee( - amount: [Coin.fromTokenAmountModel(txLocalInfoModel.feeTokenAmountModel)], - ), - messages: [txLocalInfoModel.txMsgModel.toMsgDto()], - ); - } - - Map toSignatureJson() { - return { - 'account_number': accountNumber, - 'sequence': sequence, - 'chain_id': chainId, - 'memo': memo, - 'fee': fee.toSignatureJson(), - 'msgs': messages.map((ATxMsg txMsg) => txMsg.toSignatureJson()).toList(), - }; - } - - @override - List get props => [accountNumber, sequence, chainId, memo, fee, messages]; -} diff --git a/lib/infra/dto/api_kira/broadcast/request/transaction/tx.dart b/lib/infra/dto/api_kira/broadcast/request/transaction/tx.dart deleted file mode 100644 index c65ce4e2..00000000 --- a/lib/infra/dto/api_kira/broadcast/request/transaction/tx.dart +++ /dev/null @@ -1,73 +0,0 @@ -import 'package:equatable/equatable.dart'; -import 'package:miro/infra/dto/api_kira/broadcast/request/transaction/components/auth_info.dart'; -import 'package:miro/infra/dto/api_kira/broadcast/request/transaction/components/mode_info/mode_info.dart'; -import 'package:miro/infra/dto/api_kira/broadcast/request/transaction/components/mode_info/sign_mode.dart'; -import 'package:miro/infra/dto/api_kira/broadcast/request/transaction/components/mode_info/single_mode_info.dart'; -import 'package:miro/infra/dto/api_kira/broadcast/request/transaction/components/signer_info.dart'; -import 'package:miro/infra/dto/api_kira/broadcast/request/transaction/components/tx_body.dart'; -import 'package:miro/infra/dto/api_kira/broadcast/request/transaction/components/tx_fee.dart'; -import 'package:miro/infra/dto/api_kira/broadcast/request/transaction/components/tx_pub_key.dart'; -import 'package:miro/infra/dto/shared/coin.dart'; -import 'package:miro/infra/dto/shared/messages/a_tx_msg.dart'; -import 'package:miro/shared/models/transactions/signed_transaction_model.dart'; -import 'package:miro/shared/models/transactions/tx_local_info_model.dart'; -import 'package:miro/shared/models/transactions/tx_remote_info_model.dart'; - -/// Standard type used for broadcasting transactions. -/// -/// https://docs.cosmos.network/v0.44/core/proto-docs.html#cosmos.tx.v1beta1.Tx -class Tx extends Equatable { - /// Processable content of the transaction - final TxBody body; - - /// Authorization related content of the transaction, - /// specifically signers, signer modes and fee - final AuthInfo authInfo; - - /// List of signatures that matches the length and order of - /// AuthInfo's signer_infos to allow connecting signature meta information like - /// public key and signing mode by position. - final List signatures; - - const Tx({ - required this.body, - required this.authInfo, - required this.signatures, - }); - - factory Tx.fromSignedTxModel(SignedTxModel signedTxModel) { - TxLocalInfoModel txLocalInfoModel = signedTxModel.txLocalInfoModel; - TxRemoteInfoModel txRemoteInfoModel = signedTxModel.txRemoteInfoModel; - - SignerInfo signerInfo = SignerInfo( - publicKey: TxPubKey(key: signedTxModel.publicKeyCompressed), - modeInfo: const ModeInfo(single: SingleModeInfo(mode: SignMode.SIGN_MODE_LEGACY_AMINO_JSON)), - sequence: txRemoteInfoModel.sequence, - ); - - return Tx( - body: TxBody( - messages: [txLocalInfoModel.txMsgModel.toMsgDto()], - memo: txLocalInfoModel.replacedMemo, - ), - authInfo: AuthInfo( - signerInfos: [signerInfo], - fee: TxFee( - amount: [ - Coin.fromTokenAmountModel(txLocalInfoModel.feeTokenAmountModel), - ], - ), - ), - signatures: [signedTxModel.signatureModel.signature], - ); - } - - Map toJson() => { - 'body': body.toJson(), - 'auth_info': authInfo.toJson(), - 'signatures': signatures, - }; - - @override - List get props => [body, authInfo, signatures]; -} diff --git a/lib/infra/dto/shared/messages/a_tx_msg.dart b/lib/infra/dto/shared/messages/a_tx_msg.dart index 2cd522f8..d59e1624 100644 --- a/lib/infra/dto/shared/messages/a_tx_msg.dart +++ b/lib/infra/dto/shared/messages/a_tx_msg.dart @@ -1,4 +1,4 @@ -import 'package:equatable/equatable.dart'; +import 'package:codec_utils/codec_utils.dart'; import 'package:miro/infra/dto/shared/messages/identity_records/msg_cancel_identity_records_verify_request.dart'; import 'package:miro/infra/dto/shared/messages/identity_records/msg_delete_identity_records.dart'; import 'package:miro/infra/dto/shared/messages/identity_records/msg_handle_identity_records_verify_request.dart'; @@ -18,58 +18,37 @@ import 'package:miro/shared/models/transactions/messages/tx_msg_type.dart'; /// - Broadcast (as a transaction message used in request) /// Represents Msg interface from Kira SDK /// https://github.com/KiraCore/sekai/blob/master/types/Msg.go -abstract class ATxMsg extends Equatable { - final String _messageType; - final String _signatureMessageType; - +abstract class ATxMsg extends ProtobufAny { const ATxMsg({ - required String messageType, - required String signatureMessageType, - }) : _messageType = messageType, - _signatureMessageType = signatureMessageType; + required super.typeUrl, + }); static ATxMsg buildFromJson(Map json) { TxMsgType txMsgType = InterxMsgTypes.getType(json['type'] as String); switch (txMsgType) { case TxMsgType.msgCancelIdentityRecordsVerifyRequest: - return MsgCancelIdentityRecordsVerifyRequest.fromJson(json); + return MsgCancelIdentityRecordsVerifyRequest.fromData(json); case TxMsgType.msgClaimRewards: - return MsgClaimRewards.fromJson(json); + return MsgClaimRewards.fromData(json); case TxMsgType.msgClaimUndelegation: - return MsgClaimUndelegation.fromJson(json); + return MsgClaimUndelegation.fromData(json); case TxMsgType.msgDelegate: - return MsgDelegate.fromJson(json); + return MsgDelegate.fromData(json); case TxMsgType.msgDeleteIdentityRecords: - return MsgDeleteIdentityRecords.fromJson(json); + return MsgDeleteIdentityRecords.fromData(json); case TxMsgType.msgHandleIdentityRecordsVerifyRequest: - return MsgHandleIdentityRecordsVerifyRequest.fromJson(json); + return MsgHandleIdentityRecordsVerifyRequest.fromData(json); case TxMsgType.msgRegisterIdentityRecords: - return MsgRegisterIdentityRecords.fromJson(json); + return MsgRegisterIdentityRecords.fromData(json); case TxMsgType.msgRequestIdentityRecordsVerify: - return MsgRequestIdentityRecordsVerify.fromJson(json); + return MsgRequestIdentityRecordsVerify.fromData(json); case TxMsgType.msgSend: - return MsgSend.fromJson(json); + return MsgSend.fromData(json); case TxMsgType.msgUndelegate: - return MsgUndelegate.fromJson(json); + return MsgUndelegate.fromData(json); default: return const MsgUndefined(); } } - - Map toJson(); - - Map toJsonWithType() { - return { - '@type': _messageType, - ...toJson(), - }; - } - - Map toSignatureJson() { - return { - 'type': _signatureMessageType, - 'value': toJson(), - }; - } } diff --git a/lib/infra/dto/shared/messages/identity_records/msg_cancel_identity_records_verify_request.dart b/lib/infra/dto/shared/messages/identity_records/msg_cancel_identity_records_verify_request.dart index c9ab8fbc..1292922a 100644 --- a/lib/infra/dto/shared/messages/identity_records/msg_cancel_identity_records_verify_request.dart +++ b/lib/infra/dto/shared/messages/identity_records/msg_cancel_identity_records_verify_request.dart @@ -1,3 +1,7 @@ +import 'dart:typed_data'; + +import 'package:codec_utils/codec_utils.dart'; +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:miro/infra/dto/shared/messages/a_tx_msg.dart'; /// Proposal message to edit an identity record @@ -5,30 +9,36 @@ import 'package:miro/infra/dto/shared/messages/a_tx_msg.dart'; /// https://github.com/KiraCore/sekai/blob/master/proto/kira/gov/identity_registrar.proto class MsgCancelIdentityRecordsVerifyRequest extends ATxMsg { /// The address of requester - final String executor; + final CosmosAccAddress executor; /// The id of verification request final BigInt verifyRequestId; - const MsgCancelIdentityRecordsVerifyRequest({ + MsgCancelIdentityRecordsVerifyRequest({ required this.executor, required this.verifyRequestId, - }) : super( - messageType: '/kira.gov.MsgCancelIdentityRecordsVerifyRequest', - signatureMessageType: 'kiraHub/MsgCancelIdentityRecordsVerifyRequest', - ); + }) : super(typeUrl: '/kira.gov.MsgCancelIdentityRecordsVerifyRequest'); - factory MsgCancelIdentityRecordsVerifyRequest.fromJson(Map json) { + factory MsgCancelIdentityRecordsVerifyRequest.fromData(Map data) { return MsgCancelIdentityRecordsVerifyRequest( - executor: json['executor'] as String, - verifyRequestId: BigInt.from(json['verify_request_id'] as num), + executor: CosmosAccAddress(data['executor'] as String), + verifyRequestId: BigInt.from(data['verify_request_id'] as num), ); } @override - Map toJson() { + Uint8List toProtoBytes() { + return ProtobufEncoder.encode({ + 1: executor, + 2: ProtobufInt64(verifyRequestId), + }); + } + + @override + Map toProtoJson() { return { - 'executor': executor, + '@type': typeUrl, + 'executor': executor.value, 'verify_request_id': verifyRequestId.toString(), }; } diff --git a/lib/infra/dto/shared/messages/identity_records/msg_delete_identity_records.dart b/lib/infra/dto/shared/messages/identity_records/msg_delete_identity_records.dart index 5d2dff78..c2b716ff 100644 --- a/lib/infra/dto/shared/messages/identity_records/msg_delete_identity_records.dart +++ b/lib/infra/dto/shared/messages/identity_records/msg_delete_identity_records.dart @@ -1,3 +1,7 @@ +import 'dart:typed_data'; + +import 'package:codec_utils/codec_utils.dart'; +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:miro/infra/dto/shared/messages/a_tx_msg.dart'; /// Message to delete identity records owned by an address @@ -5,30 +9,36 @@ import 'package:miro/infra/dto/shared/messages/a_tx_msg.dart'; /// https://github.com/KiraCore/sekai/blob/master/proto/kira/gov/identity_registrar.proto class MsgDeleteIdentityRecords extends ATxMsg { /// The address for the identity record - final String address; + final CosmosAccAddress address; /// The array string that defines identity record key values to be deleted final List keys; - const MsgDeleteIdentityRecords({ + MsgDeleteIdentityRecords({ required this.address, required this.keys, - }) : super( - messageType: '/kira.gov.MsgDeleteIdentityRecords', - signatureMessageType: 'kiraHub/MsgDeleteIdentityRecords', - ); + }) : super(typeUrl: '/kira.gov.MsgDeleteIdentityRecords'); - factory MsgDeleteIdentityRecords.fromJson(Map json) { + factory MsgDeleteIdentityRecords.fromData(Map data) { return MsgDeleteIdentityRecords( - address: json['address'] as String, - keys: (json['keys'] as List).map((dynamic e) => e as String).toList(), + address: CosmosAccAddress(data['address'] as String), + keys: (data['keys'] as List).map((dynamic e) => e as String).toList(), ); } @override - Map toJson() { + Uint8List toProtoBytes() { + return ProtobufEncoder.encode({ + 1: address, + 2: ProtobufList(keys.map(ProtobufString.new).toList()), + }); + } + + @override + Map toProtoJson() { return { - 'address': address, + '@type': typeUrl, + 'address': address.value, 'keys': keys, }; } diff --git a/lib/infra/dto/shared/messages/identity_records/msg_handle_identity_records_verify_request.dart b/lib/infra/dto/shared/messages/identity_records/msg_handle_identity_records_verify_request.dart index d4d1d95a..50fe9f99 100644 --- a/lib/infra/dto/shared/messages/identity_records/msg_handle_identity_records_verify_request.dart +++ b/lib/infra/dto/shared/messages/identity_records/msg_handle_identity_records_verify_request.dart @@ -1,3 +1,7 @@ +import 'dart:typed_data'; + +import 'package:codec_utils/codec_utils.dart'; +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:miro/infra/dto/shared/messages/a_tx_msg.dart'; /// Proposal message to approve or reject an identity record request @@ -5,7 +9,7 @@ import 'package:miro/infra/dto/shared/messages/a_tx_msg.dart'; /// https://github.com/KiraCore/sekai/blob/master/proto/kira/gov/identity_registrar.proto class MsgHandleIdentityRecordsVerifyRequest extends ATxMsg { /// The address of verifier - final String verifier; + final CosmosAccAddress verifier; /// The id of verification request final int verifyRequestId; @@ -13,27 +17,34 @@ class MsgHandleIdentityRecordsVerifyRequest extends ATxMsg { /// Defines approval or rejecting an identity request final bool yes; - const MsgHandleIdentityRecordsVerifyRequest({ + MsgHandleIdentityRecordsVerifyRequest({ required this.verifier, required this.verifyRequestId, required this.yes, - }) : super( - messageType: '/kira.gov.MsgHandleIdentityRecordsVerifyRequest', - signatureMessageType: 'kiraHub/MsgHandleIdentityRecordsVerifyRequest', - ); + }) : super(typeUrl: '/kira.gov.MsgHandleIdentityRecordsVerifyRequest'); - factory MsgHandleIdentityRecordsVerifyRequest.fromJson(Map json) { + factory MsgHandleIdentityRecordsVerifyRequest.fromData(Map data) { return MsgHandleIdentityRecordsVerifyRequest( - verifier: json['verifier'] as String, - verifyRequestId: json['verify_request_id'] as int, - yes: json['yes'] as bool? ?? false, + verifier: CosmosAccAddress(data['verifier'] as String), + verifyRequestId: data['verify_request_id'] as int, + yes: data['yes'] as bool? ?? false, ); } @override - Map toJson() { + Uint8List toProtoBytes() { + return ProtobufEncoder.encode({ + 1: verifier, + 2: ProtobufInt32(verifyRequestId), + 3: ProtobufBool(yes), + }); + } + + @override + Map toProtoJson() { return { - 'verifier': verifier, + '@type': typeUrl, + 'verifier': verifier.value, 'verify_request_id': verifyRequestId.toString(), if (yes == true) 'yes': yes, }; diff --git a/lib/infra/dto/shared/messages/identity_records/msg_request_identity_records_verify.dart b/lib/infra/dto/shared/messages/identity_records/msg_request_identity_records_verify.dart index 36f8342b..2e33efa1 100644 --- a/lib/infra/dto/shared/messages/identity_records/msg_request_identity_records_verify.dart +++ b/lib/infra/dto/shared/messages/identity_records/msg_request_identity_records_verify.dart @@ -1,4 +1,7 @@ -import 'package:miro/infra/dto/shared/coin.dart'; +import 'dart:typed_data'; + +import 'package:codec_utils/codec_utils.dart'; +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:miro/infra/dto/shared/messages/a_tx_msg.dart'; /// Proposal message to request an identity record verification from a specific verifier @@ -6,46 +9,54 @@ import 'package:miro/infra/dto/shared/messages/a_tx_msg.dart'; /// https://github.com/KiraCore/sekai/blob/master/proto/kira/gov/identity_registrar.proto class MsgRequestIdentityRecordsVerify extends ATxMsg { /// The address of requester - final String address; + final CosmosAccAddress address; + + /// The address of verifier + final CosmosAccAddress verifier; /// The id of records to be verified - final List recordIds; + final List recordIds; /// The amount of coins to be given up-on accepting the request - final Coin tip; - - /// The address of verifier - final String verifier; + final CosmosCoin tip; - const MsgRequestIdentityRecordsVerify({ + MsgRequestIdentityRecordsVerify({ required this.address, + required this.verifier, required this.recordIds, required this.tip, - required this.verifier, - }) : super( - messageType: '/kira.gov.MsgRequestIdentityRecordsVerify', - signatureMessageType: 'kiraHub/MsgRequestIdentityRecordsVerify', - ); + }) : super(typeUrl: '/kira.gov.MsgRequestIdentityRecordsVerify'); - factory MsgRequestIdentityRecordsVerify.fromJson(Map json) { + factory MsgRequestIdentityRecordsVerify.fromData(Map data) { return MsgRequestIdentityRecordsVerify( - address: json['address'] as String, - recordIds: (json['record_ids'] as List).map((dynamic e) => BigInt.from(e as num)).toList(), - tip: Coin.fromJson(json['tip'] as Map), - verifier: json['verifier'] as String, + address: CosmosAccAddress(data['address'] as String), + verifier: CosmosAccAddress(data['verifier'] as String), + recordIds: (data['record_ids'] as List).map((dynamic e) => e as int).toList(), + tip: CosmosCoin.fromProtoJson(data['tip'] as Map), ); } @override - Map toJson() { + Uint8List toProtoBytes() { + return ProtobufEncoder.encode({ + 1: address, + 2: verifier, + 3: ProtobufBytes(recordIds), + 4: tip, + }); + } + + @override + Map toProtoJson() { return { - 'address': address, - 'record_ids': recordIds.map((BigInt recordId) => recordId.toString()).toList(), - 'tip': tip.toJson(), - 'verifier': verifier, + '@type': typeUrl, + 'address': address.value, + 'verifier': verifier.value, + 'record_ids': recordIds, + 'tip': tip.toProtoJson(), }; } @override - List get props => [address, recordIds, tip, verifier]; + List get props => [address, verifier, recordIds, tip]; } diff --git a/lib/infra/dto/shared/messages/identity_records/register/identity_info_entry.dart b/lib/infra/dto/shared/messages/identity_records/register/identity_info_entry.dart index 3f0a65ea..d5b754e2 100644 --- a/lib/infra/dto/shared/messages/identity_records/register/identity_info_entry.dart +++ b/lib/infra/dto/shared/messages/identity_records/register/identity_info_entry.dart @@ -1,9 +1,11 @@ -import 'package:equatable/equatable.dart'; +import 'dart:typed_data'; + +import 'package:codec_utils/codec_utils.dart'; /// Single identity record info. Used in MsgRegisterIdentityRecords /// Represents IdentityInfoEntry interface from Kira SDK: /// https://github.com/KiraCore/sekai/blob/master/proto/kira/gov/identity_registrar.proto -class IdentityInfoEntry extends Equatable { +class IdentityInfoEntry extends AProtobufObject { /// The key of the identity record final String key; @@ -15,14 +17,23 @@ class IdentityInfoEntry extends Equatable { required this.info, }); - factory IdentityInfoEntry.fromJson(Map json) { + factory IdentityInfoEntry.fromData(Map data) { return IdentityInfoEntry( - key: json['key'] as String, - info: json['info'] as String, + key: data['key'] as String, + info: data['info'] as String, ); } - Map toJson() { + @override + Uint8List toProtoBytes() { + return ProtobufEncoder.encode({ + 1: ProtobufString(key), + 2: ProtobufString(info), + }); + } + + @override + Map toProtoJson() { return { 'key': key, 'info': info, diff --git a/lib/infra/dto/shared/messages/identity_records/register/msg_register_identity_records.dart b/lib/infra/dto/shared/messages/identity_records/register/msg_register_identity_records.dart index 00232994..995aa243 100644 --- a/lib/infra/dto/shared/messages/identity_records/register/msg_register_identity_records.dart +++ b/lib/infra/dto/shared/messages/identity_records/register/msg_register_identity_records.dart @@ -1,3 +1,7 @@ +import 'dart:typed_data'; + +import 'package:codec_utils/codec_utils.dart'; +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:miro/infra/dto/shared/messages/a_tx_msg.dart'; import 'package:miro/infra/dto/shared/messages/identity_records/register/identity_info_entry.dart'; @@ -6,31 +10,37 @@ import 'package:miro/infra/dto/shared/messages/identity_records/register/identit /// https://github.com/KiraCore/sekai/blob/master/proto/kira/gov/identity_registrar.proto class MsgRegisterIdentityRecords extends ATxMsg { /// The address for the identity record - final String address; + final CosmosAccAddress address; /// The array of identity record info final List infos; - const MsgRegisterIdentityRecords({ + MsgRegisterIdentityRecords({ required this.address, required this.infos, - }) : super( - messageType: '/kira.gov.MsgRegisterIdentityRecords', - signatureMessageType: 'kiraHub/MsgRegisterIdentityRecords', - ); + }) : super(typeUrl: '/kira.gov.MsgRegisterIdentityRecords'); - factory MsgRegisterIdentityRecords.fromJson(Map json) { + factory MsgRegisterIdentityRecords.fromData(Map data) { return MsgRegisterIdentityRecords( - address: json['address'] as String, - infos: (json['infos'] as List).map((dynamic e) => IdentityInfoEntry.fromJson(e as Map)).toList(), + address: CosmosAccAddress(data['address'] as String), + infos: (data['infos'] as List).map((dynamic e) => IdentityInfoEntry.fromData(e as Map)).toList(), ); } @override - Map toJson() { + Uint8List toProtoBytes() { + return ProtobufEncoder.encode({ + 1: address, + 2: ProtobufList(infos), + }); + } + + @override + Map toProtoJson() { return { - 'address': address, - 'infos': infos.map((IdentityInfoEntry identityInfoEntry) => identityInfoEntry.toJson()).toList(), + '@type': typeUrl, + 'address': address.value, + 'infos': infos.map((IdentityInfoEntry identityInfoEntry) => identityInfoEntry.toProtoJson()).toList(), }; } diff --git a/lib/infra/dto/shared/messages/msg_send.dart b/lib/infra/dto/shared/messages/msg_send.dart index 6861d212..d9976e52 100644 --- a/lib/infra/dto/shared/messages/msg_send.dart +++ b/lib/infra/dto/shared/messages/msg_send.dart @@ -1,46 +1,47 @@ -import 'package:miro/infra/dto/shared/coin.dart'; +import 'dart:typed_data'; + +import 'package:codec_utils/codec_utils.dart'; +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:miro/infra/dto/shared/messages/a_tx_msg.dart'; -/// Message to send coins from one account to another -/// Represents MsgSend interface from Cosmos SDK: -/// https://github.com/cosmos/groups-ui/blob/master/src/generated/cosmos/bank/v1beta1/tx.ts class MsgSend extends ATxMsg { - /// Bech32 address of the sender. final String fromAddress; - - /// Bech32 address of the recipient. final String toAddress; + final List amount; - /// Coins that will be sent. - final List amount; - - /// Public constructor. - const MsgSend({ + MsgSend({ required this.fromAddress, required this.toAddress, required this.amount, - }) : super( - messageType: '/cosmos.bank.v1beta1.MsgSend', - signatureMessageType: 'cosmos-sdk/MsgSend', - ); + }) : super(typeUrl: '/cosmos.bank.v1beta1.MsgSend'); - factory MsgSend.fromJson(Map json) { + factory MsgSend.fromData(Map data) { return MsgSend( - fromAddress: json['from_address'] as String, - toAddress: json['to_address'] as String, - amount: (json['amount'] as List).map((dynamic e) => Coin.fromJson(e as Map)).toList(), + fromAddress: data['from_address'] as String, + toAddress: data['to_address'] as String, + amount: (data['amount'] as List).map((dynamic e) => CosmosCoin.fromProtoJson(e as Map)).toList(), ); } @override - Map toJson() { + Uint8List toProtoBytes() { + return ProtobufEncoder.encode({ + 1: ProtobufString(fromAddress), + 2: ProtobufString(toAddress), + 3: ProtobufList(amount), + }); + } + + @override + Map toProtoJson() { return { + '@type': typeUrl, 'from_address': fromAddress, 'to_address': toAddress, - 'amount': amount.map((Coin coin) => coin.toJson()).toList(), + 'amount': amount.map((CosmosCoin coin) => coin.toProtoJson()).toList(), }; } @override - List get props => [fromAddress, toAddress, amount]; + List get props => [fromAddress, toAddress, amount]; } diff --git a/lib/infra/dto/shared/messages/msg_undefined.dart b/lib/infra/dto/shared/messages/msg_undefined.dart index b90b1832..30e56e3b 100644 --- a/lib/infra/dto/shared/messages/msg_undefined.dart +++ b/lib/infra/dto/shared/messages/msg_undefined.dart @@ -1,16 +1,15 @@ +import 'dart:typed_data'; + import 'package:miro/infra/dto/shared/messages/a_tx_msg.dart'; class MsgUndefined extends ATxMsg { - const MsgUndefined() - : super( - messageType: '', - signatureMessageType: '', - ); + const MsgUndefined() : super(typeUrl: ''); + + @override + Map toProtoJson() => {}; @override - Map toJson() { - return {}; - } + Uint8List toProtoBytes() => Uint8List(0); @override List get props => []; diff --git a/lib/infra/dto/shared/messages/staking/msg_claim_rewards.dart b/lib/infra/dto/shared/messages/staking/msg_claim_rewards.dart index e3346de1..f2032704 100644 --- a/lib/infra/dto/shared/messages/staking/msg_claim_rewards.dart +++ b/lib/infra/dto/shared/messages/staking/msg_claim_rewards.dart @@ -1,22 +1,30 @@ +import 'dart:typed_data'; + +import 'package:codec_utils/codec_utils.dart'; import 'package:miro/infra/dto/shared/messages/a_tx_msg.dart'; class MsgClaimRewards extends ATxMsg { final String sender; - const MsgClaimRewards({ + MsgClaimRewards({ required this.sender, - }) : super( - messageType: '/kira.multistaking.MsgClaimRewards', - signatureMessageType: 'kiraHub/MsgClaimRewards', - ); + }) : super(typeUrl: '/kira.multistaking.MsgClaimRewards'); + + factory MsgClaimRewards.fromData(Map data) { + return MsgClaimRewards(sender: data['sender'] as String); + } - factory MsgClaimRewards.fromJson(Map json) { - return MsgClaimRewards(sender: json['sender'] as String); + @override + Uint8List toProtoBytes() { + return ProtobufEncoder.encode({ + 1: ProtobufString(sender), + }); } @override - Map toJson() { + Map toProtoJson() { return { + '@type': typeUrl, 'sender': sender, }; } diff --git a/lib/infra/dto/shared/messages/staking/msg_claim_undelegation.dart b/lib/infra/dto/shared/messages/staking/msg_claim_undelegation.dart index cc6cd310..a64c4489 100644 --- a/lib/infra/dto/shared/messages/staking/msg_claim_undelegation.dart +++ b/lib/infra/dto/shared/messages/staking/msg_claim_undelegation.dart @@ -1,29 +1,38 @@ +import 'dart:typed_data'; + +import 'package:codec_utils/codec_utils.dart'; import 'package:miro/infra/dto/shared/messages/a_tx_msg.dart'; class MsgClaimUndelegation extends ATxMsg { final String sender; - final String undelegationId; + final BigInt undelegationId; - const MsgClaimUndelegation({ + MsgClaimUndelegation({ required this.sender, required this.undelegationId, - }) : super( - messageType: '/kira.multistaking.MsgClaimUndelegation', - signatureMessageType: 'kiraHub/MsgClaimUndelegation', - ); + }) : super(typeUrl: '/kira.multistaking.MsgClaimUndelegation'); - factory MsgClaimUndelegation.fromJson(Map json) { + factory MsgClaimUndelegation.fromData(Map data) { return MsgClaimUndelegation( - sender: json['sender'] as String, - undelegationId: (json['undelegation_id'] as int).toString(), + sender: data['sender'] as String, + undelegationId: BigInt.from(data['undelegation_id'] as int), ); } @override - Map toJson() { + Uint8List toProtoBytes() { + return ProtobufEncoder.encode({ + 1: ProtobufString(sender), + 2: ProtobufInt64(undelegationId), + }); + } + + @override + Map toProtoJson() { return { + '@type': typeUrl, 'sender': sender, - 'undelegation_id': undelegationId, + 'undelegation_id': undelegationId.toString(), }; } diff --git a/lib/infra/dto/shared/messages/staking/msg_delegate.dart b/lib/infra/dto/shared/messages/staking/msg_delegate.dart index df7c4bea..5b104a9d 100644 --- a/lib/infra/dto/shared/messages/staking/msg_delegate.dart +++ b/lib/infra/dto/shared/messages/staking/msg_delegate.dart @@ -1,34 +1,44 @@ -import 'package:miro/infra/dto/shared/coin.dart'; +import 'dart:typed_data'; + +import 'package:codec_utils/codec_utils.dart'; +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:miro/infra/dto/shared/messages/a_tx_msg.dart'; class MsgDelegate extends ATxMsg { final String delegatorAddress; final String valoperAddress; - final List amounts; + final List amounts; - const MsgDelegate({ + MsgDelegate({ required this.delegatorAddress, required this.valoperAddress, required this.amounts, - }) : super( - messageType: '/kira.multistaking.MsgDelegate', - signatureMessageType: 'kiraHub/MsgDelegate', - ); + }) : super(typeUrl: '/kira.multistaking.MsgDelegate'); - factory MsgDelegate.fromJson(Map json) { + factory MsgDelegate.fromData(Map data) { return MsgDelegate( - delegatorAddress: json['delegator_address'] as String, - valoperAddress: json['validator_address'] as String, - amounts: (json['amounts'] as List).map((dynamic e) => Coin.fromJson(e as Map)).toList(), + delegatorAddress: data['delegator_address'] as String, + valoperAddress: data['validator_address'] as String, + amounts: (data['amounts'] as List).map((dynamic e) => CosmosCoin.fromProtoJson(e as Map)).toList(), ); } @override - Map toJson() { + Uint8List toProtoBytes() { + return ProtobufEncoder.encode({ + 1: ProtobufString(delegatorAddress), + 2: ProtobufString(valoperAddress), + 3: ProtobufList(amounts), + }); + } + + @override + Map toProtoJson() { return { + '@type': typeUrl, 'delegator_address': delegatorAddress, 'validator_address': valoperAddress, - 'amounts': amounts.map((Coin coin) => coin.toJson()).toList(), + 'amounts': amounts.map((CosmosCoin cosmosCoin) => cosmosCoin.toProtoJson()).toList(), }; } diff --git a/lib/infra/dto/shared/messages/staking/msg_undelegate.dart b/lib/infra/dto/shared/messages/staking/msg_undelegate.dart index 01a1cbca..be7ccddb 100644 --- a/lib/infra/dto/shared/messages/staking/msg_undelegate.dart +++ b/lib/infra/dto/shared/messages/staking/msg_undelegate.dart @@ -1,34 +1,44 @@ -import 'package:miro/infra/dto/shared/coin.dart'; +import 'dart:typed_data'; + +import 'package:codec_utils/codec_utils.dart'; +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:miro/infra/dto/shared/messages/a_tx_msg.dart'; class MsgUndelegate extends ATxMsg { final String delegatorAddress; final String valoperAddress; - final List amounts; + final List amounts; - const MsgUndelegate({ + MsgUndelegate({ required this.delegatorAddress, required this.valoperAddress, required this.amounts, - }) : super( - messageType: '/kira.multistaking.MsgUndelegate', - signatureMessageType: 'kiraHub/MsgUndelegate', - ); + }) : super(typeUrl: '/kira.multistaking.MsgUndelegate'); - factory MsgUndelegate.fromJson(Map json) { + factory MsgUndelegate.fromData(Map data) { return MsgUndelegate( - delegatorAddress: json['delegator_address'] as String, - valoperAddress: json['validator_address'] as String, - amounts: (json['amounts'] as List).map((dynamic e) => Coin.fromJson(e as Map)).toList(), + delegatorAddress: data['delegator_address'] as String, + valoperAddress: data['validator_address'] as String, + amounts: (data['amounts'] as List).map((dynamic e) => CosmosCoin.fromProtoJson(e as Map)).toList(), ); } @override - Map toJson() { + Uint8List toProtoBytes() { + return ProtobufEncoder.encode({ + 1: ProtobufString(delegatorAddress), + 2: ProtobufString(valoperAddress), + 3: ProtobufList(amounts), + }); + } + + @override + Map toProtoJson() { return { + '@type': typeUrl, 'delegator_address': delegatorAddress, 'validator_address': valoperAddress, - 'amounts': amounts.map((Coin coin) => coin.toJson()).toList(), + 'amounts': amounts.map((CosmosCoin cosmosCoin) => cosmosCoin.toProtoJson()).toList(), }; } diff --git a/lib/infra/services/api_kira/broadcast_service.dart b/lib/infra/services/api_kira/broadcast_service.dart index c9cb4dd7..f81e2180 100644 --- a/lib/infra/services/api_kira/broadcast_service.dart +++ b/lib/infra/services/api_kira/broadcast_service.dart @@ -2,7 +2,6 @@ import 'package:dio/dio.dart'; import 'package:miro/blocs/generic/network_module/network_module_bloc.dart'; import 'package:miro/config/locator.dart'; import 'package:miro/infra/dto/api_kira/broadcast/request/broadcast_req.dart'; -import 'package:miro/infra/dto/api_kira/broadcast/request/transaction/tx.dart'; import 'package:miro/infra/dto/api_kira/broadcast/response/broadcast_resp.dart'; import 'package:miro/infra/exceptions/dio_parse_exception.dart'; import 'package:miro/infra/exceptions/tx_broadcast_exception.dart'; @@ -24,7 +23,7 @@ class BroadcastService implements _IBroadcastService { Uri networkUri = globalLocator().state.networkUri; Response response = await _apiKiraRepository.broadcast(ApiRequestModel( networkUri: networkUri, - requestData: BroadcastReq(tx: Tx.fromSignedTxModel(signedTransactionModel)), + requestData: BroadcastReq(tx: signedTransactionModel.signedCosmosTx), )); late BroadcastRespModel broadcastRespModel; diff --git a/lib/shared/models/keyfile/decrypted_keyfile_model.dart b/lib/shared/models/keyfile/decrypted_keyfile_model.dart index 023108d5..bce6ba0d 100644 --- a/lib/shared/models/keyfile/decrypted_keyfile_model.dart +++ b/lib/shared/models/keyfile/decrypted_keyfile_model.dart @@ -1,6 +1,6 @@ import 'dart:convert'; -import 'dart:typed_data'; +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:equatable/equatable.dart'; import 'package:hex/hex.dart'; import 'package:miro/shared/entity/keyfile/keyfile_entity.dart'; @@ -8,7 +8,6 @@ import 'package:miro/shared/entity/keyfile/keyfile_secret_data_entity.dart'; import 'package:miro/shared/models/keyfile/keyfile_secret_data_model.dart'; import 'package:miro/shared/models/wallet/wallet.dart'; import 'package:miro/shared/utils/cryptography/aes256.dart'; -import 'package:miro/shared/utils/cryptography/secp256k1.dart'; class DecryptedKeyfileModel extends Equatable { static String latestKeyfileVersion = '2.0.0'; @@ -21,16 +20,15 @@ class DecryptedKeyfileModel extends Equatable { }); String buildFileContent(String password) { + ECPrivateKey ecPrivateKey = keyfileSecretDataModel.wallet.ecPrivateKey; KeyfileSecretDataEntity keyfileSecretDataEntity = KeyfileSecretDataEntity( - privateKey: HEX.encode(keyfileSecretDataModel.wallet.privateKey), + privateKey: HEX.encode(ecPrivateKey.bytes), ); String secretData = Aes256.encrypt(password, jsonEncode(keyfileSecretDataEntity.toJson())); - Uint8List publicKeyBytes = Secp256k1.privateKeyBytesToPublic(keyfileSecretDataModel.wallet.privateKey); - KeyfileEntity keyfileEntity = KeyfileEntity( version: latestKeyfileVersion, - publicKey: base64Encode(publicKeyBytes), + publicKey: base64Encode(ecPrivateKey.ecPublicKey.compressed), secretData: secretData, ); diff --git a/lib/shared/models/keyfile/encrypted_keyfile_model.dart b/lib/shared/models/keyfile/encrypted_keyfile_model.dart index 13df6329..4810b930 100644 --- a/lib/shared/models/keyfile/encrypted_keyfile_model.dart +++ b/lib/shared/models/keyfile/encrypted_keyfile_model.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'dart:typed_data'; +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:equatable/equatable.dart'; import 'package:hex/hex.dart'; import 'package:miro/shared/entity/keyfile/keyfile_entity.dart'; @@ -51,7 +52,7 @@ class EncryptedKeyfileModel extends Equatable { keyfileSecretDataModel: KeyfileSecretDataModel( wallet: Wallet( address: WalletAddress.fromPublicKey(publicKey), - privateKey: Uint8List.fromList(HEX.decode(keyfileSecretDataEntity.privateKey)), + ecPrivateKey: ECPrivateKey.fromBytes(HEX.decode(keyfileSecretDataEntity.privateKey), CurvePoints.generatorSecp256k1), ), ), ); diff --git a/lib/shared/models/transactions/form_models/ir_msg_request_verification_form_model.dart b/lib/shared/models/transactions/form_models/ir_msg_request_verification_form_model.dart index 3472d219..c3f7986b 100644 --- a/lib/shared/models/transactions/form_models/ir_msg_request_verification_form_model.dart +++ b/lib/shared/models/transactions/form_models/ir_msg_request_verification_form_model.dart @@ -43,8 +43,8 @@ class IRMsgRequestVerificationFormModel extends AMsgFormModel { walletAddress: _requesterWalletAddress!, verifierWalletAddress: _verifierWalletAddress!, tipTokenAmountModel: _tipTokenAmountModel!, - recordIds: [ - BigInt.parse(_irRecordModel.id), + recordIds: [ + int.parse(_irRecordModel.id), ], ); } diff --git a/lib/shared/models/transactions/messages/identity_registrar/ir_msg_cancel_verification_request_model.dart b/lib/shared/models/transactions/messages/identity_registrar/ir_msg_cancel_verification_request_model.dart index 1be2586e..838609d9 100644 --- a/lib/shared/models/transactions/messages/identity_registrar/ir_msg_cancel_verification_request_model.dart +++ b/lib/shared/models/transactions/messages/identity_registrar/ir_msg_cancel_verification_request_model.dart @@ -1,3 +1,4 @@ +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:flutter/material.dart'; import 'package:miro/generated/l10n.dart'; import 'package:miro/infra/dto/shared/messages/identity_records/msg_cancel_identity_records_verify_request.dart'; @@ -19,14 +20,14 @@ class IRMsgCancelVerificationRequestModel extends ATxMsgModel { factory IRMsgCancelVerificationRequestModel.fromDto(MsgCancelIdentityRecordsVerifyRequest msgCancelIdentityRecordsVerifyRequest) { return IRMsgCancelVerificationRequestModel( verifyRequestId: msgCancelIdentityRecordsVerifyRequest.verifyRequestId, - walletAddress: WalletAddress.fromBech32(msgCancelIdentityRecordsVerifyRequest.executor), + walletAddress: WalletAddress.fromBech32(msgCancelIdentityRecordsVerifyRequest.executor.value), ); } @override MsgCancelIdentityRecordsVerifyRequest toMsgDto() { return MsgCancelIdentityRecordsVerifyRequest( - executor: walletAddress.bech32Address, + executor: CosmosAccAddress(walletAddress.bech32Address), verifyRequestId: verifyRequestId, ); } diff --git a/lib/shared/models/transactions/messages/identity_registrar/ir_msg_delete_records_model.dart b/lib/shared/models/transactions/messages/identity_registrar/ir_msg_delete_records_model.dart index df411623..d6a51be0 100644 --- a/lib/shared/models/transactions/messages/identity_registrar/ir_msg_delete_records_model.dart +++ b/lib/shared/models/transactions/messages/identity_registrar/ir_msg_delete_records_model.dart @@ -1,3 +1,4 @@ +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:flutter/material.dart'; import 'package:miro/generated/l10n.dart'; import 'package:miro/infra/dto/shared/messages/identity_records/msg_delete_identity_records.dart'; @@ -25,7 +26,7 @@ class IRMsgDeleteRecordsModel extends ATxMsgModel { factory IRMsgDeleteRecordsModel.fromDto(MsgDeleteIdentityRecords msgDeleteIdentityRecords) { return IRMsgDeleteRecordsModel( keys: msgDeleteIdentityRecords.keys, - walletAddress: WalletAddress.fromBech32(msgDeleteIdentityRecords.address), + walletAddress: WalletAddress.fromBech32(msgDeleteIdentityRecords.address.value), ); } @@ -33,7 +34,7 @@ class IRMsgDeleteRecordsModel extends ATxMsgModel { MsgDeleteIdentityRecords toMsgDto() { return MsgDeleteIdentityRecords( keys: keys, - address: walletAddress.bech32Address, + address: CosmosAccAddress(walletAddress.bech32Address), ); } diff --git a/lib/shared/models/transactions/messages/identity_registrar/ir_msg_handle_verification_request_model.dart b/lib/shared/models/transactions/messages/identity_registrar/ir_msg_handle_verification_request_model.dart index d5af1694..04ffcd55 100644 --- a/lib/shared/models/transactions/messages/identity_registrar/ir_msg_handle_verification_request_model.dart +++ b/lib/shared/models/transactions/messages/identity_registrar/ir_msg_handle_verification_request_model.dart @@ -1,3 +1,4 @@ +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:flutter/material.dart'; import 'package:miro/generated/l10n.dart'; import 'package:miro/infra/dto/shared/messages/identity_records/msg_handle_identity_records_verify_request.dart'; @@ -22,7 +23,7 @@ class IRMsgHandleVerificationRequestModel extends ATxMsgModel { return IRMsgHandleVerificationRequestModel( approvalStatusBool: msgHandleIdentityRecordsVerifyRequest.yes, verifyRequestId: msgHandleIdentityRecordsVerifyRequest.verifyRequestId.toString(), - walletAddress: WalletAddress.fromBech32(msgHandleIdentityRecordsVerifyRequest.verifier), + walletAddress: WalletAddress.fromBech32(msgHandleIdentityRecordsVerifyRequest.verifier.value), ); } @@ -30,7 +31,7 @@ class IRMsgHandleVerificationRequestModel extends ATxMsgModel { MsgHandleIdentityRecordsVerifyRequest toMsgDto() { return MsgHandleIdentityRecordsVerifyRequest( verifyRequestId: int.parse(verifyRequestId), - verifier: walletAddress.bech32Address, + verifier: CosmosAccAddress(walletAddress.bech32Address), yes: approvalStatusBool, ); } diff --git a/lib/shared/models/transactions/messages/identity_registrar/ir_msg_request_verification_model.dart b/lib/shared/models/transactions/messages/identity_registrar/ir_msg_request_verification_model.dart index f7162e24..1f7e0563 100644 --- a/lib/shared/models/transactions/messages/identity_registrar/ir_msg_request_verification_model.dart +++ b/lib/shared/models/transactions/messages/identity_registrar/ir_msg_request_verification_model.dart @@ -1,7 +1,7 @@ +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:decimal/decimal.dart'; import 'package:flutter/material.dart'; import 'package:miro/generated/l10n.dart'; -import 'package:miro/infra/dto/shared/coin.dart'; import 'package:miro/infra/dto/shared/messages/identity_records/msg_request_identity_records_verify.dart'; import 'package:miro/shared/models/tokens/prefixed_token_amount_model.dart'; import 'package:miro/shared/models/tokens/token_alias_model.dart'; @@ -13,7 +13,7 @@ import 'package:miro/shared/models/transactions/messages/tx_msg_type.dart'; import 'package:miro/shared/models/wallet/wallet_address.dart'; class IRMsgRequestVerificationModel extends ATxMsgModel { - final List recordIds; + final List recordIds; final TokenAmountModel tipTokenAmountModel; final WalletAddress verifierWalletAddress; final WalletAddress walletAddress; @@ -26,32 +26,35 @@ class IRMsgRequestVerificationModel extends ATxMsgModel { }) : super(txMsgType: TxMsgType.msgRequestIdentityRecordsVerify); IRMsgRequestVerificationModel.single({ - required BigInt recordId, + required int recordId, required this.tipTokenAmountModel, required this.verifierWalletAddress, required this.walletAddress, - }) : recordIds = [recordId], + }) : recordIds = [recordId], super(txMsgType: TxMsgType.msgRequestIdentityRecordsVerify); factory IRMsgRequestVerificationModel.fromDto(MsgRequestIdentityRecordsVerify msgRequestIdentityRecordsVerify) { return IRMsgRequestVerificationModel( recordIds: msgRequestIdentityRecordsVerify.recordIds, tipTokenAmountModel: TokenAmountModel( - defaultDenominationAmount: Decimal.parse(msgRequestIdentityRecordsVerify.tip.amount), + defaultDenominationAmount: Decimal.fromBigInt(msgRequestIdentityRecordsVerify.tip.amount), tokenAliasModel: TokenAliasModel.local(msgRequestIdentityRecordsVerify.tip.denom), ), - verifierWalletAddress: WalletAddress.fromBech32(msgRequestIdentityRecordsVerify.verifier), - walletAddress: WalletAddress.fromBech32(msgRequestIdentityRecordsVerify.address), + verifierWalletAddress: WalletAddress.fromBech32(msgRequestIdentityRecordsVerify.verifier.value), + walletAddress: WalletAddress.fromBech32(msgRequestIdentityRecordsVerify.address.value), ); } @override MsgRequestIdentityRecordsVerify toMsgDto() { return MsgRequestIdentityRecordsVerify( - address: walletAddress.bech32Address, + address: CosmosAccAddress(walletAddress.bech32Address), + verifier: CosmosAccAddress(verifierWalletAddress.bech32Address), recordIds: recordIds, - tip: Coin.fromTokenAmountModel(tipTokenAmountModel), - verifier: verifierWalletAddress.bech32Address, + tip: CosmosCoin( + denom: tipTokenAmountModel.tokenAliasModel.defaultTokenDenominationModel.name, + amount: tipTokenAmountModel.getAmountInDefaultDenomination().toBigInt(), + ), ); } diff --git a/lib/shared/models/transactions/messages/identity_registrar/register/ir_msg_register_records_model.dart b/lib/shared/models/transactions/messages/identity_registrar/register/ir_msg_register_records_model.dart index 95610c94..5cdf0b7c 100644 --- a/lib/shared/models/transactions/messages/identity_registrar/register/ir_msg_register_records_model.dart +++ b/lib/shared/models/transactions/messages/identity_registrar/register/ir_msg_register_records_model.dart @@ -1,3 +1,4 @@ +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:flutter/material.dart'; import 'package:miro/generated/l10n.dart'; import 'package:miro/infra/dto/shared/messages/identity_records/register/msg_register_identity_records.dart'; @@ -26,14 +27,14 @@ class IRMsgRegisterRecordsModel extends ATxMsgModel { factory IRMsgRegisterRecordsModel.fromDto(MsgRegisterIdentityRecords msgRegisterIdentityRecords) { return IRMsgRegisterRecordsModel( irEntryModels: msgRegisterIdentityRecords.infos.map(IREntryModel.fromDto).toList(), - walletAddress: WalletAddress.fromBech32(msgRegisterIdentityRecords.address), + walletAddress: WalletAddress.fromBech32(msgRegisterIdentityRecords.address.value), ); } @override MsgRegisterIdentityRecords toMsgDto() { return MsgRegisterIdentityRecords( - address: walletAddress.bech32Address, + address: CosmosAccAddress(walletAddress.bech32Address), infos: irEntryModels.map((IREntryModel irEntryModel) => irEntryModel.toDto()).toList(), ); } diff --git a/lib/shared/models/transactions/messages/msg_send_model.dart b/lib/shared/models/transactions/messages/msg_send_model.dart index 93280551..435b6f9c 100644 --- a/lib/shared/models/transactions/messages/msg_send_model.dart +++ b/lib/shared/models/transactions/messages/msg_send_model.dart @@ -1,10 +1,10 @@ import 'dart:math'; +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:decimal/decimal.dart'; import 'package:flutter/material.dart'; import 'package:miro/config/app_icons.dart'; import 'package:miro/generated/l10n.dart'; -import 'package:miro/infra/dto/shared/coin.dart'; import 'package:miro/infra/dto/shared/messages/msg_send.dart'; import 'package:miro/shared/models/tokens/prefixed_token_amount_model.dart'; import 'package:miro/shared/models/tokens/token_alias_model.dart'; @@ -31,7 +31,7 @@ class MsgSendModel extends ATxMsgModel { fromWalletAddress: WalletAddress.fromBech32(msgSend.fromAddress), toWalletAddress: WalletAddress.fromBech32(msgSend.toAddress), tokenAmountModel: TokenAmountModel( - defaultDenominationAmount: Decimal.parse(msgSend.amount.first.amount), + defaultDenominationAmount: Decimal.fromBigInt(msgSend.amount.first.amount), tokenAliasModel: TokenAliasModel.local(msgSend.amount.first.denom), ), ); @@ -42,10 +42,10 @@ class MsgSendModel extends ATxMsgModel { return MsgSend( fromAddress: fromWalletAddress.bech32Address, toAddress: toWalletAddress.bech32Address, - amount: [ - Coin( + amount: [ + CosmosCoin( denom: tokenAmountModel.tokenAliasModel.defaultTokenDenominationModel.name, - amount: tokenAmountModel.getAmountInDefaultDenomination().toString(), + amount: tokenAmountModel.getAmountInDefaultDenomination().toBigInt(), ), ], ); diff --git a/lib/shared/models/transactions/messages/staking/staking_msg_claim_undelegation_model.dart b/lib/shared/models/transactions/messages/staking/staking_msg_claim_undelegation_model.dart index 8b3c7da6..0f39c696 100644 --- a/lib/shared/models/transactions/messages/staking/staking_msg_claim_undelegation_model.dart +++ b/lib/shared/models/transactions/messages/staking/staking_msg_claim_undelegation_model.dart @@ -20,7 +20,7 @@ class StakingMsgClaimUndelegationModel extends ATxMsgModel { factory StakingMsgClaimUndelegationModel.fromMsgDto(MsgClaimUndelegation msgClaimUndelegation) { return StakingMsgClaimUndelegationModel( senderWalletAddress: WalletAddress.fromBech32(msgClaimUndelegation.sender), - undelegationId: msgClaimUndelegation.undelegationId, + undelegationId: msgClaimUndelegation.undelegationId.toString(), ); } @@ -28,7 +28,7 @@ class StakingMsgClaimUndelegationModel extends ATxMsgModel { ATxMsg toMsgDto() { return MsgClaimUndelegation( sender: senderWalletAddress.bech32Address, - undelegationId: undelegationId, + undelegationId: BigInt.parse(undelegationId), ); } diff --git a/lib/shared/models/transactions/messages/staking/staking_msg_delegate_model.dart b/lib/shared/models/transactions/messages/staking/staking_msg_delegate_model.dart index e8f9349d..8169ba4f 100644 --- a/lib/shared/models/transactions/messages/staking/staking_msg_delegate_model.dart +++ b/lib/shared/models/transactions/messages/staking/staking_msg_delegate_model.dart @@ -1,7 +1,7 @@ +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:decimal/decimal.dart'; import 'package:flutter/material.dart'; import 'package:miro/generated/l10n.dart'; -import 'package:miro/infra/dto/shared/coin.dart'; import 'package:miro/infra/dto/shared/messages/a_tx_msg.dart'; import 'package:miro/infra/dto/shared/messages/staking/msg_delegate.dart'; import 'package:miro/shared/models/tokens/prefixed_token_amount_model.dart'; @@ -36,8 +36,8 @@ class StakingMsgDelegateModel extends ATxMsgModel { valkey: msgDelegate.valoperAddress, delegatorWalletAddress: WalletAddress.fromBech32(msgDelegate.delegatorAddress), tokenAmountModels: msgDelegate.amounts - .map((Coin coin) => TokenAmountModel( - defaultDenominationAmount: Decimal.parse(coin.amount), + .map((CosmosCoin coin) => TokenAmountModel( + defaultDenominationAmount: Decimal.fromBigInt(coin.amount), tokenAliasModel: TokenAliasModel.local(coin.denom), )) .toList(), @@ -50,9 +50,9 @@ class StakingMsgDelegateModel extends ATxMsgModel { delegatorAddress: delegatorWalletAddress.bech32Address, valoperAddress: valkey, amounts: tokenAmountModels.map((TokenAmountModel tokenAmountModel) { - return Coin( + return CosmosCoin( denom: tokenAmountModel.tokenAliasModel.defaultTokenDenominationModel.name, - amount: tokenAmountModel.getAmountInDefaultDenomination().toString(), + amount: tokenAmountModel.getAmountInDefaultDenomination().toBigInt(), ); }).toList(), ); diff --git a/lib/shared/models/transactions/messages/staking/staking_msg_undelegate_model.dart b/lib/shared/models/transactions/messages/staking/staking_msg_undelegate_model.dart index 271dc6f4..09f91a60 100644 --- a/lib/shared/models/transactions/messages/staking/staking_msg_undelegate_model.dart +++ b/lib/shared/models/transactions/messages/staking/staking_msg_undelegate_model.dart @@ -1,7 +1,7 @@ +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:decimal/decimal.dart'; import 'package:flutter/material.dart'; import 'package:miro/generated/l10n.dart'; -import 'package:miro/infra/dto/shared/coin.dart'; import 'package:miro/infra/dto/shared/messages/a_tx_msg.dart'; import 'package:miro/infra/dto/shared/messages/staking/msg_undelegate.dart'; import 'package:miro/shared/models/tokens/prefixed_token_amount_model.dart'; @@ -36,8 +36,8 @@ class StakingMsgUndelegateModel extends ATxMsgModel { valkey: msgUndelegate.valoperAddress, delegatorWalletAddress: WalletAddress.fromBech32(msgUndelegate.delegatorAddress), tokenAmountModels: msgUndelegate.amounts - .map((Coin coin) => TokenAmountModel( - defaultDenominationAmount: Decimal.parse(coin.amount), + .map((CosmosCoin coin) => TokenAmountModel( + defaultDenominationAmount: Decimal.fromBigInt(coin.amount), tokenAliasModel: TokenAliasModel.local(coin.denom), )) .toList(), @@ -50,9 +50,9 @@ class StakingMsgUndelegateModel extends ATxMsgModel { delegatorAddress: delegatorWalletAddress.bech32Address, valoperAddress: valkey, amounts: tokenAmountModels.map((TokenAmountModel tokenAmountModel) { - return Coin( + return CosmosCoin( denom: tokenAmountModel.tokenAliasModel.defaultTokenDenominationModel.name, - amount: tokenAmountModel.getAmountInDefaultDenomination().toString(), + amount: tokenAmountModel.getAmountInDefaultDenomination().toBigInt(), ); }).toList(), ); diff --git a/lib/shared/models/transactions/signature_model.dart b/lib/shared/models/transactions/signature_model.dart deleted file mode 100644 index b385660a..00000000 --- a/lib/shared/models/transactions/signature_model.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'dart:convert'; -import 'dart:typed_data'; - -import 'package:equatable/equatable.dart'; -import 'package:miro/shared/utils/crypto_address_parser.dart'; -import 'package:pointycastle/export.dart'; - -class SignatureModel extends Equatable { - final String signature; - - const SignatureModel({ - required this.signature, - }); - - factory SignatureModel.fromBytes(Uint8List signatureBytes) { - return SignatureModel( - signature: base64Encode(signatureBytes), - ); - } - - ECSignature get ecSignature { - final List signatureBytes = base64Decode(signature); - final List rBytes = signatureBytes.sublist(0, 32); - final List sBytes = signatureBytes.sublist(32, 64); - final BigInt r = CryptoAddressParser.bytesToInt(rBytes); - final BigInt s = CryptoAddressParser.bytesToInt(sBytes); - return ECSignature(r, s); - } - - @override - List get props => [signature]; -} diff --git a/lib/shared/models/transactions/signed_transaction_model.dart b/lib/shared/models/transactions/signed_transaction_model.dart index f70c11bb..0ac21d2c 100644 --- a/lib/shared/models/transactions/signed_transaction_model.dart +++ b/lib/shared/models/transactions/signed_transaction_model.dart @@ -1,21 +1,19 @@ +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:equatable/equatable.dart'; -import 'package:miro/shared/models/transactions/signature_model.dart'; import 'package:miro/shared/models/transactions/tx_local_info_model.dart'; import 'package:miro/shared/models/transactions/tx_remote_info_model.dart'; class SignedTxModel extends Equatable { - final String publicKeyCompressed; final TxLocalInfoModel txLocalInfoModel; final TxRemoteInfoModel txRemoteInfoModel; - final SignatureModel signatureModel; + final CosmosTx signedCosmosTx; const SignedTxModel({ - required this.publicKeyCompressed, required this.txLocalInfoModel, required this.txRemoteInfoModel, - required this.signatureModel, + required this.signedCosmosTx, }); @override - List get props => [publicKeyCompressed, txLocalInfoModel, txRemoteInfoModel, signatureModel]; + List get props => [txLocalInfoModel, txRemoteInfoModel, signedCosmosTx]; } diff --git a/lib/shared/models/transactions/unsigned_tx_model.dart b/lib/shared/models/transactions/unsigned_tx_model.dart index 46740c75..08b80149 100644 --- a/lib/shared/models/transactions/unsigned_tx_model.dart +++ b/lib/shared/models/transactions/unsigned_tx_model.dart @@ -1,6 +1,13 @@ +import 'dart:typed_data'; + +import 'package:codec_utils/codec_utils.dart'; +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:equatable/equatable.dart'; +import 'package:miro/shared/models/tokens/token_amount_model.dart'; +import 'package:miro/shared/models/transactions/signed_transaction_model.dart'; import 'package:miro/shared/models/transactions/tx_local_info_model.dart'; import 'package:miro/shared/models/transactions/tx_remote_info_model.dart'; +import 'package:miro/shared/models/wallet/wallet.dart'; class UnsignedTxModel extends Equatable { final TxLocalInfoModel txLocalInfoModel; @@ -11,6 +18,65 @@ class UnsignedTxModel extends Equatable { required this.txRemoteInfoModel, }); + SignedTxModel sign(Wallet wallet) { + CosmosSigner cosmosSigner = CosmosSigner(wallet.ecPrivateKey); + + CosmosAuthInfo cosmosAuthInfo = _getCosmosAuthInfo(wallet.ecPrivateKey.ecPublicKey.compressed); + CosmosTxBody cosmosTxBody = _getCosmosTxBody(); + + CosmosSignDoc cosmosSignDoc = CosmosSignDoc( + chainId: txRemoteInfoModel.chainId, + accountNumber: int.parse(txRemoteInfoModel.accountNumber), + authInfo: cosmosAuthInfo, + txBody: cosmosTxBody, + ); + + CosmosSignature cosmosSignature = cosmosSigner.signDirect(cosmosSignDoc); + CosmosTx cosmosTx = CosmosTx.signed( + body: cosmosTxBody, + authInfo: cosmosAuthInfo, + signatures: [cosmosSignature], + ); + + return SignedTxModel( + txLocalInfoModel: txLocalInfoModel, + txRemoteInfoModel: txRemoteInfoModel, + signedCosmosTx: cosmosTx, + ); + } + + CosmosAuthInfo _getCosmosAuthInfo(Uint8List compressedPublicKey) { + TokenAmountModel feeTokenAmountModel = txLocalInfoModel.feeTokenAmountModel; + BigInt feeAmount = feeTokenAmountModel.getAmountInDefaultDenomination().toBigInt(); + String feeDenom = feeTokenAmountModel.tokenAliasModel.defaultTokenDenominationModel.name; + + CosmosAuthInfo cosmosAuthInfo = CosmosAuthInfo( + signerInfos: [ + CosmosSignerInfo( + publicKey: CosmosSimplePublicKey(compressedPublicKey), + modeInfo: CosmosModeInfo.single(CosmosSignMode.signModeDirect), + sequence: int.parse(txRemoteInfoModel.sequence), + ), + ], + fee: CosmosFee( + gasLimit: BigInt.from(20000), + amount: [ + CosmosCoin(denom: feeDenom, amount: feeAmount), + ], + ), + ); + + return cosmosAuthInfo; + } + + CosmosTxBody _getCosmosTxBody() { + String memo = txLocalInfoModel.memo; + List messages = [txLocalInfoModel.txMsgModel.toMsgDto()]; + + CosmosTxBody cosmosTxBody = CosmosTxBody(messages: messages, memo: memo); + return cosmosTxBody; + } + @override List get props => [txLocalInfoModel, txRemoteInfoModel]; } diff --git a/lib/shared/models/wallet/wallet.dart b/lib/shared/models/wallet/wallet.dart index 27d13531..37e19cda 100644 --- a/lib/shared/models/wallet/wallet.dart +++ b/lib/shared/models/wallet/wallet.dart @@ -1,12 +1,7 @@ -import 'dart:typed_data'; - -import 'package:bip32/bip32.dart' as bip32; +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:equatable/equatable.dart'; -import 'package:hex/hex.dart'; -import 'package:miro/shared/models/wallet/mnemonic.dart'; +import 'package:miro/shared/models/wallet/mnemonic.dart' as miro; import 'package:miro/shared/models/wallet/wallet_address.dart'; -import 'package:miro/shared/utils/cryptography/secp256k1.dart'; -import 'package:pointycastle/export.dart'; /// Represents a wallet which contains the hex private key, the hex public key and the hex address. /// In order to create one properly, the [Wallet.derive] method should always be used. @@ -17,15 +12,12 @@ class Wallet extends Equatable { /// * https://river.com/learn/terms/d/derivation-path/ static const String baseDerivationPath = "m/44'/118'/0'/0"; - /// The wallet hex address final WalletAddress address; - - /// The wallet hex private key - final Uint8List privateKey; + final ECPrivateKey ecPrivateKey; const Wallet({ required this.address, - required this.privateKey, + required this.ecPrivateKey, }); /// ** HEAVY OPERATION ** @@ -33,54 +25,22 @@ class Wallet extends Equatable { /// Optionally can define a different derivation path setting [lastDerivationPathSegment]. /// /// Throws [FormatException] if the [int.tryParse] cannot parse [lastDerivationPathSegment] - factory Wallet.derive({ - required Mnemonic mnemonic, + static Future derive({ + required miro.Mnemonic mnemonic, String lastDerivationPathSegment = '0', - }) { - final int lastDerivationPathSegmentCheck = int.tryParse(lastDerivationPathSegment) ?? -1; - if (lastDerivationPathSegmentCheck < 0) { - throw FormatException('Invalid index format $lastDerivationPathSegment'); - } - - // Convert the mnemonic to a BIP32 instance - final bip32.BIP32 root = bip32.BIP32.fromSeed(mnemonic.seed); - - // Get the node from the derivation path - final bip32.BIP32 derivedNode = root.derivePath('$baseDerivationPath/$lastDerivationPathSegment'); - - // Get the public key - final Uint8List publicKeyBytes = Secp256k1.privateKeyBytesToPublic(derivedNode.privateKey!); - - return Wallet( - address: WalletAddress.fromPublicKey(publicKeyBytes), - privateKey: derivedNode.privateKey!, + }) async { + LegacyHDWallet legacyHDWallet = await LegacyHDWallet.fromMnemonic( + mnemonic: Mnemonic(mnemonic.array), + derivationPath: LegacyDerivationPath.parse('$baseDerivationPath/$lastDerivationPathSegment'), + walletConfig: Bip44WalletsConfig.kira, ); - } - - factory Wallet.fromKeyfileData(Map publicData, Map secretData) { - final WalletAddress walletAddress = WalletAddress.fromBech32(publicData['bech32Address'] as String); - final Uint8List privateKey = Uint8List.fromList(HEX.decode(secretData['privateKey'] as String)); return Wallet( - address: walletAddress, - privateKey: privateKey, + address: WalletAddress.fromPublicKey(legacyHDWallet.publicKey.compressed), + ecPrivateKey: (legacyHDWallet.privateKey as Secp256k1PrivateKey).ecPrivateKey, ); } - /// Returns the associated [publicKey] as an [ECPublicKey] instance. - ECPublicKey get ecPublicKey { - final ECCurve_secp256k1 secp256k1 = ECCurve_secp256k1(); - final ECPoint point = secp256k1.G; - final ECPoint? curvePoint = point * ecPrivateKey.d; - return ECPublicKey(curvePoint, ECCurve_secp256k1()); - } - - /// Returns the associated [privateKey] as an [ECPrivateKey] instance. - ECPrivateKey get ecPrivateKey { - final BigInt privateKeyInt = BigInt.parse(HEX.encode(privateKey), radix: 16); - return ECPrivateKey(privateKeyInt, ECCurve_secp256k1()); - } - @override - List get props => [address, privateKey]; + List get props => [address, ecPrivateKey]; } diff --git a/lib/shared/utils/transactions/signature_utils.dart b/lib/shared/utils/transactions/signature_utils.dart deleted file mode 100644 index 7b520f07..00000000 --- a/lib/shared/utils/transactions/signature_utils.dart +++ /dev/null @@ -1,136 +0,0 @@ -import 'dart:convert'; -import 'dart:typed_data'; - -import 'package:miro/shared/models/transactions/signature_model.dart'; -import 'package:miro/shared/models/wallet/wallet.dart'; -import 'package:miro/shared/utils/crypto_address_parser.dart'; -import 'package:miro/shared/utils/cryptography/secp256k1.dart'; -import 'package:miro/shared/utils/cryptography/sha256.dart'; -import 'package:pointycastle/export.dart'; - -class SignatureUtils { - static final BigInt _prime = BigInt.parse( - 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f', - radix: 16, - ); - - static SignatureModel generateSignature({required Wallet wallet, required Map signatureDataJson}) { - final Uint8List signatureDataHashBytes = generateSignatureDataHashBytes(signatureDataJson); - - final ECDomainParameters ecDomainParameters = ECCurve_secp256k1(); - final BigInt halfCurveOrder = ecDomainParameters.n >> 1; - - final ECDSASigner ecdsaSigner = ECDSASigner(null, HMac(SHA256Digest(), 64)) - ..init(true, PrivateKeyParameter(wallet.ecPrivateKey)); - - ECSignature ecSignature = ecdsaSigner.generateSignature(signatureDataHashBytes) as ECSignature; - - if (ecSignature.s.compareTo(halfCurveOrder) > 0) { - final BigInt canonicalS = ecDomainParameters.n - ecSignature.s; - ecSignature = ECSignature(ecSignature.r, canonicalS); - } - - Uint8List signatureBytes = Uint8List.fromList( - CryptoAddressParser.intToBytes(ecSignature.r) + CryptoAddressParser.intToBytes(ecSignature.s), - ); - - return SignatureModel.fromBytes(signatureBytes); - } - - static Uint8List generateSignatureDataHashBytes(Map signatureDataJson) { - final String signatureDataString = json.encode(signatureDataJson); - final List signatureDataHash = Sha256.encrypt(signatureDataString).bytes; - return Uint8List.fromList(signatureDataHash); - } - - static bool verifySignature({ - required SignatureModel signatureModel, - required Uint8List addressBytes, - required Uint8List signatureDataHashBytes, - }) { - List signaturePublicKeyList = _extractPublicKeysFromSignature(signatureModel.ecSignature, signatureDataHashBytes); - if (signaturePublicKeyList.isEmpty) { - return false; - } - final BigInt expectedAddress = CryptoAddressParser.bytesToInt(addressBytes); - - for (Uint8List signaturePublicKey in signaturePublicKeyList) { - final Uint8List actualAddressBytes = Secp256k1.publicKeyToAddress(signaturePublicKey); - final BigInt actualAddress = CryptoAddressParser.bytesToInt(actualAddressBytes); - final bool addressesEqual = actualAddress == expectedAddress; - if (addressesEqual) { - return true; - } - } - return false; - } - - static List _extractPublicKeysFromSignature(ECSignature ecSignature, Uint8List messageHashBytes) { - try { - final List generatedPublicKeys = List.empty(growable: true); - for (int recoveryId = 0; recoveryId < 4; recoveryId++) { - Uint8List? publicKey = _recoverFromSignature(recoveryId, ecSignature, messageHashBytes); - if (publicKey != null) { - generatedPublicKeys.add(publicKey); - } - } - return generatedPublicKeys; - } catch (_) { - return List.empty(); - } - } - - static Uint8List? _recoverFromSignature(int recoveryId, ECSignature ecSignature, Uint8List messageHashBytes) { - final ECDomainParameters params = ECCurve_secp256k1(); - - final BigInt n = params.n; - final BigInt i = BigInt.from(recoveryId ~/ 2); - final BigInt x = ecSignature.r + (i * n); - - if (x.compareTo(_prime) >= 0) { - return null; - } - - final ECPoint R = _decompressKey(x, (recoveryId & 1) == 1, params.curve)!; - if (!(R * n)!.isInfinity) { - return null; - } - - final BigInt e = CryptoAddressParser.bytesToInt(messageHashBytes); - - final BigInt eInv = (BigInt.zero - e) % n; - final BigInt rInv = ecSignature.r.modInverse(n); - final BigInt srInv = (rInv * ecSignature.s) % n; - final BigInt eInvrInv = (rInv * eInv) % n; - - final ECPoint? q = (params.G * eInvrInv)! + (R * srInv); - - final Uint8List bytes = q!.getEncoded(); - return bytes; - } - - static ECPoint? _decompressKey(BigInt xBN, bool yBit, ECCurve ecCurve) { - final int qLength = 1 + ((ecCurve.fieldSize + 7) ~/ 8); - final List compEnc = _x9IntegerToBytes(xBN, qLength); - compEnc[0] = yBit ? 0x03 : 0x02; - return ecCurve.decodePoint(compEnc); - } - - static List _x9IntegerToBytes(BigInt s, int qLength) { - final Uint8List bytes = CryptoAddressParser.intToBytes(s); - - if (qLength < bytes.length) { - return bytes.sublist(0, bytes.length - qLength); - } else if (qLength > bytes.length) { - final List tmp = List.filled(qLength, 0); - - final int offset = qLength - bytes.length; - for (int i = 0; i < bytes.length; i++) { - tmp[i + offset] = bytes[i]; - } - return tmp; - } - - return bytes; - } -} diff --git a/lib/shared/utils/transactions/tx_utils.dart b/lib/shared/utils/transactions/tx_utils.dart index fd0fb4fa..f3ad81b1 100644 --- a/lib/shared/utils/transactions/tx_utils.dart +++ b/lib/shared/utils/transactions/tx_utils.dart @@ -1,13 +1,4 @@ -import 'dart:convert'; - -import 'package:miro/infra/dto/api_kira/broadcast/request/transaction/std_sign_doc.dart'; import 'package:miro/shared/models/tokens/token_denomination_model.dart'; -import 'package:miro/shared/models/transactions/signature_model.dart'; -import 'package:miro/shared/models/transactions/signed_transaction_model.dart'; -import 'package:miro/shared/models/transactions/unsigned_tx_model.dart'; -import 'package:miro/shared/models/wallet/wallet.dart'; -import 'package:miro/shared/utils/map_utils.dart'; -import 'package:miro/shared/utils/transactions/signature_utils.dart'; class TxUtils { static Map memoReplacements = { @@ -54,18 +45,4 @@ class TxUtils { }); return replacedMemo; } - - static SignedTxModel sign({required UnsignedTxModel unsignedTxModel, required Wallet wallet}) { - StdSignDoc stdSignDoc = StdSignDoc.fromUnsignedTxModel(unsignedTxModel); - Map signatureDataJson = MapUtils.sort(stdSignDoc.toSignatureJson()); - SignatureModel signatureModel = SignatureUtils.generateSignature(wallet: wallet, signatureDataJson: signatureDataJson); - List publicKeyCompressed = wallet.ecPublicKey.Q!.getEncoded(true); - - return SignedTxModel( - publicKeyCompressed: base64Encode(publicKeyCompressed), - txLocalInfoModel: unsignedTxModel.txLocalInfoModel, - txRemoteInfoModel: unsignedTxModel.txRemoteInfoModel, - signatureModel: signatureModel, - ); - } } diff --git a/lib/test/utils/test_utils.dart b/lib/test/utils/test_utils.dart index e4af8629..bee457c1 100644 --- a/lib/test/utils/test_utils.dart +++ b/lib/test/utils/test_utils.dart @@ -1,3 +1,4 @@ +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:miro/blocs/generic/network_module/events/network_module_connect_event.dart'; import 'package:miro/blocs/generic/network_module/network_module_bloc.dart'; import 'package:miro/config/app_config.dart'; @@ -14,15 +15,18 @@ import 'package:miro/shared/models/network/status/online/network_unhealthy_model import 'package:miro/shared/models/tokens/token_alias_model.dart'; import 'package:miro/shared/models/tokens/token_default_denom_model.dart'; import 'package:miro/shared/models/tokens/token_denomination_model.dart'; -import 'package:miro/shared/models/wallet/mnemonic.dart'; import 'package:miro/shared/models/wallet/wallet.dart'; +import 'package:miro/shared/models/wallet/wallet_address.dart'; import 'package:miro/test/mocks/mock_network_list_config_json.dart'; class TestUtils { - // @formatter:off - static final Mnemonic mnemonic = Mnemonic(value: 'require point property company tongue busy bench burden caution gadget knee glance thought bulk assist month cereal report quarter tool section often require shield'); - static final Wallet wallet = Wallet.derive(mnemonic: mnemonic); - // @formatter:on + static Wallet wallet = Wallet( + address: WalletAddress.fromBech32('kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx'), + ecPrivateKey: ECPrivateKey( + CurvePoints.generatorSecp256k1, + BigInt.parse('25933686250415448129536663355227060923413846494721047098076326567395973050293'), + ), + ); static DateTime defaultLastRefreshDateTime = DateTime(2024, 3, 14, 14, 17); diff --git a/lib/views/widgets/transactions/send/tx_send_form_footer.dart b/lib/views/widgets/transactions/send/tx_send_form_footer.dart index c9a7296d..a59c53fe 100644 --- a/lib/views/widgets/transactions/send/tx_send_form_footer.dart +++ b/lib/views/widgets/transactions/send/tx_send_form_footer.dart @@ -14,7 +14,6 @@ import 'package:miro/shared/models/transactions/signed_transaction_model.dart'; import 'package:miro/shared/models/transactions/unsigned_tx_model.dart'; import 'package:miro/shared/models/wallet/wallet.dart'; import 'package:miro/shared/utils/logger/app_logger.dart'; -import 'package:miro/shared/utils/transactions/tx_utils.dart'; import 'package:miro/views/widgets/transactions/send/tx_send_form_completing_indicator.dart'; import 'package:miro/views/widgets/transactions/send/tx_send_form_next_button.dart'; @@ -113,7 +112,7 @@ class _TxSendFormFooter extends State { if (wallet == null) { throw Exception('Wallet cannot be null when signing transaction'); } - SignedTxModel signedTxModel = TxUtils.sign(unsignedTxModel: unsignedTxModel, wallet: wallet); + SignedTxModel signedTxModel = unsignedTxModel.sign(wallet); await Future.delayed(const Duration(milliseconds: 100)); return signedTxModel; } diff --git a/pubspec.yaml b/pubspec.yaml index 9aea5e88..36b02cc8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: miro description: KIRA blockchain explorer publish_to: 'none' -version: 1.29.0 +version: 1.29.1 environment: sdk: "3.2.6" @@ -169,6 +169,18 @@ dependencies: url: https://github.com/CandyLabsIT/just_the_tooltip.git ref: dp-bugfix/target-information + # Dart package containing utility methods for common cryptographic and blockchain-specific operations. + cryptography_utils: + git: + url: https://github.com/snggle/cryptography_utils.git + ref: master + + # Dart package containing utility methods for data encoding and decoding. + codec_utils: + git: + url: https://github.com/snggle/codec_utils.git + ref: master + dev_dependencies: # AutoRoute is a declarative routing solution, where everything needed for navigation is automatically generated for you. # https://pub.dev/packages/auto_route_generator diff --git a/test/integration/infra/services/api_kira/broadcast_service_test.dart b/test/integration/infra/services/api_kira/broadcast_service_test.dart index ceeafbda..1cf82399 100644 --- a/test/integration/infra/services/api_kira/broadcast_service_test.dart +++ b/test/integration/infra/services/api_kira/broadcast_service_test.dart @@ -4,7 +4,6 @@ import 'package:decimal/decimal.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:miro/config/locator.dart'; import 'package:miro/infra/dto/api_kira/broadcast/request/broadcast_req.dart'; -import 'package:miro/infra/dto/api_kira/broadcast/request/transaction/tx.dart'; import 'package:miro/infra/exceptions/dio_connect_exception.dart'; import 'package:miro/infra/exceptions/dio_parse_exception.dart'; import 'package:miro/infra/exceptions/tx_broadcast_exception.dart'; @@ -28,10 +27,9 @@ import 'package:miro/shared/models/transactions/signed_transaction_model.dart'; import 'package:miro/shared/models/transactions/tx_local_info_model.dart'; import 'package:miro/shared/models/transactions/tx_remote_info_model.dart'; import 'package:miro/shared/models/transactions/unsigned_tx_model.dart'; -import 'package:miro/shared/models/wallet/mnemonic.dart'; +import 'package:miro/shared/models/wallet/mnemonic.dart' as miro; import 'package:miro/shared/models/wallet/wallet.dart'; import 'package:miro/shared/utils/network_utils.dart'; -import 'package:miro/shared/utils/transactions/tx_utils.dart'; import 'package:miro/test/utils/test_utils.dart'; // To run this test type in console: @@ -45,11 +43,11 @@ Future main() async { // Set up the constants to run the tests. // @formatter:off - final Mnemonic senderMnemonic = Mnemonic(value: 'require point property company tongue busy bench burden caution gadget knee glance thought bulk assist month cereal report quarter tool section often require shield'); - final Wallet senderWallet = Wallet.derive(mnemonic: senderMnemonic); + final miro.Mnemonic senderMnemonic = miro.Mnemonic(value: 'require point property company tongue busy bench burden caution gadget knee glance thought bulk assist month cereal report quarter tool section often require shield'); + final Wallet senderWallet = await Wallet.derive(mnemonic: senderMnemonic); - final Mnemonic recipientMnemonic = Mnemonic(value: 'nature light entire memory garden ostrich bottom ensure brand fantasy curtain coast also solve cannon wealth hole quantum fantasy purchase check drift cloth ecology'); - final Wallet recipientWallet = Wallet.derive(mnemonic: recipientMnemonic); + final miro.Mnemonic recipientMnemonic = miro.Mnemonic(value: 'nature light entire memory garden ostrich bottom ensure brand fantasy curtain coast also solve cannon wealth hole quantum fantasy purchase check drift cloth ecology'); + final Wallet recipientWallet = await Wallet.derive(mnemonic: recipientMnemonic); // @formatter:on final TokenAmountModel feeTokenAmountModel = TokenAmountModel( @@ -62,19 +60,13 @@ Future main() async { Future signTx(TxLocalInfoModel actualTxLocalInfoModel, Wallet wallet) async { try { - final TxRemoteInfoModel txRemoteInfoModel = await queryAccountService.getTxRemoteInfo( - wallet.address.bech32Address, - ); - + final TxRemoteInfoModel txRemoteInfoModel = await queryAccountService.getTxRemoteInfo(wallet.address.bech32Address); final UnsignedTxModel actualUnsignedTxModel = UnsignedTxModel( txLocalInfoModel: actualTxLocalInfoModel, txRemoteInfoModel: txRemoteInfoModel, ); - final SignedTxModel actualSignedTxModel = TxUtils.sign( - unsignedTxModel: actualUnsignedTxModel, - wallet: wallet, - ); + final SignedTxModel actualSignedTxModel = actualUnsignedTxModel.sign(wallet); return actualSignedTxModel; } on DioConnectException catch (e) { @@ -123,7 +115,7 @@ Future main() async { SignedTxModel actualSignedTxModel = await signTx(actualTxLocalInfoModel, senderWallet); - BroadcastReq actualBroadcastReq = BroadcastReq(tx: Tx.fromSignedTxModel(actualSignedTxModel)); + BroadcastReq actualBroadcastReq = BroadcastReq(tx: actualSignedTxModel.signedCosmosTx); TestUtils.printInfo('Signed [MsgSend] transaction: ${json.encode(actualBroadcastReq.toJson())}'); await broadcastTx(actualSignedTxModel); @@ -144,7 +136,7 @@ Future main() async { SignedTxModel actualSignedTxModel = await signTx(actualTxLocalInfoModel, senderWallet); - BroadcastReq actualBroadcastReq = BroadcastReq(tx: Tx.fromSignedTxModel(actualSignedTxModel)); + BroadcastReq actualBroadcastReq = BroadcastReq(tx: actualSignedTxModel.signedCosmosTx); TestUtils.printInfo('Signed [IRMsgRegisterRecordsModel] transaction: ${json.encode(actualBroadcastReq.toJson())}'); // await broadcastTx(actualSignedTxModel); @@ -155,7 +147,7 @@ Future main() async { memo: 'Test of MsgRequestIdentityRecordsVerify message', feeTokenAmountModel: feeTokenAmountModel, txMsgModel: IRMsgRequestVerificationModel.single( - recordId: BigInt.from(964), + recordId: 964, tipTokenAmountModel: TokenAmountModel( defaultDenominationAmount: Decimal.fromInt(200), tokenAliasModel: TokenAliasModel.local('ukex'), @@ -167,7 +159,7 @@ Future main() async { SignedTxModel actualSignedTxModel = await signTx(actualTxLocalInfoModel, senderWallet); - BroadcastReq actualBroadcastReq = BroadcastReq(tx: Tx.fromSignedTxModel(actualSignedTxModel)); + BroadcastReq actualBroadcastReq = BroadcastReq(tx: actualSignedTxModel.signedCosmosTx); TestUtils.printInfo('Signed [IRMsgRequestVerificationModel] transaction: ${json.encode(actualBroadcastReq.toJson())}'); // await broadcastTx(actualSignedTxModel); @@ -185,7 +177,7 @@ Future main() async { SignedTxModel actualSignedTxModel = await signTx(actualTxLocalInfoModel, senderWallet); - BroadcastReq actualBroadcastReq = BroadcastReq(tx: Tx.fromSignedTxModel(actualSignedTxModel)); + BroadcastReq actualBroadcastReq = BroadcastReq(tx: actualSignedTxModel.signedCosmosTx); TestUtils.printInfo('Signed [IRMsgCancelVerificationRequestModel] transaction: ${json.encode(actualBroadcastReq.toJson())}'); // await broadcastTx(actualSignedTxModel); @@ -203,7 +195,7 @@ Future main() async { SignedTxModel actualSignedTxModel = await signTx(actualTxLocalInfoModel, senderWallet); - BroadcastReq actualBroadcastReq = BroadcastReq(tx: Tx.fromSignedTxModel(actualSignedTxModel)); + BroadcastReq actualBroadcastReq = BroadcastReq(tx: actualSignedTxModel.signedCosmosTx); TestUtils.printInfo('Signed [IRMsgDeleteRecordsModel] transaction: ${json.encode(actualBroadcastReq.toJson())}'); // await broadcastTx(actualSignedTxModel); @@ -222,7 +214,7 @@ Future main() async { SignedTxModel actualSignedTxModel = await signTx(actualTxLocalInfoModel, recipientWallet); - BroadcastReq actualBroadcastReq = BroadcastReq(tx: Tx.fromSignedTxModel(actualSignedTxModel)); + BroadcastReq actualBroadcastReq = BroadcastReq(tx: actualSignedTxModel.signedCosmosTx); TestUtils.printInfo('Signed [IRMsgHandleVerificationRequestModel] transaction: ${json.encode(actualBroadcastReq.toJson())}'); // await broadcastTx(actualSignedTxModel); @@ -244,7 +236,7 @@ Future main() async { SignedTxModel actualSignedTxModel = await signTx(actualTxLocalInfoModel, senderWallet); - BroadcastReq actualBroadcastReq = BroadcastReq(tx: Tx.fromSignedTxModel(actualSignedTxModel)); + BroadcastReq actualBroadcastReq = BroadcastReq(tx: actualSignedTxModel.signedCosmosTx); TestUtils.printInfo('Signed [MsgDelegate] transaction: ${json.encode(actualBroadcastReq.toJson())}'); // await broadcastTx(actualSignedTxModel); @@ -263,7 +255,7 @@ Future main() async { SignedTxModel actualSignedTxModel = await signTx(actualTxLocalInfoModel, senderWallet); - BroadcastReq actualBroadcastReq = BroadcastReq(tx: Tx.fromSignedTxModel(actualSignedTxModel)); + BroadcastReq actualBroadcastReq = BroadcastReq(tx: actualSignedTxModel.signedCosmosTx); TestUtils.printInfo('Signed [MsgUndelegate] transaction: ${json.encode(actualBroadcastReq.toJson())}'); // await broadcastTx(actualSignedTxModel); @@ -280,7 +272,7 @@ Future main() async { SignedTxModel actualSignedTxModel = await signTx(actualTxLocalInfoModel, senderWallet); - BroadcastReq actualBroadcastReq = BroadcastReq(tx: Tx.fromSignedTxModel(actualSignedTxModel)); + BroadcastReq actualBroadcastReq = BroadcastReq(tx: actualSignedTxModel.signedCosmosTx); TestUtils.printInfo('Signed [MsgClaimRewards] transaction: ${json.encode(actualBroadcastReq.toJson())}'); // await broadcastTx(actualSignedTxModel); @@ -298,7 +290,7 @@ Future main() async { SignedTxModel actualSignedTxModel = await signTx(actualTxLocalInfoModel, senderWallet); - BroadcastReq actualBroadcastReq = BroadcastReq(tx: Tx.fromSignedTxModel(actualSignedTxModel)); + BroadcastReq actualBroadcastReq = BroadcastReq(tx: actualSignedTxModel.signedCosmosTx); TestUtils.printInfo('Signed [MsgClaimUndelegation] transaction: ${json.encode(actualBroadcastReq.toJson())}'); // await broadcastTx(actualSignedTxModel); diff --git a/test/unit/blocs/pages/drawer/sign_in_keyfile_drawer_page_cubit_test.dart b/test/unit/blocs/pages/drawer/sign_in_keyfile_drawer_page_cubit_test.dart index d726098a..0860de09 100644 --- a/test/unit/blocs/pages/drawer/sign_in_keyfile_drawer_page_cubit_test.dart +++ b/test/unit/blocs/pages/drawer/sign_in_keyfile_drawer_page_cubit_test.dart @@ -101,11 +101,12 @@ Future main() async { decryptedKeyfileModel: DecryptedKeyfileModel( version: '2.0.0', keyfileSecretDataModel: KeyfileSecretDataModel( - wallet: Wallet.derive( - mnemonic: Mnemonic( - value: - 'require point property company tongue busy bench burden caution gadget knee glance thought bulk assist month cereal report quarter tool section often require shield'), - ), + wallet: await Wallet.derive( + mnemonic: Mnemonic( + value: + 'require point property company tongue busy bench burden caution gadget knee glance thought bulk assist month cereal report quarter tool section often require shield', + ), + ), ), ), ); diff --git a/test/unit/blocs/pages/transactions/tx_broadcast_cubit_test.dart b/test/unit/blocs/pages/transactions/tx_broadcast_cubit_test.dart index 19ce5edd..9a796906 100644 --- a/test/unit/blocs/pages/transactions/tx_broadcast_cubit_test.dart +++ b/test/unit/blocs/pages/transactions/tx_broadcast_cubit_test.dart @@ -1,3 +1,7 @@ +import 'dart:convert'; + +import 'package:codec_utils/codec_utils.dart'; +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:decimal/decimal.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:miro/blocs/generic/network_module/events/network_module_auto_connect_event.dart'; @@ -11,12 +15,12 @@ import 'package:miro/blocs/pages/transactions/tx_broadcast/states/tx_broadcast_l import 'package:miro/blocs/pages/transactions/tx_broadcast/tx_broadcast_cubit.dart'; import 'package:miro/config/locator.dart'; import 'package:miro/infra/dto/api_kira/broadcast/response/broadcast_resp.dart'; +import 'package:miro/infra/dto/shared/messages/msg_send.dart'; import 'package:miro/shared/models/network/error_explorer_model.dart'; import 'package:miro/shared/models/tokens/token_alias_model.dart'; import 'package:miro/shared/models/tokens/token_amount_model.dart'; import 'package:miro/shared/models/transactions/broadcast_resp_model.dart'; import 'package:miro/shared/models/transactions/messages/msg_send_model.dart'; -import 'package:miro/shared/models/transactions/signature_model.dart'; import 'package:miro/shared/models/transactions/signed_transaction_model.dart'; import 'package:miro/shared/models/transactions/tx_local_info_model.dart'; import 'package:miro/shared/models/transactions/tx_remote_info_model.dart'; @@ -31,7 +35,6 @@ Future main() async { await initMockLocator(); SignedTxModel signedTxModel = SignedTxModel( - publicKeyCompressed: 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8', txLocalInfoModel: TxLocalInfoModel( memo: 'Test transaction', feeTokenAmountModel: TokenAmountModel( @@ -52,8 +55,40 @@ Future main() async { chainId: 'testnet', sequence: '0', ), - signatureModel: const SignatureModel( - signature: 'hd+WiCdVaMcTDshpEsgkn6VOWdXAOV7QKUZEIxMRhLYzSD8bK7RQcn9jl/2I2TLa4QBoCuAStXwOircabaVQzg==', + signedCosmosTx: CosmosTx.signed( + body: CosmosTxBody( + messages: [ + MsgSend( + fromAddress: 'kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx', + toAddress: 'kira177lwmjyjds3cy7trers83r4pjn3dhv8zrqk9dl', + amount: [ + CosmosCoin(denom: 'ukex', amount: BigInt.from(100)), + ], + ), + ], + memo: 'Test transaction', + ), + authInfo: CosmosAuthInfo( + signerInfos: [ + CosmosSignerInfo( + publicKey: CosmosSimplePublicKey(base64Decode('AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8')), + modeInfo: CosmosModeInfo.single(CosmosSignMode.signModeDirect), + sequence: 0, + ), + ], + fee: CosmosFee( + gasLimit: BigInt.from(200000), + amount: [ + CosmosCoin(denom: 'ukex', amount: BigInt.from(100)), + ], + ), + ), + signatures: [ + CosmosSignature( + s: BigInt.parse('29891932639696445785621460296478741769669531437362733111307189554313331920903'), + r: BigInt.parse('105119573348349584760845537497362350123555688438276125868382281816491465425317'), + ), + ], ), ); diff --git a/test/unit/blocs/pages/transactions/tx_form_builder_cubit_test.dart b/test/unit/blocs/pages/transactions/tx_form_builder_cubit_test.dart index bfe961c0..d5373ccd 100644 --- a/test/unit/blocs/pages/transactions/tx_form_builder_cubit_test.dart +++ b/test/unit/blocs/pages/transactions/tx_form_builder_cubit_test.dart @@ -10,8 +10,6 @@ import 'package:miro/shared/models/tokens/token_amount_model.dart'; import 'package:miro/shared/models/transactions/tx_local_info_model.dart'; import 'package:miro/shared/models/transactions/tx_remote_info_model.dart'; import 'package:miro/shared/models/transactions/unsigned_tx_model.dart'; -import 'package:miro/shared/models/wallet/mnemonic.dart'; -import 'package:miro/shared/models/wallet/wallet.dart'; import 'package:miro/test/mock_locator.dart'; import 'package:miro/test/utils/test_utils.dart'; @@ -25,12 +23,7 @@ Future main() async { AuthCubit authCubit = globalLocator(); - // @formatter:off - final Mnemonic senderMnemonic = Mnemonic(value: 'require point property company tongue busy bench burden caution gadget knee glance thought bulk assist month cereal report quarter tool section often require shield'); - final Wallet senderWallet = Wallet.derive(mnemonic: senderMnemonic); - // @formatter:on - - await authCubit.signIn(senderWallet); + await authCubit.signIn(TestUtils.wallet); TokenAmountModel feeTokenAmountModel = TokenAmountModel( defaultDenominationAmount: Decimal.parse('100'), diff --git a/test/unit/blocs/pages/transactions/tx_process_cubit_test.dart b/test/unit/blocs/pages/transactions/tx_process_cubit_test.dart index bb909b80..10ef4d33 100644 --- a/test/unit/blocs/pages/transactions/tx_process_cubit_test.dart +++ b/test/unit/blocs/pages/transactions/tx_process_cubit_test.dart @@ -1,3 +1,7 @@ +import 'dart:convert'; + +import 'package:codec_utils/codec_utils.dart'; +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:decimal/decimal.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:miro/blocs/generic/auth/auth_cubit.dart'; @@ -9,13 +13,13 @@ import 'package:miro/blocs/pages/transactions/tx_process_cubit/states/tx_process import 'package:miro/blocs/pages/transactions/tx_process_cubit/states/tx_process_loading_state.dart'; import 'package:miro/blocs/pages/transactions/tx_process_cubit/tx_process_cubit.dart'; import 'package:miro/config/locator.dart'; +import 'package:miro/infra/dto/shared/messages/msg_send.dart'; import 'package:miro/shared/models/network/network_properties_model.dart'; import 'package:miro/shared/models/tokens/token_alias_model.dart'; import 'package:miro/shared/models/tokens/token_amount_model.dart'; import 'package:miro/shared/models/transactions/form_models/msg_send_form_model.dart'; import 'package:miro/shared/models/transactions/messages/msg_send_model.dart'; import 'package:miro/shared/models/transactions/messages/tx_msg_type.dart'; -import 'package:miro/shared/models/transactions/signature_model.dart'; import 'package:miro/shared/models/transactions/signed_transaction_model.dart'; import 'package:miro/shared/models/transactions/tx_local_info_model.dart'; import 'package:miro/shared/models/transactions/tx_remote_info_model.dart'; @@ -31,7 +35,6 @@ Future main() async { AuthCubit actualAuthCubit = globalLocator(); SignedTxModel signedTxModel = SignedTxModel( - publicKeyCompressed: 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8', txLocalInfoModel: TxLocalInfoModel( memo: 'Test transaction', feeTokenAmountModel: TokenAmountModel( @@ -52,8 +55,40 @@ Future main() async { chainId: 'testnet-9', sequence: '106', ), - signatureModel: const SignatureModel( - signature: 'Ahamy8xzwacGyxSPElYrvOrMIEL1MbmeS6fsiR9u73QhD3gdbVcwNv0/qRA+jziF2XV8A9eMbvunUOsYxotG6g==', + signedCosmosTx: CosmosTx.signed( + body: CosmosTxBody( + messages: [ + MsgSend( + fromAddress: 'kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx', + toAddress: 'kira177lwmjyjds3cy7trers83r4pjn3dhv8zrqk9dl', + amount: [ + CosmosCoin(denom: 'ukex', amount: BigInt.from(100)), + ], + ), + ], + memo: 'Test transaction', + ), + authInfo: CosmosAuthInfo( + signerInfos: [ + CosmosSignerInfo( + publicKey: CosmosSimplePublicKey(base64Decode('AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8')), + modeInfo: CosmosModeInfo.single(CosmosSignMode.signModeDirect), + sequence: 106, + ), + ], + fee: CosmosFee( + gasLimit: BigInt.from(20000), + amount: [ + CosmosCoin(denom: 'ukex', amount: BigInt.from(100)), + ], + ), + ), + signatures: [ + CosmosSignature( + s: BigInt.parse('24287701672903098479060975435523176452832563163469844088898365033446585323416'), + r: BigInt.parse('86600458310408845869391821482706114144477392767993083402724902623300408071608'), + ), + ], ), ); diff --git a/test/unit/infra/services/api/query_transactions_service_test.dart b/test/unit/infra/services/api/query_transactions_service_test.dart index 05b5eae7..dff461cf 100644 --- a/test/unit/infra/services/api/query_transactions_service_test.dart +++ b/test/unit/infra/services/api/query_transactions_service_test.dart @@ -125,7 +125,7 @@ Future main() async { ], txMsgModels: [ IRMsgRequestVerificationModel( - recordIds: [BigInt.from(2)], + recordIds: const [2], tipTokenAmountModel: TokenAmountModel(defaultDenominationAmount: Decimal.fromInt(200), tokenAliasModel: TokenAliasModel.local('ukex')), verifierWalletAddress: WalletAddress.fromBech32('kira177lwmjyjds3cy7trers83r4pjn3dhv8zrqk9dl'), walletAddress: WalletAddress.fromBech32('kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx'), diff --git a/test/unit/infra/services/api_kira/broadcast_service_test.dart b/test/unit/infra/services/api_kira/broadcast_service_test.dart index c7bd8429..9f468034 100644 --- a/test/unit/infra/services/api_kira/broadcast_service_test.dart +++ b/test/unit/infra/services/api_kira/broadcast_service_test.dart @@ -1,3 +1,7 @@ +import 'dart:convert'; + +import 'package:codec_utils/codec_utils.dart'; +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:decimal/decimal.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:miro/blocs/generic/network_module/events/network_module_auto_connect_event.dart'; @@ -6,7 +10,17 @@ import 'package:miro/blocs/generic/network_module/network_module_bloc.dart'; import 'package:miro/blocs/generic/network_module/network_module_state.dart'; import 'package:miro/config/locator.dart'; import 'package:miro/infra/dto/api_kira/broadcast/request/broadcast_req.dart'; -import 'package:miro/infra/dto/api_kira/broadcast/request/transaction/tx.dart'; +import 'package:miro/infra/dto/shared/messages/identity_records/msg_cancel_identity_records_verify_request.dart'; +import 'package:miro/infra/dto/shared/messages/identity_records/msg_delete_identity_records.dart'; +import 'package:miro/infra/dto/shared/messages/identity_records/msg_handle_identity_records_verify_request.dart'; +import 'package:miro/infra/dto/shared/messages/identity_records/msg_request_identity_records_verify.dart'; +import 'package:miro/infra/dto/shared/messages/identity_records/register/identity_info_entry.dart'; +import 'package:miro/infra/dto/shared/messages/identity_records/register/msg_register_identity_records.dart'; +import 'package:miro/infra/dto/shared/messages/msg_send.dart'; +import 'package:miro/infra/dto/shared/messages/staking/msg_claim_rewards.dart'; +import 'package:miro/infra/dto/shared/messages/staking/msg_claim_undelegation.dart'; +import 'package:miro/infra/dto/shared/messages/staking/msg_delegate.dart'; +import 'package:miro/infra/dto/shared/messages/staking/msg_undelegate.dart'; import 'package:miro/infra/exceptions/dio_connect_exception.dart'; import 'package:miro/infra/exceptions/dio_parse_exception.dart'; import 'package:miro/infra/exceptions/tx_broadcast_exception.dart'; @@ -25,15 +39,13 @@ import 'package:miro/shared/models/transactions/messages/staking/staking_msg_cla import 'package:miro/shared/models/transactions/messages/staking/staking_msg_claim_undelegation_model.dart'; import 'package:miro/shared/models/transactions/messages/staking/staking_msg_delegate_model.dart'; import 'package:miro/shared/models/transactions/messages/staking/staking_msg_undelegate_model.dart'; -import 'package:miro/shared/models/transactions/signature_model.dart'; import 'package:miro/shared/models/transactions/signed_transaction_model.dart'; import 'package:miro/shared/models/transactions/tx_local_info_model.dart'; import 'package:miro/shared/models/transactions/tx_remote_info_model.dart'; import 'package:miro/shared/models/transactions/unsigned_tx_model.dart'; -import 'package:miro/shared/models/wallet/mnemonic.dart'; +import 'package:miro/shared/models/wallet/mnemonic.dart' as miro; import 'package:miro/shared/models/wallet/wallet.dart'; import 'package:miro/shared/utils/network_utils.dart'; -import 'package:miro/shared/utils/transactions/tx_utils.dart'; import 'package:miro/test/mock_locator.dart'; import 'package:miro/test/utils/test_utils.dart'; @@ -49,15 +61,11 @@ Future main() async { // Set up the constants to run the tests. // @formatter:off - final Mnemonic senderMnemonic = Mnemonic( - value: - 'require point property company tongue busy bench burden caution gadget knee glance thought bulk assist month cereal report quarter tool section often require shield'); - final Wallet senderWallet = Wallet.derive(mnemonic: senderMnemonic); - - final Mnemonic recipientMnemonic = Mnemonic( - value: - 'nature light entire memory garden ostrich bottom ensure brand fantasy curtain coast also solve cannon wealth hole quantum fantasy purchase check drift cloth ecology'); - final Wallet recipientWallet = Wallet.derive(mnemonic: recipientMnemonic); + final miro.Mnemonic senderMnemonic = miro.Mnemonic(value: 'require point property company tongue busy bench burden caution gadget knee glance thought bulk assist month cereal report quarter tool section often require shield'); + final Wallet senderWallet = await Wallet.derive(mnemonic: senderMnemonic); + + final miro.Mnemonic recipientMnemonic = miro.Mnemonic(value: 'nature light entire memory garden ostrich bottom ensure brand fantasy curtain coast also solve cannon wealth hole quantum fantasy purchase check drift cloth ecology'); + final Wallet recipientWallet = await Wallet.derive(mnemonic: recipientMnemonic); // @formatter:on final TokenAmountModel feeTokenAmountModel = TokenAmountModel( @@ -65,6 +73,20 @@ Future main() async { tokenAliasModel: TokenAliasModel.local('ukex'), ); + final CosmosAuthInfo cosmosAuthInfo = CosmosAuthInfo( + signerInfos: [ + CosmosSignerInfo( + publicKey: CosmosSimplePublicKey(base64Decode('AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8')), + modeInfo: CosmosModeInfo.single(CosmosSignMode.signModeDirect), + sequence: 106, + ), + ], + fee: CosmosFee( + amount: [CosmosCoin(denom: 'ukex', amount: BigInt.from(200))], + gasLimit: BigInt.from(20000), + ), + ); + final QueryAccountService queryAccountService = globalLocator(); const TxRemoteInfoModel expectedTxRemoteInfoModel = TxRemoteInfoModel( @@ -75,18 +97,13 @@ Future main() async { Future buildUnsignedTxModel(TxLocalInfoModel actualTxLocalInfoModel, Wallet wallet) async { // Act - final TxRemoteInfoModel actualTxRemoteInfoModel = await queryAccountService.getTxRemoteInfo( - wallet.address.bech32Address, - ); + TxRemoteInfoModel actualTxRemoteInfoModel = await queryAccountService.getTxRemoteInfo(wallet.address.bech32Address); // Assert - TestUtils.printInfo('Should return [TxRemoteInfoModel], basing on interx response'); - expect( - actualTxRemoteInfoModel, - expectedTxRemoteInfoModel, - ); + TestUtils.printInfo('Should [return TxRemoteInfoModel] containing address details from INTERX'); + expect(actualTxRemoteInfoModel, expectedTxRemoteInfoModel); - final UnsignedTxModel actualUnsignedTxModel = UnsignedTxModel( + UnsignedTxModel actualUnsignedTxModel = UnsignedTxModel( txLocalInfoModel: actualTxLocalInfoModel, txRemoteInfoModel: actualTxRemoteInfoModel, ); @@ -95,9 +112,9 @@ Future main() async { } group('Tests of transaction preparation for broadcast', () { - test('Should return signed transaction with [MsgSend] message', () async { + test('Should [return signed transaction] with MsgSend message', () async { // Arrange - final TxLocalInfoModel actualTxLocalInfoModel = TxLocalInfoModel( + TxLocalInfoModel actualTxLocalInfoModel = TxLocalInfoModel( memo: 'Test of MsgSend message', feeTokenAmountModel: feeTokenAmountModel, txMsgModel: MsgSendModel( @@ -109,29 +126,40 @@ Future main() async { // Act UnsignedTxModel actualUnsignedTxModel = await buildUnsignedTxModel(actualTxLocalInfoModel, senderWallet); - SignedTxModel actualSignedTxModel = TxUtils.sign( - unsignedTxModel: actualUnsignedTxModel, - wallet: senderWallet, - ); + SignedTxModel actualSignedTxModel = actualUnsignedTxModel.sign(senderWallet); // Assert SignedTxModel expectedSignedTxModel = SignedTxModel( txLocalInfoModel: actualTxLocalInfoModel, txRemoteInfoModel: expectedTxRemoteInfoModel, - publicKeyCompressed: 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8', - signatureModel: const SignatureModel( - signature: 'BiGCQuQyTtJqgNjx9F+FXDxmj/hThzrg1tJuSlxLV9oCoScjKgCf7hAryazvpJLrh5L1IDr74HECJML8TSBbSg==', + signedCosmosTx: CosmosTx.signed( + authInfo: cosmosAuthInfo, + body: CosmosTxBody( + memo: 'Test of MsgSend message', + messages: [ + MsgSend( + fromAddress: 'kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx', + toAddress: 'kira177lwmjyjds3cy7trers83r4pjn3dhv8zrqk9dl', + amount: [CosmosCoin(denom: 'ukex', amount: BigInt.from(200))], + ), + ], + ), + signatures: [ + CosmosSignature( + r: BigInt.parse('89599907753324820443247350118296506262203633866927351078550723837179327736941'), + s: BigInt.parse('21866124806975663122088505116775312757127188676174337977018459598244507878684'), + ), + ], ), ); - TestUtils.printInfo('Should return [SignedTxModel] with [MsgSend] message'); - expect( - actualSignedTxModel, - expectedSignedTxModel, - ); + TestUtils.printInfo('Should [return SignedTxModel] with MsgSend message'); + expect(actualSignedTxModel, expectedSignedTxModel); + + // ************************************************************************************************************* // Act - BroadcastReq actualBroadcastReq = BroadcastReq(tx: Tx.fromSignedTxModel(actualSignedTxModel)); + BroadcastReq actualBroadcastReq = BroadcastReq(tx: actualSignedTxModel.signedCosmosTx); // Assert Map expectedBroadcastReqJson = { @@ -143,46 +171,45 @@ Future main() async { 'from_address': 'kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx', 'to_address': 'kira177lwmjyjds3cy7trers83r4pjn3dhv8zrqk9dl', 'amount': [ - {'amount': '200', 'denom': 'ukex'} + {'denom': 'ukex', 'amount': '200'} ] } ], 'memo': 'Test of MsgSend message', 'timeout_height': '0', - 'extension_options': [], - 'non_critical_extension_options': [] + 'extension_options': [], + 'non_critical_extension_options': [] }, 'auth_info': { 'signer_infos': [ { 'public_key': {'@type': '/cosmos.crypto.secp256k1.PubKey', 'key': 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8'}, 'mode_info': { - 'single': {'mode': 'SIGN_MODE_LEGACY_AMINO_JSON'} + 'single': {'mode': 'SIGN_MODE_DIRECT'} }, 'sequence': '106' } ], 'fee': { + 'gas_limit': '20000', 'amount': [ - {'amount': '200', 'denom': 'ukex'} + {'denom': 'ukex', 'amount': '200'} ], - 'gas_limit': '999999' + 'payer': null, + 'granter': null } }, - 'signatures': ['BiGCQuQyTtJqgNjx9F+FXDxmj/hThzrg1tJuSlxLV9oCoScjKgCf7hAryazvpJLrh5L1IDr74HECJML8TSBbSg=='] + 'signatures': ['xhfAKWWGRES3j0Aolo9bsWPXxS+fCqIBUMKjiimk7G0wV8m+QeBV+2oH0HikRO2lM2duXVLlvHIHPNSDHfEFHA=='] }, 'mode': 'block' }; - TestUtils.printInfo('Should return [Tx] as json with [MsgSend] message'); - expect( - actualBroadcastReq.toJson(), - expectedBroadcastReqJson, - ); + TestUtils.printInfo('Should [return BroadcastReq] as json with MsgSend message'); + expect(actualBroadcastReq.toJson(), expectedBroadcastReqJson); }); - test('Should return signed transaction with [IRMsgRegisterRecordsModel] message', () async { - final TxLocalInfoModel actualTxLocalInfoModel = TxLocalInfoModel( + test('Should [return signed transaction] with IRMsgRegisterRecordsModel message', () async { + TxLocalInfoModel actualTxLocalInfoModel = TxLocalInfoModel( memo: 'Test of MsgRegisterIdentityRecords message', feeTokenAmountModel: feeTokenAmountModel, txMsgModel: IRMsgRegisterRecordsModel.single( @@ -196,29 +223,41 @@ Future main() async { // Act UnsignedTxModel actualUnsignedTxModel = await buildUnsignedTxModel(actualTxLocalInfoModel, senderWallet); - SignedTxModel actualSignedTxModel = TxUtils.sign( - unsignedTxModel: actualUnsignedTxModel, - wallet: senderWallet, - ); + SignedTxModel actualSignedTxModel = actualUnsignedTxModel.sign(senderWallet); // Assert SignedTxModel expectedSignedTxModel = SignedTxModel( txLocalInfoModel: actualTxLocalInfoModel, txRemoteInfoModel: expectedTxRemoteInfoModel, - publicKeyCompressed: 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8', - signatureModel: const SignatureModel( - signature: '+Odo/kQ6xBNJCakUnZkmFq0H1tW3pgRYgnLB9ul3iMkj/XElK6pU+bHluRmiONMovMNEDKjvphZeahabtkWTiw==', + signedCosmosTx: CosmosTx.signed( + authInfo: cosmosAuthInfo, + body: CosmosTxBody( + memo: 'Test of MsgRegisterIdentityRecords message', + messages: [ + MsgRegisterIdentityRecords( + address: CosmosAccAddress('kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx'), + infos: [ + const IdentityInfoEntry(key: 'avatar', info: 'https://paganresearch.io/images/kiracore.jpg'), + ], + ), + ], + ), + signatures: [ + CosmosSignature( + r: BigInt.parse('21028702019761272517685992784987639565827921194316081946315444932502726756360'), + s: BigInt.parse('26233124607299580314002343060441837683740545835168470193313814846944351386003'), + ), + ], ), ); - TestUtils.printInfo('Should return [SignedTxModel] with [IRMsgRegisterRecordsModel] message'); - expect( - actualSignedTxModel, - expectedSignedTxModel, - ); + TestUtils.printInfo('Should [return SignedTxModel] with [IRMsgRegisterRecordsModel] message'); + expect(actualSignedTxModel, expectedSignedTxModel); + + // ************************************************************************************************************* // Act - BroadcastReq actualBroadcastReq = BroadcastReq(tx: Tx.fromSignedTxModel(actualSignedTxModel)); + BroadcastReq actualBroadcastReq = BroadcastReq(tx: actualSignedTxModel.signedCosmosTx); // Assert Map expectedBroadcastReqJson = { @@ -235,44 +274,43 @@ Future main() async { ], 'memo': 'Test of MsgRegisterIdentityRecords message', 'timeout_height': '0', - 'extension_options': [], - 'non_critical_extension_options': [] + 'extension_options': [], + 'non_critical_extension_options': [] }, 'auth_info': { 'signer_infos': [ { 'public_key': {'@type': '/cosmos.crypto.secp256k1.PubKey', 'key': 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8'}, 'mode_info': { - 'single': {'mode': 'SIGN_MODE_LEGACY_AMINO_JSON'} + 'single': {'mode': 'SIGN_MODE_DIRECT'} }, 'sequence': '106' } ], 'fee': { + 'gas_limit': '20000', 'amount': [ - {'amount': '200', 'denom': 'ukex'} + {'denom': 'ukex', 'amount': '200'} ], - 'gas_limit': '999999' + 'payer': null, + 'granter': null } }, - 'signatures': ['+Odo/kQ6xBNJCakUnZkmFq0H1tW3pgRYgnLB9ul3iMkj/XElK6pU+bHluRmiONMovMNEDKjvphZeahabtkWTiw=='] + 'signatures': ['Ln3S1LoKALZyd3snOU5M+nL3D57KQ1jAD51eDXJZyAg5/2wfc5JTK/mhLSqfbTrS75pmSRuIAsqnNywlnkR5kw=='] }, 'mode': 'block' }; - TestUtils.printInfo('Should return [Tx] as json with [MsgRegisterIdentityRecords] message'); - expect( - actualBroadcastReq.toJson(), - expectedBroadcastReqJson, - ); + TestUtils.printInfo('Should [return BroadcastReq] as json with MsgRegisterIdentityRecords message'); + expect(actualBroadcastReq.toJson(), expectedBroadcastReqJson); }); - test('Should return signed transaction with [IRMsgRequestVerificationModel] message', () async { - final TxLocalInfoModel actualTxLocalInfoModel = TxLocalInfoModel( + test('Should [return signed transaction] with IRMsgRequestVerificationModel message', () async { + TxLocalInfoModel actualTxLocalInfoModel = TxLocalInfoModel( memo: 'Test of MsgRequestIdentityRecordsVerify message', feeTokenAmountModel: feeTokenAmountModel, txMsgModel: IRMsgRequestVerificationModel.single( - recordId: BigInt.from(964), + recordId: 964, tipTokenAmountModel: TokenAmountModel( defaultDenominationAmount: Decimal.fromInt(200), tokenAliasModel: TokenAliasModel.local('ukex'), @@ -284,29 +322,41 @@ Future main() async { // Act UnsignedTxModel actualUnsignedTxModel = await buildUnsignedTxModel(actualTxLocalInfoModel, senderWallet); - SignedTxModel actualSignedTxModel = TxUtils.sign( - unsignedTxModel: actualUnsignedTxModel, - wallet: senderWallet, - ); + SignedTxModel actualSignedTxModel = actualUnsignedTxModel.sign(senderWallet); // Assert SignedTxModel expectedSignedTxModel = SignedTxModel( txLocalInfoModel: actualTxLocalInfoModel, txRemoteInfoModel: expectedTxRemoteInfoModel, - publicKeyCompressed: 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8', - signatureModel: const SignatureModel( - signature: 'SP135sI53JAnIENl3AZJoxvDXhBwCyJXuYD0HfJBVooQEHB+tyl1kkNhbyyisobSXaHpaa/Je3J2LoRzOF1zCw==', + signedCosmosTx: CosmosTx.signed( + authInfo: cosmosAuthInfo, + body: CosmosTxBody( + memo: 'Test of MsgRequestIdentityRecordsVerify message', + messages: [ + MsgRequestIdentityRecordsVerify( + recordIds: [964], + address: CosmosAccAddress('kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx'), + verifier: CosmosAccAddress('kira177lwmjyjds3cy7trers83r4pjn3dhv8zrqk9dl'), + tip: CosmosCoin(denom: 'ukex', amount: BigInt.from(200)), + ), + ], + ), + signatures: [ + CosmosSignature( + r: BigInt.parse('87859255067317020921640288784812661833164655904358063561080693251729950488999'), + s: BigInt.parse('39595110096392771142131991733046522340996157809851989421741243827765031450878'), + ), + ], ), ); - TestUtils.printInfo('Should return [SignedTxModel] with [IRMsgRequestVerificationModel] message'); - expect( - actualSignedTxModel, - expectedSignedTxModel, - ); + TestUtils.printInfo('Should [return SignedTxModel] with IRMsgRequestVerificationModel message'); + expect(actualSignedTxModel, expectedSignedTxModel); + + // ************************************************************************************************************* // Act - BroadcastReq actualBroadcastReq = BroadcastReq(tx: Tx.fromSignedTxModel(actualSignedTxModel)); + BroadcastReq actualBroadcastReq = BroadcastReq(tx: actualSignedTxModel.signedCosmosTx); // Assert Map expectedBroadcastReqJson = { @@ -316,47 +366,46 @@ Future main() async { { '@type': '/kira.gov.MsgRequestIdentityRecordsVerify', 'address': 'kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx', - 'record_ids': ['964'], - 'tip': {'amount': '200', 'denom': 'ukex'}, - 'verifier': 'kira177lwmjyjds3cy7trers83r4pjn3dhv8zrqk9dl' + 'verifier': 'kira177lwmjyjds3cy7trers83r4pjn3dhv8zrqk9dl', + 'record_ids': [964], + 'tip': {'denom': 'ukex', 'amount': '200'} } ], 'memo': 'Test of MsgRequestIdentityRecordsVerify message', 'timeout_height': '0', - 'extension_options': [], - 'non_critical_extension_options': [] + 'extension_options': [], + 'non_critical_extension_options': [] }, 'auth_info': { 'signer_infos': [ { 'public_key': {'@type': '/cosmos.crypto.secp256k1.PubKey', 'key': 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8'}, 'mode_info': { - 'single': {'mode': 'SIGN_MODE_LEGACY_AMINO_JSON'} + 'single': {'mode': 'SIGN_MODE_DIRECT'} }, 'sequence': '106' } ], 'fee': { + 'gas_limit': '20000', 'amount': [ - {'amount': '200', 'denom': 'ukex'} + {'denom': 'ukex', 'amount': '200'} ], - 'gas_limit': '999999' + 'payer': null, + 'granter': null } }, - 'signatures': ['SP135sI53JAnIENl3AZJoxvDXhBwCyJXuYD0HfJBVooQEHB+tyl1kkNhbyyisobSXaHpaa/Je3J2LoRzOF1zCw=='] + 'signatures': ['wj6TfOey21l2Bba4/zBgMhYn36CC4pvyNpM5trp/uadXignDER2Hz7AoQFxWvN/pmll/Wu/KyyNl5Ouej6e4/g=='] }, 'mode': 'block' }; - TestUtils.printInfo('Should return [Tx] as json with [IRMsgRequestVerificationModel] message'); - expect( - actualBroadcastReq.toJson(), - expectedBroadcastReqJson, - ); + TestUtils.printInfo('Should [return BroadcastReq] as json with IRMsgRequestVerificationModel message'); + expect(actualBroadcastReq.toJson(), expectedBroadcastReqJson); }); - test('Should return signed transaction with [IRMsgCancelVerificationRequestModel] message', () async { - final TxLocalInfoModel actualTxLocalInfoModel = TxLocalInfoModel( + test('Should [return signed transaction] with IRMsgCancelVerificationRequestModel message', () async { + TxLocalInfoModel actualTxLocalInfoModel = TxLocalInfoModel( memo: 'Test of MsgCancelIdentityRecordsVerifyRequest message', feeTokenAmountModel: feeTokenAmountModel, txMsgModel: IRMsgCancelVerificationRequestModel( @@ -367,29 +416,39 @@ Future main() async { // Act UnsignedTxModel actualUnsignedTxModel = await buildUnsignedTxModel(actualTxLocalInfoModel, senderWallet); - SignedTxModel actualSignedTxModel = TxUtils.sign( - unsignedTxModel: actualUnsignedTxModel, - wallet: senderWallet, - ); + SignedTxModel actualSignedTxModel = actualUnsignedTxModel.sign(senderWallet); // Assert SignedTxModel expectedSignedTxModel = SignedTxModel( txLocalInfoModel: actualTxLocalInfoModel, txRemoteInfoModel: expectedTxRemoteInfoModel, - publicKeyCompressed: 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8', - signatureModel: const SignatureModel( - signature: 'egYEN3Npnb6lqcQ5mStDQ0KXezrUTlj8iBIRho3yzOZXDPMIT6xEs8jYs/zeV96UVkD6cc3u/2FpeqsoT2qs2Q==', + signedCosmosTx: CosmosTx.signed( + authInfo: cosmosAuthInfo, + body: CosmosTxBody( + memo: 'Test of MsgCancelIdentityRecordsVerifyRequest message', + messages: [ + MsgCancelIdentityRecordsVerifyRequest( + executor: CosmosAccAddress('kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx'), + verifyRequestId: BigInt.from(3), + ), + ], + ), + signatures: [ + CosmosSignature( + r: BigInt.parse('9222004436251072072237146921185648206129469369723953401938276983576476066620'), + s: BigInt.parse('23127075334067262420724200782451981690599091574700651770491012559622830886350'), + ), + ], ), ); - TestUtils.printInfo('Should return [SignedTxModel] with [IRMsgCancelVerificationRequestModel] message'); - expect( - actualSignedTxModel, - expectedSignedTxModel, - ); + TestUtils.printInfo('Should [return SignedTxModel] with IRMsgCancelVerificationRequestModel message'); + expect(actualSignedTxModel, expectedSignedTxModel); + + // ************************************************************************************************************* // Act - BroadcastReq actualBroadcastReq = BroadcastReq(tx: Tx.fromSignedTxModel(actualSignedTxModel)); + BroadcastReq actualBroadcastReq = BroadcastReq(tx: actualSignedTxModel.signedCosmosTx); // Assert Map expectedBroadcastReqJson = { @@ -400,40 +459,39 @@ Future main() async { ], 'memo': 'Test of MsgCancelIdentityRecordsVerifyRequest message', 'timeout_height': '0', - 'extension_options': [], - 'non_critical_extension_options': [] + 'extension_options': [], + 'non_critical_extension_options': [] }, 'auth_info': { 'signer_infos': [ { 'public_key': {'@type': '/cosmos.crypto.secp256k1.PubKey', 'key': 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8'}, 'mode_info': { - 'single': {'mode': 'SIGN_MODE_LEGACY_AMINO_JSON'} + 'single': {'mode': 'SIGN_MODE_DIRECT'} }, 'sequence': '106' } ], 'fee': { + 'gas_limit': '20000', 'amount': [ - {'amount': '200', 'denom': 'ukex'} + {'denom': 'ukex', 'amount': '200'} ], - 'gas_limit': '999999' + 'payer': null, + 'granter': null } }, - 'signatures': ['egYEN3Npnb6lqcQ5mStDQ0KXezrUTlj8iBIRho3yzOZXDPMIT6xEs8jYs/zeV96UVkD6cc3u/2FpeqsoT2qs2Q=='] + 'signatures': ['FGN4M8QelKz4mVZfmlRimHZ0lRdYyZEp8jby9UKBIzwzIXX0w+0WLCN5GwYL2BRpMhrXxy1UbEkiizSvBmUNzg=='] }, 'mode': 'block' }; - TestUtils.printInfo('Should return [Tx] as json with [IRMsgCancelVerificationRequestModel] message'); - expect( - actualBroadcastReq.toJson(), - expectedBroadcastReqJson, - ); + TestUtils.printInfo('Should [return BroadcastReq] as json with IRMsgCancelVerificationRequestModel message'); + expect(actualBroadcastReq.toJson(), expectedBroadcastReqJson); }); - test('Should return signed transaction with [IRMsgDeleteRecordsModel] message', () async { - final TxLocalInfoModel actualTxLocalInfoModel = TxLocalInfoModel( + test('Should [return signed transaction] with IRMsgDeleteRecordsModel message', () async { + TxLocalInfoModel actualTxLocalInfoModel = TxLocalInfoModel( memo: 'Test of MsgDeleteIdentityRecords message', feeTokenAmountModel: feeTokenAmountModel, txMsgModel: IRMsgDeleteRecordsModel.single( @@ -444,29 +502,39 @@ Future main() async { // Act UnsignedTxModel actualUnsignedTxModel = await buildUnsignedTxModel(actualTxLocalInfoModel, senderWallet); - SignedTxModel actualSignedTxModel = TxUtils.sign( - unsignedTxModel: actualUnsignedTxModel, - wallet: senderWallet, - ); + SignedTxModel actualSignedTxModel = actualUnsignedTxModel.sign(senderWallet); // Assert SignedTxModel expectedSignedTxModel = SignedTxModel( txLocalInfoModel: actualTxLocalInfoModel, txRemoteInfoModel: expectedTxRemoteInfoModel, - publicKeyCompressed: 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8', - signatureModel: const SignatureModel( - signature: '7RlYHsYAmMqbeqaI4C3lET3XIdqQgy3StwA1AjccFdQwtp/he34Zhhdu22JbqUTmBGc9zPWPBdTo1/X57UZQAg==', + signedCosmosTx: CosmosTx.signed( + authInfo: cosmosAuthInfo, + body: CosmosTxBody( + memo: 'Test of MsgDeleteIdentityRecords message', + messages: [ + MsgDeleteIdentityRecords( + address: CosmosAccAddress('kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx'), + keys: ['avatar'], + ), + ], + ), + signatures: [ + CosmosSignature( + r: BigInt.parse('79026266621337154156741060753401210162338558944713775541782575273128987403966'), + s: BigInt.parse('5687955546390794418908963039509925541165916791887615280573209458228550913771'), + ), + ], ), ); - TestUtils.printInfo('Should return [SignedTxModel] with [IRMsgDeleteRecordsModel] message'); - expect( - actualSignedTxModel, - expectedSignedTxModel, - ); + TestUtils.printInfo('Should [return SignedTxModel] with IRMsgDeleteRecordsModel message'); + expect(actualSignedTxModel, expectedSignedTxModel); + + // ************************************************************************************************************* // Act - BroadcastReq actualBroadcastReq = BroadcastReq(tx: Tx.fromSignedTxModel(actualSignedTxModel)); + BroadcastReq actualBroadcastReq = BroadcastReq(tx: actualSignedTxModel.signedCosmosTx); // Assert Map expectedBroadcastReqJson = { @@ -481,40 +549,39 @@ Future main() async { ], 'memo': 'Test of MsgDeleteIdentityRecords message', 'timeout_height': '0', - 'extension_options': [], - 'non_critical_extension_options': [] + 'extension_options': [], + 'non_critical_extension_options': [] }, 'auth_info': { 'signer_infos': [ { 'public_key': {'@type': '/cosmos.crypto.secp256k1.PubKey', 'key': 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8'}, 'mode_info': { - 'single': {'mode': 'SIGN_MODE_LEGACY_AMINO_JSON'} + 'single': {'mode': 'SIGN_MODE_DIRECT'} }, 'sequence': '106' } ], 'fee': { + 'gas_limit': '20000', 'amount': [ - {'amount': '200', 'denom': 'ukex'} + {'denom': 'ukex', 'amount': '200'} ], - 'gas_limit': '999999' + 'payer': null, + 'granter': null } }, - 'signatures': ['7RlYHsYAmMqbeqaI4C3lET3XIdqQgy3StwA1AjccFdQwtp/he34Zhhdu22JbqUTmBGc9zPWPBdTo1/X57UZQAg=='] + 'signatures': ['rrdIJi1iHdz+w5xskAqC5gnw8u9pmmqL1MbQikC3Jr4Mk0TM+Z+9Kb0XBI1qcOLhWDg9M/yKo5eIf+v4tONO6w=='] }, 'mode': 'block' }; - TestUtils.printInfo('Should return [Tx] as json with [IRMsgDeleteRecordsModel] message'); - expect( - actualBroadcastReq.toJson(), - expectedBroadcastReqJson, - ); + TestUtils.printInfo('Should [return BroadcastReq] as json with IRMsgDeleteRecordsModel message'); + expect(actualBroadcastReq.toJson(), expectedBroadcastReqJson); }); - test('Should return signed transaction with [IRMsgHandleVerificationRequestModel] message', () async { - final TxLocalInfoModel actualTxLocalInfoModel = TxLocalInfoModel( + test('Should [return signed transaction] with IRMsgHandleVerificationRequestModel message', () async { + TxLocalInfoModel actualTxLocalInfoModel = TxLocalInfoModel( memo: 'Test of MsgHandleIdentityRecordsVerifyRequest message', feeTokenAmountModel: feeTokenAmountModel, txMsgModel: IRMsgHandleVerificationRequestModel( @@ -526,29 +593,40 @@ Future main() async { // Act UnsignedTxModel actualUnsignedTxModel = await buildUnsignedTxModel(actualTxLocalInfoModel, senderWallet); - SignedTxModel actualSignedTxModel = TxUtils.sign( - unsignedTxModel: actualUnsignedTxModel, - wallet: senderWallet, - ); + SignedTxModel actualSignedTxModel = actualUnsignedTxModel.sign(senderWallet); // Assert SignedTxModel expectedSignedTxModel = SignedTxModel( txLocalInfoModel: actualTxLocalInfoModel, txRemoteInfoModel: expectedTxRemoteInfoModel, - publicKeyCompressed: 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8', - signatureModel: const SignatureModel( - signature: 'GqNVZKBGhhE0udHNFJ+g3KhveVkT0BkWPeMQR0Jx6wlO3gYzAzN9nV/KcZQCgKSpYfxLXxEeayVucHnHM9gVGw==', + signedCosmosTx: CosmosTx.signed( + authInfo: cosmosAuthInfo, + body: CosmosTxBody( + memo: 'Test of MsgHandleIdentityRecordsVerifyRequest message', + messages: [ + MsgHandleIdentityRecordsVerifyRequest( + verifier: CosmosAccAddress('kira177lwmjyjds3cy7trers83r4pjn3dhv8zrqk9dl'), + verifyRequestId: 2, + yes: true, + ), + ], + ), + signatures: [ + CosmosSignature( + r: BigInt.parse('72933007490609640501865487430495147621153330076791856292083884954279647403436'), + s: BigInt.parse('18666428172386819201137480101541341517569119196844379112158234304637595425789'), + ), + ], ), ); - TestUtils.printInfo('Should return SignedTxModel with IRMsgHandleVerificationRequestModel message'); - expect( - actualSignedTxModel, - expectedSignedTxModel, - ); + TestUtils.printInfo('Should [return SignedTxModel] with IRMsgHandleVerificationRequestModel message'); + expect(actualSignedTxModel, expectedSignedTxModel); + + // ************************************************************************************************************* // Act - BroadcastReq actualBroadcastReq = BroadcastReq(tx: Tx.fromSignedTxModel(actualSignedTxModel)); + BroadcastReq actualBroadcastReq = BroadcastReq(tx: actualSignedTxModel.signedCosmosTx); // Assert Map expectedBroadcastReqJson = { @@ -564,40 +642,39 @@ Future main() async { ], 'memo': 'Test of MsgHandleIdentityRecordsVerifyRequest message', 'timeout_height': '0', - 'extension_options': [], - 'non_critical_extension_options': [] + 'extension_options': [], + 'non_critical_extension_options': [] }, 'auth_info': { 'signer_infos': [ { 'public_key': {'@type': '/cosmos.crypto.secp256k1.PubKey', 'key': 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8'}, 'mode_info': { - 'single': {'mode': 'SIGN_MODE_LEGACY_AMINO_JSON'} + 'single': {'mode': 'SIGN_MODE_DIRECT'} }, 'sequence': '106' } ], 'fee': { + 'gas_limit': '20000', 'amount': [ - {'amount': '200', 'denom': 'ukex'} + {'denom': 'ukex', 'amount': '200'} ], - 'gas_limit': '999999' + 'payer': null, + 'granter': null } }, - 'signatures': ['GqNVZKBGhhE0udHNFJ+g3KhveVkT0BkWPeMQR0Jx6wlO3gYzAzN9nV/KcZQCgKSpYfxLXxEeayVucHnHM9gVGw=='] + 'signatures': ['oT6ej7kXOCV7yhnsK1N/VFl+4VhM/rvx2bkTbezEXawpRNLt4kIghscs1LOYdhVjJ7Om/dPV9Y9ILujvhdIb/Q=='] }, 'mode': 'block' }; - TestUtils.printInfo('Should return Tx json with IRMsgHandleVerificationRequestModel message'); - expect( - actualBroadcastReq.toJson(), - expectedBroadcastReqJson, - ); + TestUtils.printInfo('Should [return BroadcastReq] as json with IRMsgHandleVerificationRequestModel message'); + expect(actualBroadcastReq.toJson(), expectedBroadcastReqJson); }); - test('Should return signed transaction with [MsgDelegate] message', () async { - final TxLocalInfoModel actualTxLocalInfoModel = TxLocalInfoModel( + test('Should [return signed transaction] with MsgDelegate message', () async { + TxLocalInfoModel actualTxLocalInfoModel = TxLocalInfoModel( memo: 'Test of MsgDelegate message', feeTokenAmountModel: feeTokenAmountModel, txMsgModel: StakingMsgDelegateModel.single( @@ -612,29 +689,40 @@ Future main() async { // Act UnsignedTxModel actualUnsignedTxModel = await buildUnsignedTxModel(actualTxLocalInfoModel, senderWallet); - SignedTxModel actualSignedTxModel = TxUtils.sign( - unsignedTxModel: actualUnsignedTxModel, - wallet: senderWallet, - ); + SignedTxModel actualSignedTxModel = actualUnsignedTxModel.sign(senderWallet); // Assert SignedTxModel expectedSignedTxModel = SignedTxModel( txLocalInfoModel: actualTxLocalInfoModel, txRemoteInfoModel: expectedTxRemoteInfoModel, - publicKeyCompressed: 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8', - signatureModel: const SignatureModel( - signature: '+VDMEjwfiab+bolnQzY4G5q1E0a8sIln0k0EA1b6ReJGvWymB/hjvNlu2pdqavKCslwfrAQVQP2isqrxbz2FZA==', + signedCosmosTx: CosmosTx.signed( + authInfo: cosmosAuthInfo, + body: CosmosTxBody( + memo: 'Test of MsgDelegate message', + messages: [ + MsgDelegate( + delegatorAddress: 'kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx', + valoperAddress: 'kiravaloper1c6slygj2tx7hzm0mn4qeflqpvngj73c2cw7fh7', + amounts: [CosmosCoin(denom: 'ukex', amount: BigInt.from(100))], + ), + ], + ), + signatures: [ + CosmosSignature( + r: BigInt.parse('55717454601243069088841521135755802532418319520050179086645302401638805298598'), + s: BigInt.parse('23913435960359395132492905352374853547098518607227882426156179958185778028864'), + ), + ], ), ); - TestUtils.printInfo('Should return [SignedTxModel] with [StakingMsgDelegateModel] message'); - expect( - actualSignedTxModel, - expectedSignedTxModel, - ); + TestUtils.printInfo('Should [return SignedTxModel] with StakingMsgDelegateModel message'); + expect(actualSignedTxModel, expectedSignedTxModel); + + // ************************************************************************************************************* // Act - BroadcastReq actualBroadcastReq = BroadcastReq(tx: Tx.fromSignedTxModel(actualSignedTxModel)); + BroadcastReq actualBroadcastReq = BroadcastReq(tx: actualSignedTxModel.signedCosmosTx); // Assert Map expectedBroadcastReqJson = { @@ -646,49 +734,45 @@ Future main() async { 'delegator_address': 'kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx', 'validator_address': 'kiravaloper1c6slygj2tx7hzm0mn4qeflqpvngj73c2cw7fh7', 'amounts': [ - { - 'amount': '100', - 'denom': 'ukex', - } + {'denom': 'ukex', 'amount': '100'} ] } ], 'memo': 'Test of MsgDelegate message', 'timeout_height': '0', - 'extension_options': [], - 'non_critical_extension_options': [] + 'extension_options': [], + 'non_critical_extension_options': [] }, 'auth_info': { 'signer_infos': [ { 'public_key': {'@type': '/cosmos.crypto.secp256k1.PubKey', 'key': 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8'}, 'mode_info': { - 'single': {'mode': 'SIGN_MODE_LEGACY_AMINO_JSON'} + 'single': {'mode': 'SIGN_MODE_DIRECT'} }, 'sequence': '106' } ], 'fee': { + 'gas_limit': '20000', 'amount': [ - {'amount': '200', 'denom': 'ukex'} + {'denom': 'ukex', 'amount': '200'} ], - 'gas_limit': '999999' + 'payer': null, + 'granter': null } }, - 'signatures': ['+VDMEjwfiab+bolnQzY4G5q1E0a8sIln0k0EA1b6ReJGvWymB/hjvNlu2pdqavKCslwfrAQVQP2isqrxbz2FZA=='] + 'signatures': ['ey72NRNmSpw+WSvcQQlszNrYe7MV3PNhGF+5QqAwXaY03oZte3st8EvOFmKKt+3GVJvO1yPBPNnrhRjC2ukhQA=='] }, 'mode': 'block' }; - TestUtils.printInfo('Should return [Tx] as json with [MsgDelegate] message'); - expect( - actualBroadcastReq.toJson(), - expectedBroadcastReqJson, - ); + TestUtils.printInfo('Should [return BroadcastReq] as json with MsgDelegate message'); + expect(actualBroadcastReq.toJson(), expectedBroadcastReqJson); }); - test('Should return signed transaction with [MsgUndelegate] message', () async { - final TxLocalInfoModel actualTxLocalInfoModel = TxLocalInfoModel( + test('Should [return signed transaction] with MsgUndelegate message', () async { + TxLocalInfoModel actualTxLocalInfoModel = TxLocalInfoModel( memo: 'Test of MsgUndelegate message', feeTokenAmountModel: feeTokenAmountModel, txMsgModel: StakingMsgUndelegateModel.single( @@ -703,29 +787,40 @@ Future main() async { // Act UnsignedTxModel actualUnsignedTxModel = await buildUnsignedTxModel(actualTxLocalInfoModel, senderWallet); - SignedTxModel actualSignedTxModel = TxUtils.sign( - unsignedTxModel: actualUnsignedTxModel, - wallet: senderWallet, - ); + SignedTxModel actualSignedTxModel = actualUnsignedTxModel.sign(senderWallet); // Assert SignedTxModel expectedSignedTxModel = SignedTxModel( txLocalInfoModel: actualTxLocalInfoModel, txRemoteInfoModel: expectedTxRemoteInfoModel, - publicKeyCompressed: 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8', - signatureModel: const SignatureModel( - signature: '//rz08ukc2feJPf/PB8OR+JjZL+NI7kXkmhjb0I+TxkJfjPBtgoFPy6UfEkWtU9QAccAj94jX8TtrQ00j6L6+Q==', + signedCosmosTx: CosmosTx.signed( + authInfo: cosmosAuthInfo, + body: CosmosTxBody( + memo: 'Test of MsgUndelegate message', + messages: [ + MsgUndelegate( + delegatorAddress: 'kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx', + valoperAddress: 'kiravaloper1c6slygj2tx7hzm0mn4qeflqpvngj73c2cw7fh7', + amounts: [CosmosCoin(denom: 'ukex', amount: BigInt.from(100))], + ), + ], + ), + signatures: [ + CosmosSignature( + r: BigInt.parse('72662442560263102468806670475645295622932430335239902677926380471518172892103'), + s: BigInt.parse('27868048802058524184290366108124533155351530920507136071634942531294406595168'), + ), + ], ), ); - TestUtils.printInfo('Should return [SignedTxModel] with [StakingMsgUndelegateModel] message'); - expect( - actualSignedTxModel, - expectedSignedTxModel, - ); + TestUtils.printInfo('Should [return SignedTxModel] with StakingMsgUndelegateModel message'); + expect(actualSignedTxModel, expectedSignedTxModel); + + // ************************************************************************************************************* // Act - BroadcastReq actualBroadcastReq = BroadcastReq(tx: Tx.fromSignedTxModel(actualSignedTxModel)); + BroadcastReq actualBroadcastReq = BroadcastReq(tx: actualSignedTxModel.signedCosmosTx); // Assert Map expectedBroadcastReqJson = { @@ -737,49 +832,45 @@ Future main() async { 'delegator_address': 'kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx', 'validator_address': 'kiravaloper1c6slygj2tx7hzm0mn4qeflqpvngj73c2cw7fh7', 'amounts': [ - { - 'amount': '100', - 'denom': 'ukex', - } + {'denom': 'ukex', 'amount': '100'} ] } ], 'memo': 'Test of MsgUndelegate message', 'timeout_height': '0', - 'extension_options': [], - 'non_critical_extension_options': [] + 'extension_options': [], + 'non_critical_extension_options': [] }, 'auth_info': { 'signer_infos': [ { 'public_key': {'@type': '/cosmos.crypto.secp256k1.PubKey', 'key': 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8'}, 'mode_info': { - 'single': {'mode': 'SIGN_MODE_LEGACY_AMINO_JSON'} + 'single': {'mode': 'SIGN_MODE_DIRECT'} }, 'sequence': '106' } ], 'fee': { + 'gas_limit': '20000', 'amount': [ - {'amount': '200', 'denom': 'ukex'} + {'denom': 'ukex', 'amount': '200'} ], - 'gas_limit': '999999' + 'payer': null, + 'granter': null } }, - 'signatures': ['//rz08ukc2feJPf/PB8OR+JjZL+NI7kXkmhjb0I+TxkJfjPBtgoFPy6UfEkWtU9QAccAj94jX8TtrQ00j6L6+Q=='] + 'signatures': ['oKV8LK9bvfakBapLQ1gczT9w6AKIa+Z0orJCqU6xS8c9nMG0PhZAaq1zt9Gczwnr+CpKxqOjAMoQ7DPcPNNSYA=='] }, 'mode': 'block' }; - TestUtils.printInfo('Should return [Tx] as json with [MsgUndelegate] message'); - expect( - actualBroadcastReq.toJson(), - expectedBroadcastReqJson, - ); + TestUtils.printInfo('Should [return BroadcastReq] as json with MsgUndelegate message'); + expect(actualBroadcastReq.toJson(), expectedBroadcastReqJson); }); - test('Should return signed transaction with [MsgClaimRewards] message', () async { - final TxLocalInfoModel actualTxLocalInfoModel = TxLocalInfoModel( + test('Should [return signed transaction] with MsgClaimRewards message', () async { + TxLocalInfoModel actualTxLocalInfoModel = TxLocalInfoModel( memo: 'Test of MsgClaimRewards message', feeTokenAmountModel: feeTokenAmountModel, txMsgModel: StakingMsgClaimRewardsModel( @@ -789,77 +880,80 @@ Future main() async { // Act UnsignedTxModel actualUnsignedTxModel = await buildUnsignedTxModel(actualTxLocalInfoModel, senderWallet); - SignedTxModel actualSignedTxModel = TxUtils.sign( - unsignedTxModel: actualUnsignedTxModel, - wallet: senderWallet, - ); + SignedTxModel actualSignedTxModel = actualUnsignedTxModel.sign(senderWallet); // Assert SignedTxModel expectedSignedTxModel = SignedTxModel( txLocalInfoModel: actualTxLocalInfoModel, txRemoteInfoModel: expectedTxRemoteInfoModel, - publicKeyCompressed: 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8', - signatureModel: const SignatureModel( - signature: 'n7LHpDL0eFVCospJCjR8EH9C+ib7COZ8p0CVf1z1vD0BAq0j2LDfKVot4lQrV7io0pqdHjxUy7gZq7rLjaSsxA==', + signedCosmosTx: CosmosTx.signed( + authInfo: cosmosAuthInfo, + body: CosmosTxBody( + memo: 'Test of MsgClaimRewards message', + messages: [ + MsgClaimRewards(sender: 'kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx'), + ], + ), + signatures: [ + CosmosSignature( + r: BigInt.parse('86425581516026662676457875278640935065194214567737986990204734494410721421215'), + s: BigInt.parse('32517379701721149843822157155487302717605475570919901277046173146033855619460'), + ), + ], ), ); - TestUtils.printInfo('Should return [SignedTxModel] with [StakingMsgClaimRewardsModel] message'); - expect( - actualSignedTxModel, - expectedSignedTxModel, - ); + TestUtils.printInfo('Should [return SignedTxModel] with StakingMsgClaimRewardsModel message'); + expect(actualSignedTxModel, expectedSignedTxModel); + + // ************************************************************************************************************* // Act - BroadcastReq actualBroadcastReq = BroadcastReq(tx: Tx.fromSignedTxModel(actualSignedTxModel)); + BroadcastReq actualBroadcastReq = BroadcastReq(tx: actualSignedTxModel.signedCosmosTx); // Assert Map expectedBroadcastReqJson = { 'tx': { 'body': { 'messages': [ - { - '@type': '/kira.multistaking.MsgClaimRewards', - 'sender': 'kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx', - } + {'@type': '/kira.multistaking.MsgClaimRewards', 'sender': 'kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx'} ], 'memo': 'Test of MsgClaimRewards message', 'timeout_height': '0', - 'extension_options': [], - 'non_critical_extension_options': [] + 'extension_options': [], + 'non_critical_extension_options': [] }, 'auth_info': { 'signer_infos': [ { 'public_key': {'@type': '/cosmos.crypto.secp256k1.PubKey', 'key': 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8'}, 'mode_info': { - 'single': {'mode': 'SIGN_MODE_LEGACY_AMINO_JSON'} + 'single': {'mode': 'SIGN_MODE_DIRECT'} }, 'sequence': '106' } ], 'fee': { + 'gas_limit': '20000', 'amount': [ - {'amount': '200', 'denom': 'ukex'} + {'denom': 'ukex', 'amount': '200'} ], - 'gas_limit': '999999' + 'payer': null, + 'granter': null } }, - 'signatures': ['n7LHpDL0eFVCospJCjR8EH9C+ib7COZ8p0CVf1z1vD0BAq0j2LDfKVot4lQrV7io0pqdHjxUy7gZq7rLjaSsxA=='] + 'signatures': ['vxMlSVwd9X+NqFhDRhA1UYJ+qCGWuDMsF8fQiHz/Z59H5C9H8EmpDdTuk4waYvNeOkVsLTFJ2n9tCMY1dlNhhA=='] }, 'mode': 'block' }; - TestUtils.printInfo('Should return [Tx] as json with [MsgClaimRewards] message'); - expect( - actualBroadcastReq.toJson(), - expectedBroadcastReqJson, - ); + TestUtils.printInfo('Should [return BroadcastReq] as json with MsgClaimRewards message'); + expect(actualBroadcastReq.toJson(), expectedBroadcastReqJson); }); - test('Should return signed transaction with [MsgClaimUndelegation] message', () async { - final TxLocalInfoModel actualTxLocalInfoModel = TxLocalInfoModel( - memo: 'Test of ClaimUndelegation message', + test('Should [return signed transaction] with MsgClaimUndelegation message', () async { + TxLocalInfoModel actualTxLocalInfoModel = TxLocalInfoModel( + memo: 'Test of MsgClaimUndelegation message', feeTokenAmountModel: feeTokenAmountModel, txMsgModel: StakingMsgClaimUndelegationModel( senderWalletAddress: senderWallet.address, @@ -869,77 +963,82 @@ Future main() async { // Act UnsignedTxModel actualUnsignedTxModel = await buildUnsignedTxModel(actualTxLocalInfoModel, senderWallet); - SignedTxModel actualSignedTxModel = TxUtils.sign( - unsignedTxModel: actualUnsignedTxModel, - wallet: senderWallet, - ); + SignedTxModel actualSignedTxModel = actualUnsignedTxModel.sign(senderWallet); // Assert SignedTxModel expectedSignedTxModel = SignedTxModel( txLocalInfoModel: actualTxLocalInfoModel, txRemoteInfoModel: expectedTxRemoteInfoModel, - publicKeyCompressed: 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8', - signatureModel: const SignatureModel( - signature: '0N4MNaiczcv8Qot5UD0c6aPbG1dttpiI8WCnlynndMk3M0H0m+bnr7RokB35YAscTRchBL1P+i7134q3ksgQ3w==', + signedCosmosTx: CosmosTx.signed( + authInfo: cosmosAuthInfo, + body: CosmosTxBody( + memo: 'Test of MsgClaimUndelegation message', + messages: [ + MsgClaimUndelegation( + sender: 'kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx', + undelegationId: BigInt.from(1), + ), + ], + ), + signatures: [ + CosmosSignature( + r: BigInt.parse('28706132851713258574618795789951122613176729275793441545562718387318134318988'), + s: BigInt.parse('18127497915722753838224045169955328765611750941145002583780850480177807109555'), + ), + ], ), ); - TestUtils.printInfo('Should return [SignedTxModel] with [StakingMsgClaimUndelegationModel] message'); - expect( - actualSignedTxModel, - expectedSignedTxModel, - ); + TestUtils.printInfo('Should [return SignedTxModel] with StakingMsgClaimUndelegationModel message'); + expect(actualSignedTxModel, expectedSignedTxModel); + + // ************************************************************************************************************* // Act - BroadcastReq actualBroadcastReq = BroadcastReq(tx: Tx.fromSignedTxModel(actualSignedTxModel)); + BroadcastReq actualBroadcastReq = BroadcastReq(tx: actualSignedTxModel.signedCosmosTx); // Assert Map expectedBroadcastReqJson = { 'tx': { 'body': { 'messages': [ - { - '@type': '/kira.multistaking.MsgClaimUndelegation', - 'sender': 'kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx', - 'undelegation_id': '1', - } + {'@type': '/kira.multistaking.MsgClaimUndelegation', 'sender': 'kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx', 'undelegation_id': '1'} ], - 'memo': 'Test of ClaimUndelegation message', + 'memo': 'Test of MsgClaimUndelegation message', 'timeout_height': '0', - 'extension_options': [], - 'non_critical_extension_options': [] + 'extension_options': [], + 'non_critical_extension_options': [] }, 'auth_info': { 'signer_infos': [ { 'public_key': {'@type': '/cosmos.crypto.secp256k1.PubKey', 'key': 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8'}, 'mode_info': { - 'single': {'mode': 'SIGN_MODE_LEGACY_AMINO_JSON'} + 'single': {'mode': 'SIGN_MODE_DIRECT'} }, 'sequence': '106' } ], 'fee': { + 'gas_limit': '20000', 'amount': [ - {'amount': '200', 'denom': 'ukex'} + {'denom': 'ukex', 'amount': '200'} ], - 'gas_limit': '999999' + 'payer': null, + 'granter': null } }, - 'signatures': ['0N4MNaiczcv8Qot5UD0c6aPbG1dttpiI8WCnlynndMk3M0H0m+bnr7RokB35YAscTRchBL1P+i7134q3ksgQ3w=='] + 'signatures': ['P3cYbVw5YzLCCWuq7ck7neCYRhEVrHZBQGHZu9myp4woE8zbp91uA2jF3F2385ZzhREGTwpYcGFqGoWbI8Qtsw=='] }, 'mode': 'block' }; - TestUtils.printInfo('Should return [Tx] as json with [MsgClaimUndelegation] message'); - expect( - actualBroadcastReq.toJson(), - expectedBroadcastReqJson, - ); + TestUtils.printInfo('Should [return BroadcastReq] as json with MsgClaimUndelegation message'); + expect(actualBroadcastReq.toJson(), expectedBroadcastReqJson); }); }); - group('Tests for possible exceptions that can be thrown in [BroadcastService]', () { + group('Tests for possible exceptions that can be thrown in BroadcastService', () { // Arrange late BroadcastService actualBroadcastService; late SignedTxModel actualSignedTxModel; @@ -959,9 +1058,25 @@ Future main() async { ), ), txRemoteInfoModel: expectedTxRemoteInfoModel, - publicKeyCompressed: 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8', - signatureModel: const SignatureModel( - signature: '+Odo/kQ6xBNJCakUnZkmFq0H1tW3pgRYgnLB9ul3iMkj/XElK6pU+bHluRmiONMovMNEDKjvphZeahabtkWTiw==', + signedCosmosTx: CosmosTx.signed( + authInfo: cosmosAuthInfo, + body: CosmosTxBody( + memo: 'Test of MsgRegisterIdentityRecords message', + messages: [ + MsgRegisterIdentityRecords( + address: CosmosAccAddress('kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx'), + infos: [ + const IdentityInfoEntry(key: 'avatar', info: 'https://paganresearch.io/images/kiracore.jpg'), + ], + ), + ], + ), + signatures: [ + CosmosSignature( + r: BigInt.parse('21028702019761272517685992784987639565827921194316081946315444932502726756360'), + s: BigInt.parse('26233124607299580314002343060441837683740545835168470193313814846944351386003'), + ), + ], ), ); }); diff --git a/test/unit/shared/models/keyfile/decrypted_keyfile_model_test.dart b/test/unit/shared/models/keyfile/decrypted_keyfile_model_test.dart index 3124625a..ca90194d 100644 --- a/test/unit/shared/models/keyfile/decrypted_keyfile_model_test.dart +++ b/test/unit/shared/models/keyfile/decrypted_keyfile_model_test.dart @@ -5,8 +5,6 @@ import 'package:miro/shared/entity/keyfile/keyfile_entity.dart'; import 'package:miro/shared/models/keyfile/decrypted_keyfile_model.dart'; import 'package:miro/shared/models/keyfile/encrypted_keyfile_model.dart'; import 'package:miro/shared/models/keyfile/keyfile_secret_data_model.dart'; -import 'package:miro/shared/models/wallet/mnemonic.dart'; -import 'package:miro/shared/models/wallet/wallet.dart'; import 'package:miro/test/mock_locator.dart'; import 'package:miro/test/utils/test_utils.dart'; @@ -16,17 +14,13 @@ Future main() async { await initMockLocator(); await TestUtils.setupNetworkModel(networkUri: Uri.parse('https://healthy.kira.network/')); String actualPassword = '123'; - // @formatter:off - Mnemonic actualMnemonic = Mnemonic(value: 'require point property company tongue busy bench burden caution gadget knee glance thought bulk assist month cereal report quarter tool section often require shield'); - Wallet actualWallet = Wallet.derive(mnemonic: actualMnemonic); - // @formatter:on group('Tests of DecryptedKeyfileModel.buildFileContent() method', () { test('Should [return DecryptedKeyfileModel] representing keyfile in latest version [v2.0.0]', () { // Arrange DecryptedKeyfileModel actualDecryptedKeyfileModel = DecryptedKeyfileModel( version: '2.0.0', - keyfileSecretDataModel: KeyfileSecretDataModel(wallet: actualWallet), + keyfileSecretDataModel: KeyfileSecretDataModel(wallet: TestUtils.wallet), ); // Act @@ -40,7 +34,7 @@ Future main() async { // Assert DecryptedKeyfileModel expectedDecryptedKeyfileModel = DecryptedKeyfileModel( version: '2.0.0', - keyfileSecretDataModel: KeyfileSecretDataModel(wallet: actualWallet), + keyfileSecretDataModel: KeyfileSecretDataModel(wallet: TestUtils.wallet), ); expect(actualDecryptedKeyfileModel, expectedDecryptedKeyfileModel); @@ -52,7 +46,7 @@ Future main() async { // Arrange DecryptedKeyfileModel decryptedKeyfileModel = DecryptedKeyfileModel( version: '2.0.0', - keyfileSecretDataModel: KeyfileSecretDataModel(wallet: actualWallet), + keyfileSecretDataModel: KeyfileSecretDataModel(wallet: TestUtils.wallet), ); // Act @@ -64,4 +58,4 @@ Future main() async { expect(actualFileName, expectedFileName); }); }); -} \ No newline at end of file +} diff --git a/test/unit/shared/models/keyfile/encrypted_keyfile_model_test.dart b/test/unit/shared/models/keyfile/encrypted_keyfile_model_test.dart index 069188f3..4ed8e350 100644 --- a/test/unit/shared/models/keyfile/encrypted_keyfile_model_test.dart +++ b/test/unit/shared/models/keyfile/encrypted_keyfile_model_test.dart @@ -7,8 +7,6 @@ import 'package:miro/shared/exceptions/keyfile_exception/keyfile_exception_type. import 'package:miro/shared/models/keyfile/decrypted_keyfile_model.dart'; import 'package:miro/shared/models/keyfile/encrypted_keyfile_model.dart'; import 'package:miro/shared/models/keyfile/keyfile_secret_data_model.dart'; -import 'package:miro/shared/models/wallet/mnemonic.dart'; -import 'package:miro/shared/models/wallet/wallet.dart'; import 'package:miro/test/mock_locator.dart'; import 'package:miro/test/utils/test_utils.dart'; @@ -18,10 +16,6 @@ Future main() async { await initMockLocator(); await TestUtils.setupNetworkModel(networkUri: Uri.parse('https://healthy.kira.network/')); String actualPassword = '123'; - // @formatter:off - Mnemonic actualMnemonic = Mnemonic(value: 'require point property company tongue busy bench burden caution gadget knee glance thought bulk assist month cereal report quarter tool section often require shield'); - Wallet actualWallet = Wallet.derive(mnemonic: actualMnemonic); - // @formatter:on group('Tests of EncryptedKeyfileModel.fromEntity() factory constructor', () { test('Should [return EncryptedKeyfileModel] with version 2.0.0', () { @@ -78,7 +72,7 @@ Future main() async { // Assert DecryptedKeyfileModel expectedDecryptedKeyfileModel = DecryptedKeyfileModel( version: '2.0.0', - keyfileSecretDataModel: KeyfileSecretDataModel(wallet: actualWallet), + keyfileSecretDataModel: KeyfileSecretDataModel(wallet: TestUtils.wallet), ); expect(actualDecryptedKeyfileModel, expectedDecryptedKeyfileModel); diff --git a/test/unit/shared/models/transactions/form_models/ir_msg_request_verification_form_model_test.dart b/test/unit/shared/models/transactions/form_models/ir_msg_request_verification_form_model_test.dart index 4a5289b6..e261854f 100644 --- a/test/unit/shared/models/transactions/form_models/ir_msg_request_verification_form_model_test.dart +++ b/test/unit/shared/models/transactions/form_models/ir_msg_request_verification_form_model_test.dart @@ -126,7 +126,7 @@ void main() { // Assert IRMsgRequestVerificationModel expectedIrMsgRequestVerificationModel = IRMsgRequestVerificationModel( - recordIds: [BigInt.from(3)], + recordIds: const [3], tipTokenAmountModel: actualTipTokenAmountModel, walletAddress: actualRequesterWalletAddress, verifierWalletAddress: actualVerifierWalletAddress, diff --git a/test/unit/shared/models/wallet/wallet_test.dart b/test/unit/shared/models/wallet/wallet_test.dart index e406c1d4..e262bda5 100644 --- a/test/unit/shared/models/wallet/wallet_test.dart +++ b/test/unit/shared/models/wallet/wallet_test.dart @@ -1,7 +1,8 @@ -import 'dart:typed_data'; +import 'dart:convert'; +import 'package:cryptography_utils/cryptography_utils.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:miro/shared/models/wallet/mnemonic.dart'; +import 'package:miro/shared/models/wallet/mnemonic.dart' as miro; import 'package:miro/shared/models/wallet/wallet.dart'; import 'package:miro/shared/models/wallet/wallet_address.dart'; import 'package:miro/test/mock_locator.dart'; @@ -14,89 +15,31 @@ Future main() async { await TestUtils.setupNetworkModel(networkUri: Uri.parse('https://healthy.kira.network/')); // @formatter:off - // Actual Values for tests - const String actualMnemonicString = - 'equal success expand debris crash despair awake bachelor athlete discover drop tilt reveal give oven polar party exact sign chalk hurdle move tilt chronic'; - final Mnemonic actualMnemonic = Mnemonic(value: actualMnemonicString); - final Wallet actualWallet = Wallet.derive(mnemonic: actualMnemonic); - - const Map actualKeyfilePublicJSON = { - 'version': '2.0.0', - 'bech32Address': 'kira1gdury9ednrjj8fluwj9ea5e6cu5jr9jvekl7u3', - }; - - const Map actualKeyfilePrivateJSON = { - 'privateKey': '9e737e02d062c101729fbd1483a87642dfc430c147e9733bc0f0d86855785e3c', - }; - - // Expected Values of tests - List expectedPrivateKey = [158, 115, 126, 2, 208, 98, 193, 1, 114, 159, 189, 20, 131, 168, 118, 66, 223, 196, 48, 193, 71, 233, 115, 59, 192, 240, 216, 104, 85, 120, 94, 60]; - List expectedAddress = [67, 120, 50, 23, 45, 152, 229, 35, 167, 252, 116, 139, 158, 211, 58, 199, 41, 33, 150, 76]; - - String expectedBech32address = 'kira1gdury9ednrjj8fluwj9ea5e6cu5jr9jvekl7u3'; - - Wallet expectedWallet = Wallet( - privateKey: Uint8List.fromList(expectedPrivateKey), - address: WalletAddress(addressBytes: Uint8List.fromList(expectedAddress)), - ); + String actualMnemonicString = 'equal success expand debris crash despair awake bachelor athlete discover drop tilt reveal give oven polar party exact sign chalk hurdle move tilt chronic'; + miro.Mnemonic actualMnemonic = miro.Mnemonic(value: actualMnemonicString); // @formatter:on group('Tests of factory constructor Wallet.derive()', () { test('Should create wallet keys from derived mnemonic', () async { - expect( - actualWallet, - expectedWallet, - ); - }); - test('Should throw FormatException, because lastDerivationPathSegment is less than zero', () async { - expect( - () => Wallet.derive(mnemonic: actualMnemonic, lastDerivationPathSegment: '-1'), - throwsA(isA()), - ); - }); - test('Should throw FormatException, because lastDerivationPathSegment is not a number', () async { - expect( - () => Wallet.derive(mnemonic: actualMnemonic, lastDerivationPathSegment: 'abc'), - throwsA(isA()), - ); - }); - }); + // Act + Wallet actualWallet = await Wallet.derive(mnemonic: actualMnemonic); - group('Tests of factory constructor Wallet.fromKeyfileData()', () { - test('Should create wallet keys from derived private and public json', () async { - expect( - Wallet.fromKeyfileData(actualKeyfilePublicJSON, actualKeyfilePrivateJSON), - expectedWallet, + // Assert + Wallet expectedWallet = Wallet( + ecPrivateKey: ECPrivateKey.fromBytes( + base64Decode('nnN+AtBiwQFyn70Ug6h2Qt/EMMFH6XM7wPDYaFV4Xjw='), + CurvePoints.generatorSecp256k1, + ), + address: WalletAddress(addressBytes: base64Decode('Q3gyFy2Y5SOn/HSLntM6xykhlkw=')), ); - }); - }); - group('Test of wallet class arguments and methods', () { - test('Should create valid wallet address from given mnemonic', () async { - expect( - actualWallet.address.addressBytes, - expectedAddress, - ); + expect(actualWallet, expectedWallet); }); - test('Should create valid privateKey from given mnemonic', () async { - expect( - actualWallet.privateKey, - expectedPrivateKey, - ); - }); - - test('Should create valid bech32 address from given mnemonic', () async { - expect( - actualWallet.address.bech32Address, - expectedBech32address, - ); - }); - - test('Should return short bech32 address ex. keyfile_kiraXXXX_XXXX', () async { + test('Should throw FormatException, because lastDerivationPathSegment is not a number', () async { expect( - actualWallet.address.buildBech32AddressShort(delimiter: '...'), - 'kira1gdu...l7u3', + () => Wallet.derive(mnemonic: actualMnemonic, lastDerivationPathSegment: 'abc'), + throwsA(isA()), ); }); }); diff --git a/test/unit/shared/utils/transactions/signature_utils_test.dart b/test/unit/shared/utils/transactions/signature_utils_test.dart deleted file mode 100644 index 4b51ff62..00000000 --- a/test/unit/shared/utils/transactions/signature_utils_test.dart +++ /dev/null @@ -1,203 +0,0 @@ -import 'dart:typed_data'; - -import 'package:flutter_test/flutter_test.dart'; -import 'package:miro/shared/models/transactions/signature_model.dart'; -import 'package:miro/shared/models/wallet/wallet.dart'; -import 'package:miro/shared/models/wallet/wallet_address.dart'; -import 'package:miro/shared/utils/transactions/signature_utils.dart'; -import 'package:miro/test/utils/test_utils.dart'; - -void main() { - Wallet actualWallet = TestUtils.wallet; - - final Map txStdSignDocJson = { - 'account_number': '669', - 'chain_id': 'testnet', - 'fee': { - 'amount': >[ - {'amount': '100', 'denom': 'ukex'} - ], - 'gas': '999999' - }, - 'memo': 'Test transaction', - 'msgs': >[ - { - 'type': 'cosmos-sdk/MsgSend', - 'value': { - 'amount': >[ - {'amount': '100', 'denom': 'ukex'} - ], - 'from_address': 'kira143q8vxpvuykt9pq50e6hng9s38vmy844n8k9wx', - 'to_address': 'kira177lwmjyjds3cy7trers83r4pjn3dhv8zrqk9dl' - } - } - ], - 'sequence': '5' - }; - - final Map queryAccountResponse = { - 'account': { - '@type': '/cosmos.auth.v1beta1.BaseAccount', - 'account_number': '669', - 'address': 'a2lyYTE0M3E4dnhwdnV5a3Q5cHE1MGU2aG5nOXMzOHZteTg0NG44azl3eA==', - 'pub_key': 'Ch8vY29zbW9zLmNyeXB0by5zZWNwMjU2azEuUHViS2V5EiMKIQJS2rPAiepZucmSfIdFOULvZ81b4L7JIB7lETwd471MfA==', - 'sequence': '96' - } - }; - - Map queryAccountResponseSign = { - 'chain_id': 'testnet-9', - 'block': 3914180, - 'block_time': '2022-08-22T10:43:05.682448427Z', - 'timestamp': 1661165056, - 'response': '4da7ce0f135eef0854cc07a1c5d964644769ea409cde2f939af964074278a1e5', - }; - - // @formatter:off - - // 4e1b257c7e926d7881a8838aa6b8a675c6e8a208591b21598a3c1dd1313849b9 - Uint8List stdTxSignDocHashBytes = Uint8List.fromList([78, 27, 37, 124, 126, 146, 109, 120, 129, 168, 131, 138, 166, 184, 166, 117, 198, 232, 162, 8, 89, 27, 33, 89, 138, 60, 29, 209, 49, 56, 73, 185]); - - // 4da7ce0f135eef0854cc07a1c5d964644769ea409cde2f939af964074278a1e5 - Uint8List queryAccountResponseHashBytes = Uint8List.fromList([77, 167, 206, 15, 19, 94, 239, 8, 84, 204, 7, 161, 197, 217, 100, 100, 71, 105, 234, 64, 156, 222, 47, 147, 154, 249, 100, 7, 66, 120, 161, 229]); - - // c25798e59c3c362f40961c2d6e9aaa4be8f229511500423b84b2bb3ac9f3603c - Uint8List queryAccountResponseSignHashBytes = Uint8List.fromList([194, 87, 152, 229, 156, 60, 54, 47, 64, 150, 28, 45, 110, 154, 170, 75, 232, 242, 41, 81, 21, 0, 66, 59, 132, 178, 187, 58, 201, 243, 96, 60]); - - // @formatter:on - - group('Tests of SignatureUtils.generateSignature() method', () { - test('Should return signature for specified json', () { - // Act - SignatureModel actualSignatureModel = SignatureUtils.generateSignature( - wallet: actualWallet, - signatureDataJson: txStdSignDocJson, - ); - - // Assert - SignatureModel expectedSignatureModel = const SignatureModel( - signature: 'GJbeZ35afeBr7XVmclweWEqUE9+QZ/urq52n8wzvEZxGHwvpcSJfyY4SV4DSo4q7IMJjxkol6DTHq/Zlyj4jZA==', - ); - - expect(actualSignatureModel, expectedSignatureModel); - }); - }); - - group('Tests of SignatureUtils.generateSignatureDataHash() method', () { - test('Should encrypt StdSignDoc via SHA256 algorithm', () { - // Act - Uint8List actualSignatureDataHashBytes = SignatureUtils.generateSignatureDataHashBytes(txStdSignDocJson); - - // Assert - Uint8List expectedSignatureDataHashBytes = stdTxSignDocHashBytes; - - expect(actualSignatureDataHashBytes, expectedSignatureDataHashBytes); - }); - - test('Should encrypt Interx Response via SHA256 algorithm', () { - // Act - Uint8List actualSignatureDataHashBytes = SignatureUtils.generateSignatureDataHashBytes(queryAccountResponse); - - // Assert - Uint8List expectedSignatureDataHashBytes = queryAccountResponseHashBytes; - - expect(actualSignatureDataHashBytes, expectedSignatureDataHashBytes); - }); - - test('Should encrypt Interx Response Sign via SHA256 algorithm', () { - // Act - Uint8List actualSignatureDataHashBytes = SignatureUtils.generateSignatureDataHashBytes(queryAccountResponseSign); - - // Assert - Uint8List expectedSignatureDataHashBytes = queryAccountResponseSignHashBytes; - - expect(actualSignatureDataHashBytes, expectedSignatureDataHashBytes); - }); - }); - - group('Tests of SignatureUtils.verifySignature() method', () { - test('Should return true if transaction signature was created with provided address', () { - // Arrange - SignatureModel signatureModel = const SignatureModel( - signature: 'GJbeZ35afeBr7XVmclweWEqUE9+QZ/urq52n8wzvEZxGHwvpcSJfyY4SV4DSo4q7IMJjxkol6DTHq/Zlyj4jZA==', - ); - - Uint8List addressBytes = actualWallet.address.addressBytes; - - // Act - bool actualSignatureValid = SignatureUtils.verifySignature( - addressBytes: addressBytes, - signatureDataHashBytes: stdTxSignDocHashBytes, - signatureModel: signatureModel, - ); - - // Assert - expect(actualSignatureValid, true); - }); - - test('Should return false if transaction signature was not created with provided address', () { - // Arrange - SignatureModel signatureModel = const SignatureModel( - signature: 'CybmU4aM0mgcULqYsQOjYXiR8uWMD7axfyz0vT9nNqQNrN7wXAOiWMcnCFsCbFONKIpMrHcxSVLEZxLh3p34Tg==', - ); - - Uint8List addressBytes = actualWallet.address.addressBytes; - - // Act - bool actualSignatureValid = SignatureUtils.verifySignature( - addressBytes: addressBytes, - signatureDataHashBytes: stdTxSignDocHashBytes, - signatureModel: signatureModel, - ); - - // Assert - expect(actualSignatureValid, false); - }); - - test('Should return true if response signature was created with provided validator address', () { - // Arrange - SignatureModel signatureModel = const SignatureModel( - signature: 'Qg7gb8rnRXaxIVMwqadPb0HkZnnWhHSmVZRRGAITZ7p3rFcsA1cj3CF8iKsHQ1lOYUoDru1IUm//0oNB+0LceQ==', - ); - - // Uint8List publicKeyBytes = Uint8List.fromList(HEX.decode('02813B6B17BDBA3DB6AB44C51B7F0340B705A880D6E98D41B14AE107E9BA0E5B74')); - // Uint8List addressBytes = Secp256k1.publicKeyToAddress(publicKeyBytes); - - WalletAddress walletAddress = WalletAddress.fromBech32('kira15gmk7pr6xlvnmet4g2qcyzt7edp4mwyjhaf894'); - Uint8List addressBytes = walletAddress.addressBytes; - - // Act - bool actualSignatureValid = SignatureUtils.verifySignature( - addressBytes: addressBytes, - signatureDataHashBytes: queryAccountResponseSignHashBytes, - signatureModel: signatureModel, - ); - - // Assert - expect(actualSignatureValid, true); - }); - - test('Should return false if response signature was not created with provided validator address', () { - // Arrange - SignatureModel signatureModel = const SignatureModel( - signature: 'bMfNtQHLWT6TcazOfCTm6u1UG5s9DygWfNLG5e0WWvQUmPzfu3f/TB0wyhOfVjgo+DcTQbZ3iJp0X3KVZ2mheg==', - ); - - // Uint8List publicKeyBytes = Uint8List.fromList(HEX.decode('02813B6B17BDBA3DB6AB44C51B7F0340B705A880D6E98D41B14AE107E9BA0E5B74')); - // Uint8List addressBytes = Secp256k1.publicKeyToAddress(publicKeyBytes); - - WalletAddress walletAddress = WalletAddress.fromBech32('kira15gmk7pr6xlvnmet4g2qcyzt7edp4mwyjhaf894'); - Uint8List addressBytes = walletAddress.addressBytes; - - // Act - bool actualSignatureValid = SignatureUtils.verifySignature( - addressBytes: addressBytes, - signatureDataHashBytes: queryAccountResponseSignHashBytes, - signatureModel: signatureModel, - ); - - // Assert - expect(actualSignatureValid, false); - }); - }); -} diff --git a/test/unit/shared/utils/transactions/tx_utils_test.dart b/test/unit/shared/utils/transactions/tx_utils_test.dart index 388cd1ec..1027961f 100644 --- a/test/unit/shared/utils/transactions/tx_utils_test.dart +++ b/test/unit/shared/utils/transactions/tx_utils_test.dart @@ -1,15 +1,5 @@ -import 'package:decimal/decimal.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:miro/shared/models/tokens/token_alias_model.dart'; -import 'package:miro/shared/models/tokens/token_amount_model.dart'; import 'package:miro/shared/models/tokens/token_denomination_model.dart'; -import 'package:miro/shared/models/transactions/messages/msg_send_model.dart'; -import 'package:miro/shared/models/transactions/signature_model.dart'; -import 'package:miro/shared/models/transactions/signed_transaction_model.dart'; -import 'package:miro/shared/models/transactions/tx_local_info_model.dart'; -import 'package:miro/shared/models/transactions/tx_remote_info_model.dart'; -import 'package:miro/shared/models/transactions/unsigned_tx_model.dart'; -import 'package:miro/shared/models/wallet/wallet_address.dart'; import 'package:miro/shared/utils/transactions/tx_utils.dart'; import 'package:miro/test/mock_locator.dart'; import 'package:miro/test/utils/test_utils.dart'; @@ -163,54 +153,4 @@ Future main() async { expect(actualEncodedMemo, expectedEncodedMemo); }); }); - - group('Tests of TxUtils.sign() method', () { - test('Should return SignedTxModel with generated signature', () { - // Arrange - TxRemoteInfoModel txRemoteInfoModel = const TxRemoteInfoModel( - accountNumber: '669', - chainId: 'testnet', - sequence: '0', - ); - - TxLocalInfoModel txLocalInfoModel = TxLocalInfoModel( - memo: 'Test transaction', - feeTokenAmountModel: TokenAmountModel( - defaultDenominationAmount: Decimal.fromInt(100), - tokenAliasModel: TokenAliasModel.local('ukex'), - ), - txMsgModel: MsgSendModel( - fromWalletAddress: TestUtils.wallet.address, - toWalletAddress: WalletAddress.fromBech32('kira177lwmjyjds3cy7trers83r4pjn3dhv8zrqk9dl'), - tokenAmountModel: TokenAmountModel( - defaultDenominationAmount: Decimal.fromInt(100), - tokenAliasModel: TokenAliasModel.local('ukex'), - ), - ), - ); - - UnsignedTxModel actualUnsignedTxModel = UnsignedTxModel( - txLocalInfoModel: txLocalInfoModel, - txRemoteInfoModel: txRemoteInfoModel, - ); - - // Act - SignedTxModel actualSignedTxModel = TxUtils.sign( - unsignedTxModel: actualUnsignedTxModel, - wallet: TestUtils.wallet, - ); - - // Assert - SignedTxModel expectedSignedTxModel = SignedTxModel( - publicKeyCompressed: 'AlLas8CJ6lm5yZJ8h0U5Qu9nzVvgvskgHuURPB3jvUx8', - txLocalInfoModel: txLocalInfoModel, - txRemoteInfoModel: txRemoteInfoModel, - signatureModel: const SignatureModel( - signature: 'hd+WiCdVaMcTDshpEsgkn6VOWdXAOV7QKUZEIxMRhLYzSD8bK7RQcn9jl/2I2TLa4QBoCuAStXwOircabaVQzg==', - ), - ); - - expect(actualSignedTxModel, expectedSignedTxModel); - }); - }); }