Merge pull request #11274 from MetaMask/Version-v9.7.0
Version v9.7.0 RCfeature/default_network_editable
commit
cbb0e4d45c
@ -0,0 +1,56 @@ |
||||
export const currentNetworkTxListSample = { |
||||
"id": 7900715443136469, |
||||
"time": 1621395091737, |
||||
"status": "unapproved", |
||||
"metamaskNetworkId": "1337", |
||||
"chainId": "0x539", |
||||
"loadingDefaults": false, |
||||
"txParams": { |
||||
"from": "0x90f79bf6eb2c4f870365e785982e1f101e93b906", |
||||
"to": "0x057ef64e23666f000b34ae31332854acbd1c8544", |
||||
"value": "0x0", |
||||
"data": "0x095ea7b30000000000000000000000009bc5baf874d2da8d216ae9f137804184ee5afef40000000000000000000000000000000000000000000000000000000000011170", |
||||
"gas": "0xea60", |
||||
"gasPrice": "0x4a817c800" |
||||
}, |
||||
"origin": "https://metamask.github.io", |
||||
"type": "approve", |
||||
"history": [ |
||||
{ |
||||
"id": 7900715443136469, |
||||
"time": 1621395091737, |
||||
"status": "unapproved", |
||||
"metamaskNetworkId": "1337", |
||||
"chainId": "0x539", |
||||
"loadingDefaults": true, |
||||
"txParams": { |
||||
"from": "0x90f79bf6eb2c4f870365e785982e1f101e93b906", |
||||
"to": "0x057ef64e23666f000b34ae31332854acbd1c8544", |
||||
"value": "0x0", |
||||
"data": "0x095ea7b30000000000000000000000009bc5baf874d2da8d216ae9f137804184ee5afef40000000000000000000000000000000000000000000000000000000000011170", |
||||
"gas": "0xea60", |
||||
"gasPrice": "0x4a817c800" |
||||
}, |
||||
"origin": "https://metamask.github.io", |
||||
"type": "approve" |
||||
}, |
||||
[ |
||||
{ |
||||
"op": "replace", |
||||
"path": "/loadingDefaults", |
||||
"value": false, |
||||
"note": "Added new unapproved transaction.", |
||||
"timestamp": 1621395091742 |
||||
} |
||||
] |
||||
] |
||||
} |
||||
|
||||
export const domainMetadata = { |
||||
"https://metamask.github.io": { |
||||
"name": "E2E Test Dapp", |
||||
"icon": "https://metamask.github.io/test-dapp/metamask-fox.svg", |
||||
"lastUpdated": 1620723443380, |
||||
"host": "metamask.github.io" |
||||
} |
||||
} |
@ -0,0 +1,24 @@ |
||||
import React from 'react'; |
||||
import { |
||||
MetaMetricsProvider, |
||||
LegacyMetaMetricsProvider, |
||||
} from '../ui/contexts/metametrics'; |
||||
import { |
||||
MetaMetricsProvider as NewMetaMetricsProvider, |
||||
LegacyMetaMetricsProvider as NewLegacyMetaMetricsProvider, |
||||
} from '../ui/contexts/metametrics.new'; |
||||
|
||||
const MetaMetricsProviderStorybook = (props) =>
|
||||
( |
||||
<MetaMetricsProvider> |
||||
<LegacyMetaMetricsProvider> |
||||
<NewMetaMetricsProvider> |
||||
<NewLegacyMetaMetricsProvider> |
||||
{props.children} |
||||
</NewLegacyMetaMetricsProvider> |
||||
</NewMetaMetricsProvider> |
||||
</LegacyMetaMetricsProvider> |
||||
</MetaMetricsProvider> |
||||
); |
||||
|
||||
export default MetaMetricsProviderStorybook |
@ -1,217 +1,782 @@ |
||||
import { TRANSACTION_STATUSES } from '../shared/constants/transaction'; |
||||
|
||||
const state = { |
||||
metamask: { |
||||
isInitialized: true, |
||||
isUnlocked: true, |
||||
featureFlags: { sendHexData: true }, |
||||
identities: { |
||||
'0xfdea65c8e26263f6d9a1b5de9555d2931a33b825': { |
||||
address: '0xfdea65c8e26263f6d9a1b5de9555d2931a33b825', |
||||
name: 'Send Account 1', |
||||
}, |
||||
'0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb': { |
||||
address: '0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb', |
||||
name: 'Send Account 2', |
||||
}, |
||||
'0x2f8d4a878cfa04a6e60d46362f5644deab66572d': { |
||||
address: '0x2f8d4a878cfa04a6e60d46362f5644deab66572d', |
||||
name: 'Send Account 3', |
||||
}, |
||||
'0xd85a4b6a394794842887b8284293d69163007bbb': { |
||||
address: '0xd85a4b6a394794842887b8284293d69163007bbb', |
||||
name: 'Send Account 4', |
||||
}, |
||||
}, |
||||
cachedBalances: {}, |
||||
currentBlockGasLimit: '0x4c1878', |
||||
currentCurrency: 'USD', |
||||
conversionRate: 1200.88200327, |
||||
conversionDate: 1489013762, |
||||
nativeCurrency: 'ETH', |
||||
frequentRpcList: [], |
||||
network: '3', |
||||
provider: { |
||||
type: 'ropsten', |
||||
chainId: '0x3', |
||||
}, |
||||
accounts: { |
||||
'0xfdea65c8e26263f6d9a1b5de9555d2931a33b825': { |
||||
code: '0x', |
||||
balance: '0x47c9d71831c76efe', |
||||
nonce: '0x1b', |
||||
address: '0xfdea65c8e26263f6d9a1b5de9555d2931a33b825', |
||||
}, |
||||
'0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb': { |
||||
code: '0x', |
||||
balance: '0x37452b1315889f80', |
||||
nonce: '0xa', |
||||
address: '0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb', |
||||
}, |
||||
'0x2f8d4a878cfa04a6e60d46362f5644deab66572d': { |
||||
code: '0x', |
||||
balance: '0x30c9d71831c76efe', |
||||
nonce: '0x1c', |
||||
address: '0x2f8d4a878cfa04a6e60d46362f5644deab66572d', |
||||
}, |
||||
'0xd85a4b6a394794842887b8284293d69163007bbb': { |
||||
code: '0x', |
||||
balance: '0x0', |
||||
nonce: '0x0', |
||||
address: '0xd85a4b6a394794842887b8284293d69163007bbb', |
||||
}, |
||||
}, |
||||
addressBook: { |
||||
'0x3': { |
||||
'0x06195827297c7a80a443b6894d3bdb8824b43896': { |
||||
address: '0x06195827297c7a80a443b6894d3bdb8824b43896', |
||||
name: 'Address Book Account 1', |
||||
chainId: '0x3', |
||||
}, |
||||
}, |
||||
}, |
||||
tokens: [ |
||||
{ |
||||
address: '0x1a195821297c7a80a433b6894d3bdb8824b43896', |
||||
decimals: 18, |
||||
symbol: 'ABC', |
||||
"invalidCustomNetwork": { |
||||
"state": "CLOSED", |
||||
"networkName": "" |
||||
}, |
||||
"unconnectedAccount": { |
||||
"state": "CLOSED" |
||||
}, |
||||
"activeTab": {}, |
||||
"metamask": { |
||||
"isInitialized": true, |
||||
"isUnlocked": true, |
||||
"isAccountMenuOpen": false, |
||||
"rpcUrl": "https://rawtestrpc.metamask.io/", |
||||
"identities": { |
||||
"0x983211ce699ea5ab57cc528086154b6db1ad8e55": { |
||||
"name": "Account 1", |
||||
"address": "0x983211ce699ea5ab57cc528086154b6db1ad8e55" |
||||
}, |
||||
{ |
||||
address: '0x8d6b81208414189a58339873ab429b6c47ab92d3', |
||||
decimals: 4, |
||||
symbol: 'DEF', |
||||
"0xb19ac54efa18cc3a14a5b821bfec73d284bf0c5e": { |
||||
"name": "Account 2", |
||||
"address": "0xb19ac54efa18cc3a14a5b821bfec73d284bf0c5e" |
||||
}, |
||||
"0x9d0ba4ddac06032527b140912ec808ab9451b788": { |
||||
"name": "Account 3", |
||||
"address": "0x9d0ba4ddac06032527b140912ec808ab9451b788" |
||||
} |
||||
}, |
||||
"unapprovedTxs": { |
||||
"7786962153682822": { |
||||
"id": 7786962153682822, |
||||
"time": 1620710815484, |
||||
"status": "unapproved", |
||||
"metamaskNetworkId": "3", |
||||
"chainId": "0x3", |
||||
"loadingDefaults": false, |
||||
"txParams": { |
||||
"from": "0x64a845a5b02460acf8a3d84503b0d68d028b4bb4", |
||||
"to": "0xad6d458402f60fd3bd25163575031acdce07538d", |
||||
"value": "0x0", |
||||
"data": "0xa9059cbb000000000000000000000000b19ac54efa18cc3a14a5b821bfec73d284bf0c5e0000000000000000000000000000000000000000000000003782dace9d900000", |
||||
"gas": "0xcb28", |
||||
"gasPrice": "0x77359400" |
||||
}, |
||||
"type": "standard", |
||||
"origin": "metamask", |
||||
"transactionCategory": "transfer", |
||||
"history": [ |
||||
{ |
||||
"id": 7786962153682822, |
||||
"time": 1620710815484, |
||||
"status": "unapproved", |
||||
"metamaskNetworkId": "3", |
||||
"chainId": "0x3", |
||||
"loadingDefaults": true, |
||||
"txParams": { |
||||
"from": "0x64a845a5b02460acf8a3d84503b0d68d028b4bb4", |
||||
"to": "0xad6d458402f60fd3bd25163575031acdce07538d", |
||||
"value": "0x0", |
||||
"data": "0xa9059cbb000000000000000000000000b19ac54efa18cc3a14a5b821bfec73d284bf0c5e0000000000000000000000000000000000000000000000003782dace9d900000", |
||||
"gas": "0xcb28", |
||||
"gasPrice": "0x77359400" |
||||
}, |
||||
"type": "standard", |
||||
"origin": "metamask", |
||||
"transactionCategory": "transfer" |
||||
}, |
||||
[ |
||||
{ |
||||
"op": "replace", |
||||
"path": "/loadingDefaults", |
||||
"value": false, |
||||
"note": "Added new unapproved transaction.", |
||||
"timestamp": 1620710815497 |
||||
} |
||||
] |
||||
] |
||||
} |
||||
}, |
||||
"frequentRpcList": [], |
||||
"addressBook": { |
||||
"undefined": { |
||||
"0": { |
||||
"address": "0x39a4e4Af7cCB654dB9500F258c64781c8FbD39F0", |
||||
"name": "", |
||||
"isEns": false |
||||
} |
||||
} |
||||
}, |
||||
"contractExchangeRates": { |
||||
"0xad6d458402f60fd3bd25163575031acdce07538d": 0 |
||||
}, |
||||
"tokens": [ |
||||
{ |
||||
address: '0xa42084c8d1d9a2198631988579bb36b48433a72b', |
||||
decimals: 18, |
||||
symbol: 'GHI', |
||||
"address": "0xad6d458402f60fd3bd25163575031acdce07538d", |
||||
"symbol": "DAI", |
||||
"decimals": 18 |
||||
} |
||||
], |
||||
"pendingTokens": {}, |
||||
"customNonceValue": "", |
||||
"send": { |
||||
"gasLimit": "0xcb28", |
||||
"gasPrice": null, |
||||
"gasTotal": null, |
||||
"tokenBalance": "8.7a73149c048545a3fe58", |
||||
"from": "", |
||||
"to": "0xb19ac54efa18cc3a14a5b821bfec73d284bf0c5e", |
||||
"amount": "3782dace9d900000", |
||||
"memo": "", |
||||
"errors": {}, |
||||
"maxModeOn": false, |
||||
"editingTransactionId": null, |
||||
"toNickname": "Account 2", |
||||
"ensResolution": null, |
||||
"ensResolutionError": "", |
||||
"token": { |
||||
"address": "0xad6d458402f60fd3bd25163575031acdce07538d", |
||||
"symbol": "DAI", |
||||
"decimals": 18 |
||||
} |
||||
}, |
||||
"useBlockie": false, |
||||
"featureFlags": {}, |
||||
"welcomeScreenSeen": false, |
||||
"currentLocale": "en", |
||||
"preferences": { |
||||
"useNativeCurrencyAsPrimaryCurrency": true |
||||
}, |
||||
"firstTimeFlowType": "create", |
||||
"completedOnboarding": true, |
||||
"knownMethodData": { |
||||
"0x60806040": { |
||||
"name": "Approve Tokens" |
||||
}, |
||||
"0x095ea7b3": { |
||||
"name": "Approve Tokens" |
||||
} |
||||
}, |
||||
"participateInMetaMetrics": true, |
||||
"metaMetricsSendCount": 2, |
||||
"nextNonce": 71, |
||||
"connectedStatusPopoverHasBeenShown": true, |
||||
"swapsWelcomeMessageHasBeenShown": true, |
||||
"defaultHomeActiveTabName": "Assets", |
||||
"provider": { |
||||
"type": "ropsten", |
||||
"ticker": "ETH", |
||||
"nickname": "", |
||||
"rpcUrl": "", |
||||
"chainId": "0x3" |
||||
}, |
||||
"previousProviderStore": { |
||||
"type": "ropsten", |
||||
"ticker": "ETH", |
||||
"nickname": "", |
||||
"rpcUrl": "", |
||||
"chainId": "0x3" |
||||
}, |
||||
"network": "3", |
||||
"accounts": { |
||||
"0x983211ce699ea5ab57cc528086154b6db1ad8e55": { |
||||
"address": "0x983211ce699ea5ab57cc528086154b6db1ad8e55", |
||||
"balance": "0x176e5b6f173ebe66" |
||||
}, |
||||
"0xb19ac54efa18cc3a14a5b821bfec73d284bf0c5e": { |
||||
"address": "0xb19ac54efa18cc3a14a5b821bfec73d284bf0c5e", |
||||
"balance": "0x2d3142f5000" |
||||
}, |
||||
"0x9d0ba4ddac06032527b140912ec808ab9451b788": { |
||||
"address": "0x9d0ba4ddac06032527b140912ec808ab9451b788", |
||||
"balance": "0x15f6f0b9d4f8d000" |
||||
} |
||||
}, |
||||
"currentBlockGasLimit": "0x793af4", |
||||
"currentNetworkTxList": [ |
||||
|
||||
], |
||||
"cachedBalances": { |
||||
"1": { |
||||
"0x64a845a5b02460acf8a3d84503b0d68d028b4bb4": "0x0", |
||||
"0xb19ac54efa18cc3a14a5b821bfec73d284bf0c5e": "0xcaf5317161f400", |
||||
"0x9d0ba4ddac06032527b140912ec808ab9451b788": "0x0" |
||||
}, |
||||
"3": { |
||||
"0x64a845a5b02460acf8a3d84503b0d68d028b4bb4": "0x18d289d450bace66", |
||||
"0xb19ac54efa18cc3a14a5b821bfec73d284bf0c5e": "0x2d3142f5000", |
||||
"0x9d0ba4ddac06032527b140912ec808ab9451b788": "0x15f6f0b9d4f8d000" |
||||
}, |
||||
"0x3": { |
||||
"0x64a845a5b02460acf8a3d84503b0d68d028b4bb4": "0x176e5b6f173ebe66", |
||||
"0xb19ac54efa18cc3a14a5b821bfec73d284bf0c5e": "0x2d3142f5000", |
||||
"0x9d0ba4ddac06032527b140912ec808ab9451b788": "0x15f6f0b9d4f8d000" |
||||
} |
||||
}, |
||||
"unapprovedMsgs": {}, |
||||
"unapprovedMsgCount": 0, |
||||
"unapprovedPersonalMsgs": {}, |
||||
"unapprovedPersonalMsgCount": 0, |
||||
"unapprovedDecryptMsgs": {}, |
||||
"unapprovedDecryptMsgCount": 0, |
||||
"unapprovedEncryptionPublicKeyMsgs": {}, |
||||
"unapprovedEncryptionPublicKeyMsgCount": 0, |
||||
"unapprovedTypedMessages": {}, |
||||
"unapprovedTypedMessagesCount": 0, |
||||
"keyringTypes": [ |
||||
"Simple Key Pair", |
||||
"HD Key Tree", |
||||
"Trezor Hardware", |
||||
"Ledger Hardware" |
||||
], |
||||
transactions: {}, |
||||
currentNetworkTxList: [ |
||||
"keyrings": [ |
||||
{ |
||||
id: 'mockTokenTx1', |
||||
txParams: { |
||||
to: '0x8d6b81208414189a58339873ab429b6c47ab92d3', |
||||
from: '0xd85a4b6a394794842887b8284293d69163007bbb', |
||||
"type": "HD Key Tree", |
||||
"accounts": [ |
||||
"0x64a845a5b02460acf8a3d84503b0d68d028b4bb4", |
||||
"0xb19ac54efa18cc3a14a5b821bfec73d284bf0c5e", |
||||
"0x9d0ba4ddac06032527b140912ec808ab9451b788" |
||||
] |
||||
} |
||||
], |
||||
"frequentRpcListDetail": [ |
||||
{ |
||||
"rpcUrl": "http://localhost:8545", |
||||
"chainId": "0x539", |
||||
"ticker": "ETH", |
||||
"nickname": "Localhost 8545", |
||||
"rpcPrefs": {} |
||||
} |
||||
], |
||||
"accountTokens": { |
||||
"0x64a845a5b02460acf8a3d84503b0d68d028b4bb4": { |
||||
"0x1": [ |
||||
{ |
||||
"address": "0x6b175474e89094c44da98b954eedeac495271d0f", |
||||
"symbol": "DAI", |
||||
"decimals": 18 |
||||
}, |
||||
{ |
||||
"address": "0x0d8775f648430679a709e98d2b0cb6250d2887ef", |
||||
"symbol": "BAT", |
||||
"decimals": 18 |
||||
} |
||||
], |
||||
"0x3": [ |
||||
{ |
||||
"address": "0xad6d458402f60fd3bd25163575031acdce07538d", |
||||
"symbol": "DAI", |
||||
"decimals": 18 |
||||
} |
||||
] |
||||
}, |
||||
"0xb19ac54efa18cc3a14a5b821bfec73d284bf0c5e": {}, |
||||
"0x9d0ba4ddac06032527b140912ec808ab9451b788": {} |
||||
}, |
||||
"accountHiddenTokens": { |
||||
"0x64a845a5b02460acf8a3d84503b0d68d028b4bb4": { |
||||
"0x3": [] |
||||
} |
||||
}, |
||||
"assetImages": { |
||||
"0xad6d458402f60fd3bd25163575031acdce07538d": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xaD6D458402F60fD3Bd25163575031ACDce07538D/logo.png" |
||||
}, |
||||
"hiddenTokens": [], |
||||
"suggestedTokens": {}, |
||||
"useNonceField": false, |
||||
"usePhishDetect": true, |
||||
"lostIdentities": {}, |
||||
"forgottenPassword": false, |
||||
"ipfsGateway": "dweb.link", |
||||
"infuraBlocked": false, |
||||
"migratedPrivacyMode": false, |
||||
"selectedAddress": "0x64a845a5b02460acf8a3d84503b0d68d028b4bb4", |
||||
"metaMetricsId": "0xc2377d11fec1c3b7dd88c4854240ee5e3ed0d9f63b00456d98d80320337b827f", |
||||
"conversionDate": 1620710825.03, |
||||
"conversionRate": 3910.28, |
||||
"currentCurrency": "usd", |
||||
"nativeCurrency": "ETH", |
||||
"usdConversionRate": 3910.28, |
||||
"ticker": "ETH", |
||||
"alertEnabledness": { |
||||
"unconnectedAccount": true, |
||||
"web3ShimUsage": true |
||||
}, |
||||
"unconnectedAccountAlertShownOrigins": {}, |
||||
"web3ShimUsageOrigins": {}, |
||||
"seedPhraseBackedUp": null, |
||||
"onboardingTabs": {}, |
||||
"incomingTransactions": { |
||||
"0x2de9256a7c604586f7ecfd87ae9509851e217f588f9f85feed793c54ed2ce0aa": { |
||||
"blockNumber": "8888976", |
||||
"id": 4678200543090532, |
||||
"metamaskNetworkId": "1", |
||||
"status": "confirmed", |
||||
"time": 1573114896000, |
||||
"txParams": { |
||||
"from": "0x3f1b52850109023775d238c7ed5d5e7161041fd1", |
||||
"gas": "0x5208", |
||||
"gasPrice": "0x124101100", |
||||
"nonce": "0x35", |
||||
"to": "0x045c619e4d29bba3b92769508831b681b83d6a96", |
||||
"value": "0xbca9bce4d98ca3" |
||||
}, |
||||
time: 1700000000000, |
||||
"hash": "0x2de9256a7c604586f7ecfd87ae9509851e217f588f9f85feed793c54ed2ce0aa", |
||||
"transactionCategory": "incoming" |
||||
}, |
||||
"0x320a1fd769373578f78570e5d8f56e89bc7bce9657bb5f4c12d8fe790d471bfd": { |
||||
"blockNumber": "9453174", |
||||
"id": 4678200543090535, |
||||
"metamaskNetworkId": "1", |
||||
"status": "confirmed", |
||||
"time": 1581312411000, |
||||
"txParams": { |
||||
"from": "0xa17bd07d6d38cb9e37b29f7659a4b1047701e969", |
||||
"gas": "0xc350", |
||||
"gasPrice": "0x1a13b8600", |
||||
"nonce": "0x0", |
||||
"to": "0x045c619e4d29bba3b92769508831b681b83d6a96", |
||||
"value": "0xcdb08ab4254000" |
||||
}, |
||||
"hash": "0x320a1fd769373578f78570e5d8f56e89bc7bce9657bb5f4c12d8fe790d471bfd", |
||||
"transactionCategory": "incoming" |
||||
}, |
||||
"0x8add6c1ea089a8de9b15fa2056b1875360f17916755c88ace9e5092b7a4b1239": { |
||||
"blockNumber": "10892417", |
||||
"id": 4678200543090542, |
||||
"metamaskNetworkId": "1", |
||||
"status": "confirmed", |
||||
"time": 1600515224000, |
||||
"txParams": { |
||||
"from": "0x0681d8db095565fe8a346fa0277bffde9c0edbbf", |
||||
"gas": "0x5208", |
||||
"gasPrice": "0x1d1a94a200", |
||||
"nonce": "0x2bb8a5", |
||||
"to": "0x045c619e4d29bba3b92769508831b681b83d6a96", |
||||
"value": "0xe6ed27d6668000" |
||||
}, |
||||
"hash": "0x8add6c1ea089a8de9b15fa2056b1875360f17916755c88ace9e5092b7a4b1239", |
||||
"transactionCategory": "incoming" |
||||
}, |
||||
"0x50be62ab1cabd03ff104c602c11fdef7a50f3d73c55006d5583ba97950ab1144": { |
||||
"blockNumber": "10902987", |
||||
"id": 4678200543090545, |
||||
"metamaskNetworkId": "1", |
||||
"status": "confirmed", |
||||
"time": 1600654021000, |
||||
"txParams": { |
||||
"from": "0x64a845a5b02460acf8a3d84503b0d68d028b4bb4", |
||||
"gas": "0x5208", |
||||
"gasPrice": "0x147d357000", |
||||
"nonce": "0xf", |
||||
"to": "0x045c619e4d29bba3b92769508831b681b83d6a96", |
||||
"value": "0x63eb89da4ed00000" |
||||
}, |
||||
"hash": "0x50be62ab1cabd03ff104c602c11fdef7a50f3d73c55006d5583ba97950ab1144", |
||||
"transactionCategory": "incoming" |
||||
} |
||||
}, |
||||
"incomingTxLastFetchedBlocksByNetwork": { |
||||
"ropsten": 8872820, |
||||
"rinkeby": null, |
||||
"kovan": null, |
||||
"goerli": null, |
||||
"mainnet": 10902989 |
||||
}, |
||||
"permissionsRequests": [], |
||||
"permissionsDescriptions": {}, |
||||
"domains": { |
||||
"https://app.uniswap.org": { |
||||
"permissions": [ |
||||
{ |
||||
"@context": [ |
||||
"https://github.com/MetaMask/rpc-cap" |
||||
], |
||||
"invoker": "https://app.uniswap.org", |
||||
"parentCapability": "eth_accounts", |
||||
"id": "a7342e4b-beae-4525-a36c-c0635fd03359", |
||||
"date": 1620710693178, |
||||
"caveats": [ |
||||
{ |
||||
"type": "limitResponseLength", |
||||
"value": 1, |
||||
"name": "primaryAccountOnly" |
||||
}, |
||||
{ |
||||
"type": "filterResponse", |
||||
"value": [ |
||||
"0x64a845a5b02460acf8a3d84503b0d68d028b4bb4" |
||||
], |
||||
"name": "exposedAccounts" |
||||
} |
||||
] |
||||
} |
||||
] |
||||
} |
||||
}, |
||||
"permissionsLog": [ |
||||
{ |
||||
id: 'mockTokenTx2', |
||||
txParams: { |
||||
to: '0xafaketokenaddress', |
||||
from: '0xd85a4b6a394794842887b8284293d69163007bbb', |
||||
"id": 522690215, |
||||
"method": "eth_accounts", |
||||
"methodType": "restricted", |
||||
"origin": "https://metamask.io", |
||||
"request": { |
||||
"method": "eth_accounts", |
||||
"params": [], |
||||
"jsonrpc": "2.0", |
||||
"id": 522690215, |
||||
"origin": "https://metamask.io", |
||||
"tabId": 5 |
||||
}, |
||||
time: 1600000000000, |
||||
"requestTime": 1602643170686, |
||||
"response": { |
||||
"id": 522690215, |
||||
"jsonrpc": "2.0", |
||||
"result": [] |
||||
}, |
||||
"responseTime": 1602643170688, |
||||
"success": true |
||||
}, |
||||
{ |
||||
id: 'mockTokenTx3', |
||||
txParams: { |
||||
to: '0x8d6b81208414189a58339873ab429b6c47ab92d3', |
||||
from: '0xd85a4b6a394794842887b8284293d69163007bbb', |
||||
"id": 1620464600, |
||||
"method": "eth_accounts", |
||||
"methodType": "restricted", |
||||
"origin": "https://widget.getacute.io", |
||||
"request": { |
||||
"method": "eth_accounts", |
||||
"params": [], |
||||
"jsonrpc": "2.0", |
||||
"id": 1620464600, |
||||
"origin": "https://widget.getacute.io", |
||||
"tabId": 5 |
||||
}, |
||||
"requestTime": 1602643172935, |
||||
"response": { |
||||
"id": 1620464600, |
||||
"jsonrpc": "2.0", |
||||
"result": [] |
||||
}, |
||||
time: 1500000000000, |
||||
"responseTime": 1602643172935, |
||||
"success": true |
||||
}, |
||||
{ |
||||
id: 'mockEthTx1', |
||||
txParams: { |
||||
to: '0xd85a4b6a394794842887b8284293d69163007bbb', |
||||
from: '0xd85a4b6a394794842887b8284293d69163007bbb', |
||||
"id": 4279100021, |
||||
"method": "eth_accounts", |
||||
"methodType": "restricted", |
||||
"origin": "https://app.uniswap.org", |
||||
"request": { |
||||
"method": "eth_accounts", |
||||
"jsonrpc": "2.0", |
||||
"id": 4279100021, |
||||
"origin": "https://app.uniswap.org", |
||||
"tabId": 5 |
||||
}, |
||||
time: 1400000000000, |
||||
"requestTime": 1620710669962, |
||||
"response": { |
||||
"id": 4279100021, |
||||
"jsonrpc": "2.0", |
||||
"result": [] |
||||
}, |
||||
"responseTime": 1620710669963, |
||||
"success": true |
||||
}, |
||||
], |
||||
unapprovedMsgs: { |
||||
'0xabc': { id: 'unapprovedMessage1', time: 1650000000000 }, |
||||
'0xdef': { id: 'unapprovedMessage2', time: 1550000000000 }, |
||||
'0xghi': { id: 'unapprovedMessage3', time: 1450000000000 }, |
||||
}, |
||||
unapprovedMsgCount: 0, |
||||
unapprovedPersonalMsgs: {}, |
||||
unapprovedPersonalMsgCount: 0, |
||||
unapprovedDecryptMsgs: {}, |
||||
unapprovedDecryptMsgCount: 0, |
||||
unapprovedEncryptionPublicKeyMsgs: {}, |
||||
unapprovedEncryptionPublicKeyMsgCount: 0, |
||||
keyringTypes: ['Simple Key Pair', 'HD Key Tree'], |
||||
keyrings: [ |
||||
{ |
||||
type: 'HD Key Tree', |
||||
accounts: [ |
||||
'fdea65c8e26263f6d9a1b5de9555d2931a33b825', |
||||
'c5b8dbac4c1d3f152cdeb400e2313f309c410acb', |
||||
'2f8d4a878cfa04a6e60d46362f5644deab66572d', |
||||
], |
||||
"id": 4279100022, |
||||
"method": "eth_requestAccounts", |
||||
"methodType": "restricted", |
||||
"origin": "https://app.uniswap.org", |
||||
"request": { |
||||
"method": "eth_requestAccounts", |
||||
"jsonrpc": "2.0", |
||||
"id": 4279100022, |
||||
"origin": "https://app.uniswap.org", |
||||
"tabId": 5 |
||||
}, |
||||
"requestTime": 1620710686872, |
||||
"response": { |
||||
"id": 4279100022, |
||||
"jsonrpc": "2.0", |
||||
"result": [ |
||||
"0x64a845a5b02460acf8a3d84503b0d68d028b4bb4" |
||||
] |
||||
}, |
||||
"responseTime": 1620710693187, |
||||
"success": true |
||||
}, |
||||
{ |
||||
type: 'Simple Key Pair', |
||||
accounts: ['0xd85a4b6a394794842887b8284293d69163007bbb'], |
||||
"id": 4279100023, |
||||
"method": "eth_requestAccounts", |
||||
"methodType": "restricted", |
||||
"origin": "https://app.uniswap.org", |
||||
"request": { |
||||
"method": "eth_requestAccounts", |
||||
"jsonrpc": "2.0", |
||||
"id": 4279100023, |
||||
"origin": "https://app.uniswap.org", |
||||
"tabId": 5 |
||||
}, |
||||
"requestTime": 1620710693204, |
||||
"response": { |
||||
"id": 4279100023, |
||||
"jsonrpc": "2.0", |
||||
"result": [ |
||||
"0x64a845a5b02460acf8a3d84503b0d68d028b4bb4" |
||||
] |
||||
}, |
||||
"responseTime": 1620710693213, |
||||
"success": true |
||||
}, |
||||
{ |
||||
"id": 4279100034, |
||||
"method": "eth_accounts", |
||||
"methodType": "restricted", |
||||
"origin": "https://app.uniswap.org", |
||||
"request": { |
||||
"method": "eth_accounts", |
||||
"params": [], |
||||
"jsonrpc": "2.0", |
||||
"id": 4279100034, |
||||
"origin": "https://app.uniswap.org", |
||||
"tabId": 5 |
||||
}, |
||||
"requestTime": 1620710712072, |
||||
"response": { |
||||
"id": 4279100034, |
||||
"jsonrpc": "2.0", |
||||
"result": [ |
||||
"0x64a845a5b02460acf8a3d84503b0d68d028b4bb4" |
||||
] |
||||
}, |
||||
"responseTime": 1620710712075, |
||||
"success": true |
||||
} |
||||
], |
||||
selectedAddress: '0xd85a4b6a394794842887b8284293d69163007bbb', |
||||
send: { |
||||
gasLimit: '0xFFFF', |
||||
gasPrice: '0xaa', |
||||
gasTotal: '0xb451dc41b578', |
||||
tokenBalance: 3434, |
||||
from: '0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb', |
||||
to: '0x987fedabc', |
||||
amount: '0x080', |
||||
memo: '', |
||||
errors: { |
||||
someError: null, |
||||
}, |
||||
maxModeOn: false, |
||||
editingTransactionId: 97531, |
||||
}, |
||||
unapprovedTxs: { |
||||
4768706228115573: { |
||||
id: 4768706228115573, |
||||
time: 1487363153561, |
||||
status: TRANSACTION_STATUSES.UNAPPROVED, |
||||
gasMultiplier: 1, |
||||
metamaskNetworkId: '3', |
||||
txParams: { |
||||
from: '0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb', |
||||
to: '0x18a3462427bcc9133bb46e88bcbe39cd7ef0e761', |
||||
value: '0xde0b6b3a7640000', |
||||
metamaskId: 4768706228115573, |
||||
metamaskNetworkId: '3', |
||||
gas: '0x5209', |
||||
}, |
||||
txFee: '17e0186e60800', |
||||
txValue: 'de0b6b3a7640000', |
||||
maxCost: 'de234b52e4a0800', |
||||
gasPrice: '4a817c800', |
||||
}, |
||||
}, |
||||
currentLocale: 'en', |
||||
"permissionsHistory": { |
||||
"https://app.uniswap.org": { |
||||
"eth_accounts": { |
||||
"lastApproved": 1620710693213, |
||||
"accounts": { |
||||
"0x64a845a5b02460acf8a3d84503b0d68d028b4bb4": 1620710693213 |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"domainMetadata": { |
||||
"https://metamask.github.io": { |
||||
"name": "E2E Test Dapp", |
||||
"icon": "https://metamask.github.io/test-dapp/metamask-fox.svg", |
||||
"lastUpdated": 1620723443380, |
||||
"host": "metamask.github.io" |
||||
} |
||||
}, |
||||
"threeBoxSyncingAllowed": false, |
||||
"showRestorePrompt": true, |
||||
"threeBoxLastUpdated": 0, |
||||
"threeBoxAddress": null, |
||||
"threeBoxSynced": false, |
||||
"threeBoxDisabled": false, |
||||
"swapsState": { |
||||
"quotes": {}, |
||||
"fetchParams": null, |
||||
"tokens": null, |
||||
"tradeTxId": null, |
||||
"approveTxId": null, |
||||
"quotesLastFetched": null, |
||||
"customMaxGas": "", |
||||
"customGasPrice": null, |
||||
"selectedAggId": null, |
||||
"customApproveTxData": "", |
||||
"errorKey": "", |
||||
"topAggId": null, |
||||
"routeState": "", |
||||
"swapsFeatureIsLive": false, |
||||
"swapsQuoteRefreshTime": 60000 |
||||
}, |
||||
"ensResolutionsByAddress": {}, |
||||
"pendingApprovals": {}, |
||||
"pendingApprovalCount": 0 |
||||
}, |
||||
appState: { |
||||
menuOpen: false, |
||||
currentView: { |
||||
name: 'accountDetail', |
||||
detailView: null, |
||||
context: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', |
||||
}, |
||||
accountDetail: { |
||||
subview: 'transactions', |
||||
}, |
||||
modal: { |
||||
modalState: {}, |
||||
previousModalState: {}, |
||||
}, |
||||
isLoading: false, |
||||
warning: null, |
||||
scrollToBottom: false, |
||||
forgottenPassword: null, |
||||
"appState": { |
||||
"shouldClose": false, |
||||
"menuOpen": false, |
||||
"modal": { |
||||
"open": false, |
||||
"modalState": { |
||||
"name": null, |
||||
"props": {} |
||||
}, |
||||
"previousModalState": { |
||||
"name": null |
||||
} |
||||
}, |
||||
"sidebar": { |
||||
"isOpen": false, |
||||
"transitionName": "", |
||||
"type": "", |
||||
"props": {} |
||||
}, |
||||
"alertOpen": false, |
||||
"alertMessage": null, |
||||
"qrCodeData": null, |
||||
"networkDropdownOpen": false, |
||||
"accountDetail": { |
||||
"subview": "transactions" |
||||
}, |
||||
"isLoading": false, |
||||
"warning": null, |
||||
"buyView": {}, |
||||
"isMouseUser": true, |
||||
"gasIsLoading": false, |
||||
"defaultHdPaths": { |
||||
"trezor": "m/44'/60'/0'/0", |
||||
"ledger": "m/44'/60'/0'/0/0" |
||||
}, |
||||
"networksTabSelectedRpcUrl": "", |
||||
"networksTabIsInAddMode": false, |
||||
"loadingMethodData": false, |
||||
"show3BoxModalAfterImport": false, |
||||
"threeBoxLastUpdated": null, |
||||
"requestAccountTabs": {}, |
||||
"openMetaMaskTabs": {}, |
||||
"currentWindowTab": {} |
||||
}, |
||||
send: { |
||||
fromDropdownOpen: false, |
||||
toDropdownOpen: false, |
||||
errors: { someError: null }, |
||||
"history": { |
||||
"mostRecentOverviewPage": "/" |
||||
}, |
||||
}; |
||||
"send": { |
||||
"toDropdownOpen": false, |
||||
"gasButtonGroupShown": true, |
||||
"errors": {} |
||||
}, |
||||
"confirmTransaction": { |
||||
"txData": { |
||||
"id": 3111025347726181, |
||||
"time": 1620723786838, |
||||
"status": "unapproved", |
||||
"metamaskNetworkId": "3", |
||||
"chainId": "0x3", |
||||
"loadingDefaults": false, |
||||
"txParams": { |
||||
"from": "0x983211ce699ea5ab57cc528086154b6db1ad8e55", |
||||
"to": "0xad6d458402f60fd3bd25163575031acdce07538d", |
||||
"value": "0x0", |
||||
"data": "0x095ea7b30000000000000000000000009bc5baf874d2da8d216ae9f137804184ee5afef40000000000000000000000000000000000000000000000000000000000011170", |
||||
"gas": "0xea60", |
||||
"gasPrice": "0x4a817c800" |
||||
}, |
||||
"type": "standard", |
||||
"origin": "https://metamask.github.io", |
||||
"transactionCategory": "approve", |
||||
"history": [ |
||||
{ |
||||
"id": 3111025347726181, |
||||
"time": 1620723786838, |
||||
"status": "unapproved", |
||||
"metamaskNetworkId": "3", |
||||
"chainId": "0x3", |
||||
"loadingDefaults": true, |
||||
"txParams": { |
||||
"from": "0x983211ce699ea5ab57cc528086154b6db1ad8e55", |
||||
"to": "0xad6d458402f60fd3bd25163575031acdce07538d", |
||||
"value": "0x0", |
||||
"data": "0x095ea7b30000000000000000000000009bc5baf874d2da8d216ae9f137804184ee5afef40000000000000000000000000000000000000000000000000000000000011170", |
||||
"gas": "0xea60", |
||||
"gasPrice": "0x4a817c800" |
||||
}, |
||||
"type": "standard", |
||||
"origin": "https://metamask.github.io", |
||||
"transactionCategory": "approve" |
||||
}, |
||||
[ |
||||
{ |
||||
"op": "replace", |
||||
"path": "/loadingDefaults", |
||||
"value": false, |
||||
"note": "Added new unapproved transaction.", |
||||
"timestamp": 1620723786844 |
||||
} |
||||
] |
||||
] |
||||
}, |
||||
"tokenData": { |
||||
"args": [ |
||||
"0x9bc5baF874d2DA8D216aE9f137804184EE5AfEF4", |
||||
{ |
||||
"type": "BigNumber", |
||||
"hex": "0x011170" |
||||
} |
||||
], |
||||
"functionFragment": { |
||||
"type": "function", |
||||
"name": "approve", |
||||
"constant": false, |
||||
"inputs": [ |
||||
{ |
||||
"name": "_spender", |
||||
"type": "address", |
||||
"indexed": null, |
||||
"components": null, |
||||
"arrayLength": null, |
||||
"arrayChildren": null, |
||||
"baseType": "address", |
||||
"_isParamType": true |
||||
}, |
||||
{ |
||||
"name": "_value", |
||||
"type": "uint256", |
||||
"indexed": null, |
||||
"components": null, |
||||
"arrayLength": null, |
||||
"arrayChildren": null, |
||||
"baseType": "uint256", |
||||
"_isParamType": true |
||||
} |
||||
], |
||||
"outputs": [ |
||||
{ |
||||
"name": "success", |
||||
"type": "bool", |
||||
"indexed": null, |
||||
"components": null, |
||||
"arrayLength": null, |
||||
"arrayChildren": null, |
||||
"baseType": "bool", |
||||
"_isParamType": true |
||||
} |
||||
], |
||||
"payable": false, |
||||
"stateMutability": "nonpayable", |
||||
"gas": null, |
||||
"_isFragment": true |
||||
}, |
||||
"name": "approve", |
||||
"signature": "approve(address,uint256)", |
||||
"sighash": "0x095ea7b3", |
||||
"value": { |
||||
"type": "BigNumber", |
||||
"hex": "0x00" |
||||
} |
||||
}, |
||||
"fiatTransactionAmount": "0", |
||||
"fiatTransactionFee": "4.72", |
||||
"fiatTransactionTotal": "4.72", |
||||
"ethTransactionAmount": "0", |
||||
"ethTransactionFee": "0.0012", |
||||
"ethTransactionTotal": "0.0012", |
||||
"hexTransactionAmount": "0x0", |
||||
"hexTransactionFee": "0x44364c5bb0000", |
||||
"hexTransactionTotal": "0x44364c5bb0000", |
||||
"nonce": "" |
||||
}, |
||||
"swaps": { |
||||
"aggregatorMetadata": null, |
||||
"approveTxId": null, |
||||
"balanceError": false, |
||||
"fetchingQuotes": false, |
||||
"fromToken": null, |
||||
"quotesFetchStartTime": null, |
||||
"topAssets": {}, |
||||
"toToken": null, |
||||
"customGas": { |
||||
"price": null, |
||||
"limit": null, |
||||
"loading": "INITIAL", |
||||
"priceEstimates": {}, |
||||
"fallBackPrice": null |
||||
} |
||||
}, |
||||
"gas": { |
||||
"customData": { |
||||
"price": null, |
||||
"limit": "0xcb28" |
||||
}, |
||||
"basicEstimates": { |
||||
"average": 2 |
||||
}, |
||||
"basicEstimateIsLoading": false |
||||
} |
||||
} |
||||
|
||||
export default state; |
||||
|
@ -1,40 +1,194 @@ |
||||
import { strict as assert } from 'assert'; |
||||
import { ObservableStore } from '@metamask/obs-store'; |
||||
import { |
||||
BaseController, |
||||
BaseControllerV2, |
||||
ControllerMessenger, |
||||
} from '@metamask/controllers'; |
||||
import ComposableObservableStore from './ComposableObservableStore'; |
||||
|
||||
class OldExampleController extends BaseController { |
||||
name = 'OldExampleController'; |
||||
|
||||
defaultState = { |
||||
baz: 'baz', |
||||
}; |
||||
|
||||
constructor() { |
||||
super(); |
||||
this.initialize(); |
||||
} |
||||
|
||||
updateBaz(contents) { |
||||
this.update({ baz: contents }); |
||||
} |
||||
} |
||||
class ExampleController extends BaseControllerV2 { |
||||
static defaultState = { |
||||
bar: 'bar', |
||||
}; |
||||
|
||||
static metadata = { |
||||
bar: { persist: true, anonymous: true }, |
||||
}; |
||||
|
||||
constructor({ messenger }) { |
||||
super({ |
||||
messenger, |
||||
name: 'ExampleController', |
||||
metadata: ExampleController.metadata, |
||||
state: ExampleController.defaultState, |
||||
}); |
||||
} |
||||
|
||||
updateBar(contents) { |
||||
this.update(() => { |
||||
return { bar: contents }; |
||||
}); |
||||
} |
||||
} |
||||
|
||||
describe('ComposableObservableStore', function () { |
||||
it('should register initial state', function () { |
||||
const store = new ComposableObservableStore('state'); |
||||
const controllerMessenger = new ControllerMessenger(); |
||||
const store = new ComposableObservableStore({ |
||||
controllerMessenger, |
||||
state: 'state', |
||||
}); |
||||
assert.strictEqual(store.getState(), 'state'); |
||||
}); |
||||
|
||||
it('should register initial structure', function () { |
||||
const controllerMessenger = new ControllerMessenger(); |
||||
const testStore = new ObservableStore(); |
||||
const store = new ComposableObservableStore(null, { TestStore: testStore }); |
||||
const store = new ComposableObservableStore({ |
||||
config: { TestStore: testStore }, |
||||
controllerMessenger, |
||||
}); |
||||
testStore.putState('state'); |
||||
assert.deepEqual(store.getState(), { TestStore: 'state' }); |
||||
}); |
||||
|
||||
it('should update structure', function () { |
||||
it('should update structure with observable store', function () { |
||||
const controllerMessenger = new ControllerMessenger(); |
||||
const testStore = new ObservableStore(); |
||||
const store = new ComposableObservableStore(); |
||||
const store = new ComposableObservableStore({ controllerMessenger }); |
||||
store.updateStructure({ TestStore: testStore }); |
||||
testStore.putState('state'); |
||||
assert.deepEqual(store.getState(), { TestStore: 'state' }); |
||||
}); |
||||
|
||||
it('should update structure with BaseController-based controller', function () { |
||||
const controllerMessenger = new ControllerMessenger(); |
||||
const oldExampleController = new OldExampleController(); |
||||
const store = new ComposableObservableStore({ controllerMessenger }); |
||||
store.updateStructure({ OldExample: oldExampleController }); |
||||
oldExampleController.updateBaz('state'); |
||||
assert.deepEqual(store.getState(), { OldExample: { baz: 'state' } }); |
||||
}); |
||||
|
||||
it('should update structure with BaseControllerV2-based controller', function () { |
||||
const controllerMessenger = new ControllerMessenger(); |
||||
const exampleController = new ExampleController({ |
||||
messenger: controllerMessenger, |
||||
}); |
||||
const store = new ComposableObservableStore({ controllerMessenger }); |
||||
store.updateStructure({ Example: exampleController }); |
||||
exampleController.updateBar('state'); |
||||
console.log(exampleController.state); |
||||
assert.deepEqual(store.getState(), { Example: { bar: 'state' } }); |
||||
}); |
||||
|
||||
it('should update structure with all three types of stores', function () { |
||||
const controllerMessenger = new ControllerMessenger(); |
||||
const exampleStore = new ObservableStore(); |
||||
const exampleController = new ExampleController({ |
||||
messenger: controllerMessenger, |
||||
}); |
||||
const oldExampleController = new OldExampleController(); |
||||
const store = new ComposableObservableStore({ controllerMessenger }); |
||||
store.updateStructure({ |
||||
Example: exampleController, |
||||
OldExample: oldExampleController, |
||||
Store: exampleStore, |
||||
}); |
||||
exampleStore.putState('state'); |
||||
exampleController.updateBar('state'); |
||||
oldExampleController.updateBaz('state'); |
||||
assert.deepEqual(store.getState(), { |
||||
Example: { bar: 'state' }, |
||||
OldExample: { baz: 'state' }, |
||||
Store: 'state', |
||||
}); |
||||
}); |
||||
|
||||
it('should return flattened state', function () { |
||||
const controllerMessenger = new ControllerMessenger(); |
||||
const fooStore = new ObservableStore({ foo: 'foo' }); |
||||
const barStore = new ObservableStore({ bar: 'bar' }); |
||||
const store = new ComposableObservableStore(null, { |
||||
FooStore: fooStore, |
||||
BarStore: barStore, |
||||
const barController = new ExampleController({ |
||||
messenger: controllerMessenger, |
||||
}); |
||||
const bazController = new OldExampleController(); |
||||
const store = new ComposableObservableStore({ |
||||
config: { |
||||
FooStore: fooStore, |
||||
BarStore: barController, |
||||
BazStore: bazController, |
||||
}, |
||||
controllerMessenger, |
||||
state: { |
||||
FooStore: fooStore.getState(), |
||||
BarStore: barController.state, |
||||
BazStore: bazController.state, |
||||
}, |
||||
}); |
||||
assert.deepEqual(store.getFlatState(), { |
||||
foo: 'foo', |
||||
bar: 'bar', |
||||
baz: 'baz', |
||||
}); |
||||
assert.deepEqual(store.getFlatState(), { foo: 'foo', bar: 'bar' }); |
||||
}); |
||||
|
||||
it('should return empty flattened state when not configured', function () { |
||||
const store = new ComposableObservableStore(); |
||||
const controllerMessenger = new ControllerMessenger(); |
||||
const store = new ComposableObservableStore({ controllerMessenger }); |
||||
assert.deepEqual(store.getFlatState(), {}); |
||||
}); |
||||
|
||||
it('should throw if the controller messenger is omitted and the config includes a BaseControllerV2 controller', function () { |
||||
const controllerMessenger = new ControllerMessenger(); |
||||
const exampleController = new ExampleController({ |
||||
messenger: controllerMessenger, |
||||
}); |
||||
assert.throws( |
||||
() => |
||||
new ComposableObservableStore({ |
||||
config: { |
||||
Example: exampleController, |
||||
}, |
||||
}), |
||||
); |
||||
}); |
||||
|
||||
it('should throw if the controller messenger is omitted and updateStructure called with a BaseControllerV2 controller', function () { |
||||
const controllerMessenger = new ControllerMessenger(); |
||||
const exampleController = new ExampleController({ |
||||
messenger: controllerMessenger, |
||||
}); |
||||
const store = new ComposableObservableStore({}); |
||||
assert.throws(() => store.updateStructure({ Example: exampleController })); |
||||
}); |
||||
|
||||
it('should throw if initialized with undefined config entry', function () { |
||||
const controllerMessenger = new ControllerMessenger(); |
||||
assert.throws( |
||||
() => |
||||
new ComposableObservableStore({ |
||||
config: { |
||||
Example: undefined, |
||||
}, |
||||
controllerMessenger, |
||||
}), |
||||
); |
||||
}); |
||||
}); |
||||
|
@ -0,0 +1,32 @@ |
||||
import { cloneDeep } from 'lodash'; |
||||
|
||||
const version = 61; |
||||
|
||||
/** |
||||
* Initialize attributes related to recovery seed phrase reminder |
||||
*/ |
||||
export default { |
||||
version, |
||||
async migrate(originalVersionedData) { |
||||
const versionedData = cloneDeep(originalVersionedData); |
||||
versionedData.meta.version = version; |
||||
const state = versionedData.data; |
||||
const newState = transformState(state); |
||||
versionedData.data = newState; |
||||
return versionedData; |
||||
}, |
||||
}; |
||||
|
||||
function transformState(state) { |
||||
const currentTime = new Date().getTime(); |
||||
if (state.AppStateController) { |
||||
state.AppStateController.recoveryPhraseReminderHasBeenShown = false; |
||||
state.AppStateController.recoveryPhraseReminderLastShown = currentTime; |
||||
} else { |
||||
state.AppStateController = { |
||||
recoveryPhraseReminderHasBeenShown: false, |
||||
recoveryPhraseReminderLastShown: currentTime, |
||||
}; |
||||
} |
||||
return state; |
||||
} |
@ -0,0 +1,67 @@ |
||||
import { strict as assert } from 'assert'; |
||||
import sinon from 'sinon'; |
||||
import migration61 from './061'; |
||||
|
||||
describe('migration #61', function () { |
||||
let dateStub; |
||||
|
||||
beforeEach(function () { |
||||
dateStub = sinon.stub(Date.prototype, 'getTime').returns(1621580400000); |
||||
}); |
||||
|
||||
afterEach(function () { |
||||
dateStub.restore(); |
||||
}); |
||||
|
||||
it('should update the version metadata', async function () { |
||||
const oldStorage = { |
||||
meta: { |
||||
version: 60, |
||||
}, |
||||
data: {}, |
||||
}; |
||||
|
||||
const newStorage = await migration61.migrate(oldStorage); |
||||
assert.deepEqual(newStorage.meta, { |
||||
version: 61, |
||||
}); |
||||
}); |
||||
|
||||
it('should set recoveryPhraseReminderHasBeenShown to false and recoveryPhraseReminderLastShown to the current time', async function () { |
||||
const oldStorage = { |
||||
meta: {}, |
||||
data: { |
||||
AppStateController: { |
||||
existingProperty: 'foo', |
||||
}, |
||||
}, |
||||
}; |
||||
|
||||
const newStorage = await migration61.migrate(oldStorage); |
||||
assert.deepEqual(newStorage.data, { |
||||
AppStateController: { |
||||
recoveryPhraseReminderHasBeenShown: false, |
||||
recoveryPhraseReminderLastShown: 1621580400000, |
||||
existingProperty: 'foo', |
||||
}, |
||||
}); |
||||
}); |
||||
|
||||
it('should initialize AppStateController if it does not exist', async function () { |
||||
const oldStorage = { |
||||
meta: {}, |
||||
data: { |
||||
existingProperty: 'foo', |
||||
}, |
||||
}; |
||||
|
||||
const newStorage = await migration61.migrate(oldStorage); |
||||
assert.deepEqual(newStorage.data, { |
||||
existingProperty: 'foo', |
||||
AppStateController: { |
||||
recoveryPhraseReminderHasBeenShown: false, |
||||
recoveryPhraseReminderLastShown: 1621580400000, |
||||
}, |
||||
}); |
||||
}); |
||||
}); |
@ -0,0 +1,134 @@ |
||||
const spawn = require('cross-spawn'); |
||||
|
||||
/** |
||||
* Run a command to completion using the system shell. |
||||
* |
||||
* This will run a command with the specified arguments, and resolve when the |
||||
* process has exited. The STDOUT stream is monitored for output, which is |
||||
* returned after being split into lines. All output is expected to be UTF-8 |
||||
* encoded, and empty lines are removed from the output. |
||||
* |
||||
* Anything received on STDERR is assumed to indicate a problem, and is tracked |
||||
* as an error. |
||||
* |
||||
* @param {string} command - The command to run |
||||
* @param {Array<string>} [args] - The arguments to pass to the command |
||||
* @returns {Array<string>} Lines of output received via STDOUT |
||||
*/ |
||||
async function runCommand(command, args) { |
||||
const output = []; |
||||
let mostRecentError; |
||||
let errorSignal; |
||||
let errorCode; |
||||
const internalError = new Error('Internal'); |
||||
try { |
||||
await new Promise((resolve, reject) => { |
||||
const childProcess = spawn(command, args, { encoding: 'utf8' }); |
||||
childProcess.stdout.setEncoding('utf8'); |
||||
childProcess.stderr.setEncoding('utf8'); |
||||
|
||||
childProcess.on('error', (error) => { |
||||
mostRecentError = error; |
||||
}); |
||||
|
||||
childProcess.stdout.on('data', (message) => { |
||||
const nonEmptyLines = message.split('\n').filter((line) => line !== ''); |
||||
output.push(...nonEmptyLines); |
||||
}); |
||||
|
||||
childProcess.stderr.on('data', (message) => { |
||||
mostRecentError = new Error(message.trim()); |
||||
}); |
||||
|
||||
childProcess.once('exit', (code, signal) => { |
||||
if (code === 0) { |
||||
return resolve(); |
||||
} |
||||
errorCode = code; |
||||
errorSignal = signal; |
||||
return reject(internalError); |
||||
}); |
||||
}); |
||||
} catch (error) { |
||||
/** |
||||
* The error is re-thrown here in an `async` context to preserve the stack trace. If this was |
||||
* was thrown inside the Promise constructor, the stack trace would show a few frames of |
||||
* Node.js internals then end, without indicating where `runCommand` was called. |
||||
*/ |
||||
if (error === internalError) { |
||||
let errorMessage; |
||||
if (errorCode !== null && errorSignal !== null) { |
||||
errorMessage = `Terminated by signal '${errorSignal}'; exited with code '${errorCode}'`; |
||||
} else if (errorSignal !== null) { |
||||
errorMessage = `Terminaled by signal '${errorSignal}'`; |
||||
} else if (errorCode === null) { |
||||
errorMessage = 'Exited with no code or signal'; |
||||
} else { |
||||
errorMessage = `Exited with code '${errorCode}'`; |
||||
} |
||||
const improvedError = new Error(errorMessage); |
||||
if (mostRecentError) { |
||||
improvedError.cause = mostRecentError; |
||||
} |
||||
throw improvedError; |
||||
} |
||||
} |
||||
return output; |
||||
} |
||||
|
||||
/** |
||||
* Run a command to using the system shell. |
||||
* |
||||
* This will run a command with the specified arguments, and resolve when the |
||||
* process has exited. The STDIN, STDOUT and STDERR streams are inherited, |
||||
* letting the command take over completely until it completes. The success or |
||||
* failure of the process is determined entirely by the exit code; STDERR |
||||
* output is not used to indicate failure. |
||||
* |
||||
* @param {string} command - The command to run |
||||
* @param {Array<string>} [args] - The arguments to pass to the command |
||||
*/ |
||||
async function runInShell(command, args) { |
||||
let errorSignal; |
||||
let errorCode; |
||||
const internalError = new Error('Internal'); |
||||
try { |
||||
await new Promise((resolve, reject) => { |
||||
const childProcess = spawn(command, args, { |
||||
encoding: 'utf8', |
||||
stdio: 'inherit', |
||||
}); |
||||
|
||||
childProcess.once('exit', (code, signal) => { |
||||
if (code === 0) { |
||||
return resolve(); |
||||
} |
||||
errorCode = code; |
||||
errorSignal = signal; |
||||
return reject(internalError); |
||||
}); |
||||
}); |
||||
} catch (error) { |
||||
/** |
||||
* The error is re-thrown here in an `async` context to preserve the stack trace. If this was |
||||
* was thrown inside the Promise constructor, the stack trace would show a few frames of |
||||
* Node.js internals then end, without indicating where `runInShell` was called. |
||||
*/ |
||||
if (error === internalError) { |
||||
let errorMessage; |
||||
if (errorCode !== null && errorSignal !== null) { |
||||
errorMessage = `Terminated by signal '${errorSignal}'; exited with code '${errorCode}'`; |
||||
} else if (errorSignal !== null) { |
||||
errorMessage = `Terminaled by signal '${errorSignal}'`; |
||||
} else if (errorCode === null) { |
||||
errorMessage = 'Exited with no code or signal'; |
||||
} else { |
||||
errorMessage = `Exited with code '${errorCode}'`; |
||||
} |
||||
const improvedError = new Error(errorMessage); |
||||
throw improvedError; |
||||
} |
||||
} |
||||
} |
||||
|
||||
module.exports = { runCommand, runInShell }; |
@ -1,14 +1,7 @@ |
||||
{ |
||||
"exclude": [ |
||||
"*.log", |
||||
"builds", |
||||
"coverage", |
||||
"dist", |
||||
"docs", |
||||
"lavamoat", |
||||
"node:console", |
||||
"node_modules", |
||||
"patches", |
||||
"test-artifacts" |
||||
] |
||||
"compilerOptions": { |
||||
"target": "ES6", |
||||
"module": "commonjs" |
||||
}, |
||||
"include": ["ui/**/*.js", "app/**/*.js", "shared/**/*.js"] |
||||
} |
||||
|
@ -0,0 +1,11 @@ |
||||
import { addHexPrefix } from 'ethereumjs-util'; |
||||
|
||||
const TWENTY_ONE_THOUSAND = 21000; |
||||
const ONE_HUNDRED_THOUSAND = 100000; |
||||
|
||||
export const GAS_LIMITS = { |
||||
// maximum gasLimit of a simple send
|
||||
SIMPLE: addHexPrefix(TWENTY_ONE_THOUSAND.toString(16)), |
||||
// a base estimate for token transfers.
|
||||
BASE_TOKEN_ESTIMATE: addHexPrefix(ONE_HUNDRED_THOUSAND.toString(16)), |
||||
}; |
@ -0,0 +1,5 @@ |
||||
export const MILLISECOND = 1; |
||||
export const SECOND = MILLISECOND * 1000; |
||||
export const MINUTE = SECOND * 60; |
||||
export const HOUR = MINUTE * 60; |
||||
export const DAY = HOUR * 24; |
@ -1,96 +0,0 @@ |
||||
import { strict as assert } from 'assert'; |
||||
import { |
||||
MAINNET_CHAIN_ID, |
||||
MAINNET_NETWORK_ID, |
||||
ROPSTEN_CHAIN_ID, |
||||
ROPSTEN_NETWORK_ID, |
||||
} from '../../constants/network'; |
||||
import { getBlockExplorerUrlForTx } from '../transaction.utils'; |
||||
|
||||
const tests = [ |
||||
{ |
||||
expected: 'https://etherscan.io/tx/0xabcd', |
||||
transaction: { |
||||
metamaskNetworkId: MAINNET_NETWORK_ID, |
||||
hash: '0xabcd', |
||||
}, |
||||
}, |
||||
{ |
||||
expected: 'https://ropsten.etherscan.io/tx/0xdef0', |
||||
transaction: { |
||||
metamaskNetworkId: ROPSTEN_NETWORK_ID, |
||||
hash: '0xdef0', |
||||
}, |
||||
rpcPrefs: {}, |
||||
}, |
||||
{ |
||||
// test handling of `blockExplorerUrl` for a custom RPC
|
||||
expected: 'https://block.explorer/tx/0xabcd', |
||||
transaction: { |
||||
metamaskNetworkId: '31', |
||||
hash: '0xabcd', |
||||
}, |
||||
rpcPrefs: { |
||||
blockExplorerUrl: 'https://block.explorer', |
||||
}, |
||||
}, |
||||
{ |
||||
// test handling of trailing `/` in `blockExplorerUrl` for a custom RPC
|
||||
expected: 'https://another.block.explorer/tx/0xdef0', |
||||
transaction: { |
||||
networkId: '33', |
||||
hash: '0xdef0', |
||||
}, |
||||
rpcPrefs: { |
||||
blockExplorerUrl: 'https://another.block.explorer/', |
||||
}, |
||||
}, |
||||
{ |
||||
expected: 'https://etherscan.io/tx/0xabcd', |
||||
transaction: { |
||||
chainId: MAINNET_CHAIN_ID, |
||||
hash: '0xabcd', |
||||
}, |
||||
}, |
||||
{ |
||||
expected: 'https://ropsten.etherscan.io/tx/0xdef0', |
||||
transaction: { |
||||
chainId: ROPSTEN_CHAIN_ID, |
||||
hash: '0xdef0', |
||||
}, |
||||
rpcPrefs: {}, |
||||
}, |
||||
{ |
||||
// test handling of `blockExplorerUrl` for a custom RPC
|
||||
expected: 'https://block.explorer/tx/0xabcd', |
||||
transaction: { |
||||
chainId: '0x1f', |
||||
hash: '0xabcd', |
||||
}, |
||||
rpcPrefs: { |
||||
blockExplorerUrl: 'https://block.explorer', |
||||
}, |
||||
}, |
||||
{ |
||||
// test handling of trailing `/` in `blockExplorerUrl` for a custom RPC
|
||||
expected: 'https://another.block.explorer/tx/0xdef0', |
||||
transaction: { |
||||
chainId: '0x21', |
||||
hash: '0xdef0', |
||||
}, |
||||
rpcPrefs: { |
||||
blockExplorerUrl: 'https://another.block.explorer/', |
||||
}, |
||||
}, |
||||
]; |
||||
|
||||
describe('getBlockExplorerUrlForTx', function () { |
||||
tests.forEach((test) => { |
||||
it(`should return '${test.expected}' for transaction with hash: '${test.transaction.hash}'`, function () { |
||||
assert.strictEqual( |
||||
getBlockExplorerUrlForTx(test.transaction, test.rpcPrefs), |
||||
test.expected, |
||||
); |
||||
}); |
||||
}); |
||||
}); |
@ -0,0 +1,151 @@ |
||||
{ |
||||
"data": { |
||||
"AppStateController": { |
||||
"mkrMigrationReminderTimestamp": null |
||||
}, |
||||
"CachedBalancesController": { |
||||
"cachedBalances": { |
||||
"4": {} |
||||
} |
||||
}, |
||||
"CurrencyController": { |
||||
"conversionDate": 1575697244.188, |
||||
"conversionRate": 149.61, |
||||
"currentCurrency": "usd", |
||||
"nativeCurrency": "ETH" |
||||
}, |
||||
"IncomingTransactionsController": { |
||||
"incomingTransactions": {}, |
||||
"incomingTxLastFetchedBlocksByNetwork": { |
||||
"goerli": null, |
||||
"kovan": null, |
||||
"mainnet": null, |
||||
"rinkeby": 5570536 |
||||
} |
||||
}, |
||||
"KeyringController": { |
||||
"vault": "{\"data\":\"s6TpYjlUNsn7ifhEFTkuDGBUM1GyOlPrim7JSjtfIxgTt8/6MiXgiR/CtFfR4dWW2xhq85/NGIBYEeWrZThGdKGarBzeIqBfLFhw9n509jprzJ0zc2Rf+9HVFGLw+xxC4xPxgCS0IIWeAJQ+XtGcHmn0UZXriXm8Ja4kdlow6SWinB7sr/WM3R0+frYs4WgllkwggDf2/Tv6VHygvLnhtzp6hIJFyTjh+l/KnyJTyZW1TkZhDaNDzX3SCOHT\",\"iv\":\"FbeHDAW5afeWNORfNJBR0Q==\",\"salt\":\"TxZ+WbCW6891C9LK/hbMAoUsSEW1E8pyGLVBU6x5KR8=\"}" |
||||
}, |
||||
"NetworkController": { |
||||
"network": "1337", |
||||
"provider": { |
||||
"nickname": "Localhost 8545", |
||||
"rpcUrl": "http://localhost:8545", |
||||
"chainId": "0x539", |
||||
"ticker": "ETH", |
||||
"type": "rpc" |
||||
} |
||||
}, |
||||
"NotificationController": { |
||||
"notifications": { |
||||
"1": { |
||||
"isShown": true |
||||
}, |
||||
"3": { |
||||
"isShown": true |
||||
}, |
||||
"5": { |
||||
"isShown": true |
||||
}, |
||||
"6": { |
||||
"isShown": true |
||||
} |
||||
} |
||||
}, |
||||
"OnboardingController": { |
||||
"onboardingTabs": {}, |
||||
"seedPhraseBackedUp": false |
||||
}, |
||||
"PermissionsMetadata": { |
||||
"domainMetadata": { |
||||
"metamask.github.io": { |
||||
"icon": null, |
||||
"name": "M E T A M A S K M E S H T E S T" |
||||
} |
||||
}, |
||||
"permissionsHistory": {}, |
||||
"permissionsLog": [ |
||||
{ |
||||
"id": 746677923, |
||||
"method": "eth_accounts", |
||||
"methodType": "restricted", |
||||
"origin": "metamask.github.io", |
||||
"request": { |
||||
"id": 746677923, |
||||
"jsonrpc": "2.0", |
||||
"method": "eth_accounts", |
||||
"origin": "metamask.github.io", |
||||
"params": [] |
||||
}, |
||||
"requestTime": 1575697241368, |
||||
"response": { |
||||
"id": 746677923, |
||||
"jsonrpc": "2.0", |
||||
"result": [] |
||||
}, |
||||
"responseTime": 1575697241370, |
||||
"success": true |
||||
} |
||||
] |
||||
}, |
||||
"PreferencesController": { |
||||
"accountTokens": { |
||||
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": { |
||||
"0x539": [ |
||||
{ |
||||
"address": "0x86002be4cdd922de1ccb831582bf99284b99ac12", |
||||
"symbol": "TST", |
||||
"decimals": 4 |
||||
} |
||||
], |
||||
"rinkeby": [], |
||||
"ropsten": [] |
||||
} |
||||
}, |
||||
"assetImages": {}, |
||||
"completedOnboarding": true, |
||||
"currentLocale": "en", |
||||
"featureFlags": { |
||||
"showIncomingTransactions": true, |
||||
"transactionTime": false |
||||
}, |
||||
"firstTimeFlowType": "create", |
||||
"forgottenPassword": false, |
||||
"frequentRpcListDetail": [], |
||||
"identities": { |
||||
"0x5cfe73b6021e818b776b421b1c4db2474086a7e1": { |
||||
"address": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1", |
||||
"name": "Account 1" |
||||
} |
||||
}, |
||||
"knownMethodData": {}, |
||||
"lostIdentities": {}, |
||||
"metaMetricsId": null, |
||||
"metaMetricsSendCount": 0, |
||||
"participateInMetaMetrics": false, |
||||
"preferences": { |
||||
"useNativeCurrencyAsPrimaryCurrency": true |
||||
}, |
||||
"selectedAddress": "0x5cfe73b6021e818b776b421b1c4db2474086a7e1", |
||||
"suggestedTokens": {}, |
||||
"tokens": [ |
||||
{ |
||||
"address": "0x86002be4cdd922de1ccb831582bf99284b99ac12", |
||||
"symbol": "TST", |
||||
"decimals": 4 |
||||
} |
||||
], |
||||
"useBlockie": false, |
||||
"useNonceField": false, |
||||
"usePhishDetect": true |
||||
}, |
||||
"config": {}, |
||||
"firstTimeInfo": { |
||||
"date": 1575697234195, |
||||
"version": "7.7.0" |
||||
} |
||||
}, |
||||
"meta": { |
||||
"version": 40 |
||||
} |
||||
} |
@ -0,0 +1,94 @@ |
||||
const { strict: assert } = require('assert'); |
||||
const { withFixtures } = require('../helpers'); |
||||
|
||||
describe('Hide token', function () { |
||||
const ganacheOptions = { |
||||
accounts: [ |
||||
{ |
||||
secretKey: |
||||
'0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC', |
||||
balance: 25000000000000000000, |
||||
}, |
||||
], |
||||
}; |
||||
it('hides the token when clicked', async function () { |
||||
await withFixtures( |
||||
{ |
||||
fixtures: 'custom-token', |
||||
ganacheOptions, |
||||
title: this.test.title, |
||||
}, |
||||
async ({ driver }) => { |
||||
await driver.navigate(); |
||||
await driver.fill('#password', 'correct horse battery staple'); |
||||
await driver.press('#password', driver.Key.ENTER); |
||||
|
||||
await driver.waitForSelector({ |
||||
css: '.asset-list-item__token-button', |
||||
text: '0 TST', |
||||
}); |
||||
|
||||
let assets = await driver.findElements('.asset-list-item'); |
||||
assert.equal(assets.length, 2); |
||||
|
||||
await driver.clickElement({ text: 'Assets', tag: 'button' }); |
||||
|
||||
await driver.clickElement({ text: 'TST', tag: 'span' }); |
||||
|
||||
await driver.clickElement('[data-testid="asset-options__button"]'); |
||||
|
||||
await driver.clickElement('[data-testid="asset-options__hide"]'); |
||||
|
||||
// wait for confirm hide modal to be visible
|
||||
const confirmHideModal = await driver.findVisibleElement('span .modal'); |
||||
|
||||
await driver.clickElement( |
||||
'[data-testid="hide-token-confirmation__hide"]', |
||||
); |
||||
|
||||
// wait for confirm hide modal to be removed from DOM.
|
||||
await confirmHideModal.waitForElementState('hidden'); |
||||
|
||||
assets = await driver.findElements('.asset-list-item'); |
||||
assert.equal(assets.length, 1); |
||||
}, |
||||
); |
||||
}); |
||||
}); |
||||
|
||||
describe('Add existing token using search', function () { |
||||
const ganacheOptions = { |
||||
accounts: [ |
||||
{ |
||||
secretKey: |
||||
'0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC', |
||||
balance: 25000000000000000000, |
||||
}, |
||||
], |
||||
}; |
||||
it('renders the balance for the chosen token', async function () { |
||||
await withFixtures( |
||||
{ |
||||
fixtures: 'imported-account', |
||||
ganacheOptions, |
||||
title: this.test.title, |
||||
}, |
||||
async ({ driver }) => { |
||||
await driver.navigate(); |
||||
await driver.fill('#password', 'correct horse battery staple'); |
||||
await driver.press('#password', driver.Key.ENTER); |
||||
|
||||
await driver.clickElement({ text: 'Add Token', tag: 'button' }); |
||||
await driver.fill('#search-tokens', 'BAT'); |
||||
await driver.clickElement({ text: 'BAT', tag: 'span' }); |
||||
await driver.clickElement({ text: 'Next', tag: 'button' }); |
||||
await driver.clickElement({ text: 'Add Tokens', tag: 'button' }); |
||||
|
||||
await driver.waitForSelector({ |
||||
css: '.token-overview__primary-balance', |
||||
text: '0 BAT', |
||||
}); |
||||
}, |
||||
); |
||||
}); |
||||
}); |
@ -0,0 +1 @@ |
||||
export { default } from './recovery-phrase-reminder'; |
@ -0,0 +1,10 @@ |
||||
.recovery-phrase-reminder { |
||||
&__list { |
||||
list-style: disc; |
||||
padding-left: 20px; |
||||
|
||||
li { |
||||
margin-bottom: 5px; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,91 @@ |
||||
import React from 'react'; |
||||
import PropTypes from 'prop-types'; |
||||
import { useHistory } from 'react-router-dom'; |
||||
import { useI18nContext } from '../../../hooks/useI18nContext'; |
||||
// Components
|
||||
import Box from '../../ui/box'; |
||||
import Button from '../../ui/button'; |
||||
import Popover from '../../ui/popover'; |
||||
import Typography from '../../ui/typography'; |
||||
// Helpers
|
||||
import { |
||||
COLORS, |
||||
DISPLAY, |
||||
TEXT_ALIGN, |
||||
TYPOGRAPHY, |
||||
BLOCK_SIZES, |
||||
FONT_WEIGHT, |
||||
JUSTIFY_CONTENT, |
||||
} from '../../../helpers/constants/design-system'; |
||||
import { INITIALIZE_BACKUP_SEED_PHRASE_ROUTE } from '../../../helpers/constants/routes'; |
||||
|
||||
export default function RecoveryPhraseReminder({ onConfirm, hasBackedUp }) { |
||||
const t = useI18nContext(); |
||||
const history = useHistory(); |
||||
|
||||
const handleBackUp = () => { |
||||
history.push(INITIALIZE_BACKUP_SEED_PHRASE_ROUTE); |
||||
}; |
||||
|
||||
return ( |
||||
<Popover centerTitle title={t('recoveryPhraseReminderTitle')}> |
||||
<Box padding={[0, 4, 6, 4]} className="recovery-phrase-reminder"> |
||||
<Typography |
||||
color={COLORS.BLACK} |
||||
align={TEXT_ALIGN.CENTER} |
||||
variant={TYPOGRAPHY.Paragraph} |
||||
boxProps={{ marginTop: 0, marginBottom: 4 }} |
||||
> |
||||
{t('recoveryPhraseReminderSubText')} |
||||
</Typography> |
||||
<Box margin={[4, 0, 8, 0]}> |
||||
<ul className="recovery-phrase-reminder__list"> |
||||
<li> |
||||
<Typography |
||||
tag="span" |
||||
color={COLORS.BLACK} |
||||
fontWeight={FONT_WEIGHT.BOLD} |
||||
> |
||||
{t('recoveryPhraseReminderItemOne')} |
||||
</Typography> |
||||
</li> |
||||
<li>{t('recoveryPhraseReminderItemTwo')}</li> |
||||
<li> |
||||
{hasBackedUp ? ( |
||||
t('recoveryPhraseReminderHasBackedUp') |
||||
) : ( |
||||
<> |
||||
{t('recoveryPhraseReminderHasNotBackedUp')} |
||||
<Box display={DISPLAY.INLINE_BLOCK} marginLeft={1}> |
||||
<Button |
||||
type="link" |
||||
onClick={handleBackUp} |
||||
style={{ |
||||
fontSize: 'inherit', |
||||
padding: 0, |
||||
}} |
||||
> |
||||
{t('recoveryPhraseReminderBackupStart')} |
||||
</Button> |
||||
</Box> |
||||
</> |
||||
)} |
||||
</li> |
||||
</ul> |
||||
</Box> |
||||
<Box justifyContent={JUSTIFY_CONTENT.CENTER}> |
||||
<Box width={BLOCK_SIZES.TWO_FIFTHS}> |
||||
<Button rounded type="primary" onClick={onConfirm}> |
||||
{t('recoveryPhraseReminderConfirm')} |
||||
</Button> |
||||
</Box> |
||||
</Box> |
||||
</Box> |
||||
</Popover> |
||||
); |
||||
} |
||||
|
||||
RecoveryPhraseReminder.propTypes = { |
||||
hasBackedUp: PropTypes.bool.isRequired, |
||||
onConfirm: PropTypes.func.isRequired, |
||||
}; |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue