From eb4dc30e6b37f22bc5772f7da727562e88cf9643 Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 22 Mar 2023 10:51:23 +0200 Subject: [PATCH 01/54] Add dot seller functional --- .../common/inputs/SelectAccountInput.tsx | 57 ++++-- .../domains/EligibleDomainsSection.tsx | 40 ++-- .../domains/dot-seller/BuyByDotButton.tsx | 176 ++++++++++++++++++ .../domains/dot-seller/Index.module.sass | 57 ++++++ src/components/domains/dot-seller/config.ts | 10 + .../domains/dot-seller/remark/config.ts | 46 +++++ .../domains/dot-seller/remark/core.ts | 135 ++++++++++++++ .../domains/dot-seller/remark/decorators.ts | 46 +++++ .../domains/dot-seller/remark/index.ts | 1 + .../domains/dot-seller/remark/types.ts | 140 ++++++++++++++ .../domains/dot-seller/remark/utils.ts | 6 + src/components/domains/dot-seller/utils.tsx | 12 ++ .../domains/manage/ManageDomainProvider.tsx | 26 ++- src/components/domains/utils.tsx | 7 +- src/components/donate/LazyTxButton.tsx | 36 ++-- src/config/connections/staging.ts | 2 +- yarn.lock | 72 +++---- 17 files changed, 785 insertions(+), 84 deletions(-) create mode 100644 src/components/domains/dot-seller/BuyByDotButton.tsx create mode 100644 src/components/domains/dot-seller/Index.module.sass create mode 100644 src/components/domains/dot-seller/config.ts create mode 100644 src/components/domains/dot-seller/remark/config.ts create mode 100644 src/components/domains/dot-seller/remark/core.ts create mode 100644 src/components/domains/dot-seller/remark/decorators.ts create mode 100644 src/components/domains/dot-seller/remark/index.ts create mode 100644 src/components/domains/dot-seller/remark/types.ts create mode 100644 src/components/domains/dot-seller/remark/utils.ts create mode 100644 src/components/domains/dot-seller/utils.tsx diff --git a/src/components/common/inputs/SelectAccountInput.tsx b/src/components/common/inputs/SelectAccountInput.tsx index 0fec0d289..2fa1193eb 100644 --- a/src/components/common/inputs/SelectAccountInput.tsx +++ b/src/components/common/inputs/SelectAccountInput.tsx @@ -1,20 +1,32 @@ -import { GenericAccountId } from '@polkadot/types' -import { isAddress } from '@polkadot/util-crypto' -import registry from '@subsocial/api/utils/registry' -import { isEmptyArray, toSubsocialAddress } from '@subsocial/utils' import { Select } from 'antd' import { useEffect, useState } from 'react' -import { useMyAccounts } from 'src/components/auth/MyAccountsContext' -import { equalAddresses } from 'src/components/substrate' -import { useSelectProfile } from 'src/rtk/app/hooks' import { SelectAddressPreview } from '../../profile-selector/MyAccountMenu' +import { isEmptyArray, toSubsocialAddress } from '@subsocial/utils' +import registry from '@subsocial/api/utils/registry' +import { GenericAccountId } from '@polkadot/types' import Avatar from '../../profiles/address-views/Avatar' import styles from './inputs.module.sass' +import { useSelectProfile } from 'src/rtk/app/hooks' +import { useMyAccounts } from 'src/components/auth/MyAccountsContext' +import { equalAddresses } from 'src/components/substrate' + +export const isValidAccount = (address?: string) => { + try { + if (address) { + return !!new GenericAccountId(registry, address) + } + + return false + } catch {} + + return false +} type SelectAccountInputProps = { className?: string setValue: (value: string) => void value?: string + withAvatar?: boolean } const filterSelectOptions = (adresses: string[], value?: string) => { @@ -31,12 +43,17 @@ const filterSelectOptions = (adresses: string[], value?: string) => { }) } -export const SelectAccountInput = ({ setValue, value, className }: SelectAccountInputProps) => { +export const SelectAccountInput = ({ + setValue, + value, + className, + withAvatar = true, +}: SelectAccountInputProps) => { const { accounts, status } = useMyAccounts() const allExtensionAccounts = accounts.map(x => toSubsocialAddress(x.address) as string) - const [defaultOptions, setDefaultOptions] = useState([]) - const [selectOptions, setSelectOptions] = useState(defaultOptions) + const [ defaultOptions, setDefaultOptions ] = useState([]) + const [ selectOptions, setSelectOptions ] = useState(defaultOptions) const profile = useSelectProfile(value) useEffect(() => { @@ -45,7 +62,7 @@ export const SelectAccountInput = ({ setValue, value, className }: SelectAccount const options = status === 'OK' ? filterSelectOptions(allExtensionAccounts, value) : [] setDefaultOptions(options) setSelectOptions(options) - }, [value, status]) + }, [ value, status ]) const onSelectChange = (value: string) => { setValue(value) @@ -54,7 +71,7 @@ export const SelectAccountInput = ({ setValue, value, className }: SelectAccount const onSearchHandler = (searchValue: any) => { const options = [] - if (isAddress(searchValue)) { + if (isValidAccount(searchValue)) { options.push({ key: 'key-' + searchValue, label: ( @@ -84,19 +101,23 @@ export const SelectAccountInput = ({ setValue, value, className }: SelectAccount } } + const avatar = ( +
+ {value + ? + :
} +
+ ) + return (
- {value ? ( - - ) : ( -
- )} + {withAvatar && avatar}
) diff --git a/src/components/common/inputs/inputs.module.sass b/src/components/common/inputs/inputs.module.sass index a2e4d5ba1..da59c259d 100644 --- a/src/components/common/inputs/inputs.module.sass +++ b/src/components/common/inputs/inputs.module.sass @@ -10,16 +10,25 @@ .Select overflow: hidden - \:global .ant-select-selector + .ant-select-selection-item + align-self: center + font-weight: bold + font-size: $font_normal + height: 100% !important + \:global .ant-select-selector .ant-select-selection-search overflow: hidden .ant-select-selection-item + height: 100% !important align-self: center - font-weight: bold font-size: $font_normal .ant-select-selection-placeholder align-self: center - font-size: $font_normal \ No newline at end of file + font-size: $font_normal + +.AddressPreview + text-overflow: ellipsis + overflow: hidden diff --git a/src/components/domains/dot-seller/BuyByDotModal.tsx b/src/components/domains/dot-seller/BuyByDotModal.tsx index b792bda4b..2a733d1dc 100644 --- a/src/components/domains/dot-seller/BuyByDotModal.tsx +++ b/src/components/domains/dot-seller/BuyByDotModal.tsx @@ -3,12 +3,12 @@ import clsx from 'clsx' import { useState } from 'react' import { SelectAccountInput } from 'src/components/common/inputs/SelectAccountInput' import { useBalancesByNetwork } from 'src/components/donate/AmountInput' -import { useMyAddress } from '../../auth/MyAccountsContext' +import { useSelectSellerConfig } from 'src/rtk/features/sellerConfig/sellerConfigHooks' import { FormatBalance } from '../../common/balances/Balance' import { MutedDiv } from '../../utils/MutedText' import { useManageDomainContext } from '../manage/ManageDomainProvider' import BuyByDotTxButton from './BuyByDotTxButton' -import { domainsNetwork, validDomainPrice } from './config' +import { domainsNetwork } from './config' import styles from './Index.module.sass' import { useGetDecimalAndSymbol } from './utils' @@ -18,17 +18,18 @@ type ModalBodyProps = { const ModalBody = ({ domainName }: ModalBodyProps) => { const { recipient, purchaser, setRecipient, setPurchaser } = useManageDomainContext() - const myAddress = useMyAddress() + const sellerConfig = useSelectSellerConfig() const { decimal, symbol } = useGetDecimalAndSymbol(domainsNetwork) const balance = useBalancesByNetwork({ - account: myAddress, + account: purchaser, network: domainsNetwork, currency: symbol, }) const { freeBalance } = balance || {} + const { domainRegistrationPriceFixed } = sellerConfig || {} return ( @@ -49,6 +50,7 @@ const ModalBody = ({ domainName }: ModalBodyProps) => { setValue={setPurchaser} value={purchaser} withAvatar={false} + network={domainsNetwork} /> @@ -60,6 +62,7 @@ const ModalBody = ({ domainName }: ModalBodyProps) => { setValue={setRecipient} value={recipient} withAvatar={false} + network={domainsNetwork} /> Choose the recipient to whom the domain will be registered @@ -72,7 +75,13 @@ const ModalBody = ({ domainName }: ModalBodyProps) => {
Price: -
0.56 DOT
+
+ +
@@ -119,14 +128,27 @@ type BuyByDotButtonProps = { withPrice?: boolean } -const BuyByDotButton = ({ domainName, label = 'Register', withPrice = true }: BuyByDotButtonProps) => { +const BuyByDotButton = ({ + domainName, + label = 'Register', + withPrice = true, +}: BuyByDotButtonProps) => { const [open, setOpen] = useState(false) const { decimal, symbol } = useGetDecimalAndSymbol(domainsNetwork) + const sellerConfig = useSelectSellerConfig() + + const { domainRegistrationPriceFixed } = sellerConfig || {} const close = () => setOpen(false) - const price = ( - + const price = domainRegistrationPriceFixed ? ( + + ) : ( +
-
) return ( diff --git a/src/components/domains/dot-seller/BuyByDotTxButton.tsx b/src/components/domains/dot-seller/BuyByDotTxButton.tsx index 93cc08d1f..a3aef7566 100644 --- a/src/components/domains/dot-seller/BuyByDotTxButton.tsx +++ b/src/components/domains/dot-seller/BuyByDotTxButton.tsx @@ -14,7 +14,7 @@ import { useAppDispatch } from 'src/rtk/app/store' import { fetchPendingOrdersByAccount } from 'src/rtk/features/domainPendingOrders/pendingOrdersSlice' import { useSelectSellerConfig } from 'src/rtk/features/sellerConfig/sellerConfigHooks' import { useManageDomainContext } from '../manage/ManageDomainProvider' -import { domainsNetwork, validDomainPrice } from './config' +import { domainsNetwork } from './config' type BuyByDotTxButtonProps = { domainName: string @@ -41,6 +41,7 @@ const BuyByDotTxButton = ({ domainName, className, close }: BuyByDotTxButtonProp sellerTreasuryAccount, remarkProtVersion, domainHostChain, + domainRegistrationPriceFixed, sellerToken: { name: tokenName }, } = sellerConfig @@ -48,7 +49,7 @@ const BuyByDotTxButton = ({ domainName, className, close }: BuyByDotTxButtonProp if (!api) return [] - const transferTx = api.tx.balances.transfer(sellerTreasuryAccount, validDomainPrice) + const transferTx = api.tx.balances.transfer(sellerTreasuryAccount, domainRegistrationPriceFixed) SocialRemark.setConfig({ protNames: [remarkProtName] }) diff --git a/src/components/domains/dot-seller/Index.module.sass b/src/components/domains/dot-seller/Index.module.sass index f3f04544b..45019aec2 100644 --- a/src/components/domains/dot-seller/Index.module.sass +++ b/src/components/domains/dot-seller/Index.module.sass @@ -61,7 +61,7 @@ $element_height: 40px .RegisterButton display: flex align-items: center - gap: $space_tiny + gap: $space_normal button font-size: $font_normal diff --git a/src/components/domains/dot-seller/config.ts b/src/components/domains/dot-seller/config.ts index 54c61da36..93d8df295 100644 --- a/src/components/domains/dot-seller/config.ts +++ b/src/components/domains/dot-seller/config.ts @@ -1,8 +1,5 @@ -import BN from 'bn.js' import { GraphQLClient } from 'graphql-request' -export const validDomainPrice = new BN('100000000') // 0.01 - export const domainsNetwork = 'rococo' export const xSellerSquid = 'https://squid.subsquid.io/x-seller-squid-rococo-soon/graphql' diff --git a/src/components/domains/dot-seller/utils.tsx b/src/components/domains/dot-seller/utils.tsx index 7ef0237c5..431a34ab0 100644 --- a/src/components/domains/dot-seller/utils.tsx +++ b/src/components/domains/dot-seller/utils.tsx @@ -1,8 +1,10 @@ import { useChainInfo } from '../../../rtk/features/chainsInfo/chainsInfoHooks' -export const useGetDecimalAndSymbol = (network: string) => { +export const useGetDecimalAndSymbol = (network?: string) => { const chainsInfo = useChainInfo() + if(!network) return {} + const { tokenDecimals, tokenSymbols, nativeToken } = chainsInfo[network] || {} const decimal = tokenDecimals?.[0] || 0 diff --git a/src/components/profile-selector/MyAccountMenu.tsx b/src/components/profile-selector/MyAccountMenu.tsx index 58fb8877f..69dccdaa3 100644 --- a/src/components/profile-selector/MyAccountMenu.tsx +++ b/src/components/profile-selector/MyAccountMenu.tsx @@ -16,6 +16,7 @@ type SelectAddressType = AddressProps & { onClick?: () => void withShortAddress?: boolean withoutBalances?: boolean + network?: string } export const SelectAddressPreview: FC = ({ @@ -24,6 +25,7 @@ export const SelectAddressPreview: FC = ({ onClick, owner, withoutBalances = false, + network }) => { return (
@@ -38,7 +40,7 @@ export const SelectAddressPreview: FC = ({ address={address} withShortAddress={withShortAddress} /> - {!withoutBalances && } + {!withoutBalances && }
) diff --git a/src/components/profiles/address-views/AuthorPreview.tsx b/src/components/profiles/address-views/AuthorPreview.tsx index 17de6505b..ffa615af4 100644 --- a/src/components/profiles/address-views/AuthorPreview.tsx +++ b/src/components/profiles/address-views/AuthorPreview.tsx @@ -14,13 +14,14 @@ export type InfoProps = { address?: string | AccountId balance?: string | BN | number details?: JSX.Element + network?: string } -export const InfoDetails: React.FC = ({ details, balance, address }) => { +export const InfoDetails: React.FC = ({ details, balance, address, network }) => { return ( <>
- {balance || (address && )} + {balance || (address && )} {details &&
{details}
}
diff --git a/src/components/profiles/address-views/utils/NameDetails.tsx b/src/components/profiles/address-views/utils/NameDetails.tsx index 8678f735a..e1cded86b 100644 --- a/src/components/profiles/address-views/utils/NameDetails.tsx +++ b/src/components/profiles/address-views/utils/NameDetails.tsx @@ -12,6 +12,7 @@ type Props = AddressProps & { withFollowButton?: boolean withLabel?: boolean withDetails?: boolean + network?: string } export const NameDetails = ({ From 56db7cde78f57a86575ba4ff356bd2bd2be48cbd Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 17 Apr 2023 13:13:42 +0300 Subject: [PATCH 15/54] Refactor code --- .../common/inputs/SelectAccountInput.tsx | 19 --------- .../domains/EligibleDomainsSection.tsx | 24 ++++++++---- .../domains/dot-seller/BuyByDotModal.tsx | 18 ++++----- .../domains/dot-seller/BuyByDotTxButton.tsx | 39 ++++++++++++------- src/components/domains/dot-seller/config.ts | 2 - .../domains/pendingOrders/index.tsx | 20 ++++++---- src/components/domains/utils.tsx | 6 +++ .../domainPendingOrders/pendingOrdersHooks.ts | 6 +-- .../features/domains/domainsByOwnerSlice.ts | 2 - 9 files changed, 73 insertions(+), 63 deletions(-) diff --git a/src/components/common/inputs/SelectAccountInput.tsx b/src/components/common/inputs/SelectAccountInput.tsx index 4dc576398..4ccceced2 100644 --- a/src/components/common/inputs/SelectAccountInput.tsx +++ b/src/components/common/inputs/SelectAccountInput.tsx @@ -32,21 +32,6 @@ type SelectAccountInputProps = { disabled?: boolean } -type SelectInputPreviewProps = { - address: string -} - -export const SelectInputPreview = ({ address }: SelectInputPreviewProps) => { - const profile = useSelectProfile(address) - - profile?.content?.image - - return
- -
{address}
-
-} - const filterSelectOptions = (adresses: string[], value?: string, network?: string) => { return adresses .filter(x => { @@ -57,7 +42,6 @@ const filterSelectOptions = (adresses: string[], value?: string, network?: strin key: address + index, label: , value: address, - preview: } }) } @@ -108,7 +92,6 @@ export const SelectAccountInput = ({ network={network} /> ), - preview: , value: searchValue, }) } else { @@ -144,8 +127,6 @@ export const SelectAccountInput = ({ ) - console.log(selectOptions) - return (
{withAvatar && avatar} diff --git a/src/components/domains/EligibleDomainsSection.tsx b/src/components/domains/EligibleDomainsSection.tsx index b15a3d95a..e4a7fba76 100644 --- a/src/components/domains/EligibleDomainsSection.tsx +++ b/src/components/domains/EligibleDomainsSection.tsx @@ -3,10 +3,10 @@ import { isEmptyArray, newLogger, parseDomain } from '@subsocial/utils' import { Button, Card, Divider, Radio, RadioChangeEvent, Result, Row, Tag, Tooltip } from 'antd' import BN from 'bn.js' import clsx from 'clsx' -import React, { useState } from 'react' +import React, { useEffect, useState } from 'react' import { showErrorMessage } from 'src/components/utils/Message' import config from 'src/config' -import { useSelectPendingOrderById } from '../../rtk/features/domainPendingOrders/pendingOrdersHooks' +import { useCreateReloadPendingOrdersByAccount, useSelectPendingOrderById } from '../../rtk/features/domainPendingOrders/pendingOrdersHooks' import { useBuildDomainsWithTldByDomain, useCreateReloadMyDomains, @@ -26,7 +26,8 @@ import ClaimFreeDomainModal from './ClaimFreeDomainModal' import BuyByDotButton from './dot-seller/BuyByDotModal' import styles from './index.module.sass' import { useManageDomainContext } from './manage/ManageDomainProvider' -import { DomainDetails, ResultContainer } from './utils' +import { DomainDetails, ResultContainer, getTime } from './utils' +import { useSelectSellerConfig } from 'src/rtk/features/sellerConfig/sellerConfigHooks' const log = newLogger('DD') @@ -48,6 +49,8 @@ const BuyDomainSection = ({ domain: { id: domain }, label = 'Register' }: Domain const reloadMyDomains = useCreateReloadMyDomains() const { openManageModal } = useManageDomainContext() const { api, isApiReady } = useSubstrate() + const reloadPendingOrders = useCreateReloadPendingOrdersByAccount() + const myAddress = useMyAddress() if (!isApiReady) return null @@ -59,6 +62,7 @@ const BuyDomainSection = ({ domain: { id: domain }, label = 'Register' }: Domain const onSuccess: TxCallback = async () => { await reloadMyDomains() + reloadPendingOrders(myAddress) openManageModal('success', domain) } @@ -80,7 +84,6 @@ const BuyDomainSection = ({ domain: { id: domain }, label = 'Register' }: Domain tx={'domains.registerDomain'} onSuccess={onSuccess} onFailed={onFailed} - // onClick={onSuccess} // ! for debug isFreeTx params={getTxParams} className={styles.DomainPrimaryButton} @@ -157,17 +160,20 @@ const UnavailableBtn = ({ domain: { owner, id } }: DomainProps) => { const DomainAction = ({ domain }: DomainProps) => { const { owner } = domain const { promoCode, variant } = useManageDomainContext() + const sellerConfig = useSelectSellerConfig() const myAddress = useMyAddress() const pendingOrder = useSelectPendingOrderById(domain.id) + const { dmnRegPendingOrderExpTime } = sellerConfig || {} + const { account } = pendingOrder || {} if (account && account !== myAddress) { return ( @@ -325,6 +331,10 @@ const ChooseDomain = ({ domain }: DomainProps) => { content = } /> } + useEffect(() => { + setVariant('SUB') + }, [domain.id]) + const onVariantChange = (e: RadioChangeEvent) => { setVariant(e.target.value) } diff --git a/src/components/domains/dot-seller/BuyByDotModal.tsx b/src/components/domains/dot-seller/BuyByDotModal.tsx index 2a733d1dc..cab9ee8eb 100644 --- a/src/components/domains/dot-seller/BuyByDotModal.tsx +++ b/src/components/domains/dot-seller/BuyByDotModal.tsx @@ -8,7 +8,6 @@ import { FormatBalance } from '../../common/balances/Balance' import { MutedDiv } from '../../utils/MutedText' import { useManageDomainContext } from '../manage/ManageDomainProvider' import BuyByDotTxButton from './BuyByDotTxButton' -import { domainsNetwork } from './config' import styles from './Index.module.sass' import { useGetDecimalAndSymbol } from './utils' @@ -20,16 +19,17 @@ const ModalBody = ({ domainName }: ModalBodyProps) => { const { recipient, purchaser, setRecipient, setPurchaser } = useManageDomainContext() const sellerConfig = useSelectSellerConfig() - const { decimal, symbol } = useGetDecimalAndSymbol(domainsNetwork) + const { domainRegistrationPriceFixed, sellerChain } = sellerConfig || {} + + const { decimal, symbol } = useGetDecimalAndSymbol(sellerChain) const balance = useBalancesByNetwork({ account: purchaser, - network: domainsNetwork, + network: sellerChain, currency: symbol, }) const { freeBalance } = balance || {} - const { domainRegistrationPriceFixed } = sellerConfig || {} return ( @@ -50,7 +50,7 @@ const ModalBody = ({ domainName }: ModalBodyProps) => { setValue={setPurchaser} value={purchaser} withAvatar={false} - network={domainsNetwork} + network={sellerChain} /> @@ -62,7 +62,7 @@ const ModalBody = ({ domainName }: ModalBodyProps) => { setValue={setRecipient} value={recipient} withAvatar={false} - network={domainsNetwork} + network={sellerChain} /> Choose the recipient to whom the domain will be registered @@ -133,11 +133,11 @@ const BuyByDotButton = ({ label = 'Register', withPrice = true, }: BuyByDotButtonProps) => { - const [open, setOpen] = useState(false) - const { decimal, symbol } = useGetDecimalAndSymbol(domainsNetwork) const sellerConfig = useSelectSellerConfig() + const { domainRegistrationPriceFixed, sellerChain } = sellerConfig || {} - const { domainRegistrationPriceFixed } = sellerConfig || {} + const [open, setOpen] = useState(false) + const { decimal, symbol } = useGetDecimalAndSymbol(sellerChain) const close = () => setOpen(false) diff --git a/src/components/domains/dot-seller/BuyByDotTxButton.tsx b/src/components/domains/dot-seller/BuyByDotTxButton.tsx index a3aef7566..52a7ee6d4 100644 --- a/src/components/domains/dot-seller/BuyByDotTxButton.tsx +++ b/src/components/domains/dot-seller/BuyByDotTxButton.tsx @@ -5,7 +5,9 @@ import { SocialRemarkMessageVersion, SubSclSource, } from '@subsocial/utils' +import BN from 'bignumber.js' import { useMyAddress } from 'src/components/auth/MyAccountsContext' +import { useBalancesByNetwork } from 'src/components/donate/AmountInput' import LazyTxButton from 'src/components/donate/LazyTxButton' import { useLazyConnectionsContext } from 'src/components/lazy-connection/LazyConnectionContext' import { showErrorMessage } from 'src/components/utils/Message' @@ -14,7 +16,7 @@ import { useAppDispatch } from 'src/rtk/app/store' import { fetchPendingOrdersByAccount } from 'src/rtk/features/domainPendingOrders/pendingOrdersSlice' import { useSelectSellerConfig } from 'src/rtk/features/sellerConfig/sellerConfigHooks' import { useManageDomainContext } from '../manage/ManageDomainProvider' -import { domainsNetwork } from './config' +import { useGetDecimalAndSymbol } from './utils' type BuyByDotTxButtonProps = { domainName: string @@ -33,6 +35,18 @@ const BuyByDotTxButton = ({ domainName, className, close }: BuyByDotTxButtonProp const myAddress = useMyAddress() const { getApiByNetwork } = useLazyConnectionsContext() + const { sellerChain, domainRegistrationPriceFixed } = sellerConfig || {} + + const { symbol } = useGetDecimalAndSymbol(sellerChain) + + const balance = useBalancesByNetwork({ + account: purchaser, + network: sellerChain, + currency: symbol, + }) + + const { freeBalance } = balance || {} + const getParams = async () => { if (!purchaser || !sellerConfig) return [] @@ -43,9 +57,10 @@ const BuyByDotTxButton = ({ domainName, className, close }: BuyByDotTxButtonProp domainHostChain, domainRegistrationPriceFixed, sellerToken: { name: tokenName }, + sellerChain, } = sellerConfig - const api = await getApiByNetwork(domainsNetwork) + const api = await getApiByNetwork(sellerChain) if (!api) return [] @@ -76,26 +91,20 @@ const BuyByDotTxButton = ({ domainName, className, close }: BuyByDotTxButtonProp } const onSuccess = async () => { - if (!myAddress) return - setIsFetchNewDomains(true) close() } - const onFailed = () => { - console.log('Extrinsic failed') - } - const onClick = async () => { - if (!sellerConfig) return + if (!sellerConfig || !myAddress) return const { sellerApiAuthTokenManager } = sellerConfig const result = await createPendingOrder(purchaser, domainName, sellerApiAuthTokenManager) if (result?.success) { - dispatch(fetchPendingOrdersByAccount({ id: myAddress || '', reload: true })) + dispatch(fetchPendingOrdersByAccount({ id: recipient, reload: true })) return false } else { showErrorMessage(result?.errors) @@ -109,13 +118,17 @@ const BuyByDotTxButton = ({ domainName, className, close }: BuyByDotTxButtonProp block type='primary' size='middle' - network={domainsNetwork} + network={sellerChain || ''} accountId={purchaser} - disabled={!recipient} + disabled={ + !recipient || + !freeBalance || + !domainRegistrationPriceFixed || + new BN(freeBalance).lt(domainRegistrationPriceFixed) + } tx={'utility.batchAll'} params={getParams} onSuccess={onSuccess} - onFailed={onFailed} onClick={() => onClick()} label={'Register'} className={className} diff --git a/src/components/domains/dot-seller/config.ts b/src/components/domains/dot-seller/config.ts index 93d8df295..c09d6201e 100644 --- a/src/components/domains/dot-seller/config.ts +++ b/src/components/domains/dot-seller/config.ts @@ -1,7 +1,5 @@ import { GraphQLClient } from 'graphql-request' -export const domainsNetwork = 'rococo' - export const xSellerSquid = 'https://squid.subsquid.io/x-seller-squid-rococo-soon/graphql' export const sellerSquidGraphQlClient = new GraphQLClient(xSellerSquid) \ No newline at end of file diff --git a/src/components/domains/pendingOrders/index.tsx b/src/components/domains/pendingOrders/index.tsx index c82ece59e..3a7be7fc3 100644 --- a/src/components/domains/pendingOrders/index.tsx +++ b/src/components/domains/pendingOrders/index.tsx @@ -1,15 +1,16 @@ import { InfoCircleOutlined } from '@ant-design/icons' -import { SubDate, isEmptyArray } from '@subsocial/utils' +import { isEmptyArray, SubDate } from '@subsocial/utils' import { Space, Tooltip } from 'antd' +import dayjs from 'dayjs' import { useMemo } from 'react' import CardWithContent from 'src/components/utils/cards/CardWithContent' import { useSelectPendingOrdersByAccount } from 'src/rtk/features/domainPendingOrders/pendingOrdersHooks' import { PendingDomainEntity } from 'src/rtk/features/domainPendingOrders/pendingOrdersSlice' -import { MutedDiv } from '../../utils/MutedText' -import styles from './Index.module.sass' -import dayjs from 'dayjs' import { useSelectSellerConfig } from 'src/rtk/features/sellerConfig/sellerConfigHooks' +import { MutedDiv } from '../../utils/MutedText' import BuyByDotButton from '../dot-seller/BuyByDotModal' +import { getTime } from '../utils' +import styles from './Index.module.sass' type PendingDomainProps = { pendingDomain: PendingDomainEntity @@ -21,7 +22,9 @@ const PendingDomain = ({ pendingDomain }: PendingDomainProps) => { const { domain, timestamp } = pendingDomain const { dmnRegPendingOrderExpTime } = sellerConfig || {} - const expiresAt = SubDate.formatDate((dayjs(timestamp).valueOf() + (dmnRegPendingOrderExpTime || 0))) + const expiresAt = SubDate.formatDate( + dayjs(timestamp).valueOf() + (dmnRegPendingOrderExpTime || 0), + ) return (
@@ -41,6 +44,9 @@ const PendingDomain = ({ pendingDomain }: PendingDomainProps) => { const PendingOrdersSection = () => { const pendingOrders = useSelectPendingOrdersByAccount() + const sellerConfig = useSelectSellerConfig() + + const { dmnRegPendingOrderExpTime } = sellerConfig || {} const pendingDomains = useMemo(() => { const orders = pendingOrders.map((pendingDomain, i) => ( @@ -59,8 +65,8 @@ const PendingOrdersSection = () => { return ( - You have a pending order to buy a domain. It will be canceled automatically after 10 - minutes. + You have a pending order to buy a domain. It will be canceled automatically after{' '} + {getTime(dmnRegPendingOrderExpTime)} minutes. {pendingDomains} diff --git a/src/components/domains/utils.tsx b/src/components/domains/utils.tsx index 9797812a7..8a003022e 100644 --- a/src/components/domains/utils.tsx +++ b/src/components/domains/utils.tsx @@ -46,6 +46,12 @@ export const CardWithTitle: FC = props => ( ) +export const getTime = (miliseconds?: number) => { + if(!miliseconds) return '-' + + return miliseconds / 60 / 1000 +} + export const useAddAstronautBg = () => useAddClassNameToRootElement('astronaut-bg') export type DomainStruct = { diff --git a/src/rtk/features/domainPendingOrders/pendingOrdersHooks.ts b/src/rtk/features/domainPendingOrders/pendingOrdersHooks.ts index 23e05ef1e..dabc2e2c7 100644 --- a/src/rtk/features/domainPendingOrders/pendingOrdersHooks.ts +++ b/src/rtk/features/domainPendingOrders/pendingOrdersHooks.ts @@ -39,10 +39,8 @@ export const useSelectPendingOrdersByAccount = () => { } export const useCreateReloadPendingOrdersByAccount = () => { - const myAddress = useMyAddress() - - return useActions(({ dispatch }) => { - myAddress && dispatch(fetchPendingOrdersByAccount({ id: myAddress })) + return useActions(({ dispatch, args }) => { + args && dispatch(fetchPendingOrdersByAccount({ id: args })) }) } diff --git a/src/rtk/features/domains/domainsByOwnerSlice.ts b/src/rtk/features/domains/domainsByOwnerSlice.ts index 50ae07a7f..1b4a6c5da 100644 --- a/src/rtk/features/domains/domainsByOwnerSlice.ts +++ b/src/rtk/features/domains/domainsByOwnerSlice.ts @@ -56,8 +56,6 @@ export const fetchDomainsByOwner = createAsyncThunk< const domains: Domain[] = await api.blockchain.domainsByOwner(myAddress) - console.log('New domains', domains) - return { id: myAddress, domains, From 43898e69cbd728028d548430c1fb65c13a3a5cfc Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 17 Apr 2023 13:40:12 +0300 Subject: [PATCH 16/54] Remove .env file --- .env.local | 42 ---------------------- .gitignore | 1 + dev.env | 51 ++++++++++++++------------- package.json | 8 ++--- src/pages/_app.js | 2 +- src/pages/api/pending-order/create.ts | 2 +- 6 files changed, 33 insertions(+), 73 deletions(-) delete mode 100644 .env.local diff --git a/.env.local b/.env.local deleted file mode 100644 index bc02000ef..000000000 --- a/.env.local +++ /dev/null @@ -1,42 +0,0 @@ -# Logger level -NEXT_PUBLIC_LOG_LEVEL=debug - -# App kind: 'polkaverse' | 'staging' -NEXT_PUBLIC_APP_KIND=polkaverse - -# Connection kind: -# 'local' - For development in localhost infrastructure (local Substrate, IPFS, etc.) -# 'dev' - For development in betanet/mainnet infrastructure. -# 'staging' - For development in staging infrastructure. -# 'main' - If running this web app on a production server. -NEXT_PUBLIC_CONNECTION_KIND=staging - -CLIENT_ID='5DYm3Wk4aa1BbfhH1ajmY6MNEELXoicmKRnP4tzHYjSKnD9K' -SELLER_SOONSOCIAL_FE_CLIENT_TOKEN_SIGNER='retire strong pole intact cool music high path salt praise stadium spatial' - -# Id for Google Analytics -# NEXT_PUBLIC_GA_ID= - -# NEXT_PUBLIC_ENABLE_MAINTENANCE_PAGE=true -# NEXT_PUBLIC_MAINTENANCE_TEXT='' - -# NEXT_PUBLIC_SUBSTRATE_URL= -# NEXT_PUBLIC_SUBSTRATE_RPC_URL= -# NEXT_PUBLIC_OFFCHAIN_URL= -# NEXT_PUBLIC_OFFCHAIN_WS= -# NEXT_PUBLIC_GRAPHQL_URL= -# NEXT_PUBLIC_IPFS_NODE_URL= - -# UI settings overwrite -# NEXT_PUBLIC_ENABLE_SEARCH=true -# NEXT_PUBLIC_ENABLE_FEED=true -# NEXT_PUBLIC_ENABLE_NOTIFICATIONS=true -# NEXT_PUBLIC_ENABLE_ACTIVITY=true -# NEXT_PUBLIC_ENABLE_SESSION_KEY=true -# NEXT_PUBLIC_ENABLE_EMAIL_SETTINGS=true -# NEXT_PUBLIC_ENABLE_FAUCET=true -# NEXT_PUBLIC_ENABLE_DOWNVOTES=true -# NEXT_PUBLIC_ENABLE_GRAPHQL=true -# NEXT_PUBLIC_ENABLE_CONTRIBUTION_PAGE=true -# NEXT_PUBLIC_ENABLE_ONCHAIN_ACTIVITIES=true -# NEXT_PUBLIC_ENABLE_SQUID_DATA_SOURCE=true diff --git a/.gitignore b/.gitignore index 2bb7e1c0a..028c3dfcf 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,7 @@ typings/ .yarn-integrity # dotenv environment variables file +.env*.local .env public/env.js diff --git a/dev.env b/dev.env index 2d6c99493..f6c6918a6 100644 --- a/dev.env +++ b/dev.env @@ -1,39 +1,42 @@ # Logger level -LOG_LEVEL=debug +NEXT_PUBLIC_LOG_LEVEL=debug # App kind: 'polkaverse' | 'staging' -APP_KIND=polkaverse +NEXT_PUBLIC_APP_KIND=polkaverse # Connection kind: # 'local' - For development in localhost infrastructure (local Substrate, IPFS, etc.) # 'dev' - For development in betanet/mainnet infrastructure. # 'staging' - For development in staging infrastructure. # 'main' - If running this web app on a production server. -CONNECTION_KIND=dev +NEXT_PUBLIC_CONNECTION_KIND=staging + +SELLER_CLIENT_ID='' +SELLER_SOONSOCIAL_FE_CLIENT_TOKEN_SIGNER='' # Id for Google Analytics -# GA_ID= +# NEXT_PUBLIC_GA_ID= -# ENABLE_MAINTENANCE_PAGE=true -# MAINTENANCE_TEXT='' +# NEXT_PUBLIC_ENABLE_MAINTENANCE_PAGE=true +# NEXT_PUBLIC_MAINTENANCE_TEXT='' -# SUBSTRATE_URL= -# SUBSTRATE_RPC_URL= -# OFFCHAIN_URL= -# OFFCHAIN_WS= -# GRAPHQL_URL= -# IPFS_NODE_URL= +# NEXT_PUBLIC_SUBSTRATE_URL= +# NEXT_PUBLIC_SUBSTRATE_RPC_URL= +# NEXT_PUBLIC_OFFCHAIN_URL= +# NEXT_PUBLIC_OFFCHAIN_WS= +# NEXT_PUBLIC_GRAPHQL_URL= +# NEXT_PUBLIC_IPFS_NODE_URL= # UI settings overwrite -# ENABLE_SEARCH=true -# ENABLE_FEED=true -# ENABLE_NOTIFICATIONS=true -# ENABLE_ACTIVITY=true -# ENABLE_SESSION_KEY=true -# ENABLE_EMAIL_SETTINGS=true -# ENABLE_FAUCET=true -# ENABLE_DOWNVOTES=true -# ENABLE_GRAPHQL=true -# ENABLE_CONTRIBUTION_PAGE=true -# ENABLE_ONCHAIN_ACTIVITIES=true -# ENABLE_SQUID_DATA_SOURCE=true +# NEXT_PUBLIC_ENABLE_SEARCH=true +# NEXT_PUBLIC_ENABLE_FEED=true +# NEXT_PUBLIC_ENABLE_NOTIFICATIONS=true +# NEXT_PUBLIC_ENABLE_ACTIVITY=true +# NEXT_PUBLIC_ENABLE_SESSION_KEY=true +# NEXT_PUBLIC_ENABLE_EMAIL_SETTINGS=true +# NEXT_PUBLIC_ENABLE_FAUCET=true +# NEXT_PUBLIC_ENABLE_DOWNVOTES=true +# NEXT_PUBLIC_ENABLE_GRAPHQL=true +# NEXT_PUBLIC_ENABLE_CONTRIBUTION_PAGE=true +# NEXT_PUBLIC_ENABLE_ONCHAIN_ACTIVITIES=true +# NEXT_PUBLIC_ENABLE_SQUID_DATA_SOURCE=true diff --git a/package.json b/package.json index af7235202..516785115 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "check": "yarn lint", "lint": "tsc && eslint --cache 'src/**/*.{ts,tsx,js}'", "pre-commit": "pretty-quick --staged && yarn run lint", - "test": "yarn patch && echo \"skipping tests\"", + "test": "echo \"skipping tests\"", "test:e2e": "yarn build && yarn cy:test", "test:e2e:video": "yarn build && yarn cy:test:video", "cy:open": "cypress open", @@ -22,11 +22,9 @@ "cy:run": "export CYPRESS_VIDEO=false && cypress run", "cy:run:video": "cypress run", "dev": "NODE_OPTIONS=--max_old_space_size=4096 next -p 3003", - "analyze": "yarn patch && ANALYZE=true next build", - "build": "yarn patch && next build", + "analyze": "ANALYZE=true next build", + "build": "next build", "export": "next export", - "export-env": "node export-env.js", - "patch": "yarn export-env", "start": "NODE_ENV=production yarn patch && next start -p 3003", "graphql:types": "./scripts/graphql-generate-types.sh", "prepare": "husky install", diff --git a/src/pages/_app.js b/src/pages/_app.js index b617e214e..476894108 100644 --- a/src/pages/_app.js +++ b/src/pages/_app.js @@ -47,7 +47,7 @@ function MyApp(props) { return ( <> -