commit
e85418b11a
@ -1 +1,2 @@ |
|||||||
app/scripts/lib/extension-instance.js |
app/scripts/lib/extension-instance.js |
||||||
|
ui/app/conversion-util.js |
||||||
|
@ -0,0 +1,10 @@ |
|||||||
|
{ |
||||||
|
"appName": { |
||||||
|
"message": "MetaMask", |
||||||
|
"description": "The name of the application" |
||||||
|
}, |
||||||
|
"appDescription": { |
||||||
|
"message": "Administración de identidad en Ethereum", |
||||||
|
"description": "The description of the application" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,10 @@ |
|||||||
|
{ |
||||||
|
"appName": { |
||||||
|
"message": "MetaMask", |
||||||
|
"description": "The name of the application" |
||||||
|
}, |
||||||
|
"appDescription": { |
||||||
|
"message": "Administración de identidad en Ethereum", |
||||||
|
"description": "The description of the application" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,10 @@ |
|||||||
|
{ |
||||||
|
"appName": { |
||||||
|
"message": "MetaMask", |
||||||
|
"description": "The name of the application" |
||||||
|
}, |
||||||
|
"appDescription": { |
||||||
|
"message": "以太坊身份管理", |
||||||
|
"description": "The description of the application" |
||||||
|
} |
||||||
|
} |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 41 KiB |
@ -0,0 +1,16 @@ |
|||||||
|
<!doctype html> |
||||||
|
<html> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<title>MetaMask Notification</title> |
||||||
|
<style> |
||||||
|
body { |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
</style> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<div id="app-content"></div> |
||||||
|
<script src="./scripts/popup.js" type="text/javascript" charset="utf-8"></script> |
||||||
|
</body> |
||||||
|
</html> |
@ -1,24 +0,0 @@ |
|||||||
module.exports = ensnare |
|
||||||
|
|
||||||
// creates a proxy object that calls cb everytime the obj's properties/fns are accessed
|
|
||||||
function ensnare (obj, cb) { |
|
||||||
var proxy = {} |
|
||||||
Object.keys(obj).forEach(function (key) { |
|
||||||
var val = obj[key] |
|
||||||
switch (typeof val) { |
|
||||||
case 'function': |
|
||||||
proxy[key] = function () { |
|
||||||
cb() |
|
||||||
val.apply(obj, arguments) |
|
||||||
} |
|
||||||
return |
|
||||||
default: |
|
||||||
Object.defineProperty(proxy, key, { |
|
||||||
get: function () { cb(); return obj[key] }, |
|
||||||
set: function (val) { cb(); obj[key] = val; return val }, |
|
||||||
}) |
|
||||||
return |
|
||||||
} |
|
||||||
}) |
|
||||||
return proxy |
|
||||||
} |
|
@ -0,0 +1,8 @@ |
|||||||
|
module.exports = function isPopupOrNotification() { |
||||||
|
const url = window.location.href |
||||||
|
if (url.match(/popup.html$/)) { |
||||||
|
return 'popup' |
||||||
|
} else { |
||||||
|
return 'notification' |
||||||
|
} |
||||||
|
} |
@ -1,56 +0,0 @@ |
|||||||
const Duplex = require('readable-stream').Duplex |
|
||||||
const inherits = require('util').inherits |
|
||||||
|
|
||||||
module.exports = LocalMessageDuplexStream |
|
||||||
|
|
||||||
inherits(LocalMessageDuplexStream, Duplex) |
|
||||||
|
|
||||||
function LocalMessageDuplexStream (opts) { |
|
||||||
Duplex.call(this, { |
|
||||||
objectMode: true, |
|
||||||
}) |
|
||||||
|
|
||||||
// this._origin = opts.origin
|
|
||||||
this._name = opts.name |
|
||||||
this._target = opts.target |
|
||||||
|
|
||||||
// console.log('LocalMessageDuplexStream ('+this._name+') - initialized...')
|
|
||||||
window.addEventListener('message', this._onMessage.bind(this), false) |
|
||||||
} |
|
||||||
|
|
||||||
// private
|
|
||||||
|
|
||||||
LocalMessageDuplexStream.prototype._onMessage = function (event) { |
|
||||||
var msg = event.data |
|
||||||
// console.log('LocalMessageDuplexStream ('+this._name+') - heard message...', event)
|
|
||||||
// validate message
|
|
||||||
if (event.origin !== location.origin) return // console.log('LocalMessageDuplexStream ('+this._name+') - rejected - (event.origin !== location.origin) ')
|
|
||||||
if (typeof msg !== 'object') return // console.log('LocalMessageDuplexStream ('+this._name+') - rejected - (typeof msg !== "object") ')
|
|
||||||
if (msg.target !== this._name) return // console.log('LocalMessageDuplexStream ('+this._name+') - rejected - (msg.target !== this._name) ', msg.target, this._name)
|
|
||||||
if (!msg.data) return // console.log('LocalMessageDuplexStream ('+this._name+') - rejected - (!msg.data) ')
|
|
||||||
// console.log('LocalMessageDuplexStream ('+this._name+') - accepted', msg.data)
|
|
||||||
// forward message
|
|
||||||
try { |
|
||||||
this.push(msg.data) |
|
||||||
} catch (err) { |
|
||||||
this.emit('error', err) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// stream plumbing
|
|
||||||
|
|
||||||
LocalMessageDuplexStream.prototype._read = noop |
|
||||||
|
|
||||||
LocalMessageDuplexStream.prototype._write = function (data, encoding, cb) { |
|
||||||
// console.log('LocalMessageDuplexStream ('+this._name+') - sending message...')
|
|
||||||
var message = { |
|
||||||
target: this._target, |
|
||||||
data: data, |
|
||||||
} |
|
||||||
window.postMessage(message, location.origin) |
|
||||||
cb() |
|
||||||
} |
|
||||||
|
|
||||||
// util
|
|
||||||
|
|
||||||
function noop () {} |
|
@ -1,159 +1,48 @@ |
|||||||
const createId = require('hat') |
|
||||||
const extend = require('xtend') |
|
||||||
const unmountComponentAtNode = require('react-dom').unmountComponentAtNode |
|
||||||
const findDOMNode = require('react-dom').findDOMNode |
|
||||||
const render = require('react-dom').render |
|
||||||
const h = require('react-hyperscript') |
|
||||||
const PendingTxDetails = require('../../../ui/app/components/pending-tx-details') |
|
||||||
const PendingMsgDetails = require('../../../ui/app/components/pending-msg-details') |
|
||||||
const MetaMaskUiCss = require('../../../ui/css') |
|
||||||
const extension = require('./extension') |
const extension = require('./extension') |
||||||
var notificationHandlers = {} |
|
||||||
|
|
||||||
const notifications = { |
const notifications = { |
||||||
createUnlockRequestNotification: createUnlockRequestNotification, |
show, |
||||||
createTxNotification: createTxNotification, |
getPopup, |
||||||
createMsgNotification: createMsgNotification, |
closePopup, |
||||||
} |
} |
||||||
module.exports = notifications |
module.exports = notifications |
||||||
window.METAMASK_NOTIFIER = notifications |
window.METAMASK_NOTIFIER = notifications |
||||||
|
|
||||||
setupListeners() |
function show () { |
||||||
|
getPopup((popup) => { |
||||||
function setupListeners () { |
if (popup) { |
||||||
// guard for extension bug https://github.com/MetaMask/metamask-plugin/issues/236
|
return extension.windows.update(popup.id, { focused: true }) |
||||||
if (!extension.notifications) return console.error('Chrome notifications API missing...') |
|
||||||
|
|
||||||
// notification button press
|
|
||||||
extension.notifications.onButtonClicked.addListener(function (notificationId, buttonIndex) { |
|
||||||
var handlers = notificationHandlers[notificationId] |
|
||||||
if (buttonIndex === 0) { |
|
||||||
handlers.confirm() |
|
||||||
} else { |
|
||||||
handlers.cancel() |
|
||||||
} |
} |
||||||
extension.notifications.clear(notificationId) |
|
||||||
}) |
|
||||||
|
|
||||||
// notification teardown
|
|
||||||
extension.notifications.onClosed.addListener(function (notificationId) { |
|
||||||
delete notificationHandlers[notificationId] |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
// creation helper
|
|
||||||
function createUnlockRequestNotification (opts) { |
|
||||||
// guard for extension bug https://github.com/MetaMask/metamask-plugin/issues/236
|
|
||||||
if (!extension.notifications) return console.error('Chrome notifications API missing...') |
|
||||||
var message = 'An Ethereum app has requested a signature. Please unlock your account.' |
|
||||||
|
|
||||||
var id = createId() |
|
||||||
extension.notifications.create(id, { |
|
||||||
type: 'basic', |
|
||||||
iconUrl: '/images/icon-128.png', |
|
||||||
title: opts.title, |
|
||||||
message: message, |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
function createTxNotification (state) { |
|
||||||
// guard for extension bug https://github.com/MetaMask/metamask-plugin/issues/236
|
|
||||||
if (!extension.notifications) return console.error('Chrome notifications API missing...') |
|
||||||
|
|
||||||
renderTxNotificationSVG(state, function (err, notificationSvgSource) { |
|
||||||
if (err) throw err |
|
||||||
|
|
||||||
showNotification(extend(state, { |
|
||||||
title: 'New Unsigned Transaction', |
|
||||||
imageUrl: toSvgUri(notificationSvgSource), |
|
||||||
})) |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
function createMsgNotification (state) { |
|
||||||
// guard for extension bug https://github.com/MetaMask/metamask-plugin/issues/236
|
|
||||||
if (!extension.notifications) return console.error('Chrome notifications API missing...') |
|
||||||
|
|
||||||
renderMsgNotificationSVG(state, function (err, notificationSvgSource) { |
|
||||||
if (err) throw err |
|
||||||
|
|
||||||
showNotification(extend(state, { |
extension.windows.create({ |
||||||
title: 'New Unsigned Message', |
url: 'notification.html', |
||||||
imageUrl: toSvgUri(notificationSvgSource), |
type: 'detached_panel', |
||||||
})) |
focused: true, |
||||||
|
width: 360, |
||||||
|
height: 500, |
||||||
|
}) |
||||||
}) |
}) |
||||||
} |
} |
||||||
|
|
||||||
function showNotification (state) { |
function getPopup(cb) { |
||||||
// guard for extension bug https://github.com/MetaMask/metamask-plugin/issues/236
|
|
||||||
if (!extension.notifications) return console.error('Chrome notifications API missing...') |
|
||||||
|
|
||||||
var id = createId() |
// Ignore in test environment
|
||||||
extension.notifications.create(id, { |
if (!extension.windows) { |
||||||
type: 'image', |
return cb(null) |
||||||
requireInteraction: true, |
|
||||||
iconUrl: '/images/icon-128.png', |
|
||||||
imageUrl: state.imageUrl, |
|
||||||
title: state.title, |
|
||||||
message: '', |
|
||||||
buttons: [{ |
|
||||||
title: 'Approve', |
|
||||||
}, { |
|
||||||
title: 'Reject', |
|
||||||
}], |
|
||||||
}) |
|
||||||
notificationHandlers[id] = { |
|
||||||
confirm: state.onConfirm, |
|
||||||
cancel: state.onCancel, |
|
||||||
} |
} |
||||||
} |
|
||||||
|
|
||||||
function renderTxNotificationSVG (state, cb) { |
extension.windows.getAll({}, (windows) => { |
||||||
var content = h(PendingTxDetails, state) |
let popup = windows.find((win) => { |
||||||
renderNotificationSVG(content, cb) |
return win.type === 'popup' |
||||||
} |
}) |
||||||
|
|
||||||
function renderMsgNotificationSVG (state, cb) { |
cb(popup) |
||||||
var content = h(PendingMsgDetails, state) |
|
||||||
renderNotificationSVG(content, cb) |
|
||||||
} |
|
||||||
|
|
||||||
function renderNotificationSVG (content, cb) { |
|
||||||
var container = document.createElement('div') |
|
||||||
var confirmView = h('div.app-primary', { |
|
||||||
style: { |
|
||||||
width: '360px', |
|
||||||
height: '240px', |
|
||||||
padding: '16px', |
|
||||||
// background: '#F7F7F7',
|
|
||||||
background: 'white', |
|
||||||
}, |
|
||||||
}, [ |
|
||||||
h('style', MetaMaskUiCss()), |
|
||||||
content, |
|
||||||
]) |
|
||||||
|
|
||||||
render(confirmView, container, function ready() { |
|
||||||
var rootElement = findDOMNode(this) |
|
||||||
var viewSource = rootElement.outerHTML |
|
||||||
unmountComponentAtNode(container) |
|
||||||
var svgSource = svgWrapper(viewSource) |
|
||||||
// insert content into svg wrapper
|
|
||||||
cb(null, svgSource) |
|
||||||
}) |
}) |
||||||
} |
} |
||||||
|
|
||||||
function svgWrapper (content) { |
function closePopup() { |
||||||
var wrapperSource = ` |
getPopup((popup) => { |
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="360" height="240"> |
if (!popup) return |
||||||
<foreignObject x="0" y="0" width="100%" height="100%"> |
extension.windows.remove(popup.id, console.error) |
||||||
<body xmlns="http://www.w3.org/1999/xhtml" height="100%">{{content}}</body> |
}) |
||||||
</foreignObject> |
|
||||||
</svg> |
|
||||||
` |
|
||||||
return wrapperSource.split('{{content}}').join(content) |
|
||||||
} |
|
||||||
|
|
||||||
function toSvgUri (content) { |
|
||||||
return 'data:image/svg+xml;utf8,' + encodeURIComponent(content) |
|
||||||
} |
} |
||||||
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,163 @@ |
|||||||
|
{ |
||||||
|
"metamask": { |
||||||
|
"currentFiat": "USD", |
||||||
|
"conversionRate": 11.06608791, |
||||||
|
"conversionDate": 1470421024, |
||||||
|
"isInitialized": true, |
||||||
|
"isUnlocked": true, |
||||||
|
"currentDomain": "example.com", |
||||||
|
"rpcTarget": "https://rawtestrpc.metamask.io/", |
||||||
|
"shapeShiftTxList":[ |
||||||
|
{ |
||||||
|
"depositAddress": "1L8BJCR6KHkCiVceDqibt7zJscqPpH7pFw", |
||||||
|
"depositType": "BTC", |
||||||
|
"key": "shapeshift", |
||||||
|
"time": 1471564825772, |
||||||
|
"response": { |
||||||
|
"status": "complete", |
||||||
|
"outgoingCoin": "100.00", |
||||||
|
"incomingCoin": "1.000", |
||||||
|
"transaction": "0x3701e0ac344a12a1fc5417cf251109a7c41f3edab922310202630d9c012414c8" |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"depositAddress": "1L8BJCR6KHkCiVceDqibt7zJscqPpH7pFw", |
||||||
|
"depositType": "BTC", |
||||||
|
"key": "shapeshift", |
||||||
|
"time": 1471566579224, |
||||||
|
"response": { |
||||||
|
"status": "no_deposits", |
||||||
|
"depositAddress": "1L8BJCR6KHkCiVceDqibt7zJscqPpH7pFw" |
||||||
|
} |
||||||
|
}, |
||||||
|
{ |
||||||
|
"depositAddress": "1L8BJCR6KHkCiVceDqibt7zJscqPpH7pFw", |
||||||
|
"depositType": "BTC", |
||||||
|
"key": "shapeshift", |
||||||
|
"time": 1471566565378, |
||||||
|
"response": { |
||||||
|
"status": "received", |
||||||
|
"depositAddress": "1L8BJCR6KHkCiVceDqibt7zJscqPpH7pFw" |
||||||
|
} |
||||||
|
} |
||||||
|
], |
||||||
|
"transactions": [ { |
||||||
|
"id": 1467921503489592, |
||||||
|
"txParams": { |
||||||
|
"from": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc", |
||||||
|
"to": "0x18a3462427bcc9133bb46e88bcbe39cd7ef0e761", |
||||||
|
"value": "0x66c899104aa57038000", |
||||||
|
"origin": "thelongestdomainnameintheworldandthensomeandthensomemoreandmore.com", |
||||||
|
"metamaskId": 1467921503489592, |
||||||
|
"metamaskNetworkId": "2" |
||||||
|
}, |
||||||
|
"time": 1467921503489, |
||||||
|
"status": "rejected", |
||||||
|
"containsDelegateCall": false |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1467923203344608, |
||||||
|
"txParams": { |
||||||
|
"from": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc", |
||||||
|
"to": "0x18a3462427bcc9133bb46e88bcbe39cd7ef0e761", |
||||||
|
"value": "0x0", |
||||||
|
"origin": "thelongestdomainnameintheworldandthensomeandthensomemoreandmore.com", |
||||||
|
"metamaskId": 1467923203344608, |
||||||
|
"metamaskNetworkId": "2" |
||||||
|
}, |
||||||
|
"time": 1467923203344, |
||||||
|
"status": "confirmed", |
||||||
|
"containsDelegateCall": false, |
||||||
|
"hash": "0x957bbba51e2732a86c10c5e7e8a484a093795a06f2e2c38ad02da1b20aeca620" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1467921503489592, |
||||||
|
"txParams": { |
||||||
|
"from": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc", |
||||||
|
"to": "0x18a3462427bcc9133bb46e88bcbe39cd7ef0e761", |
||||||
|
"value": "0x66c899104aa57038000", |
||||||
|
"origin": "thelongestdomainnameintheworldandthensomeandthensomemoreandmore.com", |
||||||
|
"metamaskId": 1467921503489592, |
||||||
|
"metamaskNetworkId": "2" |
||||||
|
}, |
||||||
|
"time": 1467921503489, |
||||||
|
"status": "confirmed", |
||||||
|
"containsDelegateCall": false |
||||||
|
}], |
||||||
|
"identities": { |
||||||
|
"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc": { |
||||||
|
"name": "Wallet 1", |
||||||
|
"address": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc", |
||||||
|
"mayBeFauceting": false |
||||||
|
}, |
||||||
|
"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b": { |
||||||
|
"name": "Wallet 2", |
||||||
|
"address": "0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b", |
||||||
|
"mayBeFauceting": false |
||||||
|
}, |
||||||
|
"0xeb9e64b93097bc15f01f13eae97015c57ab64823": { |
||||||
|
"name": "Wallet 3", |
||||||
|
"address": "0xeb9e64b93097bc15f01f13eae97015c57ab64823", |
||||||
|
"mayBeFauceting": false |
||||||
|
}, |
||||||
|
"0x704107d04affddd9b66ab9de3dd7b095852e9b69": { |
||||||
|
"name": "Wallet 4", |
||||||
|
"address": "0x704107d04affddd9b66ab9de3dd7b095852e9b69", |
||||||
|
"mayBeFauceting": false |
||||||
|
} |
||||||
|
}, |
||||||
|
"unconfTxs": {}, |
||||||
|
"accounts": { |
||||||
|
"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc": { |
||||||
|
"code": "0x", |
||||||
|
"balance": "0x0", |
||||||
|
"nonce": "0x0", |
||||||
|
"address": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc" |
||||||
|
}, |
||||||
|
"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b": { |
||||||
|
"code": "0x", |
||||||
|
"nonce": "0x0", |
||||||
|
"balance": "0x0", |
||||||
|
"address": "0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b" |
||||||
|
}, |
||||||
|
"0xeb9e64b93097bc15f01f13eae97015c57ab64823": { |
||||||
|
"code": "0x", |
||||||
|
"nonce": "0x0", |
||||||
|
"balance": "0x0", |
||||||
|
"address": "0xeb9e64b93097bc15f01f13eae97015c57ab64823" |
||||||
|
}, |
||||||
|
"0x704107d04affddd9b66ab9de3dd7b095852e9b69": { |
||||||
|
"code": "0x", |
||||||
|
"balance": "0x0", |
||||||
|
"nonce": "0x0", |
||||||
|
"address": "0x704107d04affddd9b66ab9de3dd7b095852e9b69" |
||||||
|
} |
||||||
|
}, |
||||||
|
"selectedAddress": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc", |
||||||
|
"network": "1", |
||||||
|
"seedWords": null, |
||||||
|
"isConfirmed": true, |
||||||
|
"unconfMsgs": {}, |
||||||
|
"messages": [], |
||||||
|
"provider": { |
||||||
|
"type": "mainnet" |
||||||
|
}, |
||||||
|
"selectedAccount": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc" |
||||||
|
}, |
||||||
|
"appState": { |
||||||
|
"menuOpen": false, |
||||||
|
"currentView": { |
||||||
|
"name": "accountDetail", |
||||||
|
"detailView": null, |
||||||
|
"context": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc" |
||||||
|
}, |
||||||
|
"accountDetail": { |
||||||
|
"subview": "transactions" |
||||||
|
}, |
||||||
|
"currentDomain": "127.0.0.1:9966", |
||||||
|
"transForward": true, |
||||||
|
"isLoading": false, |
||||||
|
"warning": null |
||||||
|
}, |
||||||
|
"identities": {} |
||||||
|
} |
File diff suppressed because one or more lines are too long
@ -0,0 +1,406 @@ |
|||||||
|
{ |
||||||
|
"metamask": { |
||||||
|
"isInitialized": true, |
||||||
|
"isUnlocked": true, |
||||||
|
"isEthConfirmed": true, |
||||||
|
"currentDomain": "example.com", |
||||||
|
"rpcTarget": "https://rawtestrpc.metamask.io/", |
||||||
|
"identities": { |
||||||
|
"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": { |
||||||
|
"name": "Wallet 1", |
||||||
|
"address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"mayBeFauceting": false |
||||||
|
}, |
||||||
|
"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": { |
||||||
|
"name": "Wallet 2", |
||||||
|
"address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb", |
||||||
|
"mayBeFauceting": false |
||||||
|
}, |
||||||
|
"0x2f8d4a878cfa04a6e60d46362f5644deab66572d": { |
||||||
|
"name": "Wallet 3", |
||||||
|
"address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d", |
||||||
|
"mayBeFauceting": false |
||||||
|
} |
||||||
|
}, |
||||||
|
"unconfTxs": {}, |
||||||
|
"currentFiat": "USD", |
||||||
|
"conversionRate": 11.02269525, |
||||||
|
"conversionDate": 1472076963, |
||||||
|
"accounts": { |
||||||
|
"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": { |
||||||
|
"balance": "0x056ace16d84b1c7e78", |
||||||
|
"nonce": "0x17", |
||||||
|
"code": "0x0", |
||||||
|
"address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825" |
||||||
|
}, |
||||||
|
"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": { |
||||||
|
"balance": "0x00000000000000056bc75e2d63100000", |
||||||
|
"nonce": "0x0", |
||||||
|
"code": "0x0", |
||||||
|
"address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb" |
||||||
|
}, |
||||||
|
"0x2f8d4a878cfa04a6e60d46362f5644deab66572d": { |
||||||
|
"balance": "0x00000000000000056bc75e2d63100000", |
||||||
|
"nonce": "0x0", |
||||||
|
"code": "0x0", |
||||||
|
"address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d" |
||||||
|
} |
||||||
|
}, |
||||||
|
"transactions": [ |
||||||
|
{ |
||||||
|
"id": 1471975421223082, |
||||||
|
"txParams": { |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"to": "0x48ff0cbac0acefedf152281ee80e9a0a01d5da63", |
||||||
|
"data": "0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb000000000000000000000000000000000000000000000000000000000000000a", |
||||||
|
"origin": "localhost", |
||||||
|
"metamaskId": 1471975421223082, |
||||||
|
"metamaskNetworkId": "1471904489432" |
||||||
|
}, |
||||||
|
"time": 1471975421223, |
||||||
|
"status": "confirmed", |
||||||
|
"containsDelegateCall": true, |
||||||
|
"estimatedGas": "0x89ef", |
||||||
|
"hash": "0xd0fe393e2586ebded866c9f13b90494e902bc49047fbf25ba2ac96c805a2f5d3" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1471975427199819, |
||||||
|
"txParams": { |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"to": "0x48ff0cbac0acefedf152281ee80e9a0a01d5da63", |
||||||
|
"data": "0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb000000000000000000000000000000000000000000000000000000000000000a", |
||||||
|
"origin": "localhost", |
||||||
|
"metamaskId": 1471975427199819, |
||||||
|
"metamaskNetworkId": "1471904489432" |
||||||
|
}, |
||||||
|
"time": 1471975427199, |
||||||
|
"status": "rejected", |
||||||
|
"containsDelegateCall": true, |
||||||
|
"estimatedGas": "0x89ef", |
||||||
|
"hash": "0xb1f2f63f3e265f05d7c353ab38dd8b73fce8e7214489037311ee1f58a994dae3" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1471975806981442, |
||||||
|
"txParams": { |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"to": "0x48ff0cbac0acefedf152281ee80e9a0a01d5da63", |
||||||
|
"data": "0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb000000000000000000000000000000000000000000000000000000000000000a", |
||||||
|
"origin": "localhost", |
||||||
|
"metamaskId": 1471975806981442, |
||||||
|
"metamaskNetworkId": "1471904489432" |
||||||
|
}, |
||||||
|
"time": 1471975806981, |
||||||
|
"status": "confirmed", |
||||||
|
"containsDelegateCall": true, |
||||||
|
"estimatedGas": "0x89ef", |
||||||
|
"hash": "0xeeb89e91aaeea14c4950016c45d60df8ee8874daa6f414de5cf267ea2c17bc6e" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1471975810133789, |
||||||
|
"txParams": { |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"to": "0x48ff0cbac0acefedf152281ee80e9a0a01d5da63", |
||||||
|
"data": "0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb000000000000000000000000000000000000000000000000000000000000000a", |
||||||
|
"origin": "localhost", |
||||||
|
"metamaskId": 1471975810133789, |
||||||
|
"metamaskNetworkId": "1471904489432" |
||||||
|
}, |
||||||
|
"time": 1471975810133, |
||||||
|
"status": "confirmed", |
||||||
|
"containsDelegateCall": true, |
||||||
|
"estimatedGas": "0x89ef", |
||||||
|
"hash": "0xe54cab2e54b8495691b6d8315ca24a190cba546a9fcb056642479ce5770cec8b" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1471976546865348, |
||||||
|
"txParams": { |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"to": "0x48ff0cbac0acefedf152281ee80e9a0a01d5da63", |
||||||
|
"data": "0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb000000000000000000000000000000000000000000000000000000000000000a", |
||||||
|
"origin": "localhost", |
||||||
|
"metamaskId": 1471976546865348, |
||||||
|
"metamaskNetworkId": "1471904489432" |
||||||
|
}, |
||||||
|
"time": 1471976546865, |
||||||
|
"status": "confirmed", |
||||||
|
"containsDelegateCall": true, |
||||||
|
"estimatedGas": "0x89ef", |
||||||
|
"hash": "0x54e10f77e17f28f4d12751749a2ca22f9b528592d1140ef53c6430a68e731542" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1471976930101889, |
||||||
|
"txParams": { |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"to": "0x48ff0cbac0acefedf152281ee80e9a0a01d5da63", |
||||||
|
"data": "0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000005", |
||||||
|
"origin": "localhost", |
||||||
|
"metamaskId": 1471976930101889, |
||||||
|
"metamaskNetworkId": "1471904489432" |
||||||
|
}, |
||||||
|
"time": 1471976930101, |
||||||
|
"status": "confirmed", |
||||||
|
"containsDelegateCall": true, |
||||||
|
"estimatedGas": "0x89ef", |
||||||
|
"hash": "0x60b5af26fad18c5549949064b67c8f965c9f20cd3e890c69512ca3acad10ed8b" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1471977268048169, |
||||||
|
"txParams": { |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"to": "0x48ff0cbac0acefedf152281ee80e9a0a01d5da63", |
||||||
|
"data": "0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000002", |
||||||
|
"origin": "localhost", |
||||||
|
"metamaskId": 1471977268048169, |
||||||
|
"metamaskNetworkId": "1471904489432" |
||||||
|
}, |
||||||
|
"time": 1471977268048, |
||||||
|
"status": "confirmed", |
||||||
|
"containsDelegateCall": true, |
||||||
|
"estimatedGas": "0x89ef", |
||||||
|
"hash": "0x1f96e29305ef11a9c993302c29e5419d87017e8222d4034daea0d86e155dc3aa" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1471977310778630, |
||||||
|
"txParams": { |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"to": "0x48ff0cbac0acefedf152281ee80e9a0a01d5da63", |
||||||
|
"data": "0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000005", |
||||||
|
"origin": "localhost", |
||||||
|
"metamaskId": 1471977310778630, |
||||||
|
"metamaskNetworkId": "1471904489432" |
||||||
|
}, |
||||||
|
"time": 1471977310778, |
||||||
|
"status": "rejected", |
||||||
|
"containsDelegateCall": true, |
||||||
|
"estimatedGas": "0x89ef" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1471977316241561, |
||||||
|
"txParams": { |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"to": "0x48ff0cbac0acefedf152281ee80e9a0a01d5da63", |
||||||
|
"data": "0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000005", |
||||||
|
"origin": "localhost", |
||||||
|
"metamaskId": 1471977316241561, |
||||||
|
"metamaskNetworkId": "1471904489432" |
||||||
|
}, |
||||||
|
"time": 1471977316240, |
||||||
|
"status": "confirmed", |
||||||
|
"containsDelegateCall": true, |
||||||
|
"estimatedGas": "0x89ef", |
||||||
|
"hash": "0xdbd610c92d77a07c76b82e14e32674d382c45c4780dd2a550888b5cc40d54bcc" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1471977344018510, |
||||||
|
"txParams": { |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"to": "0x48ff0cbac0acefedf152281ee80e9a0a01d5da63", |
||||||
|
"data": "0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000004", |
||||||
|
"origin": "localhost", |
||||||
|
"metamaskId": 1471977344018510, |
||||||
|
"metamaskNetworkId": "1471904489432" |
||||||
|
}, |
||||||
|
"time": 1471977344018, |
||||||
|
"status": "confirmed", |
||||||
|
"containsDelegateCall": true, |
||||||
|
"estimatedGas": "0x89ef", |
||||||
|
"hash": "0x709d871d9ded0108de9f7718a7490b19d45e5e7562b1ba6c5bf6cce56e767d48" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1471977403830380, |
||||||
|
"txParams": { |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"to": "0x48ff0cbac0acefedf152281ee80e9a0a01d5da63", |
||||||
|
"data": "0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000001", |
||||||
|
"origin": "localhost", |
||||||
|
"metamaskId": 1471977403830380, |
||||||
|
"metamaskNetworkId": "1471904489432" |
||||||
|
}, |
||||||
|
"time": 1471977403830, |
||||||
|
"status": "confirmed", |
||||||
|
"containsDelegateCall": true, |
||||||
|
"estimatedGas": "0x89ef", |
||||||
|
"hash": "0x94f5088a127bba181b303d6427ae93cbfa9867997bea1326f30da311e36c6aca" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1471977431563703, |
||||||
|
"txParams": { |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"to": "0x48ff0cbac0acefedf152281ee80e9a0a01d5da63", |
||||||
|
"data": "0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000001", |
||||||
|
"origin": "localhost", |
||||||
|
"metamaskId": 1471977431563703, |
||||||
|
"metamaskNetworkId": "1471904489432" |
||||||
|
}, |
||||||
|
"time": 1471977431563, |
||||||
|
"status": "rejected", |
||||||
|
"containsDelegateCall": true, |
||||||
|
"estimatedGas": "0x89ef" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1471977436074587, |
||||||
|
"txParams": { |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"to": "0x48ff0cbac0acefedf152281ee80e9a0a01d5da63", |
||||||
|
"data": "0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000001", |
||||||
|
"origin": "localhost", |
||||||
|
"metamaskId": 1471977436074587, |
||||||
|
"metamaskNetworkId": "1471904489432" |
||||||
|
}, |
||||||
|
"time": 1471977436074, |
||||||
|
"status": "confirmed", |
||||||
|
"containsDelegateCall": true, |
||||||
|
"estimatedGas": "0x89ef", |
||||||
|
"hash": "0x5f514dfe3bd48f6f301c809a7a75f73f0fc93bc3a0e469368b84dce032aff9ec" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1471991826717707, |
||||||
|
"txParams": { |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"to": "0x48ff0cbac0acefedf152281ee80e9a0a01d5da63", |
||||||
|
"data": "0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000004", |
||||||
|
"origin": "localhost", |
||||||
|
"metamaskId": 1471991826717707, |
||||||
|
"metamaskNetworkId": "1471904489432" |
||||||
|
}, |
||||||
|
"time": 1471991826717, |
||||||
|
"status": "confirmed", |
||||||
|
"containsDelegateCall": true, |
||||||
|
"estimatedGas": "0x89ef", |
||||||
|
"hash": "0xab1e706f8981680a6c921f9f57f8ce573392bbb4f0fe85cf45e5cbf858fa5f3e" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1471991851917592, |
||||||
|
"txParams": { |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"to": "0x48ff0cbac0acefedf152281ee80e9a0a01d5da63", |
||||||
|
"data": "0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000004", |
||||||
|
"origin": "localhost", |
||||||
|
"metamaskId": 1471991851917592, |
||||||
|
"metamaskNetworkId": "1471904489432" |
||||||
|
}, |
||||||
|
"time": 1471991851917, |
||||||
|
"status": "confirmed", |
||||||
|
"containsDelegateCall": true, |
||||||
|
"estimatedGas": "0x89ef", |
||||||
|
"hash": "0xdea144f7a6f06969739f676d8702a9a11efc689e032f1981fe67afc9261dd4de" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1471992032999543, |
||||||
|
"txParams": { |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"to": "0x48ff0cbac0acefedf152281ee80e9a0a01d5da63", |
||||||
|
"data": "0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000005", |
||||||
|
"origin": "localhost", |
||||||
|
"metamaskId": 1471992032999543, |
||||||
|
"metamaskNetworkId": "1471904489432" |
||||||
|
}, |
||||||
|
"time": 1471992032999, |
||||||
|
"status": "confirmed", |
||||||
|
"containsDelegateCall": true, |
||||||
|
"estimatedGas": "0x89ef", |
||||||
|
"hash": "0xdf31b8cc0fbd2ab6727e0b63536bd4eab51a147aa29e04691e68fae28b866fb3" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1471992043490878, |
||||||
|
"txParams": { |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"to": "0x48ff0cbac0acefedf152281ee80e9a0a01d5da63", |
||||||
|
"data": "0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000005", |
||||||
|
"origin": "localhost", |
||||||
|
"metamaskId": 1471992043490878, |
||||||
|
"metamaskNetworkId": "1471904489432" |
||||||
|
}, |
||||||
|
"time": 1471992043490, |
||||||
|
"status": "rejected", |
||||||
|
"containsDelegateCall": true, |
||||||
|
"estimatedGas": "0x89ef" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1472068030402279, |
||||||
|
"txParams": { |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"value": "0x3782dace9d90000", |
||||||
|
"gas": "0x493e0", |
||||||
|
"to": "0x18a672e11d637fffadccc99b152f4895da069601", |
||||||
|
"data": "0x5b7d47a900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", |
||||||
|
"origin": "www.rouleth.com", |
||||||
|
"metamaskId": 1472068030402279, |
||||||
|
"metamaskNetworkId": "1" |
||||||
|
}, |
||||||
|
"time": 1472068030402, |
||||||
|
"status": "rejected", |
||||||
|
"containsDelegateCall": false, |
||||||
|
"estimatedGas": "0x24704" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 1472068061833258, |
||||||
|
"txParams": { |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"value": "0x16345785d8a0000", |
||||||
|
"gas": "0x493e0", |
||||||
|
"to": "0x18a672e11d637fffadccc99b152f4895da069601", |
||||||
|
"data": "0x5b7d47a900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", |
||||||
|
"origin": "www.rouleth.com", |
||||||
|
"metamaskId": 1472068061833258, |
||||||
|
"metamaskNetworkId": "1" |
||||||
|
}, |
||||||
|
"time": 1472068061833, |
||||||
|
"status": "confirmed", |
||||||
|
"containsDelegateCall": false, |
||||||
|
"estimatedGas": "0x24704", |
||||||
|
"hash": "0xb6e6ff57e7b5f6bd7f2e6dc44c39f4e858a227c9509586634ca547179345a13e" |
||||||
|
} |
||||||
|
], |
||||||
|
"selectedAddress": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"network": "1471904489432", |
||||||
|
"seedWords": null, |
||||||
|
"isConfirmed": true, |
||||||
|
"unconfMsgs": { |
||||||
|
"1472076978535283": { |
||||||
|
"id": 1472076978535283, |
||||||
|
"msgParams": { |
||||||
|
"origin": "localhost", |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"data": "hello" |
||||||
|
}, |
||||||
|
"time": 1472076978535, |
||||||
|
"status": "unconfirmed" |
||||||
|
} |
||||||
|
}, |
||||||
|
"messages": [ |
||||||
|
{ |
||||||
|
"id": 1472076978535283, |
||||||
|
"msgParams": { |
||||||
|
"origin": "localhost", |
||||||
|
"from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"data": "hello" |
||||||
|
}, |
||||||
|
"time": 1472076978535, |
||||||
|
"status": "unconfirmed" |
||||||
|
} |
||||||
|
], |
||||||
|
"shapeShiftTxList": [], |
||||||
|
"provider": { |
||||||
|
"type": "rpc", |
||||||
|
"rpcTarget": "http://localhost:8545" |
||||||
|
}, |
||||||
|
"selectedAccount": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825" |
||||||
|
}, |
||||||
|
"appState": { |
||||||
|
"menuOpen": false, |
||||||
|
"currentView": { |
||||||
|
"name": "confTx", |
||||||
|
"detailView": null, |
||||||
|
"context": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825" |
||||||
|
}, |
||||||
|
"accountDetail": { |
||||||
|
"subview": "transactions" |
||||||
|
}, |
||||||
|
"currentDomain": "ebjbdknjcgcbchkagneicjfpneaghdhb", |
||||||
|
"transForward": true, |
||||||
|
"isLoading": false, |
||||||
|
"warning": null |
||||||
|
}, |
||||||
|
"identities": {} |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
{ |
||||||
|
"metamask": { |
||||||
|
"isInitialized": false, |
||||||
|
"isUnlocked": false, |
||||||
|
"isEthConfirmed": false, |
||||||
|
"currentDomain": "example.com", |
||||||
|
"rpcTarget": "https://rawtestrpc.metamask.io/", |
||||||
|
"identities": {}, |
||||||
|
"unconfTxs": {}, |
||||||
|
"currentFiat": "USD", |
||||||
|
"conversionRate": 0, |
||||||
|
"conversionDate": "N/A", |
||||||
|
"accounts": {}, |
||||||
|
"transactions": [], |
||||||
|
"seedWords": null, |
||||||
|
"isConfirmed": true, |
||||||
|
"unconfMsgs": {}, |
||||||
|
"messages": [], |
||||||
|
"shapeShiftTxList": [], |
||||||
|
"provider": { |
||||||
|
"type": "testnet" |
||||||
|
}, |
||||||
|
"network": "2" |
||||||
|
}, |
||||||
|
"appState": { |
||||||
|
"menuOpen": false, |
||||||
|
"currentView": { |
||||||
|
"name": "restoreVault" |
||||||
|
}, |
||||||
|
"accountDetail": { |
||||||
|
"subview": "transactions" |
||||||
|
}, |
||||||
|
"currentDomain": "extensions", |
||||||
|
"transForward": true, |
||||||
|
"isLoading": false, |
||||||
|
"warning": null |
||||||
|
}, |
||||||
|
"identities": {} |
||||||
|
} |
@ -0,0 +1,76 @@ |
|||||||
|
{ |
||||||
|
"metamask": { |
||||||
|
"isInitialized": true, |
||||||
|
"isUnlocked": true, |
||||||
|
"isEthConfirmed": false, |
||||||
|
"currentDomain": "example.com", |
||||||
|
"rpcTarget": "https://rawtestrpc.metamask.io/", |
||||||
|
"identities": { |
||||||
|
"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": { |
||||||
|
"name": "Wallet 1", |
||||||
|
"address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"mayBeFauceting": false |
||||||
|
}, |
||||||
|
"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": { |
||||||
|
"name": "Wallet 2", |
||||||
|
"address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb", |
||||||
|
"mayBeFauceting": false |
||||||
|
}, |
||||||
|
"0x2f8d4a878cfa04a6e60d46362f5644deab66572d": { |
||||||
|
"name": "Wallet 3", |
||||||
|
"address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d", |
||||||
|
"mayBeFauceting": false |
||||||
|
} |
||||||
|
}, |
||||||
|
"unconfTxs": {}, |
||||||
|
"currentFiat": "USD", |
||||||
|
"conversionRate": 11.21283484, |
||||||
|
"conversionDate": 1472158984, |
||||||
|
"accounts": { |
||||||
|
"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": { |
||||||
|
"code": "0x", |
||||||
|
"balance": "0x34693f54a1e25900", |
||||||
|
"nonce": "0x100013", |
||||||
|
"address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825" |
||||||
|
}, |
||||||
|
"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": { |
||||||
|
"code": "0x", |
||||||
|
"nonce": "0x100000", |
||||||
|
"balance": "0x18af912cee770000", |
||||||
|
"address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb" |
||||||
|
}, |
||||||
|
"0x2f8d4a878cfa04a6e60d46362f5644deab66572d": { |
||||||
|
"code": "0x", |
||||||
|
"nonce": "0x100000", |
||||||
|
"balance": "0x2386f26fc10000", |
||||||
|
"address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d" |
||||||
|
} |
||||||
|
}, |
||||||
|
"transactions": [], |
||||||
|
"network": "2", |
||||||
|
"seedWords": null, |
||||||
|
"isConfirmed": true, |
||||||
|
"unconfMsgs": {}, |
||||||
|
"messages": [], |
||||||
|
"shapeShiftTxList": [], |
||||||
|
"provider": { |
||||||
|
"type": "testnet" |
||||||
|
}, |
||||||
|
"selectedAccount": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825" |
||||||
|
}, |
||||||
|
"appState": { |
||||||
|
"menuOpen": false, |
||||||
|
"currentView": { |
||||||
|
"name": "sendTransaction" |
||||||
|
}, |
||||||
|
"accountDetail": { |
||||||
|
"subview": "transactions" |
||||||
|
}, |
||||||
|
"currentDomain": "127.0.0.1:9966", |
||||||
|
"transForward": true, |
||||||
|
"isLoading": false, |
||||||
|
"warning": null, |
||||||
|
"detailView": {} |
||||||
|
}, |
||||||
|
"identities": {} |
||||||
|
} |
@ -0,0 +1,348 @@ |
|||||||
|
{ |
||||||
|
"metamask": { |
||||||
|
"isInitialized": true, |
||||||
|
"isUnlocked": true, |
||||||
|
"isEthConfirmed": true, |
||||||
|
"currentDomain": "example.com", |
||||||
|
"rpcTarget": "https://rawtestrpc.metamask.io/", |
||||||
|
"identities": { |
||||||
|
"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": { |
||||||
|
"name": "Wallet 1", |
||||||
|
"address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"mayBeFauceting": false |
||||||
|
}, |
||||||
|
"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": { |
||||||
|
"name": "Wallet 2", |
||||||
|
"address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb", |
||||||
|
"mayBeFauceting": false |
||||||
|
}, |
||||||
|
"0x2f8d4a878cfa04a6e60d46362f5644deab66572d": { |
||||||
|
"name": "Wallet 3", |
||||||
|
"address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d", |
||||||
|
"mayBeFauceting": false |
||||||
|
} |
||||||
|
}, |
||||||
|
"unconfTxs": {}, |
||||||
|
"currentFiat": "USD", |
||||||
|
"conversionRate": 11.21274318, |
||||||
|
"conversionDate": 1472159644, |
||||||
|
"accounts": { |
||||||
|
"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": { |
||||||
|
"code": "0x", |
||||||
|
"nonce": "0x13", |
||||||
|
"balance": "0x461d4a64e937d3d1", |
||||||
|
"address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825" |
||||||
|
}, |
||||||
|
"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": { |
||||||
|
"code": "0x", |
||||||
|
"nonce": "0x0", |
||||||
|
"balance": "0x0", |
||||||
|
"address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb" |
||||||
|
}, |
||||||
|
"0x2f8d4a878cfa04a6e60d46362f5644deab66572d": { |
||||||
|
"code": "0x", |
||||||
|
"balance": "0x0", |
||||||
|
"nonce": "0x0", |
||||||
|
"address": "0x2f8d4a878cfa04a6e60d46362f5644deab66572d" |
||||||
|
} |
||||||
|
}, |
||||||
|
"transactions": [], |
||||||
|
"selectedAddress": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"network": "1", |
||||||
|
"seedWords": null, |
||||||
|
"isConfirmed": true, |
||||||
|
"unconfMsgs": {}, |
||||||
|
"messages": [], |
||||||
|
"shapeShiftTxList": [], |
||||||
|
"provider": { |
||||||
|
"type": "mainnet" |
||||||
|
}, |
||||||
|
"selectedAccount": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825" |
||||||
|
}, |
||||||
|
"appState": { |
||||||
|
"menuOpen": false, |
||||||
|
"currentView": { |
||||||
|
"name": "buyEth", |
||||||
|
"context": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825" |
||||||
|
}, |
||||||
|
"accountDetail": { |
||||||
|
"subview": "transactions" |
||||||
|
}, |
||||||
|
"currentDomain": "127.0.0.1:9966", |
||||||
|
"transForward": true, |
||||||
|
"isLoading": false, |
||||||
|
"detailView": {}, |
||||||
|
"buyView": { |
||||||
|
"subview": "buyForm", |
||||||
|
"formView": { |
||||||
|
"coinbase": false, |
||||||
|
"shapeshift": true, |
||||||
|
"marketinfo": { |
||||||
|
"pair": "btc_eth", |
||||||
|
"rate": 51.14252949, |
||||||
|
"minerFee": 0.01, |
||||||
|
"limit": 2.60306578, |
||||||
|
"minimum": 0.00038935, |
||||||
|
"maxLimit": 8.67688592 |
||||||
|
}, |
||||||
|
"coinOptions": { |
||||||
|
"BTC": { |
||||||
|
"name": "Bitcoin", |
||||||
|
"symbol": "BTC", |
||||||
|
"image": "https://shapeshift.io/images/coins/bitcoin.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"BCY": { |
||||||
|
"name": "BitCrystals", |
||||||
|
"symbol": "BCY", |
||||||
|
"image": "https://shapeshift.io/images/coins/bitcrystals.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"BLK": { |
||||||
|
"name": "Blackcoin", |
||||||
|
"symbol": "BLK", |
||||||
|
"image": "https://shapeshift.io/images/coins/blackcoin.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"BTS": { |
||||||
|
"name": "Bitshares", |
||||||
|
"symbol": "BTS", |
||||||
|
"specialReturn": false, |
||||||
|
"specialOutgoing": true, |
||||||
|
"specialIncoming": true, |
||||||
|
"fieldName": "destTag", |
||||||
|
"fieldKey": "destTag", |
||||||
|
"image": "https://shapeshift.io/images/coins/bitshares.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"CLAM": { |
||||||
|
"name": "Clams", |
||||||
|
"symbol": "CLAM", |
||||||
|
"image": "https://shapeshift.io/images/coins/clams.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"DASH": { |
||||||
|
"name": "Dash", |
||||||
|
"symbol": "DASH", |
||||||
|
"image": "https://shapeshift.io/images/coins/dash.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"DGB": { |
||||||
|
"name": "Digibyte", |
||||||
|
"symbol": "DGB", |
||||||
|
"image": "https://shapeshift.io/images/coins/digibyte.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"DAO": { |
||||||
|
"name": "TheDao", |
||||||
|
"symbol": "DAO", |
||||||
|
"image": "https://shapeshift.io/images/coins/thedao.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"DGD": { |
||||||
|
"name": "DigixDao", |
||||||
|
"symbol": "DGD", |
||||||
|
"image": "https://shapeshift.io/images/coins/digixdao.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"DOGE": { |
||||||
|
"name": "Dogecoin", |
||||||
|
"symbol": "DOGE", |
||||||
|
"image": "https://shapeshift.io/images/coins/dogecoin.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"EMC": { |
||||||
|
"name": "Emercoin", |
||||||
|
"symbol": "EMC", |
||||||
|
"image": "https://shapeshift.io/images/coins/emercoin.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"ETH": { |
||||||
|
"name": "Ether", |
||||||
|
"symbol": "ETH", |
||||||
|
"image": "https://shapeshift.io/images/coins/ether.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"ETC": { |
||||||
|
"name": "Ether Classic", |
||||||
|
"symbol": "ETC", |
||||||
|
"image": "https://shapeshift.io/images/coins/etherclassic.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"FCT": { |
||||||
|
"name": "Factoids", |
||||||
|
"symbol": "FCT", |
||||||
|
"image": "https://shapeshift.io/images/coins/factoids.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"LBC": { |
||||||
|
"name": "LBRY Credits", |
||||||
|
"symbol": "LBC", |
||||||
|
"image": "https://shapeshift.io/images/coins/lbry.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"LSK": { |
||||||
|
"name": "Lisk", |
||||||
|
"symbol": "LSK", |
||||||
|
"image": "https://shapeshift.io/images/coins/lisk.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"LTC": { |
||||||
|
"name": "Litecoin", |
||||||
|
"symbol": "LTC", |
||||||
|
"image": "https://shapeshift.io/images/coins/litecoin.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"MAID": { |
||||||
|
"name": "Maidsafe", |
||||||
|
"symbol": "MAID", |
||||||
|
"image": "https://shapeshift.io/images/coins/maidsafe.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"MINT": { |
||||||
|
"name": "Mintcoin", |
||||||
|
"symbol": "MINT", |
||||||
|
"image": "https://shapeshift.io/images/coins/mintcoin.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"MONA": { |
||||||
|
"name": "Monacoin", |
||||||
|
"symbol": "MONA", |
||||||
|
"image": "https://shapeshift.io/images/coins/monacoin.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"MSC": { |
||||||
|
"name": "Omni", |
||||||
|
"symbol": "MSC", |
||||||
|
"image": "https://shapeshift.io/images/coins/mastercoin.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"NBT": { |
||||||
|
"name": "Nubits", |
||||||
|
"symbol": "NBT", |
||||||
|
"image": "https://shapeshift.io/images/coins/nubits.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"NMC": { |
||||||
|
"name": "Namecoin", |
||||||
|
"symbol": "NMC", |
||||||
|
"image": "https://shapeshift.io/images/coins/namecoin.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"NVC": { |
||||||
|
"name": "Novacoin", |
||||||
|
"symbol": "NVC", |
||||||
|
"image": "https://shapeshift.io/images/coins/novacoin.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"NXT": { |
||||||
|
"name": "Nxt", |
||||||
|
"symbol": "NXT", |
||||||
|
"specialReturn": false, |
||||||
|
"specialOutgoing": true, |
||||||
|
"specialIncoming": true, |
||||||
|
"specialIncomingStatus": false, |
||||||
|
"fieldName": "Public Key (only for unfunded accounts!)", |
||||||
|
"fieldKey": "rsAddress", |
||||||
|
"image": "https://shapeshift.io/images/coins/nxt.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"PPC": { |
||||||
|
"name": "Peercoin", |
||||||
|
"symbol": "PPC", |
||||||
|
"image": "https://shapeshift.io/images/coins/peercoin.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"RDD": { |
||||||
|
"name": "Reddcoin", |
||||||
|
"symbol": "RDD", |
||||||
|
"image": "https://shapeshift.io/images/coins/reddcoin.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"SDC": { |
||||||
|
"name": "Shadowcash", |
||||||
|
"symbol": "SDC", |
||||||
|
"image": "https://shapeshift.io/images/coins/shadowcash.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"SC": { |
||||||
|
"name": "Siacoin", |
||||||
|
"symbol": "SC", |
||||||
|
"image": "https://shapeshift.io/images/coins/siacoin.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"SJCX": { |
||||||
|
"name": "StorjX", |
||||||
|
"symbol": "SJCX", |
||||||
|
"image": "https://shapeshift.io/images/coins/storjcoinx.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"START": { |
||||||
|
"name": "Startcoin", |
||||||
|
"symbol": "START", |
||||||
|
"image": "https://shapeshift.io/images/coins/startcoin.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"STEEM": { |
||||||
|
"name": "Steem", |
||||||
|
"symbol": "STEEM", |
||||||
|
"specialReturn": false, |
||||||
|
"specialOutgoing": true, |
||||||
|
"specialIncoming": true, |
||||||
|
"fieldName": "destTag", |
||||||
|
"fieldKey": "destTag", |
||||||
|
"image": "https://shapeshift.io/images/coins/steem.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"USDT": { |
||||||
|
"name": "Tether", |
||||||
|
"symbol": "USDT", |
||||||
|
"image": "https://shapeshift.io/images/coins/tether.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"VOX": { |
||||||
|
"name": "Voxels", |
||||||
|
"symbol": "VOX", |
||||||
|
"image": "https://shapeshift.io/images/coins/voxels.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"VRC": { |
||||||
|
"name": "Vericoin", |
||||||
|
"symbol": "VRC", |
||||||
|
"image": "https://shapeshift.io/images/coins/vericoin.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"VTC": { |
||||||
|
"name": "Vertcoin", |
||||||
|
"symbol": "VTC", |
||||||
|
"image": "https://shapeshift.io/images/coins/vertcoin.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"XCP": { |
||||||
|
"name": "Counterparty", |
||||||
|
"symbol": "XCP", |
||||||
|
"image": "https://shapeshift.io/images/coins/counterparty.png", |
||||||
|
"status": "available" |
||||||
|
}, |
||||||
|
"XMR": { |
||||||
|
"name": "Monero", |
||||||
|
"symbol": "XMR", |
||||||
|
"specialReturn": false, |
||||||
|
"specialOutgoing": true, |
||||||
|
"specialIncoming": true, |
||||||
|
"fieldName": "Payment Id", |
||||||
|
"qrName": "tx_payment_id", |
||||||
|
"fieldKey": "paymentId", |
||||||
|
"image": "https://shapeshift.io/images/coins/monero.png", |
||||||
|
"status": "available" |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
"buyAddress": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", |
||||||
|
"amount": "5.00", |
||||||
|
"warning": null |
||||||
|
}, |
||||||
|
"isSubLoading": false |
||||||
|
}, |
||||||
|
"identities": {} |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
# Form Persisting Architecture |
||||||
|
|
||||||
|
Since: |
||||||
|
- The popup is torn down completely on every click outside of it. |
||||||
|
- We have forms with multiple fields (like passwords & seed phrases) that might encourage a user to leave our panel to refer to a password manager. |
||||||
|
|
||||||
|
We cause user friction when we lose the contents of certain forms. |
||||||
|
|
||||||
|
This calls for an architecture of a form component that can completely persist its values to LocalStorage on every relevant change, and restore those values on reopening. |
||||||
|
|
||||||
|
To achieve this, we have defined a class, a subclass of `React.Component`, called `PersistentForm`, and it's stored at `ui/lib/persistent-form.js`. |
||||||
|
|
||||||
|
To use this class, simply take your form component (the component that renders `input`, `select`, or `textarea` elements), and make it subclass from `PersistentForm` instead of `React.Component`. |
||||||
|
|
||||||
|
You can see an example of this in use in `ui/app/first-time/restore-vault.js`. |
||||||
|
|
||||||
|
Additionally, any field whose value should be persisted, should have a `persistentFormId` attribute, which needs to be assigned under a `dataset` key on the main `attributes` hash. For example: |
||||||
|
|
||||||
|
```javascript |
||||||
|
return h('textarea.twelve-word-phrase.letter-spacey', { |
||||||
|
dataset: { |
||||||
|
persistentFormId: 'wallet-seed', |
||||||
|
}, |
||||||
|
}) |
||||||
|
``` |
||||||
|
|
||||||
|
That's it! This field should be persisted to `localStorage` on each `keyUp`, those values should be restored on view load, and the cached values should be cleared when navigating deliberately away from the form. |
||||||
|
|
@ -0,0 +1,12 @@ |
|||||||
|
var assert = require('assert') |
||||||
|
var linkGen = require('../../ui/lib/account-link') |
||||||
|
|
||||||
|
describe('account-link', function() { |
||||||
|
|
||||||
|
it('adds testnet prefix to morden test network', function() { |
||||||
|
var result = linkGen('account', '2') |
||||||
|
assert.notEqual(result.indexOf('testnet'), -1, 'testnet injected') |
||||||
|
assert.notEqual(result.indexOf('account'), -1, 'account included') |
||||||
|
}) |
||||||
|
|
||||||
|
}) |
@ -0,0 +1,140 @@ |
|||||||
|
const Component = require('react').Component |
||||||
|
const h = require('react-hyperscript') |
||||||
|
const inherits = require('util').inherits |
||||||
|
const connect = require('react-redux').connect |
||||||
|
const formatBalance = require('../util').formatBalance |
||||||
|
const generateBalanceObject = require('../util').generateBalanceObject |
||||||
|
const Tooltip = require('./tooltip.js') |
||||||
|
|
||||||
|
module.exports = connect(mapStateToProps)(EthBalanceComponent) |
||||||
|
|
||||||
|
function mapStateToProps (state) { |
||||||
|
return { |
||||||
|
conversionRate: state.metamask.conversionRate, |
||||||
|
conversionDate: state.metamask.conversionDate, |
||||||
|
currentFiat: state.metamask.currentFiat, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
inherits(EthBalanceComponent, Component) |
||||||
|
function EthBalanceComponent () { |
||||||
|
Component.call(this) |
||||||
|
} |
||||||
|
|
||||||
|
EthBalanceComponent.prototype.render = function () { |
||||||
|
var state = this.props |
||||||
|
var style = state.style |
||||||
|
|
||||||
|
const value = formatBalance(state.value, 6) |
||||||
|
var width = state.width |
||||||
|
|
||||||
|
return ( |
||||||
|
|
||||||
|
h('.ether-balance', { |
||||||
|
style: style, |
||||||
|
}, [ |
||||||
|
h('.ether-balance-amount', { |
||||||
|
style: { |
||||||
|
display: 'inline', |
||||||
|
width: width, |
||||||
|
}, |
||||||
|
}, this.renderBalance(value, state)), |
||||||
|
]) |
||||||
|
|
||||||
|
) |
||||||
|
} |
||||||
|
EthBalanceComponent.prototype.renderBalance = function (value, state) { |
||||||
|
if (value === 'None') return value |
||||||
|
var balanceObj = generateBalanceObject(value, state.shorten ? 1 : 3) |
||||||
|
var balance, fiatDisplayNumber, fiatTooltipNumber |
||||||
|
var splitBalance = value.split(' ') |
||||||
|
var ethNumber = splitBalance[0] |
||||||
|
var ethSuffix = splitBalance[1] |
||||||
|
|
||||||
|
|
||||||
|
if (state.conversionRate !== 0) { |
||||||
|
fiatTooltipNumber = Number(splitBalance[0]) * state.conversionRate |
||||||
|
fiatDisplayNumber = fiatTooltipNumber.toFixed(2) |
||||||
|
} else { |
||||||
|
fiatDisplayNumber = 'N/A' |
||||||
|
} |
||||||
|
|
||||||
|
var fiatSuffix = state.currentFiat |
||||||
|
|
||||||
|
if (state.shorten) { |
||||||
|
balance = balanceObj.shortBalance |
||||||
|
} else { |
||||||
|
balance = balanceObj.balance |
||||||
|
} |
||||||
|
|
||||||
|
var label = balanceObj.label |
||||||
|
|
||||||
|
return ( |
||||||
|
h('.flex-column', [ |
||||||
|
h(Tooltip, { |
||||||
|
position: 'bottom', |
||||||
|
title: `${ethNumber} ${ethSuffix}`, |
||||||
|
}, [ |
||||||
|
h('.flex-row', { |
||||||
|
style: { |
||||||
|
alignItems: 'flex-end', |
||||||
|
lineHeight: '13px', |
||||||
|
fontFamily: 'Montserrat Light', |
||||||
|
textRendering: 'geometricPrecision', |
||||||
|
marginBottom: '5px', |
||||||
|
}, |
||||||
|
}, [ |
||||||
|
h('div', { |
||||||
|
style: { |
||||||
|
width: '100%', |
||||||
|
textAlign: 'right', |
||||||
|
}, |
||||||
|
}, balance), |
||||||
|
h('div', { |
||||||
|
style: { |
||||||
|
color: '#AEAEAE', |
||||||
|
marginLeft: '5px', |
||||||
|
}, |
||||||
|
}, label), |
||||||
|
]), |
||||||
|
]), |
||||||
|
h(Tooltip, { |
||||||
|
position: 'bottom', |
||||||
|
title: `${fiatTooltipNumber} ${fiatSuffix}`, |
||||||
|
}, [ |
||||||
|
fiatDisplay(fiatDisplayNumber, fiatSuffix), |
||||||
|
]), |
||||||
|
]) |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
function fiatDisplay (fiatDisplayNumber, fiatSuffix) { |
||||||
|
if (fiatDisplayNumber !== 'N/A') { |
||||||
|
return h('.flex-row', { |
||||||
|
style: { |
||||||
|
alignItems: 'flex-end', |
||||||
|
lineHeight: '13px', |
||||||
|
fontFamily: 'Montserrat Light', |
||||||
|
textRendering: 'geometricPrecision', |
||||||
|
}, |
||||||
|
}, [ |
||||||
|
h('div', { |
||||||
|
style: { |
||||||
|
width: '100%', |
||||||
|
textAlign: 'right', |
||||||
|
fontSize: '12px', |
||||||
|
color: '#333333', |
||||||
|
}, |
||||||
|
}, fiatDisplayNumber), |
||||||
|
h('div', { |
||||||
|
style: { |
||||||
|
color: '#AEAEAE', |
||||||
|
marginLeft: '5px', |
||||||
|
fontSize: '12px', |
||||||
|
}, |
||||||
|
}, fiatSuffix), |
||||||
|
]) |
||||||
|
} else { |
||||||
|
return h('div') |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
const Component = require('react').Component |
||||||
|
const h = require('react-hyperscript') |
||||||
|
const inherits = require('util').inherits |
||||||
|
const Tooltip = require('./tooltip') |
||||||
|
const genAccountLink = require('../../lib/account-link') |
||||||
|
const extension = require('../../../app/scripts/lib/extension') |
||||||
|
|
||||||
|
module.exports = AccountInfoLink |
||||||
|
|
||||||
|
inherits(AccountInfoLink, Component) |
||||||
|
function AccountInfoLink () { |
||||||
|
Component.call(this) |
||||||
|
} |
||||||
|
|
||||||
|
AccountInfoLink.prototype.render = function () { |
||||||
|
const { selected, network } = this.props |
||||||
|
const title = 'View account on etherscan' |
||||||
|
const url = genAccountLink(selected, network) |
||||||
|
|
||||||
|
if (!url) { |
||||||
|
return null |
||||||
|
} |
||||||
|
|
||||||
|
return h('.account-info-link', { |
||||||
|
style: { |
||||||
|
display: 'flex', |
||||||
|
alignItems: 'center', |
||||||
|
}, |
||||||
|
}, [ |
||||||
|
|
||||||
|
h(Tooltip, { |
||||||
|
title, |
||||||
|
}, [ |
||||||
|
h('i.fa.fa-info-circle.cursor-pointer.color-orange', { |
||||||
|
style: { |
||||||
|
margin: '5px', |
||||||
|
}, |
||||||
|
onClick () { extension.tabs.create({ url }) }, |
||||||
|
}), |
||||||
|
]), |
||||||
|
]) |
||||||
|
} |
@ -0,0 +1,123 @@ |
|||||||
|
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 CoinbaseForm = require('./coinbase-form') |
||||||
|
const ShapeshiftForm = require('./shapeshift-form') |
||||||
|
const extension = require('../../../app/scripts/lib/extension') |
||||||
|
|
||||||
|
module.exports = connect(mapStateToProps)(BuyButtonSubview) |
||||||
|
|
||||||
|
function mapStateToProps (state) { |
||||||
|
return { |
||||||
|
selectedAccount: state.selectedAccount, |
||||||
|
warning: state.appState.warning, |
||||||
|
buyView: state.appState.buyView, |
||||||
|
network: state.metamask.network, |
||||||
|
provider: state.metamask.provider, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
inherits(BuyButtonSubview, Component) |
||||||
|
function BuyButtonSubview () { |
||||||
|
Component.call(this) |
||||||
|
} |
||||||
|
|
||||||
|
BuyButtonSubview.prototype.render = function () { |
||||||
|
const props = this.props |
||||||
|
const currentForm = props.buyView.formView |
||||||
|
|
||||||
|
return ( |
||||||
|
h('.buy-eth-section', [ |
||||||
|
// back button
|
||||||
|
h('.flex-row', { |
||||||
|
style: { |
||||||
|
alignItems: 'center', |
||||||
|
justifyContent: 'center', |
||||||
|
}, |
||||||
|
}, [ |
||||||
|
h('i.fa.fa-arrow-left.fa-lg.cursor-pointer.color-orange', { |
||||||
|
onClick: () => props.dispatch(actions.backToAccountDetail(props.selectedAccount)), |
||||||
|
style: { |
||||||
|
position: 'absolute', |
||||||
|
left: '10px', |
||||||
|
}, |
||||||
|
}), |
||||||
|
h('h2.page-subtitle', 'Buy Eth'), |
||||||
|
]), |
||||||
|
h('h3.flex-row.text-transform-uppercase', { |
||||||
|
style: { |
||||||
|
background: '#EBEBEB', |
||||||
|
color: '#AEAEAE', |
||||||
|
paddingTop: '4px', |
||||||
|
justifyContent: 'space-around', |
||||||
|
}, |
||||||
|
}, [ |
||||||
|
h(currentForm.coinbase ? '.activeForm' : '.inactiveForm.pointer', { |
||||||
|
onClick: () => props.dispatch(actions.coinBaseSubview()), |
||||||
|
}, 'Coinbase'), |
||||||
|
h('a', { |
||||||
|
onClick: (event) => this.navigateTo('https://github.com/MetaMask/faq/blob/master/COINBASE.md'), |
||||||
|
}, [ |
||||||
|
h('i.fa.fa-question-circle', { |
||||||
|
style: { |
||||||
|
position: 'relative', |
||||||
|
right: '33px', |
||||||
|
}, |
||||||
|
}), |
||||||
|
]), |
||||||
|
h(currentForm.shapeshift ? '.activeForm' : '.inactiveForm.pointer', { |
||||||
|
onClick: () => props.dispatch(actions.shapeShiftSubview(props.provider.type)), |
||||||
|
}, 'Shapeshift'), |
||||||
|
|
||||||
|
h('a', { |
||||||
|
href: 'https://github.com/MetaMask/faq/blob/master/COINBASE.md', |
||||||
|
onClick: (event) => this.navigateTo('https://info.shapeshift.io/about'), |
||||||
|
}, [ |
||||||
|
h('i.fa.fa-question-circle', { |
||||||
|
style: { |
||||||
|
position: 'relative', |
||||||
|
right: '28px', |
||||||
|
}, |
||||||
|
}), |
||||||
|
]), |
||||||
|
]), |
||||||
|
this.formVersionSubview(), |
||||||
|
]) |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
BuyButtonSubview.prototype.formVersionSubview = function () { |
||||||
|
if (this.props.network === '1') { |
||||||
|
if (this.props.buyView.formView.coinbase) { |
||||||
|
return h(CoinbaseForm, this.props) |
||||||
|
} else if (this.props.buyView.formView.shapeshift) { |
||||||
|
return h(ShapeshiftForm, this.props) |
||||||
|
} |
||||||
|
} else { |
||||||
|
return h('div.flex-column', { |
||||||
|
style: { |
||||||
|
alignItems: 'center', |
||||||
|
margin: '50px', |
||||||
|
}, |
||||||
|
}, [ |
||||||
|
h('h3.text-transform-uppercase', { |
||||||
|
style: { |
||||||
|
width: '225px', |
||||||
|
}, |
||||||
|
}, 'In order to access this feature please switch too the Main Network'), |
||||||
|
h('h3.text-transform-uppercase', 'or:'), |
||||||
|
this.props.network === '2' ? h('button.text-transform-uppercase', { |
||||||
|
onClick: () => this.props.dispatch(actions.buyEth()), |
||||||
|
style: { |
||||||
|
marginTop: '15px', |
||||||
|
}, |
||||||
|
}, 'Go To Test Faucet') : null, |
||||||
|
]) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
BuyButtonSubview.prototype.navigateTo = function (url) { |
||||||
|
extension.tabs.create({ url }) |
||||||
|
} |
@ -0,0 +1,162 @@ |
|||||||
|
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 isValidAddress = require('../util').isValidAddress |
||||||
|
module.exports = connect(mapStateToProps)(CoinbaseForm) |
||||||
|
|
||||||
|
function mapStateToProps(state) { |
||||||
|
return { |
||||||
|
selectedAccount: state.selectedAccount, |
||||||
|
warning: state.appState.warning, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
inherits(CoinbaseForm, Component) |
||||||
|
|
||||||
|
function CoinbaseForm() { |
||||||
|
Component.call(this) |
||||||
|
} |
||||||
|
|
||||||
|
CoinbaseForm.prototype.render = function () { |
||||||
|
var props = this.props |
||||||
|
var amount = props.buyView.amount |
||||||
|
var address = props.buyView.buyAddress |
||||||
|
|
||||||
|
return h('.flex-column', { |
||||||
|
style: { |
||||||
|
// margin: '10px',
|
||||||
|
padding: '25px', |
||||||
|
}, |
||||||
|
}, [ |
||||||
|
h('.flex-column', { |
||||||
|
style: { |
||||||
|
alignItems: 'flex-start', |
||||||
|
}, |
||||||
|
}, [ |
||||||
|
h('.flex-row', [ |
||||||
|
h('div', 'Address:'), |
||||||
|
h('.ellip-address', address), |
||||||
|
]), |
||||||
|
h('.flex-row', [ |
||||||
|
h('div', 'Amount: $'), |
||||||
|
h('.input-container', [ |
||||||
|
h('input.buy-inputs', { |
||||||
|
style: { |
||||||
|
width: '3em', |
||||||
|
boxSizing: 'border-box', |
||||||
|
}, |
||||||
|
defaultValue: amount, |
||||||
|
onChange: this.handleAmount.bind(this), |
||||||
|
}), |
||||||
|
h('i.fa.fa-pencil-square-o.edit-text', { |
||||||
|
style: { |
||||||
|
fontSize: '12px', |
||||||
|
color: '#F7861C', |
||||||
|
position: 'relative', |
||||||
|
bottom: '5px', |
||||||
|
right: '11px', |
||||||
|
}, |
||||||
|
}), |
||||||
|
]), |
||||||
|
]), |
||||||
|
]), |
||||||
|
|
||||||
|
h('.info-gray', { |
||||||
|
style: { |
||||||
|
fontSize: '10px', |
||||||
|
fontFamily: 'Montserrat Light', |
||||||
|
margin: '15px', |
||||||
|
lineHeight: '13px', |
||||||
|
}, |
||||||
|
}, |
||||||
|
`there is a USD$ 5 a day max and a USD$ 50
|
||||||
|
dollar limit per the life time of an account without a |
||||||
|
coinbase account. A fee of 3.75% will be aplied to debit/credit cards.`),
|
||||||
|
|
||||||
|
!props.warning ? h('div', { |
||||||
|
style: { |
||||||
|
width: '340px', |
||||||
|
height: '22px', |
||||||
|
}, |
||||||
|
}) : props.warning && h('span.error.flex-center', props.warning), |
||||||
|
|
||||||
|
|
||||||
|
h('.flex-row', { |
||||||
|
style: { |
||||||
|
justifyContent: 'space-around', |
||||||
|
margin: '33px', |
||||||
|
}, |
||||||
|
}, [ |
||||||
|
h('button', { |
||||||
|
onClick: this.toCoinbase.bind(this), |
||||||
|
}, 'Continue to Coinbase'), |
||||||
|
|
||||||
|
h('button', { |
||||||
|
onClick: () => props.dispatch(actions.backTobuyView(props.accounts.address)), |
||||||
|
}, 'Cancel'), |
||||||
|
]), |
||||||
|
]) |
||||||
|
} |
||||||
|
CoinbaseForm.prototype.handleAmount = function (event) { |
||||||
|
this.props.dispatch(actions.updateCoinBaseAmount(event.target.value)) |
||||||
|
} |
||||||
|
CoinbaseForm.prototype.handleAddress = function (event) { |
||||||
|
this.props.dispatch(actions.updateBuyAddress(event.target.value)) |
||||||
|
} |
||||||
|
CoinbaseForm.prototype.toCoinbase = function () { |
||||||
|
var props = this.props |
||||||
|
var amount = props.buyView.amount |
||||||
|
var address = props.buyView.buyAddress |
||||||
|
var message |
||||||
|
|
||||||
|
if (isValidAddress(address) && isValidAmountforCoinBase(amount).valid) { |
||||||
|
props.dispatch(actions.buyEth(address, props.buyView.amount)) |
||||||
|
} else if (!isValidAmountforCoinBase(amount).valid) { |
||||||
|
message = isValidAmountforCoinBase(amount).message |
||||||
|
return props.dispatch(actions.showWarning(message)) |
||||||
|
} else { |
||||||
|
message = 'Receiving address is invalid.' |
||||||
|
return props.dispatch(actions.showWarning(message)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
CoinbaseForm.prototype.renderLoading = function () { |
||||||
|
|
||||||
|
return h('img', { |
||||||
|
style: { |
||||||
|
width: '27px', |
||||||
|
marginRight: '-27px', |
||||||
|
}, |
||||||
|
src: 'images/loading.svg', |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
function isValidAmountforCoinBase(amount) { |
||||||
|
amount = parseFloat(amount) |
||||||
|
|
||||||
|
if (amount) { |
||||||
|
if (amount <= 5 && amount > 0) { |
||||||
|
return { |
||||||
|
valid: true, |
||||||
|
} |
||||||
|
} else if (amount > 5) { |
||||||
|
return { |
||||||
|
valid: false, |
||||||
|
message: 'The amount can not be greater then $5', |
||||||
|
} |
||||||
|
} else { |
||||||
|
return { |
||||||
|
valid: false, |
||||||
|
message: 'Can not buy amounts less then $0', |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
return { |
||||||
|
valid: false, |
||||||
|
message: 'The amount entered is not a number', |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,71 @@ |
|||||||
|
const Component = require('react').Component |
||||||
|
const h = require('react-hyperscript') |
||||||
|
const inherits = require('util').inherits |
||||||
|
const connect = require('react-redux').connect |
||||||
|
const CopyButton = require('./copyButton') |
||||||
|
|
||||||
|
module.exports = connect(mapStateToProps)(QrCodeView) |
||||||
|
|
||||||
|
function mapStateToProps (state) { |
||||||
|
return { |
||||||
|
Qr: state.appState.Qr, |
||||||
|
buyView: state.appState.buyView, |
||||||
|
warning: state.appState.warning, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
inherits(QrCodeView, Component) |
||||||
|
|
||||||
|
function QrCodeView () { |
||||||
|
Component.call(this) |
||||||
|
} |
||||||
|
|
||||||
|
QrCodeView.prototype.render = function () { |
||||||
|
var props = this.props |
||||||
|
var Qr = props.Qr |
||||||
|
return h('.main-container.flex-column', { |
||||||
|
key: 'qr', |
||||||
|
style: { |
||||||
|
justifyContent: 'center', |
||||||
|
padding: '45px', |
||||||
|
alignItems: 'center', |
||||||
|
}, |
||||||
|
}, [ |
||||||
|
Array.isArray(Qr.message) ? h('.message-container', this.renderMultiMessage()) : h('h3', Qr.message), |
||||||
|
|
||||||
|
this.props.warning ? this.props.warning && h('span.error.flex-center', { |
||||||
|
style: { |
||||||
|
textAlign: 'center', |
||||||
|
width: '229px', |
||||||
|
height: '82px', |
||||||
|
}, |
||||||
|
}, |
||||||
|
this.props.warning) : null, |
||||||
|
|
||||||
|
h('#qr-container.flex-column', { |
||||||
|
style: { |
||||||
|
marginTop: '25px', |
||||||
|
marginBottom: '15px', |
||||||
|
}, |
||||||
|
dangerouslySetInnerHTML: { |
||||||
|
__html: Qr.image, |
||||||
|
}, |
||||||
|
}), |
||||||
|
h('.flex-row', [ |
||||||
|
h('h3.ellip-address', { |
||||||
|
style: { |
||||||
|
width: '247px', |
||||||
|
}, |
||||||
|
}, Qr.data), |
||||||
|
h(CopyButton, { |
||||||
|
value: Qr.data, |
||||||
|
}), |
||||||
|
]), |
||||||
|
]) |
||||||
|
} |
||||||
|
|
||||||
|
QrCodeView.prototype.renderMultiMessage = function () { |
||||||
|
var Qr = this.props.Qr |
||||||
|
var multiMessage = Qr.message.map((message) => h('.qr-message', message)) |
||||||
|
return multiMessage |
||||||
|
} |
@ -0,0 +1,322 @@ |
|||||||
|
const PersistentForm = require('../../lib/persistent-form') |
||||||
|
const h = require('react-hyperscript') |
||||||
|
const inherits = require('util').inherits |
||||||
|
const connect = require('react-redux').connect |
||||||
|
const ReactCSSTransitionGroup = require('react-addons-css-transition-group') |
||||||
|
const actions = require('../actions') |
||||||
|
const Qr = require('./qr-code') |
||||||
|
const isValidAddress = require('../util').isValidAddress |
||||||
|
module.exports = connect(mapStateToProps)(ShapeshiftForm) |
||||||
|
|
||||||
|
function mapStateToProps(state) { |
||||||
|
return { |
||||||
|
selectedAccount: state.selectedAccount, |
||||||
|
warning: state.appState.warning, |
||||||
|
isSubLoading: state.appState.isSubLoading, |
||||||
|
qrRequested: state.appState.qrRequested, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
inherits(ShapeshiftForm, PersistentForm) |
||||||
|
|
||||||
|
function ShapeshiftForm () { |
||||||
|
PersistentForm.call(this) |
||||||
|
this.persistentFormParentId = 'shapeshift-buy-form' |
||||||
|
} |
||||||
|
|
||||||
|
ShapeshiftForm.prototype.render = function () { |
||||||
|
|
||||||
|
return h(ReactCSSTransitionGroup, { |
||||||
|
className: 'css-transition-group', |
||||||
|
transitionName: 'main', |
||||||
|
transitionEnterTimeout: 300, |
||||||
|
transitionLeaveTimeout: 300, |
||||||
|
}, [ |
||||||
|
this.props.qrRequested ? h(Qr, {key: 'qr'}) : this.renderMain(), |
||||||
|
]) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
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: { |
||||||
|
// marginTop: '10px',
|
||||||
|
padding: '25px', |
||||||
|
width: '100%', |
||||||
|
alignItems: 'center', |
||||||
|
}, |
||||||
|
}, [ |
||||||
|
h('.flex-row', { |
||||||
|
style: { |
||||||
|
justifyContent: 'center', |
||||||
|
alignItems: 'baseline', |
||||||
|
}, |
||||||
|
}, [ |
||||||
|
h('img', { |
||||||
|
src: coinOptions[coin].image, |
||||||
|
width: '25px', |
||||||
|
height: '25px', |
||||||
|
style: { |
||||||
|
marginRight: '5px', |
||||||
|
}, |
||||||
|
}), |
||||||
|
|
||||||
|
h('.input-container', [ |
||||||
|
h('input#fromCoin.buy-inputs.ex-coins', { |
||||||
|
type: 'text', |
||||||
|
list: 'coinList', |
||||||
|
dataset: { |
||||||
|
persistentFormId: 'input-coin', |
||||||
|
}, |
||||||
|
style: { |
||||||
|
boxSizing: 'border-box', |
||||||
|
}, |
||||||
|
onChange: this.handleLiveInput.bind(this), |
||||||
|
defaultValue: 'BTC', |
||||||
|
}), |
||||||
|
|
||||||
|
this.renderCoinList(), |
||||||
|
|
||||||
|
h('i.fa.fa-pencil-square-o.edit-text', { |
||||||
|
style: { |
||||||
|
fontSize: '12px', |
||||||
|
color: '#F7861C', |
||||||
|
position: 'relative', |
||||||
|
bottom: '48px', |
||||||
|
left: '106px', |
||||||
|
}, |
||||||
|
}), |
||||||
|
]), |
||||||
|
|
||||||
|
h('.icon-control', [ |
||||||
|
h('i.fa.fa-refresh.fa-4.orange', { |
||||||
|
style: { |
||||||
|
position: 'relative', |
||||||
|
bottom: '5px', |
||||||
|
left: '5px', |
||||||
|
color: '#F7861C', |
||||||
|
}, |
||||||
|
onClick: this.updateCoin.bind(this), |
||||||
|
}), |
||||||
|
h('i.fa.fa-chevron-right.fa-4.orange', { |
||||||
|
style: { |
||||||
|
position: 'relative', |
||||||
|
bottom: '26px', |
||||||
|
left: '10px', |
||||||
|
color: '#F7861C', |
||||||
|
}, |
||||||
|
onClick: this.updateCoin.bind(this), |
||||||
|
}), |
||||||
|
]), |
||||||
|
|
||||||
|
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', |
||||||
|
}, |
||||||
|
}), |
||||||
|
]), |
||||||
|
|
||||||
|
this.props.isSubLoading ? this.renderLoading() : null, |
||||||
|
h('.flex-column', { |
||||||
|
style: { |
||||||
|
width: '235px', |
||||||
|
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(), |
||||||
|
]), |
||||||
|
|
||||||
|
h('.flex-row', { |
||||||
|
style: { |
||||||
|
padding: '10px', |
||||||
|
paddingBottom: '2px', |
||||||
|
width: '100%', |
||||||
|
}, |
||||||
|
}, [ |
||||||
|
h('div', 'Receiving address:'), |
||||||
|
h('.ellip-address', this.props.buyView.buyAddress), |
||||||
|
]), |
||||||
|
|
||||||
|
h(this.activeToggle('.input-container'), { |
||||||
|
style: { |
||||||
|
padding: '10px', |
||||||
|
paddingTop: '0px', |
||||||
|
width: '100%', |
||||||
|
}, |
||||||
|
}, [ |
||||||
|
h('div', `${coin} Address:`), |
||||||
|
|
||||||
|
h('input#fromCoinAddress.buy-inputs', { |
||||||
|
type: 'text', |
||||||
|
placeholder: `Your ${coin} Refund Address`, |
||||||
|
dataset: { |
||||||
|
persistentFormId: 'refund-address', |
||||||
|
}, |
||||||
|
style: { |
||||||
|
boxSizing: 'border-box', |
||||||
|
width: '278px', |
||||||
|
height: '20px', |
||||||
|
padding: ' 5px ', |
||||||
|
}, |
||||||
|
}), |
||||||
|
|
||||||
|
h('i.fa.fa-pencil-square-o.edit-text', { |
||||||
|
style: { |
||||||
|
fontSize: '12px', |
||||||
|
color: '#F7861C', |
||||||
|
position: 'relative', |
||||||
|
bottom: '5px', |
||||||
|
right: '11px', |
||||||
|
}, |
||||||
|
}), |
||||||
|
h('.flex-row', { |
||||||
|
style: { |
||||||
|
justifyContent: 'flex-end', |
||||||
|
}, |
||||||
|
}, [ |
||||||
|
h('button', { |
||||||
|
onClick: this.shift.bind(this), |
||||||
|
style: { |
||||||
|
marginTop: '10px', |
||||||
|
}, |
||||||
|
}, |
||||||
|
'Submit'), |
||||||
|
]), |
||||||
|
]), |
||||||
|
]) |
||||||
|
} |
||||||
|
|
||||||
|
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) |
||||||
|
}) |
||||||
|
|
||||||
|
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.showWarning(message)) |
||||||
|
} else { |
||||||
|
return props.dispatch(actions.pairUpdate(coin)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
ShapeshiftForm.prototype.handleLiveInput = function () { |
||||||
|
const props = this.props |
||||||
|
var coinOptions = this.props.buyView.formView.coinOptions |
||||||
|
var coin = document.getElementById('fromCoin').value |
||||||
|
|
||||||
|
if (!coinOptions[coin.toUpperCase()] || coin.toUpperCase() === 'ETH') { |
||||||
|
return null |
||||||
|
} else { |
||||||
|
return props.dispatch(actions.pairUpdate(coin)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
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() |
||||||
|
|
||||||
|
return h('span', { |
||||||
|
style: { |
||||||
|
marginTop: '15px', |
||||||
|
marginBottom: '15px', |
||||||
|
}, |
||||||
|
}, [ |
||||||
|
h('h3.flex-row.text-transform-uppercase', { |
||||||
|
style: { |
||||||
|
color: '#AEAEAE', |
||||||
|
paddingTop: '4px', |
||||||
|
justifyContent: 'space-around', |
||||||
|
textAlign: 'center', |
||||||
|
fontSize: '14px', |
||||||
|
}, |
||||||
|
}, `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.handleAddress = function (event) { |
||||||
|
this.props.dispatch(actions.updateBuyAddress(event.target.value)) |
||||||
|
} |
||||||
|
|
||||||
|
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('img', { |
||||||
|
style: { |
||||||
|
width: '60px', |
||||||
|
}, |
||||||
|
src: 'images/loading.svg', |
||||||
|
}), |
||||||
|
]) |
||||||
|
} |
@ -0,0 +1,202 @@ |
|||||||
|
const inherits = require('util').inherits |
||||||
|
const Component = require('react').Component |
||||||
|
const h = require('react-hyperscript') |
||||||
|
const connect = require('react-redux').connect |
||||||
|
const vreme = new (require('vreme')) |
||||||
|
const explorerLink = require('../../lib/explorer-link') |
||||||
|
const extension = require('../../../app/scripts/lib/extension') |
||||||
|
const actions = require('../actions') |
||||||
|
const addressSummary = require('../util').addressSummary |
||||||
|
|
||||||
|
const CopyButton = require('./copyButton') |
||||||
|
const EtherBalance = require('./eth-balance') |
||||||
|
const Tooltip = require('./tooltip') |
||||||
|
|
||||||
|
|
||||||
|
module.exports = connect(mapStateToProps)(ShiftListItem) |
||||||
|
|
||||||
|
function mapStateToProps (state) { |
||||||
|
return {} |
||||||
|
} |
||||||
|
|
||||||
|
inherits(ShiftListItem, Component) |
||||||
|
|
||||||
|
function ShiftListItem () { |
||||||
|
Component.call(this) |
||||||
|
} |
||||||
|
|
||||||
|
ShiftListItem.prototype.render = function () { |
||||||
|
|
||||||
|
return ( |
||||||
|
h('.transaction-list-item.flex-row', { |
||||||
|
style: { |
||||||
|
paddingTop: '20px', |
||||||
|
paddingBottom: '20px', |
||||||
|
justifyContent: 'space-around', |
||||||
|
alignItems: 'center', |
||||||
|
}, |
||||||
|
}, [ |
||||||
|
h('div', { |
||||||
|
style: { |
||||||
|
width: '0px', |
||||||
|
position: 'relative', |
||||||
|
bottom: '19px', |
||||||
|
}, |
||||||
|
}, [ |
||||||
|
h('img', { |
||||||
|
src: 'https://info.shapeshift.io/sites/default/files/logo.png', |
||||||
|
style: { |
||||||
|
height: '35px', |
||||||
|
width: '132px', |
||||||
|
position: 'absolute', |
||||||
|
clip: 'rect(0px,23px,34px,0px)', |
||||||
|
}, |
||||||
|
}), |
||||||
|
]), |
||||||
|
|
||||||
|
this.renderInfo(), |
||||||
|
this.renderUtilComponents(), |
||||||
|
]) |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
function formatDate (date) { |
||||||
|
return vreme.format(new Date(date), 'March 16 2014 14:30') |
||||||
|
} |
||||||
|
|
||||||
|
ShiftListItem.prototype.renderUtilComponents = function () { |
||||||
|
var props = this.props |
||||||
|
|
||||||
|
switch (props.response.status) { |
||||||
|
case 'no_deposits': |
||||||
|
return h('.flex-row', [ |
||||||
|
h(CopyButton, { |
||||||
|
value: this.props.depositAddress, |
||||||
|
}), |
||||||
|
h(Tooltip, { |
||||||
|
title: 'QR Code', |
||||||
|
}, [ |
||||||
|
h('i.fa.fa-qrcode.pointer.pop-hover', { |
||||||
|
onClick: () => props.dispatch(actions.reshowQrCode(props.depositAddress, props.depositType)), |
||||||
|
style: { |
||||||
|
margin: '5px', |
||||||
|
marginLeft: '23px', |
||||||
|
marginRight: '12px', |
||||||
|
fontSize: '20px', |
||||||
|
color: '#F7861C', |
||||||
|
}, |
||||||
|
}), |
||||||
|
]), |
||||||
|
]) |
||||||
|
case 'received': |
||||||
|
return h('.flex-row') |
||||||
|
|
||||||
|
case 'complete': |
||||||
|
return h('.flex-row', [ |
||||||
|
h(CopyButton, { |
||||||
|
value: this.props.response.transaction, |
||||||
|
}), |
||||||
|
h(EtherBalance, { |
||||||
|
value: `${props.response.outgoingCoin}`, |
||||||
|
width: '55px', |
||||||
|
shorten: true, |
||||||
|
needsParse: false, |
||||||
|
incoming: true, |
||||||
|
style: { |
||||||
|
fontSize: '15px', |
||||||
|
color: '#01888C', |
||||||
|
}, |
||||||
|
}), |
||||||
|
]) |
||||||
|
|
||||||
|
case 'failed': |
||||||
|
return '' |
||||||
|
default: |
||||||
|
return '' |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
ShiftListItem.prototype.renderInfo = function () { |
||||||
|
var props = this.props |
||||||
|
switch (props.response.status) { |
||||||
|
case 'no_deposits': |
||||||
|
return h('.flex-column', { |
||||||
|
style: { |
||||||
|
width: '200px', |
||||||
|
overflow: 'hidden', |
||||||
|
}, |
||||||
|
}, [ |
||||||
|
h('div', { |
||||||
|
style: { |
||||||
|
fontSize: 'x-small', |
||||||
|
color: '#ABA9AA', |
||||||
|
width: '100%', |
||||||
|
}, |
||||||
|
}, `${props.depositType} to ETH via ShapeShift`), |
||||||
|
h('div', 'No deposits received'), |
||||||
|
h('div', { |
||||||
|
style: { |
||||||
|
fontSize: 'x-small', |
||||||
|
color: '#ABA9AA', |
||||||
|
width: '100%', |
||||||
|
}, |
||||||
|
}, formatDate(props.time)), |
||||||
|
]) |
||||||
|
case 'received': |
||||||
|
return h('.flex-column', { |
||||||
|
style: { |
||||||
|
width: '200px', |
||||||
|
overflow: 'hidden', |
||||||
|
}, |
||||||
|
}, [ |
||||||
|
h('div', { |
||||||
|
style: { |
||||||
|
fontSize: 'x-small', |
||||||
|
color: '#ABA9AA', |
||||||
|
width: '100%', |
||||||
|
}, |
||||||
|
}, `${props.depositType} to ETH via ShapeShift`), |
||||||
|
h('div', 'Conversion in progress'), |
||||||
|
h('div', { |
||||||
|
style: { |
||||||
|
fontSize: 'x-small', |
||||||
|
color: '#ABA9AA', |
||||||
|
width: '100%', |
||||||
|
}, |
||||||
|
}, formatDate(props.time)), |
||||||
|
]) |
||||||
|
case 'complete': |
||||||
|
var url = explorerLink(props.response.transaction, parseInt('1')) |
||||||
|
|
||||||
|
return h('.flex-column.pointer', { |
||||||
|
style: { |
||||||
|
width: '200px', |
||||||
|
overflow: 'hidden', |
||||||
|
}, |
||||||
|
onClick: () => extension.tabs.create({ |
||||||
|
url, |
||||||
|
}), |
||||||
|
}, [ |
||||||
|
h('div', { |
||||||
|
style: { |
||||||
|
fontSize: 'x-small', |
||||||
|
color: '#ABA9AA', |
||||||
|
width: '100%', |
||||||
|
}, |
||||||
|
}, 'From ShapeShift'), |
||||||
|
h('div', formatDate(props.time)), |
||||||
|
h('div', { |
||||||
|
style: { |
||||||
|
fontSize: 'x-small', |
||||||
|
color: '#ABA9AA', |
||||||
|
width: '100%', |
||||||
|
}, |
||||||
|
}, addressSummary(props.response.transaction)), |
||||||
|
]) |
||||||
|
|
||||||
|
case 'failed': |
||||||
|
return h('span.error', '(Failed)') |
||||||
|
default: |
||||||
|
return '' |
||||||
|
} |
||||||
|
} |
File diff suppressed because one or more lines are too long
@ -0,0 +1,18 @@ |
|||||||
|
module.exports = function(address, network) { |
||||||
|
const net = parseInt(network) |
||||||
|
let link |
||||||
|
|
||||||
|
switch (net) { |
||||||
|
case 1: // main net
|
||||||
|
link = `http://etherscan.io/address/${address}` |
||||||
|
break |
||||||
|
case 2: // morden test net
|
||||||
|
link = `http://testnet.etherscan.io/address/${address}` |
||||||
|
break |
||||||
|
default: |
||||||
|
link = '' |
||||||
|
break |
||||||
|
} |
||||||
|
|
||||||
|
return link |
||||||
|
} |
@ -0,0 +1,57 @@ |
|||||||
|
const inherits = require('util').inherits |
||||||
|
const Component = require('react').Component |
||||||
|
const defaultKey = 'persistent-form-default' |
||||||
|
const eventName = 'keyup' |
||||||
|
|
||||||
|
module.exports = PersistentForm |
||||||
|
|
||||||
|
function PersistentForm () { |
||||||
|
Component.call(this) |
||||||
|
} |
||||||
|
|
||||||
|
inherits(PersistentForm, Component) |
||||||
|
|
||||||
|
PersistentForm.prototype.componentDidMount = function () { |
||||||
|
const fields = document.querySelectorAll('[data-persistent-formid]') |
||||||
|
const store = this.getPersistentStore() |
||||||
|
fields.forEach((field) => { |
||||||
|
const key = field.getAttribute('data-persistent-formid') |
||||||
|
const cached = store[key] |
||||||
|
if (cached !== undefined) { |
||||||
|
field.value = cached |
||||||
|
} |
||||||
|
|
||||||
|
field.addEventListener(eventName, this.persistentFieldDidUpdate.bind(this)) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
PersistentForm.prototype.getPersistentStore = function () { |
||||||
|
let store = window.localStorage[this.persistentFormParentId || defaultKey] |
||||||
|
if (store && store !== 'null') { |
||||||
|
store = JSON.parse(store) |
||||||
|
} else { |
||||||
|
store = {} |
||||||
|
} |
||||||
|
return store |
||||||
|
} |
||||||
|
|
||||||
|
PersistentForm.prototype.setPersistentStore = function (newStore) { |
||||||
|
window.localStorage[this.persistentFormParentId || defaultKey] = JSON.stringify(newStore) |
||||||
|
} |
||||||
|
|
||||||
|
PersistentForm.prototype.persistentFieldDidUpdate = function (event) { |
||||||
|
const field = event.target |
||||||
|
const store = this.getPersistentStore() |
||||||
|
const key = field.getAttribute('data-persistent-formid') |
||||||
|
const val = field.value |
||||||
|
store[key] = val |
||||||
|
this.setPersistentStore(store) |
||||||
|
} |
||||||
|
|
||||||
|
PersistentForm.prototype.componentWillUnmount = function () { |
||||||
|
const fields = document.querySelectorAll('[data-persistent-formid]') |
||||||
|
fields.forEach((field) => { |
||||||
|
field.removeEventListener(eventName, this.persistentFieldDidUpdate.bind(this)) |
||||||
|
}) |
||||||
|
this.setPersistentStore({}) |
||||||
|
} |
Loading…
Reference in new issue