Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d353f24f01 | ||
|
|
5755347a31 | ||
|
|
ade1dff30d | ||
|
|
5ca65260c9 | ||
|
|
c276106cfc | ||
|
|
a1ec426a6e | ||
|
|
e20202f895 |
+2
-1
@@ -1,2 +1,3 @@
|
||||
* @vegaprotocol/frontend @vegaprotocol/frontend-qa
|
||||
* @vegaprotocol/frontend
|
||||
* @vegaprotocol/frontend-qa
|
||||
*.graphql @vegaprotocol/core
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {
|
||||
AppFailure,
|
||||
NetworkLoader,
|
||||
NodeFailure,
|
||||
NodeGuard,
|
||||
NodeSwitcherDialog,
|
||||
useEnvironment,
|
||||
@@ -31,7 +31,7 @@ function App() {
|
||||
<NetworkLoader cache={DEFAULT_CACHE_CONFIG}>
|
||||
<NodeGuard
|
||||
skeleton={<div>{t('Loading')}</div>}
|
||||
failure={<NodeFailure title={t(`Node: ${VEGA_URL} is unsuitable`)} />}
|
||||
failure={<AppFailure title={t(`Node: ${VEGA_URL} is unsuitable`)} />}
|
||||
>
|
||||
<Suspense fallback={splashLoading}>
|
||||
<RouterProvider router={router} fallbackElement={splashLoading} />
|
||||
|
||||
@@ -38,10 +38,10 @@ import {
|
||||
NetworkLoader,
|
||||
useInitializeEnv,
|
||||
NodeGuard,
|
||||
AppFailure,
|
||||
NodeSwitcherDialog,
|
||||
useNodeSwitcherStore,
|
||||
DocsLinks,
|
||||
NodeFailure,
|
||||
} from '@vegaprotocol/environment';
|
||||
import { ENV } from './config';
|
||||
import type { InMemoryCacheConfig } from '@apollo/client';
|
||||
@@ -184,7 +184,7 @@ const Web3Container = ({
|
||||
<TemplateSidebar sidebar={sideBar}>
|
||||
<AppRouter />
|
||||
</TemplateSidebar>
|
||||
<footer className="p-4 break-all border-t border-neutral-700">
|
||||
<footer className="p-4 border-t border-neutral-700 break-all">
|
||||
<NetworkInfo />
|
||||
</footer>
|
||||
</AppLayout>
|
||||
@@ -312,7 +312,7 @@ const AppContainer = () => {
|
||||
<NodeGuard
|
||||
skeleton={<div>{t('Loading')}</div>}
|
||||
failure={
|
||||
<NodeFailure title={t('NodeUnsuitable', { url: VEGA_URL })} />
|
||||
<AppFailure title={t('NodeUnsuitable', { url: VEGA_URL })} />
|
||||
}
|
||||
>
|
||||
<AsyncRenderer<EthereumConfig | null>
|
||||
|
||||
@@ -718,8 +718,6 @@
|
||||
"UpdateAssetProposal": "Update asset proposal",
|
||||
"NewFreeformProposal": "New freeform proposal",
|
||||
"NewRawProposal": "New proposal",
|
||||
"NewTransferProposal": "New transfer proposal",
|
||||
"CancelTransferProposal": "Cancel transfer proposal",
|
||||
"MARKET_STATE_UPDATE_TYPE_RESUME": "Resume market",
|
||||
"MARKET_STATE_UPDATE_TYPE_SUSPEND": "Suspend market",
|
||||
"MARKET_STATE_UPDATE_TYPE_TERMINATE": "Terminate market",
|
||||
@@ -740,8 +738,6 @@
|
||||
"UpdateVolumeDiscountProgram": "Update volume discount program",
|
||||
"NewAsset": "New asset",
|
||||
"UpdateAsset": "Update asset",
|
||||
"NewTransfer": "New transfer",
|
||||
"CancelTransfer": "Cancel transfer",
|
||||
"AssetID": "Asset ID",
|
||||
"Freeform": "Freeform",
|
||||
"RawProposal": "Let me choose (raw proposal)",
|
||||
@@ -918,31 +914,5 @@
|
||||
"EndOfProgramTimestamp": "End of program",
|
||||
"EndOfProgramTimestampDescription": "Time after which when the current epoch ends, the programs will end and benefits will be disabled.",
|
||||
"BenefitTierVolumeDiscountFactor": "Volume discount factor",
|
||||
"BenefitTierVolumeDiscountFactorDescription": "Discount given to those in this benefit tier",
|
||||
"ACCOUNT_TYPE_INSURANCE": "Insurance account",
|
||||
"ACCOUNT_TYPE_GLOBAL_INSURANCE": "Global insurance account",
|
||||
"ACCOUNT_TYPE_SETTLEMENT": "Settlement account",
|
||||
"ACCOUNT_TYPE_MARGIN": "Margin account ",
|
||||
"ACCOUNT_TYPE_GENERAL": "General account",
|
||||
"ACCOUNT_TYPE_FEES_INFRASTRUCTURE": "Infrastructure fees account",
|
||||
"ACCOUNT_TYPE_FEES_LIQUIDITY": "Liquidity fees account",
|
||||
"ACCOUNT_TYPE_FEES_MAKER": "Maker fees account",
|
||||
"ACCOUNT_TYPE_BOND": "Bond account",
|
||||
"ACCOUNT_TYPE_EXTERNAL": "External account",
|
||||
"ACCOUNT_TYPE_GLOBAL_REWARD": "Global reward account",
|
||||
"ACCOUNT_TYPE_PENDING_TRANSFERS": "Pending transfers account",
|
||||
"ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES": "Maker paid fees reward account",
|
||||
"ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES": "Maker received fees reward account",
|
||||
"ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES": "Liquidity provider received fees reward account",
|
||||
"ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS": "Market proposers reward account",
|
||||
"ACCOUNT_TYPE_HOLDING": "Holding account",
|
||||
"ACCOUNT_TYPE_LP_LIQUIDITY_FEES": "Liquidity provider fees account",
|
||||
"ACCOUNT_TYPE_NETWORK_TREASURY": "Network treasury account",
|
||||
"ACCOUNT_TYPE_VESTING_REWARDS": "Vesting rewards account",
|
||||
"ACCOUNT_TYPE_VESTED_REWARDS": "Vested rewards account",
|
||||
"ACCOUNT_TYPE_REWARD_AVERAGE_POSITION": "Average position reward account",
|
||||
"ACCOUNT_TYPE_REWARD_RELATIVE_RETURN": "Relative return reward account",
|
||||
"ACCOUNT_TYPE_REWARD_RETURN_VOLATILITY": "Return volatility reward account",
|
||||
"ACCOUNT_TYPE_REWARD_VALIDATOR_RANKING": "Validator ranking reward account",
|
||||
"ACCOUNT_TYPE_PENDING_FEE_REFERRAL_REWARD": "Pending fee referral reward account"
|
||||
"BenefitTierVolumeDiscountFactorDescription": "Discount given to those in this benefit tier"
|
||||
}
|
||||
|
||||
+1
-4
@@ -263,10 +263,7 @@ const NewTransferSummary = ({ proposalId }: { proposalId?: string | null }) => {
|
||||
return (
|
||||
<span>
|
||||
{GovernanceTransferKindMapping[details.kind.__typename]}{' '}
|
||||
{t('transfer from')}{' '}
|
||||
<Lozenge>
|
||||
{truncateMiddle(details.source) || t(details.sourceType)}
|
||||
</Lozenge>{' '}
|
||||
{t('transfer from')} <Lozenge>{truncateMiddle(details.source)}</Lozenge>{' '}
|
||||
{t('to')} <Lozenge>{truncateMiddle(details.destination)}</Lozenge>
|
||||
</span>
|
||||
);
|
||||
|
||||
+39
-36
@@ -63,42 +63,44 @@ const mockReferralProposal = generateProposal({
|
||||
terms: {
|
||||
change: {
|
||||
__typename: 'UpdateReferralProgram',
|
||||
benefitTiers: [
|
||||
{
|
||||
minimumEpochs: 6,
|
||||
minimumRunningNotionalTakerVolume: '10000',
|
||||
referralDiscountFactor: '0.001',
|
||||
referralRewardFactor: '0.001',
|
||||
},
|
||||
{
|
||||
minimumEpochs: 24,
|
||||
minimumRunningNotionalTakerVolume: '500000',
|
||||
referralDiscountFactor: '0.005',
|
||||
referralRewardFactor: '0.005',
|
||||
},
|
||||
{
|
||||
minimumEpochs: 48,
|
||||
minimumRunningNotionalTakerVolume: '1000000',
|
||||
referralDiscountFactor: '0.01',
|
||||
referralRewardFactor: '0.01',
|
||||
},
|
||||
],
|
||||
endOfProgram: '2026-10-03T10:34:34Z',
|
||||
windowLength: 3,
|
||||
stakingTiers: [
|
||||
{
|
||||
minimumStakedTokens: '1',
|
||||
referralRewardMultiplier: '1',
|
||||
},
|
||||
{
|
||||
minimumStakedTokens: '2',
|
||||
referralRewardMultiplier: '2',
|
||||
},
|
||||
{
|
||||
minimumStakedTokens: '5',
|
||||
referralRewardMultiplier: '3',
|
||||
},
|
||||
],
|
||||
changes: {
|
||||
benefitTiers: [
|
||||
{
|
||||
minimumEpochs: 6,
|
||||
minimumRunningNotionalTakerVolume: '10000',
|
||||
referralDiscountFactor: '0.001',
|
||||
referralRewardFactor: '0.001',
|
||||
},
|
||||
{
|
||||
minimumEpochs: 24,
|
||||
minimumRunningNotionalTakerVolume: '500000',
|
||||
referralDiscountFactor: '0.005',
|
||||
referralRewardFactor: '0.005',
|
||||
},
|
||||
{
|
||||
minimumEpochs: 48,
|
||||
minimumRunningNotionalTakerVolume: '1000000',
|
||||
referralDiscountFactor: '0.01',
|
||||
referralRewardFactor: '0.01',
|
||||
},
|
||||
],
|
||||
endOfProgramTimestamp: '2026-10-03T10:34:34Z',
|
||||
windowLength: 3,
|
||||
stakingTiers: [
|
||||
{
|
||||
minimumStakedTokens: '1',
|
||||
referralRewardMultiplier: '1',
|
||||
},
|
||||
{
|
||||
minimumStakedTokens: '2',
|
||||
referralRewardMultiplier: '2',
|
||||
},
|
||||
{
|
||||
minimumStakedTokens: '5',
|
||||
referralRewardMultiplier: '3',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -130,6 +132,7 @@ describe('<ProposalReferralProgramDetails />', () => {
|
||||
terms: {
|
||||
change: {
|
||||
__typename: 'UpdateReferralProgram',
|
||||
changes: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
+5
-4
@@ -54,10 +54,11 @@ export const ProposalReferralProgramDetails = ({
|
||||
return null;
|
||||
}
|
||||
|
||||
const benefitTiers = proposal?.terms?.change?.benefitTiers;
|
||||
const stakingTiers = proposal?.terms?.change?.stakingTiers;
|
||||
const windowLength = proposal?.terms?.change?.windowLength;
|
||||
const endOfProgramTimestamp = proposal?.terms?.change?.endOfProgram;
|
||||
const benefitTiers = proposal?.terms?.change?.changes?.benefitTiers;
|
||||
const stakingTiers = proposal?.terms?.change?.changes?.stakingTiers;
|
||||
const windowLength = proposal?.terms?.change?.changes?.windowLength;
|
||||
const endOfProgramTimestamp =
|
||||
proposal?.terms?.change?.changes?.endOfProgramTimestamp;
|
||||
|
||||
if (
|
||||
!benefitTiers &&
|
||||
|
||||
@@ -30,8 +30,6 @@ export const useProposalNetworkParams = ({
|
||||
NetworkParams.governance_proposal_freeform_requiredParticipation,
|
||||
NetworkParams.governance_proposal_VolumeDiscountProgram_requiredMajority,
|
||||
NetworkParams.governance_proposal_VolumeDiscountProgram_requiredParticipation,
|
||||
NetworkParams.governance_proposal_transfer_requiredParticipation,
|
||||
NetworkParams.governance_proposal_transfer_requiredMajority,
|
||||
]);
|
||||
|
||||
const fallback = {
|
||||
@@ -113,14 +111,6 @@ export const useProposalNetworkParams = ({
|
||||
params.governance_proposal_VolumeDiscountProgram_requiredParticipation
|
||||
),
|
||||
};
|
||||
case 'NewTransfer':
|
||||
case 'CancelTransfer':
|
||||
return {
|
||||
requiredMajority: params.governance_proposal_transfer_requiredMajority,
|
||||
requiredParticipation: new BigNumber(
|
||||
params.governance_proposal_transfer_requiredParticipation
|
||||
),
|
||||
};
|
||||
default:
|
||||
return fallback;
|
||||
}
|
||||
|
||||
@@ -47,17 +47,19 @@ fragment UpdateReferralProgram on Proposal {
|
||||
terms {
|
||||
change {
|
||||
... on UpdateReferralProgram {
|
||||
benefitTiers {
|
||||
minimumEpochs
|
||||
minimumRunningNotionalTakerVolume
|
||||
referralDiscountFactor
|
||||
referralRewardFactor
|
||||
}
|
||||
endOfProgram: endOfProgramTimestamp
|
||||
windowLength
|
||||
stakingTiers {
|
||||
minimumStakedTokens
|
||||
referralRewardMultiplier
|
||||
changes {
|
||||
benefitTiers {
|
||||
minimumEpochs
|
||||
minimumRunningNotionalTakerVolume
|
||||
referralDiscountFactor
|
||||
referralRewardFactor
|
||||
}
|
||||
endOfProgramTimestamp
|
||||
windowLength
|
||||
stakingTiers {
|
||||
minimumStakedTokens
|
||||
referralRewardMultiplier
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -47,17 +47,19 @@ fragment UpdateReferralPrograms on Proposal {
|
||||
terms {
|
||||
change {
|
||||
... on UpdateReferralProgram {
|
||||
benefitTiers {
|
||||
minimumEpochs
|
||||
minimumRunningNotionalTakerVolume
|
||||
referralDiscountFactor
|
||||
referralRewardFactor
|
||||
}
|
||||
endOfProgram: endOfProgramTimestamp
|
||||
windowLength
|
||||
stakingTiers {
|
||||
minimumStakedTokens
|
||||
referralRewardMultiplier
|
||||
changes {
|
||||
benefitTiers {
|
||||
minimumEpochs
|
||||
minimumRunningNotionalTakerVolume
|
||||
referralDiscountFactor
|
||||
referralRewardFactor
|
||||
}
|
||||
endOfProgramTimestamp
|
||||
windowLength
|
||||
stakingTiers {
|
||||
minimumStakedTokens
|
||||
referralRewardMultiplier
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+15
-13
@@ -7,7 +7,7 @@ export type NewMarketProductFieldsFragment = { __typename?: 'Proposal', terms: {
|
||||
|
||||
export type UpdateMarketStatesFragment = { __typename?: 'Proposal', terms: { __typename?: 'ProposalTerms', change: { __typename?: 'CancelTransfer' } | { __typename?: 'NewAsset' } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket' } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket' } | { __typename?: 'UpdateMarketState', updateType: Types.MarketUpdateType, price?: string | null, market: { __typename?: 'Market', decimalPlaces: number, id: string, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, code: string, product: { __typename: 'Future', quoteName: string } | { __typename: 'Perpetual', quoteName: string } | { __typename: 'Spot' } } } } } | { __typename?: 'UpdateNetworkParameter' } | { __typename?: 'UpdateReferralProgram' } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram' } } };
|
||||
|
||||
export type UpdateReferralProgramsFragment = { __typename?: 'Proposal', terms: { __typename?: 'ProposalTerms', change: { __typename?: 'CancelTransfer' } | { __typename?: 'NewAsset' } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket' } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket' } | { __typename?: 'UpdateMarketState' } | { __typename?: 'UpdateNetworkParameter' } | { __typename?: 'UpdateReferralProgram', windowLength: number, endOfProgram: string, benefitTiers: Array<{ __typename?: 'BenefitTier', minimumEpochs: number, minimumRunningNotionalTakerVolume: string, referralDiscountFactor: string, referralRewardFactor: string }>, stakingTiers: Array<{ __typename?: 'StakingTier', minimumStakedTokens: string, referralRewardMultiplier: string }> } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram' } } };
|
||||
export type UpdateReferralProgramsFragment = { __typename?: 'Proposal', terms: { __typename?: 'ProposalTerms', change: { __typename?: 'CancelTransfer' } | { __typename?: 'NewAsset' } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket' } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket' } | { __typename?: 'UpdateMarketState' } | { __typename?: 'UpdateNetworkParameter' } | { __typename?: 'UpdateReferralProgram', changes: { __typename?: 'ReferralProgram', endOfProgramTimestamp: string, windowLength: number, benefitTiers: Array<{ __typename?: 'BenefitTier', minimumEpochs: number, minimumRunningNotionalTakerVolume: string, referralDiscountFactor: string, referralRewardFactor: string }>, stakingTiers: Array<{ __typename?: 'StakingTier', minimumStakedTokens: string, referralRewardMultiplier: string }> } } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram' } } };
|
||||
|
||||
export type UpdateVolumeDiscountProgramsFragment = { __typename?: 'Proposal', terms: { __typename?: 'ProposalTerms', change: { __typename?: 'CancelTransfer' } | { __typename?: 'NewAsset' } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket' } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket' } | { __typename?: 'UpdateMarketState' } | { __typename?: 'UpdateNetworkParameter' } | { __typename?: 'UpdateReferralProgram' } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram', endOfProgramTimestamp: any, windowLength: number, benefitTiers: Array<{ __typename?: 'VolumeBenefitTier', minimumRunningNotionalTakerVolume: string, volumeDiscountFactor: string }> } } };
|
||||
|
||||
@@ -21,7 +21,7 @@ export type ProposalsQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type ProposalsQuery = { __typename?: 'Query', proposalsConnection?: { __typename?: 'ProposalsConnection', edges?: Array<{ __typename?: 'ProposalEdge', node: { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: any, rejectionReason?: Types.ProposalRejectionReason | null, errorDetails?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string }, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: any, enactmentDatetime?: any | null, change: { __typename?: 'CancelTransfer' } | { __typename: 'NewAsset', name: string, symbol: string, decimals: number, quantum: string, source: { __typename?: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename?: 'ERC20', contractAddress: string, withdrawThreshold: string, lifetimeLimit: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', instrument: { __typename?: 'InstrumentConfiguration', name: string, code: string, futureProduct?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | null, product?: { __typename: 'FutureProduct' } | { __typename: 'PerpetualProduct' } | { __typename: 'SpotProduct' } | null } } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset', quantum: string, assetId: string, source: { __typename?: 'UpdateERC20', lifetimeLimit: string, withdrawThreshold: string } } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateMarketState', updateType: Types.MarketUpdateType, price?: string | null, market: { __typename?: 'Market', decimalPlaces: number, id: string, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, code: string, product: { __typename: 'Future', quoteName: string } | { __typename: 'Perpetual', quoteName: string } | { __typename: 'Spot' } } } } } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } | { __typename?: 'UpdateReferralProgram', windowLength: number, endOfProgram: string, benefitTiers: Array<{ __typename?: 'BenefitTier', minimumEpochs: number, minimumRunningNotionalTakerVolume: string, referralDiscountFactor: string, referralRewardFactor: string }>, stakingTiers: Array<{ __typename?: 'StakingTier', minimumStakedTokens: string, referralRewardMultiplier: string }> } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram', endOfProgramTimestamp: any, windowLength: number, benefitTiers: Array<{ __typename?: 'VolumeBenefitTier', minimumRunningNotionalTakerVolume: string, volumeDiscountFactor: string }> } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string } } } } | null> | null } | null };
|
||||
export type ProposalsQuery = { __typename?: 'Query', proposalsConnection?: { __typename?: 'ProposalsConnection', edges?: Array<{ __typename?: 'ProposalEdge', node: { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: any, rejectionReason?: Types.ProposalRejectionReason | null, errorDetails?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string }, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: any, enactmentDatetime?: any | null, change: { __typename?: 'CancelTransfer' } | { __typename: 'NewAsset', name: string, symbol: string, decimals: number, quantum: string, source: { __typename?: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename?: 'ERC20', contractAddress: string, withdrawThreshold: string, lifetimeLimit: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', instrument: { __typename?: 'InstrumentConfiguration', name: string, code: string, futureProduct?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | null, product?: { __typename: 'FutureProduct' } | { __typename: 'PerpetualProduct' } | { __typename: 'SpotProduct' } | null } } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset', quantum: string, assetId: string, source: { __typename?: 'UpdateERC20', lifetimeLimit: string, withdrawThreshold: string } } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateMarketState', updateType: Types.MarketUpdateType, price?: string | null, market: { __typename?: 'Market', decimalPlaces: number, id: string, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, code: string, product: { __typename: 'Future', quoteName: string } | { __typename: 'Perpetual', quoteName: string } | { __typename: 'Spot' } } } } } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } | { __typename?: 'UpdateReferralProgram', changes: { __typename?: 'ReferralProgram', endOfProgramTimestamp: string, windowLength: number, benefitTiers: Array<{ __typename?: 'BenefitTier', minimumEpochs: number, minimumRunningNotionalTakerVolume: string, referralDiscountFactor: string, referralRewardFactor: string }>, stakingTiers: Array<{ __typename?: 'StakingTier', minimumStakedTokens: string, referralRewardMultiplier: string }> } } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram', endOfProgramTimestamp: any, windowLength: number, benefitTiers: Array<{ __typename?: 'VolumeBenefitTier', minimumRunningNotionalTakerVolume: string, volumeDiscountFactor: string }> } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string } } } } | null> | null } | null };
|
||||
|
||||
export const NewMarketProductFieldsFragmentDoc = gql`
|
||||
fragment NewMarketProductFields on Proposal {
|
||||
@@ -75,17 +75,19 @@ export const UpdateReferralProgramsFragmentDoc = gql`
|
||||
terms {
|
||||
change {
|
||||
... on UpdateReferralProgram {
|
||||
benefitTiers {
|
||||
minimumEpochs
|
||||
minimumRunningNotionalTakerVolume
|
||||
referralDiscountFactor
|
||||
referralRewardFactor
|
||||
}
|
||||
endOfProgram: endOfProgramTimestamp
|
||||
windowLength
|
||||
stakingTiers {
|
||||
minimumStakedTokens
|
||||
referralRewardMultiplier
|
||||
changes {
|
||||
benefitTiers {
|
||||
minimumEpochs
|
||||
minimumRunningNotionalTakerVolume
|
||||
referralDiscountFactor
|
||||
referralRewardFactor
|
||||
}
|
||||
endOfProgramTimestamp
|
||||
windowLength
|
||||
stakingTiers {
|
||||
minimumStakedTokens
|
||||
referralRewardMultiplier
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
import { removeDecimal } from '@vegaprotocol/cypress';
|
||||
import { ethers } from 'ethers';
|
||||
import { connectEthereumWallet } from '../support/ethereum-wallet';
|
||||
import { selectAsset } from '../support/helpers';
|
||||
|
||||
const assetSelectField = 'select[name="asset"]';
|
||||
const toAddressField = 'input[name="to"]';
|
||||
const amountField = 'input[name="amount"]';
|
||||
const formFieldError = 'input-error-text';
|
||||
|
||||
const ASSET_EURO = 1;
|
||||
|
||||
describe('deposit form validation', { tags: '@smoke' }, () => {
|
||||
function openDepositForm() {
|
||||
cy.mockWeb3Provider();
|
||||
cy.mockSubscription();
|
||||
cy.mockTradingPage();
|
||||
cy.setVegaWallet();
|
||||
cy.visit('/#/portfolio');
|
||||
cy.get('[data-testid="pathname-/portfolio"]').should('exist');
|
||||
cy.getByTestId('Deposits').click();
|
||||
cy.getByTestId('deposit-button').click();
|
||||
connectEthereumWallet('MetaMask');
|
||||
cy.wait('@Assets');
|
||||
}
|
||||
|
||||
before(() => {
|
||||
openDepositForm();
|
||||
});
|
||||
|
||||
it('handles empty fields', () => {
|
||||
cy.getByTestId('deposit-submit').click();
|
||||
cy.getByTestId(formFieldError).should('contain.text', 'Required');
|
||||
// once Ethereum wallet is connected and key selected the only field that will
|
||||
// error is the asset select
|
||||
cy.getByTestId(formFieldError).should('have.length', 1);
|
||||
cy.get('[data-testid="input-error-text"][aria-describedby="asset"]').should(
|
||||
'have.length',
|
||||
1
|
||||
);
|
||||
});
|
||||
|
||||
it('unable to select assets not enabled', () => {
|
||||
// Assets not enabled in mocks
|
||||
cy.get(assetSelectField + ' option:contains(Asset 2)').should('not.exist');
|
||||
cy.get(assetSelectField + ' option:contains(Asset 3)').should('not.exist');
|
||||
cy.get(assetSelectField + ' option:contains(Asset 4)').should('not.exist');
|
||||
});
|
||||
|
||||
it('invalid public key when entering address manually', () => {
|
||||
cy.getByTestId('enter-pubkey-manually').click();
|
||||
cy.get(toAddressField).clear().type('INVALID_DEPOSIT_TO_ADDRESS');
|
||||
cy.get(`[data-testid="${formFieldError}"][aria-describedby="to"]`).should(
|
||||
'have.text',
|
||||
'Invalid Vega key'
|
||||
);
|
||||
});
|
||||
|
||||
it('invalid amount', () => {
|
||||
mockWeb3DepositCalls({
|
||||
allowance: '1000',
|
||||
depositLifetimeLimit: '1000',
|
||||
balance: '800',
|
||||
deposited: '0',
|
||||
dps: 5,
|
||||
});
|
||||
// Deposit amount smaller than minimum viable for selected asset
|
||||
// Select an amount so that we have a known decimal places value to work with
|
||||
selectAsset(ASSET_EURO);
|
||||
|
||||
cy.get(amountField)
|
||||
.clear()
|
||||
.type('0.00000000000000000000000000000000001')
|
||||
.next(`[data-testid="${formFieldError}"]`)
|
||||
.should('have.text', 'Value is below minimum');
|
||||
});
|
||||
|
||||
it('insufficient funds', () => {
|
||||
// 1001-DEPO-004
|
||||
mockWeb3DepositCalls({
|
||||
allowance: '1000',
|
||||
depositLifetimeLimit: '1000',
|
||||
balance: '800',
|
||||
deposited: '0',
|
||||
dps: 5,
|
||||
});
|
||||
cy.get(amountField)
|
||||
.clear()
|
||||
.type('850')
|
||||
.next(`[data-testid="${formFieldError}"]`)
|
||||
.should(
|
||||
'have.text',
|
||||
"You can't deposit more than you have in your Ethereum wallet, 800 tEURO"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('deposit actions', { tags: '@smoke' }, () => {
|
||||
before(() => {
|
||||
cy.mockWeb3Provider();
|
||||
cy.mockTradingPage();
|
||||
cy.mockSubscription();
|
||||
cy.setVegaWallet();
|
||||
cy.visit('/#/markets/market-1');
|
||||
});
|
||||
|
||||
it.skip('Deposit to trade is visible', () => {
|
||||
cy.getByTestId('Collateral').click();
|
||||
cy.get('[row-id="asset-id"]').contains('tEURO').should('be.visible');
|
||||
cy.contains('[data-testid="deposit"]', 'Deposit').should('be.visible');
|
||||
cy.contains('[data-testid="deposit"]', 'Deposit').click();
|
||||
cy.getByTestId('deposit-submit').should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
function mockWeb3DepositCalls({
|
||||
allowance,
|
||||
depositLifetimeLimit,
|
||||
balance,
|
||||
deposited,
|
||||
dps,
|
||||
}: {
|
||||
allowance: string;
|
||||
depositLifetimeLimit: string;
|
||||
balance: string;
|
||||
deposited: string;
|
||||
dps: number;
|
||||
}) {
|
||||
const assetContractAddress = '0x0158031158bb4df2ad02eaa31e8963e84ea978a4';
|
||||
const collateralBridgeAddress = '0x7fe27d970bc8afc3b11cc8d9737bfb66b1efd799';
|
||||
const toResult = (value: string, dps: number) => {
|
||||
const rawValue = removeDecimal(value, dps);
|
||||
return ethers.utils.hexZeroPad(
|
||||
ethers.utils.hexlify(parseInt(rawValue)),
|
||||
32
|
||||
);
|
||||
};
|
||||
cy.intercept('POST', 'http://localhost:8545', (req) => {
|
||||
// Mock chainId call
|
||||
if (req.body.method === 'eth_chainId') {
|
||||
req.alias = 'eth_chainId';
|
||||
req.reply({
|
||||
id: req.body.id,
|
||||
jsonrpc: req.body.jsonrpc,
|
||||
result: '0xaa36a7', // 11155111 for sepolia chain id
|
||||
});
|
||||
}
|
||||
|
||||
// Mock deposited amount
|
||||
if (req.body.method === 'eth_getStorageAt') {
|
||||
req.alias = 'eth_getStorageAt';
|
||||
req.reply({
|
||||
id: req.body.id,
|
||||
jsonrpc: req.body.jsonrpc,
|
||||
result: toResult(deposited, dps),
|
||||
});
|
||||
}
|
||||
|
||||
if (req.body.method === 'eth_call') {
|
||||
// Mock approved amount for asset on collateral bridge
|
||||
if (
|
||||
req.body.params[0].to === assetContractAddress &&
|
||||
req.body.params[0].data ===
|
||||
'0xdd62ed3e000000000000000000000000ee7d375bcb50c26d52e1a4a472d8822a2a22d94f0000000000000000000000007fe27d970bc8afc3b11cc8d9737bfb66b1efd799'
|
||||
) {
|
||||
req.alias = 'eth_call_allowance';
|
||||
req.reply({
|
||||
id: req.body.id,
|
||||
jsonrpc: req.body.jsonrpc,
|
||||
result: toResult(allowance, dps),
|
||||
});
|
||||
}
|
||||
// Mock balance of asset in Ethereum wallet
|
||||
else if (
|
||||
req.body.params[0].to === assetContractAddress &&
|
||||
req.body.params[0].data ===
|
||||
'0x70a08231000000000000000000000000ee7d375bcb50c26d52e1a4a472d8822a2a22d94f'
|
||||
) {
|
||||
req.alias = 'eth_call_balanceOf';
|
||||
req.reply({
|
||||
id: req.body.id,
|
||||
jsonrpc: req.body.jsonrpc,
|
||||
result: toResult(balance, dps),
|
||||
});
|
||||
}
|
||||
// Mock deposit lifetime limit
|
||||
else if (
|
||||
req.body.params[0].to === collateralBridgeAddress &&
|
||||
req.body.params[0].data ===
|
||||
'0x354a897a0000000000000000000000000158031158bb4df2ad02eaa31e8963e84ea978a4'
|
||||
) {
|
||||
req.alias = 'eth_call_get_deposit_maximum'; // deposit lifetime limit
|
||||
req.reply({
|
||||
id: req.body.id,
|
||||
jsonrpc: req.body.jsonrpc,
|
||||
result: toResult(depositLifetimeLimit, dps),
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import MarketPage from '../market';
|
||||
|
||||
export const ClosedMarketPage = () => {
|
||||
return <MarketPage closed />;
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export { ClosedMarketPage as default } from './closed-market';
|
||||
@@ -1,48 +0,0 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { VegaIconNames } from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
SidebarButton,
|
||||
SidebarDivider,
|
||||
ViewType,
|
||||
} from '../../components/sidebar';
|
||||
import { useGetCurrentRouteId } from '../../lib/hooks/use-get-current-route-id';
|
||||
|
||||
export const LiquiditySidebar = () => {
|
||||
const currentRouteId = useGetCurrentRouteId();
|
||||
|
||||
return (
|
||||
<>
|
||||
<SidebarButton
|
||||
view={ViewType.Deposit}
|
||||
icon={VegaIconNames.DEPOSIT}
|
||||
tooltip={t('Deposit')}
|
||||
routeId={currentRouteId}
|
||||
/>
|
||||
<SidebarButton
|
||||
view={ViewType.Withdraw}
|
||||
icon={VegaIconNames.WITHDRAW}
|
||||
tooltip={t('Withdraw')}
|
||||
routeId={currentRouteId}
|
||||
/>
|
||||
<SidebarButton
|
||||
view={ViewType.Transfer}
|
||||
icon={VegaIconNames.TRANSFER}
|
||||
tooltip={t('Transfer')}
|
||||
routeId={currentRouteId}
|
||||
/>
|
||||
<SidebarDivider />
|
||||
<SidebarButton
|
||||
view={ViewType.Order}
|
||||
icon={VegaIconNames.TICKET}
|
||||
tooltip={t('Order')}
|
||||
routeId={currentRouteId}
|
||||
/>
|
||||
<SidebarButton
|
||||
view={ViewType.Info}
|
||||
icon={VegaIconNames.BREAKDOWN}
|
||||
tooltip={t('Market specification')}
|
||||
routeId={currentRouteId}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -43,7 +43,7 @@ export const MarketHeaderStats = ({ market }: MarketHeaderStatsProps) => {
|
||||
const asset = getAsset(market);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex gap-8">
|
||||
<HeaderStat heading={t('Mark Price')} testId="market-price">
|
||||
<MarketMarkPrice
|
||||
marketId={market.id}
|
||||
@@ -144,7 +144,7 @@ export const MarketHeaderStats = ({ market }: MarketHeaderStatsProps) => {
|
||||
</HeaderStat>
|
||||
)}
|
||||
<MarketProposalNotification marketId={market.id} />
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -9,9 +9,10 @@ import { useGlobalStore, usePageTitleStore } from '../../stores';
|
||||
import { TradeGrid } from './trade-grid';
|
||||
import { TradePanels } from './trade-panels';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { Links } from '../../lib/links';
|
||||
import { Links, Routes } from '../../lib/links';
|
||||
import { ViewType, useSidebar } from '../../components/sidebar';
|
||||
import { useGetCurrentRouteId } from '../../lib/hooks/use-get-current-route-id';
|
||||
import { MarketState } from '@vegaprotocol/types';
|
||||
|
||||
const calculatePrice = (markPrice?: string, decimalPlaces?: number) => {
|
||||
return markPrice && decimalPlaces
|
||||
@@ -56,7 +57,7 @@ const TitleUpdater = ({
|
||||
return null;
|
||||
};
|
||||
|
||||
export const MarketPage = () => {
|
||||
export const MarketPage = ({ closed }: { closed?: boolean }) => {
|
||||
const { marketId } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const currentRouteId = useGetCurrentRouteId();
|
||||
@@ -69,11 +70,25 @@ export const MarketPage = () => {
|
||||
|
||||
const { data, loading } = useMarket(marketId);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
data?.state &&
|
||||
[
|
||||
MarketState.STATE_SETTLED,
|
||||
MarketState.STATE_TRADING_TERMINATED,
|
||||
].includes(data.state) &&
|
||||
currentRouteId !== Routes.CLOSED_MARKETS &&
|
||||
marketId
|
||||
) {
|
||||
navigate(Links.CLOSED_MARKETS(marketId));
|
||||
}
|
||||
}, [data?.state, currentRouteId, navigate, marketId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (data?.id && data.id !== lastMarketId && !closed) {
|
||||
update({ marketId: data.id });
|
||||
}
|
||||
}, [update, lastMarketId, data?.id]);
|
||||
}, [update, lastMarketId, data?.id, closed]);
|
||||
|
||||
useEffect(() => {
|
||||
if (largeScreen && view === undefined) {
|
||||
@@ -82,7 +97,7 @@ export const MarketPage = () => {
|
||||
currentRouteId
|
||||
);
|
||||
}
|
||||
}, [setViews, view, currentRouteId, largeScreen]);
|
||||
}, [setViews, view, currentRouteId, largeScreen, closed]);
|
||||
|
||||
const pinnedAsset = data && getAsset(data);
|
||||
|
||||
|
||||
@@ -73,19 +73,10 @@ const MainGrid = memo(
|
||||
{market &&
|
||||
market.tradableInstrument.instrument.product.__typename ===
|
||||
'Perpetual' ? (
|
||||
<Tab id="funding-history" name={t('Funding history')}>
|
||||
<Tab id="funding" name={t('Funding')}>
|
||||
<TradingViews.funding.component marketId={marketId} />
|
||||
</Tab>
|
||||
) : null}
|
||||
{market &&
|
||||
market.tradableInstrument.instrument.product.__typename ===
|
||||
'Perpetual' ? (
|
||||
<Tab id="funding-payments" name={t('Funding payments')}>
|
||||
<TradingViews.fundingPayments.component
|
||||
marketId={marketId}
|
||||
/>
|
||||
</Tab>
|
||||
) : null}
|
||||
</Tabs>
|
||||
</TradeGridChild>
|
||||
</ResizableGridPanel>
|
||||
@@ -148,6 +139,9 @@ const MainGrid = memo(
|
||||
<Tab id="fills" name={t('Fills')}>
|
||||
<TradingViews.fills.component />
|
||||
</Tab>
|
||||
<Tab id="funding-payments" name={t('Funding payments')}>
|
||||
<TradingViews.fundingPayments.component />
|
||||
</Tab>
|
||||
<Tab
|
||||
id="accounts"
|
||||
name={t('Collateral')}
|
||||
|
||||
@@ -363,12 +363,12 @@ describe('Closed', () => {
|
||||
const container = within(
|
||||
document.querySelector('.ag-center-cols-container') as HTMLElement
|
||||
);
|
||||
const cell = container.getAllByRole('gridcell', {
|
||||
name: (_name, element) => element.getAttribute('col-id') === 'code',
|
||||
})[0];
|
||||
|
||||
const cells = await container.findAllByRole('gridcell');
|
||||
const cell = cells.find((el) => el.getAttribute('col-id') === 'code');
|
||||
|
||||
expect(
|
||||
within(cell as HTMLElement).getByTestId('stack-cell-secondary')
|
||||
).toHaveTextContent('PRNT');
|
||||
expect(within(cell).getByTestId('stack-cell-secondary')).toHaveTextContent(
|
||||
'PRNT'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { CellClickedEvent } from 'ag-grid-community';
|
||||
import compact from 'lodash/compact';
|
||||
import { isAfter } from 'date-fns';
|
||||
import type {
|
||||
@@ -6,7 +5,6 @@ import type {
|
||||
VegaValueFormatterParams,
|
||||
} from '@vegaprotocol/datagrid';
|
||||
import { AgGrid, COL_DEFS } from '@vegaprotocol/datagrid';
|
||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
||||
import { useMemo } from 'react';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import type { Asset } from '@vegaprotocol/types';
|
||||
@@ -19,11 +17,13 @@ import {
|
||||
import { closedMarketsWithDataProvider, getAsset } from '@vegaprotocol/markets';
|
||||
import type { DataSourceFilterFragment } from '@vegaprotocol/markets';
|
||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||
import { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
|
||||
import { SettlementDateCell } from './settlement-date-cell';
|
||||
import { SettlementPriceCell } from './settlement-price-cell';
|
||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
||||
import { MarketCodeCell } from './market-code-cell';
|
||||
import { MarketActionsDropdown } from './market-table-actions';
|
||||
import type { CellClickedEvent } from 'ag-grid-community';
|
||||
import { useClosedMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
|
||||
|
||||
type SettlementAsset = Pick<
|
||||
Asset,
|
||||
@@ -127,7 +127,7 @@ const ClosedMarketsDataGrid = ({
|
||||
rowData: Row[];
|
||||
error: Error | undefined;
|
||||
}) => {
|
||||
const handleOnSelect = useMarketClickHandler();
|
||||
const handleOnSelect = useClosedMarketClickHandler();
|
||||
const openAssetDialog = useAssetDetailsDialogStore((store) => store.open);
|
||||
|
||||
const colDefs = useMemo(() => {
|
||||
@@ -302,11 +302,8 @@ const ClosedMarketsDataGrid = ({
|
||||
return;
|
||||
}
|
||||
|
||||
handleOnSelect(
|
||||
data.id,
|
||||
// @ts-ignore metaKey exists
|
||||
event ? event.metaKey : false
|
||||
);
|
||||
// @ts-ignore metaKey exists
|
||||
handleOnSelect(data.id, event ? event.metaKey : false);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
import { Route, Routes, useParams } from 'react-router-dom';
|
||||
import { MarketState } from '@vegaprotocol/types';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { useMarket } from '@vegaprotocol/markets';
|
||||
import { VegaIconNames } from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
SidebarButton,
|
||||
SidebarDivider,
|
||||
ViewType,
|
||||
} from '../../components/sidebar';
|
||||
import { useGetCurrentRouteId } from '../../lib/hooks/use-get-current-route-id';
|
||||
|
||||
export const MarketsSidebar = () => {
|
||||
const { marketId } = useParams();
|
||||
const currentRouteId = useGetCurrentRouteId();
|
||||
const { data } = useMarket(marketId);
|
||||
const active =
|
||||
data &&
|
||||
[MarketState.STATE_ACTIVE, MarketState.STATE_PENDING].includes(data.state);
|
||||
|
||||
return (
|
||||
<>
|
||||
<SidebarButton
|
||||
view={ViewType.Deposit}
|
||||
icon={VegaIconNames.DEPOSIT}
|
||||
tooltip={t('Deposit')}
|
||||
routeId={currentRouteId}
|
||||
/>
|
||||
<SidebarButton
|
||||
view={ViewType.Withdraw}
|
||||
icon={VegaIconNames.WITHDRAW}
|
||||
tooltip={t('Withdraw')}
|
||||
routeId={currentRouteId}
|
||||
/>
|
||||
<SidebarButton
|
||||
view={ViewType.Transfer}
|
||||
icon={VegaIconNames.TRANSFER}
|
||||
tooltip={t('Transfer')}
|
||||
routeId={currentRouteId}
|
||||
/>
|
||||
<Routes>
|
||||
<Route
|
||||
path=":marketId"
|
||||
element={
|
||||
<>
|
||||
<SidebarDivider />
|
||||
{active && (
|
||||
<SidebarButton
|
||||
view={ViewType.Order}
|
||||
icon={VegaIconNames.TICKET}
|
||||
tooltip={t('Order')}
|
||||
routeId={currentRouteId}
|
||||
/>
|
||||
)}
|
||||
<SidebarButton
|
||||
view={ViewType.Info}
|
||||
icon={VegaIconNames.BREAKDOWN}
|
||||
tooltip={t('Market specification')}
|
||||
routeId={currentRouteId}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</Routes>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,31 +0,0 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { VegaIconNames } from '@vegaprotocol/ui-toolkit';
|
||||
import { SidebarButton, ViewType } from '../../components/sidebar';
|
||||
import { useGetCurrentRouteId } from '../../lib/hooks/use-get-current-route-id';
|
||||
|
||||
export const PortfolioSidebar = () => {
|
||||
const currentRouteId = useGetCurrentRouteId();
|
||||
|
||||
return (
|
||||
<>
|
||||
<SidebarButton
|
||||
view={ViewType.Deposit}
|
||||
icon={VegaIconNames.DEPOSIT}
|
||||
tooltip={t('Deposit')}
|
||||
routeId={currentRouteId}
|
||||
/>
|
||||
<SidebarButton
|
||||
view={ViewType.Withdraw}
|
||||
icon={VegaIconNames.WITHDRAW}
|
||||
tooltip={t('Withdraw')}
|
||||
routeId={currentRouteId}
|
||||
/>
|
||||
<SidebarButton
|
||||
view={ViewType.Transfer}
|
||||
icon={VegaIconNames.TRANSFER}
|
||||
tooltip={t('Transfer')}
|
||||
routeId={currentRouteId}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -4,11 +4,11 @@ import {
|
||||
AppLoader,
|
||||
DocsLinks,
|
||||
NetworkLoader,
|
||||
NodeFailure,
|
||||
NodeGuard,
|
||||
useEnvironment,
|
||||
} from '@vegaprotocol/environment';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { MaintenancePage } from '@vegaprotocol/ui-toolkit';
|
||||
import { VegaWalletProvider } from '@vegaprotocol/wallet';
|
||||
import type { ReactNode } from 'react';
|
||||
import { Web3Provider } from './web3-provider';
|
||||
@@ -20,10 +20,15 @@ export const Bootstrapper = ({ children }: { children: ReactNode }) => {
|
||||
VEGA_ENV,
|
||||
VEGA_WALLET_URL,
|
||||
VEGA_EXPLORER_URL,
|
||||
MAINTENANCE_PAGE,
|
||||
MOZILLA_EXTENSION_URL,
|
||||
CHROME_EXTENSION_URL,
|
||||
} = useEnvironment();
|
||||
|
||||
if (MAINTENANCE_PAGE) {
|
||||
return <MaintenancePage />;
|
||||
}
|
||||
|
||||
if (
|
||||
!VEGA_URL ||
|
||||
!VEGA_WALLET_URL ||
|
||||
@@ -32,7 +37,7 @@ export const Bootstrapper = ({ children }: { children: ReactNode }) => {
|
||||
!MOZILLA_EXTENSION_URL ||
|
||||
!DocsLinks
|
||||
) {
|
||||
return <AppLoader />;
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -45,14 +50,9 @@ export const Bootstrapper = ({ children }: { children: ReactNode }) => {
|
||||
>
|
||||
<NodeGuard
|
||||
skeleton={<AppLoader />}
|
||||
failure={<NodeFailure title={t(`Node: ${VEGA_URL} is unsuitable`)} />}
|
||||
failure={<AppFailure title={t(`Node: ${VEGA_URL} is unsuitable`)} />}
|
||||
>
|
||||
<Web3Provider
|
||||
skeleton={<AppLoader />}
|
||||
failure={
|
||||
<AppFailure title={t(`Could not configure web3 provider`)} />
|
||||
}
|
||||
>
|
||||
<Web3Provider>
|
||||
<VegaWalletProvider
|
||||
config={{
|
||||
network: VEGA_ENV,
|
||||
|
||||
@@ -6,20 +6,14 @@ import {
|
||||
useWeb3ConnectStore,
|
||||
createDefaultProvider,
|
||||
} from '@vegaprotocol/web3';
|
||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { useEnvironment } from '@vegaprotocol/environment';
|
||||
import type { ReactNode } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
export const Web3Provider = ({
|
||||
children,
|
||||
skeleton,
|
||||
failure,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
skeleton: ReactNode;
|
||||
failure: ReactNode;
|
||||
}) => {
|
||||
export const Web3Provider = ({ children }: { children: ReactNode }) => {
|
||||
const { config, loading, error } = useEthereumConfig();
|
||||
const { ETHEREUM_PROVIDER_URL, ETH_LOCAL_PROVIDER_URL, ETH_WALLET_MNEMONIC } =
|
||||
useEnvironment();
|
||||
@@ -55,20 +49,23 @@ export const Web3Provider = ({
|
||||
ETH_WALLET_MNEMONIC,
|
||||
]);
|
||||
|
||||
if (error) {
|
||||
return <>{failure}</>;
|
||||
}
|
||||
|
||||
if (loading || !connectors.length) {
|
||||
return <>{skeleton}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
<Web3ProviderInternal
|
||||
connectors={connectors}
|
||||
defaultProvider={defaultProvider}
|
||||
<AsyncRenderer
|
||||
loading={loading}
|
||||
error={error}
|
||||
data={connectors}
|
||||
noDataCondition={(d) => {
|
||||
if (!d) return true;
|
||||
return d.length < 1;
|
||||
}}
|
||||
noDataMessage={t('Could not fetch Ethereum configuration')}
|
||||
>
|
||||
<>{children}</>
|
||||
</Web3ProviderInternal>
|
||||
<Web3ProviderInternal
|
||||
connectors={connectors}
|
||||
defaultProvider={defaultProvider}
|
||||
>
|
||||
<>{children}</>
|
||||
</Web3ProviderInternal>
|
||||
</AsyncRenderer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -9,11 +9,7 @@ import type { DataGridSlice } from '../../stores/datagrid-store-slice';
|
||||
import { createDataGridSlice } from '../../stores/datagrid-store-slice';
|
||||
import { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
|
||||
|
||||
export const FundingPaymentsContainer = ({
|
||||
marketId,
|
||||
}: {
|
||||
marketId?: string;
|
||||
}) => {
|
||||
export const FundingPaymentsContainer = () => {
|
||||
const onMarketClick = useMarketClickHandler(true);
|
||||
const { pubKey } = useVegaWallet();
|
||||
|
||||
@@ -37,7 +33,6 @@ export const FundingPaymentsContainer = ({
|
||||
return (
|
||||
<FundingPaymentsManager
|
||||
partyId={pubKey}
|
||||
marketId={marketId}
|
||||
onMarketClick={onMarketClick}
|
||||
gridProps={gridStoreCallbacks}
|
||||
/>
|
||||
|
||||
@@ -17,11 +17,11 @@ export const Header = ({ title, children }: TradeMarketHeaderProps) => {
|
||||
);
|
||||
return (
|
||||
<header className={headerClasses}>
|
||||
<div className="flex-col items-start justify-center hidden pt-2 pb-0 pl-3 lg:flex lg:pl-4 xl:pb-2">
|
||||
<div className="hidden lg:flex flex-col justify-center items-start pl-3 lg:pl-4 pt-2 xl:pb-2 pb-0">
|
||||
{title}
|
||||
</div>
|
||||
<div data-testid="header-summary" className="min-w-0">
|
||||
<div className="flex items-center px-3 py-2 overflow-x-auto text-xs lg:px-4 flex-nowrap gap-6">
|
||||
<div className="px-3 lg:px-4 py-2 flex flex-nowrap gap-4 items-center text-xs overflow-x-auto">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
@@ -70,7 +70,7 @@ export const HeaderTitle = ({ children }: { children: ReactNode }) => {
|
||||
return (
|
||||
<h1
|
||||
data-testid="header-title"
|
||||
className="flex items-center text-lg gap-4 whitespace-nowrap xl:pr-4 xl:border-r border-default"
|
||||
className="flex gap-4 items-center text-lg whitespace-nowrap xl:pr-4 xl:border-r border-default"
|
||||
>
|
||||
{children}
|
||||
</h1>
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import { Outlet } from 'react-router-dom';
|
||||
import { Outlet, Routes, Route } from 'react-router-dom';
|
||||
import { Sidebar, SidebarContent, useSidebar } from '../sidebar';
|
||||
import classNames from 'classnames';
|
||||
import { MarketHeader } from '../market-header';
|
||||
import { LiquidityHeader } from '../liquidity-header';
|
||||
import { useGetCurrentRouteId } from '../../lib/hooks/use-get-current-route-id';
|
||||
|
||||
export const LayoutWithSidebar = ({
|
||||
header,
|
||||
sidebar,
|
||||
}: {
|
||||
header?: ReactNode;
|
||||
sidebar?: ReactNode;
|
||||
}) => {
|
||||
export const LayoutWithSidebar = () => {
|
||||
const currentRouteId = useGetCurrentRouteId();
|
||||
const views = useSidebar((store) => store.views);
|
||||
const sidebarView = views[currentRouteId] || null;
|
||||
@@ -25,7 +20,16 @@ export const LayoutWithSidebar = ({
|
||||
|
||||
return (
|
||||
<div className={gridClasses}>
|
||||
<div className="col-span-full">{header}</div>
|
||||
<div className="col-span-full">
|
||||
<Routes>
|
||||
<Route path="markets/:marketId" element={<MarketHeader />} />
|
||||
<Route
|
||||
path="markets/all/closed/:marketId"
|
||||
element={<MarketHeader />}
|
||||
/>
|
||||
<Route path="liquidity/:marketId" element={<LiquidityHeader />} />
|
||||
</Routes>
|
||||
</div>
|
||||
<main
|
||||
className={classNames('col-start-1 col-end-1', {
|
||||
'lg:col-end-3': !sidebarOpen,
|
||||
@@ -36,12 +40,9 @@ export const LayoutWithSidebar = ({
|
||||
</main>
|
||||
<aside
|
||||
// min-h-0 is needed as this element is part of a grid, we want the content to be scrollable, without it it will push the grid element taller
|
||||
className={classNames(
|
||||
'col-start-1 lg:col-start-2 min-h-0 lg:border-l border-default lg:bg-vega-clight-800 dark:lg:bg-vega-cdark-800',
|
||||
{
|
||||
hidden: !sidebarOpen,
|
||||
}
|
||||
)}
|
||||
className={classNames('col-start-1 lg:col-start-2 min-h-0', {
|
||||
hidden: !sidebarOpen,
|
||||
})}
|
||||
>
|
||||
<SidebarContent />
|
||||
</aside>
|
||||
@@ -53,7 +54,7 @@ export const LayoutWithSidebar = ({
|
||||
'lg:row-start-2 lg:row-span-full lg:col-start-3'
|
||||
)}
|
||||
>
|
||||
<Sidebar options={sidebar} />
|
||||
<Sidebar />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Popover, VegaIcon, VegaIconNames } from '@vegaprotocol/ui-toolkit';
|
||||
import { Header, HeaderTitle } from '../header';
|
||||
import { Route, Routes, useParams } from 'react-router-dom';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { MarketSelector } from '../../components/market-selector/market-selector';
|
||||
import { MarketHeaderStats } from '../../client-pages/market/market-header-stats';
|
||||
import { useMarket, useMarketList } from '@vegaprotocol/markets';
|
||||
@@ -19,44 +19,36 @@ export const MarketHeader = () => {
|
||||
if (!data) return null;
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
<Route
|
||||
path=":marketId"
|
||||
element={
|
||||
<Header
|
||||
title={
|
||||
<Popover
|
||||
open={open}
|
||||
onChange={setOpen}
|
||||
trigger={
|
||||
<HeaderTitle>
|
||||
<span>
|
||||
{data.tradableInstrument.instrument.code}
|
||||
<span className="ml-1 text-xs uppercase text-muted">
|
||||
{data.tradableInstrument.instrument.product
|
||||
.__typename &&
|
||||
ProductTypeShortName[
|
||||
data.tradableInstrument.instrument.product
|
||||
.__typename
|
||||
]}
|
||||
</span>
|
||||
</span>
|
||||
<VegaIcon name={VegaIconNames.CHEVRON_DOWN} size={14} />
|
||||
</HeaderTitle>
|
||||
}
|
||||
alignOffset={-10}
|
||||
>
|
||||
<MarketSelector
|
||||
currentMarketId={marketId}
|
||||
onSelect={() => setOpen(false)}
|
||||
/>
|
||||
</Popover>
|
||||
}
|
||||
>
|
||||
<MarketHeaderStats market={data} />
|
||||
</Header>
|
||||
}
|
||||
/>
|
||||
</Routes>
|
||||
<Header
|
||||
title={
|
||||
<Popover
|
||||
open={open}
|
||||
onChange={setOpen}
|
||||
trigger={
|
||||
<HeaderTitle>
|
||||
<span>
|
||||
{data.tradableInstrument.instrument.code}
|
||||
<span className="ml-2 text-xs uppercase text-muted">
|
||||
{' '}
|
||||
{data.tradableInstrument.instrument.product.__typename &&
|
||||
ProductTypeShortName[
|
||||
data.tradableInstrument.instrument.product.__typename
|
||||
]}{' '}
|
||||
</span>
|
||||
</span>
|
||||
<VegaIcon name={VegaIconNames.CHEVRON_DOWN} size={14} />
|
||||
</HeaderTitle>
|
||||
}
|
||||
alignOffset={-10}
|
||||
>
|
||||
<MarketSelector
|
||||
currentMarketId={marketId}
|
||||
onSelect={() => setOpen(false)}
|
||||
/>
|
||||
</Popover>
|
||||
}
|
||||
>
|
||||
<MarketHeaderStats market={data} />
|
||||
</Header>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -63,7 +63,7 @@ describe('Navbar', () => {
|
||||
|
||||
const expectedLinks = [
|
||||
['/', ''],
|
||||
['/markets', 'Markets'],
|
||||
['/markets/all', 'Markets'],
|
||||
[`/markets/${marketId}`, 'Trading'],
|
||||
['/portfolio', 'Portfolio'],
|
||||
['/referrals', 'Referrals'],
|
||||
@@ -80,7 +80,7 @@ describe('Navbar', () => {
|
||||
});
|
||||
|
||||
it('Markets page route should not match empty market page', () => {
|
||||
renderComponent(['/markets']);
|
||||
renderComponent(['/markets/all']);
|
||||
expect(screen.getByRole('link', { name: 'Markets' })).toHaveClass('active');
|
||||
expect(screen.getByRole('link', { name: 'Trading' })).not.toHaveClass(
|
||||
'active'
|
||||
@@ -96,7 +96,7 @@ describe('Navbar', () => {
|
||||
const menu = within(menuEl);
|
||||
|
||||
const expectedLinks = [
|
||||
['/markets', 'Markets'],
|
||||
['/markets/all', 'Markets'],
|
||||
[`/markets/${marketId}`, 'Trading'],
|
||||
['/portfolio', 'Portfolio'],
|
||||
['/referrals', 'Referrals'],
|
||||
|
||||
@@ -264,7 +264,6 @@ const NavbarLink = ({
|
||||
<N.Link asChild={true}>
|
||||
<NavLink
|
||||
to={to}
|
||||
end={true}
|
||||
className={classNames(
|
||||
'block lg:flex lg:h-full flex-col justify-center',
|
||||
'px-6 py-2 lg:p-0 text-lg lg:text-sm',
|
||||
|
||||
@@ -3,12 +3,14 @@ import { Filter, OrderListManager } from '@vegaprotocol/orders';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { useNavigateWithMeta } from '../../lib/hooks/use-market-click-handler';
|
||||
import {
|
||||
useMarketClickHandler,
|
||||
useMarketLiquidityClickHandler,
|
||||
} from '../../lib/hooks/use-market-click-handler';
|
||||
import { create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
import type { DataGridStore } from '../../stores/datagrid-store-slice';
|
||||
import { OrderStatus } from '@vegaprotocol/types';
|
||||
import { Links } from '../../lib/links';
|
||||
|
||||
export const FilterStatusValue = {
|
||||
[Filter.Open]: [OrderStatus.STATUS_ACTIVE, OrderStatus.STATUS_PARKED],
|
||||
@@ -30,7 +32,8 @@ const AUTO_SIZE_COLUMNS = ['instrument-code'];
|
||||
|
||||
export const OrdersContainer = ({ filter }: OrderContainerProps) => {
|
||||
const { pubKey, isReadOnly } = useVegaWallet();
|
||||
const navigate = useNavigateWithMeta();
|
||||
const onMarketClick = useMarketClickHandler(true);
|
||||
const onOrderTypeClick = useMarketLiquidityClickHandler();
|
||||
const { gridState, updateGridState } = useOrderListGridState(filter);
|
||||
const gridStoreCallbacks = useDataGridEvents(
|
||||
gridState,
|
||||
@@ -48,12 +51,8 @@ export const OrdersContainer = ({ filter }: OrderContainerProps) => {
|
||||
<OrderListManager
|
||||
partyId={pubKey}
|
||||
filter={filter}
|
||||
onMarketClick={(marketId, metaKey) => {
|
||||
navigate(Links.MARKET(marketId), metaKey);
|
||||
}}
|
||||
onOrderTypeClick={(marketId, metaKey) =>
|
||||
navigate(Links.LIQUIDITY(marketId), metaKey)
|
||||
}
|
||||
onMarketClick={onMarketClick}
|
||||
onOrderTypeClick={onOrderTypeClick}
|
||||
isReadOnly={isReadOnly}
|
||||
gridProps={gridStoreCallbacks}
|
||||
/>
|
||||
|
||||
@@ -38,68 +38,79 @@ const walletContext = {
|
||||
} as VegaWalletContextShape;
|
||||
|
||||
describe('Sidebar', () => {
|
||||
beforeEach(() => {
|
||||
useSidebar.setState({ views: {} });
|
||||
});
|
||||
it.each(['/markets/all', '/portfolio'])(
|
||||
'does not render ticket and info',
|
||||
(path) => {
|
||||
render(
|
||||
<VegaWalletContext.Provider value={walletContext}>
|
||||
<MemoryRouter initialEntries={[path]}>
|
||||
<Sidebar />
|
||||
</MemoryRouter>
|
||||
</VegaWalletContext.Provider>
|
||||
);
|
||||
|
||||
it('renders options prop', () => {
|
||||
expect(screen.getByTestId(ViewType.ViewAs)).toBeInTheDocument();
|
||||
expect(screen.getByTestId(ViewType.Settings)).toBeInTheDocument();
|
||||
expect(screen.getByTestId(ViewType.Transfer)).toBeInTheDocument();
|
||||
expect(screen.getByTestId(ViewType.Deposit)).toBeInTheDocument();
|
||||
expect(screen.getByTestId(ViewType.Withdraw)).toBeInTheDocument();
|
||||
expect(screen.getByTestId('node-health')).toBeInTheDocument();
|
||||
|
||||
// no order or info sidebars
|
||||
expect(screen.queryByTestId(ViewType.Order)).not.toBeInTheDocument();
|
||||
expect(screen.queryByTestId(ViewType.Info)).not.toBeInTheDocument();
|
||||
}
|
||||
);
|
||||
|
||||
it('renders ticket and info on market pages', () => {
|
||||
render(
|
||||
<VegaWalletContext.Provider value={walletContext}>
|
||||
<MemoryRouter>
|
||||
<Sidebar options={<div data-testid="options" />} />
|
||||
<MemoryRouter initialEntries={['/markets/ABC']}>
|
||||
<Sidebar />
|
||||
</MemoryRouter>
|
||||
</VegaWalletContext.Provider>
|
||||
);
|
||||
|
||||
expect(screen.getByTestId(ViewType.ViewAs)).toBeInTheDocument();
|
||||
expect(screen.getByTestId(ViewType.Settings)).toBeInTheDocument();
|
||||
expect(screen.getByTestId(ViewType.Transfer)).toBeInTheDocument();
|
||||
expect(screen.getByTestId(ViewType.Deposit)).toBeInTheDocument();
|
||||
expect(screen.getByTestId(ViewType.Withdraw)).toBeInTheDocument();
|
||||
expect(screen.getByTestId('node-health')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('options')).toBeInTheDocument();
|
||||
|
||||
// order and info sidebars are shown
|
||||
expect(screen.getByTestId(ViewType.Order)).toBeInTheDocument();
|
||||
expect(screen.getByTestId(ViewType.Info)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders selected state', async () => {
|
||||
const routeId = '/markets/ABC';
|
||||
render(
|
||||
<VegaWalletContext.Provider value={walletContext}>
|
||||
<MemoryRouter initialEntries={[routeId]}>
|
||||
<Sidebar
|
||||
options={
|
||||
<SidebarButton
|
||||
view={ViewType.Deposit}
|
||||
icon={VegaIconNames.DEPOSIT}
|
||||
tooltip="Deposit"
|
||||
routeId={'/markets/:marketId'}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<MemoryRouter initialEntries={['/markets/ABC']}>
|
||||
<Sidebar />
|
||||
</MemoryRouter>
|
||||
</VegaWalletContext.Provider>
|
||||
);
|
||||
|
||||
const settingsButton = screen.getByTestId(ViewType.Settings);
|
||||
const depositButton = screen.getByTestId(ViewType.Deposit);
|
||||
const orderButton = screen.getByTestId(ViewType.Order);
|
||||
|
||||
// select settings first
|
||||
await userEvent.click(settingsButton);
|
||||
expect(settingsButton).toHaveClass('bg-vega-yellow text-black');
|
||||
|
||||
// switch to deposit
|
||||
await userEvent.click(depositButton);
|
||||
|
||||
// switch to order
|
||||
await userEvent.click(orderButton);
|
||||
expect(settingsButton).not.toHaveClass('bg-vega-yellow text-black');
|
||||
expect(depositButton).toHaveClass('bg-vega-yellow text-black');
|
||||
expect(orderButton).toHaveClass('bg-vega-yellow text-black');
|
||||
|
||||
// close order
|
||||
await userEvent.click(depositButton);
|
||||
expect(depositButton).not.toHaveClass('bg-vega-yellow text-black');
|
||||
await userEvent.click(orderButton);
|
||||
expect(orderButton).not.toHaveClass('bg-vega-yellow text-black');
|
||||
});
|
||||
});
|
||||
|
||||
describe('SidebarContent', () => {
|
||||
beforeEach(() => {
|
||||
useSidebar.setState({ views: {} });
|
||||
});
|
||||
|
||||
it('renders the correct content', () => {
|
||||
const { container } = render(
|
||||
<VegaWalletContext.Provider value={walletContext}>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import classNames from 'classnames';
|
||||
import type { ReactNode } from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { Route, Routes, useParams } from 'react-router-dom';
|
||||
import { create } from 'zustand';
|
||||
import { TransferContainer } from '@vegaprotocol/accounts';
|
||||
import { DealTicketContainer } from '@vegaprotocol/deal-ticket';
|
||||
@@ -50,14 +50,108 @@ type SidebarView =
|
||||
type: ViewType.Settings;
|
||||
};
|
||||
|
||||
export const Sidebar = ({ options }: { options?: ReactNode }) => {
|
||||
const MarketSidebarButtons = () => {
|
||||
const currentRouteId = useGetCurrentRouteId();
|
||||
|
||||
return (
|
||||
<>
|
||||
<SidebarButton
|
||||
view={ViewType.Order}
|
||||
icon={VegaIconNames.TICKET}
|
||||
tooltip={t('Order')}
|
||||
routeId={currentRouteId}
|
||||
/>
|
||||
<SidebarButton
|
||||
view={ViewType.Info}
|
||||
icon={VegaIconNames.BREAKDOWN}
|
||||
tooltip={t('Market specification')}
|
||||
routeId={currentRouteId}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const AssetSidebarButtons = () => {
|
||||
const currentRouteId = useGetCurrentRouteId();
|
||||
|
||||
return (
|
||||
<>
|
||||
<SidebarButton
|
||||
view={ViewType.Deposit}
|
||||
icon={VegaIconNames.DEPOSIT}
|
||||
tooltip={t('Deposit')}
|
||||
routeId={currentRouteId}
|
||||
/>
|
||||
<SidebarButton
|
||||
view={ViewType.Withdraw}
|
||||
icon={VegaIconNames.WITHDRAW}
|
||||
tooltip={t('Withdraw')}
|
||||
routeId={currentRouteId}
|
||||
/>
|
||||
<SidebarButton
|
||||
view={ViewType.Transfer}
|
||||
icon={VegaIconNames.TRANSFER}
|
||||
tooltip={t('Transfer')}
|
||||
routeId={currentRouteId}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const Sidebar = () => {
|
||||
const currentRouteId = useGetCurrentRouteId();
|
||||
const navClasses = 'flex lg:flex-col items-center gap-2 lg:gap-4 p-1';
|
||||
const setViewAsDialogOpen = useViewAsDialog((state) => state.setOpen);
|
||||
const { pubKeys } = useVegaWallet();
|
||||
return (
|
||||
<div className="flex h-full p-1 lg:flex-col gap-2" data-testid="sidebar">
|
||||
{options && <nav className={navClasses}>{options}</nav>}
|
||||
<nav className={navClasses}>
|
||||
<Routes>
|
||||
<Route path="markets/all" element={<AssetSidebarButtons />} />
|
||||
<Route path="portfolio">
|
||||
<Route
|
||||
// Show deposit/withdraw/transfer sidebar options only on portflio dashboard (index)
|
||||
index={true}
|
||||
element={<AssetSidebarButtons />}
|
||||
/>
|
||||
</Route>
|
||||
<Route
|
||||
path="markets/:marketId"
|
||||
element={
|
||||
<>
|
||||
<AssetSidebarButtons />
|
||||
<SidebarDivider />
|
||||
<MarketSidebarButtons />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="liquidity/:marketId"
|
||||
element={
|
||||
<>
|
||||
<AssetSidebarButtons />
|
||||
<SidebarDivider />
|
||||
<MarketSidebarButtons />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="markets/all/closed/:marketId"
|
||||
element={
|
||||
<>
|
||||
<AssetSidebarButtons />
|
||||
<SidebarDivider />
|
||||
<SidebarButton
|
||||
view={ViewType.Info}
|
||||
icon={VegaIconNames.BREAKDOWN}
|
||||
tooltip={t('Market specification')}
|
||||
routeId={currentRouteId}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</Routes>
|
||||
</nav>
|
||||
<nav className={classNames(navClasses, 'ml-auto lg:mt-auto lg:ml-0')}>
|
||||
<SidebarButton
|
||||
view={ViewType.ViewAs}
|
||||
@@ -140,7 +234,7 @@ export const SidebarButton = ({
|
||||
);
|
||||
};
|
||||
|
||||
export const SidebarDivider = () => {
|
||||
const SidebarDivider = () => {
|
||||
return (
|
||||
<div
|
||||
className="w-px h-4 bg-vega-clight-600 dark:bg-vega-cdark-600 lg:w-4 lg:h-px"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useCallback } from 'react';
|
||||
import { Links } from '../../lib/links';
|
||||
|
||||
export const useMarketClickHandler = (replace = false) => {
|
||||
@@ -14,10 +15,17 @@ export const useMarketClickHandler = (replace = false) => {
|
||||
};
|
||||
};
|
||||
|
||||
export const useNavigateWithMeta = (replace = false) => {
|
||||
export const useMarketLiquidityClickHandler = () => {
|
||||
return useCallback((selectedId: string, metaKey?: boolean) => {
|
||||
window.open(`/#/liquidity/${selectedId}`, metaKey ? '_blank' : '_self');
|
||||
}, []);
|
||||
};
|
||||
|
||||
export const useClosedMarketClickHandler = (replace = false) => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (link: string, metaKey?: boolean) => {
|
||||
return (selectedId: string, metaKey?: boolean) => {
|
||||
const link = Links.CLOSED_MARKETS(selectedId);
|
||||
if (metaKey) {
|
||||
window.open(`/#${link}`, '_blank');
|
||||
} else {
|
||||
|
||||
@@ -4,7 +4,8 @@ import trimEnd from 'lodash/trimEnd';
|
||||
// href creation
|
||||
export const Routes = {
|
||||
HOME: '/',
|
||||
MARKETS: '/markets',
|
||||
MARKETS: '/markets/all',
|
||||
CLOSED_MARKETS: '/markets/all/closed/:marketId',
|
||||
MARKET: '/markets/:marketId',
|
||||
LIQUIDITY: '/liquidity/:marketId',
|
||||
PORTFOLIO: '/portfolio',
|
||||
@@ -28,6 +29,8 @@ export const Links: ConsoleLinks = {
|
||||
MARKET: (marketId: string) =>
|
||||
trimEnd(Routes.MARKET.replace(':marketId', marketId)),
|
||||
MARKETS: () => Routes.MARKETS,
|
||||
CLOSED_MARKETS: (marketId: string) =>
|
||||
trimEnd(Routes.CLOSED_MARKETS.replace(':marketId', marketId)),
|
||||
PORTFOLIO: () => Routes.PORTFOLIO,
|
||||
LIQUIDITY: (marketId: string) =>
|
||||
trimEnd(Routes.LIQUIDITY.replace(':marketId', marketId)),
|
||||
|
||||
@@ -1,7 +1,21 @@
|
||||
import { useMemo } from 'react';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import Head from 'next/head';
|
||||
import type { AppProps } from 'next/app';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import {
|
||||
useEagerConnect as useVegaEagerConnect,
|
||||
useVegaWallet,
|
||||
} from '@vegaprotocol/wallet';
|
||||
import {
|
||||
useVegaTransactionManager,
|
||||
useVegaTransactionUpdater,
|
||||
} from '@vegaprotocol/web3';
|
||||
import {
|
||||
useEagerConnect as useEthereumEagerConnect,
|
||||
useEthTransactionManager,
|
||||
useEthTransactionUpdater,
|
||||
useEthWithdrawApprovalsManager,
|
||||
} from '@vegaprotocol/web3';
|
||||
import {
|
||||
envTriggerMapping,
|
||||
Networks,
|
||||
@@ -11,11 +25,21 @@ import {
|
||||
useNodeSwitcherStore,
|
||||
} from '@vegaprotocol/environment';
|
||||
import './styles.css';
|
||||
import { usePageTitleStore } from '../stores';
|
||||
import { useGlobalStore, usePageTitleStore } from '../stores';
|
||||
import DialogsContainer from './dialogs-container';
|
||||
import ToastsManager from './toasts-manager';
|
||||
import { HashRouter, useLocation, Route, Routes } from 'react-router-dom';
|
||||
import {
|
||||
HashRouter,
|
||||
useLocation,
|
||||
Route,
|
||||
Routes,
|
||||
useSearchParams,
|
||||
} from 'react-router-dom';
|
||||
import { Connectors } from '../lib/vega-connectors';
|
||||
import { Bootstrapper } from '../components/bootstrapper';
|
||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
||||
import { activeOrdersProvider } from '@vegaprotocol/orders';
|
||||
import { useTelemetryApproval } from '../lib/hooks/use-telemetry-approval';
|
||||
import { AnnouncementBanner } from '../components/banner';
|
||||
import { Navbar } from '../components/navbar';
|
||||
import classNames from 'classnames';
|
||||
@@ -29,9 +53,6 @@ import { NavHeader } from '../components/navbar/nav-header';
|
||||
import { Telemetry } from '../components/telemetry';
|
||||
import { Routes as AppRoutes } from '../lib/links';
|
||||
import { SSRLoader } from './ssr-loader';
|
||||
import { PartyActiveOrdersHandler } from './party-active-orders-handler';
|
||||
import { MaybeConnectEagerly } from './maybe-connect-eagerly';
|
||||
import { TransactionHandlers } from './transaction-handlers';
|
||||
|
||||
const DEFAULT_TITLE = t('Welcome to Vega trading!');
|
||||
|
||||
@@ -56,6 +77,15 @@ const Title = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const InitializeHandlers = () => {
|
||||
useVegaTransactionManager();
|
||||
useVegaTransactionUpdater();
|
||||
useEthTransactionManager();
|
||||
useEthTransactionUpdater();
|
||||
useEthWithdrawApprovalsManager();
|
||||
return null;
|
||||
};
|
||||
|
||||
function AppBody({ Component }: AppProps) {
|
||||
const location = useLocation();
|
||||
const { VEGA_ENV } = useEnvironment();
|
||||
@@ -95,9 +125,9 @@ function AppBody({ Component }: AppProps) {
|
||||
</div>
|
||||
<DialogsContainer />
|
||||
<ToastsManager />
|
||||
<TransactionHandlers />
|
||||
<InitializeHandlers />
|
||||
<MaybeConnectEagerly />
|
||||
<PartyActiveOrdersHandler />
|
||||
<PartyData />
|
||||
<Telemetry />
|
||||
</div>
|
||||
);
|
||||
@@ -110,14 +140,10 @@ function VegaTradingApp(props: AppProps) {
|
||||
store.setDialogOpen,
|
||||
]);
|
||||
|
||||
// Start validation of env vars and determine VEGA_URL
|
||||
useInitializeEnv();
|
||||
|
||||
// Prevent HashRouter from being server side rendered as it
|
||||
// relies on presence of document object
|
||||
//
|
||||
// This is the last point at which we get pregenerated
|
||||
// HTML so render a ssr friendly loader component
|
||||
if (status === 'default') {
|
||||
return <SSRLoader />;
|
||||
}
|
||||
@@ -133,3 +159,36 @@ function VegaTradingApp(props: AppProps) {
|
||||
}
|
||||
|
||||
export default VegaTradingApp;
|
||||
|
||||
const PartyData = () => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const variables = { partyId: pubKey || '' };
|
||||
const skip = !pubKey;
|
||||
useDataProvider({
|
||||
dataProvider: activeOrdersProvider,
|
||||
variables,
|
||||
skip,
|
||||
});
|
||||
return null;
|
||||
};
|
||||
|
||||
const MaybeConnectEagerly = () => {
|
||||
const { VEGA_ENV, SENTRY_DSN } = useEnvironment();
|
||||
const update = useGlobalStore((store) => store.update);
|
||||
const eagerConnecting = useVegaEagerConnect(Connectors);
|
||||
const [isTelemetryApproved] = useTelemetryApproval();
|
||||
useEthereumEagerConnect(
|
||||
isTelemetryApproved ? { dsn: SENTRY_DSN, env: VEGA_ENV } : {}
|
||||
);
|
||||
|
||||
const { pubKey, connect } = useVegaWallet();
|
||||
const [searchParams] = useSearchParams();
|
||||
const [query] = useState(searchParams.get('address'));
|
||||
if (query && !pubKey) {
|
||||
connect(Connectors['view']);
|
||||
}
|
||||
useEffect(() => {
|
||||
update({ eagerConnecting });
|
||||
}, [update, eagerConnecting]);
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { RouteObject } from 'react-router-dom';
|
||||
import { Navigate, useRoutes } from 'react-router-dom';
|
||||
import { Navigate, Outlet, useRoutes } from 'react-router-dom';
|
||||
import { lazy, Suspense } from 'react';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { Loader, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
@@ -13,7 +13,7 @@ import { Assets } from '../client-pages/assets';
|
||||
import { Deposit } from '../client-pages/deposit';
|
||||
import { Withdraw } from '../client-pages/withdraw';
|
||||
import { Transfer } from '../client-pages/transfer';
|
||||
import { Routes as AppRoutes } from '../lib/links';
|
||||
import { Routes } from '../lib/links';
|
||||
import { LayoutWithSky } from '../client-pages/referrals/layout';
|
||||
import { Referrals } from '../client-pages/referrals/referrals';
|
||||
import { ReferralStatistics } from '../client-pages/referrals/referral-statistics';
|
||||
@@ -22,15 +22,11 @@ import { CreateCodeContainer } from '../client-pages/referrals/create-code-form'
|
||||
import { NotFound as ReferralNotFound } from '../client-pages/referrals/error-boundary';
|
||||
import { compact } from 'lodash';
|
||||
import { FLAGS } from '@vegaprotocol/environment';
|
||||
import { LiquidityHeader } from '../components/liquidity-header';
|
||||
import { MarketHeader } from '../components/market-header';
|
||||
import { PortfolioSidebar } from '../client-pages/portfolio/portfolio-sidebar';
|
||||
import { LiquiditySidebar } from '../client-pages/liquidity/liquidity-sidebar';
|
||||
import { MarketsSidebar } from '../client-pages/markets/markets-sidebar';
|
||||
|
||||
// These must remain dynamically imported as pennant cannot be compiled by nextjs due to ESM
|
||||
// Using dynamic imports is a workaround for this until pennant is published as ESM
|
||||
const MarketPage = lazy(() => import('../client-pages/market'));
|
||||
const ClosedMarketPage = lazy(() => import('../client-pages/closed-market'));
|
||||
const Portfolio = lazy(() => import('../client-pages/portfolio'));
|
||||
|
||||
const NotFound = () => (
|
||||
@@ -40,21 +36,18 @@ const NotFound = () => (
|
||||
);
|
||||
|
||||
export const routerConfig: RouteObject[] = compact([
|
||||
{
|
||||
index: true,
|
||||
element: <Home />,
|
||||
id: AppRoutes.HOME,
|
||||
},
|
||||
// Pages that don't use the LayoutWithSidebar must come first
|
||||
// to ensure they are matched before the catch all route '/*'
|
||||
{
|
||||
path: 'disclaimer',
|
||||
element: <LayoutCentered />,
|
||||
id: AppRoutes.DISCLAIMER,
|
||||
id: Routes.DISCLAIMER,
|
||||
children: [{ index: true, element: <Disclaimer /> }],
|
||||
},
|
||||
// Referrals routing (the pages should be available if the feature flag is on)
|
||||
FLAGS.REFERRALS
|
||||
? {
|
||||
path: AppRoutes.REFERRALS,
|
||||
path: Routes.REFERRALS,
|
||||
element: <LayoutWithSky />,
|
||||
children: [
|
||||
{
|
||||
@@ -65,11 +58,11 @@ export const routerConfig: RouteObject[] = compact([
|
||||
element: <ReferralStatistics />,
|
||||
},
|
||||
{
|
||||
path: AppRoutes.REFERRALS_CREATE_CODE,
|
||||
path: Routes.REFERRALS_CREATE_CODE,
|
||||
element: <CreateCodeContainer />,
|
||||
},
|
||||
{
|
||||
path: AppRoutes.REFERRALS_APPLY_CODE,
|
||||
path: Routes.REFERRALS_APPLY_CODE,
|
||||
element: <ApplyCodeForm />,
|
||||
},
|
||||
],
|
||||
@@ -81,74 +74,75 @@ export const routerConfig: RouteObject[] = compact([
|
||||
],
|
||||
}
|
||||
: undefined,
|
||||
// All other pages will use the sidebar
|
||||
{
|
||||
path: 'markets/*',
|
||||
element: (
|
||||
<LayoutWithSidebar
|
||||
header={<MarketHeader />}
|
||||
sidebar={<MarketsSidebar />}
|
||||
/>
|
||||
),
|
||||
path: '/*',
|
||||
element: <LayoutWithSidebar />,
|
||||
children: [
|
||||
{
|
||||
index: true,
|
||||
element: <MarketsPage />,
|
||||
id: AppRoutes.MARKETS,
|
||||
element: <Home />,
|
||||
id: Routes.HOME,
|
||||
},
|
||||
{
|
||||
path: 'all',
|
||||
element: <Navigate to="/markets" />,
|
||||
},
|
||||
{
|
||||
path: ':marketId',
|
||||
element: <MarketPage />,
|
||||
id: AppRoutes.MARKET,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'portfolio/*',
|
||||
element: <LayoutWithSidebar sidebar={<PortfolioSidebar />} />,
|
||||
children: [
|
||||
{
|
||||
index: true,
|
||||
element: <Portfolio />,
|
||||
id: AppRoutes.PORTFOLIO,
|
||||
},
|
||||
{
|
||||
path: 'assets',
|
||||
element: <Assets />,
|
||||
id: AppRoutes.ASSETS,
|
||||
path: 'markets',
|
||||
element: <Outlet />,
|
||||
children: [
|
||||
{ index: true, element: <Navigate to="deposit" /> },
|
||||
{ path: 'deposit', element: <Deposit />, id: AppRoutes.DEPOSIT },
|
||||
{ path: 'withdraw', element: <Withdraw />, id: AppRoutes.WITHDRAW },
|
||||
{ path: 'transfer', element: <Transfer />, id: AppRoutes.TRANSFER },
|
||||
{
|
||||
index: true,
|
||||
element: <Navigate to="all" />,
|
||||
},
|
||||
{
|
||||
path: 'all',
|
||||
element: <MarketsPage />,
|
||||
id: Routes.MARKETS,
|
||||
},
|
||||
{
|
||||
path: ':marketId',
|
||||
element: <MarketPage />,
|
||||
id: Routes.MARKET,
|
||||
},
|
||||
{
|
||||
path: 'all/closed/:marketId',
|
||||
element: <ClosedMarketPage />,
|
||||
id: Routes.CLOSED_MARKETS,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
path: 'liquidity/*',
|
||||
element: (
|
||||
<LayoutWithSidebar
|
||||
header={<LiquidityHeader />}
|
||||
sidebar={<LiquiditySidebar />}
|
||||
/>
|
||||
),
|
||||
id: AppRoutes.LIQUIDITY,
|
||||
children: [
|
||||
{
|
||||
path: ':marketId',
|
||||
path: 'portfolio',
|
||||
element: <Outlet />,
|
||||
children: [
|
||||
{
|
||||
index: true,
|
||||
element: <Portfolio />,
|
||||
id: Routes.PORTFOLIO,
|
||||
},
|
||||
{
|
||||
path: 'assets',
|
||||
element: <Assets />,
|
||||
id: Routes.ASSETS,
|
||||
children: [
|
||||
{ index: true, element: <Navigate to="deposit" /> },
|
||||
{ path: 'deposit', element: <Deposit />, id: Routes.DEPOSIT },
|
||||
{ path: 'withdraw', element: <Withdraw />, id: Routes.WITHDRAW },
|
||||
{ path: 'transfer', element: <Transfer />, id: Routes.TRANSFER },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'liquidity/:marketId',
|
||||
element: <Liquidity />,
|
||||
id: Routes.LIQUIDITY,
|
||||
},
|
||||
// NotFound page is here so its caught within parent '/*' route
|
||||
{
|
||||
path: '*',
|
||||
element: <NotFound />,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '*',
|
||||
element: <NotFound />,
|
||||
},
|
||||
]);
|
||||
|
||||
export const ClientRouter = () => {
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useEnvironment } from '@vegaprotocol/environment';
|
||||
import { useEagerConnect as useEthereumEagerConnect } from '@vegaprotocol/web3';
|
||||
import {
|
||||
useEagerConnect as useVegaEagerConnect,
|
||||
useVegaWallet,
|
||||
} from '@vegaprotocol/wallet';
|
||||
import { useGlobalStore } from '../stores';
|
||||
import { Connectors } from '../lib/vega-connectors';
|
||||
import { useTelemetryApproval } from '../lib/hooks/use-telemetry-approval';
|
||||
|
||||
export const MaybeConnectEagerly = () => {
|
||||
const { VEGA_ENV, SENTRY_DSN } = useEnvironment();
|
||||
const update = useGlobalStore((store) => store.update);
|
||||
const eagerConnecting = useVegaEagerConnect(Connectors);
|
||||
const [isTelemetryApproved] = useTelemetryApproval();
|
||||
useEthereumEagerConnect(
|
||||
isTelemetryApproved ? { dsn: SENTRY_DSN, env: VEGA_ENV } : {}
|
||||
);
|
||||
|
||||
const { pubKey, connect } = useVegaWallet();
|
||||
const [searchParams] = useSearchParams();
|
||||
const [query] = useState(searchParams.get('address'));
|
||||
if (query && !pubKey) {
|
||||
connect(Connectors['view']);
|
||||
}
|
||||
useEffect(() => {
|
||||
update({ eagerConnecting });
|
||||
}, [update, eagerConnecting]);
|
||||
return null;
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
||||
import { activeOrdersProvider } from '@vegaprotocol/orders';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
|
||||
export const PartyActiveOrdersHandler = () => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const variables = { partyId: pubKey || '' };
|
||||
const skip = !pubKey;
|
||||
useDataProvider({
|
||||
dataProvider: activeOrdersProvider,
|
||||
variables,
|
||||
skip,
|
||||
});
|
||||
return null;
|
||||
};
|
||||
@@ -1,18 +0,0 @@
|
||||
import {
|
||||
useVegaTransactionManager,
|
||||
useVegaTransactionUpdater,
|
||||
} from '@vegaprotocol/web3';
|
||||
import {
|
||||
useEthTransactionManager,
|
||||
useEthTransactionUpdater,
|
||||
useEthWithdrawApprovalsManager,
|
||||
} from '@vegaprotocol/web3';
|
||||
|
||||
export const TransactionHandlers = () => {
|
||||
useVegaTransactionManager();
|
||||
useVegaTransactionUpdater();
|
||||
useEthTransactionManager();
|
||||
useEthTransactionUpdater();
|
||||
useEthWithdrawApprovalsManager();
|
||||
return null;
|
||||
};
|
||||
@@ -45,28 +45,6 @@ const secondRow = {
|
||||
} as AccountFields;
|
||||
const multiRowData = [singleRow, secondRow];
|
||||
|
||||
const zeroBalanceRow = {
|
||||
__typename: 'AccountBalance',
|
||||
type: Types.AccountType.ACCOUNT_TYPE_MARGIN,
|
||||
balance: '0',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: '10cd0a793ad2887b340940337fa6d97a212e0e517fe8e9eab2b5ef3a38633f35',
|
||||
},
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
||||
symbol: 'tBTC',
|
||||
decimals: 5,
|
||||
},
|
||||
available: '0',
|
||||
used: '0',
|
||||
total: '0',
|
||||
} as AccountFields;
|
||||
const zeroBalanceRowData = [zeroBalanceRow];
|
||||
|
||||
const onClickDepositMock = jest.fn();
|
||||
|
||||
describe('AccountsTable', () => {
|
||||
it('should render correct columns', async () => {
|
||||
// 7001-COLL-001
|
||||
@@ -93,27 +71,6 @@ describe('AccountsTable', () => {
|
||||
).toEqual(expectedHeaders);
|
||||
});
|
||||
|
||||
it('should render deposit button', async () => {
|
||||
render(
|
||||
<AccountTable
|
||||
rowData={zeroBalanceRowData}
|
||||
onClickAsset={() => null}
|
||||
isReadOnly={false}
|
||||
onClickDeposit={onClickDepositMock}
|
||||
pinnedAsset={{
|
||||
decimals: 5,
|
||||
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
||||
symbol: 'tBTC',
|
||||
name: 'tBTC',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
const depositButton = screen.getByTestId('deposit');
|
||||
expect(depositButton).toBeVisible();
|
||||
await userEvent.click(depositButton);
|
||||
expect(onClickDepositMock).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should apply correct formatting', async () => {
|
||||
const { container } = render(
|
||||
<AccountTable
|
||||
|
||||
@@ -4,10 +4,9 @@ import {
|
||||
} from '@vegaprotocol/data-provider';
|
||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
||||
import { AssetsDocument } from './__generated__/Assets';
|
||||
import { AssetStatus } from '@vegaprotocol/types';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { AssetsQuery } from './__generated__/Assets';
|
||||
import type { Asset } from './asset-data-provider';
|
||||
import { DENY_LIST } from './constants';
|
||||
|
||||
export interface BuiltinAssetSource {
|
||||
__typename: 'BuiltinAsset';
|
||||
@@ -49,7 +48,6 @@ export const assetsMapProvider = makeDerivedDataProvider<
|
||||
}
|
||||
);
|
||||
|
||||
/** Returns a record of assets by id */
|
||||
export const useAssetsMapProvider = () =>
|
||||
useDataProvider({
|
||||
dataProvider: assetsMapProvider,
|
||||
@@ -60,32 +58,13 @@ export const enabledAssetsProvider = makeDerivedDataProvider<
|
||||
ReturnType<typeof getData>,
|
||||
never
|
||||
>([assetsProvider], ([assets]) =>
|
||||
(assets as ReturnType<typeof getData>)
|
||||
.filter((a) => a.status === AssetStatus.STATUS_ENABLED)
|
||||
.filter((a) => {
|
||||
const env = process.env['NX_VEGA_ENV'];
|
||||
|
||||
if (!env || !DENY_LIST[env]) return true;
|
||||
|
||||
if (DENY_LIST[env].includes(a.id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
})
|
||||
(assets as ReturnType<typeof getData>).filter(
|
||||
(a) => a.status === Schema.AssetStatus.STATUS_ENABLED
|
||||
)
|
||||
);
|
||||
|
||||
/** Returns all assets */
|
||||
export const useAssetsDataProvider = () =>
|
||||
useDataProvider({
|
||||
dataProvider: assetsProvider,
|
||||
variables: undefined,
|
||||
});
|
||||
|
||||
/** Returns assets that are enabled and are not on the deny list */
|
||||
export const useEnabledAssets = () => {
|
||||
return useDataProvider({
|
||||
dataProvider: enabledAssetsProvider,
|
||||
variables: undefined,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,67 +1,4 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
|
||||
export const WITHDRAW_THRESHOLD_TOOLTIP_TEXT = t(
|
||||
"The maximum you can withdraw instantly. There's no limit on the size of a withdrawal, but all withdrawals over the threshold will have a delay time added to them"
|
||||
);
|
||||
|
||||
// List of defunct and no longer used assets that were created for various testnets
|
||||
export const DENY_LIST: Record<string, string[]> = {
|
||||
TESTNET: [
|
||||
'07f8ce4e3df6c649f3fd794112f545ede9fbd9cfa76a9e380a7502a8d525e4db',
|
||||
'0b87ac58d4af7fc11c8b417153fcb62631cfd9643835ef28db3f5a1caef0b379',
|
||||
'169fd651dd1303fc6f3e1dee8349439140cf467a190bc9a04bff3e617509cfd4',
|
||||
'16ae5dbb1fd7aa2ddef725703bfe66b3647a4da7b844bfdd04e985756f53d9d6',
|
||||
'177e8f6c25a955bd18475084b99b2b1d37f28f3dec393fab7755a7e69c3d8c3b',
|
||||
'20ffe5b1f70364a6b976007d96d306345bc7b880256ddffbbea2c590096ef375',
|
||||
'2792b6ead78a812bd0169b2adbe9c2ea5b8c21510e40b93bf8d2cba6a0838e90',
|
||||
'27c0229ab9edc6a3ba6a3e9716c1b324d6515a3168004256879e2de7c240f453',
|
||||
'285923fed8c66ffb416b163e8ec72d3a87b9b8e2570e7ee7fe97d7092a918bc8',
|
||||
'2af02165ef5ea1d1284b4251117eaae45faa961ec918e3f69b66903a18822387',
|
||||
'2bf406160d06280d92412605eb397d08142736f4e17967e404dc892da278e9da',
|
||||
'373d90d97bd3f97f0c13cf449926cfd7f1ed5f3746c3091e8dd894d60bf5eac8',
|
||||
'3c7d6bd83dac3174923ba65f3af01f42858e267ca5b722fe2b0b3fec14e98ec2',
|
||||
'434b502cabb7a9a36d3036a599d589537da293d8bbab224692629351a7926249',
|
||||
'43bb50d6ba0a871088014cb204079ace4811970ce3d52b15896f6e7a88f900b7',
|
||||
'46e9d23142762db57751b1b507e15747fe9478de504cbc4a0bffd828c39e3776',
|
||||
'4b6957c6a184b002db80c7a4dd811d0e70866be4a4c8fffa4894e78aa132b407',
|
||||
'4cbe1ad4cf232fb2232176e3f440f6e6fdc3ba7b1d95a99cb69116b9e379eae8',
|
||||
'4e4e80abff30cab933b8c4ac6befc618372eb76b2cbddc337eff0b4a3a4d25b8',
|
||||
'51eed0c17e3287996ba6006ce56de2591550ebfad46631f3a0129886967420e1',
|
||||
'522e09779d984ae77b60036f4ecd80f0491f5f0c8cc386a0712b78a020ab62e6',
|
||||
'5c950d4cfe1aaf9174c4358ee5df03f7e6bc556eac06a012cf6c07db154e20c4',
|
||||
'5d8eb4e4e385b85c5c11f47111f315d5d201e04f4ef5e294763bf51036974b91',
|
||||
'5dd5c226e944b4c3df3e8dbbbc473e72fb134f4c5b82a1968cc3cf7c1b40fe9e',
|
||||
'638b4dbe4f3ce5b81546bef29108e8374a7293012c6189ca00f287f8c62a98a5',
|
||||
'644c3a6e258382542a108c4dca16fae93657b6ff40238b2bb55854a125316052',
|
||||
'71ea74ef1aa7582bcdd4ef843b3e79584ded4d16e692f3946cac4c9d61aed4f2',
|
||||
'72f051ea66686ae004086f1ad086866f720f25896319abf3427cae101a58d985',
|
||||
'827bbacde0dd5bfec857933dbbf642147f2afe6a9db0a543839b1b5239ca6786',
|
||||
'83f4970aa1aeab85d01d8a976cbfd0fb3afedf391e18197e8c94c4021b3dffa1',
|
||||
'84a20b554854c9af10ef84d308795dfae455834d1a207798292d66e19fd72c92',
|
||||
'84fff099818dc4f5319477f0812b4341565cfb32ccf735beede734e386b8108f',
|
||||
'85771250f0aa84727a1c01ba8926e59217ca13a7706ba03cf2ad95abbbc2e3bc',
|
||||
'8a246b15bf185065d3f41a710f3eea0fbbe8754a8464501cf4a6d253d69c6423',
|
||||
'8e5553ee4e95db51523640d1d03b00c8ab31dd69d787e169b0d958ef52e19a0a',
|
||||
'92747340d922e9cda5bde17c46af8b409e47d6342f3b9c8fb058a34c6206d373',
|
||||
'9b43c6791aebed5f7b38d91907539173aa278de88294b6422f3dd8282cd2c6e2',
|
||||
'9e0bb9bd7ea2ec51efcdc98b432b6f0b055b2ed7973cfac9b44899d6e6c5deab',
|
||||
'a0cf0835cb5af7bd03c56d12d846eed81c182eab36ea61c074961c115da9c8c4',
|
||||
'a26dc4f6dea91e80d42e4736da7fe3c42f6275df9c4dca48be3ef96850192242',
|
||||
'a4c945aea50ef321eabf8a3bcf0b8bb74288452c4638876ee4df5fb59be4a0ec',
|
||||
'ae28c1043e79bdb95cae0e9919d4436157d14b183e24ab4572793812f3d89222',
|
||||
'b0cf8be4e4d1d2ac5156c2298aa42edc7a74d25b7838d06e2279e94018a47f3f',
|
||||
'b6d11705cb456768ff8271074dd8adcd78bd042a27fc205e9b52f9f945f42ea1',
|
||||
'be478570584211521890fb65a41bded4d2bf29beb0b61ac3cc3b97f828a27b22',
|
||||
'befde6d78ea1c996ae1d959342730220e274992097aeeae00c908a971314e6ae',
|
||||
'bf5b9464d154ffeff57f05f90b223c1045f0754befd01a9a42c99382115e7833',
|
||||
'd2239a7c92bc5c72a959a73ccee7727ba0966f4d88a33d71dbbc26e3f171555d',
|
||||
'd3f9cf6e1711595b4588366a96b725fc039f72a8a28b2e4c1b630016dd2eed39',
|
||||
'd9a9ab00bb79ce7dca7f6329ab627dcea2e53e5c16b85bf4aa8c3980b76fad57',
|
||||
'dd73f7d1e721ef5cba95f454a3019521456c1b43b97084ad29e3e6509148d45d',
|
||||
'eb30d55e90e1f9e5c4727d6fa2a5a8cd36ab9ae9738eb8f3faf53e2bee4861ee',
|
||||
'ede4076aef07fd79502d14326c54ab3911558371baaf697a19d077f4f89de399',
|
||||
'f481abe5700c6940ca996adfa9d07c9d9f07a486a7ce9cdb2e6ee0fa6450fe31',
|
||||
'f7355ec52730c2e6ba02216da8501b4b6934cd363511e9d47ae5b97056d02703',
|
||||
'fdf0ec118d98393a7702cf72e46fc87ad680b152f64b2aac59e093ac2d688fbb',
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
import { Networks, useEnvironment } from '@vegaprotocol/environment';
|
||||
import { AsyncRendererInline } from '@vegaprotocol/ui-toolkit';
|
||||
import { DepositManager } from './deposit-manager';
|
||||
import { useEnabledAssets } from '@vegaprotocol/assets';
|
||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
||||
import { enabledAssetsProvider } from '@vegaprotocol/assets';
|
||||
|
||||
/**
|
||||
* Fetches data required for the Deposit page
|
||||
*/
|
||||
export const DepositContainer = ({ assetId }: { assetId?: string }) => {
|
||||
const { VEGA_ENV } = useEnvironment();
|
||||
const { data, error, loading } = useEnabledAssets();
|
||||
const { data, loading, error } = useDataProvider({
|
||||
dataProvider: enabledAssetsProvider,
|
||||
variables: undefined,
|
||||
});
|
||||
|
||||
return (
|
||||
<AsyncRendererInline data={data} loading={loading} error={error}>
|
||||
|
||||
@@ -148,7 +148,7 @@ describe('Deposit form', () => {
|
||||
});
|
||||
|
||||
fireEvent.submit(screen.getByTestId('deposit-form'));
|
||||
// 1001-DEPO-004
|
||||
|
||||
expect(
|
||||
await screen.findByText(
|
||||
"You can't deposit more than you have in your Ethereum wallet, 5"
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { Button, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { useNodeSwitcherStore } from '../../hooks/use-node-switcher-store';
|
||||
|
||||
export const AppFailure = ({
|
||||
title,
|
||||
@@ -7,10 +9,16 @@ export const AppFailure = ({
|
||||
title: string;
|
||||
error?: string | null;
|
||||
}) => {
|
||||
const setNodeSwitcher = useNodeSwitcherStore((store) => store.setDialogOpen);
|
||||
return (
|
||||
<Splash>
|
||||
<p className="mb-4 text-xl">{title}</p>
|
||||
{error && <p className="mb-8 text-sm">{error}</p>}
|
||||
<div className="text-center">
|
||||
<p className="mb-4 text-xl">{title}</p>
|
||||
{error && <p className="mb-8 text-sm">{error}</p>}
|
||||
<Button onClick={() => setNodeSwitcher(true)}>
|
||||
{t('Change node')}
|
||||
</Button>
|
||||
</div>
|
||||
</Splash>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -4,5 +4,4 @@ export * from './network-loader';
|
||||
export * from './network-switcher';
|
||||
export * from './node-guard';
|
||||
export * from './node-switcher';
|
||||
export * from './node-failure';
|
||||
export * from './etherscan-link';
|
||||
|
||||
@@ -33,14 +33,15 @@ export function NetworkLoader({
|
||||
return undefined;
|
||||
}, [VEGA_URL, status, cache]);
|
||||
|
||||
const nonIdealWrapperClasses =
|
||||
'h-full min-h-screen flex items-center justify-center';
|
||||
|
||||
if (status === 'failed') {
|
||||
// eslint-disable-next-line react/jsx-no-useless-fragment
|
||||
return <>{failure}</>;
|
||||
return <div className={nonIdealWrapperClasses}>{failure}</div>;
|
||||
}
|
||||
|
||||
if (status === 'default' || status === 'pending' || !client) {
|
||||
// eslint-disable-next-line react/jsx-no-useless-fragment
|
||||
return <>{skeleton}</>;
|
||||
return <div className={nonIdealWrapperClasses}>{skeleton}</div>;
|
||||
}
|
||||
|
||||
return <ApolloProvider client={client}>{children}</ApolloProvider>;
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export { NodeFailure } from './node-failure';
|
||||
@@ -1,24 +0,0 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { Button, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { useNodeSwitcherStore } from '../../hooks/use-node-switcher-store';
|
||||
|
||||
export const NodeFailure = ({
|
||||
title,
|
||||
error,
|
||||
}: {
|
||||
title: string;
|
||||
error?: string | null;
|
||||
}) => {
|
||||
const setNodeSwitcher = useNodeSwitcherStore((store) => store.setDialogOpen);
|
||||
return (
|
||||
<Splash>
|
||||
<div className="text-center">
|
||||
<p className="mb-4 text-xl">{title}</p>
|
||||
{error && <p className="mb-8 text-sm">{error}</p>}
|
||||
<Button onClick={() => setNodeSwitcher(true)}>
|
||||
{t('Change node')}
|
||||
</Button>
|
||||
</div>
|
||||
</Splash>
|
||||
);
|
||||
};
|
||||
@@ -11,10 +11,11 @@ export const NodeGuard = ({
|
||||
skeleton: ReactNode;
|
||||
}) => {
|
||||
const { data, error, loading } = useNodeGuardQuery();
|
||||
const wrapperClasses =
|
||||
'h-full min-h-screen flex items-center justify-center text-black dark:text-white';
|
||||
|
||||
if (loading) {
|
||||
// eslint-disable-next-line
|
||||
return <>{skeleton}</>;
|
||||
return <div className={wrapperClasses}>{skeleton}</div>;
|
||||
}
|
||||
|
||||
// It is possible for nodes to have a functioning datanode, but not return
|
||||
@@ -22,10 +23,9 @@ export const NodeGuard = ({
|
||||
const netParamEdges = data?.networkParametersConnection.edges;
|
||||
|
||||
if (error || !netParamEdges || !netParamEdges.length) {
|
||||
// eslint-disable-next-line react/jsx-no-useless-fragment
|
||||
return <>{failure}</>;
|
||||
return <div className={wrapperClasses}>{failure}</div>;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react/jsx-no-useless-fragment
|
||||
// eslint-disable-next-line
|
||||
return <>{children}</>;
|
||||
};
|
||||
|
||||
@@ -338,6 +338,9 @@ function compileEnvVars() {
|
||||
'GITHUB_FEEDBACK_URL',
|
||||
process.env['NX_GITHUB_FEEDBACK_URL']
|
||||
),
|
||||
MAINTENANCE_PAGE: parseBoolean(
|
||||
windowOrDefault('MAINTENANCE_PAGE', process.env['NX_MAINTENANCE_PAGE'])
|
||||
),
|
||||
GIT_BRANCH: windowOrDefault(
|
||||
'GIT_COMMIT_BRANCH',
|
||||
process.env['GIT_COMMIT_BRANCH']
|
||||
@@ -521,6 +524,10 @@ function parseNetworks(value?: string) {
|
||||
return {};
|
||||
}
|
||||
|
||||
function parseBoolean(value?: string) {
|
||||
return ['true', '1', 'yes'].includes(value?.toLowerCase() || '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a fallback ethereum provider url for test purposes in some apps
|
||||
*/
|
||||
|
||||
@@ -50,6 +50,7 @@ export const envSchema = z
|
||||
message: 'The NX_ETHERSCAN_URL environment variable must be a valid url',
|
||||
}),
|
||||
HOSTED_WALLET_URL: z.optional(z.string()),
|
||||
MAINTENANCE_PAGE: z.optional(z.boolean()),
|
||||
ETH_LOCAL_PROVIDER_URL: z.optional(z.string()),
|
||||
ETH_WALLET_MNEMONIC: z.optional(z.string()),
|
||||
ANNOUNCEMENTS_CONFIG_URL: z.optional(z.string()),
|
||||
|
||||
@@ -6,12 +6,8 @@ fragment FundingPaymentFields on FundingPayment {
|
||||
timestamp
|
||||
}
|
||||
|
||||
query FundingPayments($partyId: ID!, $pagination: Pagination, $marketId: ID) {
|
||||
fundingPayments(
|
||||
partyId: $partyId
|
||||
pagination: $pagination
|
||||
marketId: $marketId
|
||||
) {
|
||||
query FundingPayments($partyId: ID!, $pagination: Pagination) {
|
||||
fundingPayments(partyId: $partyId, pagination: $pagination) {
|
||||
edges {
|
||||
node {
|
||||
...FundingPaymentFields
|
||||
|
||||
@@ -8,7 +8,6 @@ export type FundingPaymentFieldsFragment = { __typename?: 'FundingPayment', mark
|
||||
export type FundingPaymentsQueryVariables = Types.Exact<{
|
||||
partyId: Types.Scalars['ID'];
|
||||
pagination?: Types.InputMaybe<Types.Pagination>;
|
||||
marketId?: Types.InputMaybe<Types.Scalars['ID']>;
|
||||
}>;
|
||||
|
||||
|
||||
@@ -24,8 +23,8 @@ export const FundingPaymentFieldsFragmentDoc = gql`
|
||||
}
|
||||
`;
|
||||
export const FundingPaymentsDocument = gql`
|
||||
query FundingPayments($partyId: ID!, $pagination: Pagination, $marketId: ID) {
|
||||
fundingPayments(partyId: $partyId, pagination: $pagination, marketId: $marketId) {
|
||||
query FundingPayments($partyId: ID!, $pagination: Pagination) {
|
||||
fundingPayments(partyId: $partyId, pagination: $pagination) {
|
||||
edges {
|
||||
node {
|
||||
...FundingPaymentFields
|
||||
@@ -56,7 +55,6 @@ export const FundingPaymentsDocument = gql`
|
||||
* variables: {
|
||||
* partyId: // value for 'partyId'
|
||||
* pagination: // value for 'pagination'
|
||||
* marketId: // value for 'marketId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
|
||||
@@ -8,14 +8,12 @@ import { fundingPaymentsWithMarketProvider } from './funding-payments-data-provi
|
||||
|
||||
interface FundingPaymentsManagerProps {
|
||||
partyId: string;
|
||||
marketId?: string;
|
||||
onMarketClick?: (marketId: string, metaKey?: boolean) => void;
|
||||
gridProps: ReturnType<typeof useDataGridEvents>;
|
||||
}
|
||||
|
||||
export const FundingPaymentsManager = ({
|
||||
partyId,
|
||||
marketId,
|
||||
onMarketClick,
|
||||
gridProps,
|
||||
}: FundingPaymentsManagerProps) => {
|
||||
@@ -29,7 +27,7 @@ export const FundingPaymentsManager = ({
|
||||
}
|
||||
return false;
|
||||
},
|
||||
variables: { partyId, marketId },
|
||||
variables: { partyId },
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
@@ -128,26 +128,6 @@ export const NetworkParams = {
|
||||
'governance_proposal_VolumeDiscountProgram_requiredMajority',
|
||||
governance_proposal_VolumeDiscountProgram_requiredParticipation:
|
||||
'governance_proposal_VolumeDiscountProgram_requiredParticipation',
|
||||
governance_proposal_transfer_maxAmount:
|
||||
'governance_proposal_transfer_maxAmount',
|
||||
governance_proposal_transfer_maxClose:
|
||||
'governance_proposal_transfer_maxClose',
|
||||
governance_proposal_transfer_maxEnact:
|
||||
'governance_proposal_transfer_maxEnact',
|
||||
governance_proposal_transfer_maxFraction:
|
||||
'governance_proposal_transfer_maxFraction',
|
||||
governance_proposal_transfer_minClose:
|
||||
'governance_proposal_transfer_minClose',
|
||||
governance_proposal_transfer_minEnact:
|
||||
'governance_proposal_transfer_minEnact',
|
||||
governance_proposal_transfer_minProposerBalance:
|
||||
'governance_proposal_transfer_minProposerBalance',
|
||||
governance_proposal_transfer_minVoterBalance:
|
||||
'governance_proposal_transfer_minVoterBalance',
|
||||
governance_proposal_transfer_requiredMajority:
|
||||
'governance_proposal_transfer_requiredMajority',
|
||||
governance_proposal_transfer_requiredParticipation:
|
||||
'governance_proposal_transfer_requiredParticipation',
|
||||
validators_delegation_minAmount: 'validators_delegation_minAmount',
|
||||
spam_protection_minimumWithdrawalQuantumMultiple:
|
||||
'spam_protection_minimumWithdrawalQuantumMultiple',
|
||||
|
||||
@@ -104,13 +104,7 @@ describe('TradesTable', () => {
|
||||
const [firstDateCell, secondDateCell] = createdAtCells;
|
||||
|
||||
// Compare the times as strings
|
||||
// Note: I've changed it form literal strings to this because of the
|
||||
// locale mismatch. Mocking the format also resulted with strange "space" diff.
|
||||
expect(firstDateCell.textContent).toBe(
|
||||
getTimeFormat().format(new Date(trade2.createdAt))
|
||||
);
|
||||
expect(secondDateCell.textContent).toBe(
|
||||
getTimeFormat().format(new Date(trade.createdAt))
|
||||
);
|
||||
expect(firstDateCell.textContent).toBe('6:59:00 PM');
|
||||
expect(secondDateCell.textContent).toBe('7:00:00 PM');
|
||||
});
|
||||
});
|
||||
|
||||
Generated
+7
-20
@@ -4605,8 +4605,6 @@ export type QueryreferralFeeStatsArgs = {
|
||||
assetId?: InputMaybe<Scalars['ID']>;
|
||||
epoch?: InputMaybe<Scalars['Int']>;
|
||||
marketId?: InputMaybe<Scalars['ID']>;
|
||||
referee?: InputMaybe<Scalars['ID']>;
|
||||
referrer?: InputMaybe<Scalars['ID']>;
|
||||
};
|
||||
|
||||
|
||||
@@ -4622,9 +4620,9 @@ export type QueryreferralSetRefereesArgs = {
|
||||
/** Queries allow a caller to read data and filter data via GraphQL. */
|
||||
export type QueryreferralSetStatsArgs = {
|
||||
epoch?: InputMaybe<Scalars['Int']>;
|
||||
id: Scalars['ID'];
|
||||
pagination?: InputMaybe<Pagination>;
|
||||
partyId?: InputMaybe<Scalars['ID']>;
|
||||
setId?: InputMaybe<Scalars['ID']>;
|
||||
};
|
||||
|
||||
|
||||
@@ -4884,10 +4882,6 @@ export type ReferralSetStats = {
|
||||
referralSetRunningNotionalTakerVolume: Scalars['String'];
|
||||
/** Reward factor applied to the party. */
|
||||
rewardFactor: Scalars['String'];
|
||||
/** The proportion of the referees taker fees to be rewarded to the referrer. */
|
||||
rewardsFactorMultiplier: Scalars['String'];
|
||||
/** The multiplier applied to the referral reward factor when calculating referral rewards due to the referrer. */
|
||||
rewardsMultiplier: Scalars['String'];
|
||||
};
|
||||
|
||||
/** Connection type for retrieving cursor-based paginated referral set statistics information */
|
||||
@@ -6149,18 +6143,7 @@ export type UpdateProductConfiguration = UpdateFutureProduct | UpdatePerpetualPr
|
||||
|
||||
export type UpdateReferralProgram = {
|
||||
__typename?: 'UpdateReferralProgram';
|
||||
/** Defined tiers in increasing order. First element will give Tier 1, second element will give Tier 2, etc. */
|
||||
benefitTiers: Array<BenefitTier>;
|
||||
/** Timestamp as RFC3339, after which when the current epoch ends, the programs will end and benefits will be disabled. */
|
||||
endOfProgramTimestamp: Scalars['String'];
|
||||
/**
|
||||
* Defined staking tiers in increasing order. First element will give Tier 1,
|
||||
* second element will give Tier 2, and so on. Determines the level of
|
||||
* benefit a party can expect based on their staking.
|
||||
*/
|
||||
stakingTiers: Array<StakingTier>;
|
||||
/** Number of epochs over which to evaluate a referral set's running volume. */
|
||||
windowLength: Scalars['Int'];
|
||||
changes: ReferralProgram;
|
||||
};
|
||||
|
||||
/** Update an existing spot market on Vega */
|
||||
@@ -6192,7 +6175,11 @@ export type UpdateVolumeDiscountProgram = {
|
||||
benefitTiers: Array<VolumeBenefitTier>;
|
||||
/** The end time of the program */
|
||||
endOfProgramTimestamp: Scalars['Timestamp'];
|
||||
/** The window length to consider for the volume discount program */
|
||||
/** ID of the proposal that created the discount program */
|
||||
id: Scalars['ID'];
|
||||
/** The current version of the volume discount program */
|
||||
version: Scalars['Int'];
|
||||
/** The window legnth to consider for the volume discount program */
|
||||
windowLength: Scalars['Int'];
|
||||
};
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ export * from './key-value-table';
|
||||
export * from './link';
|
||||
export * from './loader';
|
||||
export * from './lozenge';
|
||||
export * from './maintenance-page';
|
||||
export * from './nav-dropdown';
|
||||
export * from './nav';
|
||||
export * from './navigation';
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from './maintenance-page';
|
||||
@@ -0,0 +1,11 @@
|
||||
import type { Story, Meta } from '@storybook/react';
|
||||
import { MaintenancePage } from './maintenance-page';
|
||||
|
||||
export default {
|
||||
component: MaintenancePage,
|
||||
title: 'Maintenance Page',
|
||||
} as Meta;
|
||||
|
||||
const Template: Story = (args) => <MaintenancePage />;
|
||||
|
||||
export const Default = Template.bind({});
|
||||
@@ -0,0 +1,224 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { ExternalLink } from '../link';
|
||||
import { BackgroundVideo } from '../background-video';
|
||||
|
||||
const BLOG_URL = 'https://blog.vega.xyz/';
|
||||
|
||||
export const MaintenancePage = () => {
|
||||
return (
|
||||
<div
|
||||
className="flex flex-col w-full min-h-full justify-center items-center dark:bg-black dark:text-white"
|
||||
data-testid="maintenance-page"
|
||||
>
|
||||
<div className="max-w-[540px] w-[80%]">
|
||||
<div className="pb-[24.6944444%] relative w-full mb-6">
|
||||
<div className="absolute inset-px">
|
||||
<BackgroundVideo />
|
||||
</div>
|
||||
<div className="absolute w-full h-full">
|
||||
<svg
|
||||
viewBox="0 0 1080 266.7"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="absolute left-0 right-0 block w-full h-auto"
|
||||
>
|
||||
<path
|
||||
className="dark:fill-black fill-white"
|
||||
d="M0,0v265.7h93c73.7-25.9,101.2-167.1,190.5-176.5c55-5.8,71.3,43.1,150.2,46c145.6,5.4,162.8-114.5,276.1-121.6 c146.7-9.2,199.8,222.9,274.4,252.1h95.8V0H0z"
|
||||
></path>
|
||||
<g className="dark:fill-white fill-black">
|
||||
<path d="M992.6,129.3H990v2.6h2.6V129.3z"></path>
|
||||
<path d="M995.2,126.7h-2.6v2.6h2.6V126.7z"></path>
|
||||
<path d="M995.2,131.9h-2.6v2.6h2.6V131.9z"></path>
|
||||
<path d="M997.9,129.3h-2.6v2.6h2.6V129.3z"></path>
|
||||
<path d="M574.6,5.3H572v2.6h2.6V5.3z"></path>
|
||||
<path d="M577.2,2.7h-2.6v2.6h2.6V2.7z"></path>
|
||||
<path d="M577.2,7.9h-2.6v2.6h2.6V7.9z"></path>
|
||||
<path d="M579.9,5.3h-2.6v2.6h2.6V5.3z"></path>
|
||||
<path d="M384,53.7h-3v3h3V53.7z"></path>
|
||||
<path d="M387,50.7v-3h-3v3v3h3V50.7z"></path>
|
||||
<path d="M381,56.7h-6v3h6V56.7z"></path>
|
||||
<path d="M384,59.7h-3v3h3V59.7z"></path>
|
||||
<path d="M387,62.7h-3v6h3V62.7z"></path>
|
||||
<path d="M390,59.7h-3v3h3V59.7z"></path>
|
||||
<path d="M395.9,56.7h-6v3h6V56.7z"></path>
|
||||
<path d="M390,53.7h-3v3h3V53.7z"></path>
|
||||
<path d="M130,158.7h-3v3h3V158.7z"></path>
|
||||
<path d="M133,155.7v-3h-3v3v3h3V155.7z"></path>
|
||||
<path d="M127,161.7h-6v3h6V161.7z"></path>
|
||||
<path d="M130,164.7h-3v3h3V164.7z"></path>
|
||||
<path d="M133,167.7h-3v6h3V167.7z"></path>
|
||||
<path d="M136,164.7h-3v3h3V164.7z"></path>
|
||||
<path d="M141.9,161.7h-6v3h6V161.7z"></path>
|
||||
<path d="M136,158.7h-3v3h3V158.7z"></path>
|
||||
<path d="M751.6,55.3H749v2.6h2.6V55.3z"></path>
|
||||
<path d="M754.2,52.7h-2.6v2.6h2.6V52.7z"></path>
|
||||
<path d="M754.2,57.9h-2.6v2.6h2.6V57.9z"></path>
|
||||
<path d="M756.9,55.3h-2.6v2.6h2.6V55.3z"></path>
|
||||
<path d="M720,85.7h-3v3h3V85.7z"></path>
|
||||
<path d="M723,82.7v-3h-3v3v3h3V82.7z"></path>
|
||||
<path d="M717,88.7h-6v3h6V88.7z"></path>
|
||||
<path d="M720,91.7h-3v3h3V91.7z"></path>
|
||||
<path d="M723,94.7h-3v6h3V94.7z"></path>
|
||||
<path d="M726,91.7h-3v3h3V91.7z"></path>
|
||||
<path d="M731.9,88.7h-6v3h6V88.7z"></path>
|
||||
<path d="M726,85.7h-3v3h3V85.7z"></path>
|
||||
<polyline points="0,266.7 1080,266.7 1080,264.7 0,264.7"></polyline>
|
||||
</g>
|
||||
<svg
|
||||
width="64"
|
||||
height="68"
|
||||
viewBox="0 0 32 34"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
x="301"
|
||||
y="200"
|
||||
>
|
||||
<g className="dark:fill-white fill-black animate-rotate">
|
||||
<path d="M28.6963 19.8359C28.9074 18.9106 29.0218 17.9742 29.0218 17C29.0218 16.0258 28.9074 15.0738 28.6963 14.1475C28.5949 13.7212 28.8023 13.2405 29.1846 13.0196L32 11.4248L28.8749 6.05954L26.0595 7.6543C25.6809 7.8716 25.1629 7.81635 24.8392 7.52539C23.4338 6.24001 21.7345 5.26493 19.8585 4.68945C19.4381 4.55963 19.1256 4.1416 19.1256 3.70608V0.5H12.8753V3.70608C12.8753 4.1416 12.5628 4.55963 12.1424 4.68945C10.2655 5.26493 8.56713 6.24001 7.16175 7.52539C6.83808 7.81635 6.32001 7.87068 5.94146 7.6543L3.12606 6.05954L0 11.4248L2.8154 13.0196C3.19767 13.2405 3.40509 13.7212 3.30371 14.1475C3.09257 15.0729 2.97817 16.0258 2.97817 17C2.97817 17.9742 3.09257 18.9106 3.30371 19.8359C3.40509 20.2623 3.19767 20.7429 2.8154 20.9639L0 22.5586L3.12513 27.9239L5.94053 26.3291C6.3228 26.1164 6.84087 26.1781 7.16082 26.4737C8.5662 27.7591 10.2655 28.7185 12.1415 29.2931C12.5665 29.4247 12.88 29.851 12.8744 30.2921V33.4982H19.1247V30.2921C19.1182 29.851 19.4316 29.4238 19.8576 29.2931C21.7345 28.7176 23.4329 27.7591 24.8382 26.4737C25.1591 26.1781 25.6772 26.1164 26.0585 26.3291L28.8739 27.9239L31.9991 22.5586L29.1837 20.9639C28.8014 20.7429 28.594 20.2623 28.6954 19.8359H28.6963ZM16.0005 23.7031C12.2485 23.7031 9.22936 20.7143 9.22936 17C9.22936 13.2857 12.2485 10.2969 16.0005 10.2969C19.7525 10.2969 22.7716 13.2857 22.7716 17C22.7716 20.7143 19.7525 23.7031 16.0005 23.7031Z" />
|
||||
</g>
|
||||
</svg>
|
||||
<svg
|
||||
width="64"
|
||||
height="68"
|
||||
viewBox="0 0 32 34"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
x="521"
|
||||
y="200"
|
||||
>
|
||||
<g className="dark:fill-white fill-black animate-rotate">
|
||||
<path d="M28.6963 19.8359C28.9074 18.9106 29.0218 17.9742 29.0218 17C29.0218 16.0258 28.9074 15.0738 28.6963 14.1475C28.5949 13.7212 28.8023 13.2405 29.1846 13.0196L32 11.4248L28.8749 6.05954L26.0595 7.6543C25.6809 7.8716 25.1629 7.81635 24.8392 7.52539C23.4338 6.24001 21.7345 5.26493 19.8585 4.68945C19.4381 4.55963 19.1256 4.1416 19.1256 3.70608V0.5H12.8753V3.70608C12.8753 4.1416 12.5628 4.55963 12.1424 4.68945C10.2655 5.26493 8.56713 6.24001 7.16175 7.52539C6.83808 7.81635 6.32001 7.87068 5.94146 7.6543L3.12606 6.05954L0 11.4248L2.8154 13.0196C3.19767 13.2405 3.40509 13.7212 3.30371 14.1475C3.09257 15.0729 2.97817 16.0258 2.97817 17C2.97817 17.9742 3.09257 18.9106 3.30371 19.8359C3.40509 20.2623 3.19767 20.7429 2.8154 20.9639L0 22.5586L3.12513 27.9239L5.94053 26.3291C6.3228 26.1164 6.84087 26.1781 7.16082 26.4737C8.5662 27.7591 10.2655 28.7185 12.1415 29.2931C12.5665 29.4247 12.88 29.851 12.8744 30.2921V33.4982H19.1247V30.2921C19.1182 29.851 19.4316 29.4238 19.8576 29.2931C21.7345 28.7176 23.4329 27.7591 24.8382 26.4737C25.1591 26.1781 25.6772 26.1164 26.0585 26.3291L28.8739 27.9239L31.9991 22.5586L29.1837 20.9639C28.8014 20.7429 28.594 20.2623 28.6954 19.8359H28.6963ZM16.0005 23.7031C12.2485 23.7031 9.22936 20.7143 9.22936 17C9.22936 13.2857 12.2485 10.2969 16.0005 10.2969C19.7525 10.2969 22.7716 13.2857 22.7716 17C22.7716 20.7143 19.7525 23.7031 16.0005 23.7031Z" />
|
||||
</g>
|
||||
</svg>
|
||||
<svg
|
||||
width="64"
|
||||
height="68"
|
||||
viewBox="0 0 32 34"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
x="381"
|
||||
y="200"
|
||||
>
|
||||
<g className="dark:fill-white fill-black animate-rotate-back">
|
||||
<path d="M28.6963 19.8359C28.9074 18.9106 29.0218 17.9742 29.0218 17C29.0218 16.0258 28.9074 15.0738 28.6963 14.1475C28.5949 13.7212 28.8023 13.2405 29.1846 13.0196L32 11.4248L28.8749 6.05954L26.0595 7.6543C25.6809 7.8716 25.1629 7.81635 24.8392 7.52539C23.4338 6.24001 21.7345 5.26493 19.8585 4.68945C19.4381 4.55963 19.1256 4.1416 19.1256 3.70608V0.5H12.8753V3.70608C12.8753 4.1416 12.5628 4.55963 12.1424 4.68945C10.2655 5.26493 8.56713 6.24001 7.16175 7.52539C6.83808 7.81635 6.32001 7.87068 5.94146 7.6543L3.12606 6.05954L0 11.4248L2.8154 13.0196C3.19767 13.2405 3.40509 13.7212 3.30371 14.1475C3.09257 15.0729 2.97817 16.0258 2.97817 17C2.97817 17.9742 3.09257 18.9106 3.30371 19.8359C3.40509 20.2623 3.19767 20.7429 2.8154 20.9639L0 22.5586L3.12513 27.9239L5.94053 26.3291C6.3228 26.1164 6.84087 26.1781 7.16082 26.4737C8.5662 27.7591 10.2655 28.7185 12.1415 29.2931C12.5665 29.4247 12.88 29.851 12.8744 30.2921V33.4982H19.1247V30.2921C19.1182 29.851 19.4316 29.4238 19.8576 29.2931C21.7345 28.7176 23.4329 27.7591 24.8382 26.4737C25.1591 26.1781 25.6772 26.1164 26.0585 26.3291L28.8739 27.9239L31.9991 22.5586L29.1837 20.9639C28.8014 20.7429 28.594 20.2623 28.6954 19.8359H28.6963ZM16.0005 23.7031C12.2485 23.7031 9.22936 20.7143 9.22936 17C9.22936 13.2857 12.2485 10.2969 16.0005 10.2969C19.7525 10.2969 22.7716 13.2857 22.7716 17C22.7716 20.7143 19.7525 23.7031 16.0005 23.7031Z" />
|
||||
</g>
|
||||
</svg>
|
||||
<svg
|
||||
width="64"
|
||||
height="68"
|
||||
viewBox="0 0 32 34"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
x="721"
|
||||
y="200"
|
||||
>
|
||||
<g className="dark:fill-white fill-black animate-rotate-back">
|
||||
<path d="M28.6963 19.8359C28.9074 18.9106 29.0218 17.9742 29.0218 17C29.0218 16.0258 28.9074 15.0738 28.6963 14.1475C28.5949 13.7212 28.8023 13.2405 29.1846 13.0196L32 11.4248L28.8749 6.05954L26.0595 7.6543C25.6809 7.8716 25.1629 7.81635 24.8392 7.52539C23.4338 6.24001 21.7345 5.26493 19.8585 4.68945C19.4381 4.55963 19.1256 4.1416 19.1256 3.70608V0.5H12.8753V3.70608C12.8753 4.1416 12.5628 4.55963 12.1424 4.68945C10.2655 5.26493 8.56713 6.24001 7.16175 7.52539C6.83808 7.81635 6.32001 7.87068 5.94146 7.6543L3.12606 6.05954L0 11.4248L2.8154 13.0196C3.19767 13.2405 3.40509 13.7212 3.30371 14.1475C3.09257 15.0729 2.97817 16.0258 2.97817 17C2.97817 17.9742 3.09257 18.9106 3.30371 19.8359C3.40509 20.2623 3.19767 20.7429 2.8154 20.9639L0 22.5586L3.12513 27.9239L5.94053 26.3291C6.3228 26.1164 6.84087 26.1781 7.16082 26.4737C8.5662 27.7591 10.2655 28.7185 12.1415 29.2931C12.5665 29.4247 12.88 29.851 12.8744 30.2921V33.4982H19.1247V30.2921C19.1182 29.851 19.4316 29.4238 19.8576 29.2931C21.7345 28.7176 23.4329 27.7591 24.8382 26.4737C25.1591 26.1781 25.6772 26.1164 26.0585 26.3291L28.8739 27.9239L31.9991 22.5586L29.1837 20.9639C28.8014 20.7429 28.594 20.2623 28.6954 19.8359H28.6963ZM16.0005 23.7031C12.2485 23.7031 9.22936 20.7143 9.22936 17C9.22936 13.2857 12.2485 10.2969 16.0005 10.2969C19.7525 10.2969 22.7716 13.2857 22.7716 17C22.7716 20.7143 19.7525 23.7031 16.0005 23.7031Z" />
|
||||
</g>
|
||||
</svg>
|
||||
<svg
|
||||
x="580"
|
||||
y="32"
|
||||
width="146"
|
||||
height="247"
|
||||
viewBox="0 0 56 85"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g>
|
||||
<path d="M19 60.5H17V84.5H19V60.5Z" fill="black" />
|
||||
<path d="M41 0.5H3V60.5H41V0.5Z" fill="white" />
|
||||
<path d="M15 18.5H13V20.5H15V18.5Z" fill="black" />
|
||||
<path d="M17 20.5H15V22.5H17V20.5Z" fill="black" />
|
||||
<path d="M19 18.5H17V20.5H19V18.5Z" fill="black" />
|
||||
<path d="M15 22.5H13V24.5H15V22.5Z" fill="black" />
|
||||
<path d="M19 22.5H17V24.5H19V22.5Z" fill="black" />
|
||||
<path d="M29 28.5H15V30.5H29V28.5Z" fill="black" />
|
||||
<path d="M27 18.5H25V20.5H27V18.5Z" fill="black" />
|
||||
<path d="M29 20.5H27V22.5H29V20.5Z" fill="black" />
|
||||
<path d="M31 18.5H29V20.5H31V18.5Z" fill="black" />
|
||||
<path d="M27 22.5H25V24.5H27V22.5Z" fill="black" />
|
||||
<path d="M31 22.5H29V24.5H31V22.5Z" fill="black" />
|
||||
<path d="M31 26.5H29V28.5H31V26.5Z" fill="black" />
|
||||
<path d="M27 60.5H25V62.5H27V60.5Z" fill="black" />
|
||||
<path d="M27 60.5H25V84.5H27V60.5Z" fill="black" />
|
||||
<path d="M19 60.5H17V84.5H19V60.5Z" fill="black" />
|
||||
<path d="M27 60.5H25V62.5H27V60.5Z" fill="black" />
|
||||
<path d="M27 60.5H25V84.5H27V60.5Z" fill="black" />
|
||||
<path d="M27 60.5H25V62.5H27V60.5Z" fill="black" />
|
||||
<path
|
||||
d="M3 42.5V58.64V60.5V64.5H21V60.5H23V64.5H41V60.5V58.64V42.5H3Z"
|
||||
fill="#00F780"
|
||||
/>
|
||||
<path d="M35 46.5H41V42.5H3V46.5H31H35Z" fill="#00D16C" />
|
||||
<path
|
||||
d="M3 32.32V29.5L0 32.5V60.5H2V33.33L3 32.32Z"
|
||||
fill="black"
|
||||
/>
|
||||
<path
|
||||
d="M41 31.8V29.49L54.79 21.53L55.79 23.26L41 31.8Z"
|
||||
fill="black"
|
||||
/>
|
||||
<path d="M36 54.5H35V55.5H36V54.5Z" fill="black" />
|
||||
<path d="M35 53.5H34V54.5H35V53.5Z" fill="black" />
|
||||
<path d="M34 48.5H33V53.5H34V48.5Z" fill="black" />
|
||||
<path d="M38 48.5H37V52.5H38V48.5Z" fill="black" />
|
||||
<path d="M37 53.5H36V54.5H37V53.5Z" fill="black" />
|
||||
<path d="M39 52.5H38V53.5H39V52.5Z" fill="black" />
|
||||
</g>
|
||||
</svg>
|
||||
<svg
|
||||
x="699"
|
||||
y="61"
|
||||
width="29"
|
||||
height="44"
|
||||
viewBox="0 0 11 17"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
style={{ transformOrigin: 'bottom right' }}
|
||||
className="animate-wave"
|
||||
d="M10.79 16.27L8.05998 15.54L0.0999756 1.75L1.82998 0.75L10.79 16.27Z"
|
||||
fill="black"
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
x="639"
|
||||
y="28"
|
||||
width="109"
|
||||
height="65"
|
||||
viewBox="0 0 42 25"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g
|
||||
style={{ transformOrigin: '50px 29px' }}
|
||||
className="animate-wave"
|
||||
>
|
||||
<path
|
||||
transform="translate(6, 4) scale(0.8)"
|
||||
d="M9.19758 10.4284L30.461 19.6961C30.7275 21.4423 31.8514 23.0054 33.5831 23.7591C36.2712 24.9284 39.4029 23.7006 40.5721 21.0125C41.7414 18.3245 40.5136 15.1928 37.8256 14.0235C36.0939 13.2697 34.1773 13.5089 32.7222 14.5012L11.4589 5.23339C11.1923 3.48724 10.0684 1.92415 8.33672 1.17039C6.21236 0.242586 3.8207 0.809016 2.3249 2.41195L7.84213 4.81833L6.43125 8.06016L0.914027 5.65377C0.757196 7.83641 1.9699 9.97822 4.08426 10.9062C5.81592 11.6599 7.7325 11.4208 9.18758 10.4285L9.19758 10.4284ZM33.1119 17.7656L35.3963 16.0607L37.9937 17.1913L38.2969 20.027L36.0126 21.732L33.4151 20.6013L33.1119 17.7656Z"
|
||||
fill="#A6A6A6"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex mb-2">
|
||||
<span className="font-alpha calt uppercase text-xl text-center">
|
||||
{t("We're doing some maintenance right now, check back later")}
|
||||
</span>
|
||||
</div>
|
||||
<p>
|
||||
<span className="text-neutral-500 dark:text-neutral-400">
|
||||
{t('Learn more on')}
|
||||
</span>{' '}
|
||||
<ExternalLink href={BLOG_URL}>{t('our blog')}</ExternalLink>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -41,7 +41,7 @@ const ethereumRequest = <T>(args: RequestArguments): Promise<T> => {
|
||||
|
||||
export const LOCAL_SNAP_ID = 'local:http://localhost:8080';
|
||||
export const DEFAULT_SNAP_ID = 'npm:@vegaprotocol/snap';
|
||||
export const DEFAULT_SNAP_VERSION = '0.3.1';
|
||||
export const DEFAULT_SNAP_VERSION = '0.2.0';
|
||||
|
||||
type GetSnapsResponse = Record<string, Snap>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user