From 20b9c3502a15b6cb8926c93c4d611a0b09e1130e Mon Sep 17 00:00:00 2001 From: Cepera Date: Fri, 18 Feb 2022 07:01:24 +0300 Subject: [PATCH] Add signing eip712 for hardware accounts (#12265) (cherry picked from commit e8a688c6c7e41592c74d13fa64d843eb51324524) --- .../brave_wallet_provider_impl_unittest.cc | 73 +- .../brave_wallet_service_unittest.cc | 16 +- .../browser/brave_wallet_constants.h | 5 +- .../browser/brave_wallet_provider_impl.cc | 55 +- .../browser/brave_wallet_provider_impl.h | 7 +- .../brave_wallet/common/brave_wallet.mojom | 8 +- .../brave_wallet/common/eth_request_helper.cc | 20 +- .../brave_wallet/common/eth_request_helper.h | 5 +- .../common/eth_request_helper_unittest.cc | 18 +- .../common/eth_sign_typed_data_helper.cc | 35 +- .../common/eth_sign_typed_data_helper.h | 8 +- .../eth_sign_typed_data_helper_unittest.cc | 11 +- .../renderer/brave_wallet_js_handler.cc | 16 +- .../brave_wallet_ui/common/async/hardware.ts | 16 +- .../common/hardware/interfaces.ts | 2 + .../eth_ledger_bridge_keyring.test.ts | 40 +- .../ledgerjs/eth_ledger_bridge_keyring.ts | 20 +- .../common/hardware/trezor/trezor-messages.ts | 18 +- .../trezor/trezor_bridge_keyring.test.ts | 34 + .../hardware/trezor/trezor_bridge_keyring.ts | 36 +- .../panel/async/wallet_panel_async_handler.ts | 2 +- .../panel/reducers/panel_reducer.ts | 5 +- components/brave_wallet_ui/trezor/trezor.ts | 12 +- components/resources/wallet_strings.grdp | 3 + package-lock.json | 680 ++---------------- package.json | 4 +- 26 files changed, 419 insertions(+), 730 deletions(-) diff --git a/browser/brave_wallet/brave_wallet_provider_impl_unittest.cc b/browser/brave_wallet/brave_wallet_provider_impl_unittest.cc index 1bf8191eaccc..80aed6a65ef4 100644 --- a/browser/brave_wallet/brave_wallet_provider_impl_unittest.cc +++ b/browser/brave_wallet/brave_wallet_provider_impl_unittest.cc @@ -81,6 +81,12 @@ void ValidateErrorCode(BraveWalletProviderImpl* provider, ASSERT_TRUE(callback_is_called); } +std::vector DecodeHexHash(const std::string& hash_hex) { + std::vector hash; + base::HexStringToBytes(hash_hex, &hash); + return hash; +} + } // namespace class TestEventsListener : public brave_wallet::mojom::EventsListener { @@ -425,7 +431,8 @@ class BraveWalletProviderImplUnitTest : public testing::Test { void SignTypedMessage(absl::optional user_approved, const std::string& address, const std::string& message, - const std::string& message_to_sign, + const std::vector& domain_hash, + const std::vector& primary_hash, base::Value&& domain, std::string* signature_out, mojom::ProviderError* error_out, @@ -435,7 +442,7 @@ class BraveWalletProviderImplUnitTest : public testing::Test { base::RunLoop run_loop; provider()->SignTypedMessage( - address, message, message_to_sign, std::move(domain), + address, message, domain_hash, primary_hash, std::move(domain), base::BindLambdaForTesting([&](const std::string& signature, mojom::ProviderError error, const std::string& error_message) { @@ -1197,22 +1204,25 @@ TEST_F(BraveWalletProviderImplUnitTest, SignTypedMessage) { EXPECT_EQ(json_rpc_service()->GetChainId(), "0x1"); CreateWallet(); AddAccount(); - const std::string valid_message_to_sign = - "be609aee343fb3c4b28e1df9e632fca64fcfaede20f02e86244efddf30957bd2"; std::string signature; mojom::ProviderError error; std::string error_message; base::Value domain(base::Value::Type::DICTIONARY); + std::vector domain_hash = DecodeHexHash( + "f2cee375fa42b42143804025fc449deafd50cc031ca257e0b194a650a912090f"); + std::vector primary_hash = DecodeHexHash( + "c52c0ee5d84264471806290a3f2c4cecfc5490626bf912d01f240d7a274b371e"); domain.SetIntKey("chainId", 1); - SignTypedMessage(absl::nullopt, "1234", "{...}", valid_message_to_sign, + SignTypedMessage(absl::nullopt, "1234", "{...}", domain_hash, primary_hash, domain.Clone(), &signature, &error, &error_message); EXPECT_TRUE(signature.empty()); EXPECT_EQ(error, mojom::ProviderError::kInvalidParams); EXPECT_EQ(error_message, l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS)); - SignTypedMessage(absl::nullopt, "0x12345678", "{...}", valid_message_to_sign, - domain.Clone(), &signature, &error, &error_message); + SignTypedMessage(absl::nullopt, "0x12345678", "{...}", domain_hash, + primary_hash, domain.Clone(), &signature, &error, + &error_message); EXPECT_TRUE(signature.empty()); EXPECT_EQ(error, mojom::ProviderError::kInvalidParams); EXPECT_EQ(error_message, @@ -1220,24 +1230,24 @@ TEST_F(BraveWalletProviderImplUnitTest, SignTypedMessage) { const std::string address = "0x1234567890123456789012345678901234567890"; // domain not dict - SignTypedMessage(absl::nullopt, address, "{...}", valid_message_to_sign, + SignTypedMessage(absl::nullopt, address, "{...}", domain_hash, primary_hash, base::Value("not dict"), &signature, &error, &error_message); EXPECT_TRUE(signature.empty()); EXPECT_EQ(error, mojom::ProviderError::kInvalidParams); EXPECT_EQ(error_message, l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS)); - // not valid hex - SignTypedMessage(absl::nullopt, address, "{...}", "brave", domain.Clone(), - &signature, &error, &error_message); + // not valid domain hash + SignTypedMessage(absl::nullopt, address, "{...}", {}, primary_hash, + domain.Clone(), &signature, &error, &error_message); EXPECT_TRUE(signature.empty()); EXPECT_EQ(error, mojom::ProviderError::kInvalidParams); EXPECT_EQ(error_message, l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS)); - // not valid eip712 hash - SignTypedMessage(absl::nullopt, address, "{...}", "deadbeef", domain.Clone(), - &signature, &error, &error_message); + // not valid primary hash + SignTypedMessage(absl::nullopt, address, "{...}", domain_hash, {}, + domain.Clone(), &signature, &error, &error_message); EXPECT_TRUE(signature.empty()); EXPECT_EQ(error, mojom::ProviderError::kInvalidParams); EXPECT_EQ(error_message, @@ -1246,7 +1256,7 @@ TEST_F(BraveWalletProviderImplUnitTest, SignTypedMessage) { domain.SetIntKey("chainId", 4); std::string chain_id = "0x4"; // not active network - SignTypedMessage(absl::nullopt, address, "{...}", valid_message_to_sign, + SignTypedMessage(absl::nullopt, address, "{...}", domain_hash, primary_hash, domain.Clone(), &signature, &error, &error_message); EXPECT_TRUE(signature.empty()); EXPECT_EQ(error, mojom::ProviderError::kInternalError); @@ -1256,7 +1266,7 @@ TEST_F(BraveWalletProviderImplUnitTest, SignTypedMessage) { base::ASCIIToUTF16(chain_id))); domain.SetIntKey("chainId", 1); - SignTypedMessage(absl::nullopt, address, "{...}", valid_message_to_sign, + SignTypedMessage(absl::nullopt, address, "{...}", domain_hash, primary_hash, domain.Clone(), &signature, &error, &error_message); EXPECT_TRUE(signature.empty()); EXPECT_EQ(error, mojom::ProviderError::kUnauthorized); @@ -1267,8 +1277,9 @@ TEST_F(BraveWalletProviderImplUnitTest, SignTypedMessage) { // No permission const std::vector addresses = GetAddresses(); ASSERT_FALSE(address.empty()); - SignTypedMessage(absl::nullopt, addresses[0], "{...}", valid_message_to_sign, - domain.Clone(), &signature, &error, &error_message); + SignTypedMessage(absl::nullopt, addresses[0], "{...}", domain_hash, + primary_hash, domain.Clone(), &signature, &error, + &error_message); EXPECT_TRUE(signature.empty()); EXPECT_EQ(error, mojom::ProviderError::kUnauthorized); EXPECT_EQ(error_message, @@ -1277,7 +1288,7 @@ TEST_F(BraveWalletProviderImplUnitTest, SignTypedMessage) { GURL url("https://brave.com"); Navigate(url); AddEthereumPermission(url); - SignTypedMessage(true, addresses[0], "{...}", valid_message_to_sign, + SignTypedMessage(true, addresses[0], "{...}", domain_hash, primary_hash, domain.Clone(), &signature, &error, &error_message); EXPECT_FALSE(signature.empty()); @@ -1285,19 +1296,35 @@ TEST_F(BraveWalletProviderImplUnitTest, SignTypedMessage) { EXPECT_TRUE(error_message.empty()); // User reject request - SignTypedMessage(false, addresses[0], "{...}", valid_message_to_sign, + SignTypedMessage(false, addresses[0], "{...}", domain_hash, primary_hash, domain.Clone(), &signature, &error, &error_message); EXPECT_TRUE(signature.empty()); EXPECT_EQ(error, mojom::ProviderError::kUserRejectedRequest); EXPECT_EQ(error_message, l10n_util::GetStringUTF8(IDS_WALLET_USER_REJECTED_REQUEST)); - + // not valid eip712 domain hash + SignTypedMessage(absl::nullopt, address, "{...}", DecodeHexHash("brave"), + primary_hash, domain.Clone(), &signature, &error, + &error_message); + EXPECT_TRUE(signature.empty()); + EXPECT_EQ(error, mojom::ProviderError::kInvalidParams); + EXPECT_EQ(error_message, + l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS)); + // not valid eip712 primary hash + SignTypedMessage(absl::nullopt, address, "{...}", domain_hash, + DecodeHexHash("primary"), domain.Clone(), &signature, &error, + &error_message); + EXPECT_TRUE(signature.empty()); + EXPECT_EQ(error, mojom::ProviderError::kInvalidParams); + EXPECT_EQ(error_message, + l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS)); keyring_service()->Lock(); // nullopt for the first param here because we don't AddSignMessageRequest // whent here are no accounts returned. - SignTypedMessage(absl::nullopt, addresses[0], "{...}", valid_message_to_sign, - domain.Clone(), &signature, &error, &error_message); + SignTypedMessage(absl::nullopt, addresses[0], "{...}", domain_hash, + primary_hash, domain.Clone(), &signature, &error, + &error_message); EXPECT_TRUE(signature.empty()); EXPECT_EQ(error, mojom::ProviderError::kUnauthorized); EXPECT_EQ(error_message, diff --git a/browser/brave_wallet/brave_wallet_service_unittest.cc b/browser/brave_wallet/brave_wallet_service_unittest.cc index 7986a3f386a3..0e5f3c637962 100644 --- a/browser/brave_wallet/brave_wallet_service_unittest.cc +++ b/browser/brave_wallet/brave_wallet_service_unittest.cc @@ -4,6 +4,7 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "brave/components/brave_wallet/browser/brave_wallet_service.h" +#include #include "base/memory/raw_ptr.h" #include "base/test/bind.h" @@ -1315,7 +1316,8 @@ TEST_F(BraveWalletServiceUnitTest, SignMessageHardware) { std::string address = "0xbe862ad9abfe6f22bcb087716c7d89a26051f74c"; std::string message = "0xAB"; auto request1 = mojom::SignMessageRequest::New( - 1, address, std::string(message.begin(), message.end())); + 1, address, std::string(message.begin(), message.end()), false, + absl::nullopt, absl::nullopt); bool callback_is_called = false; service_->AddSignMessageRequest( std::move(request1), base::BindLambdaForTesting( @@ -1337,7 +1339,8 @@ TEST_F(BraveWalletServiceUnitTest, SignMessageHardware) { callback_is_called = false; std::string expected_error = "error"; auto request2 = mojom::SignMessageRequest::New( - 2, address, std::string(message.begin(), message.end())); + 2, address, std::string(message.begin(), message.end()), false, + absl::nullopt, absl::nullopt); service_->AddSignMessageRequest( std::move(request2), base::BindLambdaForTesting( [&](bool approved, const std::string& signature, @@ -1359,7 +1362,8 @@ TEST_F(BraveWalletServiceUnitTest, SignMessage) { std::string address = "0xbe862ad9abfe6f22bcb087716c7d89a26051f74c"; std::string message = "0xAB"; auto request1 = mojom::SignMessageRequest::New( - 1, address, std::string(message.begin(), message.end())); + 1, address, std::string(message.begin(), message.end()), false, + absl::nullopt, absl::nullopt); bool callback_is_called = false; service_->AddSignMessageRequest( std::move(request1), base::BindLambdaForTesting( @@ -1377,7 +1381,8 @@ TEST_F(BraveWalletServiceUnitTest, SignMessage) { callback_is_called = false; std::string expected_error = "error"; auto request2 = mojom::SignMessageRequest::New( - 2, address, std::string(message.begin(), message.end())); + 2, address, std::string(message.begin(), message.end()), false, + absl::nullopt, absl::nullopt); service_->AddSignMessageRequest( std::move(request2), base::BindLambdaForTesting( [&](bool approved, const std::string& signature, @@ -1569,7 +1574,8 @@ TEST_F(BraveWalletServiceUnitTest, Reset) { std::string address = "0xbe862ad9abfe6f22bcb087716c7d89a26051f74c"; std::string message = "0xAB"; auto request1 = mojom::SignMessageRequest::New( - 1, address, std::string(message.begin(), message.end())); + 1, address, std::string(message.begin(), message.end()), false, + absl::nullopt, absl::nullopt); service_->AddSignMessageRequest( std::move(request1), base::BindLambdaForTesting( diff --git a/components/brave_wallet/browser/brave_wallet_constants.h b/components/brave_wallet/browser/brave_wallet_constants.h index 07098f4ee3e2..46305ec71fd0 100644 --- a/components/brave_wallet/browser/brave_wallet_constants.h +++ b/components/brave_wallet/browser/brave_wallet_constants.h @@ -588,7 +588,10 @@ constexpr webui::LocalizedString kLocalizedStrings[] = { {"braveWalletNFTDetailBlockchain", IDS_BRAVE_WALLET_NFT_DETAIL_BLOCKCHAIN}, {"braveWalletNFTDetailTokenStandard", IDS_BRAVE_WALLET_NFT_DETAIL_TOKEN_STANDARD}, - {"braveWalletNFTDetailTokenID", IDS_BRAVE_WALLET_NFT_DETAIL_TOKEN_ID}}; + {"braveWalletNFTDetailTokenID", IDS_BRAVE_WALLET_NFT_DETAIL_TOKEN_ID}, + {"braveWalletTrezorSignTypedDataError", + IDS_BRAVE_WALLET_TREZOR_SIGN_TYPED_DATA_ERROR}, +}; const char kRopstenSwapBaseAPIURL[] = "https://ropsten.api.0x.org/"; const char kRopstenBuyTokenPercentageFee[] = "0.00875"; diff --git a/components/brave_wallet/browser/brave_wallet_provider_impl.cc b/components/brave_wallet/browser/brave_wallet_provider_impl.cc index e9eee70f9566..e90500fa6dcd 100644 --- a/components/brave_wallet/browser/brave_wallet_provider_impl.cc +++ b/components/brave_wallet/browser/brave_wallet_provider_impl.cc @@ -5,6 +5,7 @@ #include "brave/components/brave_wallet/browser/brave_wallet_provider_impl.h" +#include #include #include "base/json/json_reader.h" @@ -20,6 +21,7 @@ #include "brave/components/brave_wallet/browser/json_rpc_service.h" #include "brave/components/brave_wallet/browser/keyring_service.h" #include "brave/components/brave_wallet/common/eth_address.h" +#include "brave/components/brave_wallet/common/eth_sign_typed_data_helper.h" #include "brave/components/brave_wallet/common/hex_utils.h" #include "brave/components/brave_wallet/common/value_conversion_utils.h" #include "brave/components/brave_wallet/common/web3_provider_constants.h" @@ -364,11 +366,11 @@ void BraveWalletProviderImpl::SignMessage(const std::string& address, // Convert to checksum address auto checksum_address = EthAddress::FromHex(address); GetAllowedAccounts( - false, - base::BindOnce(&BraveWalletProviderImpl::ContinueSignMessage, - weak_factory_.GetWeakPtr(), - checksum_address.ToChecksumAddress(), message_str, - std::move(message_bytes), std::move(callback), false)); + false, base::BindOnce(&BraveWalletProviderImpl::ContinueSignMessage, + weak_factory_.GetWeakPtr(), + checksum_address.ToChecksumAddress(), message_str, + std::move(message_bytes), absl::nullopt, + absl::nullopt, false, std::move(callback))); } void BraveWalletProviderImpl::RecoverAddress(const std::string& message, @@ -413,19 +415,17 @@ void BraveWalletProviderImpl::RecoverAddress(const std::string& message, void BraveWalletProviderImpl::SignTypedMessage( const std::string& address, const std::string& message, - const std::string& message_to_sign, + const std::vector& domain_hash, + const std::vector& primary_hash, base::Value domain, SignTypedMessageCallback callback) { - std::vector eip712_hash; - if (!EthAddress::IsValidAddress(address) || - !base::HexStringToBytes(message_to_sign, &eip712_hash) || - eip712_hash.size() != 32 || !domain.is_dict()) { + if (!EthAddress::IsValidAddress(address) || !domain.is_dict() || + domain_hash.empty() || primary_hash.empty()) { std::move(callback).Run( "", mojom::ProviderError::kInvalidParams, l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS)); return; } - auto chain_id = domain.FindDoubleKey("chainId"); if (chain_id) { const std::string chain_id_hex = @@ -440,21 +440,40 @@ void BraveWalletProviderImpl::SignTypedMessage( } } + if (domain_hash.empty() || primary_hash.empty()) { + std::move(callback).Run( + "", mojom::ProviderError::kInvalidParams, + l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS)); + return; + } + auto message_to_sign = EthSignTypedDataHelper::GetTypedDataMessageToSign( + domain_hash, primary_hash); + if (!message_to_sign || message_to_sign->size() != 32) { + std::move(callback).Run( + "", mojom::ProviderError::kInvalidParams, + l10n_util::GetStringUTF8(IDS_WALLET_INVALID_PARAMETERS)); + return; + } + // Convert to checksum address auto checksum_address = EthAddress::FromHex(address); GetAllowedAccounts( - false, base::BindOnce(&BraveWalletProviderImpl::ContinueSignMessage, - weak_factory_.GetWeakPtr(), - checksum_address.ToChecksumAddress(), message, - std::move(eip712_hash), std::move(callback), true)); + false, + base::BindOnce(&BraveWalletProviderImpl::ContinueSignMessage, + weak_factory_.GetWeakPtr(), + checksum_address.ToChecksumAddress(), message, + std::move(*message_to_sign), base::HexEncode(domain_hash), + base::HexEncode(primary_hash), true, std::move(callback))); } void BraveWalletProviderImpl::ContinueSignMessage( const std::string& address, const std::string& message, std::vector&& message_to_sign, - SignMessageCallback callback, + const absl::optional& domain_hash, + const absl::optional& primary_hash, bool is_eip712, + SignMessageCallback callback, const std::vector& allowed_accounts, mojom::ProviderError error, const std::string& error_message) { @@ -472,7 +491,9 @@ void BraveWalletProviderImpl::ContinueSignMessage( } auto request = - mojom::SignMessageRequest::New(sign_message_id_++, address, message); + mojom::SignMessageRequest::New(sign_message_id_++, address, message, + is_eip712, domain_hash, primary_hash); + if (keyring_service_->IsHardwareAccount(address)) { brave_wallet_service_->AddSignMessageRequest( std::move(request), diff --git a/components/brave_wallet/browser/brave_wallet_provider_impl.h b/components/brave_wallet/browser/brave_wallet_provider_impl.h index 511935d685c1..4eb3450cea03 100644 --- a/components/brave_wallet/browser/brave_wallet_provider_impl.h +++ b/components/brave_wallet/browser/brave_wallet_provider_impl.h @@ -80,7 +80,8 @@ class BraveWalletProviderImpl final RecoverAddressCallback callback) override; void SignTypedMessage(const std::string& address, const std::string& message, - const std::string& message_to_sign, + const std::vector& domain_hash, + const std::vector& primary_hash, base::Value domain, SignTypedMessageCallback callback) override; void OnGetAllowedAccounts(GetAllowedAccountsCallback callback, @@ -161,8 +162,10 @@ class BraveWalletProviderImpl final void ContinueSignMessage(const std::string& address, const std::string& message, std::vector&& message_to_sign, - SignMessageCallback callback, + const absl::optional& domain_hash, + const absl::optional& primary_hash, bool is_eip712, + SignMessageCallback callback, const std::vector& allowed_accounts, mojom::ProviderError error, const std::string& error_message); diff --git a/components/brave_wallet/common/brave_wallet.mojom b/components/brave_wallet/common/brave_wallet.mojom index 5062a4835f3a..ae3696c20fc6 100644 --- a/components/brave_wallet/common/brave_wallet.mojom +++ b/components/brave_wallet/common/brave_wallet.mojom @@ -111,7 +111,8 @@ interface BraveWalletProvider { // message is for displaying the sign request to users // message_to_sign is the hex representation without 0x for eip712 hash // domain is the domain separator defined in eip712 - SignTypedMessage(string address, string message, string message_to_sign, + SignTypedMessage(string address, string message, + array domain_hash, array primary_hash, mojo_base.mojom.DictionaryValue domain) => (string signature, ProviderError error, string error_message); @@ -773,6 +774,11 @@ struct SignMessageRequest { int32 id; string address; string message; + bool is_eip712; + // These fields are for hardware eip712 signing and + // Should be used only if is_eip712 is true + string? domain_hash; + string? primary_hash; }; enum ExternalWalletType { diff --git a/components/brave_wallet/common/eth_request_helper.cc b/components/brave_wallet/common/eth_request_helper.cc index b47056866978..e562359950be 100644 --- a/components/brave_wallet/common/eth_request_helper.cc +++ b/components/brave_wallet/common/eth_request_helper.cc @@ -343,10 +343,12 @@ bool ParsePersonalEcRecoverParams(const std::string& json, bool ParseEthSignTypedDataParams(const std::string& json, std::string* address, std::string* message_out, - std::vector* message_to_sign_out, base::Value* domain_out, - EthSignTypedDataHelper::Version version) { - if (!address || !message_out || !domain_out || !message_to_sign_out) + EthSignTypedDataHelper::Version version, + std::vector* domain_hash_out, + std::vector* primary_hash_out) { + if (!address || !message_out || !domain_out || !domain_hash_out || + !primary_hash_out) return false; auto list = GetParamsList(json); @@ -386,12 +388,14 @@ bool ParseEthSignTypedDataParams(const std::string& json, EthSignTypedDataHelper::Create(*types, version); if (!helper) return false; - - auto message_to_sign = - helper->GetTypedDataMessageToSign(*primary_type, *message, *domain); - if (!message_to_sign) + auto domain_hash = helper->GetTypedDataDomainHash(*domain); + if (!domain_hash) + return false; + auto primary_hash = helper->GetTypedDataPrimaryHash(*primary_type, *message); + if (!primary_hash) return false; - *message_to_sign_out = *message_to_sign; + *domain_hash_out = *domain_hash; + *primary_hash_out = *primary_hash; *domain_out = domain->Clone(); diff --git a/components/brave_wallet/common/eth_request_helper.h b/components/brave_wallet/common/eth_request_helper.h index 69d6988bd647..ed1fcfcc930f 100644 --- a/components/brave_wallet/common/eth_request_helper.h +++ b/components/brave_wallet/common/eth_request_helper.h @@ -44,9 +44,10 @@ bool ParsePersonalEcRecoverParams(const std::string& json, bool ParseEthSignTypedDataParams(const std::string& json, std::string* address, std::string* message, - std::vector* message_to_sign, base::Value* domain, - EthSignTypedDataHelper::Version version); + EthSignTypedDataHelper::Version version, + std::vector* domain_hash_out, + std::vector* primary_hash_out); bool ParseSwitchEthereumChainParams(const std::string& json, std::string* chain_id); diff --git a/components/brave_wallet/common/eth_request_helper_unittest.cc b/components/brave_wallet/common/eth_request_helper_unittest.cc index e96e8c4a3ef5..0d7f77dbf6c2 100644 --- a/components/brave_wallet/common/eth_request_helper_unittest.cc +++ b/components/brave_wallet/common/eth_request_helper_unittest.cc @@ -664,11 +664,12 @@ TEST(EthRequestHelperUnitTest, ParseEthSignTypedDataParams) { std::string address; std::string message; base::Value domain; - std::vector message_to_sign; + std::vector domain_hash; + std::vector primary_hash; - EXPECT_TRUE(ParseEthSignTypedDataParams( - json, &address, &message, &message_to_sign, &domain, - EthSignTypedDataHelper::Version::kV4)); + EXPECT_TRUE(ParseEthSignTypedDataParams(json, &address, &message, &domain, + EthSignTypedDataHelper::Version::kV4, + &domain_hash, &primary_hash)); EXPECT_EQ(address, "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"); EXPECT_EQ( @@ -693,7 +694,14 @@ TEST(EthRequestHelperUnitTest, ParseEthSignTypedDataParams) { EXPECT_EQ(*ds_verifying_contract, "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"); - EXPECT_EQ(base::ToLowerASCII(base::HexEncode(message_to_sign)), + EXPECT_EQ(base::ToLowerASCII(base::HexEncode(domain_hash)), + "f2cee375fa42b42143804025fc449deafd50cc031ca257e0b194a650a912090f"); + EXPECT_EQ(base::ToLowerASCII(base::HexEncode(primary_hash)), + "c52c0ee5d84264471806290a3f2c4cecfc5490626bf912d01f240d7a274b371e"); + auto message_to_sign = EthSignTypedDataHelper::GetTypedDataMessageToSign( + domain_hash, primary_hash); + ASSERT_TRUE(message_to_sign); + EXPECT_EQ(base::ToLowerASCII(base::HexEncode(*message_to_sign)), "be609aee343fb3c4b28e1df9e632fca64fcfaede20f02e86244efddf30957bd2"); } diff --git a/components/brave_wallet/common/eth_sign_typed_data_helper.cc b/components/brave_wallet/common/eth_sign_typed_data_helper.cc index e5f153195fcd..5ac3ebfe7357 100644 --- a/components/brave_wallet/common/eth_sign_typed_data_helper.cc +++ b/components/brave_wallet/common/eth_sign_typed_data_helper.cc @@ -362,21 +362,30 @@ absl::optional> EthSignTypedDataHelper::EncodeField( } absl::optional> -EthSignTypedDataHelper::GetTypedDataMessageToSign( - const std::string& primary_type_name, - const base::Value& message, +EthSignTypedDataHelper::GetTypedDataDomainHash( const base::Value& domain_separator) const { - std::vector encoded_data({0x19, 0x01}); - auto domain_hash = HashStruct("EIP712Domain", domain_separator); - if (!domain_hash) - return absl::nullopt; - encoded_data.insert(encoded_data.end(), domain_hash->begin(), - domain_hash->end()); - auto primary_hash = HashStruct(primary_type_name, message); - if (!primary_hash) + return HashStruct("EIP712Domain", domain_separator); +} + +absl::optional> +EthSignTypedDataHelper::GetTypedDataPrimaryHash( + const std::string& primary_type_name, + const base::Value& message) const { + return HashStruct(primary_type_name, message); +} + +// static +absl::optional> +EthSignTypedDataHelper::GetTypedDataMessageToSign( + const std::vector& domain_hash, + const std::vector& primary_hash) { + if (domain_hash.empty() || primary_hash.empty()) return absl::nullopt; - encoded_data.insert(encoded_data.end(), primary_hash->begin(), - primary_hash->end()); + std::vector encoded_data({0x19, 0x01}); + encoded_data.insert(encoded_data.end(), domain_hash.begin(), + domain_hash.end()); + encoded_data.insert(encoded_data.end(), primary_hash.begin(), + primary_hash.end()); return KeccakHash(encoded_data); } diff --git a/components/brave_wallet/common/eth_sign_typed_data_helper.h b/components/brave_wallet/common/eth_sign_typed_data_helper.h index 293cd4ba3901..d61b271c844b 100644 --- a/components/brave_wallet/common/eth_sign_typed_data_helper.h +++ b/components/brave_wallet/common/eth_sign_typed_data_helper.h @@ -40,9 +40,13 @@ class EthSignTypedDataHelper { absl::optional> EncodeData( const std::string& primary_type_name, const base::Value& data) const; - absl::optional> GetTypedDataMessageToSign( + static absl::optional> GetTypedDataMessageToSign( + const std::vector& domain_hash, + const std::vector& primary_hash); + absl::optional> GetTypedDataPrimaryHash( const std::string& primary_type_name, - const base::Value& message, + const base::Value& message) const; + absl::optional> GetTypedDataDomainHash( const base::Value& domain_separator) const; private: diff --git a/components/brave_wallet/common/eth_sign_typed_data_helper_unittest.cc b/components/brave_wallet/common/eth_sign_typed_data_helper_unittest.cc index 55816bd60406..5fa4223a98ea 100644 --- a/components/brave_wallet/common/eth_sign_typed_data_helper_unittest.cc +++ b/components/brave_wallet/common/eth_sign_typed_data_helper_unittest.cc @@ -625,11 +625,16 @@ TEST(EthSignedTypedDataHelperUnitTest, GetTypedDataMessageToSign) { auto ds_hash = helper->HashStruct("EIP712Domain", *ds_value); ASSERT_TRUE(ds_hash); - EXPECT_EQ(base::ToLowerASCII(base::HexEncode(*ds_hash)), + auto domain_hash = helper->GetTypedDataDomainHash(*ds_value); + ASSERT_TRUE(domain_hash); + EXPECT_EQ(base::ToLowerASCII(base::HexEncode(*domain_hash)), "f2cee375fa42b42143804025fc449deafd50cc031ca257e0b194a650a912090f"); - + auto primary_hash = helper->GetTypedDataPrimaryHash("Mail", *data_value); + ASSERT_TRUE(primary_hash); + EXPECT_EQ(base::ToLowerASCII(base::HexEncode(*primary_hash)), + "c52c0ee5d84264471806290a3f2c4cecfc5490626bf912d01f240d7a274b371e"); auto message_to_sign = - helper->GetTypedDataMessageToSign("Mail", *data_value, *ds_value); + helper->GetTypedDataMessageToSign(*domain_hash, *primary_hash); ASSERT_TRUE(message_to_sign); EXPECT_EQ(base::ToLowerASCII(base::HexEncode(*message_to_sign)), "be609aee343fb3c4b28e1df9e632fca64fcfaede20f02e86244efddf30957bd2"); diff --git a/components/brave_wallet/renderer/brave_wallet_js_handler.cc b/components/brave_wallet/renderer/brave_wallet_js_handler.cc index fc95be18f865..9cc0425c30e6 100644 --- a/components/brave_wallet/renderer/brave_wallet_js_handler.cc +++ b/components/brave_wallet/renderer/brave_wallet_js_handler.cc @@ -11,7 +11,6 @@ #include "base/json/json_writer.h" #include "base/no_destructor.h" -#include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "brave/components/brave_wallet/common/eth_request_helper.h" #include "brave/components/brave_wallet/common/hex_utils.h" @@ -742,19 +741,24 @@ bool BraveWalletJSHandler::CommonRequestOrSendAsync( std::string message; base::Value domain; std::vector message_to_sign; + std::vector domain_hash_out; + std::vector primary_hash_out; if (method == kEthSignTypedDataV4) { if (!ParseEthSignTypedDataParams(normalized_json_request, &address, - &message, &message_to_sign, &domain, - EthSignTypedDataHelper::Version::kV4)) + &message, &domain, + EthSignTypedDataHelper::Version::kV4, + &domain_hash_out, &primary_hash_out)) return false; } else { if (!ParseEthSignTypedDataParams(normalized_json_request, &address, - &message, &message_to_sign, &domain, - EthSignTypedDataHelper::Version::kV3)) + &message, &domain, + EthSignTypedDataHelper::Version::kV3, + &domain_hash_out, &primary_hash_out)) return false; } + brave_wallet_provider_->SignTypedMessage( - address, message, base::HexEncode(message_to_sign), std::move(domain), + address, message, domain_hash_out, primary_hash_out, std::move(domain), base::BindOnce(&BraveWalletJSHandler::OnSignRecoverMessage, weak_ptr_factory_.GetWeakPtr(), std::move(id), std::move(global_context), std::move(global_callback), diff --git a/components/brave_wallet_ui/common/async/hardware.ts b/components/brave_wallet_ui/common/async/hardware.ts index a2c7bc4cbfb8..7cca56ff28e8 100644 --- a/components/brave_wallet_ui/common/async/hardware.ts +++ b/components/brave_wallet_ui/common/async/hardware.ts @@ -103,12 +103,22 @@ export async function signLedgerTransaction ( return { success: result.status } } -export async function signMessageWithHardwareKeyring (vendor: HardwareVendor, path: string, message: string): Promise { +export async function signMessageWithHardwareKeyring (vendor: HardwareVendor, path: string, messageData: BraveWallet.SignMessageRequest): Promise { const deviceKeyring = getHardwareKeyring(vendor) if (deviceKeyring instanceof LedgerBridgeKeyring) { - return deviceKeyring.signPersonalMessage(path, message) + if (messageData.isEip712) { + if (!messageData.domainHash || !messageData.primaryHash) { + return { success: false, error: getLocale('braveWalletUnknownInternalError') } + } + return deviceKeyring.signEip712Message(path, messageData.domainHash, messageData?.primaryHash) + } else return deviceKeyring.signPersonalMessage(path, messageData.message) } else if (deviceKeyring instanceof TrezorBridgeKeyring) { - return deviceKeyring.signPersonalMessage(path, message) + if (messageData.isEip712) { + if (!messageData.domainHash || !messageData.primaryHash) { + return { success: false, error: getLocale('braveWalletUnknownInternalError') } + } + return deviceKeyring.signEip712Message(path, messageData.domainHash, messageData.primaryHash) + } else return deviceKeyring.signPersonalMessage(path, messageData.message) } return { success: false, error: getLocale('braveWalletUnknownKeyringError') } } diff --git a/components/brave_wallet_ui/common/hardware/interfaces.ts b/components/brave_wallet_ui/common/hardware/interfaces.ts index c3725dda8b53..c2b8830029e5 100644 --- a/components/brave_wallet_ui/common/hardware/interfaces.ts +++ b/components/brave_wallet_ui/common/hardware/interfaces.ts @@ -23,12 +23,14 @@ export abstract class TrezorKeyring extends HardwareKeyring { abstract getAccounts (from: number, to: number, scheme: string): Promise abstract signTransaction (path: string, txInfo: BraveWallet.TransactionInfo, chainId: string): Promise abstract signPersonalMessage (path: string, message: string): Promise + abstract signEip712Message (path: string, domainSeparatorHex: string, hashStructMessageHex: string): Promise } export abstract class LedgerEthereumKeyring extends HardwareKeyring { abstract getAccounts (from: number, to: number, scheme: string): Promise abstract signPersonalMessage (path: string, address: string, message: string): Promise abstract signTransaction (path: string, rawTxHex: string): Promise + abstract signEip712Message (path: string, domainSeparatorHex: string, hashStructMessageHex: string): Promise } export abstract class LedgerFilecoinKeyring extends HardwareKeyring { diff --git a/components/brave_wallet_ui/common/hardware/ledgerjs/eth_ledger_bridge_keyring.test.ts b/components/brave_wallet_ui/common/hardware/ledgerjs/eth_ledger_bridge_keyring.test.ts index b137c0cf0bad..a3be04e70bf7 100644 --- a/components/brave_wallet_ui/common/hardware/ledgerjs/eth_ledger_bridge_keyring.test.ts +++ b/components/brave_wallet_ui/common/hardware/ledgerjs/eth_ledger_bridge_keyring.test.ts @@ -18,12 +18,16 @@ class MockApp { async signPersonalMessage (path: string, message: Buffer) { return Promise.resolve(this.signature) } + + async signEIP712HashedMessage (path: string, domainSeparatorHex: string, hashStructMessageHex: string) { + return Promise.resolve(this.signature) + } } -const createLedgerKeyring = () => { +const createLedgerKeyring = (app: MockApp = new MockApp()) => { const ledgerHardwareKeyring = new LedgerBridgeKeyring() ledgerHardwareKeyring.unlock = async () => { - ledgerHardwareKeyring.app = new MockApp() + ledgerHardwareKeyring.app = app ledgerHardwareKeyring.deviceId = 'device1' return { success: true } } @@ -151,3 +155,35 @@ test('Sign personal message failed', () => { 'm/44\'/60\'/0\'/0/0', 'message')) .resolves.toMatchObject({ success: false }) }) + +test('Sign typed message success', () => { + const app = new MockApp() + app.signature = { v: 28, r: 'b68983', s: 'r68983' } + const ledgerHardwareKeyring = createLedgerKeyring(app) + return expect(ledgerHardwareKeyring.signEip712Message( + 'm/44\'/60\'/0\'/0/0', 'domainSeparatorHex', 'hashStructMessageHex')) + .resolves.toStrictEqual({ payload: '0xb68983r6898301', success: true }) +}) + +test('Sign typed message locked', () => { + const ledgerHardwareKeyring = new LedgerBridgeKeyring() + ledgerHardwareKeyring.unlock = async () => { + return { success: false } + } + return expect(ledgerHardwareKeyring.signEip712Message( + 'm/44\'/60\'/0\'/0/0', 'domainSeparatorHex', 'hashStructMessageHex')) + .resolves.toStrictEqual({ success: false }) +}) + +test('Sign typed message error', () => { + const app = new MockApp() + app.signEIP712HashedMessage = async (path: string, + domainSeparatorHex: string, + hashStructMessageHex: string) => { + throw Error('some error') + } + const ledgerHardwareKeyring = createLedgerKeyring(app) + return expect(ledgerHardwareKeyring.signEip712Message( + 'm/44\'/60\'/0\'/0/0', 'domainSeparatorHex', 'hashStructMessageHex')) + .resolves.toStrictEqual({ success: false, error: 'some error', code: 'Error' }) +}) diff --git a/components/brave_wallet_ui/common/hardware/ledgerjs/eth_ledger_bridge_keyring.ts b/components/brave_wallet_ui/common/hardware/ledgerjs/eth_ledger_bridge_keyring.ts index 2b85b419c465..1a11de49e8bd 100644 --- a/components/brave_wallet_ui/common/hardware/ledgerjs/eth_ledger_bridge_keyring.ts +++ b/components/brave_wallet_ui/common/hardware/ledgerjs/eth_ledger_bridge_keyring.ts @@ -6,7 +6,6 @@ import { assert } from 'chrome://resources/js/assert.m.js' import TransportWebHID from '@ledgerhq/hw-transport-webhid' import Eth from '@ledgerhq/hw-app-eth' - import { BraveWallet } from '../../../constants/types' import { getLocale } from '../../../../common/locale' import { hardwareDeviceIdFromAddress } from '../hardwareDeviceIdFromAddress' @@ -14,8 +13,8 @@ import { GetAccountsHardwareOperationResult, SignatureVRS, SignHardwareMessageOperationResult, - SignHardwareTransactionOperationResult -, HardwareOperationResult, LedgerDerivationPaths + SignHardwareTransactionOperationResult, + HardwareOperationResult, LedgerDerivationPaths } from '../types' import { LedgerEthereumKeyring } from '../interfaces' import { HardwareVendor } from '../../api/hardware_keyrings' @@ -103,6 +102,21 @@ export default class LedgerBridgeKeyring extends LedgerEthereumKeyring { } } + signEip712Message = async (path: string, domainSeparatorHex: string, hashStructMessageHex: string): Promise => { + try { + const unlocked = await this.unlock() + if (!unlocked.success || !this.app) { + return unlocked + } + const eth: Eth = this.app + const data = await eth.signEIP712HashedMessage(path, domainSeparatorHex, hashStructMessageHex) + const signature = this.createMessageSignature(data) + return { success: true, payload: signature } + } catch (e) { + return { success: false, error: e.message, code: e.statusCode || e.id || e.name } + } + } + signPersonalMessage = async (path: string, message: string): Promise => { try { const unlocked = await this.unlock() diff --git a/components/brave_wallet_ui/common/hardware/trezor/trezor-messages.ts b/components/brave_wallet_ui/common/hardware/trezor/trezor-messages.ts index 8cc98bd717fb..915635110ecd 100644 --- a/components/brave_wallet_ui/common/hardware/trezor/trezor-messages.ts +++ b/components/brave_wallet_ui/common/hardware/trezor/trezor-messages.ts @@ -5,7 +5,7 @@ import { loadTimeData } from '../../../../common/loadTimeData' import { Unsuccessful, EthereumSignTransaction, CommonParams, Success } from 'trezor-connect' import { HDNodeResponse } from 'trezor-connect/lib/typescript' -import { EthereumSignedTx, EthereumSignMessage } from 'trezor-connect/lib/typescript/networks/ethereum' +import { EthereumSignedTx, EthereumSignMessage, EthereumSignTypedHash } from 'trezor-connect/lib/typescript/networks/ethereum' import { MessageSignature } from 'trezor-connect/lib/typescript/trezor/protobuf' export const kTrezorBridgeUrl = loadTimeData.getString('braveWalletTrezorBridgeUrl') @@ -13,7 +13,8 @@ export enum TrezorCommand { Unlock = 'trezor-unlock', GetAccounts = 'trezor-get-accounts', SignTransaction = 'trezor-sign-transaction', - SignMessage = 'trezor-sign-message' + SignMessage = 'trezor-sign-message', + SignTypedMessage = 'trezor-sign-typed-message' } export enum TrezorErrorsCodes { @@ -82,7 +83,18 @@ export type SignMessageResponsePayload = CommandMessage & { payload: SignMessageResponse } -export type TrezorFrameCommand = GetAccountsCommand | UnlockCommand | SignTransactionCommand | SignMessageCommand +// SignTypedMessage command +export type SignTypedMessageCommandPayload = CommonParams & EthereumSignTypedHash +export type SignTypedMessageCommand = CommandMessage & { + command: TrezorCommand.SignTypedMessage + payload: SignTypedMessageCommandPayload +} +export type SignTypedMessageResponse = Unsuccessful | Success +export type SignTypedMessageResponsePayload = CommandMessage & { + payload: SignTypedMessageResponse +} + +export type TrezorFrameCommand = GetAccountsCommand | UnlockCommand | SignTransactionCommand | SignMessageCommand | SignTypedMessageCommand export type TrezorFrameResponse = UnlockResponsePayload | GetAccountsResponsePayload | SignTransactionResponsePayload | SignMessageResponsePayload // Trezor library is loaded inside the chrome-untrusted webui page diff --git a/components/brave_wallet_ui/common/hardware/trezor/trezor_bridge_keyring.test.ts b/components/brave_wallet_ui/common/hardware/trezor/trezor_bridge_keyring.test.ts index 8f2562eb883a..a729f0d6d83f 100644 --- a/components/brave_wallet_ui/common/hardware/trezor/trezor_bridge_keyring.test.ts +++ b/components/brave_wallet_ui/common/hardware/trezor/trezor_bridge_keyring.test.ts @@ -108,6 +108,13 @@ const createTrezorTransport = (unlock: HardwareOperationResult, payload: signedMessagePayload }) } + if (message.command === TrezorCommand.SignTypedMessage) { + hardwareTransport.postResponse({ + id: message.id, + command: message.command, + payload: signedMessagePayload + }) + } } } hardwareTransport.createBridge = async () => { @@ -497,3 +504,30 @@ test('Sign message from unlocked device failed', () => { error: signMessagePayload.payload.error }) }) + +test('Sign typed from unlocked device, success', () => { + const signMessagePayload = { + success: true, + payload: { + signature: 'test' + } + } + const hardwareKeyring = createTrezorKeyringWithTransport( + { success: true }, undefined, undefined, signMessagePayload) + return expect(hardwareKeyring.signEip712Message('m/44\'/60\'/0\'/0', 'domainSeparatorHex', 'hashStructMessageHex')) + .resolves.toStrictEqual({ payload: signMessagePayload.payload.signature, success: signMessagePayload.success }) +}) + +test('Sign typed message api not supported', () => { + const signMessagePayload = { + success: false, + payload: { + code: 'Method_InvalidParameter', + error: 'some text' + } + } + const hardwareKeyring = createTrezorKeyringWithTransport( + { success: true }, undefined, undefined, signMessagePayload) + return expect(hardwareKeyring.signEip712Message('m/44\'/60\'/0\'/0', 'domainSeparatorHex', 'hashStructMessageHex')) + .resolves.toStrictEqual({ error: getLocale('braveWalletTrezorSignTypedDataError'), success: signMessagePayload.success }) +}) diff --git a/components/brave_wallet_ui/common/hardware/trezor/trezor_bridge_keyring.ts b/components/brave_wallet_ui/common/hardware/trezor/trezor_bridge_keyring.ts index ce6813118ceb..a99ae6bd6041 100644 --- a/components/brave_wallet_ui/common/hardware/trezor/trezor_bridge_keyring.ts +++ b/components/brave_wallet_ui/common/hardware/trezor/trezor_bridge_keyring.ts @@ -19,7 +19,8 @@ import { TrezorErrorsCodes, SignTransactionResponse, SignMessageResponse, - TrezorGetAccountsResponse + TrezorGetAccountsResponse, + SignTypedMessageResponsePayload } from './trezor-messages' import { sendTrezorCommand, closeTrezorBridge } from './trezor-bridge-transport' import { hardwareDeviceIdFromAddress } from '../hardwareDeviceIdFromAddress' @@ -143,6 +144,39 @@ export default class TrezorBridgeKeyring implements TrezorKeyring { return { success: true, payload: '0x' + response.payload.signature } } + signEip712Message = async (path: string, domainSeparatorHex: string, hashStructMessageHex: string): Promise => { + if (!this.isUnlocked()) { + const unlocked = await this.unlock() + if (!unlocked.success) { + return unlocked + } + } + const data = await this.sendTrezorCommand({ + command: TrezorCommand.SignTypedMessage, + id: path, + payload: { + path: path, + domain_separator_hash: domainSeparatorHex, + message_hash: hashStructMessageHex + }, + origin: window.origin + }) + + if (data === TrezorErrorsCodes.BridgeNotReady || + data === TrezorErrorsCodes.CommandInProgress) { + return this.createErrorFromCode(data) + } + const response: SignMessageResponse = data.payload + if (!response.success) { + const unsuccess = response.payload + if (unsuccess.code && unsuccess.code === 'Method_InvalidParameter') { + return { success: false, error: getLocale('braveWalletTrezorSignTypedDataError') } + } + return { success: false, error: unsuccess.error, code: unsuccess.code } + } + return { success: true, payload: response.payload.signature } + } + private async sendTrezorCommand (command: TrezorFrameCommand): Promise { return sendTrezorCommand(command) } diff --git a/components/brave_wallet_ui/panel/async/wallet_panel_async_handler.ts b/components/brave_wallet_ui/panel/async/wallet_panel_async_handler.ts index a5faf9c9122d..70a57d922eb8 100644 --- a/components/brave_wallet_ui/panel/async/wallet_panel_async_handler.ts +++ b/components/brave_wallet_ui/panel/async/wallet_panel_async_handler.ts @@ -370,7 +370,7 @@ handler.on(PanelActions.signMessageHardware.getType(), async (store, messageData } await navigateToConnectHardwareWallet(store) const info = hardwareAccount.hardware - const signed = await signMessageWithHardwareKeyring(info.vendor as HardwareVendor, info.path, messageData.message) + const signed = await signMessageWithHardwareKeyring(info.vendor as HardwareVendor, info.path, messageData) if (!signed.success && signed.code) { const deviceError = (info.vendor === BraveWallet.TREZOR_HARDWARE_VENDOR) ? dialogErrorFromTrezorErrorCode(signed.code) : dialogErrorFromLedgerErrorCode(signed.code) diff --git a/components/brave_wallet_ui/panel/reducers/panel_reducer.ts b/components/brave_wallet_ui/panel/reducers/panel_reducer.ts index ee0c6f64fa5a..8095ca0727e4 100644 --- a/components/brave_wallet_ui/panel/reducers/panel_reducer.ts +++ b/components/brave_wallet_ui/panel/reducers/panel_reducer.ts @@ -40,7 +40,10 @@ const defaultState: PanelState = { signMessageData: [{ id: -1, address: '', - message: '' + message: '', + isEip712: false, + domainHash: '', + primaryHash: '' }], switchChainRequest: { origin: { diff --git a/components/brave_wallet_ui/trezor/trezor.ts b/components/brave_wallet_ui/trezor/trezor.ts index afc54735e746..6d3449e8dd6c 100644 --- a/components/brave_wallet_ui/trezor/trezor.ts +++ b/components/brave_wallet_ui/trezor/trezor.ts @@ -17,7 +17,9 @@ import { SignMessageCommand, SignMessageResponsePayload, SignMessageResponse, - UnlockResponse + UnlockResponse, + SignTypedMessageCommand, + SignTypedMessageResponsePayload } from '../common/hardware/trezor/trezor-messages' import { addTrezorCommandHandler } from '../common/hardware/trezor/trezor-command-handler' @@ -70,3 +72,11 @@ addTrezorCommandHandler(TrezorCommand.SignMessage, (command: SignMessageCommand, }) }) }) + +addTrezorCommandHandler(TrezorCommand.SignTypedMessage, (command: SignTypedMessageCommand, source: Window): Promise => { + return new Promise(async (resolve) => { + TrezorConnect.ethereumSignTypedData(command.payload).then((result: SignMessageResponse) => { + resolve({ id: command.id, command: command.command, payload: result, origin: command.origin }) + }) + }) +}) diff --git a/components/resources/wallet_strings.grdp b/components/resources/wallet_strings.grdp index b8642188a107..171aff9790d9 100644 --- a/components/resources/wallet_strings.grdp +++ b/components/resources/wallet_strings.grdp @@ -404,4 +404,7 @@ This network is already added. + + Signing typed data is supported only on Trezor Model One with Firmware 1.10.5 or higher + diff --git a/package-lock.json b/package-lock.json index c2efba6ca9d0..2785b9affe48 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,8 +11,8 @@ "dependencies": { "@brave/react-virtualized-auto-sizer": "^1.0.4", "@glif/filecoin-wallet-provider": "2.0.0-alpha.14", - "@ledgerhq/hw-app-eth": "6.22.3", - "@ledgerhq/hw-transport-webhid": "6.20.0", + "@ledgerhq/hw-app-eth": "6.24.1", + "@ledgerhq/hw-transport-webhid": "6.24.1", "@noble/bls12-381": "1.0.1", "@types/jszip": "^3.1.6", "@types/parse-torrent": "^5.8.3", @@ -2436,25 +2436,6 @@ "@ethersproject/bytes": "^5.5.0" } }, - "node_modules/@ethersproject/basex": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.5.0.tgz", - "integrity": "sha512-ZIodwhHpVJ0Y3hUCfUucmxKsWQA5TMnavp5j/UOuDdzZWzJlRmuOjcTMIGgHCYuZmHt36BfiSyQPSRskPxbfaQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/properties": "^5.5.0" - } - }, "node_modules/@ethersproject/bignumber": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.5.0.tgz", @@ -2516,33 +2497,6 @@ "@ethersproject/bignumber": "^5.5.0" } }, - "node_modules/@ethersproject/contracts": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.5.0.tgz", - "integrity": "sha512-2viY7NzyvJkh+Ug17v7g3/IJC8HqZBDcOjYARZLdzRxrfGlRgmYgl6xPRKVbEzy1dWKw/iv7chDcS83pg6cLxg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abi": "^5.5.0", - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/transactions": "^5.5.0" - } - }, "node_modules/@ethersproject/hash": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.5.0.tgz", @@ -2568,65 +2522,6 @@ "@ethersproject/strings": "^5.5.0" } }, - "node_modules/@ethersproject/hdnode": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.5.0.tgz", - "integrity": "sha512-mcSOo9zeUg1L0CoJH7zmxwUG5ggQHU1UrRf8jyTYy6HxdZV+r0PBoL1bxr+JHIPXRzS6u/UW4mEn43y0tmyF8Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/basex": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/pbkdf2": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/signing-key": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/wordlists": "^5.5.0" - } - }, - "node_modules/@ethersproject/json-wallets": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.5.0.tgz", - "integrity": "sha512-9lA21XQnCdcS72xlBn1jfQdj2A1VUxZzOzi9UkNdnokNKke/9Ya2xA9aIK1SC3PQyBDLt4C+dfps7ULpkvKikQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hdnode": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/pbkdf2": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, "node_modules/@ethersproject/keccak256": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.5.0.tgz", @@ -2679,25 +2574,6 @@ "@ethersproject/logger": "^5.5.0" } }, - "node_modules/@ethersproject/pbkdf2": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.5.0.tgz", - "integrity": "sha512-SaDvQFvXPnz1QGpzr6/HToLifftSXGoXrbpZ6BvoZhmx4bNLHrxDe8MZisuecyOziP1aVEwzC2Hasj+86TgWVg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/sha2": "^5.5.0" - } - }, "node_modules/@ethersproject/properties": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.5.0.tgz", @@ -2716,61 +2592,6 @@ "@ethersproject/logger": "^5.5.0" } }, - "node_modules/@ethersproject/providers": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.5.2.tgz", - "integrity": "sha512-hkbx7x/MKcRjyrO4StKXCzCpWer6s97xnm34xkfPiarhtEUVAN4TBBpamM+z66WcTt7H5B53YwbRj1n7i8pZoQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/basex": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/networks": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/rlp": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/web": "^5.5.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "node_modules/@ethersproject/random": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.5.1.tgz", - "integrity": "sha512-YaU2dQ7DuhL5Au7KbcQLHxcRHfgyNgvFV4sQOo0HrtW3Zkrc9ctWNz8wXQ4uCSfSDsqX2vcjhroxU5RQRV0nqA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, "node_modules/@ethersproject/rlp": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.5.0.tgz", @@ -2790,26 +2611,6 @@ "@ethersproject/logger": "^5.5.0" } }, - "node_modules/@ethersproject/sha2": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.5.0.tgz", - "integrity": "sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "hash.js": "1.1.7" - } - }, "node_modules/@ethersproject/signing-key": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.5.0.tgz", @@ -2838,29 +2639,6 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, - "node_modules/@ethersproject/solidity": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.5.0.tgz", - "integrity": "sha512-9NgZs9LhGMj6aCtHXhtmFQ4AN4sth5HuFXVvAQtzmm0jpSCNOTGtrHZJAeYTh7MBjRR8brylWZxBZR9zDStXbw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, "node_modules/@ethersproject/strings": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.5.0.tgz", @@ -2907,58 +2685,6 @@ "@ethersproject/signing-key": "^5.5.0" } }, - "node_modules/@ethersproject/units": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.5.0.tgz", - "integrity": "sha512-7+DpjiZk4v6wrikj+TCyWWa9dXLNU73tSTa7n0TSJDxkYbV3Yf1eRh9ToMLlZtuctNYu9RDNNy2USq3AdqSbag==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "node_modules/@ethersproject/wallet": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.5.0.tgz", - "integrity": "sha512-Mlu13hIctSYaZmUOo7r2PhNSd8eaMPVXe1wxrz4w4FCE4tDYBywDH+bAR1Xz2ADyXGwqYMwstzTrtUVIsKDO0Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/hdnode": "^5.5.0", - "@ethersproject/json-wallets": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/signing-key": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/wordlists": "^5.5.0" - } - }, "node_modules/@ethersproject/web": { "version": "5.5.1", "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.5.1.tgz", @@ -2981,28 +2707,6 @@ "@ethersproject/strings": "^5.5.0" } }, - "node_modules/@ethersproject/wordlists": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.5.0.tgz", - "integrity": "sha512-bL0UTReWDiaQJJYOC9sh/XcRu/9i2jMrzf8VLRmPKx58ckSlOJiohODkECCO50dtLZHcGU6MLXQ4OOrgBwP77Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, "node_modules/@gar/promisify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.2.tgz", @@ -3461,17 +3165,17 @@ } }, "node_modules/@ledgerhq/cryptoassets": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/cryptoassets/-/cryptoassets-6.23.0.tgz", - "integrity": "sha512-ndZq6arggyspUbgqqHvihvnwyR9woafW1ikIsFZt6yDZrzp/aNjdovkFlLbYdJ1z7K9asMXyURBITA1xoQyBtg==", + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/cryptoassets/-/cryptoassets-6.24.1.tgz", + "integrity": "sha512-RCl2T5Qeu4fch5O+6pgT9s9AWs0ATWdBDwN2MSUuLxj7BfwdXig5+hcSObM3OIJPryNeDCtIYNK3z0blgxfTiA==", "dependencies": { "invariant": "2" } }, "node_modules/@ledgerhq/devices": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-6.20.0.tgz", - "integrity": "sha512-WehM7HGdb+nSUzyUlz1t2qJ8Tg4I+rQkOJJsx0/Dpjkx6/+1hHcX6My/apPuwh39qahqwYhjszq0H1YzGDS0Yg==", + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-6.24.1.tgz", + "integrity": "sha512-6SNXWXxojUF6WKXMVIbRs15Mveg+9k0RKJK/PKlwZh929Lnr/NcbONWdwPjWKZAp1g82eEPT4jIkG6qc4QXlcA==", "dependencies": { "@ledgerhq/errors": "^6.10.0", "@ledgerhq/logs": "^6.10.0", @@ -3499,37 +3203,38 @@ "integrity": "sha512-fQFnl2VIXh9Yd41lGjReCeK+Q2hwxQJvLZfqHnKqWapTz68NHOv5QcI0OHuZVNEbv0xhgdLhi5b65kgYeQSUVg==" }, "node_modules/@ledgerhq/hw-app-eth": { - "version": "6.22.3", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-app-eth/-/hw-app-eth-6.22.3.tgz", - "integrity": "sha512-3sJkU3PdUUhlrz509QBrpDHA3/szcTsk5RJyQLZCB+ssnw+zi9EpQbD6ICmR2Zp16zAl2q85lWTmmbyc8NGwCA==", + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-app-eth/-/hw-app-eth-6.24.1.tgz", + "integrity": "sha512-IyEY+th08RRZaJ014JmKmyS+vtrZzmFwXGgJ0aO7Z+pAzpqgZWyoFsntxf27YE/qPxR/FtHdyFma9RGYI97IEg==", "dependencies": { - "@ledgerhq/cryptoassets": "^6.22.3", + "@ethersproject/abi": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ledgerhq/cryptoassets": "^6.24.1", "@ledgerhq/errors": "^6.10.0", - "@ledgerhq/hw-transport": "^6.20.0", + "@ledgerhq/hw-transport": "^6.24.1", "@ledgerhq/logs": "^6.10.0", "axios": "^0.24.0", - "bignumber.js": "^9.0.2", - "ethers": "^5.5.2" + "bignumber.js": "^9.0.2" } }, "node_modules/@ledgerhq/hw-transport": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.20.0.tgz", - "integrity": "sha512-5KS0Y6CbWRDOv3FgNIfk53ViQOIZqMxAw0RuOexreW5GMwuYfK7ddGi4142qcu7YrxkGo7cNe42wBbx1hdXl0Q==", + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.24.1.tgz", + "integrity": "sha512-cOhxkQJrN7DvPFLLXAS2nqAZ7NIDaFqnbgu9ugTccgbJm2/z7ClRZX/uQoI4FscswZ47MuJQdXqz4nK48phteQ==", "dependencies": { - "@ledgerhq/devices": "^6.20.0", + "@ledgerhq/devices": "^6.24.1", "@ledgerhq/errors": "^6.10.0", "events": "^3.3.0" } }, "node_modules/@ledgerhq/hw-transport-webhid": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webhid/-/hw-transport-webhid-6.20.0.tgz", - "integrity": "sha512-vpbeKmvlQQHQIT7MOAt8TJV7706YkvfEsW2it/vQKAKGjmAYWgrLDXLLgmA1rEDschq0w63crOSp0El4doy+JQ==", + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webhid/-/hw-transport-webhid-6.24.1.tgz", + "integrity": "sha512-jeOB4oSQyytJD99FU+xNUkEflgSB6hWUbzhEqnz7fExnGJhMrRT39035dEmSdwshsOFBhzR/IwTUzlwNZzhNxQ==", "dependencies": { - "@ledgerhq/devices": "^6.20.0", + "@ledgerhq/devices": "^6.24.1", "@ledgerhq/errors": "^6.10.0", - "@ledgerhq/hw-transport": "^6.20.0", + "@ledgerhq/hw-transport": "^6.24.1", "@ledgerhq/logs": "^6.10.0" } }, @@ -7673,11 +7378,6 @@ "node": ">= 0.12.0" } }, - "node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=" - }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -8797,11 +8497,6 @@ "node": ">=8.0.0" } }, - "node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, "node_modules/bencode": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/bencode/-/bencode-2.0.2.tgz", @@ -13282,53 +12977,6 @@ "node": ">=10.0.0" } }, - "node_modules/ethers": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.5.3.tgz", - "integrity": "sha512-fTT4WT8/hTe/BLwRUtl7I5zlpF3XC3P/Xwqxc5AIP2HGlH15qpmjs0Ou78az93b1rLITzXLFxoNX63B8ZbUd7g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abi": "5.5.0", - "@ethersproject/abstract-provider": "5.5.1", - "@ethersproject/abstract-signer": "5.5.0", - "@ethersproject/address": "5.5.0", - "@ethersproject/base64": "5.5.0", - "@ethersproject/basex": "5.5.0", - "@ethersproject/bignumber": "5.5.0", - "@ethersproject/bytes": "5.5.0", - "@ethersproject/constants": "5.5.0", - "@ethersproject/contracts": "5.5.0", - "@ethersproject/hash": "5.5.0", - "@ethersproject/hdnode": "5.5.0", - "@ethersproject/json-wallets": "5.5.0", - "@ethersproject/keccak256": "5.5.0", - "@ethersproject/logger": "5.5.0", - "@ethersproject/networks": "5.5.2", - "@ethersproject/pbkdf2": "5.5.0", - "@ethersproject/properties": "5.5.0", - "@ethersproject/providers": "5.5.2", - "@ethersproject/random": "5.5.1", - "@ethersproject/rlp": "5.5.0", - "@ethersproject/sha2": "5.5.0", - "@ethersproject/signing-key": "5.5.0", - "@ethersproject/solidity": "5.5.0", - "@ethersproject/strings": "5.5.0", - "@ethersproject/transactions": "5.5.0", - "@ethersproject/units": "5.5.0", - "@ethersproject/wallet": "5.5.0", - "@ethersproject/web": "5.5.1", - "@ethersproject/wordlists": "5.5.0" - } - }, "node_modules/ethjs-util": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", @@ -22878,7 +22526,8 @@ "node_modules/scrypt-js": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "dev": true }, "node_modules/secp256k1": { "version": "4.0.3", @@ -29577,6 +29226,7 @@ "integrity": "sha512-auc01jSinxeV1EF1cJvVNKERxHwqkZEF3GWnz12S8EIcgAWE5eQM4Onp/zzSgFEhG2UgOHf0LLPdSMKs6xNdWQ==", "dev": true, "requires": { + "react": "^16.6.0", "react-json-view": "^1.13.3" } }, @@ -29805,15 +29455,6 @@ "@ethersproject/bytes": "^5.5.0" } }, - "@ethersproject/basex": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.5.0.tgz", - "integrity": "sha512-ZIodwhHpVJ0Y3hUCfUucmxKsWQA5TMnavp5j/UOuDdzZWzJlRmuOjcTMIGgHCYuZmHt36BfiSyQPSRskPxbfaQ==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/properties": "^5.5.0" - } - }, "@ethersproject/bignumber": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.5.0.tgz", @@ -29847,23 +29488,6 @@ "@ethersproject/bignumber": "^5.5.0" } }, - "@ethersproject/contracts": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.5.0.tgz", - "integrity": "sha512-2viY7NzyvJkh+Ug17v7g3/IJC8HqZBDcOjYARZLdzRxrfGlRgmYgl6xPRKVbEzy1dWKw/iv7chDcS83pg6cLxg==", - "requires": { - "@ethersproject/abi": "^5.5.0", - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/transactions": "^5.5.0" - } - }, "@ethersproject/hash": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.5.0.tgz", @@ -29879,45 +29503,6 @@ "@ethersproject/strings": "^5.5.0" } }, - "@ethersproject/hdnode": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.5.0.tgz", - "integrity": "sha512-mcSOo9zeUg1L0CoJH7zmxwUG5ggQHU1UrRf8jyTYy6HxdZV+r0PBoL1bxr+JHIPXRzS6u/UW4mEn43y0tmyF8Q==", - "requires": { - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/basex": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/pbkdf2": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/signing-key": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/wordlists": "^5.5.0" - } - }, - "@ethersproject/json-wallets": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.5.0.tgz", - "integrity": "sha512-9lA21XQnCdcS72xlBn1jfQdj2A1VUxZzOzi9UkNdnokNKke/9Ya2xA9aIK1SC3PQyBDLt4C+dfps7ULpkvKikQ==", - "requires": { - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hdnode": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/pbkdf2": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, "@ethersproject/keccak256": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.5.0.tgz", @@ -29940,15 +29525,6 @@ "@ethersproject/logger": "^5.5.0" } }, - "@ethersproject/pbkdf2": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.5.0.tgz", - "integrity": "sha512-SaDvQFvXPnz1QGpzr6/HToLifftSXGoXrbpZ6BvoZhmx4bNLHrxDe8MZisuecyOziP1aVEwzC2Hasj+86TgWVg==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/sha2": "^5.5.0" - } - }, "@ethersproject/properties": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.5.0.tgz", @@ -29957,41 +29533,6 @@ "@ethersproject/logger": "^5.5.0" } }, - "@ethersproject/providers": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.5.2.tgz", - "integrity": "sha512-hkbx7x/MKcRjyrO4StKXCzCpWer6s97xnm34xkfPiarhtEUVAN4TBBpamM+z66WcTt7H5B53YwbRj1n7i8pZoQ==", - "requires": { - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/basex": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/networks": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/rlp": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/web": "^5.5.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "@ethersproject/random": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.5.1.tgz", - "integrity": "sha512-YaU2dQ7DuhL5Au7KbcQLHxcRHfgyNgvFV4sQOo0HrtW3Zkrc9ctWNz8wXQ4uCSfSDsqX2vcjhroxU5RQRV0nqA==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, "@ethersproject/rlp": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.5.0.tgz", @@ -30001,16 +29542,6 @@ "@ethersproject/logger": "^5.5.0" } }, - "@ethersproject/sha2": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.5.0.tgz", - "integrity": "sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "hash.js": "1.1.7" - } - }, "@ethersproject/signing-key": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.5.0.tgz", @@ -30031,19 +29562,6 @@ } } }, - "@ethersproject/solidity": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.5.0.tgz", - "integrity": "sha512-9NgZs9LhGMj6aCtHXhtmFQ4AN4sth5HuFXVvAQtzmm0jpSCNOTGtrHZJAeYTh7MBjRR8brylWZxBZR9zDStXbw==", - "requires": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, "@ethersproject/strings": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.5.0.tgz", @@ -30070,38 +29588,6 @@ "@ethersproject/signing-key": "^5.5.0" } }, - "@ethersproject/units": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.5.0.tgz", - "integrity": "sha512-7+DpjiZk4v6wrikj+TCyWWa9dXLNU73tSTa7n0TSJDxkYbV3Yf1eRh9ToMLlZtuctNYu9RDNNy2USq3AdqSbag==", - "requires": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/wallet": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.5.0.tgz", - "integrity": "sha512-Mlu13hIctSYaZmUOo7r2PhNSd8eaMPVXe1wxrz4w4FCE4tDYBywDH+bAR1Xz2ADyXGwqYMwstzTrtUVIsKDO0Q==", - "requires": { - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/hdnode": "^5.5.0", - "@ethersproject/json-wallets": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/signing-key": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/wordlists": "^5.5.0" - } - }, "@ethersproject/web": { "version": "5.5.1", "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.5.1.tgz", @@ -30114,18 +29600,6 @@ "@ethersproject/strings": "^5.5.0" } }, - "@ethersproject/wordlists": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.5.0.tgz", - "integrity": "sha512-bL0UTReWDiaQJJYOC9sh/XcRu/9i2jMrzf8VLRmPKx58ckSlOJiohODkECCO50dtLZHcGU6MLXQ4OOrgBwP77Q==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, "@gar/promisify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.2.tgz", @@ -30521,17 +29995,17 @@ } }, "@ledgerhq/cryptoassets": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/cryptoassets/-/cryptoassets-6.23.0.tgz", - "integrity": "sha512-ndZq6arggyspUbgqqHvihvnwyR9woafW1ikIsFZt6yDZrzp/aNjdovkFlLbYdJ1z7K9asMXyURBITA1xoQyBtg==", + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/cryptoassets/-/cryptoassets-6.24.1.tgz", + "integrity": "sha512-RCl2T5Qeu4fch5O+6pgT9s9AWs0ATWdBDwN2MSUuLxj7BfwdXig5+hcSObM3OIJPryNeDCtIYNK3z0blgxfTiA==", "requires": { "invariant": "2" } }, "@ledgerhq/devices": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-6.20.0.tgz", - "integrity": "sha512-WehM7HGdb+nSUzyUlz1t2qJ8Tg4I+rQkOJJsx0/Dpjkx6/+1hHcX6My/apPuwh39qahqwYhjszq0H1YzGDS0Yg==", + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-6.24.1.tgz", + "integrity": "sha512-6SNXWXxojUF6WKXMVIbRs15Mveg+9k0RKJK/PKlwZh929Lnr/NcbONWdwPjWKZAp1g82eEPT4jIkG6qc4QXlcA==", "requires": { "@ledgerhq/errors": "^6.10.0", "@ledgerhq/logs": "^6.10.0", @@ -30555,37 +30029,38 @@ "integrity": "sha512-fQFnl2VIXh9Yd41lGjReCeK+Q2hwxQJvLZfqHnKqWapTz68NHOv5QcI0OHuZVNEbv0xhgdLhi5b65kgYeQSUVg==" }, "@ledgerhq/hw-app-eth": { - "version": "6.22.3", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-app-eth/-/hw-app-eth-6.22.3.tgz", - "integrity": "sha512-3sJkU3PdUUhlrz509QBrpDHA3/szcTsk5RJyQLZCB+ssnw+zi9EpQbD6ICmR2Zp16zAl2q85lWTmmbyc8NGwCA==", + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-app-eth/-/hw-app-eth-6.24.1.tgz", + "integrity": "sha512-IyEY+th08RRZaJ014JmKmyS+vtrZzmFwXGgJ0aO7Z+pAzpqgZWyoFsntxf27YE/qPxR/FtHdyFma9RGYI97IEg==", "requires": { - "@ledgerhq/cryptoassets": "^6.22.3", + "@ethersproject/abi": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ledgerhq/cryptoassets": "^6.24.1", "@ledgerhq/errors": "^6.10.0", - "@ledgerhq/hw-transport": "^6.20.0", + "@ledgerhq/hw-transport": "^6.24.1", "@ledgerhq/logs": "^6.10.0", "axios": "^0.24.0", - "bignumber.js": "^9.0.2", - "ethers": "^5.5.2" + "bignumber.js": "^9.0.2" } }, "@ledgerhq/hw-transport": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.20.0.tgz", - "integrity": "sha512-5KS0Y6CbWRDOv3FgNIfk53ViQOIZqMxAw0RuOexreW5GMwuYfK7ddGi4142qcu7YrxkGo7cNe42wBbx1hdXl0Q==", + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-6.24.1.tgz", + "integrity": "sha512-cOhxkQJrN7DvPFLLXAS2nqAZ7NIDaFqnbgu9ugTccgbJm2/z7ClRZX/uQoI4FscswZ47MuJQdXqz4nK48phteQ==", "requires": { - "@ledgerhq/devices": "^6.20.0", + "@ledgerhq/devices": "^6.24.1", "@ledgerhq/errors": "^6.10.0", "events": "^3.3.0" } }, "@ledgerhq/hw-transport-webhid": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webhid/-/hw-transport-webhid-6.20.0.tgz", - "integrity": "sha512-vpbeKmvlQQHQIT7MOAt8TJV7706YkvfEsW2it/vQKAKGjmAYWgrLDXLLgmA1rEDschq0w63crOSp0El4doy+JQ==", + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webhid/-/hw-transport-webhid-6.24.1.tgz", + "integrity": "sha512-jeOB4oSQyytJD99FU+xNUkEflgSB6hWUbzhEqnz7fExnGJhMrRT39035dEmSdwshsOFBhzR/IwTUzlwNZzhNxQ==", "requires": { - "@ledgerhq/devices": "^6.20.0", + "@ledgerhq/devices": "^6.24.1", "@ledgerhq/errors": "^6.10.0", - "@ledgerhq/hw-transport": "^6.20.0", + "@ledgerhq/hw-transport": "^6.24.1", "@ledgerhq/logs": "^6.10.0" } }, @@ -33757,11 +33232,6 @@ "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", "dev": true }, - "aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=" - }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -34625,11 +34095,6 @@ "stream-browserify": "^3.0.0" } }, - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, "bencode": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/bencode/-/bencode-2.0.2.tgz", @@ -38097,43 +37562,6 @@ "rlp": "^2.2.4" } }, - "ethers": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.5.3.tgz", - "integrity": "sha512-fTT4WT8/hTe/BLwRUtl7I5zlpF3XC3P/Xwqxc5AIP2HGlH15qpmjs0Ou78az93b1rLITzXLFxoNX63B8ZbUd7g==", - "requires": { - "@ethersproject/abi": "5.5.0", - "@ethersproject/abstract-provider": "5.5.1", - "@ethersproject/abstract-signer": "5.5.0", - "@ethersproject/address": "5.5.0", - "@ethersproject/base64": "5.5.0", - "@ethersproject/basex": "5.5.0", - "@ethersproject/bignumber": "5.5.0", - "@ethersproject/bytes": "5.5.0", - "@ethersproject/constants": "5.5.0", - "@ethersproject/contracts": "5.5.0", - "@ethersproject/hash": "5.5.0", - "@ethersproject/hdnode": "5.5.0", - "@ethersproject/json-wallets": "5.5.0", - "@ethersproject/keccak256": "5.5.0", - "@ethersproject/logger": "5.5.0", - "@ethersproject/networks": "5.5.2", - "@ethersproject/pbkdf2": "5.5.0", - "@ethersproject/properties": "5.5.0", - "@ethersproject/providers": "5.5.2", - "@ethersproject/random": "5.5.1", - "@ethersproject/rlp": "5.5.0", - "@ethersproject/sha2": "5.5.0", - "@ethersproject/signing-key": "5.5.0", - "@ethersproject/solidity": "5.5.0", - "@ethersproject/strings": "5.5.0", - "@ethersproject/transactions": "5.5.0", - "@ethersproject/units": "5.5.0", - "@ethersproject/wallet": "5.5.0", - "@ethersproject/web": "5.5.1", - "@ethersproject/wordlists": "5.5.0" - } - }, "ethjs-util": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", @@ -44377,7 +43805,8 @@ "integrity": "sha512-v1CDCvdfoR3zLGNp6qsBa4J1BWMEVH25+UKxF/RvQRh+mrB+emqtVHMgZ+WreUiKJoEaiwYoScaueIKhMVBHUg==", "requires": { "@babel/runtime": "^7.2.0", - "invariant": "^2.2.4" + "invariant": "^2.2.4", + "prop-types": "^15.5.7" } }, "react-syntax-highlighter": { @@ -45594,7 +45023,8 @@ "scrypt-js": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "dev": true }, "secp256k1": { "version": "4.0.3", diff --git a/package.json b/package.json index 8b7bcaa935c4..3115df266140 100644 --- a/package.json +++ b/package.json @@ -340,8 +340,8 @@ }, "dependencies": { "@brave/react-virtualized-auto-sizer": "^1.0.4", - "@ledgerhq/hw-app-eth": "6.22.3", - "@ledgerhq/hw-transport-webhid": "6.20.0", + "@ledgerhq/hw-app-eth": "6.24.1", + "@ledgerhq/hw-transport-webhid": "6.24.1", "@glif/filecoin-wallet-provider": "2.0.0-alpha.14", "@types/jszip": "^3.1.6", "@types/parse-torrent": "^5.8.3",