Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94cc725b2a | ||
|
|
a9c5605a24 | ||
|
|
06daf74ba8 | ||
|
|
c7d0025b4f | ||
|
|
6c9272cd53 |
@@ -12,6 +12,7 @@ import {
|
||||
SPECIAL_CASE_NETWORK,
|
||||
SPECIAL_CASE_NETWORK_ID,
|
||||
} from '../../links/party-link/party-link';
|
||||
import { txSignatureToDeterministicId } from '../lib/deterministic-ids';
|
||||
|
||||
type Transfer = components['schemas']['commandsv1Transfer'];
|
||||
|
||||
@@ -63,10 +64,16 @@ export const TxDetailsTransfer = ({
|
||||
return (
|
||||
<>
|
||||
<TableWithTbody className="mb-8" allowWrap={true}>
|
||||
<TableRow modifier="bordered">
|
||||
<TableRow modifier="bordered" data-testid="type">
|
||||
<TableCell {...sharedHeaderProps}>{t('Type')}</TableCell>
|
||||
<TableCell>{getTypeLabelForTransfer(transfer)}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow modifier="bordered" data-testid="id">
|
||||
<TableCell {...sharedHeaderProps}>{t('Transfer ID')}</TableCell>
|
||||
<TableCell>
|
||||
{txSignatureToDeterministicId(txData.signature.value)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TxDetailsShared
|
||||
txData={txData}
|
||||
pubKey={pubKey}
|
||||
@@ -74,7 +81,7 @@ export const TxDetailsTransfer = ({
|
||||
hideTypeRow={true}
|
||||
/>
|
||||
{from ? (
|
||||
<TableRow modifier="bordered">
|
||||
<TableRow modifier="bordered" data-testid="from">
|
||||
<TableCell>{t('From')}</TableCell>
|
||||
<TableCell>
|
||||
<PartyLink id={from} />
|
||||
@@ -82,7 +89,7 @@ export const TxDetailsTransfer = ({
|
||||
</TableRow>
|
||||
) : null}
|
||||
{transfer.to ? (
|
||||
<TableRow modifier="bordered">
|
||||
<TableRow modifier="bordered" data-testid="to">
|
||||
<TableCell>{t('To')}</TableCell>
|
||||
<TableCell>
|
||||
<PartyLink id={transfer.to} />
|
||||
@@ -90,7 +97,7 @@ export const TxDetailsTransfer = ({
|
||||
</TableRow>
|
||||
) : null}
|
||||
{transfer.asset && transfer.amount ? (
|
||||
<TableRow modifier="bordered">
|
||||
<TableRow modifier="bordered" data-testid="amount">
|
||||
<TableCell>{t('Amount')}</TableCell>
|
||||
<TableCell>
|
||||
<SizeInAsset assetId={transfer.asset} size={transfer.amount} />
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
import { getTypeLabelForTransfer } from './details/tx-transfer';
|
||||
import type { BlockExplorerTransactionResult } from '../../routes/types/block-explorer-response';
|
||||
import type { TendermintBlocksResponse } from '../../routes/blocks/tendermint-blocks-response';
|
||||
import type { components } from '../../../types/explorer';
|
||||
|
||||
import {
|
||||
TxDetailsTransfer,
|
||||
getTypeLabelForTransfer,
|
||||
} from './details/tx-transfer';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
type Transfer = components['schemas']['commandsv1Transfer'];
|
||||
|
||||
describe('TX: Transfer: getLabelForTransfer', () => {
|
||||
@@ -56,3 +65,70 @@ describe('TX: Transfer: getLabelForTransfer', () => {
|
||||
expect(getTypeLabelForTransfer(mock)).toEqual('Transfer');
|
||||
});
|
||||
});
|
||||
|
||||
describe('TxDetailsTransfer', () => {
|
||||
const mockBlockData = {
|
||||
result: {
|
||||
block: {
|
||||
header: {
|
||||
height: '123',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const mockTxData: Partial<BlockExplorerTransactionResult> = {
|
||||
hash: 'test',
|
||||
submitter:
|
||||
'e1943eea46fed576cf2be42972f3c5515ad3d0ac7ac013f56677c12a53a1b3ed',
|
||||
command: {
|
||||
nonce: '5188810881378065222',
|
||||
blockHeight: '14951513',
|
||||
transfer: {
|
||||
fromAccountType: 'ACCOUNT_TYPE_GENERAL',
|
||||
to: '78432a2808f20b18a46ccc6a917bdc4d63c2b9e7007f777bdcab5a9f462c5ba6',
|
||||
toAccountType: 'ACCOUNT_TYPE_GENERAL',
|
||||
asset:
|
||||
'dd20590509d30d20bdbbe64dc1090c1140c7690121a9b9940bc66f62dfa2e599',
|
||||
amount: '4800000000',
|
||||
reference: '',
|
||||
oneOff: {
|
||||
deliverOn: '0',
|
||||
},
|
||||
},
|
||||
},
|
||||
signature: {
|
||||
value:
|
||||
'610c2e196a7d4fed4413b9e82af267b1ff3e30e943df3a3d28096fd60604d430d752fbaf6dd4f84d496be78885bb6118f40560bff7832c06bd7a3d67b718b700',
|
||||
},
|
||||
};
|
||||
|
||||
it('renders basic transfer details', () => {
|
||||
const { getByTestId } = render(
|
||||
<MockedProvider>
|
||||
<MemoryRouter>
|
||||
<TxDetailsTransfer
|
||||
txData={mockTxData as BlockExplorerTransactionResult}
|
||||
pubKey={mockTxData.command.submitter}
|
||||
blockData={mockBlockData as TendermintBlocksResponse}
|
||||
/>
|
||||
</MemoryRouter>
|
||||
</MockedProvider>
|
||||
);
|
||||
|
||||
const id = getByTestId('id');
|
||||
expect(id.children[0].textContent).toEqual('Transfer ID');
|
||||
expect(id.children[1].textContent).toEqual(
|
||||
'51f3bab5eb2637651012507a64d497790a734248792c16e5cf36df8984074fbd'
|
||||
);
|
||||
|
||||
const type = getByTestId('type');
|
||||
expect(type.children[1].textContent).toEqual('Transfer');
|
||||
|
||||
const from = getByTestId('from');
|
||||
expect(from.children[1].textContent).toEqual(mockTxData.submitter);
|
||||
|
||||
const to = getByTestId('to');
|
||||
expect(to.children[1].textContent).toEqual(mockTxData.command.transfer.to);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -49,10 +49,10 @@ describe('capsule - without MultiSign', { tags: '@slow' }, () => {
|
||||
cy.wrap(markets[0]).as('market');
|
||||
});
|
||||
cy.visit('/#/portfolio');
|
||||
cy.connectVegaWallet();
|
||||
});
|
||||
|
||||
it('can deposit', function () {
|
||||
cy.setOnBoardingViewed();
|
||||
cy.visit('/#/portfolio');
|
||||
cy.get('[data-testid="pathname-/portfolio"]').should('exist');
|
||||
|
||||
@@ -70,6 +70,8 @@ describe('capsule - without MultiSign', { tags: '@slow' }, () => {
|
||||
cy.getByTestId('deposit-button').click();
|
||||
connectEthereumWallet('Unknown');
|
||||
selectAsset(btcName);
|
||||
cy.get('[data-testid="rich-select-option"]').eq(btcName).click();
|
||||
|
||||
cy.getByTestId('approve-default').should(
|
||||
'contain.text',
|
||||
`Before you can make a deposit of your chosen asset, ${btcSymbol}, you need to approve its use in your Ethereum wallet`
|
||||
@@ -120,7 +122,7 @@ describe('capsule - without MultiSign', { tags: '@slow' }, () => {
|
||||
cy.get('[data-testid="pathname-/portfolio"]').should('exist');
|
||||
|
||||
cy.getByTestId(collateralTab).click();
|
||||
cy.getByTestId('open-transfer').click();
|
||||
cy.getByTestId('open-transfer').eq(1).click();
|
||||
cy.getByTestId('transfer-form').should('be.visible');
|
||||
cy.getByTestId('transfer-form').find('[name="toAddress"]').select(1);
|
||||
cy.get('select option')
|
||||
@@ -147,7 +149,8 @@ describe('capsule - without MultiSign', { tags: '@slow' }, () => {
|
||||
// 0003-WTXN-011
|
||||
cy.getByTestId('Withdrawals').click();
|
||||
cy.getByTestId('withdraw-dialog-button').click();
|
||||
selectAsset(0);
|
||||
selectAsset(btcName);
|
||||
cy.get('[data-testid="rich-select-option"]').eq(btcName).click();
|
||||
cy.get(amountField).focus();
|
||||
cy.get(amountField).clear().type('1');
|
||||
cy.getByTestId('submit-withdrawal').click();
|
||||
@@ -185,19 +188,15 @@ describe('capsule', { tags: '@slow', testIsolation: true }, () => {
|
||||
|
||||
it('shows node health', function () {
|
||||
// 0006-NETW-010
|
||||
const regex = /^Operational\d+$/;
|
||||
const market = this.market;
|
||||
cy.visit(`/#/markets/${market.id}`);
|
||||
cy.getByTestId('node-health-trigger').realHover();
|
||||
cy.getByTestId('node-health')
|
||||
.children()
|
||||
.first()
|
||||
.should('contain.text', 'Operational')
|
||||
.then(($el) => {
|
||||
const blockHeight = parseInt($el.text());
|
||||
// block height will increase over the course of the test run so best
|
||||
// we can do here is check that its showing something sensible
|
||||
expect(blockHeight).to.be.greaterThan(0);
|
||||
});
|
||||
.invoke('text')
|
||||
.should('match', regex);
|
||||
cy.getByTestId('node-health')
|
||||
.children()
|
||||
.eq(1)
|
||||
@@ -239,7 +238,6 @@ describe('capsule', { tags: '@slow', testIsolation: true }, () => {
|
||||
.should('contain.text', order.size);
|
||||
|
||||
cy.getByTestId(openOrdersTab).click();
|
||||
cy.getByTestId('edit', txTimeout).should('contain.text', 'Edit');
|
||||
cy.getByTestId('tab-open-orders').within(() => {
|
||||
cy.get('.ag-center-cols-container')
|
||||
.children()
|
||||
@@ -280,8 +278,7 @@ describe('capsule', { tags: '@slow', testIsolation: true }, () => {
|
||||
cy.visit(`/#/markets/${market.id}`);
|
||||
cy.getByTestId(toastCloseBtn, txTimeout).click();
|
||||
cy.getByTestId(openOrdersTab).click();
|
||||
cy.getByTestId('edit', txTimeout).should('be.visible');
|
||||
cy.getByTestId('edit').first().should('be.visible').click();
|
||||
cy.getByTestId('edit').first().click();
|
||||
cy.getByTestId('dialog-title').should('contain.text', 'Edit order');
|
||||
cy.get('#limitPrice').focus().clear().type(newPrice);
|
||||
cy.getByTestId('edit-order').find('[type="submit"]').click();
|
||||
@@ -350,6 +347,7 @@ describe('capsule', { tags: '@slow', testIsolation: true }, () => {
|
||||
cy.getByTestId('withdraw-dialog-button').click();
|
||||
connectEthereumWallet('Unknown');
|
||||
selectAsset(btcName);
|
||||
cy.get('[data-testid="rich-select-option"]').eq(btcName).click();
|
||||
cy.get(amountField).clear().type('1');
|
||||
cy.getByTestId('submit-withdrawal').click();
|
||||
cy.getByTestId(toastContent, txTimeout).should(
|
||||
@@ -437,6 +435,7 @@ describe('capsule', { tags: '@slow', testIsolation: true }, () => {
|
||||
cy.getByTestId('deposit-button').click();
|
||||
connectEthereumWallet('Unknown');
|
||||
selectAsset(btcName);
|
||||
cy.get('[data-testid="rich-select-option"]').eq(btcName).click();
|
||||
cy.contains('Deposits of tBTC not approved').should('not.exist');
|
||||
cy.contains('Use maximum').should('be.visible');
|
||||
cy.get(amountField).clear().type('20000000');
|
||||
|
||||
@@ -81,7 +81,7 @@ export const ApplyCodeForm = () => {
|
||||
if (!res) {
|
||||
setError('code', {
|
||||
type: 'required',
|
||||
message: 'The transaction could not be sent',
|
||||
message: t('The transaction could not be sent'),
|
||||
});
|
||||
}
|
||||
if (res) {
|
||||
@@ -98,7 +98,7 @@ export const ApplyCodeForm = () => {
|
||||
message:
|
||||
err instanceof Error
|
||||
? err.message
|
||||
: 'Your code has been rejected',
|
||||
: t('Your code has been rejected'),
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -152,7 +152,7 @@ export const ApplyCodeForm = () => {
|
||||
<span className="text-vega-green-500">
|
||||
<VegaIcon name={VegaIconNames.TICK} size={20} />
|
||||
</span>{' '}
|
||||
<span className="pt-1">Code applied</span>
|
||||
<span className="pt-1">{t('Code applied')}</span>
|
||||
</h3>
|
||||
</div>
|
||||
);
|
||||
@@ -162,7 +162,7 @@ export const ApplyCodeForm = () => {
|
||||
if (!pubKey) {
|
||||
return {
|
||||
disabled: false,
|
||||
children: 'Connect wallet',
|
||||
children: t('Connect wallet'),
|
||||
type: 'button' as ButtonHTMLAttributes<HTMLButtonElement>['type'],
|
||||
onClick: ((event) => {
|
||||
event.preventDefault();
|
||||
@@ -174,7 +174,7 @@ export const ApplyCodeForm = () => {
|
||||
if (isReadOnly) {
|
||||
return {
|
||||
disabled: true,
|
||||
children: 'Apply a code',
|
||||
children: t('Apply a code'),
|
||||
type: 'submit' as ButtonHTMLAttributes<HTMLButtonElement>['type'],
|
||||
};
|
||||
}
|
||||
@@ -182,14 +182,14 @@ export const ApplyCodeForm = () => {
|
||||
if (status === 'requested') {
|
||||
return {
|
||||
disabled: true,
|
||||
children: 'Confirm in wallet...',
|
||||
children: t('Confirm in wallet...'),
|
||||
type: 'submit' as ButtonHTMLAttributes<HTMLButtonElement>['type'],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
children: 'Apply a code',
|
||||
children: t('Apply a code'),
|
||||
type: 'submit' as ButtonHTMLAttributes<HTMLButtonElement>['type'],
|
||||
};
|
||||
};
|
||||
@@ -198,10 +198,10 @@ export const ApplyCodeForm = () => {
|
||||
<>
|
||||
<div className="w-2/3 max-w-md mx-auto bg-vega-clight-800 dark:bg-vega-cdark-800 p-8 rounded-lg">
|
||||
<h3 className="mb-4 text-2xl text-center calt">
|
||||
Apply a referral code
|
||||
{t('Apply a referral code')}
|
||||
</h3>
|
||||
<p className="mb-4 text-center text-base">
|
||||
Enter a referral code to get trading discounts.
|
||||
{t('Enter a referral code to get trading discounts.')}
|
||||
</p>
|
||||
<form
|
||||
className={classNames('w-full flex flex-col gap-4', {
|
||||
@@ -210,11 +210,11 @@ export const ApplyCodeForm = () => {
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
>
|
||||
<label>
|
||||
<span className="sr-only">Your referral code</span>
|
||||
<span className="sr-only">{t('Your referral code')}</span>
|
||||
<Input
|
||||
hasError={Boolean(errors.code)}
|
||||
{...register('code', {
|
||||
required: 'You have to provide a code to apply it.',
|
||||
required: t('You have to provide a code to apply it.'),
|
||||
validate: validateCode,
|
||||
})}
|
||||
placeholder="Enter a code"
|
||||
@@ -236,7 +236,7 @@ export const ApplyCodeForm = () => {
|
||||
) : null}
|
||||
{previewData ? (
|
||||
<div className="mt-10">
|
||||
<h2 className="text-2xl mb-5">You are joining</h2>
|
||||
<h2 className="text-2xl mb-5">{t('You are joining')}</h2>
|
||||
<Statistics data={previewData} as="referee" />
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
DISCLAIMER_REFERRAL_DOCS_LINK,
|
||||
} from './constants';
|
||||
import { useReferral } from './hooks/use-referral';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
|
||||
export const CreateCodeContainer = () => {
|
||||
return <CreateCodeForm />;
|
||||
@@ -38,10 +39,13 @@ export const CreateCodeForm = () => {
|
||||
|
||||
return (
|
||||
<div className="w-2/3 max-w-md mx-auto bg-vega-clight-800 dark:bg-vega-cdark-800 p-8 rounded-lg">
|
||||
<h3 className="mb-4 text-2xl text-center calt">Create a referral code</h3>
|
||||
<h3 className="mb-4 text-2xl text-center calt">
|
||||
{t('Create a referral code')}
|
||||
</h3>
|
||||
<p className="mb-4 text-center text-base">
|
||||
Generate a referral code to share with your friends and start earning
|
||||
commission.
|
||||
{t(
|
||||
'Generate a referral code to share with your friends and start earning commission.'
|
||||
)}
|
||||
</p>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
@@ -56,12 +60,12 @@ export const CreateCodeForm = () => {
|
||||
}
|
||||
}}
|
||||
>
|
||||
{pubKey ? 'Create a referral code' : 'Connect wallet'}
|
||||
{pubKey ? t('Create a referral code') : t('Connect wallet')}
|
||||
</RainbowButton>
|
||||
</div>
|
||||
|
||||
<Dialog
|
||||
title="Create a referral code"
|
||||
title={t('Create a referral code')}
|
||||
open={dialogOpen}
|
||||
onChange={() => setDialogOpen(false)}
|
||||
size="small"
|
||||
@@ -124,21 +128,21 @@ const CreateCodeDialog = ({
|
||||
const getButtonProps = () => {
|
||||
if (status === 'idle' || status === 'error') {
|
||||
return {
|
||||
children: 'Generate code',
|
||||
children: t('Generate code'),
|
||||
onClick: () => onSubmit(),
|
||||
};
|
||||
}
|
||||
|
||||
if (status === 'loading') {
|
||||
return {
|
||||
children: 'Confirm in wallet...',
|
||||
children: t('Confirm in wallet...'),
|
||||
disabled: true,
|
||||
};
|
||||
}
|
||||
|
||||
if (status === 'success') {
|
||||
return {
|
||||
children: 'Close',
|
||||
children: t('Close'),
|
||||
intent: Intent.Success,
|
||||
onClick: () => {
|
||||
refetch();
|
||||
@@ -151,12 +155,12 @@ const CreateCodeDialog = ({
|
||||
if (!pubKey || currentStakeAvailable == null || requiredStake == null) {
|
||||
return (
|
||||
<div className="flex flex-col gap-4">
|
||||
<p>You must be connected to the Vega wallet.</p>
|
||||
<p>{t('You must be connected to the Vega wallet.')}</p>
|
||||
<TradingButton
|
||||
intent={Intent.Primary}
|
||||
onClick={() => setDialogOpen(false)}
|
||||
>
|
||||
Close
|
||||
{t('Close')}
|
||||
</TradingButton>
|
||||
</div>
|
||||
);
|
||||
@@ -166,16 +170,18 @@ const CreateCodeDialog = ({
|
||||
return (
|
||||
<div className="flex flex-col gap-4">
|
||||
<p>
|
||||
You need at least{' '}
|
||||
{addDecimalsFormatNumber(requiredStake.toString(), 18)} VEGA staked to
|
||||
generate a referral code and participate in the referral program.
|
||||
{t('You need at least')}{' '}
|
||||
{addDecimalsFormatNumber(requiredStake.toString(), 18)}{' '}
|
||||
{t(
|
||||
'VEGA staked to generate a referral code and participate in the referral program.'
|
||||
)}
|
||||
</p>
|
||||
<TradingAnchorButton
|
||||
href={createLink(TokenStaticLinks.ASSOCIATE)}
|
||||
intent={Intent.Primary}
|
||||
target="_blank"
|
||||
>
|
||||
Stake some $VEGA now
|
||||
{t('Stake some $VEGA now')}
|
||||
</TradingAnchorButton>
|
||||
</div>
|
||||
);
|
||||
@@ -185,8 +191,9 @@ const CreateCodeDialog = ({
|
||||
<div className="flex flex-col gap-4">
|
||||
{(status === 'idle' || status === 'loading' || status === 'error') && (
|
||||
<p>
|
||||
Generate a referral code to share with your friends and start earning
|
||||
commission.
|
||||
{t(
|
||||
'Generate a referral code to share with your friends and start earning commission.'
|
||||
)}
|
||||
</p>
|
||||
)}
|
||||
{status === 'success' && code && (
|
||||
@@ -201,7 +208,7 @@ const CreateCodeDialog = ({
|
||||
className="text-sm no-underline"
|
||||
icon={<VegaIcon name={VegaIconNames.COPY} />}
|
||||
>
|
||||
<span>Copy</span>
|
||||
<span>{t('Copy')}</span>
|
||||
</TradingButton>
|
||||
</CopyWithTooltip>
|
||||
</div>
|
||||
@@ -214,10 +221,10 @@ const CreateCodeDialog = ({
|
||||
{err && <InputError>{err}</InputError>}
|
||||
<div className="flex justify-center pt-5 mt-2 text-sm border-t gap-4 text-default border-default">
|
||||
<ExternalLink href={ABOUT_REFERRAL_DOCS_LINK}>
|
||||
About the referral program
|
||||
{t('About the referral program')}
|
||||
</ExternalLink>
|
||||
<ExternalLink href={DISCLAIMER_REFERRAL_DOCS_LINK}>
|
||||
Disclaimer
|
||||
{t('Disclaimer')}
|
||||
</ExternalLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@ import { RainbowButton } from './buttons';
|
||||
import { AnimatedDudeWithWire } from './graphics/dude';
|
||||
import { LayoutWithSky } from './layout';
|
||||
import { Routes } from '../../lib/links';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
|
||||
export const ErrorBoundary = () => {
|
||||
const error = useRouteError();
|
||||
@@ -39,7 +40,7 @@ export const ErrorBoundary = () => {
|
||||
variant="border"
|
||||
className="text-xs"
|
||||
>
|
||||
Go back and try again
|
||||
{t('Go back and try again')}
|
||||
</RainbowButton>
|
||||
</p>
|
||||
</LayoutWithSky>
|
||||
@@ -60,7 +61,7 @@ export const NotFound = () => {
|
||||
<h1 className="text-6xl font-alpha calt mb-10">{'Not found'}</h1>
|
||||
|
||||
<p className="text-lg mb-10">
|
||||
{"The page you're looking for doesn't exists."}
|
||||
{t("The page you're looking for doesn't exists.")}
|
||||
</p>
|
||||
|
||||
<p className="text-lg mb-10">
|
||||
@@ -69,7 +70,7 @@ export const NotFound = () => {
|
||||
variant="border"
|
||||
className="text-xs"
|
||||
>
|
||||
Go back and try again
|
||||
{t('Go back and try again')}
|
||||
</RainbowButton>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { Table } from './table';
|
||||
|
||||
export const HowItWorksTable = () => (
|
||||
@@ -13,7 +14,9 @@ export const HowItWorksTable = () => (
|
||||
1
|
||||
</span>
|
||||
),
|
||||
step: 'Referrers generate a code assigned to their key via an on chain transaction',
|
||||
step: t(
|
||||
'Referrers generate a code assigned to their key via an on chain transaction'
|
||||
),
|
||||
},
|
||||
{
|
||||
number: (
|
||||
@@ -21,7 +24,9 @@ export const HowItWorksTable = () => (
|
||||
2
|
||||
</span>
|
||||
),
|
||||
step: 'Anyone with the referral link can apply it to their key(s) of choice via an on chain transaction',
|
||||
step: t(
|
||||
'Anyone with the referral link can apply it to their key(s) of choice via an on chain transaction'
|
||||
),
|
||||
},
|
||||
{
|
||||
number: (
|
||||
@@ -29,7 +34,9 @@ export const HowItWorksTable = () => (
|
||||
3
|
||||
</span>
|
||||
),
|
||||
step: 'Discounts are applied automatically during trading based on the key(s) used',
|
||||
step: t(
|
||||
'Discounts are applied automatically during trading based on the key(s) used'
|
||||
),
|
||||
},
|
||||
{
|
||||
number: (
|
||||
@@ -37,7 +44,9 @@ export const HowItWorksTable = () => (
|
||||
4
|
||||
</span>
|
||||
),
|
||||
step: 'Referrers earn commission based on a percentage of the taker fees their referees pay',
|
||||
step: t(
|
||||
'Referrers earn commission based on a percentage of the taker fees their referees pay'
|
||||
),
|
||||
},
|
||||
{
|
||||
number: (
|
||||
@@ -45,7 +54,9 @@ export const HowItWorksTable = () => (
|
||||
5
|
||||
</span>
|
||||
),
|
||||
step: 'The commission is taken from the infrastructure fee, maker fee, and liquidity provider fee, not from the referee',
|
||||
step: t(
|
||||
'The commission is taken from the infrastructure fee, maker fee, and liquidity provider fee, not from the referee'
|
||||
),
|
||||
},
|
||||
]}
|
||||
></Table>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import classNames from 'classnames';
|
||||
import { AnimatedDudeWithWire } from './graphics/dude';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
|
||||
export const LandingBanner = () => {
|
||||
return (
|
||||
@@ -13,16 +14,17 @@ export const LandingBanner = () => {
|
||||
</div>
|
||||
<div className="pt-32 sm:w-[50%]">
|
||||
<h1 className="text-6xl font-alpha calt mb-10">
|
||||
Earn commission & stake rewards
|
||||
{t('Earn commission & stake rewards')}
|
||||
</h1>
|
||||
<p className="text-lg mb-10">
|
||||
Invite friends and earn commission in the form of Vega rewards from
|
||||
the trading fees they pay. Stake those rewards to earn multipliers
|
||||
on future rewards.
|
||||
{t(
|
||||
'Invite friends and earn commission in the form of Vega rewards from the trading fees they pay. Stake those rewards to earn multipliers on future rewards.'
|
||||
)}
|
||||
</p>
|
||||
<p className="text-lg">
|
||||
Any friends that join using the code will receive discounts off
|
||||
trading fees.
|
||||
{t(
|
||||
'Any friends that join using the code will receive discounts off trading fees.'
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -26,6 +26,7 @@ import sortBy from 'lodash/sortBy';
|
||||
import { useLayoutEffect, useRef, useState } from 'react';
|
||||
import { useCurrentEpochInfoQuery } from './hooks/__generated__/Epoch';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
|
||||
export const ReferralStatistics = () => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
@@ -116,34 +117,34 @@ export const Statistics = ({
|
||||
: 0;
|
||||
|
||||
const baseCommissionTile = (
|
||||
<StatTile title="Base commission rate">
|
||||
<StatTile title={t('Base commission rate')}>
|
||||
{baseCommissionValue * 100}%
|
||||
</StatTile>
|
||||
);
|
||||
const stakingMultiplierTile = (
|
||||
<StatTile
|
||||
title="Staking multiplier"
|
||||
title={t('Staking multiplier')}
|
||||
description={`(${addDecimalsFormatNumber(
|
||||
stakeAvailable?.toString() || 0,
|
||||
18
|
||||
)} $VEGA staked)`}
|
||||
>
|
||||
{multiplier || 'None'}
|
||||
{multiplier || t('None')}
|
||||
</StatTile>
|
||||
);
|
||||
const finalCommissionTile = (
|
||||
<StatTile title="Final commission rate">
|
||||
<StatTile title={t('Final commission rate')}>
|
||||
{finalCommissionValue * 100}%
|
||||
</StatTile>
|
||||
);
|
||||
const numberOfTradersValue = data.referees.length;
|
||||
const numberOfTradersTile = (
|
||||
<StatTile title="Number of traders">{numberOfTradersValue}</StatTile>
|
||||
<StatTile title={t('Number of traders')}>{numberOfTradersValue}</StatTile>
|
||||
);
|
||||
|
||||
const codeTile = <CodeTile code={data?.code} />;
|
||||
const createdAtTile = (
|
||||
<StatTile title="Created at">
|
||||
<StatTile title={t('Created at')}>
|
||||
<span className="text-3xl">
|
||||
{getDateFormat().format(new Date(data.createdAt))}
|
||||
</span>
|
||||
@@ -154,7 +155,10 @@ export const Statistics = ({
|
||||
.map((r) => new BigNumber(r.totalRefereeGeneratedRewards))
|
||||
.reduce((all, r) => all.plus(r), new BigNumber(0));
|
||||
const totalCommissionTile = (
|
||||
<StatTile title="Total commission (last 30 days)" description="(Quantum)">
|
||||
<StatTile
|
||||
title={t('Total commission (last 30 days)')}
|
||||
description={t('(qUSD)')}
|
||||
>
|
||||
{getNumberFormat(0).format(Number(totalCommissionValue))}
|
||||
</StatTile>
|
||||
);
|
||||
@@ -184,29 +188,31 @@ export const Statistics = ({
|
||||
});
|
||||
|
||||
const currentBenefitTierTile = (
|
||||
<StatTile title="Current tier">
|
||||
<StatTile title={t('Current tier')}>
|
||||
{currentBenefitTierValue?.tier || '-'}
|
||||
</StatTile>
|
||||
);
|
||||
const discountFactorTile = (
|
||||
<StatTile title="Discount">{discountFactorValue * 100}%</StatTile>
|
||||
<StatTile title={t('Discount')}>{discountFactorValue * 100}%</StatTile>
|
||||
);
|
||||
const runningVolumeTile = (
|
||||
<StatTile title="Combined volume">
|
||||
<StatTile title={t('Combined volume')}>
|
||||
{compactNumFormat.format(runningVolumeValue)}
|
||||
</StatTile>
|
||||
);
|
||||
const epochsTile = <StatTile title="Epochs in set">{epochsValue}</StatTile>;
|
||||
const epochsTile = (
|
||||
<StatTile title={t('Epochs in set')}>{epochsValue}</StatTile>
|
||||
);
|
||||
const nextTierVolumeTile = (
|
||||
<StatTile title="Volume to next tier">
|
||||
<StatTile title={t('Volume to next tier')}>
|
||||
{nextBenefitTierVolumeValue <= 0
|
||||
? '-'
|
||||
? '0'
|
||||
: compactNumFormat.format(nextBenefitTierVolumeValue)}
|
||||
</StatTile>
|
||||
);
|
||||
const nextTierEpochsTile = (
|
||||
<StatTile title="Epochs to next tier">
|
||||
{nextBenefitTierEpochsValue <= 0 ? '-' : nextBenefitTierEpochsValue}
|
||||
<StatTile title={t('Epochs to next tier')}>
|
||||
{nextBenefitTierEpochsValue <= 0 ? '0' : nextBenefitTierEpochsValue}
|
||||
</StatTile>
|
||||
);
|
||||
|
||||
@@ -249,7 +255,7 @@ export const Statistics = ({
|
||||
{/* Referees (only for referrer view) */}
|
||||
{as === 'referrer' && data.referees.length > 0 && (
|
||||
<div className="mt-20 mb-20">
|
||||
<h2 className="text-2xl mb-5">Referees</h2>
|
||||
<h2 className="text-2xl mb-5">{t('Referees')}</h2>
|
||||
<div
|
||||
className={classNames(
|
||||
collapsed && [
|
||||
@@ -273,12 +279,12 @@ export const Statistics = ({
|
||||
<Table
|
||||
ref={tableRef}
|
||||
columns={[
|
||||
{ name: 'party', displayName: 'Trader' },
|
||||
{ name: 'joined', displayName: 'Date Joined' },
|
||||
{ name: 'volume', displayName: 'Volume (last 30 days)' },
|
||||
{ name: 'party', displayName: t('Trader') },
|
||||
{ name: 'joined', displayName: t('Date Joined') },
|
||||
{ name: 'volume', displayName: t('Volume (last 30 days)') },
|
||||
{
|
||||
name: 'commission',
|
||||
displayName: 'Commission earned (last 30 days)',
|
||||
displayName: t('Commission earned (last 30 days)'),
|
||||
},
|
||||
]}
|
||||
data={sortBy(
|
||||
|
||||
@@ -22,9 +22,9 @@ import { t } from '@vegaprotocol/i18n';
|
||||
const Nav = () => (
|
||||
<div className="flex justify-center border-b border-vega-cdark-500">
|
||||
<TabLink end to={Routes.REFERRALS}>
|
||||
I want a code
|
||||
{t('I want a code')}
|
||||
</TabLink>
|
||||
<TabLink to={Routes.REFERRALS_APPLY_CODE}>I have a code</TabLink>
|
||||
<TabLink to={Routes.REFERRALS_APPLY_CODE}>{t('I have a code')}</TabLink>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -77,7 +77,7 @@ export const Referrals = () => {
|
||||
</div>
|
||||
) : error ? (
|
||||
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-center">
|
||||
<p>Something went wrong</p>
|
||||
<p>{t('Something went wrong')}</p>
|
||||
<span className="text-xs">{error.message}</span>
|
||||
</div>
|
||||
) : (
|
||||
@@ -88,7 +88,7 @@ export const Referrals = () => {
|
||||
<TiersContainer />
|
||||
|
||||
<div className="mt-10 mb-5 text-center">
|
||||
<h2 className="text-2xl">How it works</h2>
|
||||
<h2 className="text-2xl">{t('How it works')}</h2>
|
||||
</div>
|
||||
<div className="md:w-[60%] mx-auto">
|
||||
<HowItWorksTable />
|
||||
@@ -98,7 +98,8 @@ export const Referrals = () => {
|
||||
href={REFERRAL_DOCS_LINK}
|
||||
target="_blank"
|
||||
>
|
||||
Read the terms <VegaIcon name={VegaIconNames.OPEN_EXTERNAL} />
|
||||
{t('Read the terms')}{' '}
|
||||
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} />
|
||||
</TradingAnchorButton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,6 +7,7 @@ import { Tag } from './tag';
|
||||
import type { ComponentProps, ReactNode } from 'react';
|
||||
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { DApp, TOKEN_PROPOSALS, useLinks } from '@vegaprotocol/environment';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
|
||||
const Loading = ({ variant }: { variant: 'large' | 'inline' }) => (
|
||||
<div
|
||||
@@ -61,7 +62,7 @@ const StakingTier = ({
|
||||
<Tag color={color[tier]}>Multiplier {referralRewardMultiplier}x</Tag>
|
||||
<h3 className="mt-1 mb-1 text-base">{label}</h3>
|
||||
<p className="text-sm text-vega-clight-100 dark:text-vega-cdark-100">
|
||||
Stake a minimum of {minimumStakedTokens} $VEGA tokens
|
||||
{t('Stake a minimum of')} {minimumStakedTokens} {t('$VEGA tokens')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -81,9 +82,12 @@ export const TiersContainer = () => {
|
||||
if ((!loading && !details) || error) {
|
||||
return (
|
||||
<div className="text-base px-5 py-10 text-center">
|
||||
We're sorry but we don't have an active referral programme
|
||||
currently running. You can propose a new programme{' '}
|
||||
<ExternalLink href={governanceLink(TOKEN_PROPOSALS)}>here</ExternalLink>
|
||||
{t(
|
||||
"We're sorry but we don't have an active referral programme currently running. You can propose a new programme"
|
||||
)}{' '}
|
||||
<ExternalLink href={governanceLink(TOKEN_PROPOSALS)}>
|
||||
{t('here')}
|
||||
</ExternalLink>
|
||||
.
|
||||
</div>
|
||||
);
|
||||
@@ -93,10 +97,10 @@ export const TiersContainer = () => {
|
||||
<>
|
||||
{/* Benefit tiers */}
|
||||
<div className="flex flex-col items-baseline justify-between mt-10 mb-5">
|
||||
<h2 className="text-2xl">Referral tiers</h2>
|
||||
<h2 className="text-2xl">{t('Referral tiers')}</h2>
|
||||
{ends && (
|
||||
<span className="text-sm text-vega-clight-200 dark:text-vega-cdark-200">
|
||||
Program ends: {ends}
|
||||
{t('Program ends:')} {ends}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@@ -119,7 +123,7 @@ export const TiersContainer = () => {
|
||||
|
||||
{/* Staking tiers */}
|
||||
<div className="flex flex-row items-baseline justify-between mb-5">
|
||||
<h2 className="text-2xl">Staking multipliers</h2>
|
||||
<h2 className="text-2xl">{t('Staking multipliers')}</h2>
|
||||
</div>
|
||||
<div className="mb-20 flex flex-col justify-items-stretch lg:flex-row gap-5">
|
||||
{loading || !stakingTiers || stakingTiers.length === 0 ? (
|
||||
@@ -170,15 +174,15 @@ const TiersTable = ({
|
||||
return (
|
||||
<Table
|
||||
columns={[
|
||||
{ name: 'tierElement', displayName: 'Tier' },
|
||||
{ name: 'tierElement', displayName: t('Tier') },
|
||||
{
|
||||
name: 'commission',
|
||||
displayName: 'Referrer commission',
|
||||
tooltip: 'A percentage of commission earned by the referrer',
|
||||
displayName: t('Referrer commission'),
|
||||
tooltip: t('A percentage of commission earned by the referrer'),
|
||||
},
|
||||
{ name: 'discount', displayName: 'Referrer trading discount' },
|
||||
{ name: 'volume', displayName: 'Min. trading volume' },
|
||||
{ name: 'epochs', displayName: 'Min. epochs' },
|
||||
{ name: 'discount', displayName: t('Referrer trading discount') },
|
||||
{ name: 'volume', displayName: t('Min. trading volume') },
|
||||
{ name: 'epochs', displayName: t('Min. epochs') },
|
||||
]}
|
||||
data={data.map((d) => ({
|
||||
...d,
|
||||
|
||||
Reference in New Issue
Block a user