Skip to content

Commit

Permalink
fix: identity from ppl chain when available
Browse files Browse the repository at this point in the history
  • Loading branch information
Tbaut committed Jul 10, 2024
1 parent 1468191 commit cef1a0d
Show file tree
Hide file tree
Showing 11 changed files with 188 additions and 34 deletions.
29 changes: 16 additions & 13 deletions packages/ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import MainLayout from './components/layout/Main'
import { WatchedAddressesContextProvider } from './contexts/WatchedAddressesContext'
import { WalletConnectContextProvider } from './contexts/WalletConnectContext'
import { ModalsContextProvider } from './contexts/ModalsContext'
import { PplApiContextProvider } from './contexts/PeopleChainApiContext'

const App = () => {
const queryClient = new QueryClient()
Expand All @@ -24,19 +25,21 @@ const App = () => {
<NetworkContextProvider>
<QueryClientProvider client={queryClient}>
<ApiContextProvider>
<WatchedAddressesContextProvider>
<AccountContextProvider>
<AccountNamesContextProvider>
<MultiProxyContextProvider>
<WalletConnectContextProvider>
<ModalsContextProvider>
<MainLayout />
</ModalsContextProvider>
</WalletConnectContextProvider>
</MultiProxyContextProvider>
</AccountNamesContextProvider>
</AccountContextProvider>
</WatchedAddressesContextProvider>
<PplApiContextProvider>
<WatchedAddressesContextProvider>
<AccountContextProvider>
<AccountNamesContextProvider>
<MultiProxyContextProvider>
<WalletConnectContextProvider>
<ModalsContextProvider>
<MainLayout />
</ModalsContextProvider>
</WalletConnectContextProvider>
</MultiProxyContextProvider>
</AccountNamesContextProvider>
</AccountContextProvider>
</WatchedAddressesContextProvider>
</PplApiContextProvider>
</ApiContextProvider>
</QueryClientProvider>
</NetworkContextProvider>
Expand Down
4 changes: 2 additions & 2 deletions packages/ui/src/components/EasySetup/SetIdentity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import { styled } from '@mui/material/styles'
import { SubmittableExtrinsic } from '@polkadot/api/types'
import { ISubmittableResult } from '@polkadot/types/types'
import { ReactNode, useCallback, useEffect, useMemo, useState } from 'react'
import { useApi } from '../../contexts/ApiContext'
import { TextField } from '../library'
import { useIdentity } from '../../hooks/useIdentity'
import { useCheckBalance } from '../../hooks/useCheckBalance'
import { getErrorMessageReservedFunds } from '../../utils'
import { formatBnBalance } from '../../utils/formatBnBalance'
import { useSetIdentityReservedFunds } from '../../hooks/useSetIdentityReservedFunds'
import { useIdenityApi } from '../../hooks/useIdentityApi'

interface Props {
className?: string
Expand Down Expand Up @@ -103,7 +103,7 @@ const fieldNameAndPlaceholder = (fieldName: keyof IdentityFields) => {
const MAX_ALLOWED_VAL_LENGTH = 32

const SetIdentity = ({ className, onSetExtrinsic, from, onSetErrorMessage }: Props) => {
const { api, chainInfo } = useApi()
const { api, chainInfo } = useIdenityApi()
const [identityFields, setIdentityFields] = useState<IdentityFields | undefined>()
const chainIdentity = useIdentity(from)
const [hasChangedAtLeastAField, setHasChangedAtLeastAField] = useState(false)
Expand Down
8 changes: 4 additions & 4 deletions packages/ui/src/components/modals/Send.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { formatBnBalance } from '../../utils/formatBnBalance'
import { useGetMultisigTx } from '../../hooks/useGetMultisigTx'
import SetIdentity from '../EasySetup/SetIdentity'
import { getErrorMessageReservedFunds } from '../../utils/getErrorMessageReservedFunds'
import { useHasIdentityPallet } from '../../hooks/useHasIdentityPallet'
import { useHasIdentityFeature } from '../../hooks/useHasIdentityFeature'

export enum EasyTransferTitle {
SendTokens = 'Send tokens',
Expand Down Expand Up @@ -76,7 +76,7 @@ const Send = ({ onClose, className, onSuccess, onFinalized, preselected }: Props
(a) => !!a.address
) as AccountBaseInfo[]
}, [getMultisigAsAccountBaseInfo, selectedMultiProxy])
const hasIdentityPallet = useHasIdentityPallet()
const { hasIdentityPallet, hasPplChain } = useHasIdentityFeature()
const [selectedOrigin, setSelectedOrigin] = useState<AccountBaseInfo>(possibleOrigin[0])
const isProxySelected = useMemo(() => selectedOrigin.meta?.isProxy, [selectedOrigin])
const [selectedMultisig, setSelectedMultisig] = useState(selectedMultiProxy?.multisigs[0])
Expand Down Expand Up @@ -170,7 +170,7 @@ const Send = ({ onClose, className, onSuccess, onFinalized, preselected }: Props
[EasyTransferTitle.FromCallData]: <FromCallData onSetExtrinsic={setExtrinsicToCall} />
} as Partial<Record<EasyTransferTitle, ReactNode>>

if (hasIdentityPallet) {
if (hasIdentityPallet && !hasPplChain) {
res[EasyTransferTitle.SetIdentity] = (
<SetIdentity
from={selectedOrigin.address}
Expand All @@ -181,7 +181,7 @@ const Send = ({ onClose, className, onSuccess, onFinalized, preselected }: Props
}

return res
}, [selectedOrigin, easyOptionErrorMessage, hasIdentityPallet])
}, [selectedOrigin.address, easyOptionErrorMessage, hasIdentityPallet, hasPplChain])

const signCallback = useSigningCallback({
onSuccess,
Expand Down
7 changes: 7 additions & 0 deletions packages/ui/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,16 @@ export interface NetworkInfo {
rpcUrl: string
httpGraphqlUrl: string
logo: string
pplChainRpcUrl?: string
}

export const HTTP_GRAPHQL_URL = `https://squid.subsquid.io/multix-arrow/v/v3/graphql`

export const PAYMENT_INFO_ACCOUNT = '5CXQZrh1MSgnGGCdJu3tqvRfCv7t5iQXGGV9UKotrbfhkavs'

const kusamaPplChain = 'wss://sys.ibp.network/people-kusama'
const westendPplChain = 'wss://sys.dotters.network/people-westend'

export const networkList: Record<string, NetworkInfo> = {
polkadot: {
chainId: 'polkadot',
Expand All @@ -49,6 +53,7 @@ export const networkList: Record<string, NetworkInfo> = {
kusama: {
chainId: 'kusama',
explorerNetworkName: 'kusama',
pplChainRpcUrl: kusamaPplChain,
rpcUrl: 'wss://rpc.ibp.network/kusama',
httpGraphqlUrl: HTTP_GRAPHQL_URL,
logo: chainsKusamaSVG
Expand All @@ -64,6 +69,7 @@ export const networkList: Record<string, NetworkInfo> = {
chainId: 'asset-hub-kusama',
explorerNetworkName: 'asset-hub-kusama',
rpcUrl: 'wss://sys.ibp.network/statemine',
pplChainRpcUrl: kusamaPplChain,
httpGraphqlUrl: HTTP_GRAPHQL_URL,
logo: nodesAssetHubSVG
},
Expand Down Expand Up @@ -147,6 +153,7 @@ export const networkList: Record<string, NetworkInfo> = {
westend: {
chainId: 'westend',
explorerNetworkName: 'westend',
pplChainRpcUrl: westendPplChain,
rpcUrl: 'wss://westend-rpc.polkadot.io',
httpGraphqlUrl: HTTP_GRAPHQL_URL,
logo: nodesWestendColourSVG
Expand Down
99 changes: 99 additions & 0 deletions packages/ui/src/contexts/PeopleChainApiContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import React, { useMemo } from 'react'
import { ApiPromise, WsProvider } from '@polkadot/api'
import { useState, useEffect, createContext, useContext } from 'react'
import { useNetwork } from './NetworkContext'
import '@polkadot/api-augment'

type ApiContextProps = {
children: React.ReactNode | React.ReactNode[]
}

export interface IApiContext {
pplApi?: false | ApiPromise
pplChainInfo?: ChainInfoHuman
}

export interface ChainInfoHuman {
ss58Format: number
tokenDecimals: number
tokenSymbol: string
}

interface RawChainInfoHuman {
ss58Format: string
tokenDecimals: string[]
tokenSymbol: string[]
}

const PplApiContext = createContext<IApiContext | undefined>(undefined)

const PplApiContextProvider = ({ children }: ApiContextProps) => {
const { selectedNetworkInfo } = useNetwork()
const [chainInfo, setChainInfo] = useState<ChainInfoHuman | undefined>()
const [pplApiPromise, setPplApiPromise] = useState<ApiPromise | undefined>()
const [isPplApiReady, setIsPplApiReady] = useState(false)
const provider = useMemo(
() =>
!!selectedNetworkInfo?.pplChainRpcUrl && new WsProvider(selectedNetworkInfo?.pplChainRpcUrl),
[selectedNetworkInfo]
)

useEffect(() => {
if (!provider) return

// console.log('---> connecting to', provider.endpoint)
setIsPplApiReady(false)
const pplApi = new ApiPromise({ provider })
pplApi.isReady.then((newApi) => setPplApiPromise(newApi)).catch(console.error)

return () => {
// console.log('<---disconnecting')
setIsPplApiReady(false)
!!pplApi && pplApi.disconnect()
setPplApiPromise(undefined)
}

// prevent an infinite loop
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [provider])

useEffect(() => {
if (!pplApiPromise) return

pplApiPromise.isReady
.then((pplApi) => {
setIsPplApiReady(true)

const info = pplApi.registry.getChainProperties()
const raw = info?.toHuman() as unknown as RawChainInfoHuman
setChainInfo({
// some parachains such as interlay have a comma in the format, e.g: "2,042"
ss58Format: Number(raw?.ss58Format.replace(',', '')) || 0,
tokenDecimals: Number(raw?.tokenDecimals[0]) || 0,
tokenSymbol: raw?.tokenSymbol[0] || ''
})
})
.catch(console.error)
}, [pplApiPromise])

return (
<PplApiContext.Provider
value={{
pplApi: isPplApiReady && pplApiPromise,
pplChainInfo: chainInfo
}}
>
{children}
</PplApiContext.Provider>
)
}

const usePplApi = () => {
const context = useContext(PplApiContext)
if (context === undefined) {
throw new Error('usePplApi must be used within a PplApiContextProvider')
}
return context
}

export { PplApiContextProvider, usePplApi }
4 changes: 2 additions & 2 deletions packages/ui/src/hooks/useGetIdentity.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useCallback } from 'react'
import { useApi } from '../contexts/ApiContext'
import { useIdenityApi } from './useIdentityApi'

export const useGetIdentity = () => {
const { api } = useApi()
const { api } = useIdenityApi()

const getIdentity = useCallback(
async (address: string) => {
Expand Down
14 changes: 14 additions & 0 deletions packages/ui/src/hooks/useHasIdentityFeature.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useMemo } from 'react'
import { useNetwork } from '../contexts/NetworkContext'
import { useIdenityApi } from './useIdentityApi'

export const useHasIdentityFeature = () => {
const { api } = useIdenityApi()
const { selectedNetworkInfo } = useNetwork()
const hasIdentityPallet = useMemo(() => !!api && !!api.tx?.identity?.setIdentity, [api])
const hasPplChain = useMemo(() => !!selectedNetworkInfo?.pplChainRpcUrl, [selectedNetworkInfo])
return {
hasPplChain,
hasIdentityPallet
}
}
9 changes: 0 additions & 9 deletions packages/ui/src/hooks/useHasIdentityPallet.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions packages/ui/src/hooks/useIdentity.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useEffect, useState } from 'react'
import { useApi } from '../contexts/ApiContext'
import { DeriveAccountInfo, DeriveAccountRegistration } from '@polkadot/api-derive/types'
import { useIdenityApi } from './useIdentityApi'

export const useIdentity = (address?: string) => {
const { api } = useApi()
const { api } = useIdenityApi()
const [identity, setIdentity] = useState<DeriveAccountRegistration | null>(null)

useEffect(() => {
Expand Down
39 changes: 39 additions & 0 deletions packages/ui/src/hooks/useIdentityApi.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { ApiPromise } from '@polkadot/api'
import { useState, useEffect } from 'react'
import { useApi } from '../contexts/ApiContext'
import { ChainInfoHuman, usePplApi } from '../contexts/PeopleChainApiContext'

export const useIdenityApi = () => {
const { api, chainInfo } = useApi()
const { pplApi, pplChainInfo } = usePplApi()
const [apiToUse, setApiToUse] = useState<ApiPromise | null>(null)
const [chainInfoToUse, setChainInfoToUse] = useState<ChainInfoHuman | undefined>(undefined)

useEffect(() => {
if (!pplApi && !api) {
return
}

if (pplApi) {
setApiToUse(pplApi)
setChainInfoToUse(pplChainInfo)
} else if (api) {
setApiToUse(api)
setChainInfoToUse(chainInfo)
}
}, [api, chainInfo, pplApi, pplChainInfo])

useEffect(() => {
if (!pplApi && !api) {
return
}

if (pplApi) {
setApiToUse(pplApi)
} else if (api) {
setApiToUse(api)
}
}, [api, pplApi])

return { api: apiToUse, chainInfo: chainInfoToUse }
}
5 changes: 3 additions & 2 deletions packages/ui/src/pages/Home/MultisigActionMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from 'react-icons/hi2'
import { useGetSubscanLinks } from '../../hooks/useSubscanLink'
import { EasyTransferTitle } from '../../components/modals/Send'
import { useHasIdentityPallet } from '../../hooks/useHasIdentityPallet'
import { useHasIdentityFeature } from '../../hooks/useHasIdentityFeature'

interface MultisigActionMenuProps {
withNewTransactionButton?: boolean
Expand All @@ -25,7 +25,7 @@ const MultisigActionMenu = ({
const { selectedHasProxy, selectedIsWatched, selectedMultiProxy } = useMultiProxy()
const { setIsEditModalOpen, setIsChangeMultiModalOpen, onOpenSendModal } = useModals()
const { getSubscanAccountLink } = useGetSubscanLinks()
const hasIdentityPallet = useHasIdentityPallet()
const { hasIdentityPallet, hasPplChain } = useHasIdentityFeature()

const options: MenuOption[] = useMemo(() => {
const opts = [
Expand All @@ -48,6 +48,7 @@ const MultisigActionMenu = ({

!selectedIsWatched &&
hasIdentityPallet &&
hasPplChain &&
opts.push({
text: 'Set identity',
icon: <IdentityIcon size={20} />,
Expand Down

0 comments on commit cef1a0d

Please sign in to comment.