+
+ Eth Wallet Balance: {formatEther(ethSqtBalance.data, 4)} {TOKEN}
+
+
+ Your SQT needs to be on Polygon in order to be used on the SubQuery Network. To move SQT from the Ethereum
+ to Polygon, you’ll need to bridge them across.
+
+
+
+
+
+
+ }
+ >
+ {props.children ? props.children : }
+
+ );
+};
+export default TokenTooltip;
diff --git a/src/components/TokenTooltip/index.module.less b/src/components/TokenTooltip/index.module.less
new file mode 100644
index 000000000..99f77ede6
--- /dev/null
+++ b/src/components/TokenTooltip/index.module.less
@@ -0,0 +1,9 @@
+.tokenTooltip {
+
+ :global {
+ .ant-tooltip-inner {
+ padding: 16px;
+ width: 305px;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/config/dayjsConf.ts b/src/config/dayjsConf.ts
index 6e1f611d3..32240fcee 100644
--- a/src/config/dayjsConf.ts
+++ b/src/config/dayjsConf.ts
@@ -5,13 +5,17 @@ import dayjs from 'dayjs';
import advancedFormat from 'dayjs/plugin/advancedFormat';
import customParseFormat from 'dayjs/plugin/customParseFormat';
import localeData from 'dayjs/plugin/localeData';
+import relativeTime from 'dayjs/plugin/relativeTime';
+import utc from 'dayjs/plugin/utc';
import weekday from 'dayjs/plugin/weekday';
import weekOfYear from 'dayjs/plugin/weekOfYear';
import weekYear from 'dayjs/plugin/weekYear';
+dayjs.extend(utc);
dayjs.extend(customParseFormat);
dayjs.extend(advancedFormat);
dayjs.extend(weekday);
dayjs.extend(localeData);
dayjs.extend(weekOfYear);
dayjs.extend(weekYear);
+dayjs.extend(relativeTime);
diff --git a/src/config/rainbowConf.tsx b/src/config/rainbowConf.tsx
index efaad1eb2..e0ebeb1f1 100644
--- a/src/config/rainbowConf.tsx
+++ b/src/config/rainbowConf.tsx
@@ -4,12 +4,14 @@
import React from 'react';
import { connectorsForWallets, RainbowKitProvider } from '@rainbow-me/rainbowkit';
import { metaMaskWallet, rainbowWallet, talismanWallet, walletConnectWallet } from '@rainbow-me/rainbowkit/wallets';
-import { configureChains, createConfig, WagmiConfig } from 'wagmi';
-import { polygon, polygonMumbai } from 'wagmi/chains';
+import { configureChains, createConfig, mainnet, WagmiConfig } from 'wagmi';
+import { goerli, polygon, polygonMumbai } from 'wagmi/chains';
import { publicProvider } from 'wagmi/providers/public';
import '@rainbow-me/rainbowkit/styles.css';
-const supportedChains = import.meta.env.VITE_NETWORK === 'testnet' ? [polygonMumbai] : [polygon];
+
+// goerli and mainnet just for get data actually not supported
+const supportedChains = import.meta.env.VITE_NETWORK === 'testnet' ? [polygonMumbai, goerli] : [polygon, mainnet];
// This should ok. It seems is a bug of Ts.
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
diff --git a/src/pages/swap/index.ts b/src/const/bridge.ts
similarity index 61%
rename from src/pages/swap/index.ts
rename to src/const/bridge.ts
index 23be6f9aa..a39f52ba3 100644
--- a/src/pages/swap/index.ts
+++ b/src/const/bridge.ts
@@ -1,4 +1,4 @@
// Copyright 2020-2022 SubQuery Pte Ltd authors & contributors
// SPDX-License-Identifier: Apache-2.0
-export * from './Swap';
+export const BRIDGE_URL = 'https://portal.polygon.technology/';
diff --git a/src/containers/ProjectMetadata.ts b/src/containers/ProjectMetadata.ts
index 2e2dbda4e..f7c860f2a 100644
--- a/src/containers/ProjectMetadata.ts
+++ b/src/containers/ProjectMetadata.ts
@@ -18,8 +18,8 @@ function useProjectMetadataImpl() {
const result = await catSingle(cid);
const rawMeta = JSON.parse(Buffer.from(result).toString('utf8'));
- console.warn(rawMeta);
- return projectMetadataSchema.validate({ type: 'SUBQUERY', ...rawMeta });
+
+ return projectMetadataSchema.validate({ ...rawMeta });
};
const uploadMetadata = async (meta: ProjectMetadata): Promise => {
diff --git a/src/containers/ProjectRegistry.ts b/src/containers/ProjectRegistry.ts
index c835355ac..1ca5afebf 100644
--- a/src/containers/ProjectRegistry.ts
+++ b/src/containers/ProjectRegistry.ts
@@ -12,23 +12,13 @@ import { useWeb3Store } from 'src/stores';
import { bytes32ToCid } from '../utils';
import { createContainer, Logger } from './Container';
-function projectTypeTransform(type: InputProjectType): ProjectType {
- switch (type) {
- case InputProjectType.SUBQUERY:
- return ProjectType.SUBQUERY;
- case InputProjectType.RPC:
- return ProjectType.RPC;
- default:
- return ProjectType.SUBQUERY;
- }
-}
-
type QueryDetails = {
queryId: BigNumber;
owner: string;
metadata: string; // IPFS Cid
deployment: string; // IPFS Cid
version: string; // IPFS Cid
+ type: ProjectType;
};
function useProjectRegistryImpl(logger: Logger) {
@@ -51,7 +41,7 @@ function useProjectRegistryImpl(logger: Logger) {
metadataCid,
cidToBytes32(deploymentMetadata),
cidToBytes32(deploymentId),
- projectTypeTransform(type),
+ type,
);
};
@@ -134,36 +124,16 @@ function useProjectRegistryImpl(logger: Logger) {
metadata: uri.replace(/^ipfs:\/\//, ''),
deployment: bytes32ToCid(project.latestDeploymentId),
version: bytes32ToCid(deploymentInfo.metadata),
+ type: project.projectType,
};
}
return projectCache.current[BigNumber.from(id).toString()];
};
- // const getUserQueries = React.useCallback(
- // async (address: string): Promise => {
- // if (!pendingContracts) {
- // throw new Error('ProjectRegistry contract not available');
- // // return [];
- // }
-
- // const contracts = await pendingContracts;
-
- // const count = await contracts.projectRegistry.queryInfoCountByOwner(address);
-
- // return await Promise.all(
- // Array.from(new Array(count.toNumber()).keys()).map((_, index) =>
- // contracts.projectRegistry.queryInfoIdsByOwner(address, index),
- // ),
- // );
- // },
- // [pendingContracts],
- // );
-
return {
registerProject,
getQuery,
- // getUserQueries,
updateQueryMetadata,
updateDeployment,
};
diff --git a/src/containers/SQToken.ts b/src/containers/SQToken.ts
index dbbb2b591..126aed9bd 100644
--- a/src/containers/SQToken.ts
+++ b/src/containers/SQToken.ts
@@ -12,7 +12,7 @@ import { createContainer } from './Container';
function useSQTokenImpl() {
const { address: account } = useAccount();
- const { contracts } = useWeb3Store();
+ const { contracts, rootContracts } = useWeb3Store();
const balance = useAsyncMemo(async () => {
assert(contracts, 'Contracts not available');
assert(account, 'Account not available');
@@ -20,6 +20,13 @@ function useSQTokenImpl() {
return limitContract(() => contracts.sqToken.balanceOf(account));
}, [account, contracts]);
+ const ethSqtBalance = useAsyncMemo(async () => {
+ assert(rootContracts, 'Contracts not available');
+ assert(account, 'Account not available');
+
+ return limitContract(() => rootContracts.sqToken.balanceOf(account));
+ }, [account, rootContracts]);
+
const consumerHostBalance = useAsyncMemo(async () => {
assert(contracts, 'Contracts not available');
assert(account, 'Account not available');
@@ -64,6 +71,7 @@ function useSQTokenImpl() {
return {
balance,
+ ethSqtBalance,
consumerHostBalance,
stakingAllowance,
planAllowance,
diff --git a/src/containers/Web3.tsx b/src/containers/Web3.tsx
index a30632024..aa0780d2f 100644
--- a/src/containers/Web3.tsx
+++ b/src/containers/Web3.tsx
@@ -2,7 +2,6 @@
// SPDX-License-Identifier: Apache-2.0
import React from 'react';
-import { SubqueryNetwork } from '@subql/contract-sdk';
import mainnetJSON from '@subql/contract-sdk/publish/mainnet.json';
import testnetJSON from '@subql/contract-sdk/publish/testnet.json';
import { NETWORKS_CONFIG_INFO, SQNetworks } from '@subql/network-config';
diff --git a/src/hooks/useCreateProject.tsx b/src/hooks/useCreateProject.tsx
index ec3d50ef7..6cf6aa612 100644
--- a/src/hooks/useCreateProject.tsx
+++ b/src/hooks/useCreateProject.tsx
@@ -3,12 +3,11 @@
import * as React from 'react';
import { BigNumberish } from '@ethersproject/bignumber';
-import { ProjectType } from '@subql/network-query';
import { useIPFS, useProjectMetadata, useProjectRegistry } from '../containers';
-import { FormCreateProjectMetadata, ProjectMetadata } from '../models';
+import { FormCreateProjectMetadata, ProjectMetadata, ProjectType } from '../models';
-type P = FormCreateProjectMetadata & { versionDescription: string };
+type P = FormCreateProjectMetadata & { versionDescription: string; type: ProjectType };
export function useCreateProject(): (params: P) => Promise {
const { uploadMetadata, uploadVersionMetadata } = useProjectMetadata();
diff --git a/src/hooks/useInitContracts.ts b/src/hooks/useInitContracts.ts
index 9dc78d6bb..017b3c6de 100644
--- a/src/hooks/useInitContracts.ts
+++ b/src/hooks/useInitContracts.ts
@@ -3,9 +3,12 @@
import React from 'react';
import { NETWORK_NAME } from '@containers/Web3';
-import { ContractSDK } from '@subql/contract-sdk';
+import { ContractSDK, SQToken__factory } from '@subql/contract-sdk';
+import mainnetJSON from '@subql/contract-sdk/publish/mainnet.json';
+import testnetJSON from '@subql/contract-sdk/publish/testnet.json';
import { ContractClient } from '@subql/network-clients';
import { parseError } from '@utils';
+import { goerli, mainnet } from 'viem/chains';
import { useWeb3Store } from 'src/stores';
@@ -13,9 +16,12 @@ import { useEthersProviderWithPublic, useEthersSigner } from './useEthersProvide
export function useInitContracts(): { loading: boolean } {
const [isLoading, setIsLoading] = React.useState(false);
- const { setContracts, setContractClient } = useWeb3Store();
+ const { setContracts, setRootContracts, setContractClient } = useWeb3Store();
const { signer } = useEthersSigner();
const provider = useEthersProviderWithPublic();
+ const ethereumProvider = useEthersProviderWithPublic({
+ chainId: import.meta.env.MODE === 'testnet' ? goerli.id : mainnet.id,
+ });
React.useEffect(() => {
function initContract() {
@@ -32,6 +38,17 @@ export function useInitContracts(): { loading: boolean } {
parseError(error);
}
}
+
+ if (ethereumProvider) {
+ const sqTokenContract = SQToken__factory.connect(
+ import.meta.env.MODE === 'testnet' ? testnetJSON.root.SQToken.address : mainnetJSON.root.SQToken.address,
+ ethereumProvider,
+ );
+ const rootContractInstance = {
+ sqToken: sqTokenContract,
+ };
+ setRootContracts(rootContractInstance);
+ }
}
setIsLoading(true);
initContract();
diff --git a/src/hooks/useProject.tsx b/src/hooks/useProject.tsx
index bf13e82e9..41b3164b0 100644
--- a/src/hooks/useProject.tsx
+++ b/src/hooks/useProject.tsx
@@ -65,6 +65,7 @@ export function useProject(id: string): AsyncData {
version: query.version,
metadata,
deploymentId: query.deployment,
+ type: query.type,
};
}, [id, catSingle, getMetadataFromCid, getQuery, cacheBreak]);
}
diff --git a/src/hooks/useSortedIndexerDeployments.tsx b/src/hooks/useSortedIndexerDeployments.tsx
index 5622616a3..c4e018110 100644
--- a/src/hooks/useSortedIndexerDeployments.tsx
+++ b/src/hooks/useSortedIndexerDeployments.tsx
@@ -65,7 +65,6 @@ export function useSortedIndexerDeployments(indexer: string): AsyncDatahere<1>',
topRowData: 'Top row of the data represents the data in current era.',
secondRowData: 'Data displayed after means the data that will take into effect from next era.',
@@ -103,7 +103,7 @@ const translation = {
myDelegators: {
noDelegatorsTitle: 'You don’t have any Delegators yet',
noDelegatorsDescription:
- 'Once Delegators have delegated their kSQT to you, they will appear here. First you need to register as an Indexer and begin indexing SubQuery projects, Delegators can then delegate their kSQT to you to earn rewards. Delegators are more likely to delegate their kSQT to high performing Indexers and Consumers will be attracted to Indexers with more kSQT delegated as it indicates they are reliable.',
+ 'Once Delegators have delegated their SQT to you, they will appear here. First you need to register as an Indexer and begin indexing SubQuery projects, Delegators can then delegate their SQT to you to earn rewards. Delegators are more likely to delegate their SQT to high performing Indexers and Consumers will be attracted to Indexers with more SQT delegated as it indicates they are reliable.',
noDelegatorsInfoLink: 'Learn more about Delegators ',
},
tokenApproval: {
@@ -121,7 +121,7 @@ const translation = {
failureCollect: 'Sorry, collect rewards transaction has failed.',
},
topIndexers: {
- desc: 'View the top 100 ranked Indexers and all other Indexers in the SubQuery Network and delegate your kSQT tokens to earn rewards.',
+ desc: 'View the top 100 ranked Indexers and all other Indexers in the SubQuery Network and delegate your SQT tokens to earn rewards.',
nonData: 'There is no data to display',
rank: 'indexer rank',
uptime: 'uptime',
@@ -151,7 +151,7 @@ const translation = {
},
allIndexers: {
nonData: 'There is no Indexer available.',
- desc: 'View all Indexers in the SubQuery Network and delegate your kSQT tokens to earn rewards.',
+ desc: 'View all Indexers in the SubQuery Network and delegate your SQT tokens to earn rewards.',
},
} as const;
diff --git a/src/index.less b/src/index.less
index 8a414eec0..5da2d45c5 100644
--- a/src/index.less
+++ b/src/index.less
@@ -21,7 +21,7 @@ html {
:root {
--gradient-from: #ff4581;
- --gradient-to: #1677ff;
+ --gradient-to: var(--sq-blue600);
--sq-gradient: linear-gradient(293.04deg, var(--gradient-from) 4.09%, var(--gradient-to) 70.16%);
--sq-background-gradient: linear-gradient(293.04deg, rgba(255, 69, 129, 0.1) 4.09%, rgba(67, 136, 221, 0.1) 70.16%);
--primary: #1677ff;
@@ -298,4 +298,9 @@ label,
.staticButton.ant-btn-primary {
background-color: rgba(67, 136, 221, 0.10);
color: var(--sq-blue600);
-}
\ No newline at end of file
+}
+
+.ant-btn-primary.ant-btn-background-ghost {
+ border-color: var(--sq-blue600);
+ color: var(--sq-blue600);
+}
diff --git a/src/models.tsx b/src/models.tsx
index 200200dcb..1fd7ebc61 100644
--- a/src/models.tsx
+++ b/src/models.tsx
@@ -12,7 +12,6 @@ export enum ProjectType {
export const projectMetadataSchema = yup.object({
name: yup.string().defined(),
- type: yup.string().oneOf(['SUBQUERY', 'RPC'], 'Only RPC and SUBQUERY are allowed.').required(),
image: yup.string().optional(),
description: yup.string().default('').optional(),
websiteUrl: yup.string().optional().url(),
@@ -39,6 +38,7 @@ export type ProjectDetails = {
metadata: ProjectMetadata;
version: string;
deploymentId: string;
+ type: ProjectType;
};
export const newDeploymentSchema = yup.object({
diff --git a/src/pages/consumer/MyOffers/CreateOffer/Summary/Summary.module.css b/src/pages/consumer/MyOffers/CreateOffer/Summary/Summary.module.css
index 3eb49e26f..d5b5d8d86 100644
--- a/src/pages/consumer/MyOffers/CreateOffer/Summary/Summary.module.css
+++ b/src/pages/consumer/MyOffers/CreateOffer/Summary/Summary.module.css
@@ -5,10 +5,6 @@
padding: 1rem;
}
-.steps {
- margin: 1rem 0;
-}
-
.tabs {
display: flex;
justify-content: space-between;
diff --git a/src/pages/consumer/MyOffers/CreateOffer/Summary/Summary.tsx b/src/pages/consumer/MyOffers/CreateOffer/Summary/Summary.tsx
index 0d4abc069..c19b95add 100644
--- a/src/pages/consumer/MyOffers/CreateOffer/Summary/Summary.tsx
+++ b/src/pages/consumer/MyOffers/CreateOffer/Summary/Summary.tsx
@@ -144,7 +144,7 @@ export const Summary: React.FC = () => {
},
{
label: t('myOffers.step_2.expireDate'),
- value: offer?.expireDate ? dayjs(offer.expireDate).format() : dayjs(),
+ value: offer?.expireDate ? dayjs(offer.expireDate).format() : dayjs().format(),
},
];
diff --git a/src/pages/delegator/DoDelegate/DelegateFrom.tsx b/src/pages/delegator/DoDelegate/DelegateFrom.tsx
index e2d7763e6..0314a4664 100644
--- a/src/pages/delegator/DoDelegate/DelegateFrom.tsx
+++ b/src/pages/delegator/DoDelegate/DelegateFrom.tsx
@@ -5,6 +5,7 @@ import * as React from 'react';
import { useTranslation } from 'react-i18next';
import { BsExclamationCircle } from 'react-icons/bs';
import { useNavigate } from 'react-router';
+import TokenTooltip from '@components/TokenTooltip/TokenTooltip';
import { useFetchMetadata } from '@hooks/useFetchMetadata';
import { Typography } from '@subql/components';
import { useGetDelegationQuery, useGetDelegationsLazyQuery } from '@subql/react-hooks';
@@ -123,10 +124,15 @@ export const DelegateForm: React.FC = ({
const maxAmountText = React.useMemo(() => {
if (isYourself) {
- return t('delegate.walletBalance', {
- balance: formatEther(balance.data, 4),
- token: TOKEN,
- });
+ return (
+ <>
+ {t('delegate.walletBalance', {
+ balance: formatEther(balance.data, 4),
+ token: TOKEN,
+ })}{' '}
+
+ >
+ );
}
return t('delegate.amountAvailable', {
balance: sortedMaxAmount,
diff --git a/src/pages/indexer/MyPlans/Create/Create.tsx b/src/pages/indexer/MyPlans/Create/Create.tsx
index 919d2def9..2cc8c5e12 100644
--- a/src/pages/indexer/MyPlans/Create/Create.tsx
+++ b/src/pages/indexer/MyPlans/Create/Create.tsx
@@ -216,6 +216,7 @@ const PlanForm: React.FC = ({ templates, onSubmit, onCancel, curStep,
value: ` ${template.rateLimit} queries/sec`,
},
];
+
return (
= ({ templates, onSubmit, onCancel, curStep,
+ = ({ data, onRefresh, title }) => {
return 'inactive';
};
return (
-
+
{text()}
);
diff --git a/src/pages/indexer/MyProjects/OwnDeployments/OwnDeployments.tsx b/src/pages/indexer/MyProjects/OwnDeployments/OwnDeployments.tsx
index 5df45cfb2..010e126a8 100644
--- a/src/pages/indexer/MyProjects/OwnDeployments/OwnDeployments.tsx
+++ b/src/pages/indexer/MyProjects/OwnDeployments/OwnDeployments.tsx
@@ -4,7 +4,7 @@
import * as React from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
-import { ProgressBar, Spinner } from '@subql/components';
+import { Spinner, SubqlProgress } from '@subql/components';
import { TableTitle } from '@subql/components';
import { getDeploymentStatus } from '@utils/getIndexerStatus';
import { Table, TableProps, Typography } from 'antd';
@@ -51,7 +51,9 @@ export const OwnDeployments: React.FC = ({ indexer, emptyList, desc }) =>
{indexingProgressErr}
-
- Only participants that have been KYC’d and whitelisted can participate in the SubQuery Kepler Swap.
- You can see a list of all existing whitelisted participants{' '}
-
- here
-
- .
-
-
- If you’re new here, check out{' '}
-
- this article
- {' '}
- and follow the instructions on how to join.
-
-
- If you need any help, you can reach out on the #kepler-swap-support channel in our{' '}
-
- Discord
-
- .
-
-