1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Merge pull request #2 from MetaMask/master

update
This commit is contained in:
Orange 2018-03-15 00:20:32 +08:00 committed by GitHub
commit 95742596e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 108 additions and 6 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
npm-debug.log
node_modules
yarn.lock
app/bower_components
test/bower_components

View File

@ -1,13 +1,17 @@
# Changelog
## Current Master
- Add ability for internationalization.
- Will now throw an error if the `to` field in txParams is not valid.
- Will strip null values from the `to` field.
- Fix flashing to Log in screen after logging in or restoring from seed phrase.
- Increase tap areas for menu buttons on mobile
- Change all fonts in new-ui onboarding to Roboto, size 400
- Add a welcome screen to new-ui onboarding flow
- Make new-ui create password screen responsive
- Hide network dropdown before account is initialized
- Add ability for internationalization.
- Fix bug that could prevent MetaMask from saving the latest vault.
## 4.2.0 Tue Mar 06 2018

View File

@ -56,6 +56,7 @@
],
"permissions": [
"storage",
"unlimitedStorage",
"clipboardWrite",
"http://localhost:8545/",
"https://*.infura.io/"

View File

@ -1,9 +1,11 @@
const urlUtil = require('url')
const endOfStream = require('end-of-stream')
const pump = require('pump')
const debounce = require('debounce-stream')
const log = require('loglevel')
const extension = require('extensionizer')
const LocalStorageStore = require('obs-store/lib/localStorage')
const LocalStore = require('./lib/local-store')
const storeTransform = require('obs-store/lib/transform')
const asStream = require('obs-store/lib/asStream')
const ExtensionPlatform = require('./platforms/extension')
@ -44,6 +46,8 @@ let openMetamaskTabsIDs = {}
// state persistence
const diskStore = new LocalStorageStore({ storageKey: STORAGE_KEY })
const localStore = new LocalStore()
let versionedData
// initialization flow
initialize().catch(log.error)
@ -64,12 +68,23 @@ async function initialize () {
async function loadStateFromPersistence () {
// migrations
const migrator = new Migrator({ migrations })
// read from disk
let versionedData = diskStore.getState() || migrator.generateInitialState(firstTimeState)
// first from preferred, async API:
versionedData = (await localStore.get()) ||
diskStore.getState() ||
migrator.generateInitialState(firstTimeState)
// migrate data
versionedData = await migrator.migrateData(versionedData)
if (!versionedData) {
throw new Error('MetaMask - migrator returned undefined')
}
// write to disk
if (localStore.isSupported) localStore.set(versionedData)
diskStore.putState(versionedData)
// return just the data
return versionedData.data
}
@ -102,16 +117,30 @@ function setupController (initState) {
// setup state persistence
pump(
asStream(controller.store),
debounce(1000),
storeTransform(versionifyData),
asStream(diskStore)
storeTransform(syncDataWithExtension),
asStream(diskStore),
(error) => {
log.error('pump hit error', error)
}
)
function versionifyData (state) {
const versionedData = diskStore.getState()
versionedData.data = state
return versionedData
}
function syncDataWithExtension(state) {
if (localStore.isSupported) {
localStore.set(state)
.catch((err) => {
log.error('error setting state in local store:', err)
})
}
return state
}
//
// connect to other contexts
//

View File

@ -0,0 +1,38 @@
// We should not rely on local storage in an extension!
// We should use this instead!
// https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/storage/local
const extension = require('extensionizer')
const { promisify } = require('util')
module.exports = class ExtensionStore {
constructor() {
this.isSupported = !!(extension.storage.local)
if (!this.isSupported) {
log.error('Storage local API not available.')
}
const local = extension.storage.local
this._get = promisify(local.get).bind(local)
this._set = promisify(local.set).bind(local)
}
async get() {
if (!this.isSupported) return undefined
const result = await this._get()
// extension.storage.local always returns an obj
// if the object is empty, treat it as undefined
if (isEmpty(result)) {
return undefined
} else {
return result
}
}
async set(state) {
return this._set(state)
}
}
function isEmpty(obj) {
return Object.keys(obj).length === 0
}

View File

@ -4,7 +4,7 @@ const {
BnMultiplyByFraction,
bnToHex,
} = require('./util')
const addHexPrefix = require('ethereumjs-util').addHexPrefix
const { addHexPrefix, isValidAddress } = require('ethereumjs-util')
const SIMPLE_GAS_COST = '0x5208' // Hex for 21000, cost of a simple send.
/*
@ -113,12 +113,14 @@ module.exports = class TxGasUtil {
}
}
validateRecipient (txParams) {
if (txParams.to === '0x') {
if (txParams.to === '0x' || txParams.to === null ) {
if (txParams.data) {
delete txParams.to
} else {
throw new Error('Invalid recipient address')
}
} else if ( txParams.to !== undefined && !isValidAddress(txParams.to) ) {
throw new Error('Invalid recipient address')
}
return txParams
}

View File

@ -140,6 +140,19 @@ RestoreVaultScreen.prototype.createNewVaultAndRestore = function () {
// check seed
var seedBox = document.querySelector('textarea.twelve-word-phrase')
var seed = seedBox.value.trim()
// true if the string has more than a space between words.
if (seed.split(' ').length > 1) {
this.warning = 'there can only be a space between words'
this.props.dispatch(actions.displayWarning(this.warning))
return
}
// true if seed contains a character that is not between a-z or a space
if (!seed.match(/^[a-z ]+$/)) {
this.warning = 'seed words only have lowercase characters'
this.props.dispatch(actions.displayWarning(this.warning))
return
}
if (seed.split(' ').length !== 12) {
this.warning = 'seed phrases are 12 words long'
this.props.dispatch(actions.displayWarning(this.warning))

View File

@ -72,6 +72,7 @@
"clone": "^2.1.1",
"copy-to-clipboard": "^3.0.8",
"debounce": "^1.0.0",
"debounce-stream": "^2.0.0",
"deep-extend": "^0.5.0",
"detect-node": "^2.0.3",
"disc": "^1.3.2",

View File

@ -144,6 +144,19 @@ RestoreVaultScreen.prototype.createNewVaultAndRestore = function () {
// check seed
var seedBox = document.querySelector('textarea.twelve-word-phrase')
var seed = seedBox.value.trim()
// true if the string has more than a space between words.
if (seed.split(' ').length > 1) {
this.warning = 'there can only a space between words'
this.props.dispatch(actions.displayWarning(this.warning))
return
}
// true if seed contains a character that is not between a-z or a space
if (!seed.match(/^[a-z ]+$/)) {
this.warning = 'seed words only have lowercase characters'
this.props.dispatch(actions.displayWarning(this.warning))
return
}
if (seed.split(' ').length !== 12) {
this.warning = 'seed phrases are 12 words long'
this.props.dispatch(actions.displayWarning(this.warning))