Merge branch 'uat' of https://github.com/MetaMask/metamask-extension into cb-254
commit
ecc39c5a7a
@ -0,0 +1,10 @@ |
||||
{ |
||||
"appName": { |
||||
"message": "MetaMask", |
||||
"description": "The name of the application" |
||||
}, |
||||
"appDescription": { |
||||
"message": "이더리움 계좌 관리", |
||||
"description": "The description of the application" |
||||
} |
||||
} |
After Width: | Height: | Size: 9.5 KiB |
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 17 KiB |
@ -0,0 +1,110 @@ |
||||
const ObservableStore = require('obs-store') |
||||
const extend = require('xtend') |
||||
const BN = require('ethereumjs-util').BN |
||||
const EthQuery = require('eth-query') |
||||
|
||||
class RecentBlocksController { |
||||
|
||||
constructor (opts = {}) { |
||||
const { blockTracker, provider } = opts |
||||
this.blockTracker = blockTracker |
||||
this.ethQuery = new EthQuery(provider) |
||||
this.historyLength = opts.historyLength || 40 |
||||
|
||||
const initState = extend({ |
||||
recentBlocks: [], |
||||
}, opts.initState) |
||||
this.store = new ObservableStore(initState) |
||||
|
||||
this.blockTracker.on('block', this.processBlock.bind(this)) |
||||
this.backfill() |
||||
} |
||||
|
||||
resetState () { |
||||
this.store.updateState({ |
||||
recentBlocks: [], |
||||
}) |
||||
} |
||||
|
||||
processBlock (newBlock) { |
||||
const block = this.mapTransactionsToPrices(newBlock) |
||||
|
||||
const state = this.store.getState() |
||||
state.recentBlocks.push(block) |
||||
|
||||
while (state.recentBlocks.length > this.historyLength) { |
||||
state.recentBlocks.shift() |
||||
} |
||||
|
||||
this.store.updateState(state) |
||||
} |
||||
|
||||
backfillBlock (newBlock) { |
||||
const block = this.mapTransactionsToPrices(newBlock) |
||||
|
||||
const state = this.store.getState() |
||||
|
||||
if (state.recentBlocks.length < this.historyLength) { |
||||
state.recentBlocks.unshift(block) |
||||
} |
||||
|
||||
this.store.updateState(state) |
||||
} |
||||
|
||||
mapTransactionsToPrices (newBlock) { |
||||
const block = extend(newBlock, { |
||||
gasPrices: newBlock.transactions.map((tx) => { |
||||
return tx.gasPrice |
||||
}), |
||||
}) |
||||
delete block.transactions |
||||
return block |
||||
} |
||||
|
||||
async backfill() { |
||||
this.blockTracker.once('block', async (block) => { |
||||
let blockNum = block.number |
||||
let recentBlocks |
||||
let state = this.store.getState() |
||||
recentBlocks = state.recentBlocks |
||||
|
||||
while (recentBlocks.length < this.historyLength) { |
||||
try { |
||||
let blockNumBn = new BN(blockNum.substr(2), 16) |
||||
const newNum = blockNumBn.subn(1).toString(10) |
||||
const newBlock = await this.getBlockByNumber(newNum) |
||||
|
||||
if (newBlock) { |
||||
this.backfillBlock(newBlock) |
||||
blockNum = newBlock.number |
||||
} |
||||
|
||||
state = this.store.getState() |
||||
recentBlocks = state.recentBlocks |
||||
} catch (e) { |
||||
log.error(e) |
||||
} |
||||
await this.wait() |
||||
} |
||||
}) |
||||
} |
||||
|
||||
async wait () { |
||||
return new Promise((resolve) => { |
||||
setTimeout(resolve, 100) |
||||
}) |
||||
} |
||||
|
||||
async getBlockByNumber (number) { |
||||
const bn = new BN(number) |
||||
return new Promise((resolve, reject) => { |
||||
this.ethQuery.getBlockByNumber('0x' + bn.toString(16), true, (err, block) => { |
||||
if (err) reject(err) |
||||
resolve(block) |
||||
}) |
||||
}) |
||||
} |
||||
|
||||
} |
||||
|
||||
module.exports = RecentBlocksController |
@ -0,0 +1,739 @@ |
||||
{ |
||||
"metamask": { |
||||
"isInitialized": true, |
||||
"isUnlocked": true, |
||||
"isMascara": false, |
||||
"rpcTarget": "https://rawtestrpc.metamask.io/", |
||||
"identities": { |
||||
"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": { |
||||
"address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||
"name": "Account 1" |
||||
} |
||||
}, |
||||
"unapprovedTxs": {}, |
||||
"noActiveNotices": true, |
||||
"frequentRpcList": [ |
||||
"http://192.168.1.34:7545/" |
||||
], |
||||
"addressBook": [], |
||||
"tokenExchangeRates": {}, |
||||
"coinOptions": {}, |
||||
"provider": { |
||||
"type": "mainnet", |
||||
"rpcTarget": "https://mainnet.infura.io/metamask" |
||||
}, |
||||
"network": "1", |
||||
"accounts": { |
||||
"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": { |
||||
"code": "0x", |
||||
"balance": "0x1b3f641ed0c2f62", |
||||
"nonce": "0x35", |
||||
"address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825" |
||||
} |
||||
}, |
||||
"currentBlockGasLimit": "0x66df83", |
||||
"selectedAddressTxList": [ |
||||
{ |
||||
"id": 3516145537630216, |
||||
"time": 1512615655535, |
||||
"status": "submitted", |
||||
"metamaskNetworkId": "1", |
||||
"txParams": { |
||||
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||
"to": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||
"value": "0x16345785d8a0000", |
||||
"gasPrice": "0xc1b710800", |
||||
"gas": "0x7b0c", |
||||
"nonce": "0x35", |
||||
"chainId": "0x1" |
||||
}, |
||||
"gasPriceSpecified": false, |
||||
"gasLimitSpecified": false, |
||||
"estimatedGas": "5208", |
||||
"history": [ |
||||
{ |
||||
"id": 3516145537630216, |
||||
"time": 1512615655535, |
||||
"status": "unapproved", |
||||
"metamaskNetworkId": "1", |
||||
"txParams": { |
||||
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||
"to": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||
"value": "0x16345785d8a0000", |
||||
"gasPrice": "0xe6f7cec00", |
||||
"gas": "0x7b0c" |
||||
}, |
||||
"gasPriceSpecified": false, |
||||
"gasLimitSpecified": false, |
||||
"estimatedGas": "5208" |
||||
}, |
||||
[ |
||||
{ |
||||
"op": "replace", |
||||
"path": "/txParams/gasPrice", |
||||
"value": "0xc1b710800", |
||||
"note": "confTx: user approved transaction" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "replace", |
||||
"path": "/status", |
||||
"value": "approved", |
||||
"note": "txStateManager: setting status to approved" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "add", |
||||
"path": "/txParams/nonce", |
||||
"value": "0x35", |
||||
"note": "transactions#approveTransaction" |
||||
}, |
||||
{ |
||||
"op": "add", |
||||
"path": "/nonceDetails", |
||||
"value": { |
||||
"params": { |
||||
"highestLocalNonce": 53, |
||||
"highestSuggested": 53, |
||||
"nextNetworkNonce": 53 |
||||
}, |
||||
"local": { |
||||
"name": "local", |
||||
"nonce": 53, |
||||
"details": { |
||||
"startPoint": 53, |
||||
"highest": 53 |
||||
} |
||||
}, |
||||
"network": { |
||||
"name": "network", |
||||
"nonce": 53, |
||||
"details": { |
||||
"baseCount": 53 |
||||
} |
||||
} |
||||
} |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "add", |
||||
"path": "/txParams/chainId", |
||||
"value": "0x1", |
||||
"note": "txStateManager: setting status to signed" |
||||
}, |
||||
{ |
||||
"op": "replace", |
||||
"path": "/status", |
||||
"value": "signed" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "add", |
||||
"path": "/rawTx", |
||||
"value": "0xf86c35850c1b710800827b0c94fdea65c8e26263f6d9a1b5de9555d2931a33b82588016345785d8a00008026a0f5142ba79a13ca7ec65548953017edafb217803244bbf9821d9ad077d89921e9a03afcb614169c90be9905d5b469d06984825c76675d3a535937cdb8f2ad1c0a95", |
||||
"note": "transactions#publishTransaction" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "add", |
||||
"path": "/hash", |
||||
"value": "0x7ce19c0d128ca11293b44a4e6d3cc9063665c00ea8c8eb400f548e132c147353", |
||||
"note": "transactions#setTxHash" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "replace", |
||||
"path": "/status", |
||||
"value": "submitted", |
||||
"note": "txStateManager: setting status to submitted" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "add", |
||||
"path": "/firstRetryBlockNumber", |
||||
"value": "0x478ab3", |
||||
"note": "transactions/pending-tx-tracker#event: tx:block-update" |
||||
} |
||||
] |
||||
], |
||||
"nonceDetails": { |
||||
"params": { |
||||
"highestLocalNonce": 53, |
||||
"highestSuggested": 53, |
||||
"nextNetworkNonce": 53 |
||||
}, |
||||
"local": { |
||||
"name": "local", |
||||
"nonce": 53, |
||||
"details": { |
||||
"startPoint": 53, |
||||
"highest": 53 |
||||
} |
||||
}, |
||||
"network": { |
||||
"name": "network", |
||||
"nonce": 53, |
||||
"details": { |
||||
"baseCount": 53 |
||||
} |
||||
} |
||||
}, |
||||
"rawTx": "0xf86c35850c1b710800827b0c94fdea65c8e26263f6d9a1b5de9555d2931a33b82588016345785d8a00008026a0f5142ba79a13ca7ec65548953017edafb217803244bbf9821d9ad077d89921e9a03afcb614169c90be9905d5b469d06984825c76675d3a535937cdb8f2ad1c0a95", |
||||
"hash": "0x7ce19c0d128ca11293b44a4e6d3cc9063665c00ea8c8eb400f548e132c147353", |
||||
"firstRetryBlockNumber": "0x478ab3" |
||||
}, |
||||
{ |
||||
"id": 3516145537630211, |
||||
"time": 1512613432658, |
||||
"status": "confirmed", |
||||
"metamaskNetworkId": "1", |
||||
"txParams": { |
||||
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||
"to": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||
"value": "0x16345785d8a0000", |
||||
"gasPrice": "0xba43b7400", |
||||
"gas": "0x7b0c", |
||||
"nonce": "0x34", |
||||
"chainId": "0x1" |
||||
}, |
||||
"gasPriceSpecified": false, |
||||
"gasLimitSpecified": false, |
||||
"estimatedGas": "5208", |
||||
"history": [ |
||||
{ |
||||
"id": 3516145537630211, |
||||
"time": 1512613432658, |
||||
"status": "unapproved", |
||||
"metamaskNetworkId": "1", |
||||
"txParams": { |
||||
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||
"to": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||
"value": "0x16345785d8a0000", |
||||
"gasPrice": "0xdf8475800", |
||||
"gas": "0x7b0c" |
||||
}, |
||||
"gasPriceSpecified": false, |
||||
"gasLimitSpecified": false, |
||||
"estimatedGas": "5208" |
||||
}, |
||||
[ |
||||
{ |
||||
"op": "replace", |
||||
"path": "/txParams/gasPrice", |
||||
"value": "0xba43b7400", |
||||
"note": "confTx: user approved transaction" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "replace", |
||||
"path": "/status", |
||||
"value": "approved", |
||||
"note": "txStateManager: setting status to approved" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "add", |
||||
"path": "/txParams/nonce", |
||||
"value": "0x34", |
||||
"note": "transactions#approveTransaction" |
||||
}, |
||||
{ |
||||
"op": "add", |
||||
"path": "/nonceDetails", |
||||
"value": { |
||||
"params": { |
||||
"highestLocalNonce": 52, |
||||
"highestSuggested": 52, |
||||
"nextNetworkNonce": 52 |
||||
}, |
||||
"local": { |
||||
"name": "local", |
||||
"nonce": 52, |
||||
"details": { |
||||
"startPoint": 52, |
||||
"highest": 52 |
||||
} |
||||
}, |
||||
"network": { |
||||
"name": "network", |
||||
"nonce": 52, |
||||
"details": { |
||||
"baseCount": 52 |
||||
} |
||||
} |
||||
} |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "add", |
||||
"path": "/txParams/chainId", |
||||
"value": "0x1", |
||||
"note": "txStateManager: setting status to signed" |
||||
}, |
||||
{ |
||||
"op": "replace", |
||||
"path": "/status", |
||||
"value": "signed" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "add", |
||||
"path": "/rawTx", |
||||
"value": "0xf86c34850ba43b7400827b0c94fdea65c8e26263f6d9a1b5de9555d2931a33b82588016345785d8a00008026a073a4afdb8e8ad32b0cf9039af56c66baffd60d30e75cee5c1b783208824eafb8a0021ca6c1714a2c71281333ab77f776d3514348ab77967280fca8a5b4be44285e", |
||||
"note": "transactions#publishTransaction" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "add", |
||||
"path": "/hash", |
||||
"value": "0x5c98409883fdfd3cd24058a83b91470da6c40ffae41a40eb90d7dee0b837d26d", |
||||
"note": "transactions#setTxHash" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "replace", |
||||
"path": "/status", |
||||
"value": "submitted", |
||||
"note": "txStateManager: setting status to submitted" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "add", |
||||
"path": "/firstRetryBlockNumber", |
||||
"value": "0x478a2c", |
||||
"note": "transactions/pending-tx-tracker#event: tx:block-update" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "replace", |
||||
"path": "/status", |
||||
"value": "confirmed", |
||||
"note": "txStateManager: setting status to confirmed" |
||||
} |
||||
] |
||||
], |
||||
"nonceDetails": { |
||||
"params": { |
||||
"highestLocalNonce": 52, |
||||
"highestSuggested": 52, |
||||
"nextNetworkNonce": 52 |
||||
}, |
||||
"local": { |
||||
"name": "local", |
||||
"nonce": 52, |
||||
"details": { |
||||
"startPoint": 52, |
||||
"highest": 52 |
||||
} |
||||
}, |
||||
"network": { |
||||
"name": "network", |
||||
"nonce": 52, |
||||
"details": { |
||||
"baseCount": 52 |
||||
} |
||||
} |
||||
}, |
||||
"rawTx": "0xf86c34850ba43b7400827b0c94fdea65c8e26263f6d9a1b5de9555d2931a33b82588016345785d8a00008026a073a4afdb8e8ad32b0cf9039af56c66baffd60d30e75cee5c1b783208824eafb8a0021ca6c1714a2c71281333ab77f776d3514348ab77967280fca8a5b4be44285e", |
||||
"hash": "0x5c98409883fdfd3cd24058a83b91470da6c40ffae41a40eb90d7dee0b837d26d", |
||||
"firstRetryBlockNumber": "0x478a2c" |
||||
}, |
||||
{ |
||||
"id": 3516145537630210, |
||||
"time": 1512612826136, |
||||
"status": "confirmed", |
||||
"metamaskNetworkId": "1", |
||||
"txParams": { |
||||
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||
"to": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||
"value": "0x16345785d8a0000", |
||||
"gasPrice": "0xa7a358200", |
||||
"gas": "0x7b0c", |
||||
"nonce": "0x33", |
||||
"chainId": "0x1" |
||||
}, |
||||
"gasPriceSpecified": false, |
||||
"gasLimitSpecified": false, |
||||
"estimatedGas": "5208", |
||||
"history": [ |
||||
{ |
||||
"id": 3516145537630210, |
||||
"time": 1512612826136, |
||||
"status": "unapproved", |
||||
"metamaskNetworkId": "1", |
||||
"txParams": { |
||||
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||
"to": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||
"value": "0x16345785d8a0000", |
||||
"gasPrice": "0xba43b7400", |
||||
"gas": "0x7b0c" |
||||
}, |
||||
"gasPriceSpecified": false, |
||||
"gasLimitSpecified": false, |
||||
"estimatedGas": "5208" |
||||
}, |
||||
[ |
||||
{ |
||||
"op": "replace", |
||||
"path": "/txParams/gasPrice", |
||||
"value": "0xa7a358200", |
||||
"note": "confTx: user approved transaction" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "replace", |
||||
"path": "/status", |
||||
"value": "approved", |
||||
"note": "txStateManager: setting status to approved" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "add", |
||||
"path": "/txParams/nonce", |
||||
"value": "0x33", |
||||
"note": "transactions#approveTransaction" |
||||
}, |
||||
{ |
||||
"op": "add", |
||||
"path": "/nonceDetails", |
||||
"value": { |
||||
"params": { |
||||
"highestLocalNonce": 0, |
||||
"highestSuggested": 51, |
||||
"nextNetworkNonce": 51 |
||||
}, |
||||
"local": { |
||||
"name": "local", |
||||
"nonce": 51, |
||||
"details": { |
||||
"startPoint": 51, |
||||
"highest": 51 |
||||
} |
||||
}, |
||||
"network": { |
||||
"name": "network", |
||||
"nonce": 51, |
||||
"details": { |
||||
"baseCount": 51 |
||||
} |
||||
} |
||||
} |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "add", |
||||
"path": "/txParams/chainId", |
||||
"value": "0x1", |
||||
"note": "txStateManager: setting status to signed" |
||||
}, |
||||
{ |
||||
"op": "replace", |
||||
"path": "/status", |
||||
"value": "signed" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "add", |
||||
"path": "/rawTx", |
||||
"value": "0xf86c33850a7a358200827b0c94fdea65c8e26263f6d9a1b5de9555d2931a33b82588016345785d8a00008026a0021a8cd6c10208cc593e22af53637e5d127cee5cc6f9443a3e758a02afff1d7ca025f7420e974d3f2c668c165040987c72543a8e709bfea3528a62836a6ced9ce8", |
||||
"note": "transactions#publishTransaction" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "add", |
||||
"path": "/hash", |
||||
"value": "0x289772800898bc9cd414530d8581c0da257a9055e4aaaa6d10d92d700bfbd044", |
||||
"note": "transactions#setTxHash" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "replace", |
||||
"path": "/status", |
||||
"value": "submitted", |
||||
"note": "txStateManager: setting status to submitted" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "add", |
||||
"path": "/firstRetryBlockNumber", |
||||
"value": "0x478a04", |
||||
"note": "transactions/pending-tx-tracker#event: tx:block-update" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "replace", |
||||
"path": "/status", |
||||
"value": "confirmed", |
||||
"note": "txStateManager: setting status to confirmed" |
||||
} |
||||
] |
||||
], |
||||
"nonceDetails": { |
||||
"params": { |
||||
"highestLocalNonce": 0, |
||||
"highestSuggested": 51, |
||||
"nextNetworkNonce": 51 |
||||
}, |
||||
"local": { |
||||
"name": "local", |
||||
"nonce": 51, |
||||
"details": { |
||||
"startPoint": 51, |
||||
"highest": 51 |
||||
} |
||||
}, |
||||
"network": { |
||||
"name": "network", |
||||
"nonce": 51, |
||||
"details": { |
||||
"baseCount": 51 |
||||
} |
||||
} |
||||
}, |
||||
"rawTx": "0xf86c33850a7a358200827b0c94fdea65c8e26263f6d9a1b5de9555d2931a33b82588016345785d8a00008026a0021a8cd6c10208cc593e22af53637e5d127cee5cc6f9443a3e758a02afff1d7ca025f7420e974d3f2c668c165040987c72543a8e709bfea3528a62836a6ced9ce8", |
||||
"hash": "0x289772800898bc9cd414530d8581c0da257a9055e4aaaa6d10d92d700bfbd044", |
||||
"firstRetryBlockNumber": "0x478a04" |
||||
}, |
||||
{ |
||||
"id": 3516145537630209, |
||||
"time": 1512612809252, |
||||
"status": "failed", |
||||
"metamaskNetworkId": "1", |
||||
"txParams": { |
||||
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||
"to": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||
"value": "0x16345785d8a0000", |
||||
"gasPrice": "0x77359400", |
||||
"gas": "0x7b0c", |
||||
"nonce": "0x33", |
||||
"chainId": "0x1" |
||||
}, |
||||
"gasPriceSpecified": false, |
||||
"gasLimitSpecified": false, |
||||
"estimatedGas": "5208", |
||||
"history": [ |
||||
{ |
||||
"id": 3516145537630209, |
||||
"time": 1512612809252, |
||||
"status": "unapproved", |
||||
"metamaskNetworkId": "1", |
||||
"txParams": { |
||||
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||
"to": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||
"value": "0x16345785d8a0000", |
||||
"gasPrice": "0xba43b7400", |
||||
"gas": "0x7b0c" |
||||
}, |
||||
"gasPriceSpecified": false, |
||||
"gasLimitSpecified": false, |
||||
"estimatedGas": "5208" |
||||
}, |
||||
[ |
||||
{ |
||||
"op": "replace", |
||||
"path": "/txParams/gasPrice", |
||||
"value": "0x77359400", |
||||
"note": "confTx: user approved transaction" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "replace", |
||||
"path": "/status", |
||||
"value": "approved", |
||||
"note": "txStateManager: setting status to approved" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "add", |
||||
"path": "/txParams/nonce", |
||||
"value": "0x33", |
||||
"note": "transactions#approveTransaction" |
||||
}, |
||||
{ |
||||
"op": "add", |
||||
"path": "/nonceDetails", |
||||
"value": { |
||||
"params": { |
||||
"highestLocalNonce": 0, |
||||
"highestSuggested": 51, |
||||
"nextNetworkNonce": 51 |
||||
}, |
||||
"local": { |
||||
"name": "local", |
||||
"nonce": 51, |
||||
"details": { |
||||
"startPoint": 51, |
||||
"highest": 51 |
||||
} |
||||
}, |
||||
"network": { |
||||
"name": "network", |
||||
"nonce": 51, |
||||
"details": { |
||||
"baseCount": 51 |
||||
} |
||||
} |
||||
} |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "add", |
||||
"path": "/txParams/chainId", |
||||
"value": "0x1", |
||||
"note": "txStateManager: setting status to signed" |
||||
}, |
||||
{ |
||||
"op": "replace", |
||||
"path": "/status", |
||||
"value": "signed" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "add", |
||||
"path": "/rawTx", |
||||
"value": "0xf86b338477359400827b0c94fdea65c8e26263f6d9a1b5de9555d2931a33b82588016345785d8a00008025a098624a27ae79b2b1adc63b913850f266a920cb9d93e6588b8df9b8883eb1b323a00cc6fd855723a234f4f93b48caf7a7659366d09e5c5887f0a4c2e5fa68012cd7", |
||||
"note": "transactions#publishTransaction" |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "add", |
||||
"path": "/err", |
||||
"value": { |
||||
"message": "Error: [ethjs-rpc] rpc error with payload {\"id\":7801900228852,\"jsonrpc\":\"2.0\",\"params\":[\"0xf86b338477359400827b0c94fdea65c8e26263f6d9a1b5de9555d2931a33b82588016345785d8a00008025a098624a27ae79b2b1adc63b913850f266a920cb9d93e6588b8df9b8883eb1b323a00cc6fd855723a234f4f93b48caf7a7659366d09e5c5887f0a4c2e5fa68012cd7\"],\"method\":\"eth_sendRawTransaction\"} Error: transaction underpriced", |
||||
"stack": "Error: [ethjs-rpc] rpc error with payload {\"id\":7801900228852,\"jsonrpc\":\"2.0\",\"params\":[\"0xf86b338477359400827b0c94fdea65c8e26263f6d9a1b5de9555d2931a33b82588016345785d8a00008025a098624a27ae79b2b1adc63b913850f266a920cb9d93e6588b8df9b8883eb1b323a00cc6fd855723a234f4f93b48caf7a7659366d09e5c5887f0a4c2e5fa68012cd7\"],\"method\":\"eth_sendRawTransaction\"} Error: transaction underpriced\n at chrome-extension://ebjbdknjcgcbchkagneicjfpneaghdhb/scripts/background.js:60327:26\n at chrome-extension://ebjbdknjcgcbchkagneicjfpneaghdhb/scripts/background.js:88030:9\n at chrome-extension://ebjbdknjcgcbchkagneicjfpneaghdhb/scripts/background.js:16678:16\n at replenish (chrome-extension://ebjbdknjcgcbchkagneicjfpneaghdhb/scripts/background.js:16522:25)\n at iterateeCallback (chrome-extension://ebjbdknjcgcbchkagneicjfpneaghdhb/scripts/background.js:16512:17)\n at chrome-extension://ebjbdknjcgcbchkagneicjfpneaghdhb/scripts/background.js:16694:16\n at resultObj.id (chrome-extension://ebjbdknjcgcbchkagneicjfpneaghdhb/scripts/background.js:88012:9)\n at chrome-extension://ebjbdknjcgcbchkagneicjfpneaghdhb/scripts/background.js:16813:16\n at replenish (chrome-extension://ebjbdknjcgcbchkagneicjfpneaghdhb/scripts/background.js:16527:17)\n at iterateeCallback (chrome-extension://ebjbdknjcgcbchkagneicjfpneaghdhb/scripts/background.js:16512:17)" |
||||
} |
||||
} |
||||
], |
||||
[ |
||||
{ |
||||
"op": "replace", |
||||
"path": "/status", |
||||
"value": "failed", |
||||
"note": "txStateManager: setting status to failed" |
||||
} |
||||
] |
||||
], |
||||
"nonceDetails": { |
||||
"params": { |
||||
"highestLocalNonce": 0, |
||||
"highestSuggested": 51, |
||||
"nextNetworkNonce": 51 |
||||
}, |
||||
"local": { |
||||
"name": "local", |
||||
"nonce": 51, |
||||
"details": { |
||||
"startPoint": 51, |
||||
"highest": 51 |
||||
} |
||||
}, |
||||
"network": { |
||||
"name": "network", |
||||
"nonce": 51, |
||||
"details": { |
||||
"baseCount": 51 |
||||
} |
||||
} |
||||
}, |
||||
"rawTx": "0xf86b338477359400827b0c94fdea65c8e26263f6d9a1b5de9555d2931a33b82588016345785d8a00008025a098624a27ae79b2b1adc63b913850f266a920cb9d93e6588b8df9b8883eb1b323a00cc6fd855723a234f4f93b48caf7a7659366d09e5c5887f0a4c2e5fa68012cd7", |
||||
"err": { |
||||
"message": "Error: [ethjs-rpc] rpc error with payload {\"id\":7801900228852,\"jsonrpc\":\"2.0\",\"params\":[\"0xf86b338477359400827b0c94fdea65c8e26263f6d9a1b5de9555d2931a33b82588016345785d8a00008025a098624a27ae79b2b1adc63b913850f266a920cb9d93e6588b8df9b8883eb1b323a00cc6fd855723a234f4f93b48caf7a7659366d09e5c5887f0a4c2e5fa68012cd7\"],\"method\":\"eth_sendRawTransaction\"} Error: transaction underpriced", |
||||
"stack": "Error: [ethjs-rpc] rpc error with payload {\"id\":7801900228852,\"jsonrpc\":\"2.0\",\"params\":[\"0xf86b338477359400827b0c94fdea65c8e26263f6d9a1b5de9555d2931a33b82588016345785d8a00008025a098624a27ae79b2b1adc63b913850f266a920cb9d93e6588b8df9b8883eb1b323a00cc6fd855723a234f4f93b48caf7a7659366d09e5c5887f0a4c2e5fa68012cd7\"],\"method\":\"eth_sendRawTransaction\"} Error: transaction underpriced\n at chrome-extension://ebjbdknjcgcbchkagneicjfpneaghdhb/scripts/background.js:60327:26\n at chrome-extension://ebjbdknjcgcbchkagneicjfpneaghdhb/scripts/background.js:88030:9\n at chrome-extension://ebjbdknjcgcbchkagneicjfpneaghdhb/scripts/background.js:16678:16\n at replenish (chrome-extension://ebjbdknjcgcbchkagneicjfpneaghdhb/scripts/background.js:16522:25)\n at iterateeCallback (chrome-extension://ebjbdknjcgcbchkagneicjfpneaghdhb/scripts/background.js:16512:17)\n at chrome-extension://ebjbdknjcgcbchkagneicjfpneaghdhb/scripts/background.js:16694:16\n at resultObj.id (chrome-extension://ebjbdknjcgcbchkagneicjfpneaghdhb/scripts/background.js:88012:9)\n at chrome-extension://ebjbdknjcgcbchkagneicjfpneaghdhb/scripts/background.js:16813:16\n at replenish (chrome-extension://ebjbdknjcgcbchkagneicjfpneaghdhb/scripts/background.js:16527:17)\n at iterateeCallback (chrome-extension://ebjbdknjcgcbchkagneicjfpneaghdhb/scripts/background.js:16512:17)" |
||||
} |
||||
} |
||||
], |
||||
"unapprovedMsgs": {}, |
||||
"unapprovedMsgCount": 0, |
||||
"unapprovedPersonalMsgs": {}, |
||||
"unapprovedPersonalMsgCount": 0, |
||||
"unapprovedTypedMessages": {}, |
||||
"unapprovedTypedMessagesCount": 0, |
||||
"keyringTypes": [ |
||||
"Simple Key Pair", |
||||
"HD Key Tree" |
||||
], |
||||
"keyrings": [ |
||||
{ |
||||
"type": "HD Key Tree", |
||||
"accounts": [ |
||||
"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825" |
||||
] |
||||
} |
||||
], |
||||
"computedBalances": {}, |
||||
"currentAccountTab": "history", |
||||
"tokens": [ |
||||
{ |
||||
"address": "0x0d8775f648430679a709e98d2b0cb6250d2887ef", |
||||
"symbol": "BAT", |
||||
"decimals": "18" |
||||
} |
||||
], |
||||
"selectedAddress": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||
"currentCurrency": "usd", |
||||
"conversionRate": 418.62, |
||||
"conversionDate": 1512615622, |
||||
"infuraNetworkStatus": { |
||||
"mainnet": "ok", |
||||
"ropsten": "ok", |
||||
"kovan": "ok", |
||||
"rinkeby": "ok" |
||||
}, |
||||
"shapeShiftTxList": [], |
||||
"lostAccounts": [] |
||||
}, |
||||
"appState": { |
||||
"shouldClose": true, |
||||
"menuOpen": false, |
||||
"currentView": { |
||||
"name": "accountDetail", |
||||
"context": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825" |
||||
}, |
||||
"accountDetail": { |
||||
"subview": "transactions", |
||||
"accountExport": "none", |
||||
"privateKey": "" |
||||
}, |
||||
"transForward": false, |
||||
"isLoading": false, |
||||
"warning": null, |
||||
"forgottenPassword": false, |
||||
"scrollToBottom": false |
||||
}, |
||||
"identities": {}, |
||||
"version": "3.12.1", |
||||
"platform": { |
||||
"arch": "x86-64", |
||||
"nacl_arch": "x86-64", |
||||
"os": "mac" |
||||
}, |
||||
"browser": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36" |
||||
} |
File diff suppressed because one or more lines are too long
@ -0,0 +1,48 @@ |
||||
const assert = require('assert') |
||||
const PreferencesController = require('../../app/scripts/controllers/preferences') |
||||
|
||||
describe('preferences controller', function () { |
||||
let preferencesController |
||||
|
||||
before(() => { |
||||
preferencesController = new PreferencesController() |
||||
}) |
||||
|
||||
describe('addToken', function () { |
||||
it('should add that token to its state', async function () { |
||||
const address = '0xabcdef1234567' |
||||
const symbol = 'ABBR' |
||||
const decimals = 5 |
||||
|
||||
await preferencesController.addToken(address, symbol, decimals) |
||||
|
||||
const tokens = preferencesController.getTokens() |
||||
assert.equal(tokens.length, 1, 'one token added') |
||||
|
||||
const added = tokens[0] |
||||
assert.equal(added.address, address, 'set address correctly') |
||||
assert.equal(added.symbol, symbol, 'set symbol correctly') |
||||
assert.equal(added.decimals, decimals, 'set decimals correctly') |
||||
}) |
||||
|
||||
it('should allow updating a token value', async function () { |
||||
const address = '0xabcdef1234567' |
||||
const symbol = 'ABBR' |
||||
const decimals = 5 |
||||
|
||||
await preferencesController.addToken(address, symbol, decimals) |
||||
|
||||
const newDecimals = 6 |
||||
await preferencesController.addToken(address, symbol, newDecimals) |
||||
|
||||
const tokens = preferencesController.getTokens() |
||||
assert.equal(tokens.length, 1, 'one token added') |
||||
|
||||
const added = tokens[0] |
||||
assert.equal(added.address, address, 'set address correctly') |
||||
assert.equal(added.symbol, symbol, 'set symbol correctly') |
||||
assert.equal(added.decimals, newDecimals, 'updated decimals correctly') |
||||
}) |
||||
}) |
||||
}) |
||||
|
@ -0,0 +1,32 @@ |
||||
const assert = require('assert') |
||||
const TxGasUtils = require('../../app/scripts/lib/tx-gas-utils') |
||||
const { createStubedProvider } = require('../stub/provider') |
||||
|
||||
describe('Tx Gas Util', function () { |
||||
let txGasUtil, provider, providerResultStub |
||||
beforeEach(function () { |
||||
providerResultStub = {} |
||||
provider = createStubedProvider(providerResultStub) |
||||
txGasUtil = new TxGasUtils({ |
||||
provider, |
||||
}) |
||||
}) |
||||
|
||||
it('removes recipient for txParams with 0x when contract data is provided', function () { |
||||
const zeroRecipientandDataTxParams = { |
||||
from: '0x1678a085c290ebd122dc42cba69373b5953b831d', |
||||
to: '0x', |
||||
data: 'bytecode', |
||||
} |
||||
const sanitizedTxParams = txGasUtil.validateRecipient(zeroRecipientandDataTxParams) |
||||
assert.deepEqual(sanitizedTxParams, { from: '0x1678a085c290ebd122dc42cba69373b5953b831d', data: 'bytecode' }, 'no recipient with 0x') |
||||
}) |
||||
|
||||
it('should error when recipient is 0x', function () { |
||||
const zeroRecipientTxParams = { |
||||
from: '0x1678a085c290ebd122dc42cba69373b5953b831d', |
||||
to: '0x', |
||||
} |
||||
assert.throws(() => { txGasUtil.validateRecipient(zeroRecipientTxParams) }, Error, 'Invalid recipient address') |
||||
}) |
||||
}) |
@ -0,0 +1,96 @@ |
||||
const { Component } = require('react') |
||||
const PropTypes = require('prop-types') |
||||
const h = require('react-hyperscript') |
||||
const { connect } = require('react-redux') |
||||
const actions = require('../../actions') |
||||
|
||||
class NewAccountCreateForm extends Component { |
||||
constructor (props) { |
||||
super(props) |
||||
const { numberOfExistingAccounts = 0 } = props |
||||
const newAccountNumber = numberOfExistingAccounts + 1 |
||||
|
||||
this.state = { |
||||
newAccountName: `Account ${newAccountNumber}`, |
||||
} |
||||
} |
||||
|
||||
render () { |
||||
const { newAccountName } = this.state |
||||
|
||||
return h('div.new-account-create-form', [ |
||||
|
||||
h('div.new-account-create-form__input-label', {}, [ |
||||
'Account Name', |
||||
]), |
||||
|
||||
h('div.new-account-create-form__input-wrapper', {}, [ |
||||
h('input.new-account-create-form__input', { |
||||
value: this.state.newAccountName, |
||||
placeholder: 'E.g. My new account', |
||||
onChange: event => this.setState({ newAccountName: event.target.value }), |
||||
}, []), |
||||
]), |
||||
|
||||
h('div.new-account-create-form__buttons', {}, [ |
||||
|
||||
h('button.new-account-create-form__button-cancel', { |
||||
onClick: () => this.props.goHome(), |
||||
}, [ |
||||
'CANCEL', |
||||
]), |
||||
|
||||
h('button.new-account-create-form__button-create', { |
||||
onClick: () => this.props.createAccount(newAccountName), |
||||
}, [ |
||||
'CREATE', |
||||
]), |
||||
|
||||
]), |
||||
|
||||
]) |
||||
} |
||||
} |
||||
|
||||
NewAccountCreateForm.propTypes = { |
||||
hideModal: PropTypes.func, |
||||
showImportPage: PropTypes.func, |
||||
createAccount: PropTypes.func, |
||||
goHome: PropTypes.func, |
||||
numberOfExistingAccounts: PropTypes.number, |
||||
} |
||||
|
||||
const mapStateToProps = state => { |
||||
const { metamask: { network, selectedAddress, identities = {} } } = state |
||||
const numberOfExistingAccounts = Object.keys(identities).length |
||||
|
||||
return { |
||||
network, |
||||
address: selectedAddress, |
||||
numberOfExistingAccounts, |
||||
} |
||||
} |
||||
|
||||
const mapDispatchToProps = dispatch => { |
||||
return { |
||||
toCoinbase: (address) => { |
||||
dispatch(actions.buyEth({ network: '1', address, amount: 0 })) |
||||
}, |
||||
hideModal: () => { |
||||
dispatch(actions.hideModal()) |
||||
}, |
||||
createAccount: (newAccountName) => { |
||||
dispatch(actions.addNewAccount()) |
||||
.then((newAccountAddress) => { |
||||
if (newAccountName) { |
||||
dispatch(actions.saveAccountLabel(newAccountAddress, newAccountName)) |
||||
} |
||||
dispatch(actions.goHome()) |
||||
}) |
||||
}, |
||||
showImportPage: () => dispatch(actions.showImportPage()), |
||||
goHome: () => dispatch(actions.goHome()), |
||||
} |
||||
} |
||||
|
||||
module.exports = connect(mapStateToProps, mapDispatchToProps)(NewAccountCreateForm) |
@ -0,0 +1,81 @@ |
||||
const Component = require('react').Component |
||||
const h = require('react-hyperscript') |
||||
const inherits = require('util').inherits |
||||
const connect = require('react-redux').connect |
||||
const actions = require('../../actions') |
||||
const { getCurrentViewContext } = require('../../selectors') |
||||
const classnames = require('classnames') |
||||
|
||||
const NewAccountCreateForm = require('./create-form') |
||||
const NewAccountImportForm = require('../import') |
||||
|
||||
function mapStateToProps (state) { |
||||
return { |
||||
displayedForm: getCurrentViewContext(state), |
||||
} |
||||
} |
||||
|
||||
function mapDispatchToProps (dispatch) { |
||||
return { |
||||
displayForm: form => dispatch(actions.setNewAccountForm(form)), |
||||
showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)), |
||||
showExportPrivateKeyModal: () => { |
||||
dispatch(actions.showModal({ name: 'EXPORT_PRIVATE_KEY' })) |
||||
}, |
||||
hideModal: () => dispatch(actions.hideModal()), |
||||
saveAccountLabel: (address, label) => dispatch(actions.saveAccountLabel(address, label)), |
||||
} |
||||
} |
||||
|
||||
inherits(AccountDetailsModal, Component) |
||||
function AccountDetailsModal (props) { |
||||
Component.call(this) |
||||
|
||||
this.state = { |
||||
displayedForm: props.displayedForm, |
||||
} |
||||
} |
||||
|
||||
module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountDetailsModal) |
||||
|
||||
AccountDetailsModal.prototype.render = function () { |
||||
const { displayedForm, displayForm } = this.props |
||||
|
||||
return h('div.new-account', {}, [ |
||||
|
||||
h('div.new-account__header', [ |
||||
|
||||
h('div.new-account__title', 'New Account'), |
||||
|
||||
h('div.new-account__tabs', [ |
||||
|
||||
h('div.new-account__tabs__tab', { |
||||
className: classnames('new-account__tabs__tab', { |
||||
'new-account__tabs__selected': displayedForm === 'CREATE', |
||||
'new-account__tabs__unselected cursor-pointer': displayedForm !== 'CREATE', |
||||
}), |
||||
onClick: () => displayForm('CREATE'), |
||||
}, 'Create'), |
||||
|
||||
h('div.new-account__tabs__tab', { |
||||
className: classnames('new-account__tabs__tab', { |
||||
'new-account__tabs__selected': displayedForm === 'IMPORT', |
||||
'new-account__tabs__unselected cursor-pointer': displayedForm !== 'IMPORT', |
||||
}), |
||||
onClick: () => displayForm('IMPORT'), |
||||
}, 'Import'), |
||||
|
||||
]), |
||||
|
||||
]), |
||||
|
||||
h('div.new-account__form', [ |
||||
|
||||
displayedForm === 'CREATE' |
||||
? h(NewAccountCreateForm) |
||||
: h(NewAccountImportForm), |
||||
|
||||
]), |
||||
|
||||
]) |
||||
} |
@ -0,0 +1,184 @@ |
||||
const Component = require('react').Component |
||||
const h = require('react-hyperscript') |
||||
const inherits = require('util').inherits |
||||
const connect = require('react-redux').connect |
||||
const actions = require('../../actions') |
||||
const networkNames = require('../../../../app/scripts/config.js').networkNames |
||||
const ShapeshiftForm = require('../shapeshift-form') |
||||
|
||||
const DIRECT_DEPOSIT_ROW_TITLE = 'Directly Deposit Ether' |
||||
const DIRECT_DEPOSIT_ROW_TEXT = `If you already have some Ether, the quickest way to get Ether in
|
||||
your new wallet by direct deposit.` |
||||
const COINBASE_ROW_TITLE = 'Buy on Coinbase' |
||||
const COINBASE_ROW_TEXT = `Coinbase is the world’s most popular way to buy and sell bitcoin,
|
||||
ethereum, and litecoin.` |
||||
const SHAPESHIFT_ROW_TITLE = 'Deposit with ShapeShift' |
||||
const SHAPESHIFT_ROW_TEXT = `If you own other cryptocurrencies, you can trade and deposit Ether
|
||||
directly into your MetaMask wallet. No Account Needed.` |
||||
const FAUCET_ROW_TITLE = 'Test Faucet' |
||||
const facuetRowText = networkName => `Get Ether from a faucet for the ${networkName}` |
||||
|
||||
function mapStateToProps (state) { |
||||
return { |
||||
network: state.metamask.network, |
||||
address: state.metamask.selectedAddress, |
||||
} |
||||
} |
||||
|
||||
function mapDispatchToProps (dispatch) { |
||||
return { |
||||
toCoinbase: (address) => { |
||||
dispatch(actions.buyEth({ network: '1', address, amount: 0 })) |
||||
}, |
||||
hideModal: () => { |
||||
dispatch(actions.hideModal()) |
||||
}, |
||||
showAccountDetailModal: () => { |
||||
dispatch(actions.showModal({ name: 'ACCOUNT_DETAILS' })) |
||||
}, |
||||
toFaucet: network => dispatch(actions.buyEth({ network })), |
||||
} |
||||
} |
||||
|
||||
inherits(DepositEtherModal, Component) |
||||
function DepositEtherModal () { |
||||
Component.call(this) |
||||
|
||||
this.state = { |
||||
buyingWithShapeshift: false, |
||||
} |
||||
} |
||||
|
||||
module.exports = connect(mapStateToProps, mapDispatchToProps)(DepositEtherModal) |
||||
|
||||
DepositEtherModal.prototype.renderRow = function ({ |
||||
logo, |
||||
title, |
||||
text, |
||||
buttonLabel, |
||||
onButtonClick, |
||||
hide, |
||||
className, |
||||
hideButton, |
||||
hideTitle, |
||||
onBackClick, |
||||
showBackButton, |
||||
}) { |
||||
if (hide) { |
||||
return null |
||||
} |
||||
|
||||
return h('div', { |
||||
className: className || 'deposit-ether-modal__buy-row', |
||||
}, [ |
||||
|
||||
onBackClick && showBackButton && h('div.deposit-ether-modal__buy-row__back', { |
||||
onClick: onBackClick, |
||||
}, [ |
||||
|
||||
h('i.fa.fa-arrow-left.cursor-pointer'), |
||||
|
||||
]), |
||||
|
||||
h('div.deposit-ether-modal__buy-row__logo', [logo]), |
||||
|
||||
h('div.deposit-ether-modal__buy-row__description', [ |
||||
|
||||
!hideTitle && h('div.deposit-ether-modal__buy-row__description__title', [title]), |
||||
|
||||
h('div.deposit-ether-modal__buy-row__description__text', [text]), |
||||
|
||||
]), |
||||
|
||||
!hideButton && h('div.deposit-ether-modal__buy-row__button', [ |
||||
h('button.deposit-ether-modal__deposit-button', { |
||||
onClick: onButtonClick, |
||||
}, [buttonLabel]), |
||||
]), |
||||
|
||||
]) |
||||
} |
||||
|
||||
DepositEtherModal.prototype.render = function () { |
||||
const { network, toCoinbase, address, toFaucet } = this.props |
||||
const { buyingWithShapeshift } = this.state |
||||
|
||||
const isTestNetwork = ['3', '4', '42'].find(n => n === network) |
||||
const networkName = networkNames[network] |
||||
|
||||
return h('div.deposit-ether-modal', {}, [ |
||||
|
||||
h('div.deposit-ether-modal__header', [ |
||||
|
||||
h('div.deposit-ether-modal__header__title', ['Deposit Ether']), |
||||
|
||||
h('div.deposit-ether-modal__header__description', [ |
||||
'To interact with decentralized applications using MetaMask, you’ll need Ether in your wallet.', |
||||
]), |
||||
|
||||
h('div.deposit-ether-modal__header__close', { |
||||
onClick: () => { |
||||
this.setState({ buyingWithShapeshift: false }) |
||||
this.props.hideModal() |
||||
}, |
||||
}), |
||||
|
||||
]), |
||||
|
||||
h('div.deposit-ether-modal__buy-rows', [ |
||||
|
||||
this.renderRow({ |
||||
logo: h('img.deposit-ether-modal__buy-row__eth-logo', { src: '../../../images/eth_logo.svg' }), |
||||
title: DIRECT_DEPOSIT_ROW_TITLE, |
||||
text: DIRECT_DEPOSIT_ROW_TEXT, |
||||
buttonLabel: 'View Account', |
||||
onButtonClick: () => this.goToAccountDetailsModal(), |
||||
hide: buyingWithShapeshift, |
||||
}), |
||||
|
||||
this.renderRow({ |
||||
logo: h('i.fa.fa-tint.fa-2x'), |
||||
title: FAUCET_ROW_TITLE, |
||||
text: facuetRowText(networkName), |
||||
buttonLabel: 'Get Ether', |
||||
onButtonClick: () => toFaucet(network), |
||||
hide: !isTestNetwork || buyingWithShapeshift, |
||||
}), |
||||
|
||||
this.renderRow({ |
||||
logo: h('img.deposit-ether-modal__buy-row__coinbase-logo', { |
||||
src: '../../../images/coinbase logo.png', |
||||
}), |
||||
title: COINBASE_ROW_TITLE, |
||||
text: COINBASE_ROW_TEXT, |
||||
buttonLabel: 'Continue to Coinbase', |
||||
onButtonClick: () => toCoinbase(address), |
||||
hide: isTestNetwork || buyingWithShapeshift, |
||||
}), |
||||
|
||||
this.renderRow({ |
||||
logo: h('img.deposit-ether-modal__buy-row__shapeshift-logo', { |
||||
src: '../../../images/shapeshift logo.png', |
||||
}), |
||||
title: SHAPESHIFT_ROW_TITLE, |
||||
text: SHAPESHIFT_ROW_TEXT, |
||||
buttonLabel: 'Buy with Shapeshift', |
||||
onButtonClick: () => this.setState({ buyingWithShapeshift: true }), |
||||
hide: isTestNetwork, |
||||
hideButton: buyingWithShapeshift, |
||||
hideTitle: buyingWithShapeshift, |
||||
onBackClick: () => this.setState({ buyingWithShapeshift: false }), |
||||
showBackButton: this.state.buyingWithShapeshift, |
||||
className: buyingWithShapeshift && 'deposit-ether-modal__buy-row__shapeshift-buy', |
||||
}), |
||||
|
||||
buyingWithShapeshift && h(ShapeshiftForm), |
||||
|
||||
]), |
||||
]) |
||||
} |
||||
|
||||
DepositEtherModal.prototype.goToAccountDetailsModal = function () { |
||||
this.props.hideModal() |
||||
this.props.showAccountDetailModal() |
||||
} |
@ -1,308 +1,242 @@ |
||||
const PersistentForm = require('../../lib/persistent-form') |
||||
const h = require('react-hyperscript') |
||||
const inherits = require('util').inherits |
||||
const Component = require('react').Component |
||||
const connect = require('react-redux').connect |
||||
const actions = require('../actions') |
||||
const Qr = require('./qr-code') |
||||
const isValidAddress = require('../util').isValidAddress |
||||
module.exports = connect(mapStateToProps)(ShapeshiftForm) |
||||
const classnames = require('classnames') |
||||
const { qrcode } = require('qrcode-npm') |
||||
const { shapeShiftSubview, pairUpdate, buyWithShapeShift } = require('../actions') |
||||
const { isValidAddress } = require('../util') |
||||
const SimpleDropdown = require('./dropdowns/simple-dropdown') |
||||
|
||||
function mapStateToProps (state) { |
||||
const { |
||||
coinOptions, |
||||
tokenExchangeRates, |
||||
selectedAddress, |
||||
} = state.metamask |
||||
|
||||
return { |
||||
coinOptions, |
||||
tokenExchangeRates, |
||||
selectedAddress, |
||||
} |
||||
} |
||||
|
||||
function mapDispatchToProps (dispatch) { |
||||
return { |
||||
warning: state.appState.warning, |
||||
isSubLoading: state.appState.isSubLoading, |
||||
qrRequested: state.appState.qrRequested, |
||||
shapeShiftSubview: () => dispatch(shapeShiftSubview()), |
||||
pairUpdate: coin => dispatch(pairUpdate(coin)), |
||||
buyWithShapeShift: data => dispatch(buyWithShapeShift(data)), |
||||
} |
||||
} |
||||
|
||||
inherits(ShapeshiftForm, PersistentForm) |
||||
module.exports = connect(mapStateToProps, mapDispatchToProps)(ShapeshiftForm) |
||||
|
||||
inherits(ShapeshiftForm, Component) |
||||
function ShapeshiftForm () { |
||||
PersistentForm.call(this) |
||||
this.persistentFormParentId = 'shapeshift-buy-form' |
||||
Component.call(this) |
||||
|
||||
this.state = { |
||||
depositCoin: 'btc', |
||||
refundAddress: '', |
||||
showQrCode: false, |
||||
depositAddress: '', |
||||
errorMessage: '', |
||||
isLoading: false, |
||||
bought: false, |
||||
} |
||||
} |
||||
|
||||
ShapeshiftForm.prototype.render = function () { |
||||
return this.props.qrRequested ? h(Qr, {key: 'qr'}) : this.renderMain() |
||||
ShapeshiftForm.prototype.componentWillMount = function () { |
||||
this.props.shapeShiftSubview() |
||||
} |
||||
|
||||
ShapeshiftForm.prototype.renderMain = function () { |
||||
const marketinfo = this.props.buyView.formView.marketinfo |
||||
const coinOptions = this.props.buyView.formView.coinOptions |
||||
var coin = marketinfo.pair.split('_')[0].toUpperCase() |
||||
|
||||
return h('.flex-column', { |
||||
style: { |
||||
position: 'relative', |
||||
padding: '25px', |
||||
paddingTop: '5px', |
||||
width: '90%', |
||||
minHeight: '215px', |
||||
alignItems: 'center', |
||||
overflowY: 'auto', |
||||
}, |
||||
}, [ |
||||
h('.flex-row', { |
||||
style: { |
||||
justifyContent: 'center', |
||||
alignItems: 'baseline', |
||||
height: '42px', |
||||
}, |
||||
}, [ |
||||
h('img', { |
||||
src: coinOptions[coin].image, |
||||
width: '25px', |
||||
height: '25px', |
||||
style: { |
||||
marginRight: '5px', |
||||
}, |
||||
}), |
||||
ShapeshiftForm.prototype.onCoinChange = function (e) { |
||||
const coin = e.target.value |
||||
this.setState({ |
||||
depositCoin: coin, |
||||
errorMessage: '', |
||||
}) |
||||
this.props.pairUpdate(coin) |
||||
} |
||||
|
||||
h('.input-container', { |
||||
position: 'relative', |
||||
}, [ |
||||
h('input#fromCoin.buy-inputs.ex-coins', { |
||||
type: 'text', |
||||
list: 'coinList', |
||||
autoFocus: true, |
||||
dataset: { |
||||
persistentFormId: 'input-coin', |
||||
}, |
||||
style: { |
||||
boxSizing: 'border-box', |
||||
}, |
||||
onChange: this.handleLiveInput.bind(this), |
||||
defaultValue: 'BTC', |
||||
}), |
||||
ShapeshiftForm.prototype.onBuyWithShapeShift = function () { |
||||
this.setState({ |
||||
isLoading: true, |
||||
showQrCode: true, |
||||
}) |
||||
|
||||
this.renderCoinList(), |
||||
const { |
||||
buyWithShapeShift, |
||||
selectedAddress: withdrawal, |
||||
} = this.props |
||||
const { |
||||
refundAddress: returnAddress, |
||||
depositCoin, |
||||
} = this.state |
||||
const pair = `${depositCoin}_eth` |
||||
const data = { |
||||
withdrawal, |
||||
pair, |
||||
returnAddress, |
||||
// Public api key
|
||||
'apiKey': '803d1f5df2ed1b1476e4b9e6bcd089e34d8874595dda6a23b67d93c56ea9cc2445e98a6748b219b2b6ad654d9f075f1f1db139abfa93158c04e825db122c14b6', |
||||
} |
||||
|
||||
h('i.fa.fa-pencil-square-o.edit-text', { |
||||
style: { |
||||
fontSize: '12px', |
||||
color: '#F7861C', |
||||
position: 'absolute', |
||||
}, |
||||
}), |
||||
if (isValidAddress(withdrawal)) { |
||||
buyWithShapeShift(data) |
||||
.then(d => this.setState({ |
||||
showQrCode: true, |
||||
depositAddress: d.deposit, |
||||
isLoading: false, |
||||
})) |
||||
.catch(() => this.setState({ |
||||
showQrCode: false, |
||||
errorMessage: 'Invalid Request', |
||||
isLoading: false, |
||||
})) |
||||
} |
||||
} |
||||
|
||||
ShapeshiftForm.prototype.renderMetadata = function (label, value) { |
||||
return h('div', {className: 'shapeshift-form__metadata-wrapper'}, [ |
||||
|
||||
h('div.shapeshift-form__metadata-label', {}, [ |
||||
h('span', `${label}:`), |
||||
]), |
||||
|
||||
h('.icon-control', { |
||||
style: { |
||||
position: 'relative', |
||||
}, |
||||
}, [ |
||||
// Not visible on the screen, can't see it on master.
|
||||
|
||||
// h('i.fa.fa-refresh.fa-4.orange', {
|
||||
// style: {
|
||||
// bottom: '5px',
|
||||
// left: '5px',
|
||||
// color: '#F7861C',
|
||||
// },
|
||||
// onClick: this.updateCoin.bind(this),
|
||||
// }),
|
||||
h('i.fa.fa-chevron-right.fa-4.orange', { |
||||
style: { |
||||
position: 'absolute', |
||||
bottom: '35%', |
||||
left: '0%', |
||||
color: '#F7861C', |
||||
}, |
||||
onClick: this.updateCoin.bind(this), |
||||
}), |
||||
h('div.shapeshift-form__metadata-value', {}, [ |
||||
h('span', value), |
||||
]), |
||||
|
||||
h('#toCoin.ex-coins', marketinfo.pair.split('_')[1].toUpperCase()), |
||||
]) |
||||
} |
||||
|
||||
h('img', { |
||||
src: coinOptions[marketinfo.pair.split('_')[1].toUpperCase()].image, |
||||
width: '25px', |
||||
height: '25px', |
||||
style: { |
||||
marginLeft: '5px', |
||||
}, |
||||
}), |
||||
]), |
||||
ShapeshiftForm.prototype.renderMarketInfo = function () { |
||||
const { depositCoin } = this.state |
||||
const coinPair = `${depositCoin}_eth` |
||||
const { tokenExchangeRates } = this.props |
||||
const { |
||||
limit, |
||||
rate, |
||||
minimum, |
||||
} = tokenExchangeRates[coinPair] || {} |
||||
|
||||
h('.flex-column', { |
||||
style: { |
||||
marginTop: '1%', |
||||
alignItems: 'flex-start', |
||||
}, |
||||
}, [ |
||||
this.props.warning ? |
||||
this.props.warning && |
||||
h('span.error.flex-center', { |
||||
style: { |
||||
textAlign: 'center', |
||||
width: '229px', |
||||
height: '82px', |
||||
}, |
||||
}, this.props.warning) |
||||
: this.renderInfo(), |
||||
|
||||
this.renderRefundAddressForCoin(coin), |
||||
]), |
||||
return h('div.shapeshift-form__metadata', {}, [ |
||||
|
||||
this.renderMetadata('Status', limit ? 'Available' : 'Unavailable'), |
||||
this.renderMetadata('Limit', limit), |
||||
this.renderMetadata('Exchange Rate', rate), |
||||
this.renderMetadata('Minimum', minimum), |
||||
|
||||
]) |
||||
} |
||||
|
||||
ShapeshiftForm.prototype.renderRefundAddressForCoin = function (coin) { |
||||
return h(this.activeToggle('.input-container'), { |
||||
style: { |
||||
marginTop: '1%', |
||||
}, |
||||
}, [ |
||||
ShapeshiftForm.prototype.renderQrCode = function () { |
||||
const { depositAddress, isLoading } = this.state |
||||
const qrImage = qrcode(4, 'M') |
||||
qrImage.addData(depositAddress) |
||||
qrImage.make() |
||||
|
||||
h('div', `${coin} Address:`), |
||||
return h('div.shapeshift-form', {}, [ |
||||
|
||||
h('input#fromCoinAddress.buy-inputs', { |
||||
type: 'text', |
||||
placeholder: `Your ${coin} Refund Address`, |
||||
dataset: { |
||||
persistentFormId: 'refund-address', |
||||
|
||||
}, |
||||
style: { |
||||
boxSizing: 'border-box', |
||||
width: '227px', |
||||
height: '30px', |
||||
padding: ' 5px ', |
||||
}, |
||||
}), |
||||
h('div.shapeshift-form__deposit-instruction', [ |
||||
'Deposit your BTC to the address below:', |
||||
]), |
||||
|
||||
h('div', depositAddress), |
||||
|
||||
h('i.fa.fa-pencil-square-o.edit-text', { |
||||
style: { |
||||
fontSize: '12px', |
||||
color: '#F7861C', |
||||
position: 'absolute', |
||||
}, |
||||
h('div.shapeshift-form__qr-code', [ |
||||
isLoading |
||||
? h('img', { |
||||
src: 'images/loading.svg', |
||||
style: { width: '60px'}, |
||||
}) |
||||
: h('div', { |
||||
dangerouslySetInnerHTML: { __html: qrImage.createTableTag(4) }, |
||||
}), |
||||
h('div.flex-row', { |
||||
style: { |
||||
justifyContent: 'flex-start', |
||||
}, |
||||
}, [ |
||||
h('button', { |
||||
onClick: this.shift.bind(this), |
||||
style: { |
||||
marginTop: '1%', |
||||
}, |
||||
}, |
||||
'Submit'), |
||||
]), |
||||
|
||||
this.renderMarketInfo(), |
||||
|
||||
]) |
||||
} |
||||
|
||||
ShapeshiftForm.prototype.shift = function () { |
||||
var props = this.props |
||||
var withdrawal = this.props.buyView.buyAddress |
||||
var returnAddress = document.getElementById('fromCoinAddress').value |
||||
var pair = this.props.buyView.formView.marketinfo.pair |
||||
var data = { |
||||
'withdrawal': withdrawal, |
||||
'pair': pair, |
||||
'returnAddress': returnAddress, |
||||
// Public api key
|
||||
'apiKey': '803d1f5df2ed1b1476e4b9e6bcd089e34d8874595dda6a23b67d93c56ea9cc2445e98a6748b219b2b6ad654d9f075f1f1db139abfa93158c04e825db122c14b6', |
||||
} |
||||
var message = [ |
||||
`Deposit Limit: ${props.buyView.formView.marketinfo.limit}`, |
||||
`Deposit Minimum:${props.buyView.formView.marketinfo.minimum}`, |
||||
] |
||||
if (isValidAddress(withdrawal)) { |
||||
this.props.dispatch(actions.coinShiftRquest(data, message)) |
||||
} |
||||
} |
||||
|
||||
ShapeshiftForm.prototype.renderCoinList = function () { |
||||
var list = Object.keys(this.props.buyView.formView.coinOptions).map((item) => { |
||||
return h('option', { |
||||
value: item, |
||||
}, item) |
||||
}) |
||||
ShapeshiftForm.prototype.render = function () { |
||||
const { coinOptions, btnClass } = this.props |
||||
const { depositCoin, errorMessage, showQrCode, depositAddress } = this.state |
||||
const coinPair = `${depositCoin}_eth` |
||||
const { tokenExchangeRates } = this.props |
||||
const token = tokenExchangeRates[coinPair] |
||||
|
||||
return h('div.shapeshift-form-wrapper', [ |
||||
showQrCode |
||||
? this.renderQrCode() |
||||
: h('div.shapeshift-form', [ |
||||
h('div.shapeshift-form__selectors', [ |
||||
|
||||
h('div.shapeshift-form__selector', [ |
||||
|
||||
h('div.shapeshift-form__selector-label', 'Deposit'), |
||||
|
||||
h(SimpleDropdown, { |
||||
selectedOption: this.state.depositCoin, |
||||
onSelect: this.onCoinChange, |
||||
options: Object.entries(coinOptions).map(([coin]) => ({ |
||||
value: coin.toLowerCase(), |
||||
displayValue: coin, |
||||
})), |
||||
}), |
||||
|
||||
return h('datalist#coinList', { |
||||
onClick: (event) => { |
||||
event.preventDefault() |
||||
}, |
||||
}, list) |
||||
} |
||||
]), |
||||
|
||||
ShapeshiftForm.prototype.updateCoin = function (event) { |
||||
event.preventDefault() |
||||
const props = this.props |
||||
var coinOptions = this.props.buyView.formView.coinOptions |
||||
var coin = document.getElementById('fromCoin').value |
||||
|
||||
if (!coinOptions[coin.toUpperCase()] || coin.toUpperCase() === 'ETH') { |
||||
var message = 'Not a valid coin' |
||||
return props.dispatch(actions.displayWarning(message)) |
||||
} else { |
||||
return props.dispatch(actions.pairUpdate(coin)) |
||||
} |
||||
} |
||||
h('div.icon.shapeshift-form__caret', { |
||||
style: { backgroundImage: 'url(images/caret-right.svg)'}, |
||||
}), |
||||
|
||||
ShapeshiftForm.prototype.handleLiveInput = function () { |
||||
const props = this.props |
||||
var coinOptions = this.props.buyView.formView.coinOptions |
||||
var coin = document.getElementById('fromCoin').value |
||||
h('div.shapeshift-form__selector', [ |
||||
|
||||
if (!coinOptions[coin.toUpperCase()] || coin.toUpperCase() === 'ETH') { |
||||
return null |
||||
} else { |
||||
return props.dispatch(actions.pairUpdate(coin)) |
||||
} |
||||
} |
||||
h('div.shapeshift-form__selector-label', [ |
||||
'Receive', |
||||
]), |
||||
|
||||
ShapeshiftForm.prototype.renderInfo = function () { |
||||
const marketinfo = this.props.buyView.formView.marketinfo |
||||
const coinOptions = this.props.buyView.formView.coinOptions |
||||
var coin = marketinfo.pair.split('_')[0].toUpperCase() |
||||
h('div.shapeshift-form__selector-input', ['ETH']), |
||||
|
||||
return h('span', { |
||||
style: { |
||||
}, |
||||
}, [ |
||||
h('h3.flex-row.text-transform-uppercase', { |
||||
style: { |
||||
color: '#868686', |
||||
paddingTop: '4px', |
||||
justifyContent: 'space-around', |
||||
textAlign: 'center', |
||||
fontSize: '17px', |
||||
}, |
||||
}, `Market Info for ${marketinfo.pair.replace('_', ' to ').toUpperCase()}:`), |
||||
h('.marketinfo', ['Status : ', `${coinOptions[coin].status}`]), |
||||
h('.marketinfo', ['Exchange Rate: ', `${marketinfo.rate}`]), |
||||
h('.marketinfo', ['Limit: ', `${marketinfo.limit}`]), |
||||
h('.marketinfo', ['Minimum : ', `${marketinfo.minimum}`]), |
||||
]) |
||||
} |
||||
]), |
||||
|
||||
ShapeshiftForm.prototype.activeToggle = function (elementType) { |
||||
if (!this.props.buyView.formView.response || this.props.warning) return elementType |
||||
return `${elementType}.inactive` |
||||
} |
||||
]), |
||||
|
||||
ShapeshiftForm.prototype.renderLoading = function () { |
||||
return h('span', { |
||||
style: { |
||||
position: 'absolute', |
||||
left: '70px', |
||||
bottom: '194px', |
||||
background: 'transparent', |
||||
width: '229px', |
||||
height: '82px', |
||||
display: 'flex', |
||||
justifyContent: 'center', |
||||
}, |
||||
h('div', { |
||||
className: classnames('shapeshift-form__address-input-wrapper', { |
||||
'shapeshift-form__address-input-wrapper--error': errorMessage, |
||||
}), |
||||
}, [ |
||||
h('img', { |
||||
style: { |
||||
width: '60px', |
||||
}, |
||||
src: 'images/loading.svg', |
||||
|
||||
h('div.shapeshift-form__address-input-label', [ |
||||
'Your Refund Address', |
||||
]), |
||||
|
||||
h('input.shapeshift-form__address-input', { |
||||
type: 'text', |
||||
onChange: e => this.setState({ |
||||
refundAddress: e.target.value, |
||||
errorMessage: '', |
||||
}), |
||||
}), |
||||
|
||||
h('divshapeshift-form__address-input-error-message', [errorMessage]), |
||||
]), |
||||
|
||||
this.renderMarketInfo(), |
||||
|
||||
]), |
||||
|
||||
!depositAddress && h('button.shapeshift-form__shapeshift-buy-btn', { |
||||
className: btnClass, |
||||
disabled: !token, |
||||
onClick: () => this.onBuyWithShapeShift(), |
||||
}, ['Buy']), |
||||
|
||||
]) |
||||
} |
||||
|
@ -0,0 +1,192 @@ |
||||
.new-account { |
||||
width: 376px; |
||||
background-color: #FFFFFF; |
||||
box-shadow: 0 0 7px 0 rgba(0,0,0,0.08); |
||||
z-index: 25; |
||||
padding-bottom: 31px; |
||||
|
||||
&__header { |
||||
display: flex; |
||||
flex-flow: column; |
||||
border-bottom: 1px solid $geyser; |
||||
} |
||||
|
||||
&__title { |
||||
color: $tundora; |
||||
font-family: Roboto; |
||||
font-size: 32px; |
||||
font-weight: 500; |
||||
line-height: 43px; |
||||
margin-top: 22px; |
||||
margin-left: 29px; |
||||
} |
||||
|
||||
&__tabs { |
||||
margin-left: 22px; |
||||
display: flex; |
||||
margin-top: 10px; |
||||
|
||||
&__tab { |
||||
height: 54px; |
||||
width: 75px; |
||||
padding: 15px 10px; |
||||
color: $dusty-gray; |
||||
font-family: Roboto; |
||||
font-size: 18px; |
||||
line-height: 24px; |
||||
text-align: center; |
||||
} |
||||
|
||||
&__tab:first-of-type { |
||||
margin-right: 20px; |
||||
} |
||||
|
||||
&__unselected:hover { |
||||
color: $black; |
||||
border-bottom: none; |
||||
} |
||||
|
||||
&__selected { |
||||
color: $curious-blue; |
||||
border-bottom: 3px solid $curious-blue; |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
.new-account-import-form { |
||||
&__select-section { |
||||
display: flex; |
||||
justify-content: space-evenly; |
||||
align-items: center; |
||||
margin-top: 29px; |
||||
} |
||||
|
||||
&__select-label { |
||||
color: $scorpion; |
||||
font-family: Roboto; |
||||
font-size: 16px; |
||||
line-height: 21px; |
||||
} |
||||
|
||||
&__select { |
||||
height: 54px; |
||||
width: 210px; |
||||
border: 1px solid #D2D8DD; |
||||
border-radius: 4px; |
||||
background-color: #FFFFFF; |
||||
display: flex; |
||||
align-items: center; |
||||
|
||||
.Select-control, |
||||
.Select-control:hover { |
||||
height: 100%; |
||||
border: none; |
||||
box-shadow: none; |
||||
|
||||
.Select-value { |
||||
display: flex; |
||||
align-items: center; |
||||
} |
||||
} |
||||
} |
||||
|
||||
&__instruction { |
||||
color: $scorpion; |
||||
font-family: Roboto; |
||||
font-size: 16px; |
||||
line-height: 21px; |
||||
align-self: flex-start; |
||||
margin-left: 30px; |
||||
} |
||||
|
||||
&__private-key { |
||||
display: flex; |
||||
flex-flow: column; |
||||
align-items: center; |
||||
margin-top: 34px; |
||||
} |
||||
|
||||
&__input-password { |
||||
height: 54px; |
||||
width: 315px; |
||||
border: 1px solid $geyser; |
||||
border-radius: 4px; |
||||
background-color: $white; |
||||
margin-top: 16px; |
||||
color: $scorpion; |
||||
font-family: Roboto; |
||||
font-size: 16px; |
||||
padding: 0px 20px; |
||||
} |
||||
|
||||
&__json { |
||||
display: flex; |
||||
flex-flow: column; |
||||
align-items: center; |
||||
margin-top: 29px; |
||||
} |
||||
} |
||||
|
||||
.new-account-create-form { |
||||
display: flex; |
||||
flex-flow: column; |
||||
align-items: center; |
||||
|
||||
&__input-label { |
||||
color: $scorpion; |
||||
font-family: Roboto; |
||||
font-size: 16px; |
||||
line-height: 21px; |
||||
margin-top: 29px; |
||||
align-self: flex-start; |
||||
margin-left: 30px; |
||||
} |
||||
|
||||
&__input { |
||||
height: 54px; |
||||
width: 315.84px; |
||||
border: 1px solid $geyser; |
||||
border-radius: 4px; |
||||
background-color: $white; |
||||
color: $scorpion; |
||||
font-family: Roboto; |
||||
font-size: 16px; |
||||
line-height: 21px; |
||||
margin-top: 15px; |
||||
padding: 0px 20px; |
||||
} |
||||
|
||||
&__buttons { |
||||
margin-top: 39px; |
||||
display: flex; |
||||
width: 100%; |
||||
justify-content: space-evenly; |
||||
} |
||||
|
||||
&__button-cancel, |
||||
&__button-create { |
||||
height: 55px; |
||||
width: 150px; |
||||
border-radius: 2px; |
||||
background-color: #FFFFFF; |
||||
} |
||||
|
||||
&__button-cancel { |
||||
border: 1px solid $dusty-gray; |
||||
color: $dusty-gray; |
||||
font-family: Roboto; |
||||
font-size: 16px; |
||||
line-height: 21px; |
||||
text-align: center; |
||||
} |
||||
|
||||
&__button-create { |
||||
border: 1px solid $curious-blue; |
||||
color: $curious-blue; |
||||
font-family: Roboto; |
||||
font-size: 16px; |
||||
line-height: 21px; |
||||
text-align: center; |
||||
} |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue