Skip to content
This repository has been archived by the owner on Oct 26, 2021. It is now read-only.

Supporting default transaction (non ETH and non token transfer) #439

Open
wants to merge 14 commits into
base: develop
Choose a base branch
from
Open
18 changes: 9 additions & 9 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ PODS:
- GoogleToolboxForMac/Logger (~> 2.1)
- Protobuf (~> 3.1)
- FLAnimatedImage (1.0.12)
- GoogleToolboxForMac/Defines (2.1.4)
- GoogleToolboxForMac/Logger (2.1.4):
- GoogleToolboxForMac/Defines (= 2.1.4)
- "GoogleToolboxForMac/NSData+zlib (2.1.4)":
- GoogleToolboxForMac/Defines (= 2.1.4)
- GoogleToolboxForMac/Defines (2.2.0)
- GoogleToolboxForMac/Logger (2.2.0):
- GoogleToolboxForMac/Defines (= 2.2.0)
- "GoogleToolboxForMac/NSData+zlib (2.2.0)":
- GoogleToolboxForMac/Defines (= 2.2.0)
- nanopb (0.3.901):
- nanopb/decode (= 0.3.901)
- nanopb/encode (= 0.3.901)
Expand Down Expand Up @@ -62,8 +62,8 @@ PODS:
- React
- RNScreens (1.0.0-alpha.22):
- React
- SDWebImage/Core (4.4.2)
- SDWebImage/GIF (4.4.2):
- SDWebImage/Core (4.4.3)
- SDWebImage/GIF (4.4.3):
- FLAnimatedImage (~> 1.0)
- SDWebImage/Core
- yoga (0.57.1.React)
Expand Down Expand Up @@ -127,7 +127,7 @@ SPEC CHECKSUMS:
FirebaseInstanceID: 4f7768a98c5c3c5bd9a4c9e431ea98dccc0a51f9
FirebaseMessaging: 94579ae655d817287f029ebfebd5b0811fbb3a51
FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31
GoogleToolboxForMac: 91c824d21e85b31c2aae9bb011c5027c9b4e738f
GoogleToolboxForMac: ff31605b7d66400dcec09bed5861689aebadda4d
nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48
Protobuf: 6b0fc34ab8f2b7dbad2278a48be08a669427c59f
React: 1fe0eb13d90b625d94c3b117c274dcfd2e760e11
Expand All @@ -138,7 +138,7 @@ SPEC CHECKSUMS:
RNLanguages: e3ae05ef105937645218272429dac0c3f7633451
RNReanimated: 45d9313b7a62318ed00d60a811937321e43e076e
RNScreens: 354046589421edc3d83d5c6212475bf1fb9a731d
SDWebImage: 4170dae6332a915d44c918675d51dc1c4c06b45f
SDWebImage: c5594f1a19c48d526d321e548902b56b479cd508
yoga: b1ce48b6cf950b98deae82838f5173ea7cf89e85

PODFILE CHECKSUM: 0b876ddc904bb401eb7df12eea5f563d95631161
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"@tradle/react-native-http": "^2.0.0",
"assert": "^1.4.1",
"axios": "^0.18.0",
"balance-common": "^0.6.33",
"balance-common": "^0.6.35",
"bignumber.js": "^8.0.2",
"browserify-zlib": "^0.1.4",
"buffer": "^4.9.1",
Expand Down Expand Up @@ -67,7 +67,7 @@
"react-native-level-fs": "^3.0.1",
"react-native-linear-gradient": "^2.4.2",
"react-native-mail": "^3.0.6",
"react-native-matomo": "git+https://github.com/BonifyByForteil/react-native-matomo.git",
"react-native-matomo": "git+https://github.com/BonifyByForteil/react-native-matomo.git#32907c88a586f8dcc69a69a0303561753064cb50",
"react-native-os": "^1.2.1",
"react-native-permissions": "^1.1.1",
"react-native-qrcode-scanner": "mikedemarais/react-native-qrcode-scanner#2ca70b8c64afb87e712aba578e11409c6406069e",
Expand Down Expand Up @@ -197,4 +197,4 @@
"./src/assets/fonts"
]
}
}
}
98 changes: 98 additions & 0 deletions src/components/DefaultTransactionConfirmationSection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import PropTypes from 'prop-types';
import React from 'react';
import { ScrollView } from 'react-native';
import lang from 'i18n-js';
import styled from 'styled-components';
import Divider from './Divider';
import { withSafeAreaViewInsetValues } from '../hoc';
import { borders, colors, padding } from '../styles';
import { Column } from './layout';
import {
Monospace,
Smallcaps,
Text,
TruncatedAddress,
} from './text';

const Message = styled(Text).attrs({ size: 'lmedium' })`
color: ${colors.alpha(colors.blueGreyDark, 0.6)}
margin-top: 5;
`;

const AddressRow = styled(Column)`
${padding(19, 19, 18)}
flex-shrink: 0;
`;

const Amount = styled(Monospace).attrs({ size: 'smedium' })`
color: ${colors.alpha(colors.blueGreyDark, 0.6)}
text-transform: uppercase;
`;

const Address = styled(TruncatedAddress).attrs({ size: 'lmedium' })`
color: ${colors.alpha(colors.blueGreyDark, 0.6)}
margin-top: 5;
`;

const MessageRow = styled(Column)`
${padding(15, 19, 15)}
flex-shrink: 0;
`;

const BottomSheet = styled(Column).attrs({ justify: 'space-between' })`
${borders.buildRadius('top', 15)}
background-color: ${colors.white};
flex: 0;
min-height: ${({ bottomInset }) => (bottomInset + 360)};
padding-bottom: ${({ bottomInset }) => bottomInset};
width: 100%;
`;

const SendButtonContainer = styled.View`
${padding(7, 15, 14)}
flex-shrink: 0;
`;

const DefaultTransactionConfirmationSection = ({
asset: {
address,
data,
value,
},
safeAreaInset,
sendButton,
}) => (
<BottomSheet bottomInset={safeAreaInset.bottom}>
<AddressRow>
<Smallcaps>{lang.t('wallet.action.to')}</Smallcaps>
<Address address={address} truncationLength={15}/>
</AddressRow>
<Divider />
<AddressRow>
<Smallcaps>{lang.t('wallet.action.value')}</Smallcaps>
<Amount>{value}</Amount>
</AddressRow>
<Divider />
<MessageRow>
<Smallcaps>{lang.t('wallet.action.input')}</Smallcaps>
<ScrollView>
<Message>{data}</Message>
</ScrollView>
</MessageRow>
<SendButtonContainer>
{sendButton}
</SendButtonContainer>
</BottomSheet>
);

DefaultTransactionConfirmationSection.propTypes = {
asset: PropTypes.shape({
address: PropTypes.string,
data: PropTypes.string,
value: PropTypes.string,
}),
safeAreaInset: PropTypes.object,
sendButton: PropTypes.object,
};

export default withSafeAreaViewInsetValues(DefaultTransactionConfirmationSection);
13 changes: 12 additions & 1 deletion src/components/activity-list/RecyclerActivityList.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import { RecyclerListView, DataProvider, LayoutProvider } from 'recyclerlistview
import StickyContainer from 'recyclerlistview/dist/reactnative/core/StickyContainer';
import styled from 'styled-components/primitives/dist/styled-components-primitives.esm';
import PropTypes from 'prop-types';
import { RequestCoinRow, TransactionCoinRow } from '../coin-row';
import {
ContractInteractionCoinRow,
RequestCoinRow,
TransactionCoinRow,
} from '../coin-row';
import ActivityListHeader from './ActivityListHeader';
import ListFooter from '../list/ListFooter';

Expand Down Expand Up @@ -115,6 +119,13 @@ export default class RecyclerActivityList extends React.Component {
/>
);
}
if (!data.symbol && data.dappName) {
return (
<ContractInteractionCoinRow
item={data}
/>
);
}
return (
<TransactionCoinRow
item={data}
Expand Down
95 changes: 95 additions & 0 deletions src/components/coin-row/ContractInteractionCoinRow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { get } from 'lodash';
import PropTypes from 'prop-types';
import React, { Fragment } from 'react';
import {
compose,
mapProps,
onlyUpdateForKeys,
withHandlers,
} from 'recompact';
import { Linking } from 'react-native';
import TransactionStatusTypes from '../../helpers/transactionStatusTypes';
import { colors } from '../../styles';
import { showActionSheetWithOptions } from '../../utils/actionsheet';
import { ButtonPressAnimation } from '../animations';
import { FlexItem, Row } from '../layout';
import BalanceText from './BalanceText';
import BottomRowText from './BottomRowText';
import CoinName from './CoinName';
import CoinRow from './CoinRow';
import TransactionStatusBadge from './TransactionStatusBadge';
import { RequestVendorLogoIcon } from '../coin-icon';

const rowRenderPropTypes = {
item: PropTypes.object,
dappName: PropTypes.string,
onPressTransaction: PropTypes.func,
status: PropTypes.oneOf(Object.values(TransactionStatusTypes)),
};

const BottomRow = ({ dappName }) => {
return (
<Row align="center" justify="space-between">
<FlexItem flex={1}>
<CoinName>{dappName}</CoinName>
</FlexItem>
</Row>
);
};

BottomRow.propTypes = rowRenderPropTypes;

const TopRow = ({ status }) => (
<Fragment>
<TransactionStatusBadge status={status} />
</Fragment>
);

TopRow.propTypes = rowRenderPropTypes;

const ContractInteractionCoinRow = ({ item, onPressTransaction, ...props }) => (
<ButtonPressAnimation onPress={onPressTransaction} scaleTo={0.96}>
<CoinRow
{...item}
{...props}
coinIconRender={RequestVendorLogoIcon}
bottomRowRender={BottomRow}
shouldRasterizeIOS={true}
topRowRender={TopRow}
/>
</ButtonPressAnimation>
);

ContractInteractionCoinRow.propTypes = rowRenderPropTypes;

export default compose(
mapProps(({
item: {
hash,
pending,
...item
},
...props
}) => ({
hash,
item,
pending,
...props,
})),
withHandlers({
onPressTransaction: ({ hash }) => () => {
if (hash) {
showActionSheetWithOptions({
cancelButtonIndex: 1,
options: ['View on Etherscan', 'Cancel'],
}, (buttonIndex) => {
if (buttonIndex === 0) {
const normalizedHash = hash.replace(/-.*/g, '');
Linking.openURL(`https://etherscan.io/tx/${normalizedHash}`);
}
});
}
},
}),
onlyUpdateForKeys(['hash', 'pending']),
)(ContractInteractionCoinRow);
4 changes: 2 additions & 2 deletions src/components/coin-row/TransactionCoinRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const BottomRow = ({ name, native, status }) => {
<FlexItem flex={0}>
<BalanceText color={balanceTextColor}>
{(nativeDisplay && isStatusSent) ? '- ' : ''}
{nativeDisplay || `${native.symbol}0.00`}
{nativeDisplay || ''}
</BalanceText>
</FlexItem>
</Row>
Expand All @@ -57,7 +57,7 @@ BottomRow.propTypes = rowRenderPropTypes;
const TopRow = ({ balance, status }) => (
<Fragment>
<TransactionStatusBadge status={status} />
<BottomRowText>{get(balance, 'display')}</BottomRowText>
<BottomRowText>{get(balance, 'display', '')}</BottomRowText>
</Fragment>
);

Expand Down
3 changes: 2 additions & 1 deletion src/components/coin-row/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export { default as BalanceCoinRow } from './BalanceCoinRow';
export { default as BottomRowText } from './BottomRowText';
export { default as CoinRow } from './CoinRow';
export { default as ContractInteractionCoinRow } from './ContractInteractionCoinRow';
export { default as RequestCoinRow } from './RequestCoinRow';
export { default as TransactionCoinRow } from './TransactionCoinRow';
export { default as SendCoinRow } from './SendCoinRow';
export { default as TransactionCoinRow } from './TransactionCoinRow';
4 changes: 2 additions & 2 deletions src/helpers/transactions.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ const normalizeTransactions = ({ accountAddress, nativeCurrency, transactions })
}) => ({
...tx,
balance: value,
name: get(asset, 'name'),
name: get(asset, 'name', ''),
native: {
...supportedNativeCurrencies[nativeCurrency],
balance: get(native, `${nativeCurrency}.value`),
},
status: getTransactionStatus({ accountAddress, ...tx }),
symbol: get(asset, 'symbol'),
symbol: get(asset, 'symbol', ''),
}))
);

Expand Down
16 changes: 16 additions & 0 deletions src/redux/transactionsToApprove.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,22 @@ const getTransactionDisplayDetails = (transaction, assets, prices, nativeCurrenc
type: 'transaction',
};
}
if (transaction.data) {
const value = fromWei(convertHexToString(transaction.value));
return {
payload: {
data: transaction.data,
from: transaction.from,
gasLimit: BigNumber(convertHexToString(transaction.gasLimit)),
gasPrice: BigNumber(convertHexToString(transaction.gasPrice)),
nonce: Number(convertHexToString(transaction.nonce)),
to: transaction.to,
value,
},
timestampInMs,
type: 'default',
};
}

return null;
};
Expand Down
12 changes: 11 additions & 1 deletion src/screens/TransactionConfirmationScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import BalanceManagerLogo from '../assets/balance-manager-logo.png';
import { BlockButton, Button, LongPressButton } from '../components/buttons';
import { Centered, Column } from '../components/layout';
import TransactionConfirmationSection from '../components/TransactionConfirmationSection';
import DefaultTransactionConfirmationSection from '../components/DefaultTransactionConfirmationSection';
import MessageSigningSection from '../components/MessageSigningSection';
import { Text } from '../components/text';
import {
Expand Down Expand Up @@ -176,7 +177,7 @@ class TransactionConfirmationScreen extends Component {
message={request}
sendButton={this.renderSendButton()}
/>
) : (
) : (requestType === 'transaction') ? (
<TransactionConfirmationSection
asset={{
address: get(request, 'to'),
Expand All @@ -187,6 +188,15 @@ class TransactionConfirmationScreen extends Component {
}}
sendButton={this.renderSendButton()}
/>
) : (
<DefaultTransactionConfirmationSection
asset={{
address: get(request, 'to'),
value: get(request, 'value', '0'),
data: get(request, 'data', ''),
}}
sendButton={this.renderSendButton()}
/>
)
}
</Container>
Expand Down
Loading