Skip to content

Commit

Permalink
Integrate GABA (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
bitpshr authored Aug 2, 2018
1 parent 56edeb6 commit 486b54c
Show file tree
Hide file tree
Showing 12 changed files with 3,992 additions and 1,903 deletions.
15 changes: 11 additions & 4 deletions app/components/App/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import React from 'react';
import { StyleSheet } from 'react-native';
import { createBottomTabNavigator } from 'react-navigation';
import { createIconSetFromFontello } from 'react-native-vector-icons';
import BrowserScreen from '../BrowserScreen';
import Engine from '../../core/Engine';
import WalletScreen from '../WalletScreen';
import { createIconSetFromFontello } from 'react-native-vector-icons';
import fontelloConfig from '../../fonts/config.json';
import { colors } from '../../styles/common';

const Icon = createIconSetFromFontello(fontelloConfig);

import { colors } from '../../styles/common';
const engine = new Engine();

/**
* Root application component responsible for configuring the tab navigator
* Root application component responsible for configuring app navigation
* and instantiating the core Engine module
*/
export default createBottomTabNavigator(
{
Expand All @@ -21,7 +26,9 @@ export default createBottomTabNavigator(
})
},
Wallet: {
screen: WalletScreen,
screen: function Home() {
return <WalletScreen engine={engine} />;
},
navigationOptions: () => ({
title: 'Wallet',
tabBarIcon: ico => <Icon name="wallet" size={20} color={ico.tintColor} /> // eslint-disable-line react/display-name
Expand Down
4 changes: 2 additions & 2 deletions app/components/Screen/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ exports[`Screen should render correctly 1`] = `
<Component
style={
Object {
"backgroundColor": "#2f3542",
"backgroundColor": "#f1f2f6",
"height": 1334,
"left": 0,
"position": "absolute",
Expand All @@ -23,7 +23,7 @@ exports[`Screen should render correctly 1`] = `
<StatusBar
animated={false}
backgroundColor="#2f3542"
barStyle="light-content"
barStyle="dark-content"
showHideTransition="fade"
/>
</Component>
Expand Down
35 changes: 35 additions & 0 deletions app/components/Wallet/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,40 @@ exports[`Wallet should render correctly 1`] = `
<Component>
Wallet
</Component>
<Component>
ETH: $
0
</Component>
<Component>
NETWORK CODE:
</Component>
<Component>
NETWORK NAME:
foo
</Component>
<Component>
STATUS:
ok
</Component>
<Component>
BLOCK:
1
</Component>
<Component>
GAS PRICE:
1000000000
</Component>
<Button
onPress={[Function]}
title="MAINNET"
/>
<Button
onPress={[Function]}
title="RINKEBY"
/>
<Button
onPress={[Function]}
title="ROPSTEN"
/>
</Component>
`;
54 changes: 53 additions & 1 deletion app/components/Wallet/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import PropTypes from 'prop-types';
import { Button, StyleSheet, Text, View } from 'react-native';
import { colors } from '../../styles/common';
import { util } from 'gaba';

const styles = StyleSheet.create({
wrapper: {
Expand All @@ -15,10 +17,60 @@ const styles = StyleSheet.create({
* Wallet component
*/
export default class Wallet extends Component {
static propTypes = {
/**
* Instance of a core engine object
*/
engine: PropTypes.object.isRequired
};

componentDidMount() {
// This is a brute-force way to refresh the wallet anytime the
// datamodel changes for demonstration purposes. We should probably
// link the datamodel to redux and go that route instead.
this.props.engine.datamodel.subscribe(() => {
this.forceUpdate();
});
}

changeNetwork(type) {
this.props.engine.api.network.setProviderType(type);
}

render() {
const {
engine: {
datamodel: { state }
}
} = this.props;

return (
<View style={styles.wrapper}>
<Text>Wallet</Text>
<Text>ETH: ${state.currencyRate.conversionRate}</Text>
<Text>NETWORK CODE: {state.network.network}</Text>
<Text>NETWORK NAME: {state.network.provider.type}</Text>
<Text>STATUS: {state.networkStatus.networkStatus.infura[state.network.provider.type]}</Text>
<Text>BLOCK: {parseInt(state.blockHistory.recentBlocks[0].number, 16)}</Text>
<Text>GAS PRICE: {parseInt(util.getGasPrice(state.blockHistory.recentBlocks), 16)}</Text>
<Button
title="MAINNET"
onPress={() => {
this.changeNetwork('mainnet');
}}
/>
<Button
title="RINKEBY"
onPress={() => {
this.changeNetwork('rinkeby');
}}
/>
<Button
title="ROPSTEN"
onPress={() => {
this.changeNetwork('ropsten');
}}
/>
</View>
);
}
Expand Down
16 changes: 15 additions & 1 deletion app/components/Wallet/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,23 @@ import React from 'react';
import { shallow } from 'enzyme';
import Wallet from './';

const MOCK_ENGINE = {
datamodel: {
state: {
blockHistory: { recentBlocks: [{ number: 1 }] },
currencyRate: { conversionRate: 0 },
network: { provider: { type: 'foo' } },
networkStatus: { networkStatus: { infura: { foo: 'ok' } } }
},
subscribe: () => {
/* eslint-disable-line no-empty-function */
}
}
};

describe('Wallet', () => {
it('should render correctly', () => {
const wrapper = shallow(<Wallet />);
const wrapper = shallow(<Wallet engine={MOCK_ENGINE} />);
expect(wrapper).toMatchSnapshot();
});
});
4 changes: 3 additions & 1 deletion app/components/WalletScreen/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

exports[`WalletScreen should render correctly 1`] = `
<Screen>
<Wallet />
<Wallet
engine={Object {}}
/>
</Screen>
`;
10 changes: 9 additions & 1 deletion app/components/WalletScreen/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Wallet from '../Wallet';
import Screen from '../Screen';

/**
* Main view component for the wallet screen
*/
export default class WalletScreen extends Component {
static propTypes = {
/**
* Instance of a core engine object
*/
engine: PropTypes.object.isRequired
};

render() {
return (
<Screen>
<Wallet />
<Wallet engine={this.props.engine} />
</Screen>
);
}
Expand Down
2 changes: 1 addition & 1 deletion app/components/WalletScreen/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import WalletScreen from './';

describe('WalletScreen', () => {
it('should render correctly', () => {
const wrapper = shallow(<WalletScreen />);
const wrapper = shallow(<WalletScreen engine={{}} />);
expect(wrapper).toMatchSnapshot();
});
});
73 changes: 73 additions & 0 deletions app/core/Engine.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {
AccountTrackerController,
AddressBookController,
BlockHistoryController,
ComposableController,
CurrencyRateController,
KeyringController,
NetworkController,
NetworkStatusController,
PhishingController,
PreferencesController,
ShapeShiftController,
TokenRatesController
} from 'gaba';

import BlockTracker from 'eth-block-tracker';

/**
* Core controller responsible for composing other GABA controllers together
* and exposing convenience methods for common wallet operations.
*/
export class Engine {
/**
* Child controller instances keyed by controller name
*/
api = {
accountTracker: new AccountTrackerController(),
addressBook: new AddressBookController(),
blockHistory: new BlockHistoryController(),
currencyRate: new CurrencyRateController(),
keyring: new KeyringController(),
network: new NetworkController(undefined, {
providerConfig: {}
}),
networkStatus: new NetworkStatusController(),
phishing: new PhishingController(),
preferences: new PreferencesController(),
shapeShift: new ShapeShiftController(),
tokenRates: new TokenRatesController()
};

/**
* ComposableController reference containing all child controllers
*/
datamodel;

/**
* Creates a CoreController instance
*/
constructor() {
this.datamodel = new ComposableController(this.api);
this.api.network.subscribe(this.refreshNetwork);
this.refreshNetwork();
}

/**
* Refreshes all controllers that depend on the network
*/
refreshNetwork = () => {
const {
accountTracker,
blockHistory,
network: { provider }
} = this.api;
provider.sendAsync = provider.sendAsync.bind(provider);
const blockTracker = new BlockTracker({ provider });
blockHistory.configure({ provider, blockTracker });
accountTracker.configure({ provider, blockTracker });
blockTracker.start();
};
}

export default Engine;
Loading

0 comments on commit 486b54c

Please sign in to comment.