Skip to content

Commit

Permalink
Merge pull request #83 from paritytech/nik-api-integration-with-node
Browse files Browse the repository at this point in the history
Nik api integration with node
  • Loading branch information
wirednkod authored Feb 8, 2021
2 parents 4ce7fd1 + 4a50156 commit 5860d19
Show file tree
Hide file tree
Showing 12 changed files with 127 additions and 83 deletions.
48 changes: 30 additions & 18 deletions projects/burnr/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom'; // Pages
import { makeStyles } from '@material-ui/core/styles';

import { ApiContext } from './utils/contexts';
import { ApiContext, AccountContext } from './utils/contexts';
import { LocalStorageAccountCtx } from './utils/types';
import { useApiCreate, useLocalStorage } from './hooks';
import { createLocalStorageAccount } from './utils/utils';

Expand Down Expand Up @@ -31,33 +32,44 @@ const useStyles = makeStyles(theme => ({

const App: React.FunctionComponent<Props> = ({ className }: Props) => {
const api = useApiCreate();
const classes = useStyles();
const [endpoint, useEndpoint] = useLocalStorage('endpoint');
if (!endpoint) useEndpoint('Polkadot-WsProvider');
const [localStorageAccount, setLocalStorageAccount] = useLocalStorage(endpoint.split('-')[0]?.toLowerCase());

const [account, setCurrentAccount] = useState<LocalStorageAccountCtx>({} as LocalStorageAccountCtx);

useEffect((): void => {
if (!localStorageAccount) {
const userTmp = createLocalStorageAccount();
setLocalStorageAccount(JSON.stringify(userTmp));
if (api && api.isReady) {
if (!localStorageAccount) {
const userTmp = createLocalStorageAccount();
setLocalStorageAccount(JSON.stringify(userTmp));
setCurrentAccount(userTmp);
} else {
setCurrentAccount(JSON.parse(localStorageAccount));
}
}
}, [localStorageAccount]);
const classes = useStyles();
}, [localStorageAccount, api]);

const isEmpty = (obj: any): boolean => (Object.keys(obj).length === 0 && obj.constructor === Object)

return (
<BrowserRouter>
<div className={classes.root + ' ' + className}>
<ThemeToggleProvider>
<main className={classes.main}>
{api && api.isReady && (
<ApiContext.Provider value={api}>
<Head />
<Switch>
<Route exact path='/' component={Home} />
</Switch>
</ApiContext.Provider>
)}
</main>
<NavFooter />
<AccountContext.Provider value={{ account, setCurrentAccount }}>
<main className={classes.main}>
{api && api.isReady && !isEmpty(account) && (
<ApiContext.Provider value={api}>
<Head />
<Switch>
<Route exact path='/' component={Home} />
</Switch>
</ApiContext.Provider>
)}
</main>
<NavFooter />
</AccountContext.Provider>
</ThemeToggleProvider>
</div>
</BrowserRouter>
Expand Down
24 changes: 13 additions & 11 deletions projects/burnr/src/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import React, { useState } from 'react';
import React, { useContext } from 'react';

import { Grid, Paper, Divider, IconButton, Box, makeStyles, Theme } from '@material-ui/core';
import VisibilityIcon from '@material-ui/icons/Visibility';
import { LocalStorageUserAccount } from './utils/types';

import { AccountContext } from './utils/contexts';

import { NavTabs, AccountCard, BalanceValue, Bg } from './components';

import { useUserInfo, useLocalStorage } from './hooks';
import { useUserInfo, useBalance } from './hooks';

const useStyles = makeStyles((theme: Theme) => ({
paperAccount: {
Expand All @@ -17,12 +18,12 @@ const useStyles = makeStyles((theme: Theme) => ({
// @TODO read balance
// @TODO account name
function Home (): React.ReactElement {
const { account } = useContext(AccountContext);
const classes = useStyles();
const [endpoint] = useLocalStorage('endpoint');
const [localStorageAccount] = useLocalStorage(endpoint?.split('-')[0]?.toLowerCase());
const [user, setUser] = useState<LocalStorageUserAccount>(JSON.parse(localStorageAccount));

const userInfo = useUserInfo(user.address);
const userInfo = useUserInfo(account.userAddress);
const balanceArr = useBalance(account.userAddress);
const balance = balanceArr[0];
const unit = balanceArr[3];

return (
<>
Expand All @@ -37,7 +38,7 @@ function Home (): React.ReactElement {
<AccountCard
account={{
address: userInfo.address,
name: user?.name
name: account?.userName
}}
/>
}
Expand All @@ -51,7 +52,8 @@ function Home (): React.ReactElement {
>
<Grid item xs={12}>
<BalanceValue
value={1234.56}
value={balance}
unit={unit}
size='large'
style={{ width: '100%', justifyContent: 'flex-end' }}
/>
Expand All @@ -67,7 +69,7 @@ function Home (): React.ReactElement {
</Box>
</Paper>
<Divider/>
<NavTabs setUser={setUser} />
<NavTabs />
</>
);
}
Expand Down
35 changes: 22 additions & 13 deletions projects/burnr/src/components/AccountMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import React, { useState } from 'react';
import React, { useState, useContext } from 'react';

import { red } from '@material-ui/core/colors';
import { Grid, Button, Typography, makeStyles, Theme, createStyles } from '@material-ui/core';
import LanguageIcon from '@material-ui/icons/Language';
import GetAppIcon from '@material-ui/icons/GetApp';
import WhatshotIcon from '@material-ui/icons/Whatshot';

import { LocalStorageUserAccount } from '../utils/types';
import { AccountContext } from '../utils/contexts';

import { openInNewTab, downloadFile, createLocalStorageAccount } from '../utils/utils';
import { POLKA_ACCOUNT_ENDPOINTS } from '../utils/constants';
import { useLocalStorage } from '../hooks';
Expand All @@ -21,27 +22,27 @@ const useStyles = makeStyles((theme: Theme) =>

const { polkastats, polkascan } = POLKA_ACCOUNT_ENDPOINTS;

interface Props {
setUser: (arg0: LocalStorageUserAccount) => void;
}

const AccountMenu: React.FunctionComponent<Props> = ({ setUser }: Props) => {
const AccountMenu: React.FunctionComponent = () => {
const classes = useStyles();
const [endpoint] = useLocalStorage('endpoint');
const minEndpoint = endpoint?.split('-')[0]?.toLowerCase();
const [lclStorage, setLclStorage] = useLocalStorage(minEndpoint);
const [, setLclStorage] = useLocalStorage(minEndpoint);
const [polkastatsUri] = useState(
`https://${minEndpoint}.${polkastats}`
);
const [polkascanUri] = useState(`https://${polkascan}/${minEndpoint}`);
const { address, json, seed } = JSON.parse(lclStorage);

const { account, setCurrentAccount } = useContext(AccountContext);

const burnAndCreate = (): void => {
localStorage.removeItem(minEndpoint);
const userTmp = createLocalStorageAccount();
setLclStorage(JSON.stringify(userTmp));
setUser(userTmp);
};
setCurrentAccount(userTmp);
};

const { userAddress, userJson, userSeed } = account;

return (
<Grid
container
Expand Down Expand Up @@ -74,14 +75,22 @@ const AccountMenu: React.FunctionComponent<Props> = ({ setUser }: Props) => {
<Grid item xs={12}>
<Button
startIcon={<GetAppIcon />}
onClick={() => downloadFile(address, JSON.stringify(json), 'json')}>
onClick={() => {
userAddress &&
userJson &&
downloadFile(userAddress, JSON.stringify(userJson), 'json')
}}>
JSON file
</Button>
</Grid>
<Grid item xs={12}>
<Button
startIcon={<GetAppIcon />}
onClick={() => downloadFile(address, seed, 'txt')}>
onClick={() => {
userAddress &&
userSeed &&
downloadFile(userAddress, userSeed, 'txt')
}}>
Seed phrase
</Button>
</Grid>
Expand Down
7 changes: 4 additions & 3 deletions projects/burnr/src/components/BalanceValue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { CSSProperties } from '@material-ui/core/styles/withStyles';

interface Props extends SizeScale {
value: number | string;
unit?: string;
style?: CSSProperties;
}
interface StyleProps {
Expand Down Expand Up @@ -34,9 +35,9 @@ const useStyles = makeStyles((theme: Theme) => ({
},
}));

const BalanceValue: React.FunctionComponent<Props> = ({ value, size, style }: Props) => {
const BalanceValue: React.FunctionComponent<Props> = ({ value, unit, size, style }: Props) => {
const isBalance = typeof value === 'number';
const isColored = isBalance && value >= 0 ? true : false;
const isColored = (isBalance && value >= 0 || (!isBalance && typeof value === 'string' && parseFloat(value) > 0));
const classes = useStyles({ colored: isColored });

const TypographyVariant = size === 'large' ? 'subtitle1' : 'subtitle2';
Expand All @@ -45,7 +46,7 @@ const BalanceValue: React.FunctionComponent<Props> = ({ value, size, style }: Pr
<Box component='span' className={classes.root} style={style}>
<Typography variant={TypographyVariant}>
{value}
{isBalance && ' KSM'}
{` ${unit}`}
</Typography>
</Box>
);
Expand Down
10 changes: 2 additions & 8 deletions projects/burnr/src/components/NavTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import CallMadeSharpIcon from '@material-ui/icons/CallMadeSharp';
import CallReceivedSharpIcon from '@material-ui/icons/CallReceivedSharp';
import WhatshotSharpIcon from '@material-ui/icons/WhatshotSharp';

import { LocalStorageUserAccount } from '../utils/types';

import { HistoryTable, AccountMenu } from './index';
import SendFundsForm from './SendFundsForm';

Expand All @@ -17,10 +15,6 @@ interface TabPanelProps {
value: number;
}

interface Props {
setUser: (arg0: LocalStorageUserAccount) => void;
}

const useStyles = makeStyles((theme: Theme) => ({
root: {
height:'calc(100vh - 265px)',
Expand Down Expand Up @@ -49,7 +43,7 @@ const TabPanel: React.FunctionComponent<TabPanelProps> = ({ children, value, ind
);
};

const NavTabs: React.FunctionComponent<Props> = ({ setUser }: Props) => {
const NavTabs: React.FunctionComponent = () => {
const classes = useStyles();
const [value, setValue] = React.useState(0);
const handleChange = (event: React.ChangeEvent<{}>, newValue: number) => {
Expand Down Expand Up @@ -78,7 +72,7 @@ const NavTabs: React.FunctionComponent<Props> = ({ setUser }: Props) => {
<Typography variant='h2'>
Account Controls
</Typography>
<AccountMenu setUser={setUser} />
<AccountMenu />
</TabPanel>
<TabPanel value={value} index={1}>
<Typography variant='h2'>
Expand Down
4 changes: 2 additions & 2 deletions projects/burnr/src/hooks/api/useApiCreate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ console.log('ALL_PROVIDERS', ALL_PROVIDERS)

export default function useApiCreate (): ApiPromise | null {
const [api, setApi] = useState<ApiPromise | null>(null);
const [localEndpoint, setLocalEndpoint] = useLocalStorage('endpoint');
const [localEndpoint] = useLocalStorage('endpoint');

const [provider, setProvider] = useState<LazyProvider>(ALL_PROVIDERS[localEndpoint] || ALL_PROVIDERS['Polkadot-WsProvider']);
const [provider] = useState<LazyProvider>(ALL_PROVIDERS[localEndpoint] || ALL_PROVIDERS['Polkadot-WsProvider']);
const mountedRef = useIsMountedRef();

// @TODO Make dynamic once @substrate/connect is implemented
Expand Down
1 change: 0 additions & 1 deletion projects/burnr/src/hooks/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,3 @@ export { default as useBalance } from './useBalance';
export { default as useChainInfo } from './useChainInfo';
export { default as useUserInfo } from './useUserInfo';
export { default as useUsers } from './useUsers';

25 changes: 21 additions & 4 deletions projects/burnr/src/hooks/useBalance.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,46 @@
// SPDX-License-Identifier: Apache-2

import BN from 'bn.js';
import { useEffect, useState } from 'react';
import { useEffect, useState, useContext } from 'react';
import { formatBalance } from '@polkadot/util';
// import { useLocalStorage } from '.';
// import { AccountContext } from '../utils/contexts';

import useApi from './api/useApi';
import useIsMountedRef from './api/useIsMountedRef';

type State = [string, BN, boolean];
type State = [string, BN, boolean, string];

const ZERO = new BN(0);

export default function useBalance (address: string): State {
const api = useApi();
const [state, setState] = useState<State>(['0', ZERO, true]);
const [state, setState] = useState<State>(['0', ZERO, true, 'Units']);
const mountedRef = useIsMountedRef();
// const { account } = useContext(AccountContext);
// const [userAddress] = useLocalStorage(account.userAddress);


useEffect((): () => void => {
let unsubscribe: null | (() => void) = null;
api.query.system
.account(address, ({ data }): void => {
// const history = account.userHistory;
// history.push({
// amount: data.free,
// key: '',
// from: '',
// to: userAddress,
// wasSent: true,
// when: new Date(),
// method: 'transfer'
// })
// account.userHistory = [...history];
mountedRef.current && setState([
formatBalance(data.free, { decimals: api.registry.chainDecimals[0], forceUnit: '-', withSi: false }),
data.free,
data.free.isZero()
data.free.isZero(),
data.free.registry.chainTokens[0]
]);
})
.then((u): void => {
Expand Down
4 changes: 2 additions & 2 deletions projects/burnr/src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ export const JS_WASM_PROVIDERS: Record<string, LazyProvider> = {
* These fallback providers connect to a centralized remote RPC node.
*/
export const REMOTE_PROVIDERS: Record<string, LazyProvider> = {
'Polkadot-Local-WsProvider': {
'Local-Polkadot-WsProvider': {
description: `Local node running on ${endpoints.local}`,
id: 'Polkadot-Local-WsProvider',
id: 'Local-Polkadot-WsProvider',
network: 'Local Polkadot Network',
node: 'light',
source: 'remote',
Expand Down
7 changes: 5 additions & 2 deletions projects/burnr/src/utils/contexts.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
// SPDX-License-Identifier: Apache-2

import { AccountCtx, AdminCtx, EvtMgrCtx, EvtTxCtx } from './types';
import { LocalStorageAccountCtx, AdminCtx, EvtMgrCtx, EvtTxCtx, CreateAccountCtx } from './types';

import React from 'react';
import { ApiPromise } from '@polkadot/api';

const AccountContext = React.createContext<AccountCtx>({} as AccountCtx);
const AccountContext = React.createContext<CreateAccountCtx>({
account: {} as LocalStorageAccountCtx,
setCurrentAccount: () => {}
});
const AdminContext = React.createContext<AdminCtx>({} as AdminCtx);
const ApiContext = React.createContext<ApiPromise>({} as ApiPromise);
const EvtMgrContext = React.createContext<EvtMgrCtx>([]);
Expand Down
Loading

0 comments on commit 5860d19

Please sign in to comment.