From 539e2afc830868643578009014ab743647f43db4 Mon Sep 17 00:00:00 2001 From: Sergej Date: Sat, 11 May 2024 14:03:23 +0200 Subject: [PATCH 1/6] Cross-chain region transfers --- .env.example | 1 + next.config.js | 1 + src/contexts/apis/consts.ts | 1 + src/pages/transfer.tsx | 26 +++++++++++++++ src/utils/transfers/crossChain/index.ts | 13 +++++--- src/utils/transfers/crossChain/utils.ts | 42 ++++++++++++++----------- 6 files changed, 61 insertions(+), 23 deletions(-) diff --git a/.env.example b/.env.example index 30aa77da..dc3a855d 100644 --- a/.env.example +++ b/.env.example @@ -2,3 +2,4 @@ WS_ROCOCO_CORETIME_CHAIN="WSS endpoint of the coretime chain" WS_KUSAMA_CORETIME_CHAIN="WSS endpoint of the coretime chain" WS_ROCOCO_RELAY_CHAIN="WSS endpoint of the coretime relay chain" WS_KUSAMA_RELAY_CHAIN="WSS endpoint of the coretime relay chain" +EXPERIMENTAL=false diff --git a/next.config.js b/next.config.js index 5ab342eb..3d316ce2 100644 --- a/next.config.js +++ b/next.config.js @@ -9,6 +9,7 @@ const nextConfig = { WS_KUSAMA_CORETIME_CHAIN: process.env.WS_KUSAMA_CORETIME_CHAIN || '', WS_ROCOCO_RELAY_CHAIN: process.env.WS_ROCOCO_RELAY_CHAIN, WS_KUSAMA_RELAY_CHAIN: process.env.WS_KUSAMA_RELAY_CHAIN, + EXPERIMENTAL: process.env.EXPERIMENTAL, }, }; diff --git a/src/contexts/apis/consts.ts b/src/contexts/apis/consts.ts index ca7da40b..aeab8821 100644 --- a/src/contexts/apis/consts.ts +++ b/src/contexts/apis/consts.ts @@ -4,3 +4,4 @@ export const WS_ROCOCO_CORETIME_CHAIN = process.env.WS_ROCOCO_CORETIME_CHAIN ?? ''; export const WS_KUSAMA_CORETIME_CHAIN = process.env.WS_KUSAMA_CORETIME_CHAIN ?? ''; +export const EXPERIMENTAL = process.env.EXPERIMENTAL ?? false; diff --git a/src/pages/transfer.tsx b/src/pages/transfer.tsx index c7fb1cca..1a64ff7e 100644 --- a/src/pages/transfer.tsx +++ b/src/pages/transfer.tsx @@ -6,6 +6,7 @@ import { useEffect, useState } from 'react'; import theme from '@/utils/muiTheme'; import { + coretimeToRegionXTransfer, transferTokensFromCoretimeToRelay, transferTokensFromRelayToCoretime, } from '@/utils/transfers/crossChain'; @@ -38,6 +39,7 @@ import { RegionLocation, RegionMetadata, } from '@/models'; +import { EXPERIMENTAL } from '@/contexts/apis/consts'; const TransferPage = () => { const { @@ -165,15 +167,39 @@ const TransferPage = () => { }; const handleRegionTransfer = async () => { + if (!activeAccount || !activeSigner) return; if (!selectedRegion) { toastError('Select a region'); return; } + if (!coretimeApi || coretimeApiState !== ApiState.READY) { + toastError('Not connected to the Coretime chain'); + return; + } + if (originChain === destinationChain) { originChain === ChainType.CORETIME ? await transferCoretimeRegion(selectedRegion.region) : toastWarning('Currently not supported'); + } else if ( + originChain === ChainType.CORETIME && + destinationChain === ChainType.REGIONX + ) { + if (!EXPERIMENTAL) toastWarning('Currently not supported'); + else { + const receiverKeypair = new Keyring(); + receiverKeypair.addFromAddress( + newOwner ? newOwner : activeAccount.address + ); + coretimeToRegionXTransfer( + coretimeApi, + { address: activeAccount.address, signer: activeSigner }, + selectedRegion.rawId, + receiverKeypair.pairs[0].publicKey, + defaultHandler + ); + } } else { toastWarning('Currently not supported'); } diff --git a/src/utils/transfers/crossChain/index.ts b/src/utils/transfers/crossChain/index.ts index 9dc4f3c1..98d7f7e4 100644 --- a/src/utils/transfers/crossChain/index.ts +++ b/src/utils/transfers/crossChain/index.ts @@ -14,6 +14,8 @@ import { RelayChainFromParachainPerspective, } from './consts'; import { + fungibleAsset, + nonFungibleAsset, versionWrap, versionWrappeddFungibleAsset, versionWrappeddNonfungibleAsset, @@ -46,10 +48,13 @@ export async function coretimeToRegionXTransfer( coretimeApi.tx.polkadotXcm.limitedReserveTransferAssets( versionWrap(RegionXChain), versionWrap(beneficiary), - versionWrappeddNonfungibleAsset( - CoretimeRegionFromCoretimePerspective, - rawRegionId.toString() - ), + versionWrap([ + fungibleAsset(RcTokenFromParachainPerspective, '2500000000'), // Fee payment asset + nonFungibleAsset( + CoretimeRegionFromCoretimePerspective, + rawRegionId.toString() + ), + ]), feeAssetItem, weightLimit ); diff --git a/src/utils/transfers/crossChain/utils.ts b/src/utils/transfers/crossChain/utils.ts index dbc76f28..f6d94c3c 100644 --- a/src/utils/transfers/crossChain/utils.ts +++ b/src/utils/transfers/crossChain/utils.ts @@ -10,32 +10,36 @@ export const versionWrappeddNonfungibleAsset = ( assetLocation: any, index: string ) => { - return versionWrap([ - { - id: { - Concrete: assetLocation, - }, - fun: { - NonFungible: { - Index: index, - }, + return versionWrap([nonFungibleAsset(assetLocation, index)]); +}; + +export const nonFungibleAsset = (assetLocation: any, index: string) => { + return { + id: { + Concrete: assetLocation, + }, + fun: { + NonFungible: { + Index: index, }, }, - ]); + }; }; export const versionWrappeddFungibleAsset = ( assetLocation: any, amount: string ) => { - return versionWrap([ - { - id: { - Concrete: assetLocation, - }, - fun: { - Fungible: amount, - }, + return versionWrap([fungibleAsset(assetLocation, amount)]); +}; + +export const fungibleAsset = (assetLocation: any, amount: string) => { + return { + id: { + Concrete: assetLocation, + }, + fun: { + Fungible: amount, }, - ]); + }; }; From fb6983801ea8fdefc156e52aadce5756a21bdee6 Mon Sep 17 00:00:00 2001 From: Sergej Date: Sat, 11 May 2024 17:25:51 +0200 Subject: [PATCH 2/6] both directions work --- .env.example | 1 + next.config.js | 1 + src/contexts/apis/RegionXApi/index.tsx | 78 +++++++++++++++++++++++++ src/contexts/apis/consts.ts | 2 + src/contexts/regions/index.tsx | 17 +++++- src/contexts/regions/regionx/index.ts | 63 ++++++++++++++++++++ src/contexts/tasks/index.tsx | 1 + src/pages/_app.tsx | 33 ++++++----- src/pages/transfer.tsx | 32 +++++++++- src/utils/transfers/crossChain/index.ts | 25 ++++---- src/utils/transfers/crossChain/utils.ts | 14 ----- 11 files changed, 220 insertions(+), 47 deletions(-) create mode 100644 src/contexts/apis/RegionXApi/index.tsx create mode 100644 src/contexts/regions/regionx/index.ts diff --git a/.env.example b/.env.example index dc3a855d..42c27797 100644 --- a/.env.example +++ b/.env.example @@ -2,4 +2,5 @@ WS_ROCOCO_CORETIME_CHAIN="WSS endpoint of the coretime chain" WS_KUSAMA_CORETIME_CHAIN="WSS endpoint of the coretime chain" WS_ROCOCO_RELAY_CHAIN="WSS endpoint of the coretime relay chain" WS_KUSAMA_RELAY_CHAIN="WSS endpoint of the coretime relay chain" +WS_KUSAMA_REGIONX_CHAIN="WSS endpoint of the regionx chain" EXPERIMENTAL=false diff --git a/next.config.js b/next.config.js index 3d316ce2..5309f2f6 100644 --- a/next.config.js +++ b/next.config.js @@ -7,6 +7,7 @@ const nextConfig = { env: { WS_ROCOCO_CORETIME_CHAIN: process.env.WS_ROCOCO_CORETIME_CHAIN || '', WS_KUSAMA_CORETIME_CHAIN: process.env.WS_KUSAMA_CORETIME_CHAIN || '', + WS_KUSAMA_REGIONX_CHAIN: process.env.WS_KUSAMA_REGIONX_CHAIN || '', WS_ROCOCO_RELAY_CHAIN: process.env.WS_ROCOCO_RELAY_CHAIN, WS_KUSAMA_RELAY_CHAIN: process.env.WS_KUSAMA_RELAY_CHAIN, EXPERIMENTAL: process.env.EXPERIMENTAL, diff --git a/src/contexts/apis/RegionXApi/index.tsx b/src/contexts/apis/RegionXApi/index.tsx new file mode 100644 index 00000000..d31913d9 --- /dev/null +++ b/src/contexts/apis/RegionXApi/index.tsx @@ -0,0 +1,78 @@ +import React, { useContext, useEffect, useReducer } from 'react'; + +import { ApiState } from '@/contexts/apis/types'; +import { useNetwork } from '@/contexts/network'; +import { useToast } from '@/contexts/toast'; +import { NetworkType } from '@/models'; + +import { connect, disconnect, initialState, reducer } from '../common'; +import { WS_KUSAMA_REGIONX_CHAIN, WS_ROCOCO_CORETIME_CHAIN } from '../consts'; + +const types = { + CoreIndex: 'u32', + CoreMask: 'Vec', + Timeslice: 'u32', + RegionId: { + begin: 'Timeslice', + core: 'CoreIndex', + mask: 'CoreMask', + }, + RegionRecord: { + end: 'Timeslice', + owner: 'AccountId', + paid: 'Option', + }, +}; + +const defaultValue = { + state: { ...initialState }, + disconnectRegionX: (): void => { + /** */ + }, +}; + +const RegionXApiContext = React.createContext(defaultValue); + +const RegionXApiContextProvider = (props: any) => { + const [state, dispatch] = useReducer(reducer, initialState); + const { toastError, toastSuccess } = useToast(); + + const { network } = useNetwork(); + + useEffect(() => { + state.apiError && toastError(`Failed to connect to RegionX chain`); + }, [state.apiError, toastError]); + + useEffect(() => { + state.apiState === ApiState.READY && + state.name && + toastSuccess(`Successfully connected to ${state.name}`); + }, [state.apiState, state.name, toastSuccess]); + + const getUrl = (network: any): string => { + return network === NetworkType.ROCOCO + ? WS_ROCOCO_CORETIME_CHAIN // TODO + : WS_KUSAMA_REGIONX_CHAIN; + }; + + const disconnectRegionX = () => disconnect(state); + + useEffect(() => { + if (network === NetworkType.NONE || state.socket == getUrl(network)) return; + const updateNetwork = state.socket != getUrl(network); + if (updateNetwork) { + disconnectRegionX(); + connect(state, getUrl(network), dispatch, updateNetwork, types); + } + }, [network, state]); + + return ( + + {props.children} + + ); +}; + +const useRegionXApi = () => useContext(RegionXApiContext); + +export { RegionXApiContextProvider, useRegionXApi }; diff --git a/src/contexts/apis/consts.ts b/src/contexts/apis/consts.ts index aeab8821..2a939769 100644 --- a/src/contexts/apis/consts.ts +++ b/src/contexts/apis/consts.ts @@ -4,4 +4,6 @@ export const WS_ROCOCO_CORETIME_CHAIN = process.env.WS_ROCOCO_CORETIME_CHAIN ?? ''; export const WS_KUSAMA_CORETIME_CHAIN = process.env.WS_KUSAMA_CORETIME_CHAIN ?? ''; +export const WS_KUSAMA_REGIONX_CHAIN = + process.env.WS_KUSAMA_REGIONX_CHAIN ?? ''; export const EXPERIMENTAL = process.env.EXPERIMENTAL ?? false; diff --git a/src/contexts/regions/index.tsx b/src/contexts/regions/index.tsx index b8950732..79ef8952 100644 --- a/src/contexts/regions/index.tsx +++ b/src/contexts/regions/index.tsx @@ -15,8 +15,10 @@ import React, { import { RegionLocation, RegionMetadata } from '@/models'; import * as NativeRegions from './native'; +import * as RegionXRegions from './regionx'; import { useAccounts } from '../account'; import { useCoretimeApi } from '../apis'; +import { useRegionXApi } from '../apis/RegionXApi'; import { useCommon } from '../common'; import { useTasks } from '../tasks'; @@ -51,6 +53,9 @@ const RegionDataProvider = ({ children }: Props) => { const { state: { api: coretimeApi }, } = useCoretimeApi(); + const { + state: { api: regionxApi }, + } = useRegionXApi(); const { state: { activeAccount }, } = useAccounts(); @@ -80,10 +85,11 @@ const RegionDataProvider = ({ children }: Props) => { const tasks = await fetchWorkplan(); const brokerRegions = await NativeRegions.fetchRegions(coretimeApi); + const regionxRegions = await RegionXRegions.fetchRegions(regionxApi); // TODO const _regions: Array = []; - for await (const region of [...brokerRegions]) { + for await (const region of [...brokerRegions, ...regionxRegions]) { // Only user owned non-expired regions. if ( region.getOwner() !== activeAccount.address || @@ -95,7 +101,14 @@ const RegionDataProvider = ({ children }: Props) => { region.getRegionId(), coretimeApi ).toString(); - const location = RegionLocation.CORETIME_CHAIN; + const location = brokerRegions.find( + (r) => + JSON.stringify(r.getRegionId()) === + JSON.stringify(region.getRegionId()) && + r.getOwner() === region.getOwner() + ) + ? RegionLocation.CORETIME_CHAIN + : RegionLocation.REGIONX_CHAIN; const name = localStorage.getItem(`region-${rawId}`) ?? diff --git a/src/contexts/regions/regionx/index.ts b/src/contexts/regions/regionx/index.ts new file mode 100644 index 00000000..039efc66 --- /dev/null +++ b/src/contexts/regions/regionx/index.ts @@ -0,0 +1,63 @@ +import { ApiPromise } from '@polkadot/api'; +import { Region, RegionId } from 'coretime-utils'; + +import { parseHNString } from '@/utils/functions'; + +export const fetchRegions = async ( + regionxApi: ApiPromise | null +): Promise> => { + if (!regionxApi) { + return []; + } + try { + const regionEntries = await regionxApi.query.regions.regions.entries(); + + const regions: Array = regionEntries + .map(([key, value]) => { + const keyTuple: any = key.toHuman(undefined, true); + const { begin, core, mask } = keyTuple[0] as any; + const { owner, record: _record } = value.toHuman() as any; + + const regionId = { + begin: parseHNString(begin.toString()), + core: parseHNString(core.toString()), + mask: mask, + }; + return new Region( + regionId, + /*dummy data*/ { + end: 0, + owner, + paid: null, + } + ); + }) + .filter((entry) => !!entry) as Array; + return regions; + } catch (_) { + return []; + } +}; + +export const fetchRegion = async ( + regionxApi: ApiPromise | null, + regionId: RegionId +): Promise => { + if (!regionxApi) return null; + + const record: any = ( + await regionxApi.query.regions.regions(regionId) + ).toHuman(); + + if (record) { + const { end, owner, paid } = record; + + return new Region(regionId, { + end: parseHNString(end), + owner, + paid: paid ? parseHNString(paid) : null, + }); + } else { + return null; + } +}; diff --git a/src/contexts/tasks/index.tsx b/src/contexts/tasks/index.tsx index 1d5462ff..97050666 100644 --- a/src/contexts/tasks/index.tsx +++ b/src/contexts/tasks/index.tsx @@ -106,6 +106,7 @@ const TaskDataProvider = ({ children }: Props) => { ).toHuman() as ScheduleItem[] )[0]; + if (!workload) return null; if (workload.assignment === 'Pool') { return POOLING_TASK_ID; } else { diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 856081ae..52b351b5 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -18,6 +18,7 @@ import { CoretimeApiContextProvider, RelayApiContextProvider, } from '@/contexts/apis'; +import { RegionXApiContextProvider } from '@/contexts/apis/RegionXApi'; import { BalanceProvider } from '@/contexts/balance'; import { ContextDataProvider } from '@/contexts/common'; import { MarketProvider } from '@/contexts/market'; @@ -53,21 +54,23 @@ export default function MyApp(props: MyAppProps) { - - - - - - - - {getLayout()} - - - - - - - + + + + + + + + + {getLayout()} + + + + + + + + diff --git a/src/pages/transfer.tsx b/src/pages/transfer.tsx index 1a64ff7e..ff44c8ac 100644 --- a/src/pages/transfer.tsx +++ b/src/pages/transfer.tsx @@ -6,6 +6,7 @@ import { useEffect, useState } from 'react'; import theme from '@/utils/muiTheme'; import { + coretimeFromRegionXTransfer, coretimeToRegionXTransfer, transferTokensFromCoretimeToRelay, transferTokensFromRelayToCoretime, @@ -28,6 +29,8 @@ import AssetSelector from '@/components/Elements/Selectors/AssetSelector'; import { useAccounts } from '@/contexts/account'; import { useCoretimeApi, useRelayApi } from '@/contexts/apis'; +import { EXPERIMENTAL } from '@/contexts/apis/consts'; +import { useRegionXApi } from '@/contexts/apis/RegionXApi'; import { ApiState } from '@/contexts/apis/types'; import { useBalances } from '@/contexts/balance'; import { useRegions } from '@/contexts/regions'; @@ -39,7 +42,6 @@ import { RegionLocation, RegionMetadata, } from '@/models'; -import { EXPERIMENTAL } from '@/contexts/apis/consts'; const TransferPage = () => { const { @@ -50,6 +52,9 @@ const TransferPage = () => { const { state: { api: coretimeApi, apiState: coretimeApiState, symbol }, } = useCoretimeApi(); + const { + state: { api: regionxApi, apiState: regionxApiState }, + } = useRegionXApi(); const { state: { api: relayApi, apiState: relayApiState }, } = useRelayApi(); @@ -173,7 +178,12 @@ const TransferPage = () => { return; } - if (!coretimeApi || coretimeApiState !== ApiState.READY) { + if ( + !coretimeApi || + coretimeApiState !== ApiState.READY || + !regionxApi || + regionxApiState !== ApiState.READY + ) { toastError('Not connected to the Coretime chain'); return; } @@ -200,6 +210,24 @@ const TransferPage = () => { defaultHandler ); } + } else if ( + originChain === ChainType.REGIONX && + destinationChain === ChainType.CORETIME + ) { + if (!EXPERIMENTAL) toastWarning('Currently not supported'); + else { + const receiverKeypair = new Keyring(); + receiverKeypair.addFromAddress( + newOwner ? newOwner : activeAccount.address + ); + coretimeFromRegionXTransfer( + regionxApi, + { address: activeAccount.address, signer: activeSigner }, + selectedRegion.rawId, + receiverKeypair.pairs[0].publicKey, + defaultHandler + ); + } } else { toastWarning('Currently not supported'); } diff --git a/src/utils/transfers/crossChain/index.ts b/src/utils/transfers/crossChain/index.ts index 98d7f7e4..774a0baa 100644 --- a/src/utils/transfers/crossChain/index.ts +++ b/src/utils/transfers/crossChain/index.ts @@ -13,13 +13,7 @@ import { RegionXChain, RelayChainFromParachainPerspective, } from './consts'; -import { - fungibleAsset, - nonFungibleAsset, - versionWrap, - versionWrappeddFungibleAsset, - versionWrappeddNonfungibleAsset, -} from './utils'; +import { fungibleAsset, nonFungibleAsset, versionWrap } from './utils'; import { sendTx } from '../../functions'; export async function coretimeToRegionXTransfer( @@ -63,7 +57,7 @@ export async function coretimeToRegionXTransfer( sendTx(reserveTransfer, address, signer, handlers); } -export function regionXToCoretimeTransfer( +export function coretimeFromRegionXTransfer( api: ApiPromise, sender: Sender, rawRegionId: BN, @@ -88,10 +82,13 @@ export function regionXToCoretimeTransfer( const reserveTransfer = api.tx.polkadotXcm.limitedReserveTransferAssets( versionWrap(CoretimeChain), versionWrap(beneficiary), - versionWrappeddNonfungibleAsset( - CoretimeRegionFromRegionXPerspective, - rawRegionId.toString() - ), + versionWrap([ + fungibleAsset(RcTokenFromParachainPerspective, '2500000000'), // Fee payment asset + nonFungibleAsset( + CoretimeRegionFromRegionXPerspective, + rawRegionId.toString() + ), + ]), feeAssetItem, weightLimit ); @@ -125,7 +122,7 @@ export function transferTokensFromCoretimeToRelay( const teleportTransfer = coretimeApi.tx.polkadotXcm.limitedTeleportAssets( versionWrap(RelayChainFromParachainPerspective), versionWrap(beneficiary), - versionWrappeddFungibleAsset(RcTokenFromParachainPerspective, amount), + versionWrap([fungibleAsset(RcTokenFromParachainPerspective, amount)]), feeAssetItem, weightLimit ); @@ -160,7 +157,7 @@ export function transferTokensFromRelayToCoretime( const teleportTransfer = coretimeApi.tx.xcmPallet.limitedTeleportAssets( versionWrap(CoretimeChainFromRelayPerspective), versionWrap(beneficiary), - versionWrappeddFungibleAsset(RcTokenFromRelayPerspective, amount), + versionWrap([fungibleAsset(RcTokenFromRelayPerspective, amount)]), feeAssetItem, weightLimit ); diff --git a/src/utils/transfers/crossChain/utils.ts b/src/utils/transfers/crossChain/utils.ts index f6d94c3c..447468fc 100644 --- a/src/utils/transfers/crossChain/utils.ts +++ b/src/utils/transfers/crossChain/utils.ts @@ -6,13 +6,6 @@ export const versionWrap = (xcm: any) => { }; }; -export const versionWrappeddNonfungibleAsset = ( - assetLocation: any, - index: string -) => { - return versionWrap([nonFungibleAsset(assetLocation, index)]); -}; - export const nonFungibleAsset = (assetLocation: any, index: string) => { return { id: { @@ -26,13 +19,6 @@ export const nonFungibleAsset = (assetLocation: any, index: string) => { }; }; -export const versionWrappeddFungibleAsset = ( - assetLocation: any, - amount: string -) => { - return versionWrap([fungibleAsset(assetLocation, amount)]); -}; - export const fungibleAsset = (assetLocation: any, amount: string) => { return { id: { From b1c66d055783df7a4a76ffc4f1d9e3a4e011df6b Mon Sep 17 00:00:00 2001 From: Sergej Date: Sun, 12 May 2024 09:16:59 +0200 Subject: [PATCH 3/6] conditional --- src/components/Sidebar/index.tsx | 8 ++++++ src/contexts/apis/consts.ts | 2 +- src/contexts/regions/index.tsx | 14 +++++++---- src/pages/_app.tsx | 43 +++++++++++++++++++------------- 4 files changed, 44 insertions(+), 23 deletions(-) diff --git a/src/components/Sidebar/index.tsx b/src/components/Sidebar/index.tsx index c8a84ec3..3296f34a 100644 --- a/src/components/Sidebar/index.tsx +++ b/src/components/Sidebar/index.tsx @@ -11,6 +11,8 @@ import React from 'react'; import Logo from '@/assets/logo.png'; import { useCoretimeApi, useRelayApi } from '@/contexts/apis'; +import { EXPERIMENTAL } from '@/contexts/apis/consts'; +import { useRegionXApi } from '@/contexts/apis/RegionXApi'; import { RenewIcon } from '@/icons'; import styles from './index.module.scss'; @@ -76,6 +78,9 @@ export const Sidebar = () => { const { state: { apiState: coretimeApiState }, } = useCoretimeApi(); + const { + state: { apiState: regionxApiState }, + } = useRegionXApi(); const menu = { general: [ @@ -175,6 +180,9 @@ export const Sidebar = () => {
+ {EXPERIMENTAL && ( + + )}
diff --git a/src/contexts/apis/consts.ts b/src/contexts/apis/consts.ts index 2a939769..02b046d2 100644 --- a/src/contexts/apis/consts.ts +++ b/src/contexts/apis/consts.ts @@ -6,4 +6,4 @@ export const WS_KUSAMA_CORETIME_CHAIN = process.env.WS_KUSAMA_CORETIME_CHAIN ?? ''; export const WS_KUSAMA_REGIONX_CHAIN = process.env.WS_KUSAMA_REGIONX_CHAIN ?? ''; -export const EXPERIMENTAL = process.env.EXPERIMENTAL ?? false; +export const EXPERIMENTAL = process.env.EXPERIMENTAL == 'true' ? true : false; diff --git a/src/contexts/regions/index.tsx b/src/contexts/regions/index.tsx index 79ef8952..8e5b4465 100644 --- a/src/contexts/regions/index.tsx +++ b/src/contexts/regions/index.tsx @@ -18,6 +18,7 @@ import * as NativeRegions from './native'; import * as RegionXRegions from './regionx'; import { useAccounts } from '../account'; import { useCoretimeApi } from '../apis'; +import { EXPERIMENTAL } from '../apis/consts'; import { useRegionXApi } from '../apis/RegionXApi'; import { useCommon } from '../common'; import { useTasks } from '../tasks'; @@ -85,7 +86,9 @@ const RegionDataProvider = ({ children }: Props) => { const tasks = await fetchWorkplan(); const brokerRegions = await NativeRegions.fetchRegions(coretimeApi); - const regionxRegions = await RegionXRegions.fetchRegions(regionxApi); // TODO + const regionxRegions = EXPERIMENTAL + ? await RegionXRegions.fetchRegions(regionxApi) + : []; const _regions: Array = []; @@ -97,10 +100,6 @@ const RegionDataProvider = ({ children }: Props) => { ) continue; - const rawId = getEncodedRegionId( - region.getRegionId(), - coretimeApi - ).toString(); const location = brokerRegions.find( (r) => JSON.stringify(r.getRegionId()) === @@ -110,6 +109,11 @@ const RegionDataProvider = ({ children }: Props) => { ? RegionLocation.CORETIME_CHAIN : RegionLocation.REGIONX_CHAIN; + const rawId = getEncodedRegionId( + region.getRegionId(), + location === RegionLocation.CORETIME_CHAIN ? coretimeApi : regionxApi + ).toString(); + const name = localStorage.getItem(`region-${rawId}`) ?? `Region #${_regions.length + 1}`; diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 52b351b5..593fba53 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -18,6 +18,7 @@ import { CoretimeApiContextProvider, RelayApiContextProvider, } from '@/contexts/apis'; +import { EXPERIMENTAL } from '@/contexts/apis/consts'; import { RegionXApiContextProvider } from '@/contexts/apis/RegionXApi'; import { BalanceProvider } from '@/contexts/balance'; import { ContextDataProvider } from '@/contexts/common'; @@ -42,6 +43,24 @@ export default function MyApp(props: MyAppProps) { const { Component, emotionCache = clientSideEmotionCache, pageProps } = props; const getLayout = Component.getLayout ?? ((page) => {page}); + const Content = ( + + + + + + + + {getLayout()} + + + + + + + + ); + return ( @@ -54,23 +73,13 @@ export default function MyApp(props: MyAppProps) { - - - - - - - - - {getLayout()} - - - - - - - - + {EXPERIMENTAL ? ( + + {Content} + + ) : ( + <>{Content} + )} From cbd2daa15462e02379927e177de783abfa422400 Mon Sep 17 00:00:00 2001 From: Sergej Date: Sun, 12 May 2024 09:41:55 +0200 Subject: [PATCH 4/6] remove unused --- src/contexts/regions/index.tsx | 13 +------------ src/contexts/regions/native/index.ts | 25 +------------------------ src/contexts/regions/regionx/index.ts | 25 +------------------------ 3 files changed, 3 insertions(+), 60 deletions(-) diff --git a/src/contexts/regions/index.tsx b/src/contexts/regions/index.tsx index 8e5b4465..0fd8a295 100644 --- a/src/contexts/regions/index.tsx +++ b/src/contexts/regions/index.tsx @@ -1,9 +1,4 @@ -import { - CoreIndex, - getEncodedRegionId, - Region, - RegionId, -} from 'coretime-utils'; +import { CoreIndex, getEncodedRegionId } from 'coretime-utils'; import React, { createContext, useCallback, @@ -28,7 +23,6 @@ interface RegionsData { loading: boolean; updateRegionName: (_index: number, _name: string) => void; fetchRegions: () => Promise; - fetchRegion: (_regionId: RegionId) => Promise; } const defaultRegionData: RegionsData = { regions: [], @@ -39,9 +33,6 @@ const defaultRegionData: RegionsData = { fetchRegions: async () => { /** */ }, - fetchRegion: async () => { - return null; - }, }; const RegionDataContext = createContext(defaultRegionData); @@ -170,8 +161,6 @@ const RegionDataProvider = ({ children }: Props) => { loading, updateRegionName, fetchRegions, - fetchRegion: (_r: RegionId) => - NativeRegions.fetchRegion(coretimeApi, _r), }} > {children} diff --git a/src/contexts/regions/native/index.ts b/src/contexts/regions/native/index.ts index 353048b3..af8a06f4 100644 --- a/src/contexts/regions/native/index.ts +++ b/src/contexts/regions/native/index.ts @@ -1,5 +1,5 @@ import { ApiPromise } from '@polkadot/api'; -import { Region, RegionId } from 'coretime-utils'; +import { Region } from 'coretime-utils'; import { parseHNString } from '@/utils/functions'; @@ -35,26 +35,3 @@ export const fetchRegions = async ( return []; } }; - -export const fetchRegion = async ( - coretimeApi: ApiPromise | null, - regionId: RegionId -): Promise => { - if (!coretimeApi) return null; - - const record: any = ( - await coretimeApi.query.broker.regions(regionId) - ).toHuman(); - - if (record) { - const { end, owner, paid } = record; - - return new Region(regionId, { - end: parseHNString(end), - owner, - paid: paid ? parseHNString(paid) : null, - }); - } else { - return null; - } -}; diff --git a/src/contexts/regions/regionx/index.ts b/src/contexts/regions/regionx/index.ts index 039efc66..3fe2a13c 100644 --- a/src/contexts/regions/regionx/index.ts +++ b/src/contexts/regions/regionx/index.ts @@ -1,5 +1,5 @@ import { ApiPromise } from '@polkadot/api'; -import { Region, RegionId } from 'coretime-utils'; +import { Region } from 'coretime-utils'; import { parseHNString } from '@/utils/functions'; @@ -38,26 +38,3 @@ export const fetchRegions = async ( return []; } }; - -export const fetchRegion = async ( - regionxApi: ApiPromise | null, - regionId: RegionId -): Promise => { - if (!regionxApi) return null; - - const record: any = ( - await regionxApi.query.regions.regions(regionId) - ).toHuman(); - - if (record) { - const { end, owner, paid } = record; - - return new Region(regionId, { - end: parseHNString(end), - owner, - paid: paid ? parseHNString(paid) : null, - }); - } else { - return null; - } -}; From e07cb1cf23da2e058766c6888d7d33a306d17575 Mon Sep 17 00:00:00 2001 From: Sergej Date: Sun, 12 May 2024 14:56:02 +0200 Subject: [PATCH 5/6] remove network specific url for now --- .env.example | 2 +- next.config.js | 2 +- src/contexts/apis/RegionXApi/index.tsx | 25 +++++++------------------ src/contexts/apis/consts.ts | 3 +-- 4 files changed, 10 insertions(+), 22 deletions(-) diff --git a/.env.example b/.env.example index 42c27797..8f8f8543 100644 --- a/.env.example +++ b/.env.example @@ -2,5 +2,5 @@ WS_ROCOCO_CORETIME_CHAIN="WSS endpoint of the coretime chain" WS_KUSAMA_CORETIME_CHAIN="WSS endpoint of the coretime chain" WS_ROCOCO_RELAY_CHAIN="WSS endpoint of the coretime relay chain" WS_KUSAMA_RELAY_CHAIN="WSS endpoint of the coretime relay chain" -WS_KUSAMA_REGIONX_CHAIN="WSS endpoint of the regionx chain" +WS_REGIONX_CHAIN="WSS endpoint of the regionx chain" EXPERIMENTAL=false diff --git a/next.config.js b/next.config.js index 5309f2f6..b4e24b4e 100644 --- a/next.config.js +++ b/next.config.js @@ -7,7 +7,7 @@ const nextConfig = { env: { WS_ROCOCO_CORETIME_CHAIN: process.env.WS_ROCOCO_CORETIME_CHAIN || '', WS_KUSAMA_CORETIME_CHAIN: process.env.WS_KUSAMA_CORETIME_CHAIN || '', - WS_KUSAMA_REGIONX_CHAIN: process.env.WS_KUSAMA_REGIONX_CHAIN || '', + WS_REGIONX_CHAIN: process.env.WS_REGIONX_CHAIN || '', WS_ROCOCO_RELAY_CHAIN: process.env.WS_ROCOCO_RELAY_CHAIN, WS_KUSAMA_RELAY_CHAIN: process.env.WS_KUSAMA_RELAY_CHAIN, EXPERIMENTAL: process.env.EXPERIMENTAL, diff --git a/src/contexts/apis/RegionXApi/index.tsx b/src/contexts/apis/RegionXApi/index.tsx index d31913d9..039458e5 100644 --- a/src/contexts/apis/RegionXApi/index.tsx +++ b/src/contexts/apis/RegionXApi/index.tsx @@ -1,12 +1,10 @@ import React, { useContext, useEffect, useReducer } from 'react'; import { ApiState } from '@/contexts/apis/types'; -import { useNetwork } from '@/contexts/network'; import { useToast } from '@/contexts/toast'; -import { NetworkType } from '@/models'; import { connect, disconnect, initialState, reducer } from '../common'; -import { WS_KUSAMA_REGIONX_CHAIN, WS_ROCOCO_CORETIME_CHAIN } from '../consts'; +import { WS_REGIONX_CHAIN } from '../consts'; const types = { CoreIndex: 'u32', @@ -37,8 +35,6 @@ const RegionXApiContextProvider = (props: any) => { const [state, dispatch] = useReducer(reducer, initialState); const { toastError, toastSuccess } = useToast(); - const { network } = useNetwork(); - useEffect(() => { state.apiError && toastError(`Failed to connect to RegionX chain`); }, [state.apiError, toastError]); @@ -49,22 +45,15 @@ const RegionXApiContextProvider = (props: any) => { toastSuccess(`Successfully connected to ${state.name}`); }, [state.apiState, state.name, toastSuccess]); - const getUrl = (network: any): string => { - return network === NetworkType.ROCOCO - ? WS_ROCOCO_CORETIME_CHAIN // TODO - : WS_KUSAMA_REGIONX_CHAIN; - }; - const disconnectRegionX = () => disconnect(state); useEffect(() => { - if (network === NetworkType.NONE || state.socket == getUrl(network)) return; - const updateNetwork = state.socket != getUrl(network); - if (updateNetwork) { - disconnectRegionX(); - connect(state, getUrl(network), dispatch, updateNetwork, types); - } - }, [network, state]); + // TODO: currently we use the RegionX chain only when the experimental flag is on. + // + // For this reason we don't have different urls based on the network. However, this + // should be updated once this is in production. + connect(state, WS_REGIONX_CHAIN, dispatch, false, types); + }, [state]); return ( diff --git a/src/contexts/apis/consts.ts b/src/contexts/apis/consts.ts index 02b046d2..f47df4a7 100644 --- a/src/contexts/apis/consts.ts +++ b/src/contexts/apis/consts.ts @@ -4,6 +4,5 @@ export const WS_ROCOCO_CORETIME_CHAIN = process.env.WS_ROCOCO_CORETIME_CHAIN ?? ''; export const WS_KUSAMA_CORETIME_CHAIN = process.env.WS_KUSAMA_CORETIME_CHAIN ?? ''; -export const WS_KUSAMA_REGIONX_CHAIN = - process.env.WS_KUSAMA_REGIONX_CHAIN ?? ''; +export const WS_REGIONX_CHAIN = process.env.WS_REGIONX_CHAIN ?? ''; export const EXPERIMENTAL = process.env.EXPERIMENTAL == 'true' ? true : false; From 556872258f8d160f890257a8098426503a6befa3 Mon Sep 17 00:00:00 2001 From: Sergej Date: Sun, 12 May 2024 15:01:34 +0200 Subject: [PATCH 6/6] connect only when experimental --- src/contexts/apis/RegionXApi/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/contexts/apis/RegionXApi/index.tsx b/src/contexts/apis/RegionXApi/index.tsx index 039458e5..54732199 100644 --- a/src/contexts/apis/RegionXApi/index.tsx +++ b/src/contexts/apis/RegionXApi/index.tsx @@ -4,7 +4,7 @@ import { ApiState } from '@/contexts/apis/types'; import { useToast } from '@/contexts/toast'; import { connect, disconnect, initialState, reducer } from '../common'; -import { WS_REGIONX_CHAIN } from '../consts'; +import { EXPERIMENTAL, WS_REGIONX_CHAIN } from '../consts'; const types = { CoreIndex: 'u32', @@ -48,6 +48,7 @@ const RegionXApiContextProvider = (props: any) => { const disconnectRegionX = () => disconnect(state); useEffect(() => { + if (!EXPERIMENTAL) return; // TODO: currently we use the RegionX chain only when the experimental flag is on. // // For this reason we don't have different urls based on the network. However, this