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'; |
import { TRANSACTION_STATUSES } from '../shared/constants/transaction'; |
||||||
|
|
||||||
const state = { |
const state = { |
||||||
metamask: { |
"invalidCustomNetwork": { |
||||||
isInitialized: true, |
"state": "CLOSED", |
||||||
isUnlocked: true, |
"networkName": "" |
||||||
featureFlags: { sendHexData: true }, |
}, |
||||||
identities: { |
"unconnectedAccount": { |
||||||
'0xfdea65c8e26263f6d9a1b5de9555d2931a33b825': { |
"state": "CLOSED" |
||||||
address: '0xfdea65c8e26263f6d9a1b5de9555d2931a33b825', |
}, |
||||||
name: 'Send Account 1', |
"activeTab": {}, |
||||||
}, |
"metamask": { |
||||||
'0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb': { |
"isInitialized": true, |
||||||
address: '0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb', |
"isUnlocked": true, |
||||||
name: 'Send Account 2', |
"isAccountMenuOpen": false, |
||||||
}, |
"rpcUrl": "https://rawtestrpc.metamask.io/", |
||||||
'0x2f8d4a878cfa04a6e60d46362f5644deab66572d': { |
"identities": { |
||||||
address: '0x2f8d4a878cfa04a6e60d46362f5644deab66572d', |
"0x983211ce699ea5ab57cc528086154b6db1ad8e55": { |
||||||
name: 'Send Account 3', |
"name": "Account 1", |
||||||
}, |
"address": "0x983211ce699ea5ab57cc528086154b6db1ad8e55" |
||||||
'0xd85a4b6a394794842887b8284293d69163007bbb': { |
}, |
||||||
address: '0xd85a4b6a394794842887b8284293d69163007bbb', |
"0xb19ac54efa18cc3a14a5b821bfec73d284bf0c5e": { |
||||||
name: 'Send Account 4', |
"name": "Account 2", |
||||||
}, |
"address": "0xb19ac54efa18cc3a14a5b821bfec73d284bf0c5e" |
||||||
}, |
}, |
||||||
cachedBalances: {}, |
"0x9d0ba4ddac06032527b140912ec808ab9451b788": { |
||||||
currentBlockGasLimit: '0x4c1878', |
"name": "Account 3", |
||||||
currentCurrency: 'USD', |
"address": "0x9d0ba4ddac06032527b140912ec808ab9451b788" |
||||||
conversionRate: 1200.88200327, |
} |
||||||
conversionDate: 1489013762, |
}, |
||||||
nativeCurrency: 'ETH', |
"unapprovedTxs": { |
||||||
frequentRpcList: [], |
"7786962153682822": { |
||||||
network: '3', |
"id": 7786962153682822, |
||||||
provider: { |
"time": 1620710815484, |
||||||
type: 'ropsten', |
"status": "unapproved", |
||||||
chainId: '0x3', |
"metamaskNetworkId": "3", |
||||||
}, |
"chainId": "0x3", |
||||||
accounts: { |
"loadingDefaults": false, |
||||||
'0xfdea65c8e26263f6d9a1b5de9555d2931a33b825': { |
"txParams": { |
||||||
code: '0x', |
"from": "0x64a845a5b02460acf8a3d84503b0d68d028b4bb4", |
||||||
balance: '0x47c9d71831c76efe', |
"to": "0xad6d458402f60fd3bd25163575031acdce07538d", |
||||||
nonce: '0x1b', |
"value": "0x0", |
||||||
address: '0xfdea65c8e26263f6d9a1b5de9555d2931a33b825', |
"data": "0xa9059cbb000000000000000000000000b19ac54efa18cc3a14a5b821bfec73d284bf0c5e0000000000000000000000000000000000000000000000003782dace9d900000", |
||||||
}, |
"gas": "0xcb28", |
||||||
'0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb': { |
"gasPrice": "0x77359400" |
||||||
code: '0x', |
}, |
||||||
balance: '0x37452b1315889f80', |
"type": "standard", |
||||||
nonce: '0xa', |
"origin": "metamask", |
||||||
address: '0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb', |
"transactionCategory": "transfer", |
||||||
}, |
"history": [ |
||||||
'0x2f8d4a878cfa04a6e60d46362f5644deab66572d': { |
{ |
||||||
code: '0x', |
"id": 7786962153682822, |
||||||
balance: '0x30c9d71831c76efe', |
"time": 1620710815484, |
||||||
nonce: '0x1c', |
"status": "unapproved", |
||||||
address: '0x2f8d4a878cfa04a6e60d46362f5644deab66572d', |
"metamaskNetworkId": "3", |
||||||
}, |
"chainId": "0x3", |
||||||
'0xd85a4b6a394794842887b8284293d69163007bbb': { |
"loadingDefaults": true, |
||||||
code: '0x', |
"txParams": { |
||||||
balance: '0x0', |
"from": "0x64a845a5b02460acf8a3d84503b0d68d028b4bb4", |
||||||
nonce: '0x0', |
"to": "0xad6d458402f60fd3bd25163575031acdce07538d", |
||||||
address: '0xd85a4b6a394794842887b8284293d69163007bbb', |
"value": "0x0", |
||||||
}, |
"data": "0xa9059cbb000000000000000000000000b19ac54efa18cc3a14a5b821bfec73d284bf0c5e0000000000000000000000000000000000000000000000003782dace9d900000", |
||||||
}, |
"gas": "0xcb28", |
||||||
addressBook: { |
"gasPrice": "0x77359400" |
||||||
'0x3': { |
}, |
||||||
'0x06195827297c7a80a443b6894d3bdb8824b43896': { |
"type": "standard", |
||||||
address: '0x06195827297c7a80a443b6894d3bdb8824b43896', |
"origin": "metamask", |
||||||
name: 'Address Book Account 1', |
"transactionCategory": "transfer" |
||||||
chainId: '0x3', |
}, |
||||||
}, |
[ |
||||||
}, |
{ |
||||||
}, |
"op": "replace", |
||||||
tokens: [ |
"path": "/loadingDefaults", |
||||||
{ |
"value": false, |
||||||
address: '0x1a195821297c7a80a433b6894d3bdb8824b43896', |
"note": "Added new unapproved transaction.", |
||||||
decimals: 18, |
"timestamp": 1620710815497 |
||||||
symbol: 'ABC', |
} |
||||||
}, |
] |
||||||
{ |
] |
||||||
address: '0x8d6b81208414189a58339873ab429b6c47ab92d3', |
} |
||||||
decimals: 4, |
}, |
||||||
symbol: 'DEF', |
"frequentRpcList": [], |
||||||
}, |
"addressBook": { |
||||||
{ |
"undefined": { |
||||||
address: '0xa42084c8d1d9a2198631988579bb36b48433a72b', |
"0": { |
||||||
decimals: 18, |
"address": "0x39a4e4Af7cCB654dB9500F258c64781c8FbD39F0", |
||||||
symbol: 'GHI', |
"name": "", |
||||||
}, |
"isEns": false |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
"contractExchangeRates": { |
||||||
|
"0xad6d458402f60fd3bd25163575031acdce07538d": 0 |
||||||
|
}, |
||||||
|
"tokens": [ |
||||||
|
{ |
||||||
|
"address": "0xad6d458402f60fd3bd25163575031acdce07538d", |
||||||
|
"symbol": "DAI", |
||||||
|
"decimals": 18 |
||||||
|
} |
||||||
], |
], |
||||||
transactions: {}, |
"pendingTokens": {}, |
||||||
currentNetworkTxList: [ |
"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" |
||||||
|
], |
||||||
|
"keyrings": [ |
||||||
{ |
{ |
||||||
id: 'mockTokenTx1', |
"type": "HD Key Tree", |
||||||
txParams: { |
"accounts": [ |
||||||
to: '0x8d6b81208414189a58339873ab429b6c47ab92d3', |
"0x64a845a5b02460acf8a3d84503b0d68d028b4bb4", |
||||||
from: '0xd85a4b6a394794842887b8284293d69163007bbb', |
"0xb19ac54efa18cc3a14a5b821bfec73d284bf0c5e", |
||||||
}, |
"0x9d0ba4ddac06032527b140912ec808ab9451b788" |
||||||
time: 1700000000000, |
] |
||||||
|
} |
||||||
|
], |
||||||
|
"frequentRpcListDetail": [ |
||||||
|
{ |
||||||
|
"rpcUrl": "http://localhost:8545", |
||||||
|
"chainId": "0x539", |
||||||
|
"ticker": "ETH", |
||||||
|
"nickname": "Localhost 8545", |
||||||
|
"rpcPrefs": {} |
||||||
|
} |
||||||
|
], |
||||||
|
"accountTokens": { |
||||||
|
"0x64a845a5b02460acf8a3d84503b0d68d028b4bb4": { |
||||||
|
"0x1": [ |
||||||
|
{ |
||||||
|
"address": "0x6b175474e89094c44da98b954eedeac495271d0f", |
||||||
|
"symbol": "DAI", |
||||||
|
"decimals": 18 |
||||||
}, |
}, |
||||||
{ |
{ |
||||||
id: 'mockTokenTx2', |
"address": "0x0d8775f648430679a709e98d2b0cb6250d2887ef", |
||||||
txParams: { |
"symbol": "BAT", |
||||||
to: '0xafaketokenaddress', |
"decimals": 18 |
||||||
from: '0xd85a4b6a394794842887b8284293d69163007bbb', |
} |
||||||
|
], |
||||||
|
"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" |
||||||
|
}, |
||||||
|
"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" |
||||||
}, |
}, |
||||||
time: 1600000000000, |
{ |
||||||
|
"type": "filterResponse", |
||||||
|
"value": [ |
||||||
|
"0x64a845a5b02460acf8a3d84503b0d68d028b4bb4" |
||||||
|
], |
||||||
|
"name": "exposedAccounts" |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
}, |
||||||
|
"permissionsLog": [ |
||||||
|
{ |
||||||
|
"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 |
||||||
|
}, |
||||||
|
"requestTime": 1602643170686, |
||||||
|
"response": { |
||||||
|
"id": 522690215, |
||||||
|
"jsonrpc": "2.0", |
||||||
|
"result": [] |
||||||
|
}, |
||||||
|
"responseTime": 1602643170688, |
||||||
|
"success": true |
||||||
}, |
}, |
||||||
{ |
{ |
||||||
id: 'mockTokenTx3', |
"id": 1620464600, |
||||||
txParams: { |
"method": "eth_accounts", |
||||||
to: '0x8d6b81208414189a58339873ab429b6c47ab92d3', |
"methodType": "restricted", |
||||||
from: '0xd85a4b6a394794842887b8284293d69163007bbb', |
"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": [] |
||||||
|
}, |
||||||
|
"responseTime": 1602643172935, |
||||||
|
"success": true |
||||||
}, |
}, |
||||||
time: 1500000000000, |
{ |
||||||
|
"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 |
||||||
|
}, |
||||||
|
"requestTime": 1620710669962, |
||||||
|
"response": { |
||||||
|
"id": 4279100021, |
||||||
|
"jsonrpc": "2.0", |
||||||
|
"result": [] |
||||||
|
}, |
||||||
|
"responseTime": 1620710669963, |
||||||
|
"success": true |
||||||
}, |
}, |
||||||
{ |
{ |
||||||
id: 'mockEthTx1', |
"id": 4279100022, |
||||||
txParams: { |
"method": "eth_requestAccounts", |
||||||
to: '0xd85a4b6a394794842887b8284293d69163007bbb', |
"methodType": "restricted", |
||||||
from: '0xd85a4b6a394794842887b8284293d69163007bbb', |
"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 |
||||||
}, |
}, |
||||||
time: 1400000000000, |
{ |
||||||
|
"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 |
||||||
|
} |
||||||
], |
], |
||||||
unapprovedMsgs: { |
"permissionsHistory": { |
||||||
'0xabc': { id: 'unapprovedMessage1', time: 1650000000000 }, |
"https://app.uniswap.org": { |
||||||
'0xdef': { id: 'unapprovedMessage2', time: 1550000000000 }, |
"eth_accounts": { |
||||||
'0xghi': { id: 'unapprovedMessage3', time: 1450000000000 }, |
"lastApproved": 1620710693213, |
||||||
}, |
"accounts": { |
||||||
unapprovedMsgCount: 0, |
"0x64a845a5b02460acf8a3d84503b0d68d028b4bb4": 1620710693213 |
||||||
unapprovedPersonalMsgs: {}, |
} |
||||||
unapprovedPersonalMsgCount: 0, |
} |
||||||
unapprovedDecryptMsgs: {}, |
} |
||||||
unapprovedDecryptMsgCount: 0, |
}, |
||||||
unapprovedEncryptionPublicKeyMsgs: {}, |
"domainMetadata": { |
||||||
unapprovedEncryptionPublicKeyMsgCount: 0, |
"https://metamask.github.io": { |
||||||
keyringTypes: ['Simple Key Pair', 'HD Key Tree'], |
"name": "E2E Test Dapp", |
||||||
keyrings: [ |
"icon": "https://metamask.github.io/test-dapp/metamask-fox.svg", |
||||||
{ |
"lastUpdated": 1620723443380, |
||||||
type: 'HD Key Tree', |
"host": "metamask.github.io" |
||||||
accounts: [ |
} |
||||||
'fdea65c8e26263f6d9a1b5de9555d2931a33b825', |
}, |
||||||
'c5b8dbac4c1d3f152cdeb400e2313f309c410acb', |
"threeBoxSyncingAllowed": false, |
||||||
'2f8d4a878cfa04a6e60d46362f5644deab66572d', |
"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": { |
||||||
|
"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": {} |
||||||
|
}, |
||||||
|
"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": [ |
||||||
{ |
{ |
||||||
type: 'Simple Key Pair', |
"name": "_spender", |
||||||
accounts: ['0xd85a4b6a394794842887b8284293d69163007bbb'], |
"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 |
||||||
|
} |
||||||
], |
], |
||||||
selectedAddress: '0xd85a4b6a394794842887b8284293d69163007bbb', |
"payable": false, |
||||||
send: { |
"stateMutability": "nonpayable", |
||||||
gasLimit: '0xFFFF', |
"gas": null, |
||||||
gasPrice: '0xaa', |
"_isFragment": true |
||||||
gasTotal: '0xb451dc41b578', |
}, |
||||||
tokenBalance: 3434, |
"name": "approve", |
||||||
from: '0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb', |
"signature": "approve(address,uint256)", |
||||||
to: '0x987fedabc', |
"sighash": "0x095ea7b3", |
||||||
amount: '0x080', |
"value": { |
||||||
memo: '', |
"type": "BigNumber", |
||||||
errors: { |
"hex": "0x00" |
||||||
someError: null, |
} |
||||||
}, |
}, |
||||||
maxModeOn: false, |
"fiatTransactionAmount": "0", |
||||||
editingTransactionId: 97531, |
"fiatTransactionFee": "4.72", |
||||||
}, |
"fiatTransactionTotal": "4.72", |
||||||
unapprovedTxs: { |
"ethTransactionAmount": "0", |
||||||
4768706228115573: { |
"ethTransactionFee": "0.0012", |
||||||
id: 4768706228115573, |
"ethTransactionTotal": "0.0012", |
||||||
time: 1487363153561, |
"hexTransactionAmount": "0x0", |
||||||
status: TRANSACTION_STATUSES.UNAPPROVED, |
"hexTransactionFee": "0x44364c5bb0000", |
||||||
gasMultiplier: 1, |
"hexTransactionTotal": "0x44364c5bb0000", |
||||||
metamaskNetworkId: '3', |
"nonce": "" |
||||||
txParams: { |
}, |
||||||
from: '0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb', |
"swaps": { |
||||||
to: '0x18a3462427bcc9133bb46e88bcbe39cd7ef0e761', |
"aggregatorMetadata": null, |
||||||
value: '0xde0b6b3a7640000', |
"approveTxId": null, |
||||||
metamaskId: 4768706228115573, |
"balanceError": false, |
||||||
metamaskNetworkId: '3', |
"fetchingQuotes": false, |
||||||
gas: '0x5209', |
"fromToken": null, |
||||||
}, |
"quotesFetchStartTime": null, |
||||||
txFee: '17e0186e60800', |
"topAssets": {}, |
||||||
txValue: 'de0b6b3a7640000', |
"toToken": null, |
||||||
maxCost: 'de234b52e4a0800', |
"customGas": { |
||||||
gasPrice: '4a817c800', |
"price": null, |
||||||
}, |
"limit": null, |
||||||
}, |
"loading": "INITIAL", |
||||||
currentLocale: 'en', |
"priceEstimates": {}, |
||||||
}, |
"fallBackPrice": null |
||||||
appState: { |
} |
||||||
menuOpen: false, |
}, |
||||||
currentView: { |
"gas": { |
||||||
name: 'accountDetail', |
"customData": { |
||||||
detailView: null, |
"price": null, |
||||||
context: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', |
"limit": "0xcb28" |
||||||
}, |
}, |
||||||
accountDetail: { |
"basicEstimates": { |
||||||
subview: 'transactions', |
"average": 2 |
||||||
}, |
}, |
||||||
modal: { |
"basicEstimateIsLoading": false |
||||||
modalState: {}, |
} |
||||||
previousModalState: {}, |
} |
||||||
}, |
|
||||||
isLoading: false, |
|
||||||
warning: null, |
|
||||||
scrollToBottom: false, |
|
||||||
forgottenPassword: null, |
|
||||||
}, |
|
||||||
send: { |
|
||||||
fromDropdownOpen: false, |
|
||||||
toDropdownOpen: false, |
|
||||||
errors: { someError: null }, |
|
||||||
}, |
|
||||||
}; |
|
||||||
|
|
||||||
export default state; |
export default state; |
||||||
|
@ -1,40 +1,194 @@ |
|||||||
import { strict as assert } from 'assert'; |
import { strict as assert } from 'assert'; |
||||||
import { ObservableStore } from '@metamask/obs-store'; |
import { ObservableStore } from '@metamask/obs-store'; |
||||||
|
import { |
||||||
|
BaseController, |
||||||
|
BaseControllerV2, |
||||||
|
ControllerMessenger, |
||||||
|
} from '@metamask/controllers'; |
||||||
import ComposableObservableStore from './ComposableObservableStore'; |
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 () { |
describe('ComposableObservableStore', function () { |
||||||
it('should register initial state', 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'); |
assert.strictEqual(store.getState(), 'state'); |
||||||
}); |
}); |
||||||
|
|
||||||
it('should register initial structure', function () { |
it('should register initial structure', function () { |
||||||
|
const controllerMessenger = new ControllerMessenger(); |
||||||
const testStore = new ObservableStore(); |
const testStore = new ObservableStore(); |
||||||
const store = new ComposableObservableStore(null, { TestStore: testStore }); |
const store = new ComposableObservableStore({ |
||||||
|
config: { TestStore: testStore }, |
||||||
|
controllerMessenger, |
||||||
|
}); |
||||||
testStore.putState('state'); |
testStore.putState('state'); |
||||||
assert.deepEqual(store.getState(), { TestStore: '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 testStore = new ObservableStore(); |
||||||
const store = new ComposableObservableStore(); |
const store = new ComposableObservableStore({ controllerMessenger }); |
||||||
store.updateStructure({ TestStore: testStore }); |
store.updateStructure({ TestStore: testStore }); |
||||||
testStore.putState('state'); |
testStore.putState('state'); |
||||||
assert.deepEqual(store.getState(), { TestStore: '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 () { |
it('should return flattened state', function () { |
||||||
|
const controllerMessenger = new ControllerMessenger(); |
||||||
const fooStore = new ObservableStore({ foo: 'foo' }); |
const fooStore = new ObservableStore({ foo: 'foo' }); |
||||||
const barStore = new ObservableStore({ bar: 'bar' }); |
const barController = new ExampleController({ |
||||||
const store = new ComposableObservableStore(null, { |
messenger: controllerMessenger, |
||||||
|
}); |
||||||
|
const bazController = new OldExampleController(); |
||||||
|
const store = new ComposableObservableStore({ |
||||||
|
config: { |
||||||
FooStore: fooStore, |
FooStore: fooStore, |
||||||
BarStore: barStore, |
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 () { |
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(), {}); |
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": [ |
"compilerOptions": { |
||||||
"*.log", |
"target": "ES6", |
||||||
"builds", |
"module": "commonjs" |
||||||
"coverage", |
}, |
||||||
"dist", |
"include": ["ui/**/*.js", "app/**/*.js", "shared/**/*.js"] |
||||||
"docs", |
|
||||||
"lavamoat", |
|
||||||
"node:console", |
|
||||||
"node_modules", |
|
||||||
"patches", |
|
||||||
"test-artifacts" |
|
||||||
] |
|
||||||
} |
} |
||||||
|
@ -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