Compare commits

..
73 changed files with 518 additions and 686 deletions
+26 -25
View File
@@ -191,36 +191,37 @@ jobs:
-d '{"query": "mutation{triggerDeploy(siteId:\"f8f2e051-f18e-49e6-b876-0a39369dc0d8\"){id status}}"}' \
https://api.fleek.co/graphql
- name: Update vega.trading DNS to redirect to the new console
- name: Checkout vega.xyz
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }}
uses: actions/checkout@v3
with:
repository: vegaprotocol/vega.xyz
path: './vega-xyz'
token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
- name: Update hash on interstitial page
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }}
env:
GH_TOKEN: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
run: |
curl -L https://dist.ipfs.tech/kubo/v0.20.0/kubo_v0.20.0_linux-amd64.tar.gz -o kubo.tgz
tar -xzf kubo.tgz
export PATH="$PATH:$PWD/kubo"
which ipfs
new_hash=$(cat ${{ matrix.app }}-ipfs-hash)
new_cid=$(ipfs cid format -v 1 -b base32 $new_hash)
cd vega-xyz
./interstital-allow-update.sh ${new_hash}
git config --global user.email "vega-ci-bot@vega.xyz"
git config --global user.name "vega-ci-bot"
git add interstitial-allow.json netlify.toml
commit_msg="feat(ci): Update CID for console release @ ${{ github.ref }}"
git commit -m "${commit_msg}"
git push origin main
# Generate console URL
new_console_url_type=ipfs
# new_console_url_type=ipns
new_console_url_domain=cf-ipfs.com
# new_console_url_domain=dweb.link
new_console_url="https://${new_cid}.${new_console_url_type}.${new_console_url_domain}/"
echo "new_console_url=${new_console_url}"
# Update record in DNSimple
# docs: https://developer.dnsimple.com/v2/zones/records/#updateZoneRecord
dnsimple_account_id=84895
dnsimple_zone_name=vega.trading
dnsimple_record_id=44409591
# see: https://dnsimple.com/a/84895/domains/vega.trading/records/44409591/edit
curl -H 'Authorization: Bearer ${{ secrets.DNSIMPLE_API_TOKEN }}' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-X PATCH \
-d "{
\"content\": \"${new_console_url}\"
}" \
https://api.dnsimple.com/v2/${dnsimple_account_id}/zones/${dnsimple_zone_name}/records/${dnsimple_record_id}
# branch_name=${{ github.ref_name }}-hash-update
# git checkout -b "${branch_name}"
# git add interstitial-allow.json netlify.toml
# git push -u origin "${branch_name}"
# pr_url="$(gh pr create --title "${commit_msg}" --body 'update ipfs hash for console @ ${{ github.ref }}')"
# echo $pr_url
# gh pr merge --admin --auto $pr_url
@@ -3,7 +3,6 @@ import { Header } from './header';
import { MemoryRouter } from 'react-router-dom';
jest.mock('@vegaprotocol/environment', () => ({
...jest.requireActual('@vegaprotocol/environment'),
NetworkSwitcher: () => (
<div data-testid="network-switcher">NetworkSwitcher</div>
),
@@ -63,6 +63,7 @@ context(
});
it('should have option to go to last and newest page', function () {
waitForBeginningOfEpoch();
cy.getByTestId('goto-last-page').click();
cy.getByTestId('epoch-total-rewards-table')
.last()
@@ -1,6 +1,6 @@
import { Link } from '@vegaprotocol/ui-toolkit';
import { useTranslation } from 'react-i18next';
import { ExternalLinks } from '@vegaprotocol/environment';
import { ExternalLinks } from '@vegaprotocol/utils';
export const DownloadWalletPrompt = () => {
const { t } = useTranslation();
@@ -594,9 +594,7 @@
"numberOfAgainstVotes": "Number of votes against",
"yesPercentage": "Yes percentage",
"noPercentage": "No percentage",
"proposalJson": "Full proposal JSON",
"proposalDetails": "Proposal details",
"proposalDescription": "Description",
"proposalTerms": "Proposal terms",
"currentlySetTo": "Currently expected to ",
"currently": "currently",
"finalOutcomeMayDiffer": "Final outcome may differ",
+1 -2
View File
@@ -12,8 +12,7 @@ import { useRefreshAfterEpoch } from '../../hooks/use-refresh-after-epoch';
import { ProposalsListItem } from '../proposals/components/proposals-list-item';
import { ProtocolUpgradeProposalsListItem } from '../proposals/components/protocol-upgrade-proposals-list-item/protocol-upgrade-proposals-list-item';
import Routes from '../routes';
import { ExternalLinks } from '@vegaprotocol/environment';
import { removePaginationWrapper } from '@vegaprotocol/utils';
import { ExternalLinks, removePaginationWrapper } from '@vegaprotocol/utils';
import { useNodesQuery } from '../staking/home/__generated__/Nodes';
import { useProposalsQuery } from '../proposals/proposals/__generated__/Proposals';
import {
@@ -1 +0,0 @@
export { ProposalDescription } from './proposal-description';
@@ -1,51 +0,0 @@
import ReactMarkdown from 'react-markdown';
import classnames from 'classnames';
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Icon, RoundedWrapper } from '@vegaprotocol/ui-toolkit';
import { SubHeading } from '../../../../components/heading';
export const ProposalDescription = ({
description,
}: {
description: string;
}) => {
const { t } = useTranslation();
const [showDescription, setShowDescription] = useState(false);
const showDescriptionIconClasses = classnames('mb-4', {
'rotate-180': showDescription,
});
return (
<section data-testid="proposal-description">
<button
onClick={() => setShowDescription(!showDescription)}
data-testid="proposal-description-toggle"
>
<div className="flex items-center gap-3">
<SubHeading title={t('proposalDescription')} />
<div className={showDescriptionIconClasses}>
<Icon name="chevron-down" size={8} />
</div>
</div>
</button>
{showDescription && (
<RoundedWrapper paddingBottom={true} marginBottomLarge={true}>
<div className="p-2">
<ReactMarkdown
className="react-markdown-container"
/* Prevents HTML embedded in the description from rendering */
skipHtml={true}
/* Stops users embedding images which could be used for tracking */
disallowedElements={['img']}
linkTarget="_blank"
>
{description}
</ReactMarkdown>
</div>
</RoundedWrapper>
)}
</section>
);
};
@@ -206,6 +206,28 @@ describe('Proposal header', () => {
).not.toBeInTheDocument();
});
it('Renders Freeform proposal - long rationale (105 chars) - details', () => {
renderComponent(
generateProposal({
id: 'long',
rationale: {
title: '0x0',
description:
'Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean dolor.',
},
terms: {
change: {
__typename: 'NewFreeform',
},
},
}),
false
);
expect(screen.getByTestId('proposal-description')).toHaveTextContent(
/Class aptent/
);
});
// Remove once proposals have rationale and re-enable above tests
it('Renders Freeform proposal - id for title', () => {
renderComponent(
@@ -5,6 +5,7 @@ import { Heading, SubHeading } from '../../../../components/heading';
import type { ReactNode } from 'react';
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import ReactMarkdown from 'react-markdown';
import { truncateMiddle } from '../../../../lib/truncate-middle';
import { CurrentProposalState } from '../current-proposal-state';
import { ProposalInfoLabel } from '../proposal-info-label';
@@ -22,7 +23,12 @@ export const ProposalHeader = ({
let details: ReactNode;
let proposalType = '';
const title = proposal?.rationale.title.trim();
let title = proposal?.rationale.title.trim();
let description = proposal?.rationale.description.trim();
if (title?.length === 0 && description && description.length > 0) {
title = description;
description = '';
}
const titleContent = shorten(title ?? '', 100);
@@ -139,6 +145,23 @@ export const ProposalHeader = ({
{details}
</div>
)}
{description && !isListItem && (
<div data-testid="proposal-description">
{/*<div className="uppercase mr-2">{t('ProposalDescription')}:</div>*/}
<SubHeading title={t('ProposalDescription')} />
<ReactMarkdown
className="react-markdown-container"
/* Prevents HTML embedded in the description from rendering */
skipHtml={true}
/* Stops users embedding images which could be used for tracking */
disallowedElements={['img']}
linkTarget="_blank"
>
{description}
</ReactMarkdown>
</div>
)}
</>
);
};
@@ -1 +0,0 @@
export { ProposalJson } from './proposal-json';
@@ -0,0 +1 @@
export { ProposalTermsJson } from './proposal-terms-json';
@@ -1,15 +1,15 @@
import classnames from 'classnames';
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Icon, SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
import { SubHeading } from '../../../../components/heading';
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import type { PartialDeep } from 'type-fest';
import type * as Schema from '@vegaprotocol/types';
import { useState } from 'react';
import classnames from 'classnames';
export const ProposalJson = ({
proposal,
export const ProposalTermsJson = ({
terms,
}: {
proposal: ProposalFieldsFragment | ProposalQuery['proposal'];
terms: PartialDeep<Schema.ProposalTerms>;
}) => {
const { t } = useTranslation();
const [showDetails, setShowDetails] = useState(false);
@@ -18,20 +18,20 @@ export const ProposalJson = ({
});
return (
<section data-testid="proposal-json">
<section>
<button
onClick={() => setShowDetails(!showDetails)}
data-testid="proposal-json-toggle"
data-testid="proposal-terms-toggle"
>
<div className="flex items-center gap-3">
<SubHeading title={t('proposalJson')} />
<SubHeading title={t('proposalTerms')} />
<div className={showDetailsIconClasses}>
<Icon name="chevron-down" size={8} />
</div>
</div>
</button>
{showDetails && <SyntaxHighlighter data={proposal} />}
{showDetails && <SyntaxHighlighter data={terms} />}
</section>
);
};
@@ -1 +0,0 @@
export { ProposalTerms } from './proposal-terms';
@@ -1,142 +0,0 @@
import {
RoundedWrapper,
KeyValueTable,
KeyValueTableRow,
Icon,
} from '@vegaprotocol/ui-toolkit';
import { BigNumber } from '../../../../lib/bignumber';
import { SubHeading } from '../../../../components/heading';
import { useTranslation } from 'react-i18next';
import { useState } from 'react';
import classnames from 'classnames';
interface ProposalTermsProps {
data: Record<string, unknown>;
}
const getParsedValue = (value: unknown) => {
if (typeof value === 'string') {
try {
// Check if value is a number string - if so use bignumber to maintain precision
if (/^\d+(\.\d+)?$/.test(value)) {
return new BigNumber(value).toString();
} else {
// This would convert, for example, a JSON object ('{"key":"value"}')
// into an actual JS object ({key: "value"})
return JSON.parse(value);
}
} catch (error) {
return value;
}
} else {
return value;
}
};
const RenderKeyValue = ({
title,
value,
}: {
title: string;
value: string | number;
}) => (
<KeyValueTable>
<KeyValueTableRow>
{title}
{value}
</KeyValueTableRow>
</KeyValueTable>
);
const RenderArray = ({ title, array }: { title: string; array: unknown[] }) => {
if (array.every((item) => typeof item === 'string')) {
return <RenderKeyValue title={title} value={array.join(', ')} />;
} else {
return (
<div>
<div className="mb-2">{title}</div>
{array.map((item, index) => (
<div key={index}>
<ProposalTermsRenderer data={item as Record<string, unknown>} />
</div>
))}
</div>
);
}
};
// Working with 'unknown' type as a proposal's terms can be in many shapes
const RenderTerm = ({ title, value }: { title: string; value: unknown }) => {
const parsedValue = getParsedValue(value);
if (parsedValue === null || typeof parsedValue === 'boolean') {
return <RenderKeyValue title={title} value={String(parsedValue)} />;
} else if (
typeof parsedValue === 'string' ||
typeof parsedValue === 'number'
) {
return <RenderKeyValue title={title} value={parsedValue} />;
} else if (typeof parsedValue === 'object') {
if (Array.isArray(parsedValue)) {
return <RenderArray title={title} array={parsedValue} />;
} else {
return (
<div>
<div className="my-2">{title}</div>
<ProposalTermsRenderer
data={parsedValue as Record<string, unknown>}
/>
</div>
);
}
} else if (parsedValue === undefined) {
return <span>{'undefined'}</span>;
} else {
return <span>{String(parsedValue)}</span>;
}
};
const ProposalTermsRenderer = ({ data }: ProposalTermsProps) => {
return (
<RoundedWrapper paddingBottom={true}>
{Object.keys(data)
.filter(
(key) =>
!['__typename', 'closingDatetime', 'enactmentDatetime'].includes(
key
)
)
.map((key, index) => (
<div key={index}>
<RenderTerm title={key} value={data[key]} />
</div>
))}
</RoundedWrapper>
);
};
export const ProposalTerms = ({ data }: ProposalTermsProps) => {
const { t } = useTranslation();
const [showTerms, setShowTerms] = useState(false);
const showTermsIconClasses = classnames('mb-4', {
'rotate-180': showTerms,
});
return (
<section data-testid="proposal-terms">
<button
onClick={() => setShowTerms(!showTerms)}
data-testid="proposal-terms-toggle"
>
<div className="flex items-center gap-3">
<SubHeading title={t('proposalDetails')} />
<div className={showTermsIconClasses}>
<Icon name="chevron-down" size={8} />
</div>
</div>
</button>
{showTerms && <ProposalTermsRenderer data={data} />}
</section>
);
};
@@ -25,11 +25,8 @@ jest.mock('../proposal-detail-header/proposal-header', () => ({
jest.mock('../proposal-change-table', () => ({
ProposalChangeTable: () => <div data-testid="proposal-change-table"></div>,
}));
jest.mock('../proposal-json', () => ({
ProposalJson: () => <div data-testid="proposal-json"></div>,
}));
jest.mock('../proposal-terms/proposal-terms', () => ({
ProposalTerms: () => <div data-testid="proposal-terms"></div>,
jest.mock('../proposal-terms-json', () => ({
ProposalTermsJson: () => <div data-testid="proposal-terms-json"></div>,
}));
jest.mock('../proposal-votes-table', () => ({
ProposalVotesTable: () => <div data-testid="proposal-votes-table"></div>,
@@ -52,8 +49,7 @@ it('renders each section', async () => {
render(<Proposal proposal={proposal as ProposalQuery['proposal']} />);
expect(await screen.findByTestId('proposal-header')).toBeInTheDocument();
expect(screen.getByTestId('proposal-change-table')).toBeInTheDocument();
expect(screen.getByTestId('proposal-json')).toBeInTheDocument();
expect(screen.getByTestId('proposal-terms')).toBeInTheDocument();
expect(screen.getByTestId('proposal-terms-json')).toBeInTheDocument();
expect(screen.getByTestId('proposal-votes-table')).toBeInTheDocument();
expect(screen.getByTestId('proposal-vote-details')).toBeInTheDocument();
expect(screen.queryByTestId('proposal-list-asset')).not.toBeInTheDocument();
@@ -6,10 +6,8 @@ import { AsyncRenderer, RoundedWrapper } from '@vegaprotocol/ui-toolkit';
import { ProposalHeader } from '../proposal-detail-header/proposal-header';
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import { ProposalDescription } from '../proposal-description';
import { ProposalChangeTable } from '../proposal-change-table';
import { ProposalJson } from '../proposal-json';
import { ProposalTerms } from '../proposal-terms';
import { ProposalTermsJson } from '../proposal-terms-json';
import { ProposalVotesTable } from '../proposal-votes-table';
import { VoteDetails } from '../vote-details';
import { ListAsset } from '../list-asset';
@@ -22,7 +20,7 @@ export enum ProposalType {
PROPOSAL_NETWORK_PARAMETER = 'PROPOSAL_NETWORK_PARAMETER',
PROPOSAL_FREEFORM = 'PROPOSAL_FREEFORM',
}
export interface ProposalProps {
interface ProposalProps {
proposal: ProposalFieldsFragment | ProposalQuery['proposal'];
}
@@ -80,11 +78,9 @@ export const Proposal = ({ proposal }: ProposalProps) => {
<AsyncRenderer data={params} loading={loading} error={error}>
<section data-testid="proposal">
<ProposalHeader proposal={proposal} isListItem={false} />
<div className="my-10">
<ProposalChangeTable proposal={proposal} />
</div>
{proposal.terms.change.__typename === 'NewAsset' &&
proposal.terms.change.source.__typename === 'ERC20' &&
proposal.id ? (
@@ -94,20 +90,7 @@ export const Proposal = ({ proposal }: ProposalProps) => {
lifetimeLimit={proposal.terms.change.source.lifetimeLimit}
/>
) : null}
<div className="mb-4">
<ProposalDescription description={proposal.rationale.description} />
</div>
<div className="mb-4">
<ProposalTerms data={proposal.terms} />
</div>
<div className="mb-6">
<ProposalJson proposal={proposal} />
</div>
<div className="mb-10">
<div className="mb-12">
<RoundedWrapper paddingBottom={true}>
<VoteDetails
proposal={proposal}
@@ -119,10 +102,10 @@ export const Proposal = ({ proposal }: ProposalProps) => {
/>
</RoundedWrapper>
</div>
<div className="mb-4">
<ProposalVotesTable proposal={proposal} proposalType={proposalType} />
</div>
<ProposalTermsJson terms={proposal.terms} />
</section>
</AsyncRenderer>
);
@@ -8,11 +8,12 @@ import { ProposalsListFilter } from '../proposals-list-filter';
import Routes from '../../../routes';
import { Button, VegaIcon, VegaIconNames } from '@vegaprotocol/ui-toolkit';
import { Link } from 'react-router-dom';
import { createDocsLinks, ExternalLinks } from '@vegaprotocol/utils';
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
import type { ProtocolUpgradeProposalFieldsFragment } from '@vegaprotocol/proposals';
import { DocsLinks, ExternalLinks } from '@vegaprotocol/environment';
import { useEnvironment } from '@vegaprotocol/environment';
interface ProposalsListProps {
proposals: Array<ProposalFieldsFragment | ProposalQuery['proposal']>;
@@ -35,6 +36,7 @@ export const ProposalsList = ({
protocolUpgradeProposals,
lastBlockHeight,
}: ProposalsListProps) => {
const { VEGA_DOCS_URL } = useEnvironment();
const { t } = useTranslation();
const [filterString, setFilterString] = useState('');
const sortedProposals = proposals.reduce(
@@ -81,9 +83,9 @@ export const ProposalsList = ({
marginBottom={false}
title={t('pageTitleProposals')}
/>
{DocsLinks && (
{VEGA_DOCS_URL && (
<div className="xs:justify-self-end" data-testid="new-proposal-link">
<ExternalLink href={DocsLinks.PROPOSALS_GUIDE}>
<ExternalLink href={createDocsLinks(VEGA_DOCS_URL).PROPOSALS_GUIDE}>
<Button variant="primary" size="sm">
<div className="flex items-center gap-1">
{t('NewProposal')}
@@ -2,10 +2,9 @@ import { render, screen } from '@testing-library/react';
import { ProposalFormTerms } from './proposal-form-terms';
jest.mock('@vegaprotocol/environment', () => ({
...jest.requireActual('@vegaprotocol/environment'),
DocsLinks: {
PROPOSALS_GUIDE: 'https://docs.vega.xyz/tutorials/proposals',
},
useEnvironment: () => ({
VEGA_DOCS_URL: 'https://docs.vega.xyz',
}),
}));
const renderComponent = () => {
@@ -5,7 +5,8 @@ import {
ExternalLink,
TextArea,
} from '@vegaprotocol/ui-toolkit';
import { DocsLinks } from '@vegaprotocol/environment';
import { createDocsLinks } from '@vegaprotocol/utils';
import { useEnvironment } from '@vegaprotocol/environment';
import type { UseFormRegisterReturn } from 'react-hook-form';
interface ProposalFormTermsProps {
@@ -21,20 +22,23 @@ export const ProposalFormTerms = ({
labelOverride,
docsLink,
}: ProposalFormTermsProps) => {
const { VEGA_DOCS_URL } = useEnvironment();
const { t } = useTranslation();
return (
<FormGroup
label={labelOverride || t('ProposalTerms')}
labelFor="proposal-terms"
>
{docsLink && DocsLinks && (
{docsLink && VEGA_DOCS_URL && (
<div className="mt-[-4px] mb-2 text-sm font-light">
<span className="mr-1">{t('ProposalTermsText')}</span>
<ExternalLink
href={`${DocsLinks.PROPOSALS_GUIDE}${docsLink}`}
href={`${
createDocsLinks(VEGA_DOCS_URL).PROPOSALS_GUIDE
}${docsLink}`}
target="_blank"
>
{`${DocsLinks.PROPOSALS_GUIDE}${docsLink}`}
{`${createDocsLinks(VEGA_DOCS_URL).PROPOSALS_GUIDE}${docsLink}`}
</ExternalLink>
</div>
)}
@@ -10,10 +10,9 @@ import type { MockedResponse } from '@apollo/client/testing';
import { NetworkParamsDocument } from '@vegaprotocol/network-parameters';
jest.mock('@vegaprotocol/environment', () => ({
...jest.requireActual('@vegaprotocol/environment'),
DocsLinks: {
PROPOSALS_GUIDE: 'https://docs.vega.xyz/tutorials/proposals',
},
useEnvironment: () => ({
VEGA_DOCS_URL: 'https://docs.vega.xyz',
}),
}));
const updateMarketNetworkParamsQueryMock: MockedResponse<NetworkParamsQuery> = {
@@ -5,7 +5,7 @@ import {
useProposalSubmit,
deadlineToRoundedHours,
} from '@vegaprotocol/proposals';
import { useEnvironment, DocsLinks } from '@vegaprotocol/environment';
import { useEnvironment } from '@vegaprotocol/environment';
import {
ProposalFormDescription,
ProposalFormSubheader,
@@ -17,6 +17,7 @@ import {
import { ProposalMinRequirements } from '../../components/shared';
import { AsyncRenderer, ExternalLink } from '@vegaprotocol/ui-toolkit';
import { Heading } from '../../../../components/heading';
import { createDocsLinks } from '@vegaprotocol/utils';
import {
NetworkParams,
useNetworkParams,
@@ -41,7 +42,7 @@ export const ProposeFreeform = () => {
NetworkParams.governance_proposal_freeform_minProposerBalance,
NetworkParams.spam_protection_proposal_min_tokens,
]);
const { VEGA_EXPLORER_URL } = useEnvironment();
const { VEGA_DOCS_URL, VEGA_EXPLORER_URL } = useEnvironment();
const { t } = useTranslation();
const {
register,
@@ -110,13 +111,17 @@ export const ProposeFreeform = () => {
userAction={ProposalUserAction.CREATE}
/>
{DocsLinks && (
{VEGA_DOCS_URL && (
<p className="text-sm" data-testid="proposal-docs-link">
<span className="mr-1">{t('ProposalTermsText')}</span>
<ExternalLink
href={`${DocsLinks.PROPOSALS_GUIDE}${DOCS_LINK}`}
href={`${
createDocsLinks(VEGA_DOCS_URL).PROPOSALS_GUIDE
}${DOCS_LINK}`}
target="_blank"
>{`${DocsLinks.PROPOSALS_GUIDE}${DOCS_LINK}`}</ExternalLink>
>{`${
createDocsLinks(VEGA_DOCS_URL).PROPOSALS_GUIDE
}${DOCS_LINK}`}</ExternalLink>
</p>
)}
@@ -10,10 +10,9 @@ import { NetworkParamsDocument } from '@vegaprotocol/network-parameters';
import type { MockedResponse } from '@apollo/client/testing';
jest.mock('@vegaprotocol/environment', () => ({
...jest.requireActual('@vegaprotocol/environment'),
DocsLinks: {
PROPOSALS_GUIDE: 'https://docs.vega.xyz/tutorials/proposals',
},
useEnvironment: () => ({
VEGA_DOCS_URL: 'https://docs.vega.xyz',
}),
}));
const updateMarketNetworkParamsQueryMock: MockedResponse<NetworkParamsQuery> = {
@@ -1,7 +1,10 @@
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useForm } from 'react-hook-form';
import { suitableForSyntaxHighlighter } from '@vegaprotocol/utils';
import {
createDocsLinks,
suitableForSyntaxHighlighter,
} from '@vegaprotocol/utils';
import { useNetworkParams } from '@vegaprotocol/network-parameters';
import {
getClosingTimestamp,
@@ -9,7 +12,7 @@ import {
useProposalSubmit,
doesValueEquateToParam,
} from '@vegaprotocol/proposals';
import { useEnvironment, DocsLinks } from '@vegaprotocol/environment';
import { useEnvironment } from '@vegaprotocol/environment';
import {
ProposalFormDescription,
ProposalFormSubheader,
@@ -81,7 +84,7 @@ export const ProposeNetworkParameter = () => {
loading: networkParamsLoading,
error: networkParamsError,
} = useNetworkParams();
const { VEGA_EXPLORER_URL } = useEnvironment();
const { VEGA_EXPLORER_URL, VEGA_DOCS_URL } = useEnvironment();
const { t } = useTranslation();
const {
register,
@@ -172,13 +175,17 @@ export const ProposeNetworkParameter = () => {
userAction={ProposalUserAction.CREATE}
/>
{DocsLinks && (
{VEGA_DOCS_URL && (
<p className="text-sm" data-testid="proposal-docs-link">
<span className="mr-1">{t('ProposalTermsText')}</span>
<ExternalLink
href={`${DocsLinks.PROPOSALS_GUIDE}${DOCS_LINK}`}
href={`${
createDocsLinks(VEGA_DOCS_URL).PROPOSALS_GUIDE
}${DOCS_LINK}`}
target="_blank"
>{`${DocsLinks.PROPOSALS_GUIDE}${DOCS_LINK}`}</ExternalLink>
>{`${
createDocsLinks(VEGA_DOCS_URL).PROPOSALS_GUIDE
}${DOCS_LINK}`}</ExternalLink>
</p>
)}
@@ -10,10 +10,9 @@ import type { MockedResponse } from '@apollo/client/testing';
import { NetworkParamsDocument } from '@vegaprotocol/network-parameters';
jest.mock('@vegaprotocol/environment', () => ({
...jest.requireActual('@vegaprotocol/environment'),
DocsLinks: {
PROPOSALS_GUIDE: 'https://docs.vega.xyz/tutorials/proposals',
},
useEnvironment: () => ({
VEGA_DOCS_URL: 'https://docs.vega.xyz',
}),
}));
const newAssetNetworkParamsQueryMock: MockedResponse<NetworkParamsQuery> = {
@@ -7,8 +7,8 @@ import {
useProposalSubmit,
doesValueEquateToParam,
} from '@vegaprotocol/proposals';
import { useEnvironment, DocsLinks } from '@vegaprotocol/environment';
import { validateJson } from '@vegaprotocol/utils';
import { useEnvironment } from '@vegaprotocol/environment';
import { createDocsLinks, validateJson } from '@vegaprotocol/utils';
import {
NetworkParams,
useNetworkParams,
@@ -53,7 +53,7 @@ export const ProposeNewAsset = () => {
NetworkParams.governance_proposal_asset_minProposerBalance,
NetworkParams.spam_protection_proposal_min_tokens,
]);
const { VEGA_EXPLORER_URL } = useEnvironment();
const { VEGA_EXPLORER_URL, VEGA_DOCS_URL } = useEnvironment();
const { t } = useTranslation();
const {
register,
@@ -142,13 +142,17 @@ export const ProposeNewAsset = () => {
userAction={ProposalUserAction.CREATE}
/>
{DocsLinks && (
{VEGA_DOCS_URL && (
<p className="text-sm" data-testid="proposal-docs-link">
<span className="mr-1">{t('ProposalTermsText')}</span>
<ExternalLink
href={`${DocsLinks.PROPOSALS_GUIDE}${DOCS_LINK}`}
href={`${
createDocsLinks(VEGA_DOCS_URL).PROPOSALS_GUIDE
}${DOCS_LINK}`}
target="_blank"
>{`${DocsLinks.PROPOSALS_GUIDE}${DOCS_LINK}`}</ExternalLink>
>{`${
createDocsLinks(VEGA_DOCS_URL).PROPOSALS_GUIDE
}${DOCS_LINK}`}</ExternalLink>
</p>
)}
@@ -10,10 +10,9 @@ import type { NetworkParamsQuery } from '@vegaprotocol/network-parameters';
import { NetworkParamsDocument } from '@vegaprotocol/network-parameters';
jest.mock('@vegaprotocol/environment', () => ({
...jest.requireActual('@vegaprotocol/environment'),
DocsLinks: {
PROPOSALS_GUIDE: 'https://docs.vega.xyz/tutorials/proposals',
},
useEnvironment: () => ({
VEGA_DOCS_URL: 'https://docs.vega.xyz',
}),
}));
const newMarketNetworkParamsQueryMock: MockedResponse<NetworkParamsQuery> = {
@@ -6,8 +6,8 @@ import {
useProposalSubmit,
doesValueEquateToParam,
} from '@vegaprotocol/proposals';
import { useEnvironment, DocsLinks } from '@vegaprotocol/environment';
import { validateJson } from '@vegaprotocol/utils';
import { useEnvironment } from '@vegaprotocol/environment';
import { createDocsLinks, validateJson } from '@vegaprotocol/utils';
import {
NetworkParams,
useNetworkParams,
@@ -51,7 +51,7 @@ export const ProposeNewMarket = () => {
NetworkParams.governance_proposal_market_minProposerBalance,
NetworkParams.spam_protection_proposal_min_tokens,
]);
const { VEGA_EXPLORER_URL } = useEnvironment();
const { VEGA_EXPLORER_URL, VEGA_DOCS_URL } = useEnvironment();
const { t } = useTranslation();
const {
register,
@@ -132,13 +132,17 @@ export const ProposeNewMarket = () => {
userAction={ProposalUserAction.CREATE}
/>
{DocsLinks && (
{VEGA_DOCS_URL && (
<p className="text-sm" data-testid="proposal-docs-link">
<span className="mr-1">{t('ProposalTermsText')}</span>
<ExternalLink
href={`${DocsLinks.PROPOSALS_GUIDE}${DOCS_LINK}`}
href={`${
createDocsLinks(VEGA_DOCS_URL).PROPOSALS_GUIDE
}${DOCS_LINK}`}
target="_blank"
>{`${DocsLinks.PROPOSALS_GUIDE}${DOCS_LINK}`}</ExternalLink>
>{`${
createDocsLinks(VEGA_DOCS_URL).PROPOSALS_GUIDE
}${DOCS_LINK}`}</ExternalLink>
</p>
)}
@@ -2,11 +2,12 @@ import Routes from '../../routes';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
import { useEnvironment, DocsLinks } from '@vegaprotocol/environment';
import { useEnvironment } from '@vegaprotocol/environment';
import { Heading } from '../../../components/heading';
import { createDocsLinks } from '@vegaprotocol/utils';
export const Propose = () => {
const { VEGA_EXPLORER_URL } = useEnvironment();
const { VEGA_DOCS_URL, VEGA_EXPLORER_URL } = useEnvironment();
const { t } = useTranslation();
return (
@@ -14,11 +15,14 @@ export const Propose = () => {
<section className="pb-6">
<Heading title={t('NewProposal')} />
<div className="text-sm">
{DocsLinks && (
{VEGA_DOCS_URL && (
<p>
<span className="mr-1">{t('ProposalTermsText')}</span>
<ExternalLink href={DocsLinks.PROPOSALS_GUIDE} target="_blank">
{DocsLinks.PROPOSALS_GUIDE}
<ExternalLink
href={createDocsLinks(VEGA_DOCS_URL).PROPOSALS_GUIDE}
target="_blank"
>
{createDocsLinks(VEGA_DOCS_URL).PROPOSALS_GUIDE}
</ExternalLink>
</p>
)}
@@ -1,6 +1,6 @@
import { useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { useEnvironment, DocsLinks } from '@vegaprotocol/environment';
import { useEnvironment } from '@vegaprotocol/environment';
import { Heading } from '../../../../components/heading';
import {
AsyncRenderer,
@@ -9,7 +9,7 @@ import {
InputError,
TextArea,
} from '@vegaprotocol/ui-toolkit';
import { validateJson } from '@vegaprotocol/utils';
import { createDocsLinks, validateJson } from '@vegaprotocol/utils';
import {
NetworkParams,
useNetworkParams,
@@ -39,7 +39,7 @@ export const ProposeRaw = () => {
NetworkParams.governance_proposal_freeform_minProposerBalance,
NetworkParams.spam_protection_proposal_min_tokens,
]);
const { VEGA_EXPLORER_URL } = useEnvironment();
const { VEGA_EXPLORER_URL, VEGA_DOCS_URL } = useEnvironment();
const { t } = useTranslation();
const {
register,
@@ -79,11 +79,14 @@ export const ProposeRaw = () => {
spamProtectionMin={params.spam_protection_proposal_min_tokens}
/>
{DocsLinks && (
{VEGA_DOCS_URL && (
<p className="text-sm" data-testid="proposal-docs-link">
<span className="mr-1">{t('ProposalTermsText')}</span>
<ExternalLink href={DocsLinks.PROPOSALS_GUIDE} target="_blank">
{DocsLinks.PROPOSALS_GUIDE}
<ExternalLink
href={createDocsLinks(VEGA_DOCS_URL).PROPOSALS_GUIDE}
target="_blank"
>
{createDocsLinks(VEGA_DOCS_URL).PROPOSALS_GUIDE}
</ExternalLink>
</p>
)}
@@ -10,10 +10,9 @@ import type { MockedResponse } from '@apollo/client/testing';
import { NetworkParamsDocument } from '@vegaprotocol/network-parameters';
jest.mock('@vegaprotocol/environment', () => ({
...jest.requireActual('@vegaprotocol/environment'),
DocsLinks: {
PROPOSALS_GUIDE: 'https://docs.vega.xyz/tutorials/proposals',
},
useEnvironment: () => ({
VEGA_DOCS_URL: 'https://docs.vega.xyz',
}),
}));
const updateAssetNetworkParamsQueryMock: MockedResponse<NetworkParamsQuery> = {
@@ -6,8 +6,8 @@ import {
useProposalSubmit,
doesValueEquateToParam,
} from '@vegaprotocol/proposals';
import { useEnvironment, DocsLinks } from '@vegaprotocol/environment';
import { validateJson } from '@vegaprotocol/utils';
import { useEnvironment } from '@vegaprotocol/environment';
import { createDocsLinks, validateJson } from '@vegaprotocol/utils';
import {
NetworkParams,
useNetworkParams,
@@ -51,7 +51,7 @@ export const ProposeUpdateAsset = () => {
NetworkParams.governance_proposal_updateAsset_minProposerBalance,
NetworkParams.spam_protection_proposal_min_tokens,
]);
const { VEGA_EXPLORER_URL } = useEnvironment();
const { VEGA_EXPLORER_URL, VEGA_DOCS_URL } = useEnvironment();
const { t } = useTranslation();
const {
register,
@@ -132,13 +132,17 @@ export const ProposeUpdateAsset = () => {
userAction={ProposalUserAction.CREATE}
/>
{DocsLinks && (
{VEGA_DOCS_URL && (
<p className="text-sm" data-testid="proposal-docs-link">
<span className="mr-1">{t('ProposalTermsText')}</span>
<ExternalLink
href={`${DocsLinks.PROPOSALS_GUIDE}${DOCS_LINK}`}
href={`${
createDocsLinks(VEGA_DOCS_URL).PROPOSALS_GUIDE
}${DOCS_LINK}`}
target="_blank"
>{`${DocsLinks.PROPOSALS_GUIDE}${DOCS_LINK}`}</ExternalLink>
>{`${
createDocsLinks(VEGA_DOCS_URL).PROPOSALS_GUIDE
}${DOCS_LINK}`}</ExternalLink>
</p>
)}
@@ -7,8 +7,8 @@ import {
getEnactmentTimestamp,
useProposalSubmit,
} from '@vegaprotocol/proposals';
import { useEnvironment, DocsLinks } from '@vegaprotocol/environment';
import { validateJson } from '@vegaprotocol/utils';
import { useEnvironment } from '@vegaprotocol/environment';
import { createDocsLinks, validateJson } from '@vegaprotocol/utils';
import {
NetworkParams,
useNetworkParams,
@@ -98,7 +98,7 @@ export const ProposeUpdateMarket = () => {
const [selectedMarket, setSelectedMarket] = useState<string | undefined>(
undefined
);
const { VEGA_EXPLORER_URL } = useEnvironment();
const { VEGA_EXPLORER_URL, VEGA_DOCS_URL } = useEnvironment();
const { t } = useTranslation();
const {
register,
@@ -181,13 +181,17 @@ export const ProposeUpdateMarket = () => {
userAction={ProposalUserAction.CREATE}
/>
{DocsLinks && (
{VEGA_DOCS_URL && (
<p className="text-sm" data-testid="proposal-docs-link">
<span className="mr-1">{t('ProposalTermsText')}</span>
<ExternalLink
href={`${DocsLinks.PROPOSALS_GUIDE}${DOCS_LINK}`}
href={`${
createDocsLinks(VEGA_DOCS_URL).PROPOSALS_GUIDE
}${DOCS_LINK}`}
target="_blank"
>{`${DocsLinks.PROPOSALS_GUIDE}${DOCS_LINK}`}</ExternalLink>
>{`${
createDocsLinks(VEGA_DOCS_URL).PROPOSALS_GUIDE
}${DOCS_LINK}`}</ExternalLink>
</p>
)}
@@ -25,7 +25,7 @@ const mockData = {
amount: '0',
percentageOfTotal: '0',
},
ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES: {
ACCOUNT_TYPE_FEES_LIQUIDITY: {
amount: '0',
percentageOfTotal: '0',
},
@@ -55,9 +55,7 @@ describe('EpochIndividualRewardsTable', () => {
expect(
getByTestId('ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES')
).toBeInTheDocument();
expect(
getByTestId('ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES')
).toBeInTheDocument();
expect(getByTestId('ACCOUNT_TYPE_FEES_LIQUIDITY')).toBeInTheDocument();
expect(
getByTestId('ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS')
).toBeInTheDocument();
@@ -24,7 +24,7 @@ describe('generateEpochIndividualRewardsList', () => {
};
const reward3: RewardFieldsFragment = {
rewardType: AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
rewardType: AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
amount: '200',
percentageOfTotal: '0.2',
receivedAt: new Date(),
@@ -34,7 +34,7 @@ describe('generateEpochIndividualRewardsList', () => {
};
const reward4: RewardFieldsFragment = {
rewardType: AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
rewardType: AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
amount: '100',
percentageOfTotal: '0.1',
receivedAt: new Date(),
@@ -44,7 +44,7 @@ describe('generateEpochIndividualRewardsList', () => {
};
const reward5: RewardFieldsFragment = {
rewardType: AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
rewardType: AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
amount: '150',
percentageOfTotal: '0.15',
receivedAt: new Date(),
@@ -105,7 +105,7 @@ describe('generateEpochIndividualRewardsList', () => {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES]: {
[AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY]: {
amount: '0',
percentageOfTotal: '0',
},
@@ -172,7 +172,7 @@ describe('generateEpochIndividualRewardsList', () => {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES]: {
[AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY]: {
amount: '200',
percentageOfTotal: '0.2',
},
@@ -202,7 +202,7 @@ describe('generateEpochIndividualRewardsList', () => {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES]: {
[AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY]: {
amount: '0',
percentageOfTotal: '0',
},
@@ -237,7 +237,7 @@ describe('generateEpochIndividualRewardsList', () => {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES]: {
[AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY]: {
amount: '100',
percentageOfTotal: '0.1',
},
@@ -285,7 +285,7 @@ describe('generateEpochIndividualRewardsList', () => {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES]: {
[AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY]: {
amount: '150',
percentageOfTotal: '0.15',
},
@@ -320,7 +320,7 @@ describe('generateEpochIndividualRewardsList', () => {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES]: {
[AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY]: {
amount: '200',
percentageOfTotal: '0.2',
},
@@ -350,7 +350,7 @@ describe('generateEpochIndividualRewardsList', () => {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES]: {
[AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY]: {
amount: '0',
percentageOfTotal: '0',
},
@@ -395,7 +395,7 @@ describe('generateEpochIndividualRewardsList', () => {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES]: {
[AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY]: {
amount: '100',
percentageOfTotal: '0.1',
},
@@ -29,7 +29,7 @@ const rewardsList = [
amount: '0',
},
{
rewardType: AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
rewardType: AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
amount: '0',
},
{
@@ -78,9 +78,7 @@ describe('EpochTotalRewardsTable', () => {
expect(
getByTestId('ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES')
).toBeInTheDocument();
expect(
getByTestId('ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES')
).toBeInTheDocument();
expect(getByTestId('ACCOUNT_TYPE_FEES_LIQUIDITY')).toBeInTheDocument();
expect(
getByTestId('ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS')
).toBeInTheDocument();
@@ -162,10 +162,9 @@ describe('generateEpochAssetRewardsList', () => {
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
rewardType: AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
amount: '0',
},
],
@@ -228,7 +227,7 @@ describe('generateEpochAssetRewardsList', () => {
node: {
epoch: 2,
assetId: '1',
rewardType: AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
rewardType: AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
amount: '5',
},
},
@@ -288,10 +287,9 @@ describe('generateEpochAssetRewardsList', () => {
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
rewardType: AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
amount: '0',
},
],
@@ -353,10 +351,9 @@ describe('generateEpochAssetRewardsList', () => {
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
rewardType: AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
amount: '5',
},
],
@@ -419,7 +416,7 @@ describe('generateEpochAssetRewardsList', () => {
node: {
epoch: 2,
assetId: '1',
rewardType: AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
rewardType: AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
amount: '6',
},
},
@@ -427,7 +424,7 @@ describe('generateEpochAssetRewardsList', () => {
node: {
epoch: 2,
assetId: '1',
rewardType: AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
rewardType: AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
amount: '27',
},
},
@@ -500,10 +497,9 @@ describe('generateEpochAssetRewardsList', () => {
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
rewardType: AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
amount: '33',
},
],
@@ -565,10 +561,9 @@ describe('generateEpochAssetRewardsList', () => {
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
rewardType: AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
amount: '0',
},
],
@@ -642,10 +637,9 @@ describe('generateEpochAssetRewardsList', () => {
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
rewardType: AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
amount: '0',
},
],
@@ -11,6 +11,7 @@ import {
ExternalLink,
} from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { createDocsLinks } from '@vegaprotocol/utils';
import {
useNetworkParams,
NetworkParams,
@@ -20,7 +21,7 @@ import { EpochCountdown } from '../../../components/epoch-countdown';
import { Heading, SubHeading } from '../../../components/heading';
import { EpochIndividualRewards } from '../epoch-individual-rewards/epoch-individual-rewards';
import { useRefreshAfterEpoch } from '../../../hooks/use-refresh-after-epoch';
import { DocsLinks } from '@vegaprotocol/environment';
import { useEnvironment } from '@vegaprotocol/environment';
import { ConnectToSeeRewards } from '../connect-to-see-rewards';
import { EpochTotalRewards } from '../epoch-total-rewards/epoch-total-rewards';
@@ -28,6 +29,7 @@ type RewardsView = 'total' | 'individual';
export const RewardsPage = () => {
const { t } = useTranslation();
const { VEGA_DOCS_URL } = useEnvironment();
const { pubKey, pubKeys } = useVegaWallet();
const [toggleRewardsView, setToggleRewardsView] =
useState<RewardsView>('total');
@@ -66,9 +68,9 @@ export const RewardsPage = () => {
<Heading title={t('pageTitleRewards')} />
<p className="mb-12">
{t('rewardsIntro')}{' '}
{DocsLinks && (
{VEGA_DOCS_URL && (
<ExternalLink
href={DocsLinks.REWARDS_GUIDE}
href={createDocsLinks(VEGA_DOCS_URL).REWARDS_GUIDE}
target="_blank"
data-testid="rewards-guide-link"
className="text-white"
@@ -26,7 +26,7 @@ export const RowAccountTypes = {
columnTitle: 'rewardsColPriceMakingHeader',
description: 'rewardsColPriceMakingTooltip',
},
[AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES]: {
[AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY]: {
columnTitle: 'rewardsColLiquidityProvisionHeader',
description: 'rewardsColLiquidityProvisionTooltip',
},
+4 -7
View File
@@ -229,7 +229,7 @@ const redirects = [
const routerConfig = [
{
path: Routes.HOME,
element: <LazyHome name="Home" />,
element: <LazyHome name="Token" />,
},
{
path: Routes.PROPOSALS,
@@ -291,7 +291,7 @@ const routerConfig = [
// Not lazy as loaded when a user first hits the site
children: [
{
element: <Home name="Token" />,
element: <Home name="Home" />,
index: true,
},
{
@@ -325,11 +325,8 @@ const routerConfig = [
},
],
},
{ path: 'associate', element: <LazyStakingAssociate name="Associate" /> },
{
path: 'disassociate',
element: <LazyStakingDisassociate name="Disassociate" />,
},
{ path: 'associate', element: <LazyStakingAssociate /> },
{ path: 'disassociate', element: <LazyStakingDisassociate /> },
],
},
{
@@ -1,14 +1,12 @@
import { useEthereumConfig } from '@vegaprotocol/web3';
import { StakingWalletsContainer } from './components/staking-wallets-container';
import { StakingWalletsContainer } from './components/staking-wallets-container/staking-wallets-container';
import { AssociatePage } from './associate-page';
import { AssociatePageNoVega } from './associate-page-no-vega';
import { Heading } from '../../../components/heading';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useDocumentTitle } from '../../../hooks/use-document-title';
import type { RouteChildProps } from '../../index';
export const AssociateContainer = ({ name }: RouteChildProps) => {
useDocumentTitle(name);
export const AssociateContainer = () => {
const { t } = useTranslation();
const { config } = useEthereumConfig();
@@ -39,7 +39,7 @@ jest.mock('@vegaprotocol/wallet', () => ({
}));
const renderComponent = () => {
return render(<Disassociate name="Disassociate" />);
return render(<Disassociate />);
};
describe('Disassociate', () => {
@@ -3,12 +3,10 @@ import { useWeb3React } from '@web3-react/core';
import { EthConnectPrompt } from '../../../components/eth-connect-prompt';
import { DisassociatePage } from './components/disassociate-page';
import { Heading } from '../../../components/heading';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useDocumentTitle } from '../../../hooks/use-document-title';
import type { RouteChildProps } from '../../index';
export const DisassociateContainer = ({ name }: RouteChildProps) => {
useDocumentTitle(name);
export const DisassociateContainer = () => {
const { t } = useTranslation();
const { account } = useWeb3React();
const { pubKey } = useVegaWallet();
@@ -1,12 +1,14 @@
import { useTranslation } from 'react-i18next';
import { EpochData } from './epoch-data';
import { DocsLinks } from '@vegaprotocol/environment';
import { useEnvironment } from '@vegaprotocol/environment';
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
import { createDocsLinks } from '@vegaprotocol/utils';
import { Heading } from '../../../components/heading';
import React from 'react';
export const Staking = () => {
const { t } = useTranslation();
const { VEGA_DOCS_URL } = useEnvironment();
return (
<>
@@ -14,9 +16,9 @@ export const Staking = () => {
<section>
<p className="mb-12">
{t('stakingIntro')}{' '}
{DocsLinks && (
{VEGA_DOCS_URL && (
<ExternalLink
href={DocsLinks.STAKING_GUIDE}
href={createDocsLinks(VEGA_DOCS_URL).STAKING_GUIDE}
target="_blank"
data-testid="staking-guide-link"
className="text-white"
@@ -131,25 +131,20 @@ export const ConsensusValidatorsTable = ({
const gridRef = useRef<AgGridReact | null>(null);
const thirdOfTotalStake = useMemo(
() => new BigNumber(totalStake).dividedBy(3),
[totalStake]
);
const nodes = useMemo(() => {
if (!data) return [];
let canonisedNodes = data
.sort((a, b) => {
const aStakedTotal = new BigNumber(a.stakedTotal);
const bStakedTotal = new BigNumber(b.stakedTotal);
return bStakedTotal.minus(aStakedTotal).toNumber();
const aVotingPower = new BigNumber(a.rankingScore.votingPower);
const bVotingPower = new BigNumber(b.rankingScore.votingPower);
return bVotingPower.minus(aVotingPower).toNumber();
})
.map((node, index) => {
const stakedTotalRanking = index + 1;
const votingPowerRanking = index + 1;
return {
...node,
stakedTotalRanking,
votingPowerRanking,
};
})
.map(
@@ -162,7 +157,7 @@ export const ConsensusValidatorsTable = ({
stakedTotal,
rankingScore: { stakeScore, votingPower },
pendingStake,
stakedTotalRanking,
votingPowerRanking,
stakedByUser,
pendingUserStake,
userStakeShare,
@@ -180,7 +175,7 @@ export const ConsensusValidatorsTable = ({
return {
id,
[ValidatorFields.RANKING_INDEX]: stakedTotalRanking,
[ValidatorFields.RANKING_INDEX]: votingPowerRanking,
[ValidatorFields.VALIDATOR]: {
avatarUrl: logo,
name,
@@ -241,12 +236,16 @@ export const ConsensusValidatorsTable = ({
return canonisedNodes;
}
// The point of identifying and hiding the group that could halt the network
// is that we assume the top 1/3 of stake is held by considerably less than
// 1/3 of the validators and we really want people not to stake any more to
// that group, because we want to make it require as many difference
// validators to collude as possible to halt the network, so we hide them.
const { topThird, remaining } = canonisedNodes.reduce(
(acc, node) => {
if (acc.cumulativeScore.isLessThan(thirdOfTotalStake)) {
const prev = acc.cumulativeScore;
acc.cumulativeScore = prev.plus(
new BigNumber(node[ValidatorFields.STAKE])
if (acc.cumulativeScore < 100 / 3) {
acc.cumulativeScore += parseFloat(
node[ValidatorFields.NORMALISED_VOTING_POWER]
);
acc.topThird.push(node);
return acc;
@@ -254,70 +253,61 @@ export const ConsensusValidatorsTable = ({
acc.remaining.push(node);
return acc;
},
{ topThird: [], remaining: [], cumulativeScore: new BigNumber(0) } as {
{ topThird: [], remaining: [], cumulativeScore: 0 } as {
topThird: CanonisedConsensusNodeProps[];
remaining: CanonisedConsensusNodeProps[];
cumulativeScore: BigNumber;
cumulativeScore: number;
}
);
// We need to combine the top third of validators into a single node, this
// way the combined values can be passed to AG grid so that the combined cell's
// values are correct for ordering.
const combinedTopThird = topThird.reduce(
(acc, node) => {
const {
[ValidatorFields.STAKE]: stake,
[ValidatorFields.STAKE_SHARE]: stakeShare,
[ValidatorFields.PENDING_STAKE]: pendingStake,
[ValidatorFields.NORMALISED_VOTING_POWER]: normalisedVotingPower,
[ValidatorFields.TOTAL_PENALTIES]: totalPenalties,
} = node;
const combinedTopThird = topThird.reduce((acc, node) => {
const {
[ValidatorFields.STAKE]: stake,
[ValidatorFields.STAKE_SHARE]: stakeShare,
[ValidatorFields.PENDING_STAKE]: pendingStake,
[ValidatorFields.NORMALISED_VOTING_POWER]: normalisedVotingPower,
[ValidatorFields.TOTAL_PENALTIES]: totalPenalties,
} = node;
const {
[ValidatorFields.STAKE]: accStake,
[ValidatorFields.STAKE_SHARE]: accStakeShare,
[ValidatorFields.PENDING_STAKE]: accPendingStake,
[ValidatorFields.NORMALISED_VOTING_POWER]: accNormalisedVotingPower,
[ValidatorFields.TOTAL_PENALTIES]: accTotalPenalties,
} = acc;
const {
[ValidatorFields.STAKE]: accStake,
[ValidatorFields.STAKE_SHARE]: accStakeShare,
[ValidatorFields.PENDING_STAKE]: accPendingStake,
[ValidatorFields.NORMALISED_VOTING_POWER]: accNormalisedVotingPower,
[ValidatorFields.TOTAL_PENALTIES]: accTotalPenalties,
} = acc;
return {
...acc,
[ValidatorFields.STAKE]: new BigNumber(accStake)
.plus(new BigNumber(stake))
.toString(),
[ValidatorFields.STAKE_SHARE]: formatNumberPercentage(
new BigNumber(parseFloat(accStakeShare)).plus(
new BigNumber(parseFloat(stakeShare))
),
2
return {
...acc,
[ValidatorFields.STAKE]: toBigNum(accStake, decimals)
.plus(toBigNum(stake, decimals))
.toString(),
[ValidatorFields.STAKE_SHARE]: formatNumberPercentage(
new BigNumber(parseFloat(accStakeShare)).plus(
new BigNumber(parseFloat(stakeShare))
),
[ValidatorFields.PENDING_STAKE]: toBigNum(accPendingStake, decimals)
.plus(toBigNum(pendingStake, decimals))
.toString(),
[ValidatorFields.NORMALISED_VOTING_POWER]: formatNumberPercentage(
new BigNumber(parseFloat(accNormalisedVotingPower)).plus(
new BigNumber(parseFloat(normalisedVotingPower))
),
2
2
),
[ValidatorFields.PENDING_STAKE]: toBigNum(accPendingStake, decimals)
.plus(toBigNum(pendingStake, decimals))
.toString(),
[ValidatorFields.NORMALISED_VOTING_POWER]: formatNumberPercentage(
new BigNumber(parseFloat(accNormalisedVotingPower)).plus(
new BigNumber(parseFloat(normalisedVotingPower))
),
[ValidatorFields.TOTAL_PENALTIES]: formatNumberPercentage(
new BigNumber(parseFloat(accTotalPenalties)).plus(
new BigNumber(parseFloat(totalPenalties))
),
2
2
),
[ValidatorFields.TOTAL_PENALTIES]: formatNumberPercentage(
new BigNumber(parseFloat(accTotalPenalties)).plus(
new BigNumber(parseFloat(totalPenalties))
),
};
},
{
[ValidatorFields.STAKE]: '0',
[ValidatorFields.STAKE_SHARE]: '0',
[ValidatorFields.PENDING_STAKE]: '0',
[ValidatorFields.NORMALISED_VOTING_POWER]: '0',
[ValidatorFields.TOTAL_PENALTIES]: '0',
}
);
2
),
};
});
return [
{
@@ -332,7 +322,6 @@ export const ConsensusValidatorsTable = ({
decimals,
hideTopThird,
previousEpochData,
thirdOfTotalStake,
totalStake,
validatorsView,
]);
@@ -363,7 +352,6 @@ export const ConsensusValidatorsTable = ({
headerTooltip: t('StakeDescription').toString(),
cellRenderer: TotalStakeRenderer,
width: 120,
sort: 'desc',
},
{
field: ValidatorFields.PENDING_STAKE,
@@ -385,6 +373,7 @@ export const ConsensusValidatorsTable = ({
headerTooltip: t('NormalisedVotingPowerDescription').toString(),
cellRenderer: VotingPowerRenderer,
width: 200,
sort: 'desc',
},
{
field: ValidatorFields.TOTAL_PENALTIES,
@@ -57,16 +57,16 @@ export const StandbyPendingValidatorsTable = ({
return data
.sort((a, b) => {
const aStakedTotal = new BigNumber(a.stakedTotal);
const bStakedTotal = new BigNumber(b.stakedTotal);
return bStakedTotal.minus(aStakedTotal).toNumber();
const aVotingPower = new BigNumber(a.rankingScore.votingPower);
const bVotingPower = new BigNumber(b.rankingScore.votingPower);
return bVotingPower.minus(aVotingPower).toNumber();
})
.map((node, index) => {
const stakedTotalRanking = index + 1;
const votingPowerRanking = index + 1;
return {
...node,
stakedTotalRanking,
votingPowerRanking,
};
})
.map(
@@ -79,7 +79,7 @@ export const StandbyPendingValidatorsTable = ({
stakedTotal,
rankingScore: { stakeScore },
pendingStake,
stakedTotalRanking,
votingPowerRanking,
stakedByUser,
pendingUserStake,
userStakeShare,
@@ -125,7 +125,7 @@ export const StandbyPendingValidatorsTable = ({
return {
id,
[ValidatorFields.RANKING_INDEX]: stakedTotalRanking,
[ValidatorFields.RANKING_INDEX]: votingPowerRanking,
[ValidatorFields.VALIDATOR]: {
avatarUrl,
name,
@@ -166,7 +166,7 @@ export const StandbyPendingValidatorsTable = ({
: undefined,
[ValidatorFields.PENDING_USER_STAKE]: pendingUserStake,
[ValidatorFields.USER_STAKE_SHARE]: userStakeShare
? formatNumberPercentage(new BigNumber(userStakeShare), 2)
? formatNumberPercentage(new BigNumber(userStakeShare))
: undefined,
};
}
@@ -210,7 +210,6 @@ export const StandbyPendingValidatorsTable = ({
headerTooltip: t('StakeDescription').toString(),
cellRenderer: TotalStakeRenderer,
width: 120,
sort: 'desc',
},
{
field: ValidatorFields.PENDING_STAKE,
@@ -234,6 +233,7 @@ export const StandbyPendingValidatorsTable = ({
}),
cellRenderer: StakeNeededForPromotionRenderer,
width: 210,
sort: 'asc',
},
{
field: ValidatorFields.TOTAL_PENALTIES,
@@ -2,8 +2,12 @@ import { useMemo, useState } from 'react';
import { Trans, useTranslation } from 'react-i18next';
import BigNumber from 'bignumber.js';
import * as Schema from '@vegaprotocol/types';
import { removePaginationWrapper, toBigNum } from '@vegaprotocol/utils';
import { DocsLinks } from '@vegaprotocol/environment';
import {
createDocsLinks,
removePaginationWrapper,
toBigNum,
} from '@vegaprotocol/utils';
import { useEnvironment } from '@vegaprotocol/environment';
import { Link as UTLink, Toggle } from '@vegaprotocol/ui-toolkit';
import { formatNumber } from '../../../../lib/format-number';
@@ -38,6 +42,7 @@ export const ValidatorTables = ({
previousEpochData,
}: ValidatorsTableProps) => {
const { t } = useTranslation();
const { VEGA_DOCS_URL } = useEnvironment();
const {
appState: { decimals },
} = useAppState();
@@ -208,12 +213,12 @@ export const ValidatorTables = ({
<>
<SubHeading title={t('status-pending')} />
<p>
{DocsLinks && (
{VEGA_DOCS_URL && (
<>
<span>{t('pendingDescription1')} </span>
<span>
<UTLink
href={DocsLinks.STAKING_GUIDE}
href={createDocsLinks(VEGA_DOCS_URL).STAKING_GUIDE}
target="_blank"
data-testid="validator-forum-link"
>
@@ -1,11 +1,7 @@
import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import {
useEnvironment,
DocsLinks,
ExternalLinks,
} from '@vegaprotocol/environment';
import { toBigNum } from '@vegaprotocol/utils';
import { useEnvironment } from '@vegaprotocol/environment';
import { createDocsLinks, ExternalLinks, toBigNum } from '@vegaprotocol/utils';
import * as Schema from '@vegaprotocol/types';
import {
Link as UTLink,
@@ -68,7 +64,7 @@ export const ValidatorTable = ({
stakedTotal,
previousEpochData,
}: ValidatorTableProps) => {
const { ETHERSCAN_URL } = useEnvironment();
const { ETHERSCAN_URL, VEGA_DOCS_URL } = useEnvironment();
const { t } = useTranslation();
const {
appState: { decimals },
@@ -94,9 +90,9 @@ export const ValidatorTable = ({
<>
<p className="mb-12">
{t('validatorFormIntro')}{' '}
{DocsLinks && (
{VEGA_DOCS_URL && (
<ExternalLink
href={DocsLinks.STAKING_GUIDE}
href={createDocsLinks(VEGA_DOCS_URL).STAKING_GUIDE}
target="_blank"
data-testid="validator-table-staking-guide-link"
className="text-white"
+3 -8
View File
@@ -60,14 +60,9 @@ export const getOverstakingPenalty = (
}
return formatNumberPercentage(
BigNumber.max(
new BigNumber(1)
.minus(
new BigNumber(validatorScore).dividedBy(new BigNumber(stakeScore))
)
.times(100),
new BigNumber(0)
),
new BigNumber(1)
.minus(new BigNumber(validatorScore).dividedBy(new BigNumber(stakeScore)))
.times(100),
2
);
};
+1 -2
View File
@@ -3,8 +3,7 @@ import { Trans, useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import { Heading, SubHeading } from '../../components/heading';
import { ExternalLinks } from '@vegaprotocol/environment';
import { toBigNum } from '@vegaprotocol/utils';
import { ExternalLinks, toBigNum } from '@vegaprotocol/utils';
import { useAppState } from '../../contexts/app-state/app-state-context';
import { useDocumentTitle } from '../../hooks/use-document-title';
import type { RouteChildProps } from '..';
+27 -82
View File
@@ -82,7 +82,7 @@
"tranche_end": "2023-05-20T00:00:00.000Z",
"total_added": "19242.125",
"total_removed": "2667.900599530005",
"locked_amount": "1598.3806680652007360625",
"locked_amount": "1760.572777247300418465",
"deposits": [
{
"amount": "188",
@@ -5045,7 +5045,7 @@
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "86666.297",
"total_removed": "0",
"locked_amount": "47842.6457965491129318687",
"locked_amount": "47902.6878201683513969045",
"deposits": [
{
"amount": "86666.297",
@@ -5111,7 +5111,7 @@
"tranche_end": "2023-06-01T00:00:00.000Z",
"total_added": "2500",
"total_removed": "0",
"locked_amount": "199.06596586284075",
"locked_amount": "202.53945996133505",
"deposits": [
{
"amount": "2500",
@@ -5144,7 +5144,7 @@
"tranche_end": "2023-11-01T00:00:00.000Z",
"total_added": "15000.000000000000015",
"total_removed": "0",
"locked_amount": "13654.239319142511013654239319142511",
"locked_amount": "13674.853751509662013674853751509662",
"deposits": [
{
"amount": "1.5e-14",
@@ -5252,7 +5252,7 @@
"tranche_end": "2023-09-01T00:00:00.000Z",
"total_added": "17500",
"total_removed": "0",
"locked_amount": "10128.3154375503205",
"locked_amount": "10152.36560864532825",
"deposits": [
{
"amount": "12500",
@@ -5519,7 +5519,7 @@
"tranche_end": "2023-08-01T00:00:00.000Z",
"total_added": "37500",
"total_removed": "18500.56159815",
"locked_amount": "15640.6082143953375",
"locked_amount": "15692.99848449969375",
"deposits": [
{
"amount": "7500",
@@ -5960,7 +5960,7 @@
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "129999.45",
"total_removed": "0",
"locked_amount": "47798.995402052288763222",
"locked_amount": "47858.982644879740029465",
"deposits": [
{
"amount": "129999.45",
@@ -5993,7 +5993,7 @@
"tranche_end": "2024-04-01T00:00:00.000Z",
"total_added": "54144.7663",
"total_removed": "0",
"locked_amount": "47264.53497282707304506298",
"locked_amount": "47301.94373541695517923511",
"deposits": [
{
"amount": "54144.7663",
@@ -6026,7 +6026,7 @@
"tranche_end": "2023-09-03T00:00:00.000Z",
"total_added": "62600",
"total_removed": "0",
"locked_amount": "18607.12149289700607",
"locked_amount": "18650.49049340436032",
"deposits": [
{
"amount": "10000",
@@ -6219,7 +6219,7 @@
"tranche_end": "2023-09-17T00:00:00.000Z",
"total_added": "5000",
"total_removed": "0",
"locked_amount": "1677.97263444951825",
"locked_amount": "1681.4366121258245",
"deposits": [
{
"amount": "5000",
@@ -7288,7 +7288,7 @@
"tranche_end": "2023-06-02T00:00:00.000Z",
"total_added": "1939928.38",
"total_removed": "1709370.7872515768348",
"locked_amount": "82338.0135713287122219002",
"locked_amount": "83681.9872917193018111752",
"deposits": [
{
"amount": "1852091.69",
@@ -41160,7 +41160,7 @@
"tranche_end": "2023-06-05T00:00:00.000Z",
"total_added": "3732368.4671",
"total_removed": "715655.108029600523393",
"locked_amount": "151026.184536881782105898921",
"locked_amount": "153091.4042231713229007715616",
"deposits": [
{
"amount": "1998.95815",
@@ -42552,8 +42552,8 @@
"tranche_start": "2022-06-05T00:00:00.000Z",
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "15870102.715470999700000001",
"total_removed": "886751.39142845377669352",
"locked_amount": "5835216.73920078782616266076155334761097596",
"total_removed": "885240.49984321970795352",
"locked_amount": "5842539.8756085922637222718130454678926737",
"deposits": [
{
"amount": "16249.93",
@@ -43092,16 +43092,6 @@
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tx": "0xb048cb2dcdfc30508770a3a112ddbacd63210f740cc887559660522bd506612c"
},
{
"amount": "1007.907542",
"user": "0xF4c75FdbAe821C6B5DBB9f001bB23cBA58D1bA37",
"tx": "0x6a0d503d78cb1fd2291064c2d876cb8d2d91ad87c23ea6ff0b87b6443f8b434e"
},
{
"amount": "502.98404323406874",
"user": "0xe3eB4CF43C072658401996b71D43eE26E573562D",
"tx": "0x34f5294e12b0fcbfe0be234ce712cfbc52d4d75b159ca4e55610eb75efe43286"
},
{
"amount": "10150.87581603206683",
"user": "0xe3eB4CF43C072658401996b71D43eE26E573562D",
@@ -47090,12 +47080,6 @@
"tranche_id": 2,
"tx": "0xc8835acd2e148eeaacde2a0df0ecad19c22717c7c51b207fdeac9a1af3f98c88"
},
{
"amount": "502.98404323406874",
"user": "0xe3eB4CF43C072658401996b71D43eE26E573562D",
"tranche_id": 2,
"tx": "0x34f5294e12b0fcbfe0be234ce712cfbc52d4d75b159ca4e55610eb75efe43286"
},
{
"amount": "10150.87581603206683",
"user": "0xe3eB4CF43C072658401996b71D43eE26E573562D",
@@ -47386,8 +47370,8 @@
}
],
"total_tokens": "150551.801",
"withdrawn_tokens": "95132.09101929755535",
"remaining_tokens": "55419.70998070244465"
"withdrawn_tokens": "94629.10697606348661",
"remaining_tokens": "55922.69402393651339"
},
{
"address": "0x4d982Ab0823fD2f48e934a7be2bb0a5374a26148",
@@ -47613,12 +47597,6 @@
"tranche_id": 2,
"tx": "0xdedcbf90e8f19c2a732ba2da663f59b5a19ad94800ddca6a3575019f19e9ca20"
},
{
"amount": "1007.907542",
"user": "0xF4c75FdbAe821C6B5DBB9f001bB23cBA58D1bA37",
"tranche_id": 2,
"tx": "0x6a0d503d78cb1fd2291064c2d876cb8d2d91ad87c23ea6ff0b87b6443f8b434e"
},
{
"amount": "1784.722222",
"user": "0xF4c75FdbAe821C6B5DBB9f001bB23cBA58D1bA37",
@@ -47879,8 +47857,8 @@
}
],
"total_tokens": "200000",
"withdrawn_tokens": "126376.871282",
"remaining_tokens": "73623.128718"
"withdrawn_tokens": "125368.96374",
"remaining_tokens": "74631.03626"
},
{
"address": "0x1b956E6c00E238194B331eddEFF72Cb5f28A8d01",
@@ -59405,8 +59383,8 @@
"tranche_start": "2022-06-05T00:00:00.000Z",
"tranche_end": "2023-06-05T00:00:00.000Z",
"total_added": "472355.6199999996",
"total_removed": "45451.7934047643416",
"locked_amount": "23930.947264046135033247067681392",
"total_removed": "45345.4733895423416",
"locked_amount": "24258.2081069361612058598496600864",
"deposits": [
{
"amount": "3000",
@@ -66070,16 +66048,6 @@
"user": "0xf0d681c15447dCfaa6002f17078944FCe75B5e26",
"tx": "0xca745232557385fff568386375d868633bd9542981dd07a6c471b4633dd5c9b8"
},
{
"amount": "69.499619482",
"user": "0x8c951C54F9cd08Cf81F770248e835D7A4F491a46",
"tx": "0xfee87c40eeb3d6681eaa844b65ddb52756356c3612e2c2c8606b96f4965bc195"
},
{
"amount": "36.82039574",
"user": "0x4eD2b3c68BB4fda084ce1591a210F4aC8b71234A",
"tx": "0xebbec73307d5d44428f791ad28622e6a075fa9a02d627f028db45a1042af473a"
},
{
"amount": "182.662252664",
"user": "0xb1169C6daAc76bAcaf0D8f87641Fc38fbabe569F",
@@ -80181,12 +80149,6 @@
}
],
"withdrawals": [
{
"amount": "36.82039574",
"user": "0x4eD2b3c68BB4fda084ce1591a210F4aC8b71234A",
"tranche_id": 5,
"tx": "0xebbec73307d5d44428f791ad28622e6a075fa9a02d627f028db45a1042af473a"
},
{
"amount": "26.662404872",
"user": "0x4eD2b3c68BB4fda084ce1591a210F4aC8b71234A",
@@ -80291,8 +80253,8 @@
}
],
"total_tokens": "400",
"withdrawn_tokens": "379.711555048",
"remaining_tokens": "20.288444952"
"withdrawn_tokens": "342.891159308",
"remaining_tokens": "57.108840692"
},
{
"address": "0x5c90765F50629570738fEe7b7FA82ae118f81Ed1",
@@ -86740,12 +86702,6 @@
}
],
"withdrawals": [
{
"amount": "69.499619482",
"user": "0x8c951C54F9cd08Cf81F770248e835D7A4F491a46",
"tranche_id": 5,
"tx": "0xfee87c40eeb3d6681eaa844b65ddb52756356c3612e2c2c8606b96f4965bc195"
},
{
"amount": "26.330974124",
"user": "0x8c951C54F9cd08Cf81F770248e835D7A4F491a46",
@@ -86766,8 +86722,8 @@
}
],
"total_tokens": "200",
"withdrawn_tokens": "189.75159183",
"remaining_tokens": "10.24840817"
"withdrawn_tokens": "120.251972348",
"remaining_tokens": "79.748027652"
},
{
"address": "0x3437f6ED844013852650851D769ae7939B5e0aec",
@@ -89308,7 +89264,7 @@
"tranche_start": "2021-12-05T00:00:00.000Z",
"tranche_end": "2022-06-05T00:00:00.000Z",
"total_added": "171288.42",
"total_removed": "72069.2365096947989",
"total_removed": "71890.5995794947989",
"locked_amount": "0",
"deposits": [
{
@@ -93568,11 +93524,6 @@
"user": "0x2A6Ea2aBEf3D7d7A76CBeF3c297eE0eF9a86BBA8",
"tx": "0x163b699e8a25073ad1ad45c8a8f9b1348eb0b648d3f4bc6f3f64648e0ad726bf"
},
{
"amount": "178.6369302",
"user": "0xC3d15bD936DDCb45b87BFF3Ff13445284a6c9d43",
"tx": "0x7381b77de572d356ae185a760ff839dbdc85cb97bf408b110f7779bb095ea293"
},
{
"amount": "250",
"user": "0x0E3407C9A94effa675471afe7A9D37e687C32141",
@@ -110069,12 +110020,6 @@
}
],
"withdrawals": [
{
"amount": "178.6369302",
"user": "0xC3d15bD936DDCb45b87BFF3Ff13445284a6c9d43",
"tranche_id": 6,
"tx": "0x7381b77de572d356ae185a760ff839dbdc85cb97bf408b110f7779bb095ea293"
},
{
"amount": "71.3630698",
"user": "0xC3d15bD936DDCb45b87BFF3Ff13445284a6c9d43",
@@ -110083,8 +110028,8 @@
}
],
"total_tokens": "250",
"withdrawn_tokens": "250",
"remaining_tokens": "0"
"withdrawn_tokens": "71.3630698",
"remaining_tokens": "178.6369302"
},
{
"address": "0x4A13d4dC5e06ACdA81C011D55a7DaAc332bC5Dbf",
@@ -8,6 +8,7 @@ import {
import { tooltipMapping } from '@vegaprotocol/market-info';
import {
addDecimalsFormatNumber,
createDocsLinks,
formatNumberPercentage,
} from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
@@ -38,7 +39,7 @@ import { Link, useParams } from 'react-router-dom';
import { Links, Routes } from '../../pages/client-router';
import { useMarket, useStaticMarketData } from '@vegaprotocol/market-list';
import { DocsLinks } from '@vegaprotocol/environment';
import { useEnvironment } from '@vegaprotocol/environment';
const enum LiquidityTabs {
Active = 'active',
@@ -146,6 +147,7 @@ const LiquidityViewHeader = memo(({ marketId }: { marketId?: string }) => {
market?.tradableInstrument.instrument.product.settlementAsset.decimals || 0;
const symbol =
market?.tradableInstrument.instrument.product.settlementAsset.symbol;
const { VEGA_DOCS_URL } = useEnvironment();
const { params } = useNetworkParams([
NetworkParams.market_liquidity_stakeToCcyVolume,
@@ -214,12 +216,10 @@ const LiquidityViewHeader = memo(({ marketId }: { marketId?: string }) => {
<div className="break-word">{marketId}</div>
</HeaderStat>
<HeaderStat heading={t('Learn more')}>
{DocsLinks ? (
<ExternalLink href={DocsLinks.LIQUIDITY}>
{VEGA_DOCS_URL && (
<ExternalLink href={createDocsLinks(VEGA_DOCS_URL).LIQUIDITY}>
{t('Providing liquidity')}
</ExternalLink>
) : (
(null as React.ReactNode)
)}
</HeaderStat>
</Header>
@@ -19,10 +19,11 @@ import { useCheckLiquidityStatus } from '@vegaprotocol/liquidity';
import { AuctionTrigger, MarketTradingMode } from '@vegaprotocol/types';
import {
addDecimalsFormatNumber,
createDocsLinks,
formatNumberPercentage,
} from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import { DocsLinks } from '@vegaprotocol/environment';
import { useEnvironment } from '@vegaprotocol/environment';
interface Props {
marketId?: string;
@@ -46,6 +47,8 @@ export const MarketLiquiditySupplied = ({
params.market_liquidity_targetstake_triggering_ratio
);
const { VEGA_DOCS_URL } = useEnvironment();
const variables = useMemo(
() => ({
marketId: marketId || '',
@@ -128,8 +131,11 @@ export const MarketLiquiditySupplied = ({
<Link href={`/#/liquidity/${marketId}`} data-testid="view-liquidity-link">
{t('View liquidity provision table')}
</Link>
{DocsLinks && (
<ExternalLink href={DocsLinks.LIQUIDITY} className="mt-2">
{VEGA_DOCS_URL && (
<ExternalLink
href={createDocsLinks(VEGA_DOCS_URL).LIQUIDITY}
className="mt-2"
>
{t('Learn about providing liquidity')}
</ExternalLink>
)}
+6 -4
View File
@@ -5,7 +5,6 @@ import {
TOKEN_GOVERNANCE,
useEnvironment,
useLinks,
DocsLinks,
} from '@vegaprotocol/environment';
import { t } from '@vegaprotocol/i18n';
import { useGlobalStore } from '../../stores';
@@ -23,6 +22,7 @@ import {
} from '@vegaprotocol/ui-toolkit';
import { Links, Routes } from '../../pages/client-router';
import { createDocsLinks } from '@vegaprotocol/utils';
import { SettingsButton } from '../../client-pages/settings';
import {
ProtocolUpgradeCountdown,
@@ -34,7 +34,7 @@ export const Navbar = ({
}: {
theme: ComponentProps<typeof Navigation>['theme'];
}) => {
const { GITHUB_FEEDBACK_URL } = useEnvironment();
const { VEGA_DOCS_URL, GITHUB_FEEDBACK_URL } = useEnvironment();
const tokenLink = useLinks(DApp.Token);
const { marketId } = useGlobalStore((store) => ({
marketId: store.marketId,
@@ -92,13 +92,15 @@ export const Navbar = ({
{t('Governance')}
</NavExternalLink>
</NavigationItem>
{DocsLinks?.NEW_TO_VEGA && GITHUB_FEEDBACK_URL && (
{VEGA_DOCS_URL && GITHUB_FEEDBACK_URL && (
<NavigationItem>
<NavigationTrigger>{t('Resources')}</NavigationTrigger>
<NavigationContent>
<NavigationList>
<NavigationItem>
<NavExternalLink href={DocsLinks.NEW_TO_VEGA}>
<NavExternalLink
href={createDocsLinks(VEGA_DOCS_URL).NEW_TO_VEGA}
>
{t('Docs')}
</NavExternalLink>
</NavigationItem>
@@ -8,10 +8,11 @@ import {
import { RISK_ACCEPTED_KEY } from '../constants';
import { TelemetryApproval } from './telemetry-approval';
import {
DOCS_VEGA_WALLET,
GET_VEGA_WALLET_URL,
Networks,
useDocsLink,
useEnvironment,
DocsLinks,
ExternalLinks,
} from '@vegaprotocol/environment';
import { useLocalStorage } from '@vegaprotocol/react-helpers';
@@ -52,6 +53,8 @@ export const RiskNoticeDialog = ({ onClose, network }: Props) => {
const TestnetContent = ({ network }: { network: Networks }) => {
const { GITHUB_FEEDBACK_URL } = useEnvironment();
const docsLink = useDocsLink();
return (
<>
<p className="mb-4">
@@ -66,16 +69,16 @@ const TestnetContent = ({ network }: { network: Networks }) => {
[network]
)}
</p>
{GITHUB_FEEDBACK_URL && DocsLinks && (
{GITHUB_FEEDBACK_URL && GET_VEGA_WALLET_URL && docsLink && (
<ul className="list-disc pl-4">
<li className="mb-1">
<Link href={ExternalLinks.VEGA_WALLET_URL} target="_blank">
<Link href={GET_VEGA_WALLET_URL} target="_blank">
<span className="underline">{t('Get a Vega Wallet')}</span>{' '}
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} />
</Link>
</li>
<li className="mb-1">
<Link href={DocsLinks.VEGA_WALLET_TOOLS_URL} target="_blank">
<Link href={docsLink(DOCS_VEGA_WALLET)} target="_blank">
<span className="underline">{t('Learn about Vega Wallet')}</span>{' '}
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} />
</Link>
@@ -1,13 +1,13 @@
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/i18n';
import {
BLOG,
DApp,
Networks,
TOKEN_NEW_MARKET_PROPOSAL,
TOKEN_PROPOSALS,
useEnvironment,
useLinks,
ExternalLinks,
} from '@vegaprotocol/environment';
import { ProposedMarkets } from './proposed-markets';
@@ -52,7 +52,7 @@ export const WelcomeNoticeDialog = () => {
</ExternalLink>
</li>
<li>
<ExternalLink target="_blank" href={ExternalLinks.BLOG}>
<ExternalLink target="_blank" href={BLOG}>
{t('Read about the mainnet launch')}
</ExternalLink>
</li>
@@ -2,8 +2,8 @@ import { useMemo } from 'react';
import { parseISO, isValid, isAfter } from 'date-fns';
import classNames from 'classnames';
import { useProposalOfMarketQuery } from '@vegaprotocol/proposals';
import { DocsLinks } from '@vegaprotocol/environment';
import { getDateTimeFormat } from '@vegaprotocol/utils';
import { useEnvironment } from '@vegaprotocol/environment';
import { createDocsLinks, getDateTimeFormat } from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import * as Schema from '@vegaprotocol/types';
import { ExternalLink, SimpleGrid } from '@vegaprotocol/ui-toolkit';
@@ -23,6 +23,7 @@ export const TradingModeTooltip = ({
skip,
skipGrid,
}: TradingModeTooltipProps) => {
const { VEGA_DOCS_URL } = useEnvironment();
const { data: market } = useMarket(marketId);
const { data: marketData } = useStaticMarketData(marketId, skip);
const { marketTradingMode, trigger } = marketData || {};
@@ -101,9 +102,9 @@ export const TradingModeTooltip = ({
</span>
</>
)}
{DocsLinks && (
{VEGA_DOCS_URL && (
<ExternalLink
href={DocsLinks.AUCTION_TYPE_OPENING}
href={createDocsLinks(VEGA_DOCS_URL).AUCTION_TYPE_OPENING}
className="ml-1"
>
{t('Find out more')}
@@ -125,9 +126,12 @@ export const TradingModeTooltip = ({
'This market is in auction until it reaches sufficient liquidity.'
)}
</span>
{DocsLinks && (
{VEGA_DOCS_URL && (
<ExternalLink
href={DocsLinks.AUCTION_TYPE_LIQUIDITY_MONITORING}
href={
createDocsLinks(VEGA_DOCS_URL)
.AUCTION_TYPE_LIQUIDITY_MONITORING
}
className="ml-1"
>
{t('Find out more')}
@@ -147,9 +151,12 @@ export const TradingModeTooltip = ({
'This market may have sufficient liquidity but there are not enough priced limit orders in the order book, which are required to deploy liquidity commitment pegged orders.'
)}
</span>
{DocsLinks && (
{VEGA_DOCS_URL && (
<ExternalLink
href={DocsLinks.AUCTION_TYPE_LIQUIDITY_MONITORING}
href={
createDocsLinks(VEGA_DOCS_URL)
.AUCTION_TYPE_LIQUIDITY_MONITORING
}
className="ml-1"
>
{t('Find out more')}
@@ -167,9 +174,12 @@ export const TradingModeTooltip = ({
<span>
{t('This market is in auction due to high price volatility.')}
</span>{' '}
{DocsLinks && (
{VEGA_DOCS_URL && (
<ExternalLink
href={DocsLinks.AUCTION_TYPE_PRICE_MONITORING}
href={
createDocsLinks(VEGA_DOCS_URL)
.AUCTION_TYPE_PRICE_MONITORING
}
className="ml-1"
>
{t('Find out more')}
+23 -37
View File
@@ -4,8 +4,6 @@ import { Networks } from '../types';
import { useEnvironment } from './use-environment';
import { stripFullStops } from '@vegaprotocol/utils';
const VEGA_DOCS_URL = process.env['NX_VEGA_DOCS_URL'] || '';
type Net = Exclude<Networks, 'CUSTOM'>;
export enum DApp {
Explorer = 'Explorer',
@@ -52,25 +50,6 @@ const Links: { [k in DApp]: DAppLinks } = {
[DApp.Token]: TokenLinks,
};
export const DocsLinks = VEGA_DOCS_URL
? {
NEW_TO_VEGA: `${VEGA_DOCS_URL}/concepts/new-to-vega`,
AUCTION_TYPE_OPENING: `${VEGA_DOCS_URL}/concepts/trading-on-vega/trading-modes#auction-type-opening`,
AUCTION_TYPE_LIQUIDITY_MONITORING: `${VEGA_DOCS_URL}/concepts/trading-on-vega/trading-modes#auction-type-liquidity-monitoring`,
AUCTION_TYPE_PRICE_MONITORING: `${VEGA_DOCS_URL}/concepts/trading-on-vega/trading-modes#auction-type-price-monitoring`,
AUCTION_TYPE_CLOSING: `${VEGA_DOCS_URL}/concepts/trading-on-vega/trading-modes#auction-type-closing`,
STAKING_GUIDE: `${VEGA_DOCS_URL}/concepts/vega-chain/#staking-on-vega`,
REWARDS_GUIDE: `${VEGA_DOCS_URL}/concepts/trading-on-vega/fees-rewards#trading-rewards`,
VEGA_WALLET_CONCEPTS_URL: `${VEGA_DOCS_URL}/concepts/vega-wallet`,
VEGA_WALLET_TOOLS_URL: `${VEGA_DOCS_URL}/tools/vega-wallet`,
PROPOSALS_GUIDE: `${VEGA_DOCS_URL}/tutorials/proposals`,
NODE_OPERATORS: `${VEGA_DOCS_URL}/node-operators`,
LOSS_SOCIALIZATION: `${VEGA_DOCS_URL}/concepts/trading-on-vega/market-protections#loss-socialisation`,
POSITION_RESOLUTION: `${VEGA_DOCS_URL}/concepts/trading-on-vega/market-protections#position-resolution`,
LIQUIDITY: `${VEGA_DOCS_URL}/concepts/liquidity/provision`,
}
: undefined;
export const useLinks = (dapp: DApp, network?: Net) => {
const { VEGA_ENV, VEGA_EXPLORER_URL, VEGA_TOKEN_URL } = useEnvironment();
const fallback = {
@@ -105,6 +84,19 @@ export const useEtherscanLink = () => {
return link;
};
export const useDocsLink = () => {
const { VEGA_DOCS_URL } = useEnvironment();
const baseUrl = trim(VEGA_DOCS_URL, '/');
const link = useCallback(
(url?: string) => `${baseUrl}/${trim(url, '/') || ''}`,
[baseUrl]
);
return link;
};
// Vega blog
export const BLOG = 'https://blog.vega.xyz/';
// Governance pages
export const TOKEN_NEW_MARKET_PROPOSAL = '/proposals/propose/new-market';
export const TOKEN_NEW_NETWORK_PARAM_PROPOSAL =
@@ -138,20 +130,14 @@ export const EXPLORER_ORACLE = '/oracles/:id';
export const ETHERSCAN_ADDRESS = '/address/:hash';
export const ETHERSCAN_TX = '/tx/:hash';
export const ExternalLinks = {
FEEDBACK: 'https://github.com/vegaprotocol/feedback/discussions',
GITHUB: 'https://github.com/vegaprotocol/token-frontend',
DISCORD: 'https://vega.xyz/discord',
GOVERNANCE_PAGE: 'https://vega.xyz/governance',
VALIDATOR_FORUM: 'https://community.vega.xyz/c/mainnet-validator-candidates',
MARGIN_CREDIT_RISK:
'https://vega.xyz/papers/margins-and-credit-risk.pdf#page=7',
VEGA_WALLET_URL: 'https://vega.xyz/wallet',
VEGA_WALLET_HOSTED_URL: 'https://vega-hosted-wallet.on.fleek.co/',
BLOG: 'https://blog.vega.xyz/',
};
// Console pages
export const CONSOLE_MARKET = '/markets/:marketId';
export const CONSOLE_MARKETS = '/markets/all';
export const CONSOLE_PORTFOLIO = '/portfolio';
export const CONSOLE_LIQUIDITY = 'liquidity/:marketId';
export const TokenStaticLinks = {
PROPOSAL_PAGE: ':tokenUrl/proposals/:proposalId',
UPDATE_PROPOSAL_PAGE: ':tokenUrl/proposals/propose/update-market',
};
// Vega XYZ
export const GET_VEGA_WALLET_URL = 'https://vega.xyz/wallet/';
// Docs
export const DOCS_VEGA_WALLET = '/tools/vega-wallet';
+1 -1
View File
@@ -1,5 +1,5 @@
{
"name": "@vegaprotocol/i18n",
"version": "0.0.3",
"version": "0.0.2",
"type": "commonjs"
}
@@ -1,5 +1,5 @@
import { TokenStaticLinks, useEnvironment } from '@vegaprotocol/environment';
import { removePaginationWrapper } from '@vegaprotocol/utils';
import { useEnvironment } from '@vegaprotocol/environment';
import { removePaginationWrapper, TokenLinks } from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import { useDataProvider } from '@vegaprotocol/data-provider';
import * as Schema from '@vegaprotocol/types';
@@ -236,7 +236,7 @@ export const MarketInfoAccordion = ({
{VEGA_TOKEN_URL && (
<ExternalLink
className="mb-2 w-full"
href={generatePath(TokenStaticLinks.PROPOSAL_PAGE, {
href={generatePath(TokenLinks.PROPOSAL_PAGE, {
tokenUrl: VEGA_TOKEN_URL,
proposalId: market.proposal?.id || '',
})}
@@ -252,7 +252,7 @@ export const MarketInfoAccordion = ({
{VEGA_TOKEN_URL && (
<ExternalLink
className="w-full"
href={generatePath(TokenStaticLinks.UPDATE_PROPOSAL_PAGE, {
href={generatePath(TokenLinks.UPDATE_PROPOSAL_PAGE, {
tokenUrl: VEGA_TOKEN_URL,
})}
title={
@@ -1,4 +1,4 @@
import { ExternalLinks } from '@vegaprotocol/environment';
import { ExternalLinks } from '@vegaprotocol/utils';
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/i18n';
import type { ReactNode } from 'react';
+11 -5
View File
@@ -30,6 +30,7 @@ import {
formatNumber,
getDateTimeFormat,
addDecimalsFormatNumber,
createDocsLinks,
} from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import { AgGridColumn } from 'ag-grid-react';
@@ -38,7 +39,7 @@ import type { Position } from './positions-data-providers';
import * as Schema from '@vegaprotocol/types';
import { getRowId } from './use-positions-data';
import { PositionStatus, PositionStatusMapping } from '@vegaprotocol/types';
import { DocsLinks } from '@vegaprotocol/environment';
import { useEnvironment } from '@vegaprotocol/environment';
interface Props extends TypedDataAgGrid<Position> {
onClose?: (data: Position) => void;
@@ -396,7 +397,9 @@ export const PNLCell = ({
valueFormatted,
data,
}: VegaICellRendererParams<Position, 'realisedPNL'>) => {
const LOSS_SOCIALIZATION_LINK = DocsLinks?.LOSS_SOCIALIZATION ?? '';
const { VEGA_DOCS_URL } = useEnvironment();
const LOSS_SOCIALIZATION_LINK =
VEGA_DOCS_URL && createDocsLinks(VEGA_DOCS_URL).LOSS_SOCIALIZATION;
if (!data) {
return <>-</>;
@@ -420,7 +423,7 @@ export const PNLCell = ({
<p className="mb-2">
{t('Lifetime loss socialisation deductions: %s', lossesFormatted)}
</p>
{LOSS_SOCIALIZATION_LINK && (
{VEGA_DOCS_URL && (
<ExternalLink href={LOSS_SOCIALIZATION_LINK}>
{t('Read more about loss socialisation')}
</ExternalLink>
@@ -437,6 +440,8 @@ export const OpenVolumeCell = ({
valueFormatted,
data,
}: VegaICellRendererParams<Position, 'openVolume'>) => {
const { VEGA_DOCS_URL } = useEnvironment();
if (!data) {
return <>-</>;
}
@@ -446,7 +451,8 @@ export const OpenVolumeCell = ({
return <>{valueFormatted}</>;
}
const POSITION_RESOLUTION_LINK = DocsLinks?.POSITION_RESOLUTION ?? '';
const POSITION_RESOLUTION_LINK =
VEGA_DOCS_URL && createDocsLinks(VEGA_DOCS_URL).POSITION_RESOLUTION;
return (
<WarningCell
@@ -463,7 +469,7 @@ export const OpenVolumeCell = ({
]
)}
</p>
{POSITION_RESOLUTION_LINK && (
{VEGA_DOCS_URL && (
<ExternalLink href={POSITION_RESOLUTION_LINK}>
{t('Read more about position resolution')}
</ExternalLink>
+1 -1
View File
@@ -1,4 +1,4 @@
{
"name": "@vegaprotocol/react-helpers",
"version": "0.2.3"
"version": "0.2.2"
}
+1 -1
View File
@@ -1,4 +1,4 @@
{
"name": "@vegaprotocol/tailwindcss-config",
"version": "0.0.3"
"version": "0.0.2"
}
+1 -1
View File
@@ -1,4 +1,4 @@
{
"name": "@vegaprotocol/types",
"version": "0.0.3"
"version": "0.0.2"
}
+1 -1
View File
@@ -1,4 +1,4 @@
{
"name": "@vegaprotocol/ui-toolkit",
"version": "0.12.2"
"version": "0.12.1"
}
@@ -181,7 +181,6 @@ export const HealthBar = ({
prevLevel={prevLevel}
decimals={0}
intent={intent}
key={'healthbar-segment-' + index}
/>
) : null;
})}
+1 -1
View File
@@ -1,5 +1,5 @@
{
"name": "@vegaprotocol/utils",
"version": "0.0.3",
"version": "0.0.2",
"type": "commonjs"
}
+1
View File
@@ -6,6 +6,7 @@ export * from './lib/get-user-locale';
export * from './lib/helpers';
export * from './lib/is-asset-erc20';
export * from './lib/is-valid-url';
export * from './lib/links';
export * from './lib/local-logger';
export * from './lib/local-storage';
export * from './lib/markets';
+36
View File
@@ -0,0 +1,36 @@
/** createDocsLinks returns external documentation links that are specific to an environment
* @param {string} docsUrl - the documentation URL for the environment ex. https://docs.vega.xyz/testnet or https://docs.vega.xyz/mainnet (NX_VEGA_DOCS_URL)
*/
export const createDocsLinks = (docsUrl: string) => ({
NEW_TO_VEGA: `${docsUrl}/concepts/new-to-vega`,
AUCTION_TYPE_OPENING: `${docsUrl}/concepts/trading-on-vega/trading-modes#auction-type-opening`,
AUCTION_TYPE_LIQUIDITY_MONITORING: `${docsUrl}/concepts/trading-on-vega/trading-modes#auction-type-liquidity-monitoring`,
AUCTION_TYPE_PRICE_MONITORING: `${docsUrl}/concepts/trading-on-vega/trading-modes#auction-type-price-monitoring`,
AUCTION_TYPE_CLOSING: `${docsUrl}/concepts/trading-on-vega/trading-modes#auction-type-closing`,
STAKING_GUIDE: `${docsUrl}/concepts/vega-chain/#staking-on-vega`,
REWARDS_GUIDE: `${docsUrl}/concepts/trading-on-vega/fees-rewards#trading-rewards`,
VEGA_WALLET_CONCEPTS_URL: `${docsUrl}/concepts/vega-wallet`,
PROPOSALS_GUIDE: `${docsUrl}/tutorials/proposals`,
NODE_OPERATORS: `${docsUrl}/node-operators`,
LOSS_SOCIALIZATION: `${docsUrl}/concepts/trading-on-vega/market-protections#loss-socialisation`,
POSITION_RESOLUTION: `${docsUrl}/concepts/trading-on-vega/market-protections#position-resolution`,
LIQUIDITY: `${docsUrl}/concepts/liquidity/provision`,
});
export const ExternalLinks = {
FEEDBACK: 'https://github.com/vegaprotocol/feedback/discussions',
GITHUB: 'https://github.com/vegaprotocol/token-frontend',
DISCORD: 'https://vega.xyz/discord',
GOVERNANCE_PAGE: 'https://vega.xyz/governance',
VALIDATOR_FORUM: 'https://community.vega.xyz/c/mainnet-validator-candidates',
MARGIN_CREDIT_RISK:
'https://vega.xyz/papers/margins-and-credit-risk.pdf#page=7',
VEGA_WALLET_URL: 'https://vega.xyz/wallet',
VEGA_WALLET_HOSTED_URL: 'https://vega-hosted-wallet.on.fleek.co/',
};
export const TokenLinks = {
PROPOSAL_PAGE: ':tokenUrl/proposals/:proposalId',
UPDATE_PROPOSAL_PAGE: ':tokenUrl/proposals/propose/update-market',
};
@@ -1,4 +1,5 @@
import { DocsLinks, ExternalLinks } from '@vegaprotocol/environment';
import { useEnvironment } from '@vegaprotocol/environment';
import { createDocsLinks, ExternalLinks } from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import { Link } from '@vegaprotocol/ui-toolkit';
import type { ReactNode } from 'react';
@@ -19,6 +20,7 @@ export const ConnectDialogContent = ({ children }: { children: ReactNode }) => {
};
export const ConnectDialogFooter = ({ children }: { children?: ReactNode }) => {
const { VEGA_DOCS_URL } = useEnvironment();
return (
<footer className="flex justify-center gap-4 px-4 md:px-8 pt-4 md:pt-6 -mx-4 md:-mx-8 border-t border-neutral-500 text-neutral-500 dark:text-neutral-400">
{children ? (
@@ -29,8 +31,10 @@ export const ConnectDialogFooter = ({ children }: { children?: ReactNode }) => {
{t('Get a Vega Wallet')}
</Link>
{' | '}
{DocsLinks && (
<Link href={DocsLinks.VEGA_WALLET_CONCEPTS_URL}>
{VEGA_DOCS_URL && (
<Link
href={createDocsLinks(VEGA_DOCS_URL).VEGA_WALLET_CONCEPTS_URL}
>
{t('Having trouble?')}
</Link>
)}
@@ -10,17 +10,14 @@ import {
} from '@vegaprotocol/ui-toolkit';
import { useCallback, useState } from 'react';
import type { WalletClientError } from '@vegaprotocol/wallet-client';
import { ExternalLinks } from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import type { VegaConnector } from '../connectors';
import { ViewConnector } from '../connectors';
import { JsonRpcConnector, RestConnector } from '../connectors';
import { RestConnectorForm } from './rest-connector-form';
import { JsonRpcConnectorForm } from './json-rpc-connector-form';
import {
Networks,
useEnvironment,
ExternalLinks,
} from '@vegaprotocol/environment';
import { Networks, useEnvironment } from '@vegaprotocol/environment';
import {
ConnectDialogContent,
ConnectDialogFooter,
@@ -1,4 +1,5 @@
import capitalize from 'lodash/capitalize';
import { createDocsLinks } from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import {
ButtonLink,
@@ -13,7 +14,7 @@ import type { JsonRpcConnector } from '../connectors';
import { ClientErrors } from '../connectors';
import { ConnectDialogTitle } from './connect-dialog-elements';
import { Status } from '../use-json-rpc-connect';
import { DocsLinks } from '@vegaprotocol/environment';
import { useEnvironment } from '@vegaprotocol/environment';
export const ServiceErrors = {
NO_HEALTHY_NODE: 1000,
@@ -152,6 +153,7 @@ const Error = ({
<ButtonLink onClick={onTryAgain}>{t('Try again')}</ButtonLink>
</p>
);
const { VEGA_DOCS_URL } = useEnvironment();
if (error) {
if (error.code === ClientErrors.NO_SERVICE.code) {
@@ -171,8 +173,10 @@ const Error = ({
<>
{capitalize(error.message)}
{'. '}
{DocsLinks && (
<Link href={DocsLinks.VEGA_WALLET_CONCEPTS_URL}>
{VEGA_DOCS_URL && (
<Link
href={createDocsLinks(VEGA_DOCS_URL).VEGA_WALLET_CONCEPTS_URL}
>
{t('Read the docs to troubleshoot')}
</Link>
)}