From 2061576e32574197e08e53e3b81b86e7e8198ab2 Mon Sep 17 00:00:00 2001 From: Josh Leonard <30185185+josheleonard@users.noreply.github.com> Date: Wed, 11 Oct 2023 15:48:05 +0100 Subject: [PATCH] chore: blowfish enums (#19960) --- .../browser/simulation_response_parser.cc | 583 +++++++++++++++++- .../simulation_response_parser_unittest.cc | 236 ++++--- .../browser/simulation_responses.idl | 188 +++++- .../browser/simulation_service_unittest.cc | 28 +- .../brave_wallet/common/brave_wallet.mojom | 205 +++++- .../common/constants/blowfish.ts | 59 +- .../brave_wallet_ui/common/constants/mocks.ts | 215 +++---- components/brave_wallet_ui/constants/types.ts | 158 ++--- .../utils/tx-simulation-utils.ts | 180 ++---- 9 files changed, 1334 insertions(+), 518 deletions(-) diff --git a/components/brave_wallet/browser/simulation_response_parser.cc b/components/brave_wallet/browser/simulation_response_parser.cc index bc6322bf2d01..e53e7f0c5ff1 100644 --- a/components/brave_wallet/browser/simulation_response_parser.cc +++ b/components/brave_wallet/browser/simulation_response_parser.cc @@ -16,12 +16,293 @@ namespace brave_wallet { namespace { +mojom::BlowfishWarningSeverity ParseWarningSeverity( + const simulation_responses::WarningSeverity& severity) { + switch (severity) { + case simulation_responses::WarningSeverity::WARNING_SEVERITY_CRITICAL: + return mojom::BlowfishWarningSeverity::kCritical; + + case simulation_responses::WarningSeverity::WARNING_SEVERITY_WARNING: + return mojom::BlowfishWarningSeverity::kWarning; + + default: + return mojom::BlowfishWarningSeverity::kWarning; + } +} + +mojom::BlowfishWarningKind ParseWarningKind( + const simulation_responses::WarningKind& kind) { + switch (kind) { + case simulation_responses::WarningKind::WARNING_KIND_APPROVAL_TO_E_O_A: + return mojom::BlowfishWarningKind::kApprovalToEOA; + + case simulation_responses::WarningKind:: + WARNING_KIND_BLOCKLISTED_DOMAIN_CROSS_ORIGIN: + return mojom::BlowfishWarningKind::kBlocklistedDomainCrossOrigin; + + case simulation_responses::WarningKind::WARNING_KIND_BULK_APPROVALS_REQUEST: + return mojom::BlowfishWarningKind::kBulkApprovalsRequest; + + case simulation_responses::WarningKind:: + WARNING_KIND_COMPROMISED_AUTHORITY_UPGRADE: + return mojom::BlowfishWarningKind::kCompromisedAuthorityUpgrade; + + case simulation_responses::WarningKind::WARNING_KIND_COPY_CAT_DOMAIN: + return mojom::BlowfishWarningKind::kCopyCatDomain; + + case simulation_responses::WarningKind:: + WARNING_KIND_COPY_CAT_IMAGE_UNRESPONSIVE_DOMAIN: + return mojom::BlowfishWarningKind::kCopyCatImageUnresponsiveDomain; + + case simulation_responses::WarningKind::WARNING_KIND_DANGLING_APPROVAL: + return mojom::BlowfishWarningKind::kDanglingApproval; + + case simulation_responses::WarningKind::WARNING_KIND_DEVTOOLS_DISABLED: + return mojom::BlowfishWarningKind::kDevtoolsDisabled; + + case simulation_responses::WarningKind::WARNING_KIND_ETH_SIGN_TX_HASH: + return mojom::BlowfishWarningKind::kEthSignTxHash; + + case simulation_responses::WarningKind::WARNING_KIND_KNOWN_MALICIOUS: + return mojom::BlowfishWarningKind::kKnownMalicious; + + case simulation_responses::WarningKind:: + WARNING_KIND_MAINNET_REPLAY_POSSIBLE: + return mojom::BlowfishWarningKind::kMainnetReplayPossible; + + case simulation_responses::WarningKind::WARNING_KIND_MULTI_COPY_CAT_DOMAIN: + return mojom::BlowfishWarningKind::kMultiCopyCatDomain; + + case simulation_responses::WarningKind::WARNING_KIND_NEW_DOMAIN: + return mojom::BlowfishWarningKind::kNewDomain; + + case simulation_responses::WarningKind::WARNING_KIND_NON_ASCII_URL: + return mojom::BlowfishWarningKind::kNonAsciiUrl; + + case simulation_responses::WarningKind::WARNING_KIND_OBFUSCATED_CODE: + return mojom::BlowfishWarningKind::kObfuscatedCode; + + case simulation_responses::WarningKind::WARNING_KIND_PERMIT_NO_EXPIRATION: + return mojom::BlowfishWarningKind::kPermitNoExpiration; + + case simulation_responses::WarningKind:: + WARNING_KIND_PERMIT_UNLIMITED_ALLOWANCE: + return mojom::BlowfishWarningKind::kPermitUnlimitedAllowance; + + case simulation_responses::WarningKind::WARNING_KIND_POISONED_ADDRESS: + return mojom::BlowfishWarningKind::kPoisonedAddress; + + case simulation_responses::WarningKind:: + WARNING_KIND_REFERENCED_OFAC_ADDRESS: + return mojom::BlowfishWarningKind::kReferencedOfacAddress; + + case simulation_responses::WarningKind:: + WARNING_KIND_SEMI_TRUSTED_BLOCKLIST_DOMAIN: + return mojom::BlowfishWarningKind::kSemiTrustedBlocklistDomain; + + case simulation_responses::WarningKind::WARNING_KIND_SET_OWNER_AUTHORITY: + return mojom::BlowfishWarningKind::kSetOwnerAuthority; + + case simulation_responses::WarningKind::WARNING_KIND_SUSPECTED_MALICIOUS: + return mojom::BlowfishWarningKind::kSuspectedMalicious; + + case simulation_responses::WarningKind::WARNING_KIND_TOO_MANY_TRANSACTIONS: + return mojom::BlowfishWarningKind::kTooManyTransactions; + + case simulation_responses::WarningKind::WARNING_KIND_TRADE_FOR_NOTHING: + return mojom::BlowfishWarningKind::kTradeForNothing; + + case simulation_responses::WarningKind:: + WARNING_KIND_TRANSFERRING_ERC20_TO_OWN_CONTRACT: + return mojom::BlowfishWarningKind::kTransferringErc20ToOwnContract; + + case simulation_responses::WarningKind:: + WARNING_KIND_TRUSTED_BLOCKLIST_DOMAIN: + return mojom::BlowfishWarningKind::kTrustedBlocklistDomain; + + case simulation_responses::WarningKind:: + WARNING_KIND_UNLIMITED_ALLOWANCE_TO_NFTS: + return mojom::BlowfishWarningKind::kUnlimitedAllowanceToNfts; + + case simulation_responses::WarningKind:: + WARNING_KIND_UNUSUAL_GAS_CONSUMPTION: + return mojom::BlowfishWarningKind::kUnusualGasConsumption; + + case simulation_responses::WarningKind:: + WARNING_KIND_USER_ACCOUNT_OWNER_CHANGE: + return mojom::BlowfishWarningKind::kUserAccountOwnerChange; + + case simulation_responses::WarningKind:: + WARNING_KIND_WHITELISTED_DOMAIN_CROSS_ORIGIN: + return mojom::BlowfishWarningKind::kWhitelistedDomainCrossOrigin; + + default: + return mojom::BlowfishWarningKind::kUnknown; + } +} + +mojom::BlowfishAssetPriceSource ParseAssetPriceSource( + const simulation_responses::AssetPriceSource& source) { + switch (source) { + case simulation_responses::AssetPriceSource::ASSET_PRICE_SOURCE_COINGECKO: + return mojom::BlowfishAssetPriceSource::kCoingecko; + + case simulation_responses::AssetPriceSource::ASSET_PRICE_SOURCE_DEFILLAMA: + return mojom::BlowfishAssetPriceSource::kDefillama; + + case simulation_responses::AssetPriceSource::ASSET_PRICE_SOURCE_SIMPLEHASH: + return mojom::BlowfishAssetPriceSource::kSimplehash; + + default: + return mojom::BlowfishAssetPriceSource::kUnknown; + } +} + +mojom::BlowfishEVMRawInfoKind ParseEVMRawInfoKind( + const simulation_responses::EVMRawInfoKind& kind) { + switch (kind) { + case simulation_responses::EVMRawInfoKind:: + EVM_RAW_INFO_KIND_ANY_NFT_FROM_COLLECTION_TRANSFER: + return mojom::BlowfishEVMRawInfoKind::kAnyNftFromCollectionTransfer; + + case simulation_responses::EVMRawInfoKind:: + EVM_RAW_INFO_KIND_ERC1155_APPROVAL_FOR_ALL: + return mojom::BlowfishEVMRawInfoKind::kErc1155ApprovalForAll; + + case simulation_responses::EVMRawInfoKind:: + EVM_RAW_INFO_KIND_ERC1155_TRANSFER: + return mojom::BlowfishEVMRawInfoKind::kErc1155Transfer; + + case simulation_responses::EVMRawInfoKind::EVM_RAW_INFO_KIND_ERC20_APPROVAL: + return mojom::BlowfishEVMRawInfoKind::kErc20Approval; + + case simulation_responses::EVMRawInfoKind::EVM_RAW_INFO_KIND_ERC20_TRANSFER: + return mojom::BlowfishEVMRawInfoKind::kErc20Transfer; + + case simulation_responses::EVMRawInfoKind:: + EVM_RAW_INFO_KIND_ERC721_APPROVAL: + return mojom::BlowfishEVMRawInfoKind::kErc721Approval; + + case simulation_responses::EVMRawInfoKind:: + EVM_RAW_INFO_KIND_ERC721_APPROVAL_FOR_ALL: + return mojom::BlowfishEVMRawInfoKind::kErc721ApprovalForAll; + + case simulation_responses::EVMRawInfoKind:: + EVM_RAW_INFO_KIND_ERC721_TRANSFER: + return mojom::BlowfishEVMRawInfoKind::kErc721Transfer; + + case simulation_responses::EVMRawInfoKind:: + EVM_RAW_INFO_KIND_NATIVE_ASSET_TRANSFER: + return mojom::BlowfishEVMRawInfoKind::kNativeAssetTransfer; + + default: + return mojom::BlowfishEVMRawInfoKind::kUnknown; + } +} + +mojom::BlowfishSolanaRawInfoKind ParseSolanaRawInfoKind( + const simulation_responses::SolanaRawInfoKind& kind) { + switch (kind) { + case simulation_responses::SolanaRawInfoKind:: + SOLANA_RAW_INFO_KIND_SOL_STAKE_AUTHORITY_CHANGE: + return mojom::BlowfishSolanaRawInfoKind::kSolStakeAuthorityChange; + + case simulation_responses::SolanaRawInfoKind:: + SOLANA_RAW_INFO_KIND_SOL_TRANSFER: + return mojom::BlowfishSolanaRawInfoKind::kSolTransfer; + + case simulation_responses::SolanaRawInfoKind:: + SOLANA_RAW_INFO_KIND_SPL_APPROVAL: + return mojom::BlowfishSolanaRawInfoKind::kSplApproval; + + case simulation_responses::SolanaRawInfoKind:: + SOLANA_RAW_INFO_KIND_SPL_TRANSFER: + return mojom::BlowfishSolanaRawInfoKind::kSplTransfer; + + case simulation_responses::SolanaRawInfoKind:: + SOLANA_RAW_INFO_KIND_USER_ACCOUNT_OWNER_CHANGE: + return mojom::BlowfishSolanaRawInfoKind::kUserAccountOwnerChange; + + default: + return mojom::BlowfishSolanaRawInfoKind::kUnknown; + } +} + +mojom::BlowfishMetaplexTokenStandardKind ParseMetaplexTokenStandardKind( + const simulation_responses::MetaplexTokenStandardKind& kind) { + switch (kind) { + case simulation_responses::MetaplexTokenStandardKind:: + METAPLEX_TOKEN_STANDARD_KIND_FUNGIBLE: + return mojom::BlowfishMetaplexTokenStandardKind::kFungible; + + case simulation_responses::MetaplexTokenStandardKind:: + METAPLEX_TOKEN_STANDARD_KIND_FUNGIBLE_ASSET: + return mojom::BlowfishMetaplexTokenStandardKind::kFungibleAsset; + + case simulation_responses::MetaplexTokenStandardKind:: + METAPLEX_TOKEN_STANDARD_KIND_NON_FUNGIBLE: + return mojom::BlowfishMetaplexTokenStandardKind::kNonFungible; + + case simulation_responses::MetaplexTokenStandardKind:: + METAPLEX_TOKEN_STANDARD_KIND_NON_FUNGIBLE_EDITION: + return mojom::BlowfishMetaplexTokenStandardKind::kNonFungibleEdition; + + default: + return mojom::BlowfishMetaplexTokenStandardKind::kUnknown; + } +} + +mojom::BlowfishEVMErrorKind ParseEVMErrorKind( + const simulation_responses::EVMErrorKind& kind) { + switch (kind) { + case simulation_responses::EVMErrorKind::EVM_ERROR_KIND_SIMULATION_FAILED: + return mojom::BlowfishEVMErrorKind::kSimulationFailed; + + case simulation_responses::EVMErrorKind::EVM_ERROR_KIND_TRANSACTION_ERROR: + return mojom::BlowfishEVMErrorKind::kTransactionError; + + case simulation_responses::EVMErrorKind:: + EVM_ERROR_KIND_TRANSACTION_REVERTED: + return mojom::BlowfishEVMErrorKind::kTransactionReverted; + + case simulation_responses::EVMErrorKind::EVM_ERROR_KIND_UNKNOWN_ERROR: + default: + return mojom::BlowfishEVMErrorKind::kUnknownError; + } +} + +mojom::BlowfishEVMAddressKind ParseBlowfishEVMAddressKind( + const simulation_responses::EVMAddressKind& kind) { + switch (kind) { + case simulation_responses::EVMAddressKind::EVM_ADDRESS_KIND_ACCOUNT: + return mojom::BlowfishEVMAddressKind::kAccount; + + default: + return mojom::BlowfishEVMAddressKind::kUnknown; + } +} + +mojom::BlowfishSuggestedAction ParseBlowfishActionKind( + const std::string& action) { + if (action == "BLOCK") { + return mojom::BlowfishSuggestedAction::kBlock; + } + if (action == "WARN") { + return mojom::BlowfishSuggestedAction::kWarn; + } + if (action == "NONE") { + return mojom::BlowfishSuggestedAction::kNone; + } + return mojom::BlowfishSuggestedAction::kNone; +} + std::vector ParseWarnings( const std::vector& values) { std::vector warnings; for (const auto& warning : values) { warnings.push_back(mojom::BlowfishWarning::New( - warning.severity, warning.kind, warning.message)); + ParseWarningSeverity(warning.severity), ParseWarningKind(warning.kind), + warning.message)); } return warnings; } @@ -48,7 +329,7 @@ mojom::BlowfishPricePtr ParsePrice(const base::Value& value) { return nullptr; } - return mojom::BlowfishPrice::New(price_value->source, + return mojom::BlowfishPrice::New(ParseAssetPriceSource(price_value->source), price_value->updated_at, price_value->dollar_value_per_token); } @@ -58,7 +339,8 @@ mojom::BlowfishPricePtr ParsePrice(const base::Value& value) { mojom::BlowfishEVMContractPtr ParseContract( const simulation_responses::EVMContract& value) { - return mojom::BlowfishEVMContract::New(value.address, value.kind); + return mojom::BlowfishEVMContract::New( + value.address, ParseBlowfishEVMAddressKind(value.kind)); } mojom::BlowfishEVMAmountPtr ParseAmount( @@ -97,9 +379,9 @@ mojom::BlowfishEVMStateChangeRawInfoPtr ParseStateChangeRawInfo( } auto raw_info = mojom::BlowfishEVMStateChangeRawInfo::New(); - raw_info->kind = value.kind; + raw_info->kind = ParseEVMRawInfoKind(value.kind); - if (value.kind == "ERC20_TRANSFER") { + if (value.kind == simulation_responses::EVM_RAW_INFO_KIND_ERC20_TRANSFER) { auto data_value = simulation_responses::ERC20TransferData::FromValue( value.data.GetDict()); if (!data_value) { @@ -119,7 +401,8 @@ mojom::BlowfishEVMStateChangeRawInfoPtr ParseStateChangeRawInfo( raw_info->data = mojom::BlowfishEVMStateChangeRawInfoDataUnion::NewErc20TransferData( std::move(data)); - } else if (value.kind == "ERC20_APPROVAL") { + } else if (value.kind == + simulation_responses::EVM_RAW_INFO_KIND_ERC20_APPROVAL) { auto data_value = simulation_responses::ERC20ApprovalData::FromValue( value.data.GetDict()); if (!data_value) { @@ -141,7 +424,8 @@ mojom::BlowfishEVMStateChangeRawInfoPtr ParseStateChangeRawInfo( raw_info->data = mojom::BlowfishEVMStateChangeRawInfoDataUnion::NewErc20ApprovalData( std::move(data)); - } else if (value.kind == "NATIVE_ASSET_TRANSFER") { + } else if (value.kind == + simulation_responses::EVM_RAW_INFO_KIND_NATIVE_ASSET_TRANSFER) { auto data_value = simulation_responses::NativeAssetTransferData::FromValue( value.data.GetDict()); if (!data_value) { @@ -159,7 +443,8 @@ mojom::BlowfishEVMStateChangeRawInfoPtr ParseStateChangeRawInfo( raw_info->data = mojom::BlowfishEVMStateChangeRawInfoDataUnion:: NewNativeAssetTransferData(std::move(data)); - } else if (value.kind == "ERC721_TRANSFER") { + } else if (value.kind == + simulation_responses::EVM_RAW_INFO_KIND_ERC721_TRANSFER) { auto data_value = simulation_responses::ERC721TransferData::FromValue( value.data.GetDict()); if (!data_value) { @@ -179,7 +464,8 @@ mojom::BlowfishEVMStateChangeRawInfoPtr ParseStateChangeRawInfo( raw_info->data = mojom::BlowfishEVMStateChangeRawInfoDataUnion::NewErc721TransferData( std::move(data)); - } else if (value.kind == "ERC721_APPROVAL") { + } else if (value.kind == + simulation_responses::EVM_RAW_INFO_KIND_ERC721_APPROVAL) { auto data_value = simulation_responses::ERC721ApprovalData::FromValue( value.data.GetDict()); if (!data_value) { @@ -201,7 +487,8 @@ mojom::BlowfishEVMStateChangeRawInfoPtr ParseStateChangeRawInfo( raw_info->data = mojom::BlowfishEVMStateChangeRawInfoDataUnion::NewErc721ApprovalData( std::move(data)); - } else if (value.kind == "ERC721_APPROVAL_FOR_ALL") { + } else if (value.kind == + simulation_responses::EVM_RAW_INFO_KIND_ERC721_APPROVAL_FOR_ALL) { auto data_value = simulation_responses::ERC721ApprovalForAllData::FromValue( value.data.GetDict()); if (!data_value) { @@ -219,7 +506,8 @@ mojom::BlowfishEVMStateChangeRawInfoPtr ParseStateChangeRawInfo( raw_info->data = mojom::BlowfishEVMStateChangeRawInfoDataUnion:: NewErc721ApprovalForAllData(std::move(data)); - } else if (value.kind == "ERC1155_TRANSFER") { + } else if (value.kind == + simulation_responses::EVM_RAW_INFO_KIND_ERC1155_TRANSFER) { auto data_value = simulation_responses::ERC1155TransferData::FromValue( value.data.GetDict()); if (!data_value) { @@ -238,7 +526,8 @@ mojom::BlowfishEVMStateChangeRawInfoPtr ParseStateChangeRawInfo( raw_info->data = mojom::BlowfishEVMStateChangeRawInfoDataUnion::NewErc1155TransferData( std::move(data)); - } else if (value.kind == "ERC1155_APPROVAL_FOR_ALL") { + } else if (value.kind == + simulation_responses::EVM_RAW_INFO_KIND_ERC1155_APPROVAL_FOR_ALL) { auto data_value = simulation_responses::ERC1155ApprovalForAllData::FromValue( value.data.GetDict()); @@ -320,7 +609,8 @@ mojom::EVMSimulationResponsePtr ParseSimulationResponse( } auto simulation_response = mojom::EVMSimulationResponse::New(); - simulation_response->action = simulation_response_value->action; + simulation_response->action = + ParseBlowfishActionKind(simulation_response_value->action); simulation_response->warnings = ParseWarnings(simulation_response_value->warnings); @@ -334,8 +624,9 @@ mojom::EVMSimulationResponsePtr ParseSimulationResponse( return nullptr; } - simulation_results->error = mojom::BlowfishEVMError::New( - error_value->kind, error_value->human_readable_error); + simulation_results->error = + mojom::BlowfishEVMError::New(ParseEVMErrorKind(error_value->kind), + error_value->human_readable_error); } else if (simulation_response_value->simulation_results.error.is_none()) { simulation_results->error = nullptr; } else { @@ -376,7 +667,7 @@ mojom::BlowfishPricePtr ParsePrice(const base::Value& value) { return nullptr; } - return mojom::BlowfishPrice::New(price_value->source, + return mojom::BlowfishPrice::New(ParseAssetPriceSource(price_value->source), price_value->last_updated_at, price_value->dollar_value_per_token); } @@ -384,10 +675,22 @@ mojom::BlowfishPricePtr ParsePrice(const base::Value& value) { return nullptr; } +mojom::BlowfishDiffSign ParseDiffSign( + const simulation_responses::DiffSign& sign) { + switch (sign) { + case simulation_responses::DiffSign::DIFF_SIGN_MINUS: + return mojom::BlowfishDiffSign::kMinus; + + case simulation_responses::DiffSign::DIFF_SIGN_PLUS: + default: + return mojom::BlowfishDiffSign::kPlus; + } +} + mojom::BlowfishSolanaDiffPtr ParseDiff( const simulation_responses::SolanaDiff& value) { auto diff = mojom::BlowfishSolanaDiff::New(); - diff->sign = value.sign; + diff->sign = ParseDiffSign(value.sign); if (!base::StringToUint64(value.digits, &diff->digits)) { return nullptr; } @@ -410,9 +713,9 @@ mojom::BlowfishSolanaStateChangeRawInfoPtr ParseStateChangeRawInfo( } auto raw_info = mojom::BlowfishSolanaStateChangeRawInfo::New(); - raw_info->kind = value.kind; + raw_info->kind = ParseSolanaRawInfoKind(value.kind); - if (value.kind == "SOL_TRANSFER") { + if (value.kind == simulation_responses::SOLANA_RAW_INFO_KIND_SOL_TRANSFER) { auto data_value = simulation_responses::SOLTransferData::FromValue(value.data.GetDict()); if (!data_value) { @@ -431,7 +734,8 @@ mojom::BlowfishSolanaStateChangeRawInfoPtr ParseStateChangeRawInfo( raw_info->data = mojom::BlowfishSolanaStateChangeRawInfoDataUnion::NewSolTransferData( std::move(data)); - } else if (value.kind == "SPL_TRANSFER") { + } else if (value.kind == + simulation_responses::SOLANA_RAW_INFO_KIND_SPL_TRANSFER) { auto data_value = simulation_responses::SPLTransferData::FromValue(value.data.GetDict()); if (!data_value) { @@ -449,13 +753,15 @@ mojom::BlowfishSolanaStateChangeRawInfoPtr ParseStateChangeRawInfo( if (!base::StringToUint64(data_value->supply, &data->supply)) { return nullptr; } - data->metaplex_token_standard = data_value->metaplex_token_standard; + data->metaplex_token_standard = + ParseMetaplexTokenStandardKind(data_value->metaplex_token_standard); data->asset_price = ParsePrice(data_value->asset_price); raw_info->data = mojom::BlowfishSolanaStateChangeRawInfoDataUnion::NewSplTransferData( std::move(data)); - } else if (value.kind == "SPL_APPROVAL") { + } else if (value.kind == + simulation_responses::SOLANA_RAW_INFO_KIND_SPL_APPROVAL) { auto data_value = simulation_responses::SPLApprovalData::FromValue(value.data.GetDict()); if (!data_value) { @@ -476,13 +782,16 @@ mojom::BlowfishSolanaStateChangeRawInfoPtr ParseStateChangeRawInfo( if (!base::StringToUint64(data_value->supply, &data->supply)) { return nullptr; } - data->metaplex_token_standard = data_value->metaplex_token_standard; + data->metaplex_token_standard = + ParseMetaplexTokenStandardKind(data_value->metaplex_token_standard); data->asset_price = ParsePrice(data_value->asset_price); raw_info->data = mojom::BlowfishSolanaStateChangeRawInfoDataUnion::NewSplApprovalData( std::move(data)); - } else if (value.kind == "SOL_STAKE_AUTHORITY_CHANGE") { + } else if (value.kind == + simulation_responses:: + SOLANA_RAW_INFO_KIND_SOL_STAKE_AUTHORITY_CHANGE) { auto data_value = simulation_responses::SOLStakeAuthorityChangeData::FromValue( value.data.GetDict()); @@ -515,6 +824,221 @@ mojom::BlowfishSolanaStateChangeRawInfoPtr ParseStateChangeRawInfo( return raw_info; } +mojom::BlowfishSuggestedColor ParseSuggestedColor( + const simulation_responses::SuggestedColor& color) { + switch (color) { + case simulation_responses::SuggestedColor::SUGGESTED_COLOR_CREDIT: + return mojom::BlowfishSuggestedColor::kCredit; + + case simulation_responses::SuggestedColor::SUGGESTED_COLOR_DEBIT: + default: + return mojom::BlowfishSuggestedColor::kDebit; + } +} + +// Detects documented error kinds (see: +// https://docs.blowfish.xyz/v2023-03-08/reference/scan-transactions-solana) +mojom::BlowfishSolanaErrorKind ParseSolanaErrorKind(const std::string& error) { + // ERROR_PROCESSING_INSTRUCTION_{0}:_{1} + if (error.find("ERROR_PROCESSING_INSTRUCTION") == 0) { + return mojom::BlowfishSolanaErrorKind::kErrorProcessingInstruction; + } + + // "TRANSACTION_CONTAINS_A_DUPLICATE_INSTRUCTION_({0})_THAT_IS_NOT_ALLOWED" + if (error.find("TRANSACTION_CONTAINS_A_DUPLICATE_INSTRUCTION_") == 0) { + return mojom::BlowfishSolanaErrorKind:: + kTransactionContainsADuplicateInstructionThatIsNotAllowed; + } + + if (error == "ACCOUNT_DOES_NOT_HAVE_ENOUGH_SOL_TO_PERFORM_THE_OPERATION") { + return mojom::BlowfishSolanaErrorKind:: + kAccountDoesNotHaveEnoughSolToPerformTheOperation; + } else if (error == "ACCOUNT_DOES_NOT_SUPPORT_SPECIFIED_AUTHORITY_TYPE") { + return mojom::BlowfishSolanaErrorKind:: + kAccountDoesNotSupportSpecifiedAuthorityType; + } else if (error == "ACCOUNT_IN_USE") { + return mojom::BlowfishSolanaErrorKind::kAccountInUse; + } else if (error == "ACCOUNT_IS_FROZEN") { + return mojom::BlowfishSolanaErrorKind::kAccountIsFrozen; + } else if (error == "ACCOUNT_LOADED_TWICE") { + return mojom::BlowfishSolanaErrorKind::kAccountLoadedTwice; + } else if (error == "ACCOUNT_NOT_ASSOCIATED_WITH_THIS_MINT") { + return mojom::BlowfishSolanaErrorKind::kAccountNotAssociatedWithThisMint; + } else if (error == + "ADVANCING_STORED_NONCE_REQUIRES_A_POPULATED_RECENTBLOCKHASHES_" + "SYSVAR") { + return mojom::BlowfishSolanaErrorKind:: + kAdvancingStoredNonceRequiresAPopulatedRecentblockhashesSysvar; + } else if (error == "ALREADY_IN_USE") { + return mojom::BlowfishSolanaErrorKind::kAlreadyInUse; + } else if (error == "AN_ACCOUNT_WITH_THE_SAME_ADDRESS_ALREADY_EXISTS") { + return mojom::BlowfishSolanaErrorKind:: + kAnAccountWithTheSameAddressAlreadyExists; + } else if (error == + "ATTEMPT_TO_DEBIT_AN_ACCOUNT_BUT_FOUND_NO_RECORD_OF_A_PRIOR_" + "CREDIT") { + return mojom::BlowfishSolanaErrorKind:: + kAttemptToDebitAnAccountButFoundNoRecordOfAPriorCredit; + } else if (error == "ATTEMPT_TO_LOAD_A_PROGRAM_THAT_DOES_NOT_EXIST") { + return mojom::BlowfishSolanaErrorKind:: + kAttemptToLoadAProgramThatDoesNotExist; + } else if (error == "BAD_REQUEST") { + return mojom::BlowfishSolanaErrorKind::kBadRequest; + } else if (error == "BLOCKHASH_NOT_FOUND") { + return mojom::BlowfishSolanaErrorKind::kBlockhashNotFound; + } else if (error == "CANNOT_ALLOCATE_ACCOUNT_DATA_OF_THIS_LENGTH") { + return mojom::BlowfishSolanaErrorKind:: + kCannotAllocateAccountDataOfThisLength; + } else if (error == "CANNOT_ASSIGN_ACCOUNT_TO_THIS_PROGRAM_ID") { + return mojom::BlowfishSolanaErrorKind::kCannotAssignAccountToThisProgramId; + } else if (error == "FIXED_SUPPLY") { + return mojom::BlowfishSolanaErrorKind::kFixedSupply; + } else if (error == "INSTRUCTION_DOES_NOT_SUPPORT_NATIVE_TOKENS") { + return mojom::BlowfishSolanaErrorKind:: + kInstructionDoesNotSupportNativeTokens; + } else if (error == "INSTRUCTION_DOES_NOT_SUPPORT_NON-NATIVE_TOKENS") { + return mojom::BlowfishSolanaErrorKind:: + kInstructionDoesNotSupportNonNativeTokens; + } else if (error == "INSUFFICIENT_FUNDS") { + return mojom::BlowfishSolanaErrorKind::kInsufficientFunds; + } else if (error == "INSUFFICIENT_FUNDS_FOR_FEE") { + return mojom::BlowfishSolanaErrorKind::kInsufficientFundsForFee; + } else if (error == "INVALID_INSTRUCTION") { + return mojom::BlowfishSolanaErrorKind::kInvalidInstruction; + } else if (error == "INVALID_MINT") { + return mojom::BlowfishSolanaErrorKind::kInvalidMint; + } else if (error == "INVALID_NUMBER_OF_PROVIDED_SIGNERS") { + return mojom::BlowfishSolanaErrorKind::kInvalidNumberOfProvidedSigners; + } else if (error == "INVALID_NUMBER_OF_REQUIRED_SIGNERS") { + return mojom::BlowfishSolanaErrorKind::kInvalidNumberOfRequiredSigners; + } else if (error == "LAMPORT_BALANCE_BELOW_RENT-EXEMPT_THRESHOLD") { + return mojom::BlowfishSolanaErrorKind:: + kLamportBalanceBelowRentExemptThreshold; + } else if (error == "LENGTH_OF_REQUESTED_SEED_IS_TOO_LONG") { + return mojom::BlowfishSolanaErrorKind::kLengthOfRequestedSeedIsTooLong; + } else if (error == "LOADER_CALL_CHAIN_IS_TOO_DEEP") { + return mojom::BlowfishSolanaErrorKind::kLoaderCallChainIsTooDeep; + } else if (error == + "NON-NATIVE_ACCOUNT_CAN_ONLY_BE_CLOSED_IF_ITS_BALANCE_IS_ZERO") { + return mojom::BlowfishSolanaErrorKind:: + kNonNativeAccountCanOnlyBeClosedIfItsBalanceIsZero; + } else if (error == "OPERATION_OVERFLOWED") { + return mojom::BlowfishSolanaErrorKind::kOperationOverflowed; + } else if (error == "OWNER_DOES_NOT_MATCH") { + return mojom::BlowfishSolanaErrorKind::kOwnerDoesNotMatch; + } else if (error == + "PROVIDED_ADDRESS_DOES_NOT_MATCH_ADDRESSED_DERIVED_FROM_SEED") { + return mojom::BlowfishSolanaErrorKind:: + kProvidedAddressDoesNotMatchAddressedDerivedFromSeed; + } else if (error == "SIMULATION_FAILED") { + return mojom::BlowfishSolanaErrorKind::kSimulationFailed; + } else if (error == "SIMULATION_TIMED_OUT") { + return mojom::BlowfishSolanaErrorKind::kSimulationTimedOut; + } else if (error == "SPECIFIED_NONCE_DOES_NOT_MATCH_STORED_NONCE") { + return mojom::BlowfishSolanaErrorKind:: + kSpecifiedNonceDoesNotMatchStoredNonce; + } else if (error == "STATE_IS_INVALID_FOR_REQUESTED_OPERATION") { + return mojom::BlowfishSolanaErrorKind::kStateIsInvalidForRequestedOperation; + } else if (error == "STATE_IS_UNINITIALIZED") { + return mojom::BlowfishSolanaErrorKind::kStateIsUninitialized; + } else if (error == "STORED_NONCE_IS_STILL_IN_RECENT_BLOCKHASHES") { + return mojom::BlowfishSolanaErrorKind:: + kStoredNonceIsStillInRecentBlockhashes; + } else if (error == + "THE_PROVIDED_DECIMALS_VALUE_DIFFERENT_FROM_THE_MINT_DECIMALS") { + return mojom::BlowfishSolanaErrorKind:: + kTheProvidedDecimalsValueDifferentFromTheMintDecimals; + } else if (error == "THIS_ACCOUNT_MAY_NOT_BE_USED_TO_PAY_TRANSACTION_FEES") { + return mojom::BlowfishSolanaErrorKind:: + kThisAccountMayNotBeUsedToPayTransactionFees; + } else if (error == + "THIS_PROGRAM_MAY_NOT_BE_USED_FOR_EXECUTING_INSTRUCTIONS") { + return mojom::BlowfishSolanaErrorKind:: + kThisProgramMayNotBeUsedForExecutingInstructions; + } else if (error == "THIS_TOKEN_MINT_CANNOT_FREEZE_ACCOUNTS") { + return mojom::BlowfishSolanaErrorKind::kThisTokenMintCannotFreezeAccounts; + } else if (error == "THIS_TRANSACTION_HAS_ALREADY_BEEN_PROCESSED") { + return mojom::BlowfishSolanaErrorKind:: + kThisTransactionHasAlreadyBeenProcessed; + } else if (error == "TOO_MANY_TRANSACTIONS") { + return mojom::BlowfishSolanaErrorKind::kTooManyTransactions; + } else if (error == + "TRANSACTION_ADDRESS_TABLE_LOOKUP_USES_AN_INVALID_INDEX") { + return mojom::BlowfishSolanaErrorKind:: + kTransactionAddressTableLookupUsesAnInvalidIndex; + } else if (error == "TRANSACTION_CONTAINS_AN_INVALID_ACCOUNT_REFERENCE") { + return mojom::BlowfishSolanaErrorKind:: + kTransactionContainsAnInvalidAccountReference; + } else if (error == "TRANSACTION_DID_NOT_PASS_SIGNATURE_VERIFICATION") { + return mojom::BlowfishSolanaErrorKind:: + kTransactionDidNotPassSignatureVerification; + } else if (error == + "TRANSACTION_FAILED_TO_SANITIZE_ACCOUNTS_OFFSETS_CORRECTLY") { + return mojom::BlowfishSolanaErrorKind:: + kTransactionFailedToSanitizeAccountsOffsetsCorrectly; + } else if (error == + "TRANSACTION_LEAVES_AN_ACCOUNT_WITH_A_LOWER_BALANCE_THAN_RENT-" + "EXEMPT_MINIMUM") { + return mojom::BlowfishSolanaErrorKind:: + kTransactionLeavesAnAccountWithALowerBalanceThanRentExemptMinimum; + } else if (error == + "TRANSACTION_LOADS_A_WRITABLE_ACCOUNT_THAT_CANNOT_BE_WRITTEN") { + return mojom::BlowfishSolanaErrorKind:: + kTransactionLoadsAWritableAccountThatCannotBeWritten; + } else if (error == + "TRANSACTION_LOADS_AN_ADDRESS_TABLE_ACCOUNT_THAT_DOESN'T_EXIST") { + return mojom::BlowfishSolanaErrorKind:: + kTransactionLoadsAnAddressTableAccountThatDoesntExist; + } else if (error == + "TRANSACTION_LOADS_AN_ADDRESS_TABLE_ACCOUNT_WITH_AN_INVALID_" + "OWNER") { + return mojom::BlowfishSolanaErrorKind:: + kTransactionLoadsAnAddressTableAccountWithAnInvalidOwner; + } else if (error == + "TRANSACTION_LOADS_AN_ADDRESS_TABLE_ACCOUNT_WITH_INVALID_DATA") { + return mojom::BlowfishSolanaErrorKind:: + kTransactionLoadsAnAddressTableAccountWithInvalidData; + } else if (error == "TRANSACTION_LOCKED_TOO_MANY_ACCOUNTS") { + return mojom::BlowfishSolanaErrorKind::kTransactionLockedTooManyAccounts; + } else if (error == + "TRANSACTION_PROCESSING_LEFT_AN_ACCOUNT_WITH_AN_OUTSTANDING_" + "BORROWED_REFERENCE") { + return mojom::BlowfishSolanaErrorKind:: + kTransactionProcessingLeftAnAccountWithAnOutstandingBorrowedReference; + } else if (error == + "TRANSACTION_REQUIRES_A_FEE_BUT_HAS_NO_SIGNATURE_PRESENT") { + return mojom::BlowfishSolanaErrorKind:: + kTransactionRequiresAFeeButHasNoSignaturePresent; + } else if (error == "TRANSACTION_VERSION_IS_UNSUPPORTED") { + return mojom::BlowfishSolanaErrorKind::kTransactionVersionIsUnsupported; + } else if (error == + "TRANSACTION_WOULD_EXCEED_ACCOUNT_DATA_LIMIT_WITHIN_THE_BLOCK") { + return mojom::BlowfishSolanaErrorKind:: + kTransactionWouldExceedAccountDataLimitWithinTheBlock; + } else if (error == + "TRANSACTION_WOULD_EXCEED_MAX_ACCOUNT_LIMIT_WITHIN_THE_BLOCK") { + return mojom::BlowfishSolanaErrorKind:: + kTransactionWouldExceedMaxAccountLimitWithinTheBlock; + } else if (error == "TRANSACTION_WOULD_EXCEED_MAX_BLOCK_COST_LIMIT") { + return mojom::BlowfishSolanaErrorKind:: + kTransactionWouldExceedMaxBlockCostLimit; + } else if (error == "TRANSACTION_WOULD_EXCEED_MAX_VOTE_COST_LIMIT") { + return mojom::BlowfishSolanaErrorKind:: + kTransactionWouldExceedMaxVoteCostLimit; + } else if (error == "TRANSACTION_WOULD_EXCEED_TOTAL_ACCOUNT_DATA_LIMIT") { + return mojom::BlowfishSolanaErrorKind:: + kTransactionWouldExceedTotalAccountDataLimit; + } else if (error == + "TRANSACTIONS_ARE_CURRENTLY_DISABLED_DUE_TO_CLUSTER_MAINTENANCE") { + return mojom::BlowfishSolanaErrorKind:: + kTransactionsAreCurrentlyDisabledDueToClusterMaintenance; + } else if (error == "UNKNOWN_ERROR") { + return mojom::BlowfishSolanaErrorKind::kUnknownError; + } + + return mojom::BlowfishSolanaErrorKind::kUnknownError; +} + } // namespace mojom::SolanaSimulationResponsePtr ParseSimulationResponse( @@ -574,7 +1098,8 @@ mojom::SolanaSimulationResponsePtr ParseSimulationResponse( } auto simulation_response = mojom::SolanaSimulationResponse::New(); - simulation_response->action = simulation_response_value->action; + simulation_response->action = + ParseBlowfishActionKind(simulation_response_value->action); simulation_response->warnings = ParseWarnings(simulation_response_value->warnings); @@ -588,8 +1113,9 @@ mojom::SolanaSimulationResponsePtr ParseSimulationResponse( return nullptr; } - simulation_results->error = mojom::BlowfishSolanaError::New( - error_value->kind, error_value->human_readable_error); + simulation_results->error = + mojom::BlowfishSolanaError::New(ParseSolanaErrorKind(error_value->kind), + error_value->human_readable_error); } else if (simulation_response_value->simulation_results.error.is_none()) { simulation_results->error = nullptr; } else { @@ -600,7 +1126,8 @@ mojom::SolanaSimulationResponsePtr ParseSimulationResponse( simulation_response_value->simulation_results.expected_state_changes) { auto state_change = mojom::BlowfishSolanaStateChange::New(); state_change->human_readable_diff = state_change_value.human_readable_diff; - state_change->suggested_color = state_change_value.suggested_color; + state_change->suggested_color = + ParseSuggestedColor(state_change_value.suggested_color); if (auto raw_info = ParseStateChangeRawInfo(state_change_value.raw_info)) { state_change->raw_info = std::move(raw_info); diff --git a/components/brave_wallet/browser/simulation_response_parser_unittest.cc b/components/brave_wallet/browser/simulation_response_parser_unittest.cc index bd1b8a13368d..4f65bb486f2d 100644 --- a/components/brave_wallet/browser/simulation_response_parser_unittest.cc +++ b/components/brave_wallet/browser/simulation_response_parser_unittest.cc @@ -102,7 +102,7 @@ TEST(SimulationResponseParserUnitTest, ParseEVMSwapETHForDAI) { auto simulation_response = evm::ParseSimulationResponse(ParseJson(json)); ASSERT_TRUE(simulation_response); - EXPECT_EQ(simulation_response->action, "NONE"); + EXPECT_EQ(simulation_response->action, mojom::BlowfishSuggestedAction::kNone); EXPECT_EQ(simulation_response->warnings.size(), 0u); EXPECT_FALSE(simulation_response->simulation_results->error); ASSERT_EQ( @@ -112,7 +112,8 @@ TEST(SimulationResponseParserUnitTest, ParseEVMSwapETHForDAI) { const auto& state_change_0 = simulation_response->simulation_results->expected_state_changes.at(0); EXPECT_EQ(state_change_0->human_readable_diff, "Receive 1530.81307 DAI"); - EXPECT_EQ(state_change_0->raw_info->kind, "ERC20_TRANSFER"); + EXPECT_EQ(state_change_0->raw_info->kind, + mojom::BlowfishEVMRawInfoKind::kErc20Transfer); ASSERT_TRUE(state_change_0->raw_info->data->is_erc20_transfer_data()); const auto& state_change_0_raw_info = state_change_0->raw_info->data->get_erc20_transfer_data(); @@ -121,7 +122,8 @@ TEST(SimulationResponseParserUnitTest, ParseEVMSwapETHForDAI) { EXPECT_EQ(state_change_0_raw_info->amount->after, "557039306766411381864245"); EXPECT_EQ(state_change_0_raw_info->contract->address, "0x6b175474e89094c44da98b954eedeac495271d0f"); - EXPECT_EQ(state_change_0_raw_info->contract->kind, "ACCOUNT"); + EXPECT_EQ(state_change_0_raw_info->contract->kind, + mojom::BlowfishEVMAddressKind::kAccount); EXPECT_EQ(state_change_0_raw_info->asset->address, "0x6b175474e89094c44da98b954eedeac495271d0f"); EXPECT_EQ(state_change_0_raw_info->asset->symbol, "DAI"); @@ -133,7 +135,8 @@ TEST(SimulationResponseParserUnitTest, ParseEVMSwapETHForDAI) { EXPECT_EQ(state_change_0_raw_info->asset->lists.at(1), "ZERION"); EXPECT_EQ(state_change_0_raw_info->asset->image_url, "https://example.com/dai.png"); - EXPECT_EQ(state_change_0_raw_info->asset->price->source, "Defillama"); + EXPECT_EQ(state_change_0_raw_info->asset->price->source, + mojom::BlowfishAssetPriceSource::kDefillama); EXPECT_EQ(state_change_0_raw_info->asset->price->last_updated_at, "1680557741"); EXPECT_EQ(state_change_0_raw_info->asset->price->dollar_value_per_token, @@ -142,7 +145,8 @@ TEST(SimulationResponseParserUnitTest, ParseEVMSwapETHForDAI) { const auto& state_change_1 = simulation_response->simulation_results->expected_state_changes.at(1); EXPECT_EQ(state_change_1->human_readable_diff, "Send 1 ETH"); - EXPECT_EQ(state_change_1->raw_info->kind, "NATIVE_ASSET_TRANSFER"); + EXPECT_EQ(state_change_1->raw_info->kind, + mojom::BlowfishEVMRawInfoKind::kNativeAssetTransfer); ASSERT_TRUE(state_change_1->raw_info->data->is_native_asset_transfer_data()); const auto& state_change_1_raw_info = state_change_1->raw_info->data->get_native_asset_transfer_data(); @@ -150,7 +154,8 @@ TEST(SimulationResponseParserUnitTest, ParseEVMSwapETHForDAI) { EXPECT_EQ(state_change_1_raw_info->amount->after, "1182957389356504134754"); EXPECT_EQ(state_change_1_raw_info->contract->address, "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); - EXPECT_EQ(state_change_1_raw_info->contract->kind, "ACCOUNT"); + EXPECT_EQ(state_change_1_raw_info->contract->kind, + mojom::BlowfishEVMAddressKind::kAccount); EXPECT_EQ(state_change_1_raw_info->asset->address, "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); EXPECT_EQ(state_change_1_raw_info->asset->symbol, "ETH"); @@ -160,7 +165,8 @@ TEST(SimulationResponseParserUnitTest, ParseEVMSwapETHForDAI) { EXPECT_EQ(state_change_1_raw_info->asset->lists.size(), 0u); EXPECT_EQ(state_change_1_raw_info->asset->image_url, "https://example.com/eth.png"); - EXPECT_EQ(state_change_1_raw_info->asset->price->source, "Coingecko"); + EXPECT_EQ(state_change_1_raw_info->asset->price->source, + mojom::BlowfishAssetPriceSource::kCoingecko); EXPECT_EQ(state_change_1_raw_info->asset->price->last_updated_at, "1670324557"); EXPECT_EQ(state_change_1_raw_info->asset->price->dollar_value_per_token, @@ -231,7 +237,7 @@ TEST(SimulationResponseParserUnitTest, ParseEVMERC20Approval) { auto simulation_response = evm::ParseSimulationResponse(ParseJson(json)); ASSERT_TRUE(simulation_response); - EXPECT_EQ(simulation_response->action, "NONE"); + EXPECT_EQ(simulation_response->action, mojom::BlowfishSuggestedAction::kNone); EXPECT_EQ(simulation_response->warnings.size(), 0u); EXPECT_FALSE(simulation_response->simulation_results->error); ASSERT_EQ( @@ -242,7 +248,8 @@ TEST(SimulationResponseParserUnitTest, ParseEVMERC20Approval) { simulation_response->simulation_results->expected_state_changes.at(0); EXPECT_EQ(state_change->human_readable_diff, "Approve to transfer up to 1000 USDT"); - EXPECT_EQ(state_change->raw_info->kind, "ERC20_APPROVAL"); + EXPECT_EQ(state_change->raw_info->kind, + mojom::BlowfishEVMRawInfoKind::kErc20Approval); ASSERT_TRUE(state_change->raw_info->data->is_erc20_approval_data()); const auto& state_change_raw_info = state_change->raw_info->data->get_erc20_approval_data(); @@ -259,19 +266,23 @@ TEST(SimulationResponseParserUnitTest, ParseEVMERC20Approval) { EXPECT_EQ(state_change_raw_info->asset->lists.at(1), "ZERION"); EXPECT_EQ(state_change_raw_info->asset->image_url, "https://example.com/usdt.png"); - EXPECT_EQ(state_change_raw_info->asset->price->source, "Defillama"); + EXPECT_EQ(state_change_raw_info->asset->price->source, + mojom::BlowfishAssetPriceSource::kDefillama); EXPECT_EQ(state_change_raw_info->asset->price->last_updated_at, "1680557741"); EXPECT_EQ(state_change_raw_info->asset->price->dollar_value_per_token, "1.001"); EXPECT_EQ(state_change_raw_info->contract->address, "0xdac17f958d2ee523a2206206994597c13d831ec7"); - EXPECT_EQ(state_change_raw_info->contract->kind, "ACCOUNT"); + EXPECT_EQ(state_change_raw_info->contract->kind, + mojom::BlowfishEVMAddressKind::kAccount); EXPECT_EQ(state_change_raw_info->owner->address, "0xd8da6bf26964af9d7eed9e03e53415d37aa96045"); - EXPECT_EQ(state_change_raw_info->owner->kind, "ACCOUNT"); + EXPECT_EQ(state_change_raw_info->owner->kind, + mojom::BlowfishEVMAddressKind::kAccount); EXPECT_EQ(state_change_raw_info->spender->address, "0x68b3465833fb72a70ecdf485e0e4c7bd8665fc45"); - EXPECT_EQ(state_change_raw_info->spender->kind, "ACCOUNT"); + EXPECT_EQ(state_change_raw_info->spender->kind, + mojom::BlowfishEVMAddressKind::kAccount); } // Example from https://docs.blowfish.xyz/reference/scan-transaction-evm @@ -350,7 +361,7 @@ TEST(SimulationResponseParserUnitTest, ParseEVMBuyERC721NFTWithETH) { auto simulation_response = evm::ParseSimulationResponse(ParseJson(json)); ASSERT_TRUE(simulation_response); - EXPECT_EQ(simulation_response->action, "NONE"); + EXPECT_EQ(simulation_response->action, mojom::BlowfishSuggestedAction::kNone); EXPECT_EQ(simulation_response->warnings.size(), 0u); EXPECT_FALSE(simulation_response->simulation_results->error); ASSERT_EQ( @@ -360,13 +371,15 @@ TEST(SimulationResponseParserUnitTest, ParseEVMBuyERC721NFTWithETH) { const auto& state_change_0 = simulation_response->simulation_results->expected_state_changes.at(0); EXPECT_EQ(state_change_0->human_readable_diff, "Receive PudgyPenguins #7238"); - EXPECT_EQ(state_change_0->raw_info->kind, "ERC721_TRANSFER"); + EXPECT_EQ(state_change_0->raw_info->kind, + mojom::BlowfishEVMRawInfoKind::kErc721Transfer); ASSERT_TRUE(state_change_0->raw_info->data->is_erc721_transfer_data()); const auto& state_change_0_raw_info = state_change_0->raw_info->data->get_erc721_transfer_data(); EXPECT_EQ(state_change_0_raw_info->amount->before, "0"); EXPECT_EQ(state_change_0_raw_info->amount->after, "1"); - EXPECT_EQ(state_change_0_raw_info->contract->kind, "ACCOUNT"); + EXPECT_EQ(state_change_0_raw_info->contract->kind, + mojom::BlowfishEVMAddressKind::kAccount); EXPECT_EQ(state_change_0_raw_info->contract->address, "0xbd3531da5cf5857e7cfaa92426877b022e612cf8"); EXPECT_EQ(state_change_0_raw_info->metadata->raw_image_url, @@ -374,7 +387,8 @@ TEST(SimulationResponseParserUnitTest, ParseEVMBuyERC721NFTWithETH) { EXPECT_EQ(state_change_0_raw_info->name, "PudgyPenguins"); EXPECT_EQ(state_change_0_raw_info->symbol, "PPG"); EXPECT_EQ(state_change_0_raw_info->token_id, "7238"); - EXPECT_EQ(state_change_0_raw_info->asset_price->source, "Simplehash"); + EXPECT_EQ(state_change_0_raw_info->asset_price->source, + mojom::BlowfishAssetPriceSource::kSimplehash); EXPECT_EQ(state_change_0_raw_info->asset_price->last_updated_at, "1679331222"); EXPECT_EQ(state_change_0_raw_info->asset_price->dollar_value_per_token, @@ -383,13 +397,15 @@ TEST(SimulationResponseParserUnitTest, ParseEVMBuyERC721NFTWithETH) { const auto& state_change_1 = simulation_response->simulation_results->expected_state_changes.at(1); EXPECT_EQ(state_change_1->human_readable_diff, "Send 3.181 ETH"); - EXPECT_EQ(state_change_1->raw_info->kind, "NATIVE_ASSET_TRANSFER"); + EXPECT_EQ(state_change_1->raw_info->kind, + mojom::BlowfishEVMRawInfoKind::kNativeAssetTransfer); ASSERT_TRUE(state_change_1->raw_info->data->is_native_asset_transfer_data()); const auto& state_change_1_raw_info = state_change_1->raw_info->data->get_native_asset_transfer_data(); EXPECT_EQ(state_change_1_raw_info->amount->before, "1001607264937289938488"); EXPECT_EQ(state_change_1_raw_info->amount->after, "998426264937289938488"); - EXPECT_EQ(state_change_1_raw_info->contract->kind, "ACCOUNT"); + EXPECT_EQ(state_change_1_raw_info->contract->kind, + mojom::BlowfishEVMAddressKind::kAccount); EXPECT_EQ(state_change_1_raw_info->contract->address, "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); EXPECT_EQ(state_change_1_raw_info->asset->address, @@ -400,7 +416,10 @@ TEST(SimulationResponseParserUnitTest, ParseEVMBuyERC721NFTWithETH) { EXPECT_EQ(state_change_1_raw_info->asset->name, "Ether"); EXPECT_EQ(state_change_1_raw_info->asset->price->dollar_value_per_token, "1968.47"); - EXPECT_EQ(state_change_1_raw_info->asset->price->source, "Coingecko"); + EXPECT_EQ(state_change_1_raw_info->asset->price->source, + mojom::BlowfishAssetPriceSource::kCoingecko); + EXPECT_EQ(state_change_1_raw_info->asset->price->source, + mojom::BlowfishAssetPriceSource::kCoingecko); EXPECT_EQ(state_change_1_raw_info->asset->price->last_updated_at, "1670324557"); EXPECT_EQ(state_change_1_raw_info->asset->symbol, "ETH"); @@ -463,14 +482,15 @@ TEST(SimulationResponseParserUnitTest, ParseEVMERC721ApprovalForAll) { auto simulation_response = evm::ParseSimulationResponse(ParseJson(json)); ASSERT_TRUE(simulation_response); - EXPECT_EQ(simulation_response->action, "WARN"); + EXPECT_EQ(simulation_response->action, mojom::BlowfishSuggestedAction::kWarn); ASSERT_EQ(simulation_response->warnings.size(), 1u); EXPECT_EQ(simulation_response->warnings.at(0)->kind, - "UNLIMITED_ALLOWANCE_TO_NFTS"); + mojom::BlowfishWarningKind::kUnlimitedAllowanceToNfts); EXPECT_EQ(simulation_response->warnings.at(0)->message, "You are allowing this website to withdraw funds from your account " "in the future"); - EXPECT_EQ(simulation_response->warnings.at(0)->severity, "WARNING"); + EXPECT_EQ(simulation_response->warnings.at(0)->severity, + mojom::BlowfishWarningSeverity::kWarning); EXPECT_FALSE(simulation_response->simulation_results->error); ASSERT_EQ( simulation_response->simulation_results->expected_state_changes.size(), @@ -480,7 +500,8 @@ TEST(SimulationResponseParserUnitTest, ParseEVMERC721ApprovalForAll) { simulation_response->simulation_results->expected_state_changes.at(0); EXPECT_EQ(state_change->human_readable_diff, "Approve to transfer all your BoredApeYachtClub"); - EXPECT_EQ(state_change->raw_info->kind, "ERC721_APPROVAL_FOR_ALL"); + EXPECT_EQ(state_change->raw_info->kind, + mojom::BlowfishEVMRawInfoKind::kErc721ApprovalForAll); ASSERT_TRUE(state_change->raw_info->data->is_erc721_approval_for_all_data()); const auto& state_change_raw_info = state_change->raw_info->data->get_erc721_approval_for_all_data(); @@ -488,18 +509,22 @@ TEST(SimulationResponseParserUnitTest, ParseEVMERC721ApprovalForAll) { EXPECT_EQ(state_change_raw_info->amount->after, "115792089237316195423570985008687907853269984665640564039457584007" "913129639935"); - EXPECT_EQ(state_change_raw_info->contract->kind, "ACCOUNT"); + EXPECT_EQ(state_change_raw_info->contract->kind, + mojom::BlowfishEVMAddressKind::kAccount); EXPECT_EQ(state_change_raw_info->contract->address, "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d"); EXPECT_EQ(state_change_raw_info->name, "BoredApeYachtClub"); - EXPECT_EQ(state_change_raw_info->owner->kind, "ACCOUNT"); + EXPECT_EQ(state_change_raw_info->owner->kind, + mojom::BlowfishEVMAddressKind::kAccount); EXPECT_EQ(state_change_raw_info->owner->address, "0x38191ca1307ebf67ca1a7caf5346dbd91d882ca6"); - EXPECT_EQ(state_change_raw_info->spender->kind, "ACCOUNT"); + EXPECT_EQ(state_change_raw_info->spender->kind, + mojom::BlowfishEVMAddressKind::kAccount); EXPECT_EQ(state_change_raw_info->spender->address, "0x1e0049783f008a0085193e00003d00cd54003c71"); EXPECT_EQ(state_change_raw_info->symbol, "BAYC"); - EXPECT_EQ(state_change_raw_info->asset_price->source, "Simplehash"); + EXPECT_EQ(state_change_raw_info->asset_price->source, + mojom::BlowfishAssetPriceSource::kSimplehash); EXPECT_EQ(state_change_raw_info->asset_price->last_updated_at, "1679331222"); EXPECT_EQ(state_change_raw_info->asset_price->dollar_value_per_token, "7865.43"); @@ -559,7 +584,7 @@ TEST(SimulationResponseParserUnitTest, ParseEVMERC721Approval) { auto simulation_response = evm::ParseSimulationResponse(ParseJson(json)); ASSERT_TRUE(simulation_response); - EXPECT_EQ(simulation_response->action, "NONE"); + EXPECT_EQ(simulation_response->action, mojom::BlowfishSuggestedAction::kNone); EXPECT_EQ(simulation_response->warnings.size(), 0u); EXPECT_FALSE(simulation_response->simulation_results->error); ASSERT_EQ( @@ -570,27 +595,32 @@ TEST(SimulationResponseParserUnitTest, ParseEVMERC721Approval) { simulation_response->simulation_results->expected_state_changes.at(0); EXPECT_EQ(state_change->human_readable_diff, "Approve to transfer BoredApeYachtClub"); - EXPECT_EQ(state_change->raw_info->kind, "ERC721_APPROVAL"); + EXPECT_EQ(state_change->raw_info->kind, + mojom::BlowfishEVMRawInfoKind::kErc721Approval); ASSERT_TRUE(state_change->raw_info->data->is_erc721_approval_data()); const auto& state_change_raw_info = state_change->raw_info->data->get_erc721_approval_data(); EXPECT_EQ(state_change_raw_info->amount->before, "0"); EXPECT_EQ(state_change_raw_info->amount->after, "1"); - EXPECT_EQ(state_change_raw_info->contract->kind, "ACCOUNT"); + EXPECT_EQ(state_change_raw_info->contract->kind, + mojom::BlowfishEVMAddressKind::kAccount); EXPECT_EQ(state_change_raw_info->contract->address, "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d"); EXPECT_EQ(state_change_raw_info->metadata->raw_image_url, "https://example.com/6603.png"); EXPECT_EQ(state_change_raw_info->name, "BoredApeYachtClub"); - EXPECT_EQ(state_change_raw_info->owner->kind, "ACCOUNT"); + EXPECT_EQ(state_change_raw_info->owner->kind, + mojom::BlowfishEVMAddressKind::kAccount); EXPECT_EQ(state_change_raw_info->owner->address, "0xed2ab4948ba6a909a7751dec4f34f303eb8c7236"); - EXPECT_EQ(state_change_raw_info->spender->kind, "ACCOUNT"); + EXPECT_EQ(state_change_raw_info->spender->kind, + mojom::BlowfishEVMAddressKind::kAccount); EXPECT_EQ(state_change_raw_info->spender->address, "0x1e0049783f008a0085193e00003d00cd54003c71"); EXPECT_EQ(state_change_raw_info->symbol, "BAYC"); EXPECT_EQ(state_change_raw_info->token_id, "6603"); - EXPECT_EQ(state_change_raw_info->asset_price->source, "Simplehash"); + EXPECT_EQ(state_change_raw_info->asset_price->source, + mojom::BlowfishAssetPriceSource::kSimplehash); EXPECT_EQ(state_change_raw_info->asset_price->last_updated_at, "1679331222"); EXPECT_EQ(state_change_raw_info->asset_price->dollar_value_per_token, "7865.43"); @@ -670,7 +700,7 @@ TEST(SimulationResponseParserUnitTest, ParseEVMBuyERC1155TokenWithETH) { auto simulation_response = evm::ParseSimulationResponse(ParseJson(json)); ASSERT_TRUE(simulation_response); - EXPECT_EQ(simulation_response->action, "NONE"); + EXPECT_EQ(simulation_response->action, mojom::BlowfishSuggestedAction::kNone); EXPECT_EQ(simulation_response->warnings.size(), 0u); EXPECT_FALSE(simulation_response->simulation_results->error); ASSERT_EQ( @@ -680,13 +710,15 @@ TEST(SimulationResponseParserUnitTest, ParseEVMBuyERC1155TokenWithETH) { const auto& state_change_0 = simulation_response->simulation_results->expected_state_changes.at(0); EXPECT_EQ(state_change_0->human_readable_diff, "Send 0.033 ETH"); - EXPECT_EQ(state_change_0->raw_info->kind, "NATIVE_ASSET_TRANSFER"); + EXPECT_EQ(state_change_0->raw_info->kind, + mojom::BlowfishEVMRawInfoKind::kNativeAssetTransfer); ASSERT_TRUE(state_change_0->raw_info->data->is_native_asset_transfer_data()); const auto& state_change_0_raw_info = state_change_0->raw_info->data->get_native_asset_transfer_data(); EXPECT_EQ(state_change_0_raw_info->amount->before, "104057321770366572"); EXPECT_EQ(state_change_0_raw_info->amount->after, "71057321770366572"); - EXPECT_EQ(state_change_0_raw_info->contract->kind, "ACCOUNT"); + EXPECT_EQ(state_change_0_raw_info->contract->kind, + mojom::BlowfishEVMAddressKind::kAccount); EXPECT_EQ(state_change_0_raw_info->contract->address, "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); EXPECT_EQ(state_change_0_raw_info->asset->address, @@ -695,7 +727,9 @@ TEST(SimulationResponseParserUnitTest, ParseEVMBuyERC1155TokenWithETH) { EXPECT_EQ(state_change_0_raw_info->asset->image_url, "https://example.com/eth.png"); EXPECT_EQ(state_change_0_raw_info->asset->name, "Ether"); - EXPECT_EQ(state_change_0_raw_info->asset->price->source, "Coingecko"); + EXPECT_EQ(state_change_0_raw_info->asset->price->source, + mojom::BlowfishAssetPriceSource::kCoingecko); + EXPECT_EQ(state_change_0_raw_info->asset->price->last_updated_at, "1670324557"); EXPECT_EQ(state_change_0_raw_info->asset->price->dollar_value_per_token, @@ -706,20 +740,23 @@ TEST(SimulationResponseParserUnitTest, ParseEVMBuyERC1155TokenWithETH) { const auto& state_change_1 = simulation_response->simulation_results->expected_state_changes.at(1); EXPECT_EQ(state_change_1->human_readable_diff, "Receive Corgi"); - EXPECT_EQ(state_change_1->raw_info->kind, "ERC1155_TRANSFER"); + EXPECT_EQ(state_change_1->raw_info->kind, + mojom::BlowfishEVMRawInfoKind::kErc1155Transfer); ASSERT_TRUE(state_change_1->raw_info->data->is_erc1155_transfer_data()); const auto& state_change_1_raw_info = state_change_1->raw_info->data->get_erc1155_transfer_data(); EXPECT_EQ(state_change_1_raw_info->name, "Corgi"); EXPECT_EQ(state_change_1_raw_info->amount->before, "0"); EXPECT_EQ(state_change_1_raw_info->amount->after, "1"); - EXPECT_EQ(state_change_1_raw_info->contract->kind, "ACCOUNT"); + EXPECT_EQ(state_change_1_raw_info->contract->kind, + mojom::BlowfishEVMAddressKind::kAccount); EXPECT_EQ(state_change_1_raw_info->contract->address, "0x51e613727fdd2e0b91b51c3e5427e9440a7957e4"); EXPECT_EQ(state_change_1_raw_info->metadata->raw_image_url, "https://example.com/13014975.png"); EXPECT_EQ(state_change_1_raw_info->token_id, "13014975"); - EXPECT_EQ(state_change_1_raw_info->asset_price->source, "Simplehash"); + EXPECT_EQ(state_change_1_raw_info->asset_price->source, + mojom::BlowfishAssetPriceSource::kSimplehash); EXPECT_EQ(state_change_1_raw_info->asset_price->last_updated_at, "1679331222"); EXPECT_EQ(state_change_1_raw_info->asset_price->dollar_value_per_token, @@ -775,7 +812,7 @@ TEST(SimulationResponseParserUnitTest, ParseEVMERC1155Transfer) { evm::ParseSimulationResponse(ParseJson(json_with_token_name)); ASSERT_TRUE(simulation_response); - EXPECT_EQ(simulation_response->action, "NONE"); + EXPECT_EQ(simulation_response->action, mojom::BlowfishSuggestedAction::kNone); EXPECT_EQ(simulation_response->warnings.size(), 0u); EXPECT_FALSE(simulation_response->simulation_results->error); ASSERT_EQ( @@ -785,20 +822,23 @@ TEST(SimulationResponseParserUnitTest, ParseEVMERC1155Transfer) { const auto& state_change = simulation_response->simulation_results->expected_state_changes.at(0); EXPECT_EQ(state_change->human_readable_diff, "Receive Corgi"); - EXPECT_EQ(state_change->raw_info->kind, "ERC1155_TRANSFER"); + EXPECT_EQ(state_change->raw_info->kind, + mojom::BlowfishEVMRawInfoKind::kErc1155Transfer); ASSERT_TRUE(state_change->raw_info->data->is_erc1155_transfer_data()); const auto& state_change_raw_info = state_change->raw_info->data->get_erc1155_transfer_data(); EXPECT_EQ(state_change_raw_info->amount->before, "0"); EXPECT_EQ(state_change_raw_info->amount->after, "1"); EXPECT_EQ(state_change_raw_info->name, "Corgi"); - EXPECT_EQ(state_change_raw_info->contract->kind, "ACCOUNT"); + EXPECT_EQ(state_change_raw_info->contract->kind, + mojom::BlowfishEVMAddressKind::kAccount); EXPECT_EQ(state_change_raw_info->contract->address, "0x51e613727fdd2e0b91b51c3e5427e9440a7957e4"); EXPECT_EQ(state_change_raw_info->metadata->raw_image_url, "https://example.com/13014975.png"); EXPECT_EQ(state_change_raw_info->token_id, "13014975"); - EXPECT_EQ(state_change_raw_info->asset_price->source, "Simplehash"); + EXPECT_EQ(state_change_raw_info->asset_price->source, + mojom::BlowfishAssetPriceSource::kSimplehash); EXPECT_EQ(state_change_raw_info->asset_price->last_updated_at, "1679331222"); EXPECT_EQ(state_change_raw_info->asset_price->dollar_value_per_token, "232.43"); @@ -870,14 +910,15 @@ TEST(SimulationResponseParserUnitTest, ParseEVMERC1155ApprovalForAll) { auto simulation_response = evm::ParseSimulationResponse(ParseJson(json)); ASSERT_TRUE(simulation_response); - EXPECT_EQ(simulation_response->action, "WARN"); + EXPECT_EQ(simulation_response->action, mojom::BlowfishSuggestedAction::kWarn); ASSERT_EQ(simulation_response->warnings.size(), 1u); EXPECT_EQ(simulation_response->warnings.at(0)->kind, - "UNLIMITED_ALLOWANCE_TO_NFTS"); + mojom::BlowfishWarningKind::kUnlimitedAllowanceToNfts); EXPECT_EQ(simulation_response->warnings.at(0)->message, "You are allowing this website to withdraw funds from your account " "in the future"); - EXPECT_EQ(simulation_response->warnings.at(0)->severity, "WARNING"); + EXPECT_EQ(simulation_response->warnings.at(0)->severity, + mojom::BlowfishWarningSeverity::kWarning); EXPECT_FALSE(simulation_response->simulation_results->error); ASSERT_EQ( simulation_response->simulation_results->expected_state_changes.size(), @@ -887,7 +928,8 @@ TEST(SimulationResponseParserUnitTest, ParseEVMERC1155ApprovalForAll) { simulation_response->simulation_results->expected_state_changes.at(0); EXPECT_EQ(state_change->human_readable_diff, "Approve to transfer all your Sandbox's ASSETs"); - EXPECT_EQ(state_change->raw_info->kind, "ERC1155_APPROVAL_FOR_ALL"); + EXPECT_EQ(state_change->raw_info->kind, + mojom::BlowfishEVMRawInfoKind::kErc1155ApprovalForAll); ASSERT_TRUE(state_change->raw_info->data->is_erc1155_approval_for_all_data()); const auto& state_change_raw_info = state_change->raw_info->data->get_erc1155_approval_for_all_data(); @@ -895,16 +937,20 @@ TEST(SimulationResponseParserUnitTest, ParseEVMERC1155ApprovalForAll) { EXPECT_EQ(state_change_raw_info->amount->after, "115792089237316195423570985008687907853269984665640564039457584007" "913129639935"); - EXPECT_EQ(state_change_raw_info->contract->kind, "ACCOUNT"); + EXPECT_EQ(state_change_raw_info->contract->kind, + mojom::BlowfishEVMAddressKind::kAccount); EXPECT_EQ(state_change_raw_info->contract->address, "0xa342f5d851e866e18ff98f351f2c6637f4478db5"); - EXPECT_EQ(state_change_raw_info->owner->kind, "ACCOUNT"); + EXPECT_EQ(state_change_raw_info->owner->kind, + mojom::BlowfishEVMAddressKind::kAccount); EXPECT_EQ(state_change_raw_info->owner->address, "0xed2ab4948ba6a909a7751dec4f34f303eb8c7236"); - EXPECT_EQ(state_change_raw_info->spender->kind, "ACCOUNT"); + EXPECT_EQ(state_change_raw_info->spender->kind, + mojom::BlowfishEVMAddressKind::kAccount); EXPECT_EQ(state_change_raw_info->spender->address, "0x00000000006c3852cbef3e08e8df289169ede581"); - EXPECT_EQ(state_change_raw_info->asset_price->source, "Simplehash"); + EXPECT_EQ(state_change_raw_info->asset_price->source, + mojom::BlowfishAssetPriceSource::kSimplehash); EXPECT_EQ(state_change_raw_info->asset_price->last_updated_at, "1679331222"); EXPECT_EQ(state_change_raw_info->asset_price->dollar_value_per_token, "232.43"); @@ -999,11 +1045,11 @@ TEST(SimulationResponseParserUnitTest, ParseEVMUnknownError) { auto simulation_response = evm::ParseSimulationResponse(ParseJson(json)); ASSERT_TRUE(simulation_response); - EXPECT_EQ(simulation_response->action, "NONE"); + EXPECT_EQ(simulation_response->action, mojom::BlowfishSuggestedAction::kNone); EXPECT_EQ(simulation_response->warnings.size(), 0ULL); ASSERT_TRUE(simulation_response->simulation_results->error); EXPECT_EQ(simulation_response->simulation_results->error->kind, - "UNKNOWN_ERROR"); + mojom::BlowfishEVMErrorKind::kUnknownError); EXPECT_EQ( simulation_response->simulation_results->error->human_readable_error, "Unable to simulate transaction"); @@ -1060,7 +1106,8 @@ TEST(SimulationResponseParserUnitTest, ParseEVMNullableFields) { // OK: null values for asset->imageUrl and asset->price are allowed. ASSERT_TRUE(simulation_response); - EXPECT_EQ(simulation_response->action, "NONE"); + EXPECT_EQ(simulation_response->action, + mojom::BlowfishSuggestedAction::kNone); EXPECT_EQ(simulation_response->warnings.size(), 0ULL); EXPECT_FALSE(simulation_response->simulation_results->error); ASSERT_EQ( @@ -1070,7 +1117,8 @@ TEST(SimulationResponseParserUnitTest, ParseEVMNullableFields) { const auto& state_change = simulation_response->simulation_results->expected_state_changes.at(0); EXPECT_EQ(state_change->human_readable_diff, "Send 0.00307 BNB"); - EXPECT_EQ(state_change->raw_info->kind, "NATIVE_ASSET_TRANSFER"); + EXPECT_EQ(state_change->raw_info->kind, + mojom::BlowfishEVMRawInfoKind::kNativeAssetTransfer); ASSERT_TRUE(state_change->raw_info->data->is_native_asset_transfer_data()); const auto& state_change_raw_info = @@ -1079,7 +1127,8 @@ TEST(SimulationResponseParserUnitTest, ParseEVMNullableFields) { EXPECT_EQ(state_change_raw_info->amount->before, "93930808830306021"); EXPECT_EQ(state_change_raw_info->contract->address, "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); - EXPECT_EQ(state_change_raw_info->contract->kind, "ACCOUNT"); + EXPECT_EQ(state_change_raw_info->contract->kind, + mojom::BlowfishEVMAddressKind::kAccount); EXPECT_EQ(state_change_raw_info->asset->address, "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); EXPECT_EQ(state_change_raw_info->asset->decimals, 18); @@ -1384,7 +1433,7 @@ TEST(SimulationResponseParserUnitTest, ParseSolanaStateChanges) { auto simulation_response = solana::ParseSimulationResponse(ParseJson(json)); ASSERT_TRUE(simulation_response); - EXPECT_EQ(simulation_response->action, "NONE"); + EXPECT_EQ(simulation_response->action, mojom::BlowfishSuggestedAction::kNone); EXPECT_EQ(simulation_response->warnings.size(), 0u); EXPECT_FALSE(simulation_response->simulation_results->error); EXPECT_FALSE( @@ -1396,8 +1445,10 @@ TEST(SimulationResponseParserUnitTest, ParseSolanaStateChanges) { const auto& state_change_0 = simulation_response->simulation_results->expected_state_changes.at(0); EXPECT_EQ(state_change_0->human_readable_diff, "Receive 0.05657 SOL"); - EXPECT_EQ(state_change_0->suggested_color, "CREDIT"); - EXPECT_EQ(state_change_0->raw_info->kind, "SOL_TRANSFER"); + EXPECT_EQ(state_change_0->suggested_color, + mojom::BlowfishSuggestedColor::kCredit); + EXPECT_EQ(state_change_0->raw_info->kind, + mojom::BlowfishSolanaRawInfoKind::kSolTransfer); ASSERT_TRUE(state_change_0->raw_info->data->is_sol_transfer_data()); const auto& state_change_0_raw_info = @@ -1405,14 +1456,17 @@ TEST(SimulationResponseParserUnitTest, ParseSolanaStateChanges) { EXPECT_EQ(state_change_0_raw_info->symbol, "SOL"); EXPECT_EQ(state_change_0_raw_info->name, "Solana Native Token"); EXPECT_EQ(state_change_0_raw_info->decimals, 9); - EXPECT_EQ(state_change_0_raw_info->diff->sign, "PLUS"); + EXPECT_EQ(state_change_0_raw_info->diff->sign, + mojom::BlowfishDiffSign::kPlus); EXPECT_EQ(state_change_0_raw_info->diff->digits, 56573477ULL); const auto& state_change_1 = simulation_response->simulation_results->expected_state_changes.at(1); EXPECT_EQ(state_change_1->human_readable_diff, "Send 2 USDT"); - EXPECT_EQ(state_change_1->suggested_color, "DEBIT"); - EXPECT_EQ(state_change_1->raw_info->kind, "SPL_TRANSFER"); + EXPECT_EQ(state_change_1->suggested_color, + mojom::BlowfishSuggestedColor::kDebit); + EXPECT_EQ(state_change_1->raw_info->kind, + mojom::BlowfishSolanaRawInfoKind::kSplTransfer); ASSERT_TRUE(state_change_1->raw_info->data->is_spl_transfer_data()); const auto& state_change_1_raw_info = @@ -1423,21 +1477,26 @@ TEST(SimulationResponseParserUnitTest, ParseSolanaStateChanges) { "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"); EXPECT_EQ(state_change_1_raw_info->decimals, 6); EXPECT_EQ(state_change_1_raw_info->supply, 1000000000ULL); - EXPECT_EQ(state_change_1_raw_info->metaplex_token_standard, "unknown"); - EXPECT_EQ(state_change_1_raw_info->asset_price->source, "Coingecko"); + EXPECT_EQ(state_change_1_raw_info->metaplex_token_standard, + mojom::BlowfishMetaplexTokenStandardKind::kUnknown); + EXPECT_EQ(state_change_1_raw_info->asset_price->source, + mojom::BlowfishAssetPriceSource::kCoingecko); EXPECT_EQ(state_change_1_raw_info->asset_price->last_updated_at, "1679331222"); EXPECT_EQ(state_change_1_raw_info->asset_price->dollar_value_per_token, "0.99"); - EXPECT_EQ(state_change_1_raw_info->diff->sign, "MINUS"); + EXPECT_EQ(state_change_1_raw_info->diff->sign, + mojom::BlowfishDiffSign::kMinus); EXPECT_EQ(state_change_1_raw_info->diff->digits, 2000000ULL); const auto& state_change_2 = simulation_response->simulation_results->expected_state_changes.at(2); EXPECT_EQ(state_change_2->human_readable_diff, "Approve to transfer Phantom QA NFT"); - EXPECT_EQ(state_change_2->suggested_color, "DEBIT"); - EXPECT_EQ(state_change_2->raw_info->kind, "SPL_APPROVAL"); + EXPECT_EQ(state_change_2->suggested_color, + mojom::BlowfishSuggestedColor::kDebit); + EXPECT_EQ(state_change_2->raw_info->kind, + mojom::BlowfishSolanaRawInfoKind::kSplApproval); ASSERT_TRUE(state_change_2->raw_info->data->is_spl_approval_data()); const auto& state_change_2_raw_info = @@ -1449,18 +1508,22 @@ TEST(SimulationResponseParserUnitTest, ParseSolanaStateChanges) { EXPECT_EQ(state_change_2_raw_info->symbol, "PHANTOMQA"); EXPECT_EQ(state_change_2_raw_info->name, "Phantom QA NFT"); EXPECT_EQ(state_change_2_raw_info->decimals, 0); - EXPECT_EQ(state_change_2_raw_info->diff->sign, "PLUS"); + EXPECT_EQ(state_change_2_raw_info->diff->sign, + mojom::BlowfishDiffSign::kPlus); EXPECT_EQ(state_change_2_raw_info->diff->digits, 1525878906250000000ULL); EXPECT_EQ(state_change_2_raw_info->supply, 1ULL); - EXPECT_EQ(state_change_2_raw_info->metaplex_token_standard, "non_fungible"); + EXPECT_EQ(state_change_2_raw_info->metaplex_token_standard, + mojom::BlowfishMetaplexTokenStandardKind::kNonFungible); EXPECT_FALSE(state_change_2_raw_info->asset_price); const auto& state_change_3 = simulation_response->simulation_results->expected_state_changes.at(3); EXPECT_EQ(state_change_3->human_readable_diff, "Unapprove from transferring up to 0.00132 USDC"); - EXPECT_EQ(state_change_3->suggested_color, "CREDIT"); - EXPECT_EQ(state_change_3->raw_info->kind, "SPL_APPROVAL"); + EXPECT_EQ(state_change_3->suggested_color, + mojom::BlowfishSuggestedColor::kCredit); + EXPECT_EQ(state_change_3->raw_info->kind, + mojom::BlowfishSolanaRawInfoKind::kSplApproval); ASSERT_TRUE(state_change_3->raw_info->data->is_spl_approval_data()); const auto& state_change_3_raw_info = @@ -1472,11 +1535,14 @@ TEST(SimulationResponseParserUnitTest, ParseSolanaStateChanges) { EXPECT_EQ(state_change_3_raw_info->symbol, "USDC"); EXPECT_EQ(state_change_3_raw_info->name, "USD Coin"); EXPECT_EQ(state_change_3_raw_info->decimals, 6); - EXPECT_EQ(state_change_3_raw_info->diff->sign, "MINUS"); + EXPECT_EQ(state_change_3_raw_info->diff->sign, + mojom::BlowfishDiffSign::kMinus); EXPECT_EQ(state_change_3_raw_info->diff->digits, 1321ULL); EXPECT_EQ(state_change_3_raw_info->supply, 5034964468128435ULL); - EXPECT_EQ(state_change_3_raw_info->metaplex_token_standard, "unknown"); - EXPECT_EQ(state_change_3_raw_info->asset_price->source, "Coingecko"); + EXPECT_EQ(state_change_3_raw_info->metaplex_token_standard, + mojom::BlowfishMetaplexTokenStandardKind::kUnknown); + EXPECT_EQ(state_change_3_raw_info->asset_price->source, + mojom::BlowfishAssetPriceSource::kCoingecko); EXPECT_EQ(state_change_3_raw_info->asset_price->last_updated_at, "1679331222"); EXPECT_EQ(state_change_3_raw_info->asset_price->dollar_value_per_token, @@ -1486,8 +1552,10 @@ TEST(SimulationResponseParserUnitTest, ParseSolanaStateChanges) { simulation_response->simulation_results->expected_state_changes.at(4); EXPECT_EQ(state_change_4->human_readable_diff, "Transfer control over your SOL staking account 2AG3be..p2vFQS"); - EXPECT_EQ(state_change_4->suggested_color, "DEBIT"); - EXPECT_EQ(state_change_4->raw_info->kind, "SOL_STAKE_AUTHORITY_CHANGE"); + EXPECT_EQ(state_change_4->suggested_color, + mojom::BlowfishSuggestedColor::kDebit); + EXPECT_EQ(state_change_4->raw_info->kind, + mojom::BlowfishSolanaRawInfoKind::kSolStakeAuthorityChange); ASSERT_TRUE( state_change_4->raw_info->data->is_sol_stake_authority_change_data()); @@ -1545,18 +1613,20 @@ TEST(SimulationResponseParserUnitTest, ParseSolanaWarnings) { auto simulation_response = solana::ParseSimulationResponse(ParseJson(json)); ASSERT_TRUE(simulation_response); - EXPECT_EQ(simulation_response->action, "BLOCK"); + EXPECT_EQ(simulation_response->action, + mojom::BlowfishSuggestedAction::kBlock); ASSERT_EQ(simulation_response->warnings.size(), 2ULL); const auto& warning_1 = simulation_response->warnings.at(0); - EXPECT_EQ(warning_1->severity, "CRITICAL"); - EXPECT_EQ(warning_1->kind, "TRUSTED_BLOCKLIST_DOMAIN"); + EXPECT_EQ(warning_1->severity, mojom::BlowfishWarningSeverity::kCritical); + EXPECT_EQ(warning_1->kind, + mojom::BlowfishWarningKind::kTrustedBlocklistDomain); EXPECT_EQ(warning_1->message, "This transaction originates from a known malicious domain."); const auto& warning_2 = simulation_response->warnings.at(1); - EXPECT_EQ(warning_2->severity, "WARNING"); - EXPECT_EQ(warning_2->kind, "SUSPECTED_MALICIOUS"); + EXPECT_EQ(warning_2->severity, mojom::BlowfishWarningSeverity::kWarning); + EXPECT_EQ(warning_2->kind, mojom::BlowfishWarningKind::kSuspectedMalicious); EXPECT_EQ(warning_2->message, "We suspect this transaction is malicious. Approving may lead to " "loss of funds."); diff --git a/components/brave_wallet/browser/simulation_responses.idl b/components/brave_wallet/browser/simulation_responses.idl index 051ce45284e5..e3daf4a41f78 100644 --- a/components/brave_wallet/browser/simulation_responses.idl +++ b/components/brave_wallet/browser/simulation_responses.idl @@ -5,8 +5,103 @@ // Dummy comments to make the linter happy. namespace simulation_responses { + + enum WarningSeverity { + CRITICAL, + WARNING + }; + + // UI should defer to the supplied message if the kind isn't recognized + enum WarningKind { + APPROVAL_TO_E_O_A, + BLOCKLISTED_DOMAIN_CROSS_ORIGIN, + BULK_APPROVALS_REQUEST, + COMPROMISED_AUTHORITY_UPGRADE, + COPY_CAT_DOMAIN, + COPY_CAT_IMAGE_UNRESPONSIVE_DOMAIN, + DANGLING_APPROVAL, + DEVTOOLS_DISABLED, + ETH_SIGN_TX_HASH, + KNOWN_MALICIOUS, + MAINNET_REPLAY_POSSIBLE, + MULTI_COPY_CAT_DOMAIN, + NEW_DOMAIN, + NON_ASCII_URL, + OBFUSCATED_CODE, + PERMIT_NO_EXPIRATION, + PERMIT_UNLIMITED_ALLOWANCE, + POISONED_ADDRESS, + REFERENCED_OFAC_ADDRESS, + SEMI_TRUSTED_BLOCKLIST_DOMAIN, + SET_OWNER_AUTHORITY, + SUSPECTED_MALICIOUS, + TOO_MANY_TRANSACTIONS, + TRADE_FOR_NOTHING, + TRANSFERRING_ERC20_TO_OWN_CONTRACT, + TRUSTED_BLOCKLIST_DOMAIN, + UNLIMITED_ALLOWANCE_TO_NFTS, + UNUSUAL_GAS_CONSUMPTION, + USER_ACCOUNT_OWNER_CHANGE, + WHITELISTED_DOMAIN_CROSS_ORIGIN + }; + + enum EVMRawInfoKind { + ERC20_TRANSFER, + ERC20_APPROVAL, + NATIVE_ASSET_TRANSFER, + ERC721_TRANSFER, + ERC721_APPROVAL, + ERC721_APPROVAL_FOR_ALL, + ERC1155_TRANSFER, + ERC1155_APPROVAL_FOR_ALL, + ANY_NFT_FROM_COLLECTION_TRANSFER + }; + + enum SolanaRawInfoKind { + SOL_TRANSFER, + SPL_TRANSFER, + SPL_APPROVAL, + SOL_STAKE_AUTHORITY_CHANGE, + USER_ACCOUNT_OWNER_CHANGE + }; + + enum MetaplexTokenStandardKind { + non_fungible, + fungible_asset, + fungible, + non_fungible_edition, + unknown + }; + + enum DiffSign { + PLUS, + MINUS + }; + + enum EVMAddressKind { + ACCOUNT + }; + + enum AssetPriceSource { + Simplehash, + Defillama, + Coingecko + }; + + enum EVMErrorKind { + TRANSACTION_REVERTED, + TRANSACTION_ERROR, + SIMULATION_FAILED, + UNKNOWN_ERROR + }; + + enum SuggestedColor { + CREDIT, + DEBIT + }; + dictionary SolanaPrice { - DOMString source; + AssetPriceSource source; // FIXME: The fields below should be in camelCase. Needs an upstream fix. DOMString last_updated_at; @@ -14,25 +109,25 @@ namespace simulation_responses { }; dictionary Price { - DOMString source; + AssetPriceSource source; DOMString updatedAt; DOMString dollarValuePerToken; }; dictionary Warning { - DOMString severity; - DOMString kind; + WarningSeverity severity; + WarningKind kind; DOMString message; }; dictionary EVMError { - DOMString kind; + EVMErrorKind kind; DOMString humanReadableError; }; dictionary EVMContract { + EVMAddressKind kind; DOMString address; - DOMString kind; }; dictionary EVMAmount { @@ -144,7 +239,7 @@ namespace simulation_responses { }; dictionary EVMStateChangeRawInfo { - DOMString kind; + EVMRawInfoKind kind; // data is a non-nullable union of the following types: // - ERC20TransferData @@ -171,13 +266,13 @@ namespace simulation_responses { }; dictionary EVMSimulationResponse { - DOMString action; + DOMString action; // BLOCK | WARN | NONE Warning[] warnings; EVMSimulationResults simulationResults; }; dictionary SolanaDiff { - DOMString sign; + DiffSign sign; DOMString digits; }; @@ -187,6 +282,71 @@ namespace simulation_responses { }; dictionary SolanaError { + // ACCOUNT_DOES_NOT_HAVE_ENOUGH_SOL_TO_PERFORM_THE_OPERATION + // ACCOUNT_DOES_NOT_SUPPORT_SPECIFIED_AUTHORITY_TYPE + // ACCOUNT_IN_USE + // ACCOUNT_IS_FROZEN + // ACCOUNT_LOADED_TWICE + // ACCOUNT_NOT_ASSOCIATED_WITH_THIS_MINT + // ADVANCING_STORED_NONCE_REQUIRES_A_POPULATED_RECENTBLOCKHASHES_SYSVAR + // ALREADY_IN_USE + // AN_ACCOUNT_WITH_THE_SAME_ADDRESS_ALREADY_EXISTS + // ATTEMPT_TO_DEBIT_AN_ACCOUNT_BUT_FOUND_NO_RECORD_OF_A_PRIOR_CREDIT + // ATTEMPT_TO_LOAD_A_PROGRAM_THAT_DOES_NOT_EXIST + // BAD_REQUEST + // BLOCKHASH_NOT_FOUND + // CANNOT_ALLOCATE_ACCOUNT_DATA_OF_THIS_LENGTH + // CANNOT_ASSIGN_ACCOUNT_TO_THIS_PROGRAM_ID + // ERROR_PROCESSING_INSTRUCTION_{0}:_{1} + // FIXED_SUPPLY + // INSTRUCTION_DOES_NOT_SUPPORT_NATIVE_TOKENS + // INSTRUCTION_DOES_NOT_SUPPORT_NON-NATIVE_TOKENS + // INSUFFICIENT_FUNDS + // INSUFFICIENT_FUNDS_FOR_FEE + // INVALID_INSTRUCTION + // INVALID_MINT + // INVALID_NUMBER_OF_PROVIDED_SIGNERS + // INVALID_NUMBER_OF_REQUIRED_SIGNERS + // LAMPORT_BALANCE_BELOW_RENT-EXEMPT_THRESHOLD + // LENGTH_OF_REQUESTED_SEED_IS_TOO_LONG + // LOADER_CALL_CHAIN_IS_TOO_DEEP + // NON-NATIVE_ACCOUNT_CAN_ONLY_BE_CLOSED_IF_ITS_BALANCE_IS_ZERO + // OPERATION_OVERFLOWED + // OWNER_DOES_NOT_MATCH + // PROVIDED_ADDRESS_DOES_NOT_MATCH_ADDRESSED_DERIVED_FROM_SEED + // SIMULATION_FAILED + // SIMULATION_TIMED_OUT + // SPECIFIED_NONCE_DOES_NOT_MATCH_STORED_NONCE + // STATE_IS_INVALID_FOR_REQUESTED_OPERATION + // STATE_IS_UNINITIALIZED + // STORED_NONCE_IS_STILL_IN_RECENT_BLOCKHASHES + // THE_PROVIDED_DECIMALS_VALUE_DIFFERENT_FROM_THE_MINT_DECIMALS + // THIS_ACCOUNT_MAY_NOT_BE_USED_TO_PAY_TRANSACTION_FEES + // THIS_PROGRAM_MAY_NOT_BE_USED_FOR_EXECUTING_INSTRUCTIONS + // THIS_TOKEN_MINT_CANNOT_FREEZE_ACCOUNTS + // THIS_TRANSACTION_HAS_ALREADY_BEEN_PROCESSED + // TOO_MANY_TRANSACTIONS + // TRANSACTION_ADDRESS_TABLE_LOOKUP_USES_AN_INVALID_INDEX + // TRANSACTION_CONTAINS_A_DUPLICATE_INSTRUCTION_({0})_THAT_IS_NOT_ALLOWED + // TRANSACTION_CONTAINS_AN_INVALID_ACCOUNT_REFERENCE + // TRANSACTION_DID_NOT_PASS_SIGNATURE_VERIFICATION + // TRANSACTION_FAILED_TO_SANITIZE_ACCOUNTS_OFFSETS_CORRECTLY + // TRANSACTION_LEAVES_AN_ACCOUNT_WITH_A_LOWER_BALANCE_THAN_RENT-EXEMPT_MINIMUM + // TRANSACTION_LOADS_A_WRITABLE_ACCOUNT_THAT_CANNOT_BE_WRITTEN + // TRANSACTION_LOADS_AN_ADDRESS_TABLE_ACCOUNT_THAT_DOESN'T_EXIST + // TRANSACTION_LOADS_AN_ADDRESS_TABLE_ACCOUNT_WITH_AN_INVALID_OWNER + // TRANSACTION_LOADS_AN_ADDRESS_TABLE_ACCOUNT_WITH_INVALID_DATA + // TRANSACTION_LOCKED_TOO_MANY_ACCOUNTS + // TRANSACTION_PROCESSING_LEFT_AN_ACCOUNT_WITH_AN_OUTSTANDING_BORROWED_REFERENCE + // TRANSACTION_REQUIRES_A_FEE_BUT_HAS_NO_SIGNATURE_PRESENT + // TRANSACTION_VERSION_IS_UNSUPPORTED + // TRANSACTION_WOULD_EXCEED_ACCOUNT_DATA_LIMIT_WITHIN_THE_BLOCK + // TRANSACTION_WOULD_EXCEED_MAX_ACCOUNT_LIMIT_WITHIN_THE_BLOCK + // TRANSACTION_WOULD_EXCEED_MAX_BLOCK_COST_LIMIT + // TRANSACTION_WOULD_EXCEED_MAX_VOTE_COST_LIMIT + // TRANSACTION_WOULD_EXCEED_TOTAL_ACCOUNT_DATA_LIMIT + // TRANSACTIONS_ARE_CURRENTLY_DISABLED_DUE_TO_CLUSTER_MAINTENANCE + // UNKNOWN_ERROR DOMString kind; DOMString humanReadableError; }; @@ -205,7 +365,7 @@ namespace simulation_responses { DOMString decimals; SolanaDiff diff; DOMString supply; - DOMString metaplexTokenStandard; + MetaplexTokenStandardKind metaplexTokenStandard; // nullable field of type SolanaPrice any assetPrice; @@ -219,7 +379,7 @@ namespace simulation_responses { DOMString decimals; SolanaDiff diff; DOMString supply; - DOMString metaplexTokenStandard; + MetaplexTokenStandardKind metaplexTokenStandard; // nullable field of type SolanaPrice any assetPrice; @@ -236,7 +396,7 @@ namespace simulation_responses { }; dictionary SolanaStateChangeRawInfo { - DOMString kind; + SolanaRawInfoKind kind; // data is a non-nullable union of the following types: // - SOLTransferData @@ -248,7 +408,7 @@ namespace simulation_responses { dictionary SolanaStateChange { DOMString humanReadableDiff; - DOMString suggestedColor; + SuggestedColor suggestedColor; SolanaStateChangeRawInfo rawInfo; }; @@ -260,7 +420,7 @@ namespace simulation_responses { }; dictionary SolanaSimulationResponse { - DOMString action; + DOMString action; // BLOCK | WARN | NONE Warning[] warnings; SolanaSimulationResults simulationResults; }; diff --git a/components/brave_wallet/browser/simulation_service_unittest.cc b/components/brave_wallet/browser/simulation_service_unittest.cc index e5eefa251cd2..d2759035ba96 100644 --- a/components/brave_wallet/browser/simulation_service_unittest.cc +++ b/components/brave_wallet/browser/simulation_service_unittest.cc @@ -304,7 +304,7 @@ TEST_F(SimulationServiceUnitTest, ScanEVMTransactionValidResponse) { const std::string& error_response, const std::string& error_string) { ASSERT_TRUE(response); - EXPECT_EQ(response->action, "NONE"); + EXPECT_EQ(response->action, mojom::BlowfishSuggestedAction::kNone); EXPECT_EQ(response->warnings.size(), 0u); EXPECT_FALSE(response->simulation_results->error); ASSERT_EQ(response->simulation_results->expected_state_changes.size(), @@ -313,7 +313,8 @@ TEST_F(SimulationServiceUnitTest, ScanEVMTransactionValidResponse) { const auto& state_change = response->simulation_results->expected_state_changes.at(0).Clone(); EXPECT_EQ(state_change->human_readable_diff, "Send 1 ETH"); - EXPECT_EQ(state_change->raw_info->kind, "NATIVE_ASSET_TRANSFER"); + EXPECT_EQ(state_change->raw_info->kind, + mojom::BlowfishEVMRawInfoKind::kNativeAssetTransfer); ASSERT_TRUE( state_change->raw_info->data->is_native_asset_transfer_data()); const auto& state_change_raw_info = @@ -325,7 +326,8 @@ TEST_F(SimulationServiceUnitTest, ScanEVMTransactionValidResponse) { "1183957389356504134754"); EXPECT_EQ(state_change_raw_info->contract->address, "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); - EXPECT_EQ(state_change_raw_info->contract->kind, "ACCOUNT"); + EXPECT_EQ(state_change_raw_info->contract->kind, + mojom::BlowfishEVMAddressKind::kAccount); EXPECT_EQ(state_change_raw_info->asset->address, "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); EXPECT_EQ(state_change_raw_info->asset->decimals, 18); @@ -334,7 +336,8 @@ TEST_F(SimulationServiceUnitTest, ScanEVMTransactionValidResponse) { EXPECT_EQ(state_change_raw_info->asset->name, "Ether"); EXPECT_EQ(state_change_raw_info->asset->price->dollar_value_per_token, "1968.47"); - EXPECT_EQ(state_change_raw_info->asset->price->source, "Coingecko"); + EXPECT_EQ(state_change_raw_info->asset->price->source, + mojom::BlowfishAssetPriceSource::kCoingecko); EXPECT_EQ(state_change_raw_info->asset->price->last_updated_at, "1670324557"); EXPECT_EQ(state_change_raw_info->asset->symbol, "ETH"); @@ -490,7 +493,7 @@ TEST_F(SimulationServiceUnitTest, ScanSolanaTransactionValid) { const std::string& error_string) { ASSERT_TRUE(response); - EXPECT_EQ(response->action, "NONE"); + EXPECT_EQ(response->action, mojom::BlowfishSuggestedAction::kNone); EXPECT_EQ(response->warnings.size(), 0u); EXPECT_FALSE(response->simulation_results->error); EXPECT_FALSE(response->simulation_results->is_recent_blockhash_expired); @@ -500,8 +503,10 @@ TEST_F(SimulationServiceUnitTest, ScanSolanaTransactionValid) { const auto& state_change = response->simulation_results->expected_state_changes.at(0); EXPECT_EQ(state_change->human_readable_diff, "Send 2 USDT"); - EXPECT_EQ(state_change->suggested_color, "DEBIT"); - EXPECT_EQ(state_change->raw_info->kind, "SPL_TRANSFER"); + EXPECT_EQ(state_change->suggested_color, + mojom::BlowfishSuggestedColor::kDebit); + EXPECT_EQ(state_change->raw_info->kind, + mojom::BlowfishSolanaRawInfoKind::kSplTransfer); ASSERT_TRUE(state_change->raw_info->data->is_spl_transfer_data()); const auto& state_change_raw_info = @@ -512,13 +517,16 @@ TEST_F(SimulationServiceUnitTest, ScanSolanaTransactionValid) { "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"); EXPECT_EQ(state_change_raw_info->decimals, 6); EXPECT_EQ(state_change_raw_info->supply, 1000000000ULL); - EXPECT_EQ(state_change_raw_info->metaplex_token_standard, "unknown"); - EXPECT_EQ(state_change_raw_info->asset_price->source, "Coingecko"); + EXPECT_EQ(state_change_raw_info->metaplex_token_standard, + mojom::BlowfishMetaplexTokenStandardKind::kUnknown); + EXPECT_EQ(state_change_raw_info->asset_price->source, + mojom::BlowfishAssetPriceSource::kCoingecko); EXPECT_EQ(state_change_raw_info->asset_price->last_updated_at, "1679331222"); EXPECT_EQ(state_change_raw_info->asset_price->dollar_value_per_token, "0.99"); - EXPECT_EQ(state_change_raw_info->diff->sign, "MINUS"); + EXPECT_EQ(state_change_raw_info->diff->sign, + mojom::BlowfishDiffSign::kMinus); EXPECT_EQ(state_change_raw_info->diff->digits, 2000000ULL); EXPECT_EQ(error_response, ""); diff --git a/components/brave_wallet/common/brave_wallet.mojom b/components/brave_wallet/common/brave_wallet.mojom index 8883410e795d..689b72632c36 100644 --- a/components/brave_wallet/common/brave_wallet.mojom +++ b/components/brave_wallet/common/brave_wallet.mojom @@ -2190,27 +2190,204 @@ union SolanaTransactionRequestUnion { }; // Common Blowfish types for both EVM and Solana. +enum BlowfishSuggestedAction { + // Show the user a block screen instead of the signing UI since + // this is highly likely to be a malicious transaction. + kBlock, + // Show the user the supplied warnings. + kWarn, + // Show the signing UI without modification. + kNone, +}; + +enum BlowfishWarningSeverity { + kCritical, + kWarning +}; + +// UI should defer to the supplied message if the kind isn't recognized +enum BlowfishWarningKind { + kSuspectedMalicious, + kKnownMalicious, + kTransferringErc20ToOwnContract, + kUnlimitedAllowanceToNfts, + kBulkApprovalsRequest, + kSetOwnerAuthority, + kTrustedBlocklistDomain, + kSemiTrustedBlocklistDomain, + kDanglingApproval, + kTradeForNothing, + kPermitUnlimitedAllowance, + kPermitNoExpiration, + kEthSignTxHash, + kObfuscatedCode, + kDevtoolsDisabled, + kBlocklistedDomainCrossOrigin, + kWhitelistedDomainCrossOrigin, + kTooManyTransactions, + kNonAsciiUrl, + kCompromisedAuthorityUpgrade, + kPoisonedAddress, + kApprovalToEOA, + kCopyCatDomain, + kCopyCatImageUnresponsiveDomain, + kMultiCopyCatDomain, + kUserAccountOwnerChange, + kNewDomain, + kUnusualGasConsumption, + kReferencedOfacAddress, + kMainnetReplayPossible, + kUnknown = -1 +}; + +enum BlowfishEVMRawInfoKind { + kErc20Transfer, + kErc20Approval, + kNativeAssetTransfer, + kErc721Transfer, + kErc721Approval, + kErc721ApprovalForAll, + kErc1155Transfer, + kErc1155ApprovalForAll, + kAnyNftFromCollectionTransfer, + kUnknown = -1 +}; + +enum BlowfishSolanaRawInfoKind { + kSolTransfer, + kSplTransfer, + kSplApproval, + kSolStakeAuthorityChange, + kUserAccountOwnerChange, + kUnknown = -1 +}; + +enum BlowfishMetaplexTokenStandardKind { + kNonFungible, + kFungibleAsset, + kFungible, + kNonFungibleEdition, + kUnknown = -1 +}; + +enum BlowfishDiffSign { + kPlus, + kMinus +}; + +enum BlowfishEVMAddressKind { + kAccount, + kUnknown = -1 +}; + +enum BlowfishAssetPriceSource { + kSimplehash, + kDefillama, + kCoingecko, + kUnknown = -1 +}; + +enum BlowfishEVMErrorKind { + kTransactionReverted, + kTransactionError, + kSimulationFailed, + kUnknownError +}; + +enum BlowfishSolanaErrorKind { + kAccountDoesNotHaveEnoughSolToPerformTheOperation, + kAccountDoesNotSupportSpecifiedAuthorityType, + kAccountInUse, + kAccountIsFrozen, + kAccountLoadedTwice, + kAccountNotAssociatedWithThisMint, + kAdvancingStoredNonceRequiresAPopulatedRecentblockhashesSysvar, + kAlreadyInUse, + kAnAccountWithTheSameAddressAlreadyExists, + kAttemptToDebitAnAccountButFoundNoRecordOfAPriorCredit, + kAttemptToLoadAProgramThatDoesNotExist, + kBadRequest, + kBlockhashNotFound, + kCannotAllocateAccountDataOfThisLength, + kCannotAssignAccountToThisProgramId, + kErrorProcessingInstruction, + kFixedSupply, + kInstructionDoesNotSupportNativeTokens, + kInstructionDoesNotSupportNonNativeTokens, + kInsufficientFunds, + kInsufficientFundsForFee, + kInvalidInstruction, + kInvalidMint, + kInvalidNumberOfProvidedSigners, + kInvalidNumberOfRequiredSigners, + kLamportBalanceBelowRentExemptThreshold, + kLengthOfRequestedSeedIsTooLong, + kLoaderCallChainIsTooDeep, + kNonNativeAccountCanOnlyBeClosedIfItsBalanceIsZero, + kOperationOverflowed, + kOwnerDoesNotMatch, + kProvidedAddressDoesNotMatchAddressedDerivedFromSeed, + kSimulationFailed, + kSimulationTimedOut, + kSpecifiedNonceDoesNotMatchStoredNonce, + kStateIsInvalidForRequestedOperation, + kStateIsUninitialized, + kStoredNonceIsStillInRecentBlockhashes, + kTheProvidedDecimalsValueDifferentFromTheMintDecimals, + kThisAccountMayNotBeUsedToPayTransactionFees, + kThisProgramMayNotBeUsedForExecutingInstructions, + kThisTokenMintCannotFreezeAccounts, + kThisTransactionHasAlreadyBeenProcessed, + kTooManyTransactions, + kTransactionAddressTableLookupUsesAnInvalidIndex, + kTransactionContainsADuplicateInstructionThatIsNotAllowed, + kTransactionContainsAnInvalidAccountReference, + kTransactionDidNotPassSignatureVerification, + kTransactionFailedToSanitizeAccountsOffsetsCorrectly, + kTransactionLeavesAnAccountWithALowerBalanceThanRentExemptMinimum, + kTransactionLoadsAnAddressTableAccountThatDoesntExist, + kTransactionLoadsAnAddressTableAccountWithAnInvalidOwner, + kTransactionLoadsAnAddressTableAccountWithInvalidData, + kTransactionLoadsAWritableAccountThatCannotBeWritten, + kTransactionLockedTooManyAccounts, + kTransactionProcessingLeftAnAccountWithAnOutstandingBorrowedReference, + kTransactionRequiresAFeeButHasNoSignaturePresent, + kTransactionsAreCurrentlyDisabledDueToClusterMaintenance, + kTransactionVersionIsUnsupported, + kTransactionWouldExceedAccountDataLimitWithinTheBlock, + kTransactionWouldExceedMaxAccountLimitWithinTheBlock, + kTransactionWouldExceedMaxBlockCostLimit, + kTransactionWouldExceedMaxVoteCostLimit, + kTransactionWouldExceedTotalAccountDataLimit, + kUnknownError = -1 +}; + +enum BlowfishSuggestedColor { + kCredit, + kDebit +}; + struct BlowfishPrice { - string source; + BlowfishAssetPriceSource source; string last_updated_at; string dollar_value_per_token; }; struct BlowfishWarning { - string severity; - string kind; + BlowfishWarningSeverity severity; + BlowfishWarningKind kind; string message; }; // Blowfish types specific to EVM. struct BlowfishEVMError { - string kind; + BlowfishEVMErrorKind kind; string human_readable_error; }; struct BlowfishEVMContract { string address; - string kind; + BlowfishEVMAddressKind kind; }; struct BlowfishEVMAmount { @@ -2314,7 +2491,7 @@ union BlowfishEVMStateChangeRawInfoDataUnion { }; struct BlowfishEVMStateChangeRawInfo { - string kind; + BlowfishEVMRawInfoKind kind; BlowfishEVMStateChangeRawInfoDataUnion data; }; @@ -2329,19 +2506,19 @@ struct EVMSimulationResults { }; struct EVMSimulationResponse { - string action; + BlowfishSuggestedAction action; EVMSimulationResults simulation_results; array warnings; }; // Blowfish types specific to Solana. struct BlowfishSolanaError { - string kind; + BlowfishSolanaErrorKind kind; string human_readable_error; }; struct BlowfishSolanaDiff { - string sign; + BlowfishDiffSign sign; uint64 digits; }; @@ -2364,7 +2541,7 @@ struct BlowfishSPLTransferData { int32 decimals; BlowfishSolanaDiff diff; uint64 supply; - string metaplex_token_standard; + BlowfishMetaplexTokenStandardKind metaplex_token_standard; BlowfishPrice? asset_price; }; @@ -2376,7 +2553,7 @@ struct BlowfishSPLApprovalData { int32 decimals; BlowfishSolanaDiff diff; uint64 supply; - string metaplex_token_standard; + BlowfishMetaplexTokenStandardKind metaplex_token_standard; BlowfishPrice? asset_price; }; @@ -2398,13 +2575,13 @@ union BlowfishSolanaStateChangeRawInfoDataUnion { }; struct BlowfishSolanaStateChangeRawInfo { - string kind; + BlowfishSolanaRawInfoKind kind; BlowfishSolanaStateChangeRawInfoDataUnion data; }; struct BlowfishSolanaStateChange { string human_readable_diff; - string suggested_color; + BlowfishSuggestedColor suggested_color; BlowfishSolanaStateChangeRawInfo raw_info; }; @@ -2415,7 +2592,7 @@ struct SolanaSimulationResults { }; struct SolanaSimulationResponse { - string action; + BlowfishSuggestedAction action; array warnings; SolanaSimulationResults simulation_results; }; diff --git a/components/brave_wallet_ui/common/constants/blowfish.ts b/components/brave_wallet_ui/common/constants/blowfish.ts index 9326c881c819..e4282e511fbb 100644 --- a/components/brave_wallet_ui/common/constants/blowfish.ts +++ b/components/brave_wallet_ui/common/constants/blowfish.ts @@ -3,43 +3,34 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this file, // You can obtain one at https://mozilla.org/MPL/2.0/. +import { BraveWallet } from "../../constants/types" + export const BLOWFISH_URL_WARNING_KINDS = [ - 'BLOCKLISTED_DOMAIN_CROSS_ORIGIN', - 'COPY_CAT_DOMAIN', - 'NON_ASCII_URL', - 'SEMI_TRUSTED_BLOCKLIST_DOMAIN', + BraveWallet.BlowfishWarningKind.kBlocklistedDomainCrossOrigin, + BraveWallet.BlowfishWarningKind.kCopyCatDomain, + BraveWallet.BlowfishWarningKind.kNonAsciiUrl, + BraveWallet.BlowfishWarningKind.kSemiTrustedBlocklistDomain ] as const export const BLOWFISH_WARNING_KINDS = [ ...BLOWFISH_URL_WARNING_KINDS, - 'SUSPECTED_MALICIOUS', - 'KNOWN_MALICIOUS', - 'TRANSFERRING_ERC20_TO_OWN_CONTRACT', - 'UNLIMITED_ALLOWANCE_TO_NFTS', - 'BULK_APPROVALS_REQUEST', - 'SET_OWNER_AUTHORITY', - 'TRUSTED_BLOCKLIST_DOMAIN', - 'DANGLING_APPROVAL', - 'TRADE_FOR_NOTHING', - 'PERMIT_UNLIMITED_ALLOWANCE', - 'PERMIT_NO_EXPIRATION', - 'ETH_SIGN_TX_HASH', - 'OBFUSCATED_CODE', - 'DEVTOOLS_DISABLED', - 'WHITELISTED_DOMAIN_CROSS_ORIGIN', - 'TOO_MANY_TRANSACTIONS', - 'COMPROMISED_AUTHORITY_UPGRADE', - 'POISONED_ADDRESS', - 'APPROVAL_TO_E_O_A', + BraveWallet.BlowfishWarningKind.kSuspectedMalicious, + BraveWallet.BlowfishWarningKind.kKnownMalicious, + BraveWallet.BlowfishWarningKind.kTransferringErc20ToOwnContract, + BraveWallet.BlowfishWarningKind.kUnlimitedAllowanceToNfts, + BraveWallet.BlowfishWarningKind.kBulkApprovalsRequest, + BraveWallet.BlowfishWarningKind.kSetOwnerAuthority, + BraveWallet.BlowfishWarningKind.kTrustedBlocklistDomain, + BraveWallet.BlowfishWarningKind.kDanglingApproval, + BraveWallet.BlowfishWarningKind.kTradeForNothing, + BraveWallet.BlowfishWarningKind.kPermitUnlimitedAllowance, + BraveWallet.BlowfishWarningKind.kPermitNoExpiration, + BraveWallet.BlowfishWarningKind.kEthSignTxHash, + BraveWallet.BlowfishWarningKind.kObfuscatedCode, + BraveWallet.BlowfishWarningKind.kDevtoolsDisabled, + BraveWallet.BlowfishWarningKind.kWhitelistedDomainCrossOrigin, + BraveWallet.BlowfishWarningKind.kTooManyTransactions, + BraveWallet.BlowfishWarningKind.kCompromisedAuthorityUpgrade, + BraveWallet.BlowfishWarningKind.kPoisonedAddress, + BraveWallet.BlowfishWarningKind.kApprovalToEOA, ] as const - -/** - * Domain/Site Warnings -*/ -export type BlowfishURLWarningKind = typeof BLOWFISH_URL_WARNING_KINDS[number] - -/** - * Can be used to override specific warnings with your own custom versions. - * Our UI should defer to the supplied message if the kind isn't recognized - */ -export type BlowfishWarningKind = typeof BLOWFISH_WARNING_KINDS[number] \ No newline at end of file diff --git a/components/brave_wallet_ui/common/constants/mocks.ts b/components/brave_wallet_ui/common/constants/mocks.ts index 168d25fceb8f..0b770ebd5712 100644 --- a/components/brave_wallet_ui/common/constants/mocks.ts +++ b/components/brave_wallet_ui/common/constants/mocks.ts @@ -17,6 +17,7 @@ import { SafeERC721ApprovalForAllEvent, SafeERC721TransferEvent, SafeNativeTransferEvent, + SafeSolanaStakeChangeEvent, SerializableTransactionInfo, SpotPriceRegistry, } from '../../constants/types' @@ -655,7 +656,7 @@ export const mockSolDappSignAllTransactionsRequest: BraveWallet.SignAllTransacti export const mockBlowfishAssetPrice: BraveWallet.BlowfishPrice = { dollarValuePerToken: '100', lastUpdatedAt: new Date().toUTCString(), - source: 'Coingecko' + source: BraveWallet.BlowfishAssetPriceSource.kCoingecko } const mockTokenVerificationListNames = [ @@ -681,7 +682,7 @@ export const BlowfishEVMAssets = { price: { dollarValuePerToken: '1600.92', lastUpdatedAt: new Date().toISOString(), - source: 'Coingecko' + source: BraveWallet.BlowfishAssetPriceSource.kCoingecko }, symbol: mockEthToken.symbol, verified: true @@ -708,7 +709,7 @@ export const BlowfishEVMAssets = { 'evm%3A%3Aethereum__evm%3A%3Aethereum%3A%3Amainnet__' + '0x6b175474e89094c44da98b954eedeac495271d0f.png', price: { - source: 'Coingecko', + source: BraveWallet.BlowfishAssetPriceSource.kCoingecko, lastUpdatedAt: '1679331222', dollarValuePerToken: '0.99' } @@ -725,18 +726,18 @@ export const BlowfishEVMAssets = { '/evm__evm%3A%3Aethereum__evm%3A%3Aethereum%3A%3Amainnet__' + '0xdac17f958d2ee523a2206206994597c13d831ec7.png', price: { - source: 'Coingecko', + source: BraveWallet.BlowfishAssetPriceSource.kCoingecko, lastUpdatedAt: '1679331222', dollarValuePerToken: '0.99' } } as BraveWallet.BlowfishEVMAsset } as const -const goerliLinkTransferData = { +const goerliLinkTransferData: BraveWallet.BlowfishERC20TransferData = { contract: { // Goerli LINK address: '0x326c977e6efc84e512bb9c30f76e30c160ed06fb', - kind: 'ACCOUNT' + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, amount: { before: '28907865866843658798', @@ -747,9 +748,9 @@ const goerliLinkTransferData = { const mockedSimulationWarnings: SafeBlowfishWarning[] = [ { - kind: 'APPROVAL_TO_E_O_A', + kind: BraveWallet.BlowfishWarningKind.kApprovalToEOA, message: 'APPROVAL_TO_E_O_A', - severity: 'CRITICAL' + severity: BraveWallet.BlowfishWarningSeverity.kCritical } ] @@ -757,6 +758,7 @@ const mockedSimulationWarnings: SafeBlowfishWarning[] = [ export const mockedReceiveDaiEvent: SafeERC20TransferEvent = { humanReadableDiff: 'Receive 1530.81307 DAI', rawInfo: { + kind: BraveWallet.BlowfishEVMRawInfoKind.kErc20Transfer, data: { erc20TransferData: { amount: { @@ -765,19 +767,18 @@ export const mockedReceiveDaiEvent: SafeERC20TransferEvent = { }, contract: { address: BlowfishEVMAssets.mainnetDai.address, - kind: 'ACCOUNT' + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, asset: BlowfishEVMAssets.mainnetDai } - }, - kind: 'ERC20_TRANSFER' + } } } export const mockSendEthEvent: SafeNativeTransferEvent = { humanReadableDiff: 'Send 1 ETH', rawInfo: { - kind: 'NATIVE_ASSET_TRANSFER', + kind: BraveWallet.BlowfishEVMRawInfoKind.kNativeAssetTransfer, data: { nativeAssetTransferData: { amount: { @@ -786,7 +787,7 @@ export const mockSendEthEvent: SafeNativeTransferEvent = { }, contract: { address: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', - kind: 'ACCOUNT' + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, asset: BlowfishEVMAssets.mainnetETH } @@ -797,7 +798,7 @@ export const mockSendEthEvent: SafeNativeTransferEvent = { export const mockApproveUsdtEvent: SafeERC20ApprovalEvent = { humanReadableDiff: 'Approve to transfer up to 1000 USDT', rawInfo: { - kind: 'ERC20_APPROVAL', + kind: BraveWallet.BlowfishEVMRawInfoKind.kErc20Approval, data: { erc20ApprovalData: { amount: { @@ -807,15 +808,15 @@ export const mockApproveUsdtEvent: SafeERC20ApprovalEvent = { asset: BlowfishEVMAssets.mainnetTetherUSD, contract: { address: '0xdac17f958d2ee523a2206206994597c13d831ec7', - kind: 'ACCOUNT' + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, owner: { address: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045', - kind: 'ACCOUNT' + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, spender: { address: '0x68b3465833fb72a70ecdf485e0e4c7bd8665fc45', - kind: 'ACCOUNT' + kind: BraveWallet.BlowfishEVMAddressKind.kAccount } }, }, @@ -833,7 +834,7 @@ export const mockReceiveNftEvent: SafeERC721TransferEvent = { }, contract: { address: '0xbd3531da5cf5857e7cfaa92426877b022e612cf8', - kind: 'ACCOUNT' + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, metadata: { rawImageUrl: @@ -844,19 +845,20 @@ export const mockReceiveNftEvent: SafeERC721TransferEvent = { symbol: 'PPG', tokenId: '7238', assetPrice: { - source: 'Simplehash', + source: BraveWallet.BlowfishAssetPriceSource.kSimplehash, lastUpdatedAt: '1679331222', dollarValuePerToken: '594.99' } } }, - kind: 'ERC721_TRANSFER' + kind: BraveWallet.BlowfishEVMRawInfoKind.kErc721Transfer } } export const mockApproveBoredApeNftTransferEvent: SafeERC721ApprovalEvent = { humanReadableDiff: 'Approve to transfer BoredApeYachtClub', rawInfo: { + kind: BraveWallet.BlowfishEVMRawInfoKind.kErc721Approval, data: { erc721ApprovalData: { amount: { @@ -865,7 +867,7 @@ export const mockApproveBoredApeNftTransferEvent: SafeERC721ApprovalEvent = { }, contract: { address: '0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d', - kind: 'ACCOUNT' + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, metadata: { rawImageUrl: @@ -875,29 +877,28 @@ export const mockApproveBoredApeNftTransferEvent: SafeERC721ApprovalEvent = { name: 'BoredApeYachtClub', owner: { address: '0xed2ab4948ba6a909a7751dec4f34f303eb8c7236', - kind: 'ACCOUNT' + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, spender: { address: '0x1e0049783f008a0085193e00003d00cd54003c71', - kind: 'ACCOUNT' + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, symbol: 'BAYC', tokenId: '6603', assetPrice: { - source: 'Simplehash', + source: BraveWallet.BlowfishAssetPriceSource.kSimplehash, lastUpdatedAt: '1679331222', dollarValuePerToken: '7865.43' } } }, - kind: 'ERC721_APPROVAL' } } export const mockApproveAllBoredApeNFTsEvent: SafeERC721ApprovalForAllEvent = { humanReadableDiff: 'Approve to transfer all your BoredApeYachtClub', rawInfo: { - kind: 'ERC721_APPROVAL_FOR_ALL', + kind: BraveWallet.BlowfishEVMRawInfoKind.kErc721ApprovalForAll, data: { erc721ApprovalForAllData: { amount: { @@ -906,20 +907,20 @@ export const mockApproveAllBoredApeNFTsEvent: SafeERC721ApprovalForAllEvent = { }, contract: { address: '0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d', - kind: 'ACCOUNT' + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, name: 'BoredApeYachtClub', owner: { address: '0x38191ca1307ebf67ca1a7caf5346dbd91d882ca6', - kind: 'ACCOUNT' + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, spender: { address: '0x1e0049783f008a0085193e00003d00cd54003c71', - kind: 'ACCOUNT' + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, symbol: 'BAYC', assetPrice: { - source: 'Simplehash', + source: BraveWallet.BlowfishAssetPriceSource.kSimplehash, lastUpdatedAt: '1679331222', dollarValuePerToken: '7865.43' } @@ -937,7 +938,7 @@ export const mockApproveAllBoredApeNFTsEvent: SafeERC721ApprovalForAllEvent = { * - Send 1 ETH */ export const mockEvmSimulatedResponse: SafeBlowfishEvmResponse = { - action: 'NONE', + action: BraveWallet.BlowfishSuggestedAction.kNone, warnings: mockedSimulationWarnings, simulationResults: { error: undefined, @@ -945,7 +946,7 @@ export const mockEvmSimulatedResponse: SafeBlowfishEvmResponse = { { humanReadableDiff: 'Receive 14.4539 LINK', rawInfo: { - kind: 'ERC20_TRANSFER', + kind: BraveWallet.BlowfishEVMRawInfoKind.kErc20Transfer, data: { erc20TransferData: goerliLinkTransferData } @@ -954,7 +955,7 @@ export const mockEvmSimulatedResponse: SafeBlowfishEvmResponse = { { humanReadableDiff: 'Approve 10 LINK', rawInfo: { - kind: 'ERC20_APPROVAL', + kind: BraveWallet.BlowfishEVMRawInfoKind.kErc20Approval, data: { erc20ApprovalData: { amount: { @@ -964,15 +965,15 @@ export const mockEvmSimulatedResponse: SafeBlowfishEvmResponse = { asset: BlowfishEVMAssets.goerliLink, contract: { address: BlowfishEVMAssets.goerliLink.address, - kind: '' // todo + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, owner: { address: mockAccount.address, - kind: '' // TODO + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, spender: { address: mockAccount.address, - kind: '' // TODO + kind: BraveWallet.BlowfishEVMAddressKind.kAccount } } } @@ -983,7 +984,7 @@ export const mockEvmSimulatedResponse: SafeBlowfishEvmResponse = { mockErc721Token.name // } #${mockErc721Token.tokenId}`, rawInfo: { - kind: 'ERC721_TRANSFER', + kind: BraveWallet.BlowfishEVMRawInfoKind.kErc721Transfer, data: { erc721TransferData: { amount: { @@ -993,7 +994,7 @@ export const mockEvmSimulatedResponse: SafeBlowfishEvmResponse = { assetPrice: mockBlowfishAssetPrice, contract: { address: mockErc721Token.contractAddress, - kind: '' // TODO + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, metadata: { rawImageUrl: mockNFTMetadata[0].imageURL || '' @@ -1010,7 +1011,7 @@ export const mockEvmSimulatedResponse: SafeBlowfishEvmResponse = { mockErc721Token.symbol // } #${mockErc721Token.tokenId}`, rawInfo: { - kind: 'ERC1155_TRANSFER', + kind: BraveWallet.BlowfishEVMRawInfoKind.kErc1155Transfer, data: { erc1155TransferData: { amount: { @@ -1020,11 +1021,11 @@ export const mockEvmSimulatedResponse: SafeBlowfishEvmResponse = { assetPrice: { dollarValuePerToken: '100', // $100 lastUpdatedAt: new Date().toUTCString(), - source: 'Coingecko' + source: BraveWallet.BlowfishAssetPriceSource.kCoingecko }, contract: { address: mockErc721Token.contractAddress, - kind: '' // TODO + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, metadata: { rawImageUrl: mockNFTMetadata[0].imageURL || '' @@ -1038,7 +1039,7 @@ export const mockEvmSimulatedResponse: SafeBlowfishEvmResponse = { { humanReadableDiff: 'Send 1 ETH', rawInfo: { - kind: 'NATIVE_ASSET_TRANSFER', + kind: BraveWallet.BlowfishEVMRawInfoKind.kNativeAssetTransfer, data: { nativeAssetTransferData: { amount: { @@ -1048,7 +1049,7 @@ export const mockEvmSimulatedResponse: SafeBlowfishEvmResponse = { asset: BlowfishEVMAssets.mainnetETH, contract: { address: '', - kind: '' // TODO + kind: BraveWallet.BlowfishEVMAddressKind.kAccount } } } @@ -1059,7 +1060,7 @@ export const mockEvmSimulatedResponse: SafeBlowfishEvmResponse = { mockMoonCatNFT.name // } #${mockMoonCatNFT.tokenId}`, rawInfo: { - kind: 'ERC721_APPROVAL', + kind: BraveWallet.BlowfishEVMRawInfoKind.kErc721Approval, data: { erc721ApprovalData: { amount: { @@ -1069,20 +1070,23 @@ export const mockEvmSimulatedResponse: SafeBlowfishEvmResponse = { assetPrice: { dollarValuePerToken: '100', lastUpdatedAt: new Date().toISOString(), - source: 'Coingecko' + source: BraveWallet.BlowfishAssetPriceSource.kCoingecko }, metadata: { rawImageUrl: mockMoonCatNFT.logo }, contract: { address: '', - kind: '' // TODO + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, name: mockMoonCatNFT.name, - owner: { kind: 'ACCOUNT', address: mockAccount.address }, + owner: { + kind: BraveWallet.BlowfishEVMAddressKind.kAccount, + address: mockAccount.address + }, spender: { address: mockAccount.address, - kind: 'ACCOUNT' + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, symbol: mockMoonCatNFT.symbol, tokenId: mockMoonCatNFT.tokenId @@ -1100,7 +1104,7 @@ export const mockEvmSimulatedResponse: SafeBlowfishEvmResponse = { * - Receive 1530.81307 DAI */ export const mockSimulatedSwapETHForDAI: SafeBlowfishEvmResponse = { - action: 'NONE', + action: BraveWallet.BlowfishSuggestedAction.kNone, warnings: [], simulationResults: { error: undefined, @@ -1113,7 +1117,7 @@ export const mockSimulatedSwapETHForDAI: SafeBlowfishEvmResponse = { * - Approve to transfer up to 1000 USDT */ export const mockEvmSimulatedERC20Approval: SafeBlowfishEvmResponse = { - action: 'NONE', + action: BraveWallet.BlowfishSuggestedAction.kNone, warnings: [], simulationResults: { error: undefined, @@ -1127,7 +1131,7 @@ export const mockEvmSimulatedERC20Approval: SafeBlowfishEvmResponse = { * - Send 3.181 ETH */ export const mockSimulatedBuyNFTWithETH: SafeBlowfishEvmResponse = { - action: 'NONE', + action: BraveWallet.BlowfishSuggestedAction.kNone, warnings: [], simulationResults: { error: undefined, @@ -1136,6 +1140,7 @@ export const mockSimulatedBuyNFTWithETH: SafeBlowfishEvmResponse = { { humanReadableDiff: 'Send 3.181 ETH', rawInfo: { + kind: BraveWallet.BlowfishEVMRawInfoKind.kNativeAssetTransfer, data: { nativeAssetTransferData: { amount: { @@ -1144,12 +1149,11 @@ export const mockSimulatedBuyNFTWithETH: SafeBlowfishEvmResponse = { }, contract: { address: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', - kind: 'ACCOUNT' + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, asset: BlowfishEVMAssets.mainnetETH } }, - kind: 'NATIVE_ASSET_TRANSFER' } } ] @@ -1161,7 +1165,7 @@ export const mockSimulatedBuyNFTWithETH: SafeBlowfishEvmResponse = { * Approve to transfer BoredApeYachtClub */ export const mockSimulatedERC721Approve: SafeBlowfishEvmResponse = { - action: 'NONE', + action: BraveWallet.BlowfishSuggestedAction.kNone, warnings: [], simulationResults: { error: undefined, @@ -1174,14 +1178,14 @@ export const mockSimulatedERC721Approve: SafeBlowfishEvmResponse = { * - Approve to transfer all your BoredApeYachtClub */ export const mockERC721ApproveForAllSim: SafeBlowfishEvmResponse = { - action: 'WARN', + action: BraveWallet.BlowfishSuggestedAction.kWarn, warnings: [ { - kind: 'UNLIMITED_ALLOWANCE_TO_NFTS', + kind: BraveWallet.BlowfishWarningKind.kUnlimitedAllowanceToNfts, message: 'You are allowing this website ' + 'to withdraw funds from your account in the future', - severity: 'WARNING' + severity: BraveWallet.BlowfishWarningSeverity.kWarning } ], simulationResults: { @@ -1193,6 +1197,7 @@ export const mockERC721ApproveForAllSim: SafeBlowfishEvmResponse = { export const mockReceiveMultiStandardTokenEvent: SafeERC1155TransferEvent = { humanReadableDiff: 'Receive Corgi', rawInfo: { + kind: BraveWallet.BlowfishEVMRawInfoKind.kErc1155Transfer, data: { erc1155TransferData: { amount: { @@ -1201,7 +1206,7 @@ export const mockReceiveMultiStandardTokenEvent: SafeERC1155TransferEvent = { }, contract: { address: '0x51e613727fdd2e0b91b51c3e5427e9440a7957e4', - kind: 'ACCOUNT' + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, metadata: { rawImageUrl: @@ -1210,14 +1215,13 @@ export const mockReceiveMultiStandardTokenEvent: SafeERC1155TransferEvent = { }, tokenId: '13014975', assetPrice: { - source: 'Simplehash', + source: BraveWallet.BlowfishAssetPriceSource.kSimplehash, lastUpdatedAt: '1679331222', dollarValuePerToken: '232.43' }, name: 'Corgi #1234' } }, - kind: 'ERC1155_TRANSFER' } } @@ -1227,7 +1231,7 @@ export const mockReceiveMultiStandardTokenEvent: SafeERC1155TransferEvent = { * - Receive Corgi */ export const mockSimulatedBuyERC1155Token: SafeBlowfishEvmResponse = { - action: 'NONE', + action: BraveWallet.BlowfishSuggestedAction.kNone, warnings: [], simulationResults: { error: undefined, @@ -1235,6 +1239,7 @@ export const mockSimulatedBuyERC1155Token: SafeBlowfishEvmResponse = { { humanReadableDiff: 'Send 0.033 ETH', rawInfo: { + kind: BraveWallet.BlowfishEVMRawInfoKind.kNativeAssetTransfer, data: { nativeAssetTransferData: { amount: { @@ -1243,12 +1248,11 @@ export const mockSimulatedBuyERC1155Token: SafeBlowfishEvmResponse = { }, contract: { address: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', - kind: 'ACCOUNT' + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, asset: BlowfishEVMAssets.mainnetETH } }, - kind: 'NATIVE_ASSET_TRANSFER' } }, mockReceiveMultiStandardTokenEvent @@ -1261,14 +1265,14 @@ export const mockSimulatedBuyERC1155Token: SafeBlowfishEvmResponse = { * - Approve to transfer all your Sandbox's ASSETs */ export const mockEvmERC1155ApproveForAll: SafeBlowfishEvmResponse = { - action: 'NONE', + action: BraveWallet.BlowfishSuggestedAction.kNone, warnings: [ { - kind: 'UNLIMITED_ALLOWANCE_TO_NFTS', + kind: BraveWallet.BlowfishWarningKind.kUnlimitedAllowanceToNfts, message: 'You are allowing this website to withdraw funds ' + 'from your account in the future', - severity: 'WARNING' + severity: BraveWallet.BlowfishWarningSeverity.kWarning } ], simulationResults: { @@ -1277,7 +1281,7 @@ export const mockEvmERC1155ApproveForAll: SafeBlowfishEvmResponse = { { humanReadableDiff: `Approve to transfer all your Sandbox's ASSETs`, rawInfo: { - kind: 'ERC1155_APPROVAL_FOR_ALL', + kind: BraveWallet.BlowfishEVMRawInfoKind.kErc1155ApprovalForAll, data: { erc1155ApprovalForAllData: { amount: { @@ -1287,18 +1291,18 @@ export const mockEvmERC1155ApproveForAll: SafeBlowfishEvmResponse = { }, contract: { address: '0xa342f5d851e866e18ff98f351f2c6637f4478db5', - kind: 'ACCOUNT' + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, owner: { address: '0xed2ab4948ba6a909a7751dec4f34f303eb8c7236', - kind: 'ACCOUNT' + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, spender: { address: '0x00000000006c3852cbef3e08e8df289169ede581', - kind: 'ACCOUNT' + kind: BraveWallet.BlowfishEVMAddressKind.kAccount }, assetPrice: { - source: 'Simplehash', + source: BraveWallet.BlowfishAssetPriceSource.kSimplehash, lastUpdatedAt: '1679331222', dollarValuePerToken: '232.43' } @@ -1314,23 +1318,23 @@ export const mockEvmERC1155ApproveForAll: SafeBlowfishEvmResponse = { // Solana SVM Simulations // export const mockReceiveSolSimulation: SafeBlowfishSolanaResponse = { - action: 'BLOCK', + action: BraveWallet.BlowfishSuggestedAction.kBlock, simulationResults: { error: undefined, - isRecentBlockhashExpired: false, + // isRecentBlockhashExpired: false, expectedStateChanges: [ { humanReadableDiff: 'Receive 0.05657 SOL', - suggestedColor: 'CREDIT', + suggestedColor: BraveWallet.BlowfishSuggestedColor.kCredit, rawInfo: { - kind: 'SOL_TRANSFER', + kind: BraveWallet.BlowfishSolanaRawInfoKind.kSolTransfer, data: { solTransferData: { decimals: 9, symbol: 'SOL', diff: { digits: BigInt(500000), - sign: 'PLUS' + sign: BraveWallet.BlowfishDiffSign.kPlus }, name: 'Solana Native Token', } @@ -1341,44 +1345,43 @@ export const mockReceiveSolSimulation: SafeBlowfishSolanaResponse = { }, warnings: [ { - kind: 'APPROVAL_TO_E_O_A', + kind: BraveWallet.BlowfishWarningKind.kApprovalToEOA, message: '', - severity: 'CRITICAL' + severity: BraveWallet.BlowfishWarningSeverity.kCritical } ] } +export const mockSolStakingChangeEvent: SafeSolanaStakeChangeEvent = { + humanReadableDiff: 'Re-stake 0.05657 SOL', + suggestedColor: BraveWallet.BlowfishSuggestedColor.kCredit, + rawInfo: { + kind: BraveWallet.BlowfishSolanaRawInfoKind.kSolStakeAuthorityChange, + data: { + solStakeAuthorityChangeData: { + currAuthorities: { + staker: mockSolanaAccount.address, + withdrawer: mockSolanaAccount.address + }, + futureAuthorities: { + staker: mockSplNft.contractAddress, + withdrawer: mockSplNft.contractAddress + }, + decimals: mockSolanaMainnetNetwork.decimals, + name: mockSolanaMainnetNetwork.symbolName, + solStaked: BigInt(5657), + stakeAccount: mockSolanaAccountInfo.address, + symbol: mockSolanaMainnetNetwork.symbol + } + } + } +} + export const mockSolStakingChangeSimulation: SafeBlowfishSolanaResponse = { - action: 'BLOCK', + action: BraveWallet.BlowfishSuggestedAction.kBlock, simulationResults: { error: undefined, - isRecentBlockhashExpired: false, - expectedStateChanges: [ - { - humanReadableDiff: 'Re-stake 0.05657 SOL', - suggestedColor: 'CREDIT', - rawInfo: { - kind: 'SOL_STAKE_AUTHORITY_CHANGE', - data: { - solStakeAuthorityChangeData: { - currAuthorities: { - staker: mockSolanaAccount.address, - withdrawer: mockSolanaAccount.address - }, - futureAuthorities: { - staker: mockSplNft.contractAddress, - withdrawer: mockSplNft.contractAddress - }, - decimals: mockSolanaMainnetNetwork.decimals, - name: mockSolanaMainnetNetwork.symbolName, - solStaked: BigInt(5657), - stakeAccount: mockSolanaAccountInfo.address, - symbol: mockSolanaMainnetNetwork.symbol - } - } - } - } - ] + expectedStateChanges: [mockSolStakingChangeEvent] }, warnings: [] } diff --git a/components/brave_wallet_ui/constants/types.ts b/components/brave_wallet_ui/constants/types.ts index 1c48f141a2bb..ed7ada1d4215 100644 --- a/components/brave_wallet_ui/constants/types.ts +++ b/components/brave_wallet_ui/constants/types.ts @@ -6,7 +6,6 @@ import { TimeDelta } from 'gen/mojo/public/mojom/base/time.mojom.m.js' import * as BraveWallet from 'gen/brave/components/brave_wallet/common/brave_wallet.mojom.m.js' import { HardwareWalletResponseCodeType } from '../common/hardware/types' -import { BlowfishWarningKind } from '../common/constants/blowfish' // Re-export BraveWallet for use in other modules, to avoid hard-coding the // path of generated mojom files. @@ -1109,17 +1108,9 @@ export type BlowfishErrorKind = | 'TOO_MANY_TRANSACTIONS' | 'BAD_REQUEST' -/** - * warning severity level. - * UI should display: - * - a yellow message if "WARNING" - * - a red message if "CRITICAL". - */ -export type BlowfishWarningSeverity = 'CRITICAL' | 'WARNING' - export type SafeBlowfishWarning = { - severity: BlowfishWarningSeverity - kind: BlowfishWarningKind + severity: BraveWallet.BlowfishWarningSeverity + kind: BraveWallet.BlowfishWarningKind /** * human-readable message to present to the end-user */ @@ -1132,21 +1123,21 @@ export type SafeBlowfishWarning = { * of any NFT from a given collection (eg. Opensea collection offers) */ type EvmTransferKind = - | 'ANY_NFT_FROM_COLLECTION_TRANSFER' - | 'ERC20_TRANSFER' - | 'ERC721_TRANSFER' - | 'ERC1155_TRANSFER' - | 'NATIVE_ASSET_TRANSFER' + | typeof BraveWallet.BlowfishEVMRawInfoKind.kAnyNftFromCollectionTransfer + | typeof BraveWallet.BlowfishEVMRawInfoKind.kErc20Transfer + | typeof BraveWallet.BlowfishEVMRawInfoKind.kErc721Transfer + | typeof BraveWallet.BlowfishEVMRawInfoKind.kErc1155Transfer + | typeof BraveWallet.BlowfishEVMRawInfoKind.kNativeAssetTransfer type EvmApprovalKind = - | 'ERC20_APPROVAL' - | 'ERC721_APPROVAL' - | 'ERC721_APPROVAL_FOR_ALL' - | 'ERC1155_APPROVAL_FOR_ALL' + | typeof BraveWallet.BlowfishEVMRawInfoKind.kErc20Approval + | typeof BraveWallet.BlowfishEVMRawInfoKind.kErc721Approval + | typeof BraveWallet.BlowfishEVMRawInfoKind.kErc721ApprovalForAll + | typeof BraveWallet.BlowfishEVMRawInfoKind.kErc1155ApprovalForAll type SolanaTransferKind = - | 'SOL_TRANSFER' - | 'SPL_TRANSFER' + | typeof BraveWallet.BlowfishSolanaRawInfoKind.kSolTransfer + | typeof BraveWallet.BlowfishSolanaRawInfoKind.kSplTransfer export type EvmStateChangeKind = | EvmTransferKind @@ -1154,16 +1145,9 @@ export type EvmStateChangeKind = export type SolanaStateChangeKind = | SolanaTransferKind - | 'SPL_APPROVAL' - | 'SOL_STAKE_AUTHORITY_CHANGE' - | 'USER_ACCOUNT_OWNER_CHANGE' - -export type MetaplexTokenStandard = - | 'non_fungible' - | 'fungible_asset' - | 'fungible' - | 'non_fungible_edition' - | 'unknown' + | typeof BraveWallet.BlowfishSolanaRawInfoKind.kSplApproval + | typeof BraveWallet.BlowfishSolanaRawInfoKind.kSolStakeAuthorityChange + | typeof BraveWallet.BlowfishSolanaRawInfoKind.kUserAccountOwnerChange export type PriceSource = | 'Simplehash' @@ -1172,51 +1156,54 @@ export type PriceSource = export type BlowfishStateChangeKind = EvmStateChangeKind | SolanaStateChangeKind -interface SafeBlowfishError { - kind: string +interface SafeBlowfishEVMError { + kind: BraveWallet.BlowfishEVMErrorKind + humanReadableError: string +} + +interface SafeBlowfishSolanaError { + kind: BraveWallet.BlowfishSolanaErrorKind humanReadableError: string } -/* Suggested text color when presenting the diff to end-users */ -export type BlowfishSuggestedColor = 'CREDIT' | 'DEBIT' +export type SafeEVMStateChange< + UNION_KEY extends // + keyof BraveWallet.BlowfishEVMStateChangeRawInfoDataUnion // + = keyof BraveWallet.BlowfishEVMStateChangeRawInfoDataUnion +> = { + humanReadableDiff: string + rawInfo: SafeEvmRawInfo +} export type SafeERC20ApprovalEvent = SafeEVMStateChange< - 'ERC20_APPROVAL', 'erc20ApprovalData' > export type SafeERC721ApprovalEvent = SafeEVMStateChange< - 'ERC721_APPROVAL', 'erc721ApprovalData' > export type SafeERC721ApprovalForAllEvent = SafeEVMStateChange< - 'ERC721_APPROVAL_FOR_ALL', 'erc721ApprovalForAllData' > export type SafeERC1155ApprovalForAllEvent = SafeEVMStateChange< - 'ERC1155_APPROVAL_FOR_ALL', 'erc1155ApprovalForAllData' > export type SafeERC20TransferEvent = SafeEVMStateChange< - 'ERC20_TRANSFER', 'erc20TransferData' > export type SafeERC721TransferEvent = SafeEVMStateChange< - 'ERC721_TRANSFER', 'erc721TransferData' > export type SafeERC1155TransferEvent = SafeEVMStateChange< - 'ERC1155_TRANSFER', 'erc1155TransferData' > export type SafeNativeTransferEvent = SafeEVMStateChange< - 'NATIVE_ASSET_TRANSFER', 'nativeAssetTransferData' > @@ -1234,28 +1221,33 @@ export type SafeEvmApprovalEvent = export type SafeEvmEvent = SafeEvmApprovalEvent | SafeEvmTransferEvent +export type SafeSolanaStateChange< + UNION_KEY extends // + keyof BraveWallet.BlowfishSolanaStateChangeRawInfoDataUnion // + = keyof BraveWallet.BlowfishSolanaStateChangeRawInfoDataUnion +> = { + humanReadableDiff: string + rawInfo: SafeSolanaRawInfo + suggestedColor: BraveWallet.BlowfishSuggestedColor +} + export type SafeSplApprovalEvent = SafeSolanaStateChange< - 'SPL_APPROVAL', 'splApprovalData' > export type SafeSolanaStakeChangeEvent = SafeSolanaStateChange< - 'SOL_STAKE_AUTHORITY_CHANGE', 'solStakeAuthorityChangeData' > export type SafeSolanaAccountOwnerChangeEvent = SafeSolanaStateChange< - 'USER_ACCOUNT_OWNER_CHANGE', 'solStakeAuthorityChangeData' // TODO: not implemented in core > export type SafeSolTransferEvent = SafeSolanaStateChange< - 'SOL_TRANSFER', 'solTransferData' > export type SafeSplTransferEvent = SafeSolanaStateChange< - 'SPL_TRANSFER', 'splTransferData' > @@ -1267,65 +1259,45 @@ type SafeSolanaEvent = | SafeSolanaAccountOwnerChangeEvent export interface SafeEVMSimulationResults { - error: SafeBlowfishError | undefined + error: SafeBlowfishEVMError | undefined expectedStateChanges: SafeEvmEvent[] }; export interface SafeSolanaSimulationResults { - isRecentBlockhashExpired: boolean - error: SafeBlowfishError | undefined + error: SafeBlowfishSolanaError | undefined expectedStateChanges: SafeSolanaEvent[] }; -type ChangesDataUnionForKind = - KIND extends EvmStateChangeKind - ? Partial - : Partial - -type SafeRawInfo< - KIND extends BlowfishStateChangeKind, - DATA_UNION extends ChangesDataUnionForKind +type SafeEvmRawInfo< + DATA_UNION_KEY // + extends keyof BraveWallet.BlowfishEVMStateChangeRawInfoDataUnion > = { - kind: KIND + kind: BraveWallet.BlowfishEVMRawInfoKind data: Record< - keyof DATA_UNION, - Exclude + DATA_UNION_KEY, + Exclude< + BraveWallet.BlowfishEVMStateChangeRawInfoDataUnion[DATA_UNION_KEY], + undefined + > > } -export type SafeEVMStateChange< - KIND extends EvmStateChangeKind = EvmStateChangeKind, - UNION_KEY extends // - keyof BraveWallet.BlowfishEVMStateChangeRawInfoDataUnion // - = keyof BraveWallet.BlowfishEVMStateChangeRawInfoDataUnion +type SafeSolanaRawInfo< + DATA_UNION_KEY // + extends keyof BraveWallet.BlowfishSolanaStateChangeRawInfoDataUnion > = { - humanReadableDiff: string - rawInfo: SafeRawInfo< - KIND, - Pick - > & { data: Partial } -} - -export type SafeSolanaStateChange< - KIND extends SolanaStateChangeKind = SolanaStateChangeKind, - UNION_KEY extends // - keyof BraveWallet.BlowfishSolanaStateChangeRawInfoDataUnion // - = keyof BraveWallet.BlowfishSolanaStateChangeRawInfoDataUnion -> = { - humanReadableDiff: string - rawInfo: SafeRawInfo< - KIND, - Pick - > & { data: Partial } - suggestedColor: BlowfishSuggestedColor + kind: BraveWallet.BlowfishSolanaRawInfoKind + data: Record< + DATA_UNION_KEY, + Exclude< + BraveWallet.BlowfishSolanaStateChangeRawInfoDataUnion[DATA_UNION_KEY], + undefined + > + > } -export type BlowfishSimulationResponse = - | BraveWallet.SolanaSimulationResponse - | BraveWallet.EVMSimulationResponse - -export type SafeBlowfishResponseBase = { - action: BlowfishWarningActionKind +type SafeBlowfishResponseBase = { + action: BraveWallet.BlowfishSuggestedAction warnings: SafeBlowfishWarning[] } diff --git a/components/brave_wallet_ui/utils/tx-simulation-utils.ts b/components/brave_wallet_ui/utils/tx-simulation-utils.ts index 5216715f3edc..e1b3b0a9a91c 100644 --- a/components/brave_wallet_ui/utils/tx-simulation-utils.ts +++ b/components/brave_wallet_ui/utils/tx-simulation-utils.ts @@ -4,130 +4,48 @@ // You can obtain one at https://mozilla.org/MPL/2.0/. import { BraveWallet } from '../constants/types' -import Amount from './amount' +import { BLOWFISH_URL_WARNING_KINDS } from '../common/constants/blowfish' -interface EVMStateChanges { - erc20Approvals: BraveWallet.BlowfishERC20ApprovalData[] - erc721Approvals: BraveWallet.BlowfishERC721ApprovalData[] - erc721ApprovalsForAll: BraveWallet.BlowfishERC721ApprovalForAllData[] - erc1155ApprovalsForAll: BraveWallet.BlowfishERC1155ApprovalForAllData[] - - inboundErc1155Transfers: BraveWallet.BlowfishERC1155TransferData[] - inboundErc20Transfers: BraveWallet.BlowfishERC20TransferData[] - inboundErc721Transfers: BraveWallet.BlowfishERC721TransferData[] - inboundNativeAssetTransfers: BraveWallet.BlowfishNativeAssetTransferData[] - - outboundErc1155Transfers: BraveWallet.BlowfishERC1155TransferData[] - outboundErc20Transfers: BraveWallet.BlowfishERC20TransferData[] - outboundErc721Transfers: BraveWallet.BlowfishERC721TransferData[] - outboundNativeAssetTransfers: BraveWallet.BlowfishNativeAssetTransferData[] +interface GroupedEVMStateChanges { + evmApprovals: BraveWallet.BlowfishEVMStateChange[] + evmTransfers: BraveWallet.BlowfishEVMStateChange[] } -interface SVMStateChanges { - solStakeAuthorityChanges: BraveWallet.BlowfishSOLStakeAuthorityChangeData[] - splApprovals: BraveWallet.BlowfishSPLApprovalData[] - inboundNativeAssetTransfers: BraveWallet.BlowfishSOLTransferData[] - outboundNativeAssetTransfers: BraveWallet.BlowfishSOLTransferData[] - inboundSplTransfers: BraveWallet.BlowfishSPLTransferData[] - outboundSplTransfers: BraveWallet.BlowfishSPLTransferData[] +interface GroupedSVMStateChanges { + solStakeAuthorityChanges: BraveWallet.BlowfishSolanaStateChange[] + splApprovals: BraveWallet.BlowfishSolanaStateChange[] + svmTransfers: BraveWallet.BlowfishSolanaStateChange[] } -type DiffSign = 'PLUS' | 'MINUS' - -const isInboundEVMTransfer = (transferData: { - amount: BraveWallet.BlowfishEVMAmount -}) => { - const { amount } = transferData - if (new Amount(amount.after).gt(amount.before)) { - return true - } - - // outbound - return false -} - -const isInboundSVMTransfer = (transferData: { - diff: BraveWallet.BlowfishSolanaDiff -}) => { - const { diff } = transferData - - return diff.sign as DiffSign === 'PLUS' -} - -export const decodeSimulatedEVMStateChanges = ( +export const groupSimulatedEVMStateChanges = ( evmStateChanges: BraveWallet.BlowfishEVMStateChange[] -): EVMStateChanges => { - const changes: EVMStateChanges = { - erc1155ApprovalsForAll: [], - erc20Approvals: [], - erc721Approvals: [], - erc721ApprovalsForAll: [], - inboundErc1155Transfers: [], - inboundErc20Transfers: [], - inboundErc721Transfers: [], - inboundNativeAssetTransfers: [], - outboundErc1155Transfers: [], - outboundErc20Transfers: [], - outboundErc721Transfers: [], - outboundNativeAssetTransfers: [] +): GroupedEVMStateChanges => { + const changes: GroupedEVMStateChanges = { + evmApprovals: [], + evmTransfers: [] } - for (const { rawInfo } of evmStateChanges) { - const { data } = rawInfo - - // approvals - if (data.erc20ApprovalData) { - changes.erc20Approvals.push(data.erc20ApprovalData) - } - - if (data.erc721ApprovalData) { - changes.erc721Approvals.push(data.erc721ApprovalData) - } - - // approvals for all - if (data.erc721ApprovalForAllData) { - changes.erc721ApprovalsForAll.push(data.erc721ApprovalForAllData) - } - - if (data.erc1155ApprovalForAllData) { - changes.erc1155ApprovalsForAll.push(data.erc1155ApprovalForAllData) + for (const stateChange of evmStateChanges) { + const { data } = stateChange.rawInfo + + // approvals & approvals for all + if ( + data.erc20ApprovalData || + data.erc721ApprovalData || + data.erc721ApprovalForAllData || + data.erc1155ApprovalForAllData + ) { + changes.evmApprovals.push(stateChange) } // transfers - if (data.erc20TransferData) { - if (isInboundEVMTransfer(data.erc20TransferData)) { - changes.inboundErc20Transfers.push(data.erc20TransferData) - } - - // outbound - changes.outboundErc20Transfers.push(data.erc20TransferData) - } - - if (data.erc721TransferData) { - if (data.erc721TransferData) { - changes.inboundErc721Transfers.push(data.erc721TransferData) - } - - // outbound - changes.outboundErc721Transfers.push(data.erc721TransferData) - } - - if (data.erc1155TransferData) { - if (isInboundEVMTransfer(data.erc1155TransferData)) { - changes.inboundErc1155Transfers.push(data.erc1155TransferData) - } - - // outbound - changes.outboundErc1155Transfers.push(data.erc1155TransferData) - } - - if (data.nativeAssetTransferData) { - if (isInboundEVMTransfer(data.nativeAssetTransferData)) { - changes.inboundNativeAssetTransfers.push(data.nativeAssetTransferData) - } - - // outbound - changes.outboundNativeAssetTransfers.push(data.nativeAssetTransferData) + if ( + data.erc20TransferData || + data.erc721TransferData || + data.erc1155TransferData || + data.nativeAssetTransferData + ) { + changes.evmTransfers.push(stateChange) } } @@ -136,45 +54,35 @@ export const decodeSimulatedEVMStateChanges = ( export const decodeSimulatedSVMStateChanges = ( stateChanges: BraveWallet.BlowfishSolanaStateChange[] -): SVMStateChanges => { - - const changes: SVMStateChanges = { +): GroupedSVMStateChanges => { + const changes: GroupedSVMStateChanges = { solStakeAuthorityChanges: [], splApprovals: [], - inboundNativeAssetTransfers: [], - inboundSplTransfers: [], - outboundNativeAssetTransfers: [], - outboundSplTransfers: [] + svmTransfers: [], } - for (const { rawInfo } of stateChanges) { - const { data } = rawInfo + for (const stateChange of stateChanges) { + const { data } = stateChange.rawInfo // staking auth changes if (data.solStakeAuthorityChangeData) { - changes.solStakeAuthorityChanges.push(data.solStakeAuthorityChangeData) + changes.solStakeAuthorityChanges.push(stateChange) } // approvals if (data.splApprovalData) { - changes.splApprovals.push(data.splApprovalData) + changes.splApprovals.push(stateChange) } // transfers - if (data.solTransferData) { - if (isInboundSVMTransfer(data.solTransferData)) { - changes.inboundNativeAssetTransfers.push(data.solTransferData) - } - changes.outboundNativeAssetTransfers.push(data.solTransferData) - } - - if (data.splTransferData) { - if (isInboundSVMTransfer(data.splTransferData)) { - changes.inboundSplTransfers.push(data.splTransferData) - } - changes.outboundSplTransfers.push(data.splTransferData) + if (data.solTransferData || data.splTransferData) { + changes.svmTransfers.push(stateChange) } } return changes } + +export const isUrlWarning = (warningKind: BraveWallet.BlowfishWarningKind) => { + return BLOWFISH_URL_WARNING_KINDS.includes(warningKind) +}