Skip to content

Commit

Permalink
Selecting network
Browse files Browse the repository at this point in the history
  • Loading branch information
Szegoo committed Sep 14, 2023
1 parent 1015328 commit 5002a1a
Show file tree
Hide file tree
Showing 12 changed files with 133 additions and 61 deletions.
8 changes: 4 additions & 4 deletions chaindata/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { RELAY_CHAIN } from "@/consts";
import { gql, request } from "graphql-request"

const graphqlUrl = "https://squid.subsquid.io/chaindata/v/v4/graphql"
Expand Down Expand Up @@ -86,16 +85,17 @@ export class Chaindata {
this.tokens = tokensResult.tokens;
}

public async getChain(chainId: number): Promise<Chain> {
public async getChain(chainId: number, relay: string): Promise<Chain> {
console.log(relay);
if (chainId === 0) {
const result: any = await request(graphqlUrl, relayQuery, {
relayId: RELAY_CHAIN
relayId: relay
});
return result.chains[0];
} else {
const result: any = await request(graphqlUrl, chainQuery, {
paraId: chainId,
relayId: RELAY_CHAIN
relayId: relay
});
return result.chains[0];
}
Expand Down
6 changes: 4 additions & 2 deletions src/components/Layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,18 @@ import { Sidebar } from '../Sidebar';

interface Props {
children: ReactElement | ReactElement[];
relay: string,
setRelay: (relay: string) => void
}

export const Layout = ({ children }: Props) => {
export const Layout = ({ relay, setRelay, children }: Props) => {
const { isConnected } = useInkathon();
return (
<div className={styles.layout}>
<Header />
<div className={styles.content}>
<div className={styles.sidebar}>
<Sidebar />
<Sidebar relay={relay} setRelay={setRelay} />
</div>
<div className={styles.main}>
{isConnected ? (
Expand Down
25 changes: 25 additions & 0 deletions src/components/RelaySelect/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { FormControl, InputLabel, MenuItem, Select } from "@mui/material"

const RelaySelect = ({ relay, setRelay }: { relay: string, setRelay: (relay: string) => void }) => {

const handleChange = (e: any) => {
setRelay(e.target.value);
};

return (
<FormControl sx={{ m: 2, minWidth: 200 }} fullWidth>
<InputLabel id="demo-simple-select-label">Network</InputLabel>
<Select
id="network-select"
value={relay}
label="Relay chain"
onChange={handleChange}
>
<MenuItem value="polkadot">Polkadot</MenuItem>
<MenuItem value="kusama">Kusama</MenuItem>
</Select>
</FormControl>
);
};

export default RelaySelect;
5 changes: 5 additions & 0 deletions src/components/Sidebar/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@
.active {
color: var.$btnPrimary;
}

.networkSelect {
position: absolute;
bottom: 0;
}
12 changes: 8 additions & 4 deletions src/components/Sidebar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import ContactsIcon from '@mui/icons-material/Contacts';
import SwapHorizIcon from '@mui/icons-material/SwapHoriz';
import { useRouter } from 'next/router';
import React from 'react';
import RelaySelect from '../RelaySelect';

import styles from './index.module.scss';
interface MenuItemProps {
Expand All @@ -15,9 +16,8 @@ const MenuItem = ({ label, route, icon }: MenuItemProps) => {
const isActive = pathname === route;
return (
<div
className={`${styles.menuItem} ${
isActive ? styles.active : styles.inactive
}`}
className={`${styles.menuItem} ${isActive ? styles.active : styles.inactive
}`}
onClick={() => push(route)}
>
{{
Expand All @@ -28,7 +28,8 @@ const MenuItem = ({ label, route, icon }: MenuItemProps) => {
);
};

export const Sidebar = () => {
export const Sidebar = ({ relay, setRelay }: { relay: string, setRelay: (relay: string) => void }) => {
console.log(setRelay);
const menuItems: MenuItemProps[] = [
{
label: 'My Identity',
Expand All @@ -51,6 +52,9 @@ export const Sidebar = () => {
{menuItems.map((item, index) => (
<MenuItem key={index} {...item} />
))}
<div className={styles.networkSelect}>
<RelaySelect relay={relay} setRelay={setRelay} />
</div>
</div>
);
};
4 changes: 4 additions & 0 deletions src/consts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ export const RELAY_CHAIN = (process.env.RELAY_CHAIN || 'polkadot') as RELAY_CHAI
export const RELAY_CHAIN_ENDPOINT = RELAY_CHAIN_ENDPOINTS[RELAY_CHAIN];
export const ZERO = BigInt(0);

export const getRelayChainApiURL = (relay: "polkadot" | "kusama"): string => {
return RELAY_CHAIN_ENDPOINTS[relay];
}

// NOTE: we do not need to store the name of these chains, but they are convenient
// for us while reading to code to see which chains support local XCM execution.
export const chainsSupportingXcmExecute = [
Expand Down
43 changes: 33 additions & 10 deletions src/contexts/RelayApi/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { ApiPromise, WsProvider } from '@polkadot/api';
import jsonrpc from '@polkadot/types/interfaces/jsonrpc';
import { DefinitionRpcExt } from '@polkadot/types/types';
import React, { useContext, useEffect, useReducer } from 'react';

import { RELAY_CHAIN_ENDPOINT } from '@/consts';
import React, { useContext, useEffect, useReducer, useState } from 'react';

import { useToast } from '../Toast';
import { getRelayChainApiURL } from '@/consts';

///
// Initial state for `useReducer`

type State = {
socket: string;
jsonrpc: Record<string, Record<string, DefinitionRpcExt>>;
api: any;
apiError: any;
Expand All @@ -20,7 +18,6 @@ type State = {

const initialState: State = {
// These are the states
socket: RELAY_CHAIN_ENDPOINT,
jsonrpc: { ...jsonrpc },
api: null,
apiError: null,
Expand Down Expand Up @@ -48,8 +45,8 @@ const reducer = (state: any, action: any) => {
///
// Connecting to the Substrate node

const connect = (state: any, dispatch: any) => {
const { apiState, socket, jsonrpc } = state;
const connect = (state: any, socket: string, dispatch: any) => {
const { apiState, jsonrpc } = state;
// We only want this function to be performed once
if (apiState) return;

Expand All @@ -72,6 +69,30 @@ const defaultValue = {
state: initialState,
};

type Relay = {
relay: "polkadot" | "kusama",
setRelay(value: string): void
}

const RelayContext = React.createContext(
{ relay: "polkadot", setRelay: (_: string) => { } } as Relay
);

const RelayContextProvider = (props: any) => {
const [relay, setRelay]: [relay: "polkadot" | "kusama", setRelay: any] = useState("polkadot");

const handleChange = (value: string) => {
console.log(value);
setRelay(value);
}

return (
<RelayContext.Provider value={{ relay: relay, setRelay: handleChange }}>
{props.children}
</RelayContext.Provider>
);
}

const RelayApiContext = React.createContext(defaultValue);

const RelayApiContextProvider = (props: any) => {
Expand All @@ -91,15 +112,17 @@ const RelayApiContextProvider = (props: any) => {
}, [state.apiState]);

useEffect(() => {
connect(state, dispatch);
}, [process.env.RELAY_CHAIN_ENDPOINT]);
console.log(props.relay);
connect(state, getRelayChainApiURL(props.relay), dispatch);
}, [props.relay]);

return (
<RelayApiContext.Provider value={{ state }}>
{props.children}
</RelayApiContext.Provider>
);
};
const useRelay = () => useContext(RelayContext);
const useRelayApi = () => useContext(RelayApiContext);

export { RelayApiContextProvider, useRelayApi };
export { RelayApiContextProvider, RelayContextProvider, useRelayApi, useRelay };
5 changes: 3 additions & 2 deletions src/contracts/identity/context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ const IdentityContext = createContext<IdentityContract>(defaultIdentity);

interface Props {
children: React.ReactNode;
relay: "polkadot" | "kusama";
}

const IdentityContractProvider = ({ children }: Props) => {
const IdentityContractProvider = ({ children, relay }: Props) => {
const { contract } = useContract(IdentityMetadata, CONTRACT_IDENTITY);
const { api, activeAccount } = useInkathon();
const [identityNo, setIdentityNo] = useState<IdentityNo>(null);
Expand Down Expand Up @@ -102,7 +103,7 @@ const IdentityContractProvider = ({ children }: Props) => {
const chaindata = new Chaindata();

try {
const chain = await chaindata.getChain(chainId);
const chain = await chaindata.getChain(chainId, relay);

if (!chain) {
return null;
Expand Down
58 changes: 33 additions & 25 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ import theme from '@/utils/muiTheme';

import { Layout } from '@/components/Layout';

import { RelayApiContextProvider } from '@/contexts/RelayApi';
import { RelayApiContextProvider, RelayContextProvider, useRelay } from '@/contexts/RelayApi';
import { ToastProvider } from '@/contexts/Toast';
import { IdentityContractProvider } from '@/contracts';
import { AddressBookContractProvider } from '@/contracts/addressbook/context';
import { createContext, useState } from 'react';

// Client-side cache, shared for the whole session of the user in the browser.
const clientSideEmotionCache = createEmotionCache();
Expand All @@ -31,7 +32,12 @@ interface MyAppProps extends AppProps {

export default function MyApp(props: MyAppProps) {
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
const getLayout = Component.getLayout ?? ((page) => <Layout>{page}</Layout>);
const { relay, setRelay } = useRelay();
const getLayout = Component.getLayout ?? ((page) =>
<RelayContextProvider>
<Layout relay={relay} setRelay={setRelay}>{page}</Layout>
</RelayContextProvider>
);

return (
<CacheProvider value={emotionCache}>
Expand All @@ -43,29 +49,31 @@ export default function MyApp(props: MyAppProps) {
{/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
<CssBaseline />
<ToastProvider>
<RelayApiContextProvider>
<UseInkathonProvider
appName='DotFlow UI'
connectOnInit={false}
defaultChain={{
network: 'rocococ-contracts',
name: 'Rococo contracts',
ss58Prefix: 42,
rpcUrls: ['wss://rococo-contracts-rpc.polkadot.io'],
explorerUrls: {},
testnet: true,
faucetUrls: [],
}}
>
<IdentityContractProvider>
<AddressBookContractProvider>
<ConfirmProvider>
{getLayout(<Component {...pageProps} />)}
</ConfirmProvider>
</AddressBookContractProvider>
</IdentityContractProvider>
</UseInkathonProvider>
</RelayApiContextProvider>
<RelayContextProvider>
<RelayApiContextProvider relay={relay}>
<UseInkathonProvider
appName='DotFlow UI'
connectOnInit={false}
defaultChain={{
network: 'rocococ-contracts',
name: 'Rococo contracts',
ss58Prefix: 42,
rpcUrls: ['wss://rococo-contracts-rpc.polkadot.io'],
explorerUrls: {},
testnet: true,
faucetUrls: [],
}}
>
<IdentityContractProvider relay={relay}>
<AddressBookContractProvider>
<ConfirmProvider>
{getLayout(<Component {...pageProps} relay={relay} />)}
</ConfirmProvider>
</AddressBookContractProvider>
</IdentityContractProvider>
</UseInkathonProvider>
</RelayApiContextProvider>
</RelayContextProvider>
</ToastProvider>
</ThemeProvider>
</CacheProvider>
Expand Down
16 changes: 9 additions & 7 deletions src/pages/transfer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ import TransactionRouter, { isTeleport } from '@/utils/xcmTransfer';
import { getTeleportableAssets } from '@/utils/xcmTransfer/teleportableRoutes';
import { Fungible } from '@/utils/xcmTransfer/types';

import { chainsSupportingXcmExecute, RELAY_CHAIN } from '@/consts';
import { chainsSupportingXcmExecute } from '@/consts';
import { useRelayApi } from '@/contexts/RelayApi';
import { useToast } from '@/contexts/Toast';
import { useIdentity } from '@/contracts';
import { useAddressBook } from '@/contracts/addressbook/context';

const TransferPage = () => {
const TransferPage = ({ relay }: { relay: "polkadot" | "kusama" }) => {
const {
chains,
getAddresses,
Expand Down Expand Up @@ -91,16 +91,16 @@ const TransferPage = () => {
setAssets([]);
} else {
const _assets = await AssetRegistry.assetsSupportedOnBothChains(
RELAY_CHAIN,
relay,
chains[sourceChainId].paraId,
chains[destChainId].paraId
);
_assets.push(...getTeleportableAssets(sourceChainId, destChainId));
_assets.push(...getTeleportableAssets(sourceChainId, destChainId, relay));
setAssets(_assets);
}
} else {
const chaindata = new Chaindata();
const chain = await chaindata.getChain(sourceChainId);
const chain = await chaindata.getChain(sourceChainId, relay);

await chaindata.load();

Expand Down Expand Up @@ -203,15 +203,16 @@ const TransferPage = () => {
isTeleport(
sourceChainId,
destChainId,
getFungible(selectedAsset.xcmInteriorKey, isSourceParachain, 0)
getFungible(selectedAsset.xcmInteriorKey, isSourceParachain, 0),
relay
)
) {
return true;
}

const isOriginSupportingLocalXCM = chainsSupportingXcmExecute.findIndex(
(chain) =>
chain.paraId == sourceChainId && chain.relayChain == RELAY_CHAIN
chain.paraId == sourceChainId && chain.relayChain == relay
);

// We only need the origin chain to support XCM for any other type of transfer to
Expand Down Expand Up @@ -321,6 +322,7 @@ const TransferPage = () => {
destApi: await getApi(chains[destChainId].rpc),
reserveApi: await getApi(chains[reserveChainId].rpc),
},
relay,
activeSigner
);
toastSuccess(`Transfer succeded`);
Expand Down
Loading

0 comments on commit 5002a1a

Please sign in to comment.