Skip to content

Commit d9adbbb

Browse files
authored
Merge pull request #4 from ava-labs/development
v0.1.1-rc
2 parents d1f9ee8 + b728a95 commit d9adbbb

24 files changed

+1263
-104
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,4 @@ buck-out/
5858
# CocoaPods
5959
/ios/Pods/
6060
package-lock.json
61+
.markdownlint.json

App.js

Lines changed: 92 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,17 @@
88
import React, {Component} from 'react';
99
import {
1010
Appearance,
11+
Button,
1112
SafeAreaView,
12-
ScrollView,
13+
SectionList,
1314
StatusBar,
14-
View,
15+
StyleSheet,
16+
Text,
1517
} from 'react-native';
16-
17-
import {Colors} from 'react-native/Libraries/NewAppScreen';
18-
import Section from './src/mainView/Section';
1918
import Header from './src/mainView/Header';
2019
import AppViewModel from './src/AppViewModel';
20+
import Clock from './src/mainView/Clock';
21+
import {Colors} from 'react-native/Libraries/NewAppScreen';
2122

2223
class App extends Component {
2324
viewModel: AppViewModel = new AppViewModel(Appearance.getColorScheme());
@@ -31,6 +32,10 @@ class App extends Component {
3132
walletCAddress: '',
3233
walletEvmAddress: '',
3334
isDarkMode: false,
35+
externalAddressesX: [],
36+
externalAddressesP: [],
37+
addressC: '',
38+
availableX: '',
3439
};
3540
}
3641

@@ -44,9 +49,7 @@ class App extends Component {
4449
this.viewModel.avaxPrice.subscribe(value => {
4550
this.setState({avaxPrice: value});
4651
});
47-
this.viewModel.mnemonic.subscribe(value => {
48-
this.setState({mnemonic: value});
49-
});
52+
this.setState({mnemonic: this.viewModel.mnemonic});
5053
this.viewModel.walletCAddress.subscribe(value => {
5154
this.setState({walletCAddress: value});
5255
});
@@ -59,36 +62,97 @@ class App extends Component {
5962
this.viewModel.backgroundStyle.subscribe(value => {
6063
this.setState({backgroundStyle: value});
6164
});
65+
this.viewModel.externalAddressesX.subscribe(value => {
66+
this.setState({externalAddressesX: value});
67+
});
68+
this.viewModel.externalAddressesP.subscribe(value => {
69+
this.setState({externalAddressesP: value});
70+
});
71+
this.viewModel.addressC.subscribe(value => {
72+
this.setState({addressC: value});
73+
});
74+
this.viewModel.availableX.subscribe(value => {
75+
this.setState({availableX: value});
76+
});
6277
}
63-
6478
render() {
6579
console.log('render');
80+
81+
const sectionListData = [
82+
{
83+
title: 'Avax Price',
84+
data: ['$' + this.state.avaxPrice],
85+
},
86+
{
87+
title: 'Mnemonic',
88+
data: [this.state.mnemonic],
89+
},
90+
{
91+
title: 'External addresses X',
92+
data: [this.state.externalAddressesX],
93+
},
94+
{
95+
title: 'External addresses P',
96+
data: [this.state.externalAddressesP],
97+
},
98+
{
99+
title: 'External addresses C',
100+
data: [this.state.addressC],
101+
},
102+
{
103+
title: 'Available (X)',
104+
data: [this.state.availableX],
105+
},
106+
];
66107
return (
67108
<SafeAreaView style={this.state.backgroundStyle}>
68109
<StatusBar
69110
barStyle={this.state.isDarkMode ? 'light-content' : 'dark-content'}
70111
/>
71-
<ScrollView
72-
contentInsetAdjustmentBehavior="always"
73-
style={this.state.backgroundStyle}>
74-
<Header />
75-
<View
76-
style={{
77-
backgroundColor: this.state.isDarkMode
78-
? Colors.black
79-
: Colors.white,
80-
}}>
81-
<Section title="Avax price">${this.state.avaxPrice}</Section>
82-
<Section title="Mnemonic">{this.state.mnemonic}</Section>
83-
<Section title="C addr">{this.state.walletCAddress}</Section>
84-
<Section title="Evm addr bech">
85-
{this.state.walletEvmAddress}
86-
</Section>
87-
</View>
88-
</ScrollView>
112+
<Clock />
113+
<Header />
114+
<SectionList
115+
sections={sectionListData}
116+
renderItem={({item}) => (
117+
<Text
118+
style={[
119+
styles.item,
120+
{color: this.state.isDarkMode ? Colors.light : Colors.dark},
121+
]}>
122+
{item}
123+
</Text>
124+
)}
125+
renderSectionHeader={({section}) => (
126+
<Text style={styles.sectionHeader}>{section.title}</Text>
127+
)}
128+
keyExtractor={(item, index) => index}
129+
/>
130+
<Button
131+
title={'Reset Hd indices'}
132+
onPress={() => this.viewModel.onResetHdIndices()}
133+
/>
89134
</SafeAreaView>
90135
);
91136
}
92137
}
93-
138+
const styles = StyleSheet.create({
139+
container: {
140+
flex: 1,
141+
paddingTop: 22,
142+
},
143+
sectionHeader: {
144+
paddingTop: 2,
145+
paddingLeft: 10,
146+
paddingRight: 10,
147+
paddingBottom: 2,
148+
fontSize: 14,
149+
fontWeight: 'bold',
150+
backgroundColor: 'rgba(247,247,247,1.0)',
151+
},
152+
item: {
153+
padding: 10,
154+
fontSize: 18,
155+
height: 44,
156+
},
157+
});
94158
export default App;

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,33 @@ Next, install the dependencies.
1515
yarn install
1616
```
1717

18+
## Setup dev environment
19+
20+
Follow [these](https://reactnative.dev/docs/environment-setup) steps to setup dev environment; make sure to select
21+
**React Native CLI Quickstart** tab and select appropriate Development & Target OS.
22+
1823
## Launch iOS App
1924

20-
First open XCode and then run
25+
First install iOS dependencies.
2126

2227
```zsh
28+
# install cocoapods
29+
sudo gem install cocoapods
30+
```
31+
32+
Now you can run the app
33+
34+
```zsh
35+
# launch iOS simulator and start the app
2336
yarn ios
2437
```
2538

2639
## Launch Android App
2740

41+
Follow the steps in the React Native docs for [configuring your Android dev environment](https://reactnative.dev/docs/environment-setup).
42+
2843
```zsh
44+
# launch android emulator and start the app
2945
yarn android
3046
```
3147

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"private": true,
55
"scripts": {
66
"android": "react-native run-android",
7-
"ios": "react-native run-ios",
7+
"ios": "cd $INIT_CWD/ios && pod install && cd $INIT_CWD && react-native run-ios",
88
"start": "react-native start",
99
"test": "jest",
1010
"lint": "eslint ."
@@ -18,6 +18,7 @@
1818
"bip39": "^3.0.4",
1919
"ethereumjs-util": "^6.2.1",
2020
"hdkey": "^2.0.1",
21+
"moment": "^2.29.1",
2122
"node-libs-react-native": "^1.2.1",
2223
"react": "17.0.1",
2324
"react-native": "0.64.1",
@@ -43,4 +44,4 @@
4344
"node": ">=14.17.0",
4445
"yarn": ">=1.22.10"
4546
}
46-
}
47+
}

src/AppViewModel.ts

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
import {MnemonicWallet, NetworkConstants} from '../wallet_sdk';
22
import WalletSDK from './WalletSDK';
33
import {Colors} from 'react-native/Libraries/NewAppScreen';
4-
import {BehaviorSubject, Observable} from 'rxjs';
5-
import {map} from 'rxjs/operators';
4+
import {asyncScheduler, BehaviorSubject, Observable} from 'rxjs';
5+
import {concatMap, filter, map, subscribeOn, take} from 'rxjs/operators';
6+
import {StatusBar} from 'react-native';
67

78
export default class {
89
constructor(colorScheme: string) {
910
this.isDarkMode.next(colorScheme === 'dark');
1011
}
12+
hdIndicesSet: BehaviorSubject<boolean> = new BehaviorSubject(false);
1113
avaxPrice: BehaviorSubject<number> = new BehaviorSubject(0);
1214
isDarkMode: BehaviorSubject<boolean> = new BehaviorSubject(false);
13-
mnemonic: BehaviorSubject<string> = new BehaviorSubject(
14-
'enemy cabbage salute expire verb camera update like dirt arrest record hidden about warfare record fire hungry arch sting quality cliff inside flash list',
15-
);
16-
wallet: Observable<MnemonicWallet> = this.mnemonic.pipe(
17-
map(m => WalletSDK.getMnemonicValet(m)),
15+
mnemonic: string =
16+
'capable maze trophy install grunt close left visa cheap tilt elder end mosquito culture south stool baby animal donate creek outer learn kitten tonight';
17+
wallet: BehaviorSubject<MnemonicWallet> = new BehaviorSubject<MnemonicWallet>(
18+
WalletSDK.getMnemonicValet(this.mnemonic),
1819
);
1920
walletCAddress: Observable<string> = this.wallet.pipe(
2021
map(wallet => wallet.getAddressC()),
@@ -26,14 +27,53 @@ export default class {
2627
map(isDarkMode => {
2728
return {
2829
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
30+
flex: 1,
31+
paddingTop: StatusBar.currentHeight,
2932
};
3033
}),
3134
);
35+
externalAddressesX: Observable<string[]> = this.wallet.pipe(
36+
map(wallet => wallet.getExternalAddressesX()),
37+
);
38+
externalAddressesP: Observable<string[]> = this.wallet.pipe(
39+
map(wallet => wallet.getExternalAddressesP()),
40+
);
41+
addressC: Observable<string> = this.wallet.pipe(
42+
map(wallet => wallet.getAddressC()),
43+
);
44+
availableX: Observable<string> = this.hdIndicesSet.pipe(
45+
filter(hdIndicesSet => hdIndicesSet === true),
46+
concatMap(() => this.wallet.value.getUtxosX()),
47+
concatMap(() => this.wallet),
48+
map(
49+
wallet => wallet.getAvaxBalanceX()?.unlocked.toNumber().toFixed(2) ?? '-',
50+
),
51+
);
3252

3353
onComponentMount() {
34-
WalletSDK.setNetwork(NetworkConstants.LocalnetConfig);
35-
WalletSDK.getAvaxPrice().then(value => {
36-
this.avaxPrice.next(value);
37-
});
54+
WalletSDK.setNetwork(NetworkConstants.TestnetConfig);
55+
WalletSDK.getAvaxPrice()
56+
.then(value => {
57+
this.avaxPrice.next(value);
58+
})
59+
.catch(reason => console.log(reason));
60+
}
61+
62+
onResetHdIndices() {
63+
console.log('reset indices');
64+
this.wallet
65+
.pipe(
66+
take(1),
67+
concatMap(wallet => wallet.resetHdIndices()),
68+
subscribeOn(asyncScheduler),
69+
)
70+
.subscribe({
71+
next: value => console.log(value),
72+
error: err => console.log(err),
73+
complete: () => {
74+
this.hdIndicesSet.next(true);
75+
this.wallet.next(this.wallet.value);
76+
},
77+
});
3878
}
3979
}

src/mainView/Clock.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import React, {Component} from 'react';
2+
import {Appearance, StyleSheet, Text} from 'react-native';
3+
import {interval, Subscription} from 'rxjs';
4+
import {retry} from 'rxjs/operators';
5+
import moment from 'moment';
6+
import {Colors} from 'react-native/Libraries/NewAppScreen';
7+
8+
class Clock extends Component {
9+
disposable: Subscription;
10+
11+
constructor() {
12+
super();
13+
this.state = {
14+
currentTime: moment().format('HH:mm:ss'),
15+
};
16+
}
17+
componentDidMount() {
18+
this.disposable = interval(1000)
19+
.pipe(retry())
20+
.subscribe({
21+
next: () => {
22+
this.setState({
23+
currentTime: moment().format('HH:mm:ss'),
24+
});
25+
},
26+
error: err => console.log(err),
27+
});
28+
}
29+
componentWillUnmount() {
30+
this.disposable.unsubscribe();
31+
}
32+
33+
render() {
34+
const isDarkMode = Appearance.getColorScheme() === 'dark';
35+
return (
36+
<Text
37+
style={[
38+
styles.text,
39+
{color: isDarkMode ? Colors.white : Colors.black},
40+
]}>
41+
{this.state.currentTime}
42+
</Text>
43+
);
44+
}
45+
}
46+
47+
const styles = StyleSheet.create({
48+
text: {
49+
fontSize: 16,
50+
fontWeight: '700',
51+
textAlign: 'right',
52+
marginEnd: 20,
53+
},
54+
});
55+
56+
export default Clock;

src/mainView/Header.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,17 @@ const Header: React.FC = () => {
3232

3333
const styles = StyleSheet.create({
3434
background: {
35-
paddingBottom: 40,
36-
paddingTop: 96,
35+
paddingBottom: 0,
36+
paddingTop: 56,
3737
paddingHorizontal: 32,
3838
},
3939
logo: {
40-
marginTop: 30,
40+
marginTop: 0,
4141
height: 50,
42-
// opacity: 0.2,
4342
resizeMode: 'contain',
4443
},
4544
text: {
46-
fontSize: 40,
45+
fontSize: 30,
4746
fontWeight: '700',
4847
textAlign: 'center',
4948
},

0 commit comments

Comments
 (0)