Commit d18de4af authored by Marek Kotewicz's avatar Marek Kotewicz
Browse files

AccountAddress component (fixes #29) and new qr code transaction format (fixes #20)

parent 3728f679
......@@ -2,10 +2,10 @@
import { NEW_SCANNED_TX, SIGNED_TX } from '../constants/TransactionActions'
export function scannedTx (rlp, transaction) {
export function scannedTx (rlpHash, transaction) {
return {
type: NEW_SCANNED_TX,
rlp,
rlpHash,
transaction
}
}
......
'use strict'
import React, { Component, PropTypes } from 'react'
import { Text } from 'react-native'
import AppStyles from '../styles'
export default class AccountAddress extends Component {
static propTypes = {
address: PropTypes.string.isRequired
}
state = {
address: this.props.address
}
componentWillReceiveProps (newProps) {
if (newProps.address !== this.props.address) {
this.setState({
address: newProps.address
})
}
}
render () {
return (
<Text selectable style={AppStyles.valueText}>0x{this.state.address}</Text>
)
}
}
......@@ -4,6 +4,7 @@ import React, { Component, PropTypes } from 'react'
import { StyleSheet, View, ScrollView, Text, Button } from 'react-native'
import AppStyles from '../styles'
import AccountIcon from './AccountIcon'
import AccountAddress from './AccountAddress'
export default class AccountDetails extends Component {
static propTypes = {
......@@ -19,9 +20,9 @@ export default class AccountDetails extends Component {
<ScrollView style={AppStyles.view}>
<AccountIcon style={AppStyles.icon} seed={'0x' + this.props.account.address} />
<Text style={AppStyles.hintText}>Name</Text>
<Text selectable style={AppStyles.valueText}>{this.props.account.name ? this.props.account.name : 'no name'}</Text>
<Text style={AppStyles.valueText}>{this.props.account.name ? this.props.account.name : 'no name'}</Text>
<Text style={AppStyles.hintText}>Address</Text>
<Text selectable style={AppStyles.valueText}>0x{this.props.account.address}</Text>
<AccountAddress address={this.props.account.address} />
<View style={AppStyles.buttonContainer}>
<Button
style={styles.button}
......
......@@ -9,18 +9,15 @@ export default class AccountPin extends Component {
onNextPressed: PropTypes.func.isRequired
}
constructor (props) {
super(props)
this.state = {
text: ''
}
state = {
text: ''
}
onNext = () => {
const {text} = this.state
const {account, extra} = this.props
const {account} = this.props
this.props.onNextPressed(text, account, extra)
this.props.onNextPressed(text, account)
}
onChange = (text) => {
......
......@@ -4,6 +4,7 @@ import React, { Component, PropTypes } from 'react'
import { ScrollView, View, Text, Button } from 'react-native'
import AppStyles from '../styles'
import AccountIcon from './AccountIcon'
import AccountAddress from './AccountAddress'
export default class Send extends Component {
static propTypes = {
......@@ -24,9 +25,9 @@ export default class Send extends Component {
<ScrollView style={AppStyles.view}>
<AccountIcon style={AppStyles.icon} seed={'0x' + this.props.txSenderAddress} />
<Text style={AppStyles.hintText}>sender address</Text>
<Text style={AppStyles.valueText}>{this.props.txSenderAddress}</Text>
<AccountAddress address={this.props.txSenderAddress} />
<Text style={AppStyles.hintText}>recipient address</Text>
<Text style={AppStyles.valueText}>{this.props.txRecipientAddress}</Text>
<AccountAddress address={this.props.txRecipientAddress} />
<Text style={AppStyles.hintText}>amount to transfer (in ETH)</Text>
<Text style={AppStyles.valueText}>{this.props.txValue}</Text>
<Text style={AppStyles.hintText}>nonce</Text>
......
......@@ -6,17 +6,17 @@ import { Actions } from 'react-native-router-flux'
import AccountPin from '../components/AccountPin'
import { addAccount, setPin } from '../actions/accounts'
import { signedTx } from '../actions/transactions'
import { keccak, brainWalletSign } from '../util/native'
import { brainWalletSign } from '../util/native'
import { saveAccount } from '../util/db'
import store from '../util/store'
const mapStateToPropsEnterPin = (state, ownProps) => ({
account: state.accounts.selected,
extra: state.transactions.pendingTransaction.rlp
account: state.accounts.selected
})
async function signTransaction (dispatch, account, rlp) {
async function signTransaction (dispatch, account) {
try {
let hash = await keccak(rlp)
let hash = store.getState().transactions.pendingTransaction.rlpHash
let signature = await brainWalletSign(account.seed, hash)
dispatch(signedTx(signature))
Actions.qrViewTx()
......@@ -26,9 +26,9 @@ async function signTransaction (dispatch, account, rlp) {
}
const mapDispatchToPropsEnterPin = (dispatch, ownProps) => ({
onNextPressed: (pin, account, rlp) => {
onNextPressed: (pin, account) => {
if (pin === account.pin) {
signTransaction(dispatch, account, rlp)
signTransaction(dispatch, account)
} else {
Alert.alert('Invalid PIN')
}
......
......@@ -7,10 +7,23 @@ import QrScanner from '../components/QrScanner'
import { selectAccount } from '../actions/accounts'
import { scannedTx } from '../actions/transactions'
import transaction from '../util/transaction'
import keccak from '../util/native'
import store from '../util/store'
var scanning = false
function displayAlert (text) {
Alert.alert(text, undefined, [
{ text: 'OK', onPress: () => { scanning = false } }
])
}
function findAccountWithAddress (address) {
return store.getState().accounts.all.find(account => {
return account.address.toLowerCase() === address
})
}
async function onScannedTransaction (data, dispatch) {
try {
if (scanning) {
......@@ -18,27 +31,41 @@ async function onScannedTransaction (data, dispatch) {
}
scanning = true
let txRequest = JSON.parse(data)
let from = txRequest.from.toLowerCase()
let account = store.getState().accounts.all.find(account => {
return account.address.toLowerCase() === from
})
if (!account) {
Alert.alert('Invalid sender address ' + txRequest.from, undefined, [
{ text: 'OK', onPress: () => { scanning = false } }
])
return
switch (txRequest.action) {
case 'signTransaction': {
let account = findAccountWithAddress(txRequest.data.account)
if (!account) {
displayAlert('Invalid sender address ' + txRequest.data.account)
return
}
let tx = await transaction(txRequest.data.rlp)
let hash = await keccak(txRequest.data.rlp)
dispatch(selectAccount(account))
dispatch(scannedTx(hash, tx))
break
}
case 'signTransactionHash': {
let account = findAccountWithAddress(txRequest.data.account)
if (!account) {
displayAlert('Invalid sender address ' + txRequest.data.account)
return
}
let details = txRequest.data.details
let hash = txRequest.data.hash
dispatch(selectAccount(account))
dispatch(scannedTx(hash, details))
break
}
default: {
displayAlert('Invalid request')
return
}
}
let tx = await transaction(txRequest.rlp)
dispatch(selectAccount(account))
dispatch(scannedTx(txRequest.rlp, tx))
// Vibration.vibrate()
Actions.txDetails()
scanning = false
} catch (e) {
console.log(e)
Alert.alert('Invalid transaction', undefined, [
{ text: 'OK', onPress: () => { scanning = false } }
])
displayAlert('Invalid transaction')
}
}
......
......@@ -5,7 +5,7 @@ import { NEW_SCANNED_TX, SIGNED_TX } from '../constants/TransactionActions'
const initialState = {
pendingTransaction: {
transaction: {},
rlp: ''
rlpHash: ''
},
signedTransaction: {
signature: ''
......@@ -17,7 +17,7 @@ export default function transactions (state = initialState, action) {
case NEW_SCANNED_TX:
return Object.assign({}, state, {
pendingTransaction: {
rlp: action.rlp,
rlpHash: action.rlpHash,
transaction: action.transaction
}
})
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment