Skip to content

Commit

Permalink
dex - poolswap (#216)
Browse files Browse the repository at this point in the history
* initial commit for poolswap

* added tests for poolswap

* update

* remove formatted code

* review updates

* review updates
  • Loading branch information
thedoublejay authored Jul 7, 2021
1 parent 546b492 commit 7c89a34
Show file tree
Hide file tree
Showing 6 changed files with 1,911 additions and 8 deletions.
11 changes: 11 additions & 0 deletions app/screens/AppNavigator/screens/Dex/DexNavigator.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { PoolPairData } from '@defichain/whale-api-client/dist/api/poolpair'
import { createStackNavigator } from '@react-navigation/stack'
import * as React from 'react'
import { translate } from '../../../../translations'
import { DexScreen } from './DexScreen'
import { PoolSwapScreen } from './PoolSwap/PoolSwapScreen'

export interface DexParamList {
DexScreen: undefined
PoolSwapScreen: { poolpair: PoolPairData }

[key: string]: undefined | object
}
Expand All @@ -19,6 +22,14 @@ export function DexNavigator (): JSX.Element {
component={DexScreen}
options={{ headerTitle: translate('screens/DexScreen', 'Decentralized Exchange') }}
/>
<DexStack.Screen
name='PoolSwap'
component={PoolSwapScreen}
options={{
headerTitle: translate('screens/DexScreen', 'Decentralized Exchange'),
headerBackTitleVisible: false
}}
/>
</DexStack.Navigator>
)
}
16 changes: 9 additions & 7 deletions app/screens/AppNavigator/screens/Dex/DexScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AddressToken } from '@defichain/whale-api-client/dist/api/address'
import { PoolPairData } from '@defichain/whale-api-client/dist/api/poolpair'
import { MaterialIcons } from '@expo/vector-icons'
import { useNavigation } from '@react-navigation/native'
import * as React from 'react'
import { useEffect, useState } from 'react'
import { SectionList, TouchableOpacity } from 'react-native'
Expand All @@ -20,6 +21,7 @@ export function DexScreen (): JSX.Element {
const address = useSelector((state: RootState) => state.wallet.address)
const [pairs, setPairs] = useState<Array<DexItem<PoolPairData>>>([])
const dispatch = useDispatch()
const navigation = useNavigation()

useEffect(() => {
// TODO(fuxingloh): does not auto refresh currently, but not required for MVP. Due to limited PP availability
Expand All @@ -45,15 +47,15 @@ export function DexScreen (): JSX.Element {
},
{
key: 'Available pool pairs',
data: pairs as Array<DexItem<any>>
data: pairs
}
]}
renderItem={({ item }): JSX.Element => {
switch (item.type) {
case 'your':
return PoolPairRowYour(item.data)
case 'available':
return PoolPairRowAvailable(item.data)
return PoolPairRowAvailable(item.data, () => navigation.navigate('PoolSwap', { poolpair: item.data }))
}
}}
ListHeaderComponent={() => {
Expand Down Expand Up @@ -120,7 +122,7 @@ function PoolPairRowYour (data: AddressToken): JSX.Element {
)
}

function PoolPairRowAvailable (data: PoolPairData): JSX.Element {
function PoolPairRowAvailable (data: PoolPairData, onSwap: () => void): JSX.Element {
const [symbolA, symbolB] = data.symbol.split('-')
const IconA = getTokenIcon(symbolA)
const IconB = getTokenIcon(symbolB)
Expand All @@ -136,7 +138,7 @@ function PoolPairRowAvailable (data: PoolPairData): JSX.Element {

<View style={tailwind('flex-row -mr-2')}>
<PoolPairLiqBtn name='add' />
<PoolPairSwapBtn />
<PoolPairSwapBtn onPress={onSwap} />
</View>
</View>

Expand All @@ -156,10 +158,10 @@ function PoolPairLiqBtn (props: { name: 'remove' | 'add' }): JSX.Element {
)
}

function PoolPairSwapBtn (): JSX.Element {
function PoolPairSwapBtn ({ onPress }: { onPress: () => void }): JSX.Element {
return (
<TouchableOpacity style={tailwind('py-2 px-3 flex-row items-center')}>
<Text style={[tailwind('font-bold'), PrimaryColorStyle.text]}>SWAP</Text>
<TouchableOpacity style={tailwind('py-2 px-3 flex-row items-center')} onPress={onPress}>
<Text style={[tailwind('font-bold'), PrimaryColorStyle.text]}>{translate('screens/DexScreen', 'SWAP')}</Text>
</TouchableOpacity>
)
}
Expand Down
127 changes: 127 additions & 0 deletions app/screens/AppNavigator/screens/Dex/PoolSwap/PoolSwapScreen.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { configureStore } from "@reduxjs/toolkit";
import { act, fireEvent, render } from "@testing-library/react-native";
import * as React from "react";
import { Provider } from "react-redux";
import { RootState } from "../../../../../store";
import { wallet, WalletStatus } from "../../../../../store/wallet";
import { PoolSwapScreen } from "./PoolSwapScreen";

jest.mock('react-native/Libraries/Animated/src/NativeAnimatedHelper')

jest.mock("../../../../../hooks/wallet/TokensAPI", () => ({
useTokensAPI: () => [{
id: '0',
symbol: 'DFI',
symbolKey: 'DFI',
isDAT: true,
isLPS: false,
amount: '23',
name: 'Defi'
}, {
id: '1',
symbol: 'BTC',
symbolKey: 'BTC',
isDAT: true,
isLPS: false,
amount: '777',
name: 'Bitcoin'
},
{
id: '2',
symbol: 'ETH',
symbolKey: 'ETH',
isDAT: true,
isLPS: false,
amount: '555',
name: 'Ethereum'
}]
}));

describe('poolswap page', () => {
it('should be able to input values', async () => {
const initialState: Partial<RootState> = {
wallet: {
address: 'bcrt1q6np0fh47ykhznjhrtfvduh73cgjg32yac8t07d',
status: WalletStatus.LOADED_WALLET,
utxoBalance: '77',
tokens: []
}
};
const store = configureStore({
preloadedState: initialState,
reducer: { wallet: wallet.reducer }
})
const navigation: any = {
navigate: jest.fn(),
}
const route: any = {
params: {
poolpair: {
tokenA: {
id: '0',
reserve: '100'
},
tokenB: {
id: '1',
reserve: '10'
}
}
}
}
const component = (
<Provider store={store}>
<PoolSwapScreen navigation={navigation} route={route} />
</Provider>
);
const { getByTestId, toJSON } = render(component)
await act(async () => {
fireEvent.changeText(getByTestId('input_amount_0'), '1')
fireEvent.changeText(getByTestId('input_amount_1'), '2')
})
expect(toJSON()).toMatchSnapshot()
})

it('should be able to swap and submit', async () => {
const initialState: Partial<RootState> = {
wallet: {
address: 'bcrt1q6np0fh47ykhznjhrtfvduh73cgjg32yac8t07d',
status: WalletStatus.LOADED_WALLET,
utxoBalance: '77',
tokens: []
}
};
const store = configureStore({
preloadedState: initialState,
reducer: { wallet: wallet.reducer }
})
const navigation: any = {
navigate: jest.fn(),
}
const route: any = {
params: {
poolpair: {
tokenA: {
id: '0',
reserve: '100'
},
tokenB: {
id: '1',
reserve: '10'
}
}
}
}
const component = (
<Provider store={store}>
<PoolSwapScreen navigation={navigation} route={route} />
</Provider>
);
const { getByTestId, toJSON } = render(component)
await act(async () => {
fireEvent.press(getByTestId('max_button_token_a'))
fireEvent.press(getByTestId('swap_button'))
fireEvent.changeText(getByTestId('input_amount_1'), '2')
})
expect(toJSON()).toMatchSnapshot()
})
})
Loading

0 comments on commit 7c89a34

Please sign in to comment.