Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transfer page #56

Merged
merged 36 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
cf11225
wip
cuteolaf Aug 20, 2023
09c594d
wip: transfer page UI
cuteolaf Aug 20, 2023
a4122ae
get shared assets
cuteolaf Aug 21, 2023
8cae294
Merge branch 'main' into transfer-page
cuteolaf Aug 23, 2023
6d6d29c
Merge branch 'main' into transfer-page
Szegoo Aug 23, 2023
6b92ab6
merge fix
Szegoo Aug 23, 2023
64eabdb
fetch token balance
cuteolaf Aug 23, 2023
3275b32
Merge remote-tracking branch 'origin/transfer-page' into transfer-page
cuteolaf Aug 23, 2023
6e25fae
get addresses
cuteolaf Aug 23, 2023
a89951d
Merge branch 'main' into transfer-page
cuteolaf Aug 24, 2023
538b503
select identity, transfer
cuteolaf Aug 24, 2023
9c7b406
isTransferSupported
Szegoo Aug 25, 2023
0bbbb3d
bug fix, add input field for amount
cuteolaf Aug 25, 2023
c6788c0
lint
cuteolaf Aug 25, 2023
f4e3c53
Merge remote-tracking branch 'origin/main' into transfer-page
Szegoo Aug 26, 2023
dcd52b6
Merge branch 'main' into transfer-page
cuteolaf Aug 27, 2023
23a68e1
remove balance
cuteolaf Aug 27, 2023
924b00d
progress
Szegoo Aug 28, 2023
11a8ec3
update
Szegoo Aug 28, 2023
fc7d4c4
lint
cuteolaf Aug 28, 2023
ab9b39f
fix css
cuteolaf Aug 28, 2023
2b13040
fix signer
cuteolaf Aug 28, 2023
f5de7d1
transfer works
Szegoo Aug 28, 2023
8fbe8d8
teleports working
Szegoo Aug 28, 2023
d427b17
bydirectional teleport
Szegoo Aug 28, 2023
1ea1289
fix linting errors
Szegoo Aug 28, 2023
461c4a4
input the amount in token unit
Szegoo Aug 29, 2023
903d27e
warn non-supported transfer routes
Szegoo Aug 29, 2023
aef2a4e
resolve lint errors
Szegoo Aug 29, 2023
abb494e
working reserve transfers
Szegoo Aug 29, 2023
0f1a9cf
spinning wheel
Szegoo Aug 29, 2023
5e86b80
kind of a fix
Szegoo Aug 29, 2023
895152b
fix tests
Szegoo Aug 29, 2023
fb12a85
fix linter errors
Szegoo Aug 29, 2023
5ce1355
remove old comments
Szegoo Aug 29, 2023
84a1d90
amount
cuteolaf Aug 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
CONTRACT_IDENTITY="AddressOfIdentityContract"
CONTRACT_ADDRESS_BOOK="AddressOfAddressBookContract"
CONTRACT_ADDRESS_BOOK="AddressOfAddressBookContract"
RELAY_CHAIN="kusama_or_polkadot"
3 changes: 1 addition & 2 deletions __tests__/crossChainRouter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { u8aToHex } from '@polkadot/util';

import TransactionRouter from "../src/utils/transactionRouter";
import { Fungible, Receiver, Sender } from "../src/utils/transactionRouter/types";

import IdentityContractFactory from "../types/constructors/identity";
import IdentityContract from "../types/contracts/identity";
import { AccountType, ChainInfo } from "../types/types-arguments/identity";
Expand Down Expand Up @@ -144,7 +143,7 @@ describe("TransactionRouter Cross-chain reserve transfer", () => {
{
originApi: assetHubApi,
destApi: trappistApi
}
},
);

const senderBalanceAfter = await getAssetBalance(assetHubApi, USDT_ASSET_ID, alice.address);
Expand Down
1 change: 1 addition & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const nextConfig = {
env: {
CONTRACT_IDENTITY: process.env.CONTRACT_IDENTITY,
CONTRACT_ADDRESS_BOOK: process.env.CONTRACT_ADDRESS_BOOK,
RELAY_CHAIN: process.env.RELAY_CHAIN,
},
async redirects() {
return [
Expand Down
2 changes: 1 addition & 1 deletion src/components/Cards/AddressCard/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
line-height: 1.6;
}

.networkName {
.chainName {
display: flex;
align-items: center;
justify-content: space-between;
Expand Down
11 changes: 6 additions & 5 deletions src/components/Modals/AddAddress/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,10 @@ export const AddAddressModal = ({ open, onClose }: AddAddressModalProps) => {
onClose();
} catch (e: any) {
toastError(
`Failed to add address. Error: ${e.errorMessage === 'Error'
? 'Please check your balance.'
: e.errorMessage
`Failed to add address. Error: ${
e.errorMessage === 'Error'
? 'Please check your balance.'
: e.errorMessage
}`
);
setWorking(false);
Expand All @@ -119,7 +120,7 @@ export const AddAddressModal = ({ open, onClose }: AddAddressModalProps) => {
select
sx={{ mt: '8px' }}
required
value={chainId || ""}
value={chainId === undefined ? '' : chainId}
onChange={(e) => setChainId(Number(e.target.value))}
>
{Object.entries(chains).map(([id, chain], index) => (
Expand Down Expand Up @@ -150,7 +151,7 @@ export const AddAddressModal = ({ open, onClose }: AddAddressModalProps) => {
maxLength: 64,
}}
required
value={chainAddress || ""}
value={chainAddress || ''}
error={chainAddress === ''}
onChange={(e) => setChainAddress(e.target.value)}
/>
Expand Down
37 changes: 37 additions & 0 deletions src/consts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
export type RELAY_CHAIN_OPTION = 'polkadot' | 'kusama';
const RELAY_CHAIN_ENDPOINTS = {
polkadot: "wss://polkadot.api.onfinality.io/public-ws",
kusama: "wss://kusama.api.onfinality.io/public-ws"
};
export const RELAY_CHAIN = (process.env.RELAY_CHAIN || 'polkadot') as RELAY_CHAIN_OPTION;
export const RELAY_CHAIN_ENDPOINT = RELAY_CHAIN_ENDPOINTS[RELAY_CHAIN];
export const ZERO = BigInt(0);

// 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 = [
{
relayChain: "kusama",
paraId: 0
},
{
relayChain: "kusama",
name: "crab",
paraId: 2105
},
{
relayChain: "kusama",
name: "quartz by unique",
paraId: 2095
},
{
relayChain: "polkadot",
name: "darwinia",
paraId: 2046
},
{
relayChain: "polkadot",
name: "unique network",
paraId: 2037
}
];
105 changes: 105 additions & 0 deletions src/contexts/RelayApi/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
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 { useToast } from '../Toast';

///
// Initial state for `useReducer`

type State = {
socket: string;
jsonrpc: Record<string, Record<string, DefinitionRpcExt>>;
api: any;
apiError: any;
apiState: any;
};

const initialState: State = {
// These are the states
socket: RELAY_CHAIN_ENDPOINT,
jsonrpc: { ...jsonrpc },
api: null,
apiError: null,
apiState: null,
};

///
// Reducer function for `useReducer`

const reducer = (state: any, action: any) => {
switch (action.type) {
case 'CONNECT_INIT':
return { ...state, apiState: 'CONNECT_INIT' };
case 'CONNECT':
return { ...state, api: action.payload, apiState: 'CONNECTING' };
case 'CONNECT_SUCCESS':
return { ...state, apiState: 'READY' };
case 'CONNECT_ERROR':
return { ...state, apiState: 'ERROR', apiError: action.payload };
default:
throw new Error(`Unknown type: ${action.type}`);
}
};

///
// Connecting to the Substrate node

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

dispatch({ type: 'CONNECT_INIT' });

const provider = new WsProvider(socket);
const _api = new ApiPromise({ provider, rpc: jsonrpc });

// Set listeners for disconnection and reconnection event.
_api.on('connected', () => {
dispatch({ type: 'CONNECT', payload: _api });
// `ready` event is not emitted upon reconnection and is checked explicitly here.
_api.isReady.then(() => dispatch({ type: 'CONNECT_SUCCESS' }));
});
_api.on('ready', () => dispatch({ type: 'CONNECT_SUCCESS' }));
_api.on('error', (err) => dispatch({ type: 'CONNECT_ERROR', payload: err }));
};

const defaultValue = {
state: initialState,
};

const RelayApiContext = React.createContext(defaultValue);

const RelayApiContextProvider = (props: any) => {
const [state, dispatch] = useReducer(reducer, initialState);
const { toastError, toastSuccess } = useToast();

useEffect(() => {
state.apiError &&
toastError(
`Failed to connect to relay chain: error = ${state.apiError.toString()}`
);
}, [state.apiError]);

useEffect(() => {
state.apiState === 'READY' &&
toastSuccess('Successfully connected to relay chain');
}, [state.apiState]);

useEffect(() => {
connect(state, dispatch);
}, [process.env.RELAY_CHAIN_ENDPOINT]);

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

export { RelayApiContextProvider, useRelayApi };
29 changes: 22 additions & 7 deletions src/contracts/identity/context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ interface IdentityContract {
contract: ContractPromise | undefined;
fetchIdentityNo: () => Promise<void>;
fetchAddresses: () => Promise<void>;
getAddresses: (_id: number) => Promise<Address[]>;
loading: boolean;
}

Expand All @@ -49,6 +50,9 @@ const defaultIdentity: IdentityContract = {
fetchAddresses: async () => {
/* */
},
getAddresses: async (): Promise<Address[]> => {
return [];
},
loading: true,
};

Expand Down Expand Up @@ -165,14 +169,11 @@ const IdentityContractProvider = ({ children }: Props) => {
setLoadingChains(false);
}, [api, contract, toastError]);

const fetchAddresses = useCallback(async () => {
if (!api || !contract || identityNo === null) {
setAddresses([]);
return;
}
const getAddresses = async (no: number): Promise<Address[]> => {
if (!api || !contract) return [];
try {
const result = await contractQuery(api, '', contract, 'identity', {}, [
identityNo,
no,
]);
const { output, isError, decodedOutput } = decodeOutput(
result,
Expand All @@ -191,8 +192,21 @@ const IdentityContractProvider = ({ children }: Props) => {
address,
});
}
setAddresses(_addresses);
return _addresses;
} catch (e) {
return [];
}
};

const fetchAddresses = useCallback(async () => {
if (!api || !contract || identityNo === null) {
setAddresses([]);
return;
}
try {
const _addresses = await getAddresses(identityNo);
setAddresses(_addresses);
} catch {
setAddresses([]);
}
}, [api, contract, identityNo]);
Expand All @@ -218,6 +232,7 @@ const IdentityContractProvider = ({ children }: Props) => {
chains,
fetchAddresses,
fetchIdentityNo,
getAddresses,
loading: loadingIdentityNo || loadingChains,
}}
>
Expand Down
33 changes: 17 additions & 16 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import theme from '@/utils/muiTheme';

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

import { RelayApiContextProvider } from '@/contexts/RelayApi';
import { ToastProvider } from '@/contexts/Toast';
import { IdentityContractProvider } from '@/contracts';
import { AddressBookContractProvider } from '@/contracts/addressbook/context';
Expand Down Expand Up @@ -42,29 +43,29 @@ export default function MyApp(props: MyAppProps) {
{/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
<CssBaseline />
<ToastProvider>
<UseInkathonProvider
appName='DotFlow UI'
connectOnInit={false}
defaultChain={
{
<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>
}}
>
<IdentityContractProvider>
<AddressBookContractProvider>
<ConfirmProvider>
{getLayout(<Component {...pageProps} />)}
</ConfirmProvider>
</AddressBookContractProvider>
</IdentityContractProvider>
</UseInkathonProvider>
</RelayApiContextProvider>
</ToastProvider>
</ThemeProvider>
</CacheProvider>
Expand Down
10 changes: 2 additions & 8 deletions src/pages/identity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
Grid,
Typography,
} from '@mui/material';
import styles from '@styles/pages/identity.module.scss';
import { useState } from 'react';

import { CreateIdentity, RemoveIdentity } from '@/components/Buttons';
Expand All @@ -34,14 +35,7 @@ const IdentityPage = () => {

return (
<>
<Box
sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
marginBottom: '32px',
}}
>
<Box className={styles.identityContainer}>
<Typography variant='h4' fontWeight={700}>
My Identity
</Typography>
Expand Down
Loading