diff --git a/app/components/Views/ChoosePassword/index.js b/app/components/Views/ChoosePassword/index.js index 79ff561aeb9..e659f1831eb 100644 --- a/app/components/Views/ChoosePassword/index.js +++ b/app/components/Views/ChoosePassword/index.js @@ -551,10 +551,7 @@ class ChoosePassword extends PureComponent { const { KeyringController } = Engine.context; const { password } = this.state; const keychainPassword = this.keyringControllerPasswordSet ? password : ''; - const mnemonic = await KeyringController.exportSeedPhrase( - keychainPassword, - ).toString(); - return JSON.stringify(mnemonic).replace(/"/g, ''); + return await KeyringController.exportSeedPhrase(keychainPassword); }; jumpToConfirmPassword = () => { diff --git a/app/components/Views/ConnectQRHardware/index.tsx b/app/components/Views/ConnectQRHardware/index.tsx index 605da537ec6..cde8048415c 100644 --- a/app/components/Views/ConnectQRHardware/index.tsx +++ b/app/components/Views/ConnectQRHardware/index.tsx @@ -252,17 +252,12 @@ const ConnectQRHardware = ({ navigation }: IConnectQRHardwareProps) => { ); const onUnlock = useCallback(async () => { - const { PreferencesController } = Engine.context as any; resetError(); setBlockingModalVisible(true); - const importedAccountAddresses = []; try { for (const account of checkedAccounts) { - const accountAddress = - await KeyringController.unlockQRHardwareWalletAccount(account); - importedAccountAddresses.push(accountAddress); + await KeyringController.unlockQRHardwareWalletAccount(account); } - PreferencesController.setSelectedAddress(importedAccountAddresses[0]); } catch (err) { Logger.log('Error: Connecting QR hardware wallet', err); } diff --git a/app/components/Views/ManualBackupStep1/index.js b/app/components/Views/ManualBackupStep1/index.js index 743c27ab787..01e9cc73795 100644 --- a/app/components/Views/ManualBackupStep1/index.js +++ b/app/components/Views/ManualBackupStep1/index.js @@ -14,6 +14,7 @@ import { connect } from 'react-redux'; import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'; import FeatherIcons from 'react-native-vector-icons/Feather'; import { BlurView } from '@react-native-community/blur'; +import { wordlist } from '@metamask/scure-bip39/dist/wordlists/english'; import { baseStyles } from '../../../styles/common'; import StyledButton from '../../UI/StyledButton'; import OnboardingProgress from '../../UI/OnboardingProgress'; @@ -29,6 +30,7 @@ import { WRONG_PASSWORD_ERROR, } from '../../../constants/onboarding'; import { useTheme } from '../../../util/theme'; +import { uint8ArrayToMnemonic } from '../../../util/mnemonic'; import { createStyles } from './styles'; import { CONFIRM_CHANGE_PASSWORD_INPUT_BOX_ID } from '../../../constants/test-ids'; @@ -63,10 +65,10 @@ const ManualBackupStep1 = ({ route, navigation, appTheme }) => { const tryExportSeedPhrase = async (password) => { const { KeyringController } = Engine.context; - const mnemonic = await KeyringController.exportSeedPhrase( + const uint8ArrayMnemonic = await KeyringController.exportSeedPhrase( password, - ).toString(); - return JSON.stringify(mnemonic).replace(/"/g, '').split(' '); + ); + return uint8ArrayToMnemonic(uint8ArrayMnemonic, wordlist).split(' '); }; useEffect(() => { diff --git a/app/components/Views/ManualBackupStep2/index.js b/app/components/Views/ManualBackupStep2/index.js index e870eb1fcb8..631136b755a 100644 --- a/app/components/Views/ManualBackupStep2/index.js +++ b/app/components/Views/ManualBackupStep2/index.js @@ -16,7 +16,7 @@ import { connect } from 'react-redux'; import { seedphraseBackedUp } from '../../../actions/user'; import MaterialIcon from 'react-native-vector-icons/MaterialCommunityIcons'; import { getOnboardingNavbarOptions } from '../../UI/Navbar'; -import { shuffle, compareSRPs } from '../../../util/SRP'; +import { shuffle, compareMnemonics } from '../../../util/mnemonic'; import { MetaMetricsEvents } from '../../../core/Analytics'; import AnalyticsV2 from '../../../util/analyticsV2'; import { useTheme } from '../../../util/theme'; @@ -120,7 +120,7 @@ const ManualBackupStep2 = ({ navigation, seedphraseBackedUp, route }) => { (confirmedWord) => confirmedWord.word, ); - return compareSRPs(validWords, proposedWords); + return compareMnemonics(validWords, proposedWords); }, [confirmedWords, route.params?.words]); const goNext = () => { diff --git a/app/components/Views/ResetPassword/index.js b/app/components/Views/ResetPassword/index.js index c276fe4a205..dbf331d57b5 100644 --- a/app/components/Views/ResetPassword/index.js +++ b/app/components/Views/ResetPassword/index.js @@ -461,21 +461,6 @@ class ResetPassword extends PureComponent { ); }; - /** - * Returns current vault seed phrase - * It does it using an empty password or a password set by the user - * depending on the state the app is currently in - */ - getSeedPhrase = async () => { - const { KeyringController } = Engine.context; - const { originalPassword } = this.state; - const keychainPassword = originalPassword; - const mnemonic = await KeyringController.exportSeedPhrase( - keychainPassword, - ).toString(); - return JSON.stringify(mnemonic).replace(/"/g, ''); - }; - jumpToConfirmPassword = () => { const { current } = this.confirmPasswordInput; current && current.focus(); diff --git a/app/components/Views/RevealPrivateCredential/RevealPrivateCredential.tsx b/app/components/Views/RevealPrivateCredential/RevealPrivateCredential.tsx index ff878c4fa54..691ff5bd3e3 100644 --- a/app/components/Views/RevealPrivateCredential/RevealPrivateCredential.tsx +++ b/app/components/Views/RevealPrivateCredential/RevealPrivateCredential.tsx @@ -10,13 +10,14 @@ import { View, } from 'react-native'; import { useDispatch, useSelector } from 'react-redux'; -import AsyncStorage from '../../../store/async-storage-wrapper'; +import { wordlist } from '@metamask/scure-bip39/dist/wordlists/english'; import QRCode from 'react-native-qrcode-svg'; import ScrollableTabView, { DefaultTabBar, } from 'react-native-scrollable-tab-view'; const CustomTabView = View as any; import Icon from 'react-native-vector-icons/FontAwesome5'; +import AsyncStorage from '../../../store/async-storage-wrapper'; import ActionView from '../../UI/ActionView'; import ButtonReveal from '../../UI/ButtonReveal'; import Button, { @@ -39,6 +40,8 @@ import Engine from '../../../core/Engine'; import { BIOMETRY_CHOICE } from '../../../constants/storage'; import { MetaMetricsEvents } from '../../../core/Analytics'; import AnalyticsV2 from '../../../util/analyticsV2'; +import { uint8ArrayToMnemonic } from '../../../util/mnemonic'; +import { passwordRequirementsMet } from '../../../util/password'; import { Authentication } from '../../../core/'; import Device from '../../../util/device'; @@ -123,10 +126,8 @@ const RevealPrivateCredential = ({ try { let privateCredential; if (!isPrivateKeyReveal) { - const mnemonic = await KeyringController.exportSeedPhrase( - pswd, - ).toString(); - privateCredential = JSON.stringify(mnemonic).replace(/"/g, ''); + const uint8ArraySeed = await KeyringController.exportSeedPhrase(pswd); + privateCredential = uint8ArrayToMnemonic(uint8ArraySeed, wordlist); } else { privateCredential = await KeyringController.exportAccount( pswd, @@ -204,20 +205,23 @@ const RevealPrivateCredential = ({ navigateBack(); }; - const tryUnlock = () => { + const tryUnlock = async () => { const { KeyringController } = Engine.context as any; - if (KeyringController.validatePassword(password)) { - if (!isPrivateKey) { - const currentDate = new Date(); - dispatch(recordSRPRevealTimestamp(currentDate.toString())); - AnalyticsV2.trackEvent(MetaMetricsEvents.NEXT_REVEAL_SRP_CTA, {}); - } - setIsModalVisible(true); - setWarningIncorrectPassword(''); - } else { + try { + await KeyringController.verifyPassword(password); + } catch { const msg = strings('reveal_credential.warning_incorrect_password'); setWarningIncorrectPassword(msg); + return; } + + if (!isPrivateKey) { + const currentDate = new Date(); + dispatch(recordSRPRevealTimestamp(currentDate.toString())); + AnalyticsV2.trackEvent(MetaMetricsEvents.NEXT_REVEAL_SRP_CTA, {}); + } + setIsModalVisible(true); + setWarningIncorrectPassword(''); }; const onPasswordChange = (pswd: string) => { @@ -410,11 +414,6 @@ const RevealPrivateCredential = ({ setIsModalVisible(false); }; - const enableNextButton = () => { - const { KeyringController } = Engine.context as any; - return KeyringController.validatePassword(password); - }; - const renderModal = ( isPrivateKeyReveal: boolean, privCredentialName: string, @@ -533,7 +532,7 @@ const RevealPrivateCredential = ({ onCancelPress={unlocked ? done : cancelReveal} onConfirmPress={() => tryUnlock()} showConfirmButton={!unlocked} - confirmDisabled={!enableNextButton()} + confirmDisabled={!passwordRequirementsMet(password)} cancelTestID={SECRET_RECOVERY_PHRASE_CANCEL_BUTTON_ID} confirmTestID={SECRET_RECOVERY_PHRASE_NEXT_BUTTON_ID} > diff --git a/app/core/AppConstants.ts b/app/core/AppConstants.ts index 1945646fa80..dd642059a8f 100644 --- a/app/core/AppConstants.ts +++ b/app/core/AppConstants.ts @@ -151,6 +151,7 @@ export default { CANCEL_RATE: 'Transactions (Cancel)', SPEED_UP_RATE: 'Transactions (Speed Up)', NETWORK_STATE_CHANGE_EVENT: 'NetworkController:stateChange', + KEYRING_STATE_CHANGE_EVENT: 'KeyringController:stateChange', ETH_SIGN_ERROR: 'eth_sign requires 32 byte message hash', TERMS_OF_USE: { TERMS_DISPLAYED: 'ToU Displayed', diff --git a/app/core/BackgroundBridge/BackgroundBridge.js b/app/core/BackgroundBridge/BackgroundBridge.js index 7ba903dc0f5..fcc1ab99cae 100644 --- a/app/core/BackgroundBridge/BackgroundBridge.js +++ b/app/core/BackgroundBridge/BackgroundBridge.js @@ -92,8 +92,14 @@ export class BackgroundBridge extends EventEmitter { ); Engine.context.PreferencesController.subscribe(this.sendStateUpdate); - Engine.context.KeyringController.onLock(this.onLock.bind(this)); - Engine.context.KeyringController.onUnlock(this.onUnlock.bind(this)); + Engine.controllerMessenger.subscribe( + 'KeyringController:lock', + this.onLock.bind(this), + ); + Engine.controllerMessenger.subscribe( + 'KeyringController:unlock', + this.onUnlock.bind(this), + ); this.on('update', this.onStateUpdate); diff --git a/app/core/BackupVault/backupVault.ts b/app/core/BackupVault/backupVault.ts index 87a0cce5283..f5d837385c6 100644 --- a/app/core/BackupVault/backupVault.ts +++ b/app/core/BackupVault/backupVault.ts @@ -1,4 +1,4 @@ -import { KeyringState } from '@metamask/keyring-controller'; +import { KeyringControllerState } from '@metamask/keyring-controller'; import Logger from '../../util/Logger'; import { getInternetCredentials, @@ -35,7 +35,7 @@ interface KeyringBackupResponse { } */ export async function backupVault( - keyringState: KeyringState, + keyringState: KeyringControllerState, ): Promise { if (keyringState.vault) { const backupResult = await setInternetCredentials( diff --git a/app/core/Engine.ts b/app/core/Engine.ts index 083dea988ee..f7d325025c9 100644 --- a/app/core/Engine.ts +++ b/app/core/Engine.ts @@ -30,8 +30,10 @@ import { BaseState, ControllerMessenger } from '@metamask/base-controller'; import { ComposableController } from '@metamask/composable-controller'; import { KeyringController, - KeyringState, SignTypedDataVersion, + KeyringControllerState, + KeyringControllerActions, + KeyringControllerEvents, } from '@metamask/keyring-controller'; import { NetworkController, @@ -125,7 +127,8 @@ type GlobalActions = | GetTokenListState | NetworkControllerActions | PermissionControllerActions - | SignatureControllerActions; + | SignatureControllerActions + | KeyringControllerActions; type GlobalEvents = | ApprovalControllerEvents | CurrencyRateStateChange @@ -133,7 +136,8 @@ type GlobalEvents = | TokenListStateChange | NetworkControllerEvents | PermissionControllerEvents - | SignatureControllerEvents; + | SignatureControllerEvents + | KeyringControllerEvents; type PermissionsByRpcMethod = ReturnType; type Permissions = PermissionsByRpcMethod[keyof PermissionsByRpcMethod]; @@ -145,7 +149,7 @@ export interface EngineState { NftController: NftState; TokenListController: TokenListState; CurrencyRateController: CurrencyRateState; - KeyringController: KeyringState; + KeyringController: KeyringControllerState; NetworkController: NetworkState; PreferencesController: PreferencesState; PhishingController: PhishingState; @@ -221,7 +225,7 @@ class Engine { // eslint-disable-next-line @typescript-eslint/default-param-last constructor( initialState: Partial = {}, - initialKeyringState?: KeyringState | null, + initialKeyringState?: KeyringControllerState | null, ) { this.controllerMessenger = new ControllerMessenger(); @@ -391,8 +395,6 @@ class Engine { const phishingController = new PhishingController(); phishingController.maybeUpdateState(); - const additionalKeyrings = [QRHardwareKeyring]; - const getIdentities = () => { const identities = preferencesController.state.identities; const lowerCasedIdentities: PreferencesState['identities'] = {}; @@ -402,29 +404,40 @@ class Engine { return lowerCasedIdentities; }; - const keyringState = initialKeyringState || initialState.KeyringController; + const qrKeyringBuilder = () => new QRHardwareKeyring(); + qrKeyringBuilder.type = QRHardwareKeyring.type; - const keyringController = new KeyringController( - { - removeIdentity: preferencesController.removeIdentity.bind( - preferencesController, - ), - syncIdentities: preferencesController.syncIdentities.bind( - preferencesController, - ), - updateIdentities: preferencesController.updateIdentities.bind( - preferencesController, - ), - setSelectedAddress: preferencesController.setSelectedAddress.bind( - preferencesController, - ), - setAccountLabel: preferencesController.setAccountLabel.bind( - preferencesController, - ), - }, - { encryptor, keyringTypes: additionalKeyrings }, - keyringState, - ); + const keyringController = new KeyringController({ + removeIdentity: preferencesController.removeIdentity.bind( + preferencesController, + ), + syncIdentities: preferencesController.syncIdentities.bind( + preferencesController, + ), + updateIdentities: preferencesController.updateIdentities.bind( + preferencesController, + ), + setSelectedAddress: preferencesController.setSelectedAddress.bind( + preferencesController, + ), + setAccountLabel: preferencesController.setAccountLabel.bind( + preferencesController, + ), + encryptor, + // @ts-expect-error Error might be caused by base controller version mismatch + messenger: this.controllerMessenger.getRestricted({ + name: 'KeyringController', + allowedEvents: [ + 'KeyringController:lock', + 'KeyringController:unlock', + 'KeyringController:stateChange', + 'KeyringController:accountRemoved', + ], + allowedActions: ['KeyringController:getState'], + }), + state: initialKeyringState || initialState.KeyringController, + keyringBuilders: [qrKeyringBuilder], + }); const controllers = [ keyringController, @@ -618,7 +631,6 @@ class Engine { keyringController.signPersonalMessage.bind(keyringController), signTypedMessage: (msgParams, { version }) => keyringController.signTypedMessage( - // @ts-expect-error Error might be caused by base controller version mismatch msgParams, version as SignTypedDataVersion, ), @@ -729,19 +741,20 @@ class Engine { } handleVaultBackup() { - const { KeyringController } = this.context; - KeyringController.subscribe((state: any) => - backupVault(state) - .then((result) => { - if (result.success) { - Logger.log('Engine', 'Vault back up successful'); - } else { - Logger.log('Engine', 'Vault backup failed', result.error); - } - }) - .catch((error) => { - Logger.error(error, 'Engine Vault backup failed'); - }), + this.controllerMessenger.subscribe( + AppConstants.KEYRING_STATE_CHANGE_EVENT, + (state: KeyringControllerState) => + backupVault(state) + .then((result) => { + if (result.success) { + Logger.log('Engine', 'Vault back up successful'); + } else { + Logger.log('Engine', 'Vault backup failed', result.error); + } + }) + .catch((error) => { + Logger.error(error, 'Engine Vault backup failed'); + }), ); } diff --git a/app/core/EngineService/EngineService.ts b/app/core/EngineService/EngineService.ts index 4d4ef985705..61847333cd3 100644 --- a/app/core/EngineService/EngineService.ts +++ b/app/core/EngineService/EngineService.ts @@ -42,7 +42,10 @@ class EngineService { { name: 'TokensController' }, { name: 'TokenDetectionController' }, { name: 'NftDetectionController' }, - { name: 'KeyringController' }, + { + name: 'KeyringController', + key: `${engine.context.KeyringController.name}:stateChange`, + }, { name: 'AccountTrackerController' }, { name: 'NetworkController', diff --git a/app/core/Vault.js b/app/core/Vault.js index 615b1bd0925..9cf4876fd23 100644 --- a/app/core/Vault.js +++ b/app/core/Vault.js @@ -10,10 +10,7 @@ import { KeyringTypes } from '@metamask/keyring-controller'; */ export const getSeedPhrase = async (password = '') => { const { KeyringController } = Engine.context; - const mnemonic = await KeyringController.exportSeedPhrase( - password, - ).toString(); - return JSON.stringify(mnemonic).replace(/"/g, ''); + return await KeyringController.exportSeedPhrase(password); }; /** diff --git a/app/selectors/types.ts b/app/selectors/types.ts index 87cd6e6a6d9..669f094d234 100644 --- a/app/selectors/types.ts +++ b/app/selectors/types.ts @@ -13,7 +13,7 @@ import SwapsController from '@metamask/swaps-controller'; import { NetworkState } from '@metamask/network-controller'; import { AddressBookState } from '@metamask/address-book-controller'; import { BaseState } from '@metamask/base-controller'; -import { KeyringMemState } from '@metamask/keyring-controller'; +import { KeyringControllerMemState } from '@metamask/keyring-controller'; import { PreferencesState } from '@metamask/preferences-controller'; import { PhishingState } from '@metamask/phishing-controller'; import { TransactionState } from '@metamask/transaction-controller'; @@ -30,7 +30,7 @@ export interface EngineState { NftController: NftState; TokenListController: TokenListState; CurrencyRateController: CurrencyRateState; - KeyringController: KeyringMemState; + KeyringController: KeyringControllerMemState; NetworkController: NetworkState; PreferencesController: PreferencesState; PhishingController: PhishingState; diff --git a/app/util/SRP/index.test.ts b/app/util/SRP/index.test.ts deleted file mode 100644 index 0fef7767453..00000000000 --- a/app/util/SRP/index.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { shuffle, compareSRPs } from './onboarding'; - -const mockSRPArrayOne = [ - 'ar9gx', - 'e97vw', - '95wx4', - 'c93d1', - 'zdiai', - 'h07an', - '78eld', - 'snqx8', - '1o472', - 'ixpwq', - 'p31fg', - 'vfnfy', -]; - -const mockSRPArrayTwo = [ - 'r6rrh', - 'ujfkr', - 'n8n0h', - '9fsgb', - 'obyjo', - 'a8wnk', - 'eqcnj', - '4e55t', - '170tl', - 'uur4s', - '4wf4g', - '242lz', -]; - -describe('SRP::onboarding::shuffle', () => { - it('should shuffle the array', () => { - expect(mockSRPArrayOne.join('')).not.toEqual( - shuffle(mockSRPArrayOne).join(''), - ); - }); -}); - -describe('SRP::onboarding::compareSRPs', () => { - it('should return false', () => { - expect(compareSRPs(mockSRPArrayOne, mockSRPArrayTwo)).toBe(false); - }); - it('should return true', () => { - expect(compareSRPs(mockSRPArrayOne, mockSRPArrayOne)).toBe(true); - }); -}); diff --git a/app/util/SRP/index.ts b/app/util/SRP/index.ts deleted file mode 100644 index 2970198f4c8..00000000000 --- a/app/util/SRP/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { shuffle, compareSRPs } from './onboarding'; - -export { shuffle, compareSRPs }; diff --git a/app/util/SRP/onboarding.ts b/app/util/SRP/onboarding.ts deleted file mode 100644 index cbbb469f079..00000000000 --- a/app/util/SRP/onboarding.ts +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Method to shuffles an array of string. - * - * The previous method was replaced according to the following tutorial. - * https://javascript.info/array-methods#shuffle-an-array - * - * @param array - Array of string. - * @returns Array of string. - */ -// eslint-disable-next-line import/prefer-default-export -export const shuffle = (array: string[]): string[] => { - const shuffledArray = [...array]; - for (let i = array.length - 1; i > 0; i--) { - const j = Math.floor(Math.random() * (i + 1)); - - // Swap elements. - [shuffledArray[i], shuffledArray[j]] = [shuffledArray[j], shuffledArray[i]]; - } - return shuffledArray; -}; - -/** - * Compare two SRP arrays. - * @param validSRP - Array of string with the correct SRP. - * @param input - Array of string with the user's input. - * @returns Boolean indicating with the input matches the valid SRP. - */ -export const compareSRPs = (validSRP: string[], input: string[]): boolean => - validSRP.join('') === input.join(''); diff --git a/app/util/mnemonic/index.test.ts b/app/util/mnemonic/index.test.ts new file mode 100644 index 00000000000..8d2749e8fc6 --- /dev/null +++ b/app/util/mnemonic/index.test.ts @@ -0,0 +1,81 @@ +import { shuffle, compareMnemonics, uint8ArrayToMnemonic } from '.'; + +const mockSRPArrayOne = [ + 'ar9gx', + 'e97vw', + '95wx4', + 'c93d1', + 'zdiai', + 'h07an', + '78eld', + 'snqx8', + '1o472', + 'ixpwq', + 'p31fg', + 'vfnfy', +]; + +const mockSRPArrayTwo = [ + 'r6rrh', + 'ujfkr', + 'n8n0h', + '9fsgb', + 'obyjo', + 'a8wnk', + 'eqcnj', + '4e55t', + '170tl', + 'uur4s', + '4wf4g', + '242lz', +]; + +describe('mnemonic::shuffle', () => { + it('should shuffle the array', () => { + expect(mockSRPArrayOne.join('')).not.toEqual( + shuffle(mockSRPArrayOne).join(''), + ); + }); +}); + +describe('mnemonic::compareMnemonics', () => { + it('should return false', () => { + expect(compareMnemonics(mockSRPArrayOne, mockSRPArrayTwo)).toBe(false); + }); + it('should return true', () => { + expect(compareMnemonics(mockSRPArrayOne, mockSRPArrayOne)).toBe(true); + }); +}); + +describe('mnemonic::uint8ArrayToMnemonic', () => { + const mockWordlist = [ + 'apple', + 'banana', + 'carrot', + 'dog', + 'elephant', + 'fox', + 'grape', + 'horse', + 'abandon', + 'jellyfish', + ]; + + it('should convert a Uint8Array to a seed phrase', () => { + const uint8Array = new Uint8Array([ + 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0, + ]); + const expectedOutput = + 'apple banana carrot dog elephant fox grape horse abandon jellyfish'; + + const result = uint8ArrayToMnemonic(uint8Array, mockWordlist); + + expect(result).toEqual(expectedOutput); + }); + + it('should handle an empty Uint8Array', () => { + expect(() => + uint8ArrayToMnemonic(new Uint8Array([]), mockWordlist), + ).toThrow('The method uint8ArrayToMnemonic expects a non-empty array'); + }); +}); diff --git a/app/util/mnemonic/index.ts b/app/util/mnemonic/index.ts new file mode 100644 index 00000000000..6717144e728 --- /dev/null +++ b/app/util/mnemonic/index.ts @@ -0,0 +1,54 @@ +/** + * Method to shuffles an array of string. + * + * The previous method was replaced according to the following tutorial. + * https://javascript.info/array-methods#shuffle-an-array + * + * @param array - Array of string. + * @returns Array of string. + */ +// eslint-disable-next-line import/prefer-default-export +export const shuffle = (array: string[]): string[] => { + const shuffledArray = [...array]; + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + + // Swap elements. + [shuffledArray[i], shuffledArray[j]] = [shuffledArray[j], shuffledArray[i]]; + } + return shuffledArray; +}; + +/** + * Compare two mnemonics arrays. + * @param validMnemonic - Array of string with the correct SRP. + * @param input - Array of string with the user's input. + * @returns Boolean indicating with the input matches the valid SRP. + */ +export const compareMnemonics = ( + validMnemonic: string[], + input: string[], +): boolean => validMnemonic.join('') === input.join(''); + +/** + * Transform a typed array containing mnemonic data to the seed phrase. + * @param uint8Array - Typed array containing mnemonic data. + * @param wordlist - BIP-39 wordlist. + * @returns The seed phrase. + */ +export const uint8ArrayToMnemonic = ( + uint8Array: Uint8Array, + wordlist: string[], +): string => { + if (uint8Array.length === 0) { + throw new Error( + 'The method uint8ArrayToMnemonic expects a non-empty array', + ); + } + + const recoveredIndices = Array.from( + new Uint16Array(new Uint8Array(uint8Array).buffer), + ); + + return recoveredIndices.map((i) => wordlist[i]).join(' '); +}; diff --git a/app/util/test/initial-background-state.json b/app/util/test/initial-background-state.json index 3f10767c518..44fdd7dca3f 100644 --- a/app/util/test/initial-background-state.json +++ b/app/util/test/initial-background-state.json @@ -1,5 +1,7 @@ { "KeyringController": { + "isUnlocked": false, + "keyringTypes": [], "keyrings": [] }, "AccountTrackerController": { diff --git a/package.json b/package.json index ef425f27f59..6f602379902 100644 --- a/package.json +++ b/package.json @@ -169,12 +169,13 @@ "@metamask/eth-sig-util": "^4.0.1", "@metamask/etherscan-link": "^2.0.0", "@metamask/gas-fee-controller": "^4.0.0", - "@metamask/keyring-controller": "^1.0.1", + "@metamask/keyring-controller": "^6.0.0", "@metamask/network-controller": "^7.0.0", "@metamask/permission-controller": "^4.0.1", "@metamask/phishing-controller": "^3.0.0", "@metamask/ppom-validator": "^0.3.0", "@metamask/preferences-controller": "^3.0.0", + "@metamask/scure-bip39": "^2.1.0", "@metamask/sdk-communication-layer": "^0.5.0", "@metamask/signature-controller": "4.0.1", "@metamask/swappable-obj-proxy": "^2.1.0", @@ -554,7 +555,9 @@ "ganache>utf-8-validate": false, "wdio-image-comparison-service>webdriver-image-comparison>canvas": false, "appium-adb>@appium/support>sharp": true, - "react-native-svg-asset-plugin>sharp": true + "react-native-svg-asset-plugin>sharp": true, + "@metamask/keyring-controller>@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring>@ethereumjs/tx>ethereumjs-util>ethereum-cryptography>keccak": false, + "@metamask/keyring-controller>@keystonehq/metamask-airgapped-keyring>@keystonehq/base-eth-keyring>@ethereumjs/tx>ethereumjs-util>ethereum-cryptography>secp256k1": false } } } diff --git a/patches/@metamask+keyring-controller++@metamask+message-manager+7.3.1.patch b/patches/@metamask+keyring-controller++@metamask+message-manager+7.3.1.patch new file mode 100644 index 00000000000..005acdccd60 --- /dev/null +++ b/patches/@metamask+keyring-controller++@metamask+message-manager+7.3.1.patch @@ -0,0 +1,37 @@ +diff --git a/node_modules/@metamask/keyring-controller/node_modules/@metamask/message-manager/dist/PersonalMessageManager.d.ts b/node_modules/@metamask/keyring-controller/node_modules/@metamask/message-manager/dist/PersonalMessageManager.d.ts +index 5bf0005..2702abd 100644 +--- a/node_modules/@metamask/keyring-controller/node_modules/@metamask/message-manager/dist/PersonalMessageManager.d.ts ++++ b/node_modules/@metamask/keyring-controller/node_modules/@metamask/message-manager/dist/PersonalMessageManager.d.ts +@@ -25,7 +25,31 @@ export interface PersonalMessage extends AbstractMessage { + */ + export interface PersonalMessageParams extends AbstractMessageParams { + data: string; +- siwe?: SIWEMessage; ++ /** ++ * ============================== PATCH INFORMATION ============================== ++ * This patch addresses a type error that was introduced in ++ * @metamask+message-manager+7.0.1.patch. The error is triggered when a message is ++ * not a valid SIWE message. The patch modifies the data type as follows, ++ * ++ * Previous data type: ++ * ```ts ++ * siwe?: SIWEMessage; ++ * ``` ++ * ++ * Current data type introduced in @metamask+message-manager+7.0.1.patch: ++ * ```ts ++ * siwe?: { ++ * isSIWEMessage: boolean; ++ * parsedMessage: null; ++ * }; ++ * ``` ++ * ++ * =============================================================================== ++ */ ++ siwe?: { ++ isSIWEMessage: boolean; ++ parsedMessage: null; ++ }; + } + /** + * @type MessageParamsMetamask diff --git a/patches/@metamask+keyring-controller+1.0.1.patch b/patches/@metamask+keyring-controller+1.0.1.patch deleted file mode 100644 index 601eb60d0bf..00000000000 --- a/patches/@metamask+keyring-controller+1.0.1.patch +++ /dev/null @@ -1,80 +0,0 @@ -diff --git a/node_modules/@metamask/keyring-controller/dist/KeyringController.js b/node_modules/@metamask/keyring-controller/dist/KeyringController.js -index a5e5af1..e2dbbd2 100644 ---- a/node_modules/@metamask/keyring-controller/dist/KeyringController.js -+++ b/node_modules/@metamask/keyring-controller/dist/KeyringController.js -@@ -125,6 +125,7 @@ class KeyringController extends base_controller_1.BaseController { - } - /** - * Adds a new account to the default (first) HD seed phrase keyring. -+ * Patched to not auto switch accounts. - * - * @returns Promise resolving to current state when the account is added. - */ -@@ -140,12 +141,13 @@ class KeyringController extends base_controller_1.BaseController { - const newAccounts = yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").getAccounts(); - yield this.verifySeedPhrase(); - this.updateIdentities(newAccounts); -+ let addedAccountAddress = ''; - newAccounts.forEach((selectedAddress) => { - if (!oldAccounts.includes(selectedAddress)) { -- this.setSelectedAddress(selectedAddress); -+ addedAccountAddress = selectedAddress - } - }); -- return this.fullUpdate(); -+ return { addedAccountAddress, keyringState: this.fullUpdate() }; - }); - } - /** -@@ -313,8 +315,8 @@ class KeyringController extends base_controller_1.BaseController { - const accounts = yield newKeyring.getAccounts(); - const allAccounts = yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").getAccounts(); - this.updateIdentities(allAccounts); -- this.setSelectedAddress(accounts[0]); -- return this.fullUpdate(); -+ const importedAccountAddress = accounts[0]; -+ return { importedAccountAddress, keyringState: this.fullUpdate() }; - }); - } - /** -@@ -615,16 +617,19 @@ class KeyringController extends base_controller_1.BaseController { - yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").addNewAccount(keyring); - const newAccounts = yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").getAccounts(); - this.updateIdentities(newAccounts); -+ let newHardwareWalletAddress = ''; - newAccounts.forEach((address) => { - if (!oldAccounts.includes(address)) { - if (this.setAccountLabel) { - this.setAccountLabel(address, `${keyring.getName()} ${index}`); - } -- this.setSelectedAddress(address); -+ newHardwareWalletAddress = address; - } - }); - yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").persistAllKeyrings(); - yield this.fullUpdate(); -+ // Return address of hardware wallet address that was created. -+ return newHardwareWalletAddress; - }); - } - getAccountKeyringType(account) { -@@ -635,13 +640,15 @@ class KeyringController extends base_controller_1.BaseController { - forgetQRDevice() { - return __awaiter(this, void 0, void 0, function* () { - const keyring = yield this.getOrAddQRKeyring(); -+ const accountsIncludingHardware = (yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").getAccounts()); - keyring.forgetDevice(); -- const accounts = (yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").getAccounts()); -- accounts.forEach((account) => { -- this.setSelectedAddress(account); -- }); -+ const remainingAccounts = (yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").getAccounts()); -+ const removedAccounts = accountsIncludingHardware.filter((address) => !remainingAccounts.includes(address)); -+ this.updateIdentities(remainingAccounts); - yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").persistAllKeyrings(); - yield this.fullUpdate(); -+ // Return list of removed accounts as well as remaining accounts for the app to use. -+ return { removedAccounts, remainingAccounts }; - }); - } - } diff --git a/patches/@metamask+keyring-controller+6.1.0.patch b/patches/@metamask+keyring-controller+6.1.0.patch new file mode 100644 index 00000000000..839e8536306 --- /dev/null +++ b/patches/@metamask+keyring-controller+6.1.0.patch @@ -0,0 +1,30 @@ +diff --git a/node_modules/@metamask/keyring-controller/dist/KeyringController.js b/node_modules/@metamask/keyring-controller/dist/KeyringController.js +index c905cc0..f670fd3 100644 +--- a/node_modules/@metamask/keyring-controller/dist/KeyringController.js ++++ b/node_modules/@metamask/keyring-controller/dist/KeyringController.js +@@ -678,13 +678,21 @@ class KeyringController extends base_controller_1.BaseControllerV2 { + } + forgetQRDevice() { + return __awaiter(this, void 0, void 0, function* () { ++ /** ++ * ============================== PATCH INFORMATION ============================== ++ * This patch addresses an issue regarding the forget device functionality. It ++ * improves the logic to correctly remove the QR accounts and update the ++ * identities as needed. ++ * =============================================================================== ++ */ + const keyring = yield this.getOrAddQRKeyring(); ++ const allAccounts = (yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").getAccounts()); + keyring.forgetDevice(); +- const accounts = (yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").getAccounts()); +- accounts.forEach((account) => { +- this.setSelectedAddress(account); +- }); ++ const remainingAccounts = (yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").getAccounts()); ++ const removedAccounts = allAccounts.filter((address) => !remainingAccounts.includes(address)); ++ this.updateIdentities(remainingAccounts); + yield __classPrivateFieldGet(this, _KeyringController_keyring, "f").persistAllKeyrings(); ++ return { removedAccounts, remainingAccounts }; + }); + } + } diff --git a/patches/@metamask+message-manager+1.0.1.patch b/patches/@metamask+message-manager+1.0.1.patch deleted file mode 100644 index 8a690643b3e..00000000000 --- a/patches/@metamask+message-manager+1.0.1.patch +++ /dev/null @@ -1,36 +0,0 @@ -diff --git a/node_modules/@metamask/message-manager/dist/MessageManager.js b/node_modules/@metamask/message-manager/dist/MessageManager.js -index e7c5d99..11948f9 100644 ---- a/node_modules/@metamask/message-manager/dist/MessageManager.js -+++ b/node_modules/@metamask/message-manager/dist/MessageManager.js -@@ -58,6 +58,7 @@ class MessageManager extends AbstractMessageManager_1.AbstractMessageManager { - const messageData = { - id: messageId, - messageParams, -+ securityAlertResponse: req?.securityAlertResponse, - status: 'unapproved', - time: Date.now(), - type: 'eth_sign', -diff --git a/node_modules/@metamask/message-manager/dist/PersonalMessageManager.js b/node_modules/@metamask/message-manager/dist/PersonalMessageManager.js -index 036bd3b..c9bd117 100644 ---- a/node_modules/@metamask/message-manager/dist/PersonalMessageManager.js -+++ b/node_modules/@metamask/message-manager/dist/PersonalMessageManager.js -@@ -58,6 +58,7 @@ class PersonalMessageManager extends AbstractMessageManager_1.AbstractMessageMan - const messageData = { - id: messageId, - messageParams, -+ securityAlertResponse: req?.securityAlertResponse, - status: 'unapproved', - time: Date.now(), - type: 'personal_sign', -diff --git a/node_modules/@metamask/message-manager/dist/TypedMessageManager.js b/node_modules/@metamask/message-manager/dist/TypedMessageManager.js -index e4b1aa3..f3abc5d 100644 ---- a/node_modules/@metamask/message-manager/dist/TypedMessageManager.js -+++ b/node_modules/@metamask/message-manager/dist/TypedMessageManager.js -@@ -67,6 +67,7 @@ class TypedMessageManager extends AbstractMessageManager_1.AbstractMessageManage - const messageData = { - id: messageId, - messageParams, -+ securityAlertResponse: req?.securityAlertResponse, - status: 'unapproved', - time: Date.now(), - type: 'eth_signTypedData', diff --git a/patches/@metamask+signature-controller++@metamask+message-manager+7.0.1.patch b/patches/@metamask+message-manager+7.0.1.patch similarity index 82% rename from patches/@metamask+signature-controller++@metamask+message-manager+7.0.1.patch rename to patches/@metamask+message-manager+7.0.1.patch index ea97e5de935..07bb2bf13b7 100644 --- a/patches/@metamask+signature-controller++@metamask+message-manager+7.0.1.patch +++ b/patches/@metamask+message-manager+7.0.1.patch @@ -1,10 +1,19 @@ -diff --git a/node_modules/@metamask/signature-controller/node_modules/@metamask/message-manager/dist/.DS_Store b/node_modules/@metamask/signature-controller/node_modules/@metamask/message-manager/dist/.DS_Store -new file mode 100644 -index 0000000..e69de29 -diff --git a/node_modules/@metamask/signature-controller/node_modules/@metamask/message-manager/dist/PersonalMessageManager.d.ts b/node_modules/@metamask/signature-controller/node_modules/@metamask/message-manager/dist/PersonalMessageManager.d.ts +diff --git a/node_modules/@metamask/message-manager/dist/MessageManager.js b/node_modules/@metamask/message-manager/dist/MessageManager.js +index 89fcd8f..717ed56 100644 +--- a/node_modules/@metamask/message-manager/dist/MessageManager.js ++++ b/node_modules/@metamask/message-manager/dist/MessageManager.js +@@ -45,6 +45,7 @@ class MessageManager extends AbstractMessageManager_1.AbstractMessageManager { + const messageData = { + id: messageId, + messageParams, ++ securityAlertResponse: req?.securityAlertResponse, + status: 'unapproved', + time: Date.now(), + type: 'eth_sign', +diff --git a/node_modules/@metamask/message-manager/dist/PersonalMessageManager.d.ts b/node_modules/@metamask/message-manager/dist/PersonalMessageManager.d.ts index 078af88..0675794 100644 ---- a/node_modules/@metamask/signature-controller/node_modules/@metamask/message-manager/dist/PersonalMessageManager.d.ts -+++ b/node_modules/@metamask/signature-controller/node_modules/@metamask/message-manager/dist/PersonalMessageManager.d.ts +--- a/node_modules/@metamask/message-manager/dist/PersonalMessageManager.d.ts ++++ b/node_modules/@metamask/message-manager/dist/PersonalMessageManager.d.ts @@ -1,4 +1,3 @@ -import { SIWEMessage } from '@metamask/controller-utils'; import { AbstractMessageManager, AbstractMessage, AbstractMessageParams, AbstractMessageParamsMetamask, OriginalRequest } from './AbstractMessageManager'; @@ -22,19 +31,19 @@ index 078af88..0675794 100644 } /** * @type MessageParamsMetamask -diff --git a/node_modules/@metamask/signature-controller/node_modules/@metamask/message-manager/dist/PersonalMessageManager.d.ts.map b/node_modules/@metamask/signature-controller/node_modules/@metamask/message-manager/dist/PersonalMessageManager.d.ts.map +diff --git a/node_modules/@metamask/message-manager/dist/PersonalMessageManager.d.ts.map b/node_modules/@metamask/message-manager/dist/PersonalMessageManager.d.ts.map index ab04adc..52e6b44 100644 ---- a/node_modules/@metamask/signature-controller/node_modules/@metamask/message-manager/dist/PersonalMessageManager.d.ts.map -+++ b/node_modules/@metamask/signature-controller/node_modules/@metamask/message-manager/dist/PersonalMessageManager.d.ts.map +--- a/node_modules/@metamask/message-manager/dist/PersonalMessageManager.d.ts.map ++++ b/node_modules/@metamask/message-manager/dist/PersonalMessageManager.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"PersonalMessageManager.d.ts","sourceRoot":"","sources":["../src/PersonalMessageManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAErE,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,qBAAqB,EACrB,6BAA6B,EAC7B,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAElC;;;;;;;;;;GAUG;AACH,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,aAAa,EAAE,qBAAqB,CAAC;CACtC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAsB,SAAQ,qBAAqB;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,6BACf,SAAQ,6BAA6B;IACrC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,sBAAsB,CAChE,eAAe,EACf,qBAAqB,EACrB,6BAA6B,CAC9B;IACC;;OAEG;IACM,IAAI,SAA4B;IAEzC;;;;;;;;;OASG;IACG,oBAAoB,CACxB,aAAa,EAAE,qBAAqB,EACpC,GAAG,CAAC,EAAE,eAAe,GACpB,OAAO,CAAC,MAAM,CAAC;IA0BlB;;;;;;OAMG;IACH,qBAAqB,CACnB,aAAa,EAAE,6BAA6B,GAC3C,OAAO,CAAC,qBAAqB,CAAC;CAIlC;AAED,eAAe,sBAAsB,CAAC"} \ No newline at end of file +{"version":3,"file":"PersonalMessageManager.d.ts","sourceRoot":"","sources":["../src/PersonalMessageManager.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,qBAAqB,EACrB,6BAA6B,EAC7B,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAElC;;;;;;;;;;GAUG;AACH,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,aAAa,EAAE,qBAAqB,CAAC;CACtC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAsB,SAAQ,qBAAqB;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE;QACL,aAAa,EAAE,OAAO,CAAC;QACvB,aAAa,EAAE,IAAI,CAAC;KACrB,CAAC;CACH;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,6BACf,SAAQ,6BAA6B;IACrC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,sBAAsB,CAChE,eAAe,EACf,qBAAqB,EACrB,6BAA6B,CAC9B;IACC;;OAEG;IACM,IAAI,SAA4B;IAEzC;;;;;;;;;OASG;IACG,oBAAoB,CACxB,aAAa,EAAE,qBAAqB,EACpC,GAAG,CAAC,EAAE,eAAe,GACpB,OAAO,CAAC,MAAM,CAAC;IA6BlB;;;;;;OAMG;IACH,qBAAqB,CACnB,aAAa,EAAE,6BAA6B,GAC3C,OAAO,CAAC,qBAAqB,CAAC;CAIlC;AAED,eAAe,sBAAsB,CAAC"} \ No newline at end of file -diff --git a/node_modules/@metamask/signature-controller/node_modules/@metamask/message-manager/dist/PersonalMessageManager.js b/node_modules/@metamask/signature-controller/node_modules/@metamask/message-manager/dist/PersonalMessageManager.js -index 92e9b3d..0321f2e 100644 ---- a/node_modules/@metamask/signature-controller/node_modules/@metamask/message-manager/dist/PersonalMessageManager.js -+++ b/node_modules/@metamask/signature-controller/node_modules/@metamask/message-manager/dist/PersonalMessageManager.js +diff --git a/node_modules/@metamask/message-manager/dist/PersonalMessageManager.js b/node_modules/@metamask/message-manager/dist/PersonalMessageManager.js +index 92e9b3d..9145738 100644 +--- a/node_modules/@metamask/message-manager/dist/PersonalMessageManager.js ++++ b/node_modules/@metamask/message-manager/dist/PersonalMessageManager.js @@ -11,7 +11,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge Object.defineProperty(exports, "__esModule", { value: true }); exports.PersonalMessageManager = void 0; @@ -43,7 +52,7 @@ index 92e9b3d..0321f2e 100644 const utils_1 = require("./utils"); const AbstractMessageManager_1 = require("./AbstractMessageManager"); /** -@@ -42,7 +41,10 @@ class PersonalMessageManager extends AbstractMessageManager_1.AbstractMessageMan +@@ -42,12 +41,16 @@ class PersonalMessageManager extends AbstractMessageManager_1.AbstractMessageMan messageParams.origin = req.origin; } messageParams.data = (0, utils_1.normalizeMessageData)(messageParams.data); @@ -55,12 +64,30 @@ index 92e9b3d..0321f2e 100644 const finalMsgParams = Object.assign(Object.assign({}, messageParams), { siwe: ethereumSignInData }); const messageId = (0, uuid_1.v1)(); const messageData = { -diff --git a/node_modules/@metamask/signature-controller/node_modules/@metamask/message-manager/dist/PersonalMessageManager.js.map b/node_modules/@metamask/signature-controller/node_modules/@metamask/message-manager/dist/PersonalMessageManager.js.map + id: messageId, + messageParams: finalMsgParams, ++ securityAlertResponse: req?.securityAlertResponse, + status: 'unapproved', + time: Date.now(), + type: 'personal_sign', +diff --git a/node_modules/@metamask/message-manager/dist/PersonalMessageManager.js.map b/node_modules/@metamask/message-manager/dist/PersonalMessageManager.js.map index b23be96..00b1e54 100644 ---- a/node_modules/@metamask/signature-controller/node_modules/@metamask/message-manager/dist/PersonalMessageManager.js.map -+++ b/node_modules/@metamask/signature-controller/node_modules/@metamask/message-manager/dist/PersonalMessageManager.js.map +--- a/node_modules/@metamask/message-manager/dist/PersonalMessageManager.js.map ++++ b/node_modules/@metamask/message-manager/dist/PersonalMessageManager.js.map @@ -1 +1 @@ -{"version":3,"file":"PersonalMessageManager.js","sourceRoot":"","sources":["../src/PersonalMessageManager.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,+BAAoC;AACpC,iEAAqE;AACrE,mCAAwE;AACxE,qEAMkC;AA6ClC;;GAEG;AACH,MAAa,sBAAuB,SAAQ,+CAI3C;IAJD;;QAKE;;WAEG;QACM,SAAI,GAAG,wBAAwB,CAAC;IAsD3C,CAAC;IApDC;;;;;;;;;OASG;IACG,oBAAoB,CACxB,aAAoC,EACpC,GAAqB;;YAErB,IAAA,+BAAuB,EAAC,aAAa,CAAC,CAAC;YACvC,IAAI,GAAG,EAAE;gBACP,aAAa,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;aACnC;YACD,aAAa,CAAC,IAAI,GAAG,IAAA,4BAAoB,EAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAE9D,MAAM,kBAAkB,GAAG,IAAA,6BAAU,EAAC,aAAa,CAAC,CAAC;YACrD,MAAM,cAAc,mCAAQ,aAAa,KAAE,IAAI,EAAE,kBAAkB,GAAE,CAAC;YAEtE,MAAM,SAAS,GAAG,IAAA,SAAM,GAAE,CAAC;YAC3B,MAAM,WAAW,GAAoB;gBACnC,EAAE,EAAE,SAAS;gBACb,aAAa,EAAE,cAAc;gBAC7B,MAAM,EAAE,YAAY;gBACpB,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;gBAChB,IAAI,EAAE,eAAe;aACtB,CAAC;YACF,MAAM,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;YACnC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,mBAAmB,kCAC5B,cAAc,GACd,EAAE,UAAU,EAAE,SAAS,EAAE,EAC5B,CAAC;YACH,OAAO,SAAS,CAAC;QACnB,CAAC;KAAA;IAED;;;;;;OAMG;IACH,qBAAqB,CACnB,aAA4C;QAE5C,OAAO,aAAa,CAAC,UAAU,CAAC;QAChC,OAAO,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IACxC,CAAC;CACF;AA9DD,wDA8DC;AAED,kBAAe,sBAAsB,CAAC","sourcesContent":["import { v1 as random } from 'uuid';\nimport { detectSIWE, SIWEMessage } from '@metamask/controller-utils';\nimport { normalizeMessageData, validateSignMessageData } from './utils';\nimport {\n AbstractMessageManager,\n AbstractMessage,\n AbstractMessageParams,\n AbstractMessageParamsMetamask,\n OriginalRequest,\n} from './AbstractMessageManager';\n\n/**\n * @type Message\n *\n * Represents and contains data about a 'personal_sign' type signature request.\n * These are created when a signature for a personal_sign call is requested.\n * @property id - An id to track and identify the message object\n * @property messageParams - The parameters to pass to the personal_sign method once the signature request is approved\n * @property type - The json-prc signing method for which a signature request has been made.\n * A 'Message' which always has a 'personal_sign' type\n * @property rawSig - Raw data of the signature request\n */\nexport interface PersonalMessage extends AbstractMessage {\n messageParams: PersonalMessageParams;\n}\n\n/**\n * @type PersonalMessageParams\n *\n * Represents the parameters to pass to the personal_sign method once the signature request is approved.\n * @property data - A hex string conversion of the raw buffer data of the signature request\n * @property from - Address to sign this message from\n * @property origin? - Added for request origin identification\n */\nexport interface PersonalMessageParams extends AbstractMessageParams {\n data: string;\n siwe?: SIWEMessage;\n}\n\n/**\n * @type MessageParamsMetamask\n *\n * Represents the parameters to pass to the personal_sign method once the signature request is approved\n * plus data added by MetaMask.\n * @property metamaskId - Added for tracking and identification within MetaMask\n * @property data - A hex string conversion of the raw buffer data of the signature request\n * @property from - Address to sign this message from\n * @property origin? - Added for request origin identification\n */\nexport interface PersonalMessageParamsMetamask\n extends AbstractMessageParamsMetamask {\n data: string;\n}\n\n/**\n * Controller in charge of managing - storing, adding, removing, updating - Messages.\n */\nexport class PersonalMessageManager extends AbstractMessageManager<\n PersonalMessage,\n PersonalMessageParams,\n PersonalMessageParamsMetamask\n> {\n /**\n * Name of this controller used during composition\n */\n override name = 'PersonalMessageManager';\n\n /**\n * Creates a new Message with an 'unapproved' status using the passed messageParams.\n * this.addMessage is called to add the new Message to this.messages, and to save the\n * unapproved Messages.\n *\n * @param messageParams - The params for the personal_sign call to be made after the message\n * is approved.\n * @param req - The original request object possibly containing the origin.\n * @returns The id of the newly created message.\n */\n async addUnapprovedMessage(\n messageParams: PersonalMessageParams,\n req?: OriginalRequest,\n ): Promise {\n validateSignMessageData(messageParams);\n if (req) {\n messageParams.origin = req.origin;\n }\n messageParams.data = normalizeMessageData(messageParams.data);\n\n const ethereumSignInData = detectSIWE(messageParams);\n const finalMsgParams = { ...messageParams, siwe: ethereumSignInData };\n\n const messageId = random();\n const messageData: PersonalMessage = {\n id: messageId,\n messageParams: finalMsgParams,\n status: 'unapproved',\n time: Date.now(),\n type: 'personal_sign',\n };\n await this.addMessage(messageData);\n this.hub.emit(`unapprovedMessage`, {\n ...finalMsgParams,\n ...{ metamaskId: messageId },\n });\n return messageId;\n }\n\n /**\n * Removes the metamaskId property from passed messageParams and returns a promise which\n * resolves the updated messageParams.\n *\n * @param messageParams - The messageParams to modify.\n * @returns Promise resolving to the messageParams with the metamaskId property removed.\n */\n prepMessageForSigning(\n messageParams: PersonalMessageParamsMetamask,\n ): Promise {\n delete messageParams.metamaskId;\n return Promise.resolve(messageParams);\n }\n}\n\nexport default PersonalMessageManager;\n"]} \ No newline at end of file +{"version":3,"file":"PersonalMessageManager.js","sourceRoot":"","sources":["../src/PersonalMessageManager.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,+BAAoC;AACpC,mCAAwE;AACxE,qEAMkC;AAgDlC;;GAEG;AACH,MAAa,sBAAuB,SAAQ,+CAI3C;IAJD;;QAKE;;WAEG;QACM,SAAI,GAAG,wBAAwB,CAAC;IAyD3C,CAAC;IAvDC;;;;;;;;;OASG;IACG,oBAAoB,CACxB,aAAoC,EACpC,GAAqB;;YAErB,IAAA,+BAAuB,EAAC,aAAa,CAAC,CAAC;YACvC,IAAI,GAAG,EAAE;gBACP,aAAa,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;aACnC;YACD,aAAa,CAAC,IAAI,GAAG,IAAA,4BAAoB,EAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAE9D,MAAM,kBAAkB,GAAG;gBACzB,aAAa,EAAE,KAAK;gBACpB,aAAa,EAAE,IAAI;aACpB,CAAA;YACD,MAAM,cAAc,mCAAQ,aAAa,KAAE,IAAI,EAAE,kBAAkB,GAAE,CAAC;YAEtE,MAAM,SAAS,GAAG,IAAA,SAAM,GAAE,CAAC;YAC3B,MAAM,WAAW,GAAoB;gBACnC,EAAE,EAAE,SAAS;gBACb,aAAa,EAAE,cAAc;gBAC7B,MAAM,EAAE,YAAY;gBACpB,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;gBAChB,IAAI,EAAE,eAAe;aACtB,CAAC;YACF,MAAM,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;YACnC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,mBAAmB,kCAC5B,cAAc,GACd,EAAE,UAAU,EAAE,SAAS,EAAE,EAC5B,CAAC;YACH,OAAO,SAAS,CAAC;QACnB,CAAC;KAAA;IAED;;;;;;OAMG;IACH,qBAAqB,CACnB,aAA4C;QAE5C,OAAO,aAAa,CAAC,UAAU,CAAC;QAChC,OAAO,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IACxC,CAAC;CACF;AAjED,wDAiEC;AAED,kBAAe,sBAAsB,CAAC","sourcesContent":["import { v1 as random } from 'uuid';\nimport { normalizeMessageData, validateSignMessageData } from './utils';\nimport {\n AbstractMessageManager,\n AbstractMessage,\n AbstractMessageParams,\n AbstractMessageParamsMetamask,\n OriginalRequest,\n} from './AbstractMessageManager';\n\n/**\n * @type Message\n *\n * Represents and contains data about a 'personal_sign' type signature request.\n * These are created when a signature for a personal_sign call is requested.\n * @property id - An id to track and identify the message object\n * @property messageParams - The parameters to pass to the personal_sign method once the signature request is approved\n * @property type - The json-prc signing method for which a signature request has been made.\n * A 'Message' which always has a 'personal_sign' type\n * @property rawSig - Raw data of the signature request\n */\nexport interface PersonalMessage extends AbstractMessage {\n messageParams: PersonalMessageParams;\n}\n\n/**\n * @type PersonalMessageParams\n *\n * Represents the parameters to pass to the personal_sign method once the signature request is approved.\n * @property data - A hex string conversion of the raw buffer data of the signature request\n * @property from - Address to sign this message from\n * @property origin? - Added for request origin identification\n */\nexport interface PersonalMessageParams extends AbstractMessageParams {\n data: string;\n siwe?: {\n isSIWEMessage: boolean,\n parsedMessage: null,\n };\n}\n\n/**\n * @type MessageParamsMetamask\n *\n * Represents the parameters to pass to the personal_sign method once the signature request is approved\n * plus data added by MetaMask.\n * @property metamaskId - Added for tracking and identification within MetaMask\n * @property data - A hex string conversion of the raw buffer data of the signature request\n * @property from - Address to sign this message from\n * @property origin? - Added for request origin identification\n */\nexport interface PersonalMessageParamsMetamask\n extends AbstractMessageParamsMetamask {\n data: string;\n}\n\n/**\n * Controller in charge of managing - storing, adding, removing, updating - Messages.\n */\nexport class PersonalMessageManager extends AbstractMessageManager<\n PersonalMessage,\n PersonalMessageParams,\n PersonalMessageParamsMetamask\n> {\n /**\n * Name of this controller used during composition\n */\n override name = 'PersonalMessageManager';\n\n /**\n * Creates a new Message with an 'unapproved' status using the passed messageParams.\n * this.addMessage is called to add the new Message to this.messages, and to save the\n * unapproved Messages.\n *\n * @param messageParams - The params for the personal_sign call to be made after the message\n * is approved.\n * @param req - The original request object possibly containing the origin.\n * @returns The id of the newly created message.\n */\n async addUnapprovedMessage(\n messageParams: PersonalMessageParams,\n req?: OriginalRequest,\n ): Promise {\n validateSignMessageData(messageParams);\n if (req) {\n messageParams.origin = req.origin;\n }\n messageParams.data = normalizeMessageData(messageParams.data);\n\n const ethereumSignInData = {\n isSIWEMessage: false,\n parsedMessage: null,\n }\n const finalMsgParams = { ...messageParams, siwe: ethereumSignInData };\n\n const messageId = random();\n const messageData: PersonalMessage = {\n id: messageId,\n messageParams: finalMsgParams,\n status: 'unapproved',\n time: Date.now(),\n type: 'personal_sign',\n };\n await this.addMessage(messageData);\n this.hub.emit(`unapprovedMessage`, {\n ...finalMsgParams,\n ...{ metamaskId: messageId },\n });\n return messageId;\n }\n\n /**\n * Removes the metamaskId property from passed messageParams and returns a promise which\n * resolves the updated messageParams.\n *\n * @param messageParams - The messageParams to modify.\n * @returns Promise resolving to the messageParams with the metamaskId property removed.\n */\n prepMessageForSigning(\n messageParams: PersonalMessageParamsMetamask,\n ): Promise {\n delete messageParams.metamaskId;\n return Promise.resolve(messageParams);\n }\n}\n\nexport default PersonalMessageManager;\n"]} \ No newline at end of file +diff --git a/node_modules/@metamask/message-manager/dist/TypedMessageManager.js b/node_modules/@metamask/message-manager/dist/TypedMessageManager.js +index d5d7e37..c0eb98b 100644 +--- a/node_modules/@metamask/message-manager/dist/TypedMessageManager.js ++++ b/node_modules/@metamask/message-manager/dist/TypedMessageManager.js +@@ -57,6 +57,7 @@ class TypedMessageManager extends AbstractMessageManager_1.AbstractMessageManage + const messageData = { + id: messageId, + messageParams, ++ securityAlertResponse: req?.securityAlertResponse, + status: 'unapproved', + time: Date.now(), + type: 'eth_signTypedData', diff --git a/patches/micro-ftch+0.3.1.patch b/patches/micro-ftch+0.3.1.patch new file mode 100644 index 00000000000..545f22c0168 --- /dev/null +++ b/patches/micro-ftch+0.3.1.patch @@ -0,0 +1,255 @@ +diff --git a/node_modules/micro-ftch/index.js b/node_modules/micro-ftch/index.js +index 7f00c3d..a4a6f79 100644 +--- a/node_modules/micro-ftch/index.js ++++ b/node_modules/micro-ftch/index.js +@@ -49,123 +49,133 @@ function detectType(b, type) { + return b; + } + let agents = {}; +-function fetchNode(url, _options) { +- let options = { ...DEFAULT_OPT, ..._options }; +- const http = require('http'); +- const https = require('https'); +- const zlib = require('zlib'); +- const { promisify } = require('util'); +- const { resolve: urlResolve } = require('url'); +- const isSecure = !!/^https/.test(url); +- let opts = { +- method: options.method || 'GET', +- headers: { 'Accept-Encoding': 'gzip, deflate, br' }, +- }; +- const compactFP = (s) => s.replace(/:| /g, '').toLowerCase(); +- if (options.keepAlive) { +- const agentOpt = { +- keepAlive: true, +- keepAliveMsecs: 30 * 1000, +- maxFreeSockets: 1024, +- maxCachedSessions: 1024, +- }; +- const agentKey = [ +- isSecure, +- isSecure && options.sslPinnedCertificates?.map((i) => compactFP(i)).sort(), +- ].join(); +- opts.agent = +- agents[agentKey] || (agents[agentKey] = new (isSecure ? https : http).Agent(agentOpt)); +- } +- if (options.type === 'json') +- opts.headers['Content-Type'] = 'application/json'; +- if (options.data) { +- if (!options.method) +- opts.method = 'POST'; +- opts.body = options.type === 'json' ? JSON.stringify(options.data) : options.data; +- } +- opts.headers = { ...opts.headers, ...options.headers }; +- if (options.sslAllowSelfSigned) +- opts.rejectUnauthorized = false; +- const handleRes = async (res) => { +- const status = res.statusCode; +- if (options.redirect && 300 <= status && status < 400 && res.headers['location']) { +- if (options._redirectCount == 10) +- throw new Error('Request failed. Too much redirects.'); +- options._redirectCount += 1; +- return await fetchNode(urlResolve(url, res.headers['location']), options); +- } +- if (options.expectStatusCode && status !== options.expectStatusCode) { +- res.resume(); +- throw new InvalidStatusCodeError(status); +- } +- let buf = []; +- for await (const chunk of res) +- buf.push(chunk); +- let bytes = Buffer.concat(buf); +- const encoding = res.headers['content-encoding']; +- if (encoding === 'br') +- bytes = await promisify(zlib.brotliDecompress)(bytes); +- if (encoding === 'gzip' || encoding === 'deflate') +- bytes = await promisify(zlib.unzip)(bytes); +- const body = detectType(bytes, options.type); +- if (options.full) +- return { headers: res.headers, status, body }; +- return body; +- }; +- return new Promise((resolve, reject) => { +- const handleError = async (err) => { +- if (err && err.code === 'DEPTH_ZERO_SELF_SIGNED_CERT') { +- try { +- await fetchNode(url, { ...options, sslAllowSelfSigned: true, sslPinnedCertificates: [] }); +- } +- catch (e) { +- if (e && e.fingerprint256) { +- err = new InvalidCertError(`Self-signed SSL certificate: ${e.fingerprint256}`, e.fingerprint256); +- } +- } +- } +- reject(err); +- }; +- const req = (isSecure ? https : http).request(url, opts, (res) => { +- res.on('error', handleError); +- (async () => { +- try { +- resolve(await handleRes(res)); +- } +- catch (error) { +- reject(error); +- } +- })(); +- }); +- req.on('error', handleError); +- const pinned = options.sslPinnedCertificates?.map((i) => compactFP(i)); +- const mfetchSecureConnect = (socket) => { +- const fp256 = compactFP(socket.getPeerCertificate()?.fingerprint256 || ''); +- if (!fp256 && socket.isSessionReused()) +- return; +- if (pinned.includes(fp256)) +- return; +- req.emit('error', new InvalidCertError(`Invalid SSL certificate: ${fp256} Expected: ${pinned}`, fp256)); +- return req.abort(); +- }; +- if (options.sslPinnedCertificates) { +- req.on('socket', (socket) => { +- const hasListeners = socket +- .listeners('secureConnect') +- .map((i) => (i.name || '').replace('bound ', '')) +- .includes('mfetchSecureConnect'); +- if (hasListeners) +- return; +- socket.on('secureConnect', mfetchSecureConnect.bind(null, socket)); +- }); +- } +- if (options.keepAlive) +- req.setNoDelay(true); +- if (opts.body) +- req.write(opts.body); +- req.end(); +- }); +-} ++ ++/** ++ * ============================== PATCH INFORMATION ============================== ++ * This patch addresses an incompatibility issue with the zlib node library that ++ * causes the React Native (RN) app to crash. The zlib library isn't compatible ++ * with RN. The patch mitigates this problem by commenting out a section of code ++ * that is specific to Node.js and not applicable to RN. ++ * =============================================================================== ++ */ ++ ++// function fetchNode(url, _options) { ++// let options = { ...DEFAULT_OPT, ..._options }; ++// const http = require('http'); ++// const https = require('https'); ++// const zlib = require('zlib'); ++// const { promisify } = require('util'); ++// const { resolve: urlResolve } = require('url'); ++// const isSecure = !!/^https/.test(url); ++// let opts = { ++// method: options.method || 'GET', ++// headers: { 'Accept-Encoding': 'gzip, deflate, br' }, ++// }; ++// const compactFP = (s) => s.replace(/:| /g, '').toLowerCase(); ++// if (options.keepAlive) { ++// const agentOpt = { ++// keepAlive: true, ++// keepAliveMsecs: 30 * 1000, ++// maxFreeSockets: 1024, ++// maxCachedSessions: 1024, ++// }; ++// const agentKey = [ ++// isSecure, ++// isSecure && options.sslPinnedCertificates?.map((i) => compactFP(i)).sort(), ++// ].join(); ++// opts.agent = ++// agents[agentKey] || (agents[agentKey] = new (isSecure ? https : http).Agent(agentOpt)); ++// } ++// if (options.type === 'json') ++// opts.headers['Content-Type'] = 'application/json'; ++// if (options.data) { ++// if (!options.method) ++// opts.method = 'POST'; ++// opts.body = options.type === 'json' ? JSON.stringify(options.data) : options.data; ++// } ++// opts.headers = { ...opts.headers, ...options.headers }; ++// if (options.sslAllowSelfSigned) ++// opts.rejectUnauthorized = false; ++// const handleRes = async (res) => { ++// const status = res.statusCode; ++// if (options.redirect && 300 <= status && status < 400 && res.headers['location']) { ++// if (options._redirectCount == 10) ++// throw new Error('Request failed. Too much redirects.'); ++// options._redirectCount += 1; ++// return await fetchNode(urlResolve(url, res.headers['location']), options); ++// } ++// if (options.expectStatusCode && status !== options.expectStatusCode) { ++// res.resume(); ++// throw new InvalidStatusCodeError(status); ++// } ++// let buf = []; ++// for await (const chunk of res) ++// buf.push(chunk); ++// let bytes = Buffer.concat(buf); ++// const encoding = res.headers['content-encoding']; ++// if (encoding === 'br') ++// bytes = await promisify(zlib.brotliDecompress)(bytes); ++// if (encoding === 'gzip' || encoding === 'deflate') ++// bytes = await promisify(zlib.unzip)(bytes); ++// const body = detectType(bytes, options.type); ++// if (options.full) ++// return { headers: res.headers, status, body }; ++// return body; ++// }; ++// return new Promise((resolve, reject) => { ++// const handleError = async (err) => { ++// if (err && err.code === 'DEPTH_ZERO_SELF_SIGNED_CERT') { ++// try { ++// await fetchNode(url, { ...options, sslAllowSelfSigned: true, sslPinnedCertificates: [] }); ++// } ++// catch (e) { ++// if (e && e.fingerprint256) { ++// err = new InvalidCertError(`Self-signed SSL certificate: ${e.fingerprint256}`, e.fingerprint256); ++// } ++// } ++// } ++// reject(err); ++// }; ++// const req = (isSecure ? https : http).request(url, opts, (res) => { ++// res.on('error', handleError); ++// (async () => { ++// try { ++// resolve(await handleRes(res)); ++// } ++// catch (error) { ++// reject(error); ++// } ++// })(); ++// }); ++// req.on('error', handleError); ++// const pinned = options.sslPinnedCertificates?.map((i) => compactFP(i)); ++// const mfetchSecureConnect = (socket) => { ++// const fp256 = compactFP(socket.getPeerCertificate()?.fingerprint256 || ''); ++// if (!fp256 && socket.isSessionReused()) ++// return; ++// if (pinned.includes(fp256)) ++// return; ++// req.emit('error', new InvalidCertError(`Invalid SSL certificate: ${fp256} Expected: ${pinned}`, fp256)); ++// return req.abort(); ++// }; ++// if (options.sslPinnedCertificates) { ++// req.on('socket', (socket) => { ++// const hasListeners = socket ++// .listeners('secureConnect') ++// .map((i) => (i.name || '').replace('bound ', '')) ++// .includes('mfetchSecureConnect'); ++// if (hasListeners) ++// return; ++// socket.on('secureConnect', mfetchSecureConnect.bind(null, socket)); ++// }); ++// } ++// if (options.keepAlive) ++// req.setNoDelay(true); ++// if (opts.body) ++// req.write(opts.body); ++// req.end(); ++// }); ++// } + const SAFE_HEADERS = new Set(['Accept', 'Accept-Language', 'Content-Language', 'Content-Type'].map((i) => i.toLowerCase())); + const FORBIDDEN_HEADERS = new Set(['Accept-Charset', 'Accept-Encoding', 'Access-Control-Request-Headers', 'Access-Control-Request-Method', + 'Connection', 'Content-Length', 'Cookie', 'Cookie2', 'Date', 'DNT', 'Expect', 'Host', 'Keep-Alive', 'Origin', 'Referer', 'TE', 'Trailer', diff --git a/yarn.lock b/yarn.lock index 89882a53508..315f4f64759 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1798,7 +1798,7 @@ async "^3.2.4" ethereum-cryptography "^1.1.2" -"@ethereumjs/util@^8.1.0": +"@ethereumjs/util@^8.0.2", "@ethereumjs/util@^8.0.6", "@ethereumjs/util@^8.1.0": version "8.1.0" resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-8.1.0.tgz#299df97fb6b034e0577ce9f94c7d9d1004409ed4" integrity sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA== @@ -3822,7 +3822,7 @@ resolved "https://registry.yarnpkg.com/@log4js-node/log4js-api/-/log4js-api-1.0.2.tgz#7a8143fb33f077df3e579dca7f18fea74a02ec8b" integrity sha512-6SJfx949YEWooh/CUPpJ+F491y4BYJmknz4hUN1+RHvKoUEynKbRmhnwbk/VLmh4OthLLDNCyWXfbh4DG1cTXA== -"@metamask/abi-utils@^1.1.0": +"@metamask/abi-utils@^1.1.0", "@metamask/abi-utils@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@metamask/abi-utils/-/abi-utils-1.2.0.tgz#068e1b0f5e423dfae96961e0e5276a7c1babc03a" integrity sha512-Hf7fnBDM9ptCPDtq/wQffWbw859CdVGMwlpWUEsTH6gLXhXONGrRXHA2piyYPRuia8YYTdJvRC/zSK1/nyLvYg== @@ -3878,14 +3878,6 @@ single-call-balance-checker-abi "^1.0.0" uuid "^8.3.2" -"@metamask/base-controller@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@metamask/base-controller/-/base-controller-1.1.1.tgz#34c2db471328b92a3a46f9c2547bbb9d37803258" - integrity sha512-erDfd+OcHnixSZObPNHuDn2G3rRT2B9J/JaOmjjQN64o9RqDYid87Zb0z03wK8cbJ/pEHhhDIBn6t2gMWcdwrQ== - dependencies: - "@metamask/controller-utils" "^1.0.0" - immer "^9.0.6" - "@metamask/base-controller@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@metamask/base-controller/-/base-controller-2.0.0.tgz#8f9130df3edaa270ade00378cf57917545d44617" @@ -3902,15 +3894,18 @@ "@metamask/utils" "^5.0.2" immer "^9.0.6" -"@metamask/bip39@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@metamask/bip39/-/bip39-4.0.0.tgz#1cb867a8454e3d45d065107b4e070d58bdb64aac" - integrity sha512-xH2g8mFe9p2WePnKeQJH4U8MB6pWPyvwpsz4stb0YdnMOR7cKA6Jm/KOSFiPKr1i9+AzNDImt/XxhwF5ej4jXQ== +"@metamask/base-controller@^3.1.0", "@metamask/base-controller@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@metamask/base-controller/-/base-controller-3.2.1.tgz#9bed5764e786280eccb16a6d1f6582c0f9200871" + integrity sha512-KGMh2c9Lt/wHw+lHx7Mk/2uEqf1PKET+lc4R5UHmZ8HuasilhvVqvv/eoiUDBahoIRnK60zCbbclnc3VdnsScw== dependencies: - "@types/node" "11.11.6" - create-hash "^1.1.0" - pbkdf2 "^3.0.9" - randombytes "^2.0.1" + "@metamask/utils" "^6.2.0" + immer "^9.0.6" + +"@metamask/browser-passworder@^4.0.2": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@metamask/browser-passworder/-/browser-passworder-4.1.0.tgz#d515db2ffd69ecab813a688e2b7553f2766c5e79" + integrity sha512-FBvah1mPte5HudQdkgqAh2+Zc75T9kYxey+dCtHIj9gKohkHDcIA1bTOPLk0bBH+6PnOzYNPG8devvH04GOmPA== "@metamask/composable-controller@^2.0.0": version "2.0.0" @@ -3924,7 +3919,7 @@ resolved "https://registry.yarnpkg.com/@metamask/contract-metadata/-/contract-metadata-2.2.0.tgz#277764d0d56e37180ae7644a9d11eb96295b36fc" integrity sha512-SM6A4C7vXNbVpgMTX67kfW8QWvu3eSXxMZlY5PqZBTkvri1s9zgQ0uwRkK5r2VXNEoVmXCDnnEX/tX5EzzgNUQ== -"@metamask/controller-utils@^1.0.0", "@metamask/controller-utils@^3.0.0", "@metamask/controller-utils@^3.1.0", "@metamask/controller-utils@^3.2.0", "@metamask/controller-utils@^3.4.0", "@metamask/controller-utils@^4.0.0", "@metamask/controller-utils@^4.0.1": +"@metamask/controller-utils@^3.0.0", "@metamask/controller-utils@^3.1.0", "@metamask/controller-utils@^3.2.0", "@metamask/controller-utils@^3.4.0", "@metamask/controller-utils@^4.0.0", "@metamask/controller-utils@^4.0.1", "@metamask/controller-utils@^4.2.0", "@metamask/controller-utils@^4.3.2": version "3.4.0" resolved "https://registry.yarnpkg.com/@metamask/controller-utils/-/controller-utils-3.4.0.tgz#3714799a3e2648cd758272612578238749e3e11b" integrity sha512-/++y7qXUd9+aRzOklypfzmehO87QVKndlJXsbLRk36W5L5DJo4lrR2pd/IBbwbWEhFJWHhlfbMD+T+gEBvIftw== @@ -3992,16 +3987,15 @@ resolved "https://registry.yarnpkg.com/@metamask/eslint-config/-/eslint-config-9.0.0.tgz#22d4911b705f7e4e566efbdda0e37912da33e30f" integrity sha512-mWlLGQKjXXFOj9EtDClKSoTLeQuPW2kM1w3EpUMf4goYAQ+kLXCCa8pEff6h8ApWAnjhYmXydA1znQ2J4XvD+A== -"@metamask/eth-hd-keyring@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@metamask/eth-hd-keyring/-/eth-hd-keyring-4.0.2.tgz#0a81556a556b361755c8d6fb5aced1ce5be0331c" - integrity sha512-v47VOTCCmZUZ6uxM5tQNoasQjLdrZADmgph2fhk4m7zKVUxDvYFU7FJT3Rm55fk8mg+dKSbEObDriqbdWeBbcA== +"@metamask/eth-hd-keyring@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@metamask/eth-hd-keyring/-/eth-hd-keyring-6.0.0.tgz#a46788d4bbc7aa5d8263ed6e4348101a80519a69" + integrity sha512-dEj/I6Ag9FyCmjPcRXeXCkRXkVJE/uElhDVRcLBU6mT/GsXKgzVWXC/k0dhE8rEDrQbidhl+8wEElSJ2LI1InA== dependencies: - "@metamask/bip39" "^4.0.0" - "@metamask/eth-sig-util" "^4.0.0" - eth-simple-keyring "^4.2.0" - ethereumjs-util "^7.0.9" - ethereumjs-wallet "^1.0.1" + "@ethereumjs/util" "^8.0.2" + "@metamask/eth-sig-util" "^5.0.2" + "@metamask/scure-bip39" "^2.0.3" + ethereum-cryptography "^1.1.2" "@metamask/eth-json-rpc-provider@^1.0.0": version "1.0.1" @@ -4012,7 +4006,30 @@ "@metamask/safe-event-emitter" "^3.0.0" "@metamask/utils" "^5.0.1" -"@metamask/eth-sig-util@^4.0.0", "@metamask/eth-sig-util@^4.0.1": +"@metamask/eth-keyring-controller@^10.0.1": + version "10.0.1" + resolved "https://registry.yarnpkg.com/@metamask/eth-keyring-controller/-/eth-keyring-controller-10.0.1.tgz#732ccd7156b0139da352b028cd921dfbed05992e" + integrity sha512-oLjBT/UG4N3IjSWW/OZGkZRsUBtUstSS2yOPQJGgWKn4SL5r8sj6XZMUNRipMLBdXZTYPOuAFxhc+2pSlWh8Sw== + dependencies: + "@metamask/browser-passworder" "^4.0.2" + "@metamask/eth-hd-keyring" "^6.0.0" + "@metamask/eth-sig-util" "5.0.2" + "@metamask/eth-simple-keyring" "^5.0.0" + obs-store "^4.0.3" + +"@metamask/eth-sig-util@5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-5.0.2.tgz#c518279a6e17a88135a13d53a0b970f145ff8bce" + integrity sha512-RU6fG/H6/UlBol221uBkq5C7w3TwLK611nEZliO2u+kO0vHKGBXnIPlhI0tzKUigjhUeOd9mhCNbNvhh0LKt9Q== + dependencies: + "@ethereumjs/util" "^8.0.0" + bn.js "^4.11.8" + ethereum-cryptography "^1.1.2" + ethjs-util "^0.1.6" + tweetnacl "^1.0.3" + tweetnacl-util "^0.15.1" + +"@metamask/eth-sig-util@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz#3ad61f6ea9ad73ba5b19db780d40d9aae5157088" integrity sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ== @@ -4023,6 +4040,41 @@ tweetnacl "^1.0.3" tweetnacl-util "^0.15.1" +"@metamask/eth-sig-util@^5.0.1", "@metamask/eth-sig-util@^5.0.2": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-5.1.0.tgz#a47f62800ee1917fef976ba67544a0ccd7d1bd6b" + integrity sha512-mlgziIHYlA9pi/XZerChqg4NocdOgBPB9NmxgXWQO2U2hH8RGOJQrz6j/AIKkYxgCMIE2PY000+joOwXfzeTDQ== + dependencies: + "@ethereumjs/util" "^8.0.6" + bn.js "^4.12.0" + ethereum-cryptography "^2.0.0" + ethjs-util "^0.1.6" + tweetnacl "^1.0.3" + tweetnacl-util "^0.15.1" + +"@metamask/eth-sig-util@^6.0.0": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-6.0.1.tgz#2c5a670c9552ce4d47309d5f5d6569d0518fec23" + integrity sha512-Lt2DC4w4Sbtbd4DCsE+vfjdWcnFHSxfSfiJpt66hfLtAbetHsvbZcwKoa46TEA3G/V48ZuS4NWvJmtaA4F8UWA== + dependencies: + "@ethereumjs/util" "^8.1.0" + "@metamask/abi-utils" "^1.2.0" + "@metamask/utils" "^5.0.2" + ethereum-cryptography "^2.1.2" + ethjs-util "^0.1.6" + tweetnacl "^1.0.3" + tweetnacl-util "^0.15.1" + +"@metamask/eth-simple-keyring@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@metamask/eth-simple-keyring/-/eth-simple-keyring-5.0.0.tgz#307772d1aa3298e41a2444b428cd8f4522b7bf5c" + integrity sha512-UJfP36Z9g1eeD8mSHWaVqUvkgbgYm3S7YuzlMzQi+WgPnWu81CdbldMMtvreTlu4I1mTyljXLDMjIp65P0bygQ== + dependencies: + "@ethereumjs/util" "^8.0.0" + "@metamask/eth-sig-util" "^5.0.1" + ethereum-cryptography "^1.1.2" + randombytes "^2.1.0" + "@metamask/etherscan-link@^2.0.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@metamask/etherscan-link/-/etherscan-link-2.1.0.tgz#c0be8e68445b7b83cf85bcc03a56cdf8e256c973" @@ -4053,34 +4105,22 @@ "@metamask/safe-event-emitter" "^2.0.0" "@metamask/utils" "^5.0.1" -"@metamask/keyring-controller@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@metamask/keyring-controller/-/keyring-controller-1.0.1.tgz#c2836bbafaab8c2d1300f4e56aad3b32b3dd90c0" - integrity sha512-D7+GbSvE5B0DqPyfeTypkShoj8tATUM64a/Nb9FmqYW20slZ4TMUAdbMOHi6KqZnaZcKu8oOUTxEiRe+MsRGAw== +"@metamask/keyring-controller@^6.0.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@metamask/keyring-controller/-/keyring-controller-6.1.0.tgz#09528297bcc47a57355b9328d3ecdc94e0710d95" + integrity sha512-X+unaoqgt1ol6p32fCprmYDzU29Mhgn3mEvqI3lHkXSEjna+wFyf4l3akxlZSmn/nobJJugcw2IUkq1EQHAxTA== dependencies: "@keystonehq/metamask-airgapped-keyring" "^0.6.1" - "@metamask/base-controller" "^1.1.1" - "@metamask/controller-utils" "^1.0.0" - "@metamask/message-manager" "^1.0.1" - "@metamask/preferences-controller" "^1.0.1" + "@metamask/base-controller" "^3.1.0" + "@metamask/controller-utils" "^4.2.0" + "@metamask/eth-keyring-controller" "^10.0.1" + "@metamask/eth-sig-util" "^6.0.0" + "@metamask/message-manager" "^7.1.0" + "@metamask/preferences-controller" "^4.2.0" async-mutex "^0.2.6" - eth-keyring-controller "^7.0.2" - eth-sig-util "^3.0.0" ethereumjs-util "^7.0.10" ethereumjs-wallet "^1.0.1" - -"@metamask/message-manager@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@metamask/message-manager/-/message-manager-1.0.1.tgz#5834fb5ed14a844f35f796268966745a966847ed" - integrity sha512-8IvTS6T4gZm7mL8+xUwWHOMGuXaMF3OZJB5g34taASp0p5pXHoLNEXL+qBaw0RkgDxbFsuij02Gs3Mx/jQ6U6A== - dependencies: - "@metamask/base-controller" "^1.1.1" - "@metamask/controller-utils" "^1.0.0" - "@types/uuid" "^8.3.0" - eth-sig-util "^3.0.0" - ethereumjs-util "^7.0.10" - jsonschema "^1.2.4" - uuid "^8.3.2" + immer "^9.0.6" "@metamask/message-manager@^7.0.0": version "7.0.1" @@ -4096,6 +4136,20 @@ jsonschema "^1.2.4" uuid "^8.3.2" +"@metamask/message-manager@^7.1.0": + version "7.3.1" + resolved "https://registry.yarnpkg.com/@metamask/message-manager/-/message-manager-7.3.1.tgz#66ae6e751d8c2890eb6aefec8db4a4495526a1c2" + integrity sha512-VhDxwvqdPILBskBK6sSLPOLtby6jABQyyAUMmBe/r4PoEtKhW+AMkswVGbxbYkRKpo2A0H5qBetqeEMZaxS1Ew== + dependencies: + "@metamask/base-controller" "^3.2.1" + "@metamask/controller-utils" "^4.3.2" + "@metamask/eth-sig-util" "^6.0.0" + "@metamask/utils" "^6.2.0" + "@types/uuid" "^8.3.0" + ethereumjs-util "^7.0.10" + jsonschema "^1.2.4" + uuid "^8.3.2" + "@metamask/metamask-eth-abis@3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@metamask/metamask-eth-abis/-/metamask-eth-abis-3.0.0.tgz#eccc0746b3ab1ab63000444403819c16e88b5272" @@ -4186,14 +4240,6 @@ elliptic "^6.5.4" json-rpc-random-id "^1.0.1" -"@metamask/preferences-controller@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@metamask/preferences-controller/-/preferences-controller-1.0.1.tgz#20f2187be103a1e7f49df4021e39afb12ee422a0" - integrity sha512-6fAruDd9sag/hwJGKIP0eSdYC92J/wkDnigQo7ONpu7n94giot7vvsR5+4zNjC32tLa5GpHG50PynZaHfYzK0Q== - dependencies: - "@metamask/base-controller" "^1.1.1" - "@metamask/controller-utils" "^1.0.0" - "@metamask/preferences-controller@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@metamask/preferences-controller/-/preferences-controller-3.0.0.tgz#ef3f5e9c49fb508a5bcdcc2ad7cf3d966af9809b" @@ -4202,6 +4248,14 @@ "@metamask/base-controller" "^2.0.0" "@metamask/controller-utils" "^3.1.0" +"@metamask/preferences-controller@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@metamask/preferences-controller/-/preferences-controller-4.4.0.tgz#352b16a176695166d585c25e3b78c943219358b7" + integrity sha512-f1X15+sqqea3/NMpsCVsAzM/sx/JQgsS+JgK3BR2hnpDCyuYV0HQfLn7ilKqzKFpthtqVgDqXcoZ3q3ekp/J1Q== + dependencies: + "@metamask/base-controller" "^3.2.1" + "@metamask/controller-utils" "^4.3.2" + "@metamask/rpc-errors@^5.0.0": version "5.1.1" resolved "https://registry.yarnpkg.com/@metamask/rpc-errors/-/rpc-errors-5.1.1.tgz#f82732ad0952d34d219eca42699c0c74bee95a9e" @@ -4220,6 +4274,14 @@ resolved "https://registry.yarnpkg.com/@metamask/safe-event-emitter/-/safe-event-emitter-3.0.0.tgz#8c2b9073fe0722d48693143b0dc8448840daa3bd" integrity sha512-j6Z47VOmVyGMlnKXZmL0fyvWfEYtKWCA9yGZkU3FCsGZUT5lHGmvaV9JA5F2Y+010y7+ROtR3WMXIkvl/nVzqQ== +"@metamask/scure-bip39@^2.0.3", "@metamask/scure-bip39@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@metamask/scure-bip39/-/scure-bip39-2.1.0.tgz#13456884736e56ede15e471bd93c0aa0acdedd0b" + integrity sha512-Ndwdnld0SI6YaftEUUVq20sdoWcWNXsJXxvQkbiY42FKmrA16U6WoSh9Eq+NpugpKKwK6f5uvaTDusjndiEDGQ== + dependencies: + "@noble/hashes" "~1.1.1" + "@scure/base" "~1.1.0" + "@metamask/sdk-communication-layer@^0.5.0": version "0.5.2" resolved "https://registry.yarnpkg.com/@metamask/sdk-communication-layer/-/sdk-communication-layer-0.5.2.tgz#fd94d457569b7ee984ad40b1c965d509d569269b" @@ -4315,6 +4377,18 @@ semver "^7.3.8" superstruct "^1.0.3" +"@metamask/utils@^6.2.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@metamask/utils/-/utils-6.2.0.tgz#7e63ad2db33117df6fef89449db3a86dcd6b42b5" + integrity sha512-nM5CujDd4STfwx4ic/gim9G1W9oZcWUGKN4WbAT4waEkqNSIluVmZeHgxUKvdajZ7iCFDnjDLajkD4sP7c/ClQ== + dependencies: + "@ethereumjs/tx" "^4.1.2" + "@noble/hashes" "^1.3.1" + "@types/debug" "^4.1.7" + debug "^4.3.4" + semver "^7.3.8" + superstruct "^1.0.3" + "@ngraveio/bc-ur@^1.1.5", "@ngraveio/bc-ur@^1.1.6": version "1.1.6" resolved "https://registry.yarnpkg.com/@ngraveio/bc-ur/-/bc-ur-1.1.6.tgz#8f8c75fff22f6a5e4dfbc5a6b540d7fe8f42cd39" @@ -4335,6 +4409,13 @@ dependencies: "@noble/hashes" "1.3.0" +"@noble/curves@1.1.0", "@noble/curves@~1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d" + integrity sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA== + dependencies: + "@noble/hashes" "1.3.1" + "@noble/hashes@1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" @@ -4345,16 +4426,21 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1" integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg== +"@noble/hashes@1.3.1", "@noble/hashes@~1.3.0": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" + integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== + +"@noble/hashes@^1.3.1", "@noble/hashes@~1.3.1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" + integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== + "@noble/hashes@~1.1.1": version "1.1.5" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.5.tgz#1a0377f3b9020efe2fae03290bd2a12140c95c11" integrity sha512-LTMZiiLc+V4v1Yi16TD6aX2gmtKszNye0pQgbaLqkvhIqP7nVsSaJsWloGQjJfJ8offaoP5GtX3yY5swbcJxxQ== -"@noble/hashes@~1.3.0": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" - integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== - "@noble/secp256k1@1.6.3", "@noble/secp256k1@~1.6.0": version "1.6.3" resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.6.3.tgz#7eed12d9f4404b416999d0c87686836c4c5c9b94" @@ -4923,6 +5009,15 @@ "@noble/hashes" "~1.3.0" "@scure/base" "~1.1.0" +"@scure/bip32@1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.1.tgz#7248aea723667f98160f593d621c47e208ccbb10" + integrity sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A== + dependencies: + "@noble/curves" "~1.1.0" + "@noble/hashes" "~1.3.1" + "@scure/base" "~1.1.0" + "@scure/bip39@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.0.tgz#92f11d095bae025f166bef3defcc5bf4945d419a" @@ -4939,6 +5034,14 @@ "@noble/hashes" "~1.3.0" "@scure/base" "~1.1.0" +"@scure/bip39@1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.1.tgz#5cee8978656b272a917b7871c981e0541ad6ac2a" + integrity sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg== + dependencies: + "@noble/hashes" "~1.3.0" + "@scure/base" "~1.1.0" + "@segment/analytics-react-native@2.13.0": version "2.13.0" resolved "https://registry.yarnpkg.com/@segment/analytics-react-native/-/analytics-react-native-2.13.0.tgz#2a612253219cd91ea3716f46d4fa837231d968d8" @@ -6205,11 +6308,6 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.11.tgz#b3b790f09cb1696cffcec605de025b088fa4225f" integrity sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q== -"@types/node@11.11.6": - version "11.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a" - integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== - "@types/node@16.9.1": version "16.9.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.9.1.tgz#0611b37db4246c937feef529ddcc018cf8e35708" @@ -9585,7 +9683,7 @@ bn.js@4.11.8: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.1, bn.js@^4.11.8, bn.js@^4.11.9: +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.1, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^4.12.0: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== @@ -13091,18 +13189,6 @@ eth-keyring-controller@^6.2.1: loglevel "^1.5.0" obs-store "^4.0.3" -eth-keyring-controller@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/eth-keyring-controller/-/eth-keyring-controller-7.0.2.tgz#c4d7f9be179f08b3bb18410066bc4c8e91f50552" - integrity sha512-U4bqbXkTn7js/47rnFtVyBYQcvOKtmraD/YReBwuy4R56bFSJN8kinP0JJRl3WTtVfVS1l5A/jjsF3qk5TaTeg== - dependencies: - "@metamask/bip39" "^4.0.0" - "@metamask/eth-hd-keyring" "^4.0.2" - browser-passworder "^2.0.3" - eth-sig-util "^3.0.1" - eth-simple-keyring "^4.2.0" - obs-store "^4.0.3" - eth-method-registry@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/eth-method-registry/-/eth-method-registry-1.1.0.tgz#3cc01bd23dcf513428d14a0bb19910652cc5cac0" @@ -13233,6 +13319,16 @@ ethereum-cryptography@^2.0.0: "@scure/bip32" "1.3.0" "@scure/bip39" "1.2.0" +ethereum-cryptography@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz#18fa7108622e56481157a5cb7c01c0c6a672eb67" + integrity sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug== + dependencies: + "@noble/curves" "1.1.0" + "@noble/hashes" "1.3.1" + "@scure/bip32" "1.3.1" + "@scure/bip39" "1.2.1" + ethereum-ens-network-map@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/ethereum-ens-network-map/-/ethereum-ens-network-map-1.0.2.tgz#4e27bad18dae7bd95d84edbcac2c9e739fc959b9"