Compare commits
13
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1874095222 | ||
|
|
e459e92127 | ||
|
|
4dd65b4923 | ||
|
|
5d792d2458 | ||
|
|
59b2f75b13 | ||
|
|
95775679ca | ||
|
|
4cffee29f8 | ||
|
|
bd70b0c233 | ||
|
|
145792f216 | ||
|
|
10add7c236 | ||
|
|
362a2031c7 | ||
|
|
5aaeb87059 | ||
|
|
d240dddab5 |
@@ -54,7 +54,7 @@ const Block = () => {
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
{blockData && (
|
||||
{blockData && 'result' in blockData && (
|
||||
<>
|
||||
<TableWithTbody className="mb-8">
|
||||
<TableRow modifier="bordered">
|
||||
|
||||
@@ -32,7 +32,7 @@ CYPRESS_FAIRGROUND=false
|
||||
|
||||
# Cosmic elevator flags
|
||||
NX_SUCCESSOR_MARKETS=true
|
||||
NX_METAMASK_SNAPS=false
|
||||
NX_METAMASK_SNAPS=true
|
||||
NX_PRODUCT_PERPETUALS=true
|
||||
NX_UPDATE_MARKET_STATE=true
|
||||
NX_REFERRALS=true
|
||||
|
||||
@@ -23,7 +23,7 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
|
||||
|
||||
# Cosmic elevator flags
|
||||
NX_SUCCESSOR_MARKETS=true
|
||||
NX_METAMASK_SNAPS=false
|
||||
NX_METAMASK_SNAPS=true
|
||||
NX_PRODUCT_PERPETUALS=true
|
||||
NX_UPDATE_MARKET_STATE=true
|
||||
NX_REFERRALS=true
|
||||
|
||||
@@ -22,7 +22,7 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://be.mainnet-mirror.vega.rocks/websocket
|
||||
|
||||
# Cosmic elevator flags
|
||||
NX_SUCCESSOR_MARKETS=true
|
||||
NX_METAMASK_SNAPS=false
|
||||
NX_METAMASK_SNAPS=true
|
||||
NX_PRODUCT_PERPETUALS=true
|
||||
NX_UPDATE_MARKET_STATE=true
|
||||
NX_REFERRALS=true
|
||||
|
||||
@@ -21,7 +21,7 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.
|
||||
|
||||
# Cosmic elevator flags
|
||||
NX_SUCCESSOR_MARKETS=true
|
||||
NX_METAMASK_SNAPS=false
|
||||
NX_METAMASK_SNAPS=true
|
||||
NX_PRODUCT_PERPETUALS=true
|
||||
NX_UPDATE_MARKET_STATE=true
|
||||
NX_REFERRALS=true
|
||||
|
||||
+2
-2
@@ -281,8 +281,8 @@ describe('VoteBreakdown', () => {
|
||||
});
|
||||
|
||||
it('Progress bar displays status - LP majority', () => {
|
||||
const yesVotesLP = 800;
|
||||
const noVotesLP = 200;
|
||||
const yesVotesLP = 0.8;
|
||||
const noVotesLP = 0.2;
|
||||
const expectedProgress = (yesVotesLP / (yesVotesLP + noVotesLP)) * 100; // 80%
|
||||
|
||||
renderComponent(
|
||||
|
||||
@@ -105,8 +105,6 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
|
||||
yesLPPercentage,
|
||||
yesTokens,
|
||||
noTokens,
|
||||
yesEquityLikeShareWeight,
|
||||
noEquityLikeShareWeight,
|
||||
totalEquityLikeShareWeight,
|
||||
requiredMajorityPercentage,
|
||||
requiredMajorityLPPercentage,
|
||||
@@ -135,6 +133,7 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
|
||||
.multipliedBy(100),
|
||||
new BigNumber(100)
|
||||
);
|
||||
|
||||
const willPass = willPassByTokenVote || willPassByLPVote;
|
||||
const updateMarketVotePassMethod = willPassByTokenVote
|
||||
? t('byTokenVote')
|
||||
@@ -202,50 +201,24 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
|
||||
<div className="flex items-center gap-1">
|
||||
<span>{t('liquidityProviderVotesFor')}:</span>
|
||||
<Tooltip
|
||||
description={formatNumber(
|
||||
yesEquityLikeShareWeight,
|
||||
defaultDP
|
||||
)}
|
||||
description={
|
||||
<span>{yesLPPercentage.toFixed(defaultDP)}%</span>
|
||||
}
|
||||
>
|
||||
<button>
|
||||
<CompactVotes number={yesEquityLikeShareWeight} />
|
||||
</button>
|
||||
<button>{yesLPPercentage.toFixed(1)}%</button>
|
||||
</Tooltip>
|
||||
<span>
|
||||
(
|
||||
<Tooltip
|
||||
description={
|
||||
<span>{yesLPPercentage.toFixed(defaultDP)}%</span>
|
||||
}
|
||||
>
|
||||
<button>{yesLPPercentage.toFixed(0)}%</button>
|
||||
</Tooltip>
|
||||
)
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-1">
|
||||
<span>{t('liquidityProviderVotesAgainst')}:</span>
|
||||
<Tooltip
|
||||
description={formatNumber(
|
||||
noEquityLikeShareWeight,
|
||||
defaultDP
|
||||
)}
|
||||
>
|
||||
<button>
|
||||
<CompactVotes number={noEquityLikeShareWeight} />
|
||||
</button>
|
||||
</Tooltip>
|
||||
<span>
|
||||
(
|
||||
<Tooltip
|
||||
description={
|
||||
<span>{noLPPercentage.toFixed(defaultDP)}%</span>
|
||||
}
|
||||
>
|
||||
<button>{noLPPercentage.toFixed(0)}%</button>
|
||||
<button>{noLPPercentage.toFixed(1)}%</button>
|
||||
</Tooltip>
|
||||
)
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -282,13 +255,8 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
|
||||
defaultDP
|
||||
)}
|
||||
>
|
||||
<button>
|
||||
<CompactVotes number={totalEquityLikeShareWeight} />
|
||||
</button>
|
||||
<span>{totalEquityLikeShareWeight.toFixed(1)}%</span>
|
||||
</Tooltip>
|
||||
<span>
|
||||
({totalEquityLikeShareWeight.toFixed(defaultDP)}%)
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -54,8 +54,8 @@ describe('use-vote-information', () => {
|
||||
it('returns all required vote information', () => {
|
||||
const yesVotes = 40;
|
||||
const noVotes = 60;
|
||||
const yesEquityLikeShareWeight = '30';
|
||||
const noEquityLikeShareWeight = '70';
|
||||
const yesEquityLikeShareWeight = '0.30';
|
||||
const noEquityLikeShareWeight = '0.70';
|
||||
// Note - giving a fixedTokenValue of 1 means a ratio of 1:1 votes to tokens, making sums easier :)
|
||||
const fixedTokenValue = 1000000000000000000;
|
||||
|
||||
@@ -195,10 +195,10 @@ describe('use-vote-information', () => {
|
||||
});
|
||||
|
||||
it('correctly shows whether an update market proposal will pass by token or LP vote - both failing', () => {
|
||||
const yesVotes = 20;
|
||||
const noVotes = 70;
|
||||
const yesEquityLikeShareWeight = '30';
|
||||
const noEquityLikeShareWeight = '60';
|
||||
const yesVotes = 0.2;
|
||||
const noVotes = 0.7;
|
||||
const yesEquityLikeShareWeight = '0.30';
|
||||
const noEquityLikeShareWeight = '0.60';
|
||||
const fixedTokenValue = 1000000000000000000;
|
||||
|
||||
const proposal = generateProposal({
|
||||
|
||||
@@ -61,7 +61,7 @@ export const useVoteInformation = ({
|
||||
const noEquityLikeShareWeight = !proposal?.votes.no
|
||||
.totalEquityLikeShareWeight
|
||||
? new BigNumber(0)
|
||||
: new BigNumber(proposal.votes.no.totalEquityLikeShareWeight);
|
||||
: new BigNumber(proposal.votes.no.totalEquityLikeShareWeight).times(100);
|
||||
|
||||
const yesTokens = new BigNumber(
|
||||
addDecimal(proposal?.votes.yes.totalTokens ?? 0, decimals)
|
||||
@@ -70,7 +70,7 @@ export const useVoteInformation = ({
|
||||
const yesEquityLikeShareWeight = !proposal?.votes.yes
|
||||
.totalEquityLikeShareWeight
|
||||
? new BigNumber(0)
|
||||
: new BigNumber(proposal.votes.yes.totalEquityLikeShareWeight);
|
||||
: new BigNumber(proposal.votes.yes.totalEquityLikeShareWeight).times(100);
|
||||
|
||||
const totalTokensVoted = yesTokens.plus(noTokens);
|
||||
|
||||
@@ -81,12 +81,7 @@ export const useVoteInformation = ({
|
||||
const yesPercentage = totalTokensVoted.isZero()
|
||||
? new BigNumber(0)
|
||||
: yesTokens.multipliedBy(100).dividedBy(totalTokensVoted);
|
||||
|
||||
const yesLPPercentage = totalEquityLikeShareWeight.isZero()
|
||||
? new BigNumber(0)
|
||||
: yesEquityLikeShareWeight
|
||||
.multipliedBy(100)
|
||||
.dividedBy(totalEquityLikeShareWeight);
|
||||
const yesLPPercentage = yesEquityLikeShareWeight;
|
||||
|
||||
const noPercentage = totalTokensVoted.isZero()
|
||||
? new BigNumber(0)
|
||||
@@ -103,9 +98,7 @@ export const useVoteInformation = ({
|
||||
);
|
||||
|
||||
const participationLPMet = requiredParticipationLP
|
||||
? totalEquityLikeShareWeight.isGreaterThan(
|
||||
totalSupply.multipliedBy(requiredParticipationLP)
|
||||
)
|
||||
? totalEquityLikeShareWeight.isGreaterThan(requiredParticipationLP)
|
||||
: false;
|
||||
|
||||
const majorityMet = yesPercentage.isGreaterThanOrEqualTo(
|
||||
@@ -120,9 +113,7 @@ export const useVoteInformation = ({
|
||||
.multipliedBy(100)
|
||||
.dividedBy(totalSupply);
|
||||
|
||||
const totalLPTokensPercentage = totalEquityLikeShareWeight
|
||||
.multipliedBy(100)
|
||||
.dividedBy(totalSupply);
|
||||
const totalLPTokensPercentage = totalEquityLikeShareWeight;
|
||||
|
||||
const willPassByTokenVote =
|
||||
participationMet &&
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ export const ProtocolUpgradeProposalContainer = () => {
|
||||
time={
|
||||
pending && time ? (
|
||||
convertToCountdownString(time, '0:00:00:00')
|
||||
) : blockInfo?.result ? (
|
||||
) : blockInfo && 'result' in blockInfo && blockInfo?.result ? (
|
||||
<span title={blockInfo.result.block.header.time}>
|
||||
{formatDateWithLocalTimezone(
|
||||
new Date(blockInfo.result.block.header.time)
|
||||
|
||||
@@ -116,7 +116,8 @@ export const generateYesVotes = (
|
||||
fixedTokenValue?: number,
|
||||
totalEquityLikeShareWeight?: string
|
||||
): Votes => {
|
||||
const votes = Array.from(Array(numberOfVotes)).map(() => {
|
||||
const votes = [];
|
||||
for (let i = 0; i < numberOfVotes; i++) {
|
||||
const vote: Vote = {
|
||||
__typename: 'Vote',
|
||||
value: Schema.VoteValue.VALUE_YES,
|
||||
@@ -152,8 +153,9 @@ export const generateYesVotes = (
|
||||
datetime: faker.date.past().toISOString(),
|
||||
};
|
||||
|
||||
return vote;
|
||||
});
|
||||
votes.push(vote);
|
||||
}
|
||||
|
||||
return {
|
||||
__typename: 'ProposalVoteSide',
|
||||
totalNumber: votes.length.toString(),
|
||||
@@ -172,7 +174,8 @@ export const generateNoVotes = (
|
||||
fixedTokenValue?: number,
|
||||
totalEquityLikeShareWeight?: string
|
||||
): Votes => {
|
||||
const votes = Array.from(Array(numberOfVotes)).map(() => {
|
||||
const votes = [];
|
||||
for (let i = 0; i < numberOfVotes; i++) {
|
||||
const vote: Vote = {
|
||||
__typename: 'Vote',
|
||||
value: Schema.VoteValue.VALUE_NO,
|
||||
@@ -207,8 +210,9 @@ export const generateNoVotes = (
|
||||
},
|
||||
datetime: faker.date.past().toISOString(),
|
||||
};
|
||||
return vote;
|
||||
});
|
||||
votes.push(vote);
|
||||
}
|
||||
|
||||
return {
|
||||
__typename: 'ProposalVoteSide',
|
||||
totalNumber: votes.length.toString(),
|
||||
|
||||
@@ -188,12 +188,11 @@ const useNow = () => {
|
||||
return now;
|
||||
};
|
||||
|
||||
const useEvery = (marketId: string) => {
|
||||
const { data: marketTradingMode } = useMarketTradingMode(marketId);
|
||||
const useEvery = (marketId: string, skip: boolean) => {
|
||||
const { data: marketInfo } = useDataProvider({
|
||||
dataProvider: marketInfoProvider,
|
||||
variables: { marketId },
|
||||
skip: !marketTradingMode || isMarketInAuction(marketTradingMode),
|
||||
skip,
|
||||
});
|
||||
let every: number | undefined = undefined;
|
||||
const sourceType =
|
||||
@@ -211,8 +210,10 @@ const useEvery = (marketId: string) => {
|
||||
return every;
|
||||
};
|
||||
|
||||
const useStartTime = (marketId: string) => {
|
||||
const useStartTime = (marketId: string, skip: boolean) => {
|
||||
const { data: fundingPeriods } = useFundingPeriodsQuery({
|
||||
pollInterval: 5000,
|
||||
skip,
|
||||
variables: {
|
||||
marketId: marketId,
|
||||
pagination: { first: 1 },
|
||||
@@ -246,8 +247,10 @@ const useFormatCountdown = (
|
||||
|
||||
export const FundingCountdown = ({ marketId }: { marketId: string }) => {
|
||||
const now = useNow();
|
||||
const startTime = useStartTime(marketId);
|
||||
const every = useEvery(marketId);
|
||||
const { data: marketTradingMode } = useMarketTradingMode(marketId);
|
||||
const skip = !marketTradingMode || isMarketInAuction(marketTradingMode);
|
||||
const startTime = useStartTime(marketId, skip);
|
||||
const every = useEvery(marketId, skip);
|
||||
|
||||
return (
|
||||
<div data-testid="funding-countdown">
|
||||
|
||||
@@ -333,11 +333,7 @@ export const CurrentVolume = ({
|
||||
return (
|
||||
<div className="flex flex-col gap-3 pt-4" data-testid="current-volume">
|
||||
<CardStat
|
||||
value={
|
||||
currentVolume.isZero()
|
||||
? `<${formatNumberRounded(requiredForNextTier)}`
|
||||
: formatNumberRounded(currentVolume)
|
||||
}
|
||||
value={formatNumberRounded(currentVolume)}
|
||||
text={t('pastEpochs', 'Past {{count}} epochs', {
|
||||
count: windowLength,
|
||||
})}
|
||||
|
||||
@@ -69,11 +69,13 @@ describe('RewardPot', () => {
|
||||
balance: '100',
|
||||
asset: rewardAsset,
|
||||
},
|
||||
// should include this in total:
|
||||
{
|
||||
type: AccountType.ACCOUNT_TYPE_VESTED_REWARDS,
|
||||
balance: '100',
|
||||
asset: rewardAsset,
|
||||
},
|
||||
// should include this in total:
|
||||
{
|
||||
type: AccountType.ACCOUNT_TYPE_VESTED_REWARDS,
|
||||
balance: '50',
|
||||
@@ -138,20 +140,20 @@ describe('RewardPot', () => {
|
||||
|
||||
renderComponent(props);
|
||||
|
||||
expect(screen.getByTestId('total-rewards')).toHaveTextContent(
|
||||
`7.00 ${rewardAsset.symbol}`
|
||||
);
|
||||
|
||||
expect(screen.getByText(/Locked/).nextElementSibling).toHaveTextContent(
|
||||
'2.50'
|
||||
);
|
||||
expect(screen.getByText(/Vesting/).nextElementSibling).toHaveTextContent(
|
||||
'4.50'
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByText(/Available to withdraw/).nextElementSibling
|
||||
).toHaveTextContent('1.50');
|
||||
|
||||
// should be sum of the above
|
||||
expect(screen.getByTestId('total-rewards')).toHaveTextContent(
|
||||
`8.50 ${rewardAsset.symbol}`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -62,6 +62,10 @@ export const RewardsContainer = () => {
|
||||
},
|
||||
// Inclusion of activity streak in query currently fails
|
||||
errorPolicy: 'ignore',
|
||||
// polling here so that as rewards are are moved to ACCOUNT_TYPE_VESTED_REWARDS the vesting stats information stays
|
||||
// almost up to sync with accounts updating from subscriptions. There is a chance the data could be out
|
||||
// of sync for 10s if you happen to be on the page at the end of an epoch
|
||||
pollInterval: 10000,
|
||||
});
|
||||
|
||||
if (!epochData?.epoch || !assetMap) return null;
|
||||
@@ -295,7 +299,9 @@ export const RewardPot = ({
|
||||
: [0];
|
||||
const totalVesting = BigNumber.sum.apply(null, vestingBalances);
|
||||
|
||||
const totalRewards = totalLocked.plus(totalVesting);
|
||||
const totalRewards = totalLocked
|
||||
.plus(totalVesting)
|
||||
.plus(totalVestedRewardsByRewardAsset);
|
||||
|
||||
let rewardAsset = undefined;
|
||||
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
CONSOLE_IMAGE_NAME=vegaprotocol/trading:latest
|
||||
VEGA_VERSION=v0.73.9
|
||||
LOCAL_SERVER=false
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
CONSOLE_IMAGE_NAME=vegaprotocol/trading:main
|
||||
VEGA_VERSION=v0.73.8
|
||||
LOCAL_SERVER=false
|
||||
@@ -127,11 +127,7 @@ yarn nx serve trading
|
||||
|
||||
```
|
||||
|
||||
Once console is served you can use the flag --local-server
|
||||
|
||||
```bash
|
||||
poetry run pytest -k "test_name" -s --headed --local-server
|
||||
```
|
||||
Once console is served you can update the .env file to have local_server to true.
|
||||
|
||||
## Running Tests in Parallel 🔢
|
||||
|
||||
|
||||
@@ -6,9 +6,10 @@ import requests
|
||||
import time
|
||||
import docker
|
||||
import http.server
|
||||
|
||||
import sys
|
||||
from dotenv import load_dotenv
|
||||
from contextlib import contextmanager
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from vega_sim.null_service import VegaServiceNull, Ports
|
||||
from playwright.sync_api import Browser, Page
|
||||
from config import console_image_name, vega_version
|
||||
from datetime import datetime, timedelta
|
||||
@@ -19,7 +20,6 @@ from fixtures.market import (
|
||||
setup_perps_market,
|
||||
)
|
||||
|
||||
import sys
|
||||
|
||||
# Workaround for current xdist issue with displaying live logs from multiple workers
|
||||
# https://github.com/pytest-dev/pytest-xdist/issues/402
|
||||
@@ -28,6 +28,8 @@ sys.stdout = sys.stderr
|
||||
docker_client = docker.from_env()
|
||||
logger = logging.getLogger()
|
||||
|
||||
load_dotenv()
|
||||
|
||||
|
||||
@pytest.hookimpl(tryfirst=True)
|
||||
def pytest_runtest_makereport(item, call):
|
||||
@@ -49,16 +51,24 @@ def pytest_configure(config):
|
||||
level=config.getini("log_file_level"),
|
||||
)
|
||||
|
||||
|
||||
class CustomHttpRequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
# Set the path to your website's directory here
|
||||
if self.path == '/':
|
||||
self.path = 'dist/apps/trading/exported/index.html'
|
||||
if self.path == "/":
|
||||
self.path = "dist/apps/trading/exported/index.html"
|
||||
return http.server.SimpleHTTPRequestHandler.do_GET(self)
|
||||
|
||||
|
||||
# Start VegaServiceNull
|
||||
@contextmanager
|
||||
def init_vega(request=None):
|
||||
local_server = os.getenv("LOCAL_SERVER", "false").lower() == "true"
|
||||
port_config = None
|
||||
if local_server:
|
||||
port_config = {
|
||||
Ports.DATA_NODE_REST: 8001,
|
||||
}
|
||||
default_seconds = 1
|
||||
seconds_per_block = default_seconds
|
||||
if request and hasattr(request, "param"):
|
||||
@@ -70,21 +80,26 @@ def init_vega(request=None):
|
||||
)
|
||||
logger.info(f"Using console image: {console_image_name}")
|
||||
logger.info(f"Using vega version: {vega_version}")
|
||||
with VegaServiceNull(
|
||||
run_with_console=False,
|
||||
launch_graphql=False,
|
||||
retain_log_files=True,
|
||||
use_full_vega_wallet=True,
|
||||
store_transactions=True,
|
||||
transactions_per_block=1000,
|
||||
seconds_per_block=seconds_per_block,
|
||||
genesis_time= datetime.now() - timedelta(days=1),
|
||||
) as vega:
|
||||
|
||||
vega_service_args = {
|
||||
"run_with_console": False,
|
||||
"launch_graphql": False,
|
||||
"retain_log_files": True,
|
||||
"use_full_vega_wallet": True,
|
||||
"store_transactions": True,
|
||||
"transactions_per_block": 1000,
|
||||
"seconds_per_block": seconds_per_block,
|
||||
"genesis_time": datetime.now() - timedelta(days=1),
|
||||
}
|
||||
|
||||
if port_config is not None:
|
||||
vega_service_args["port_config"] = port_config
|
||||
|
||||
with VegaServiceNull(**vega_service_args) as vega:
|
||||
try:
|
||||
container = docker_client.containers.run(
|
||||
console_image_name, detach=True, ports={"80/tcp": vega.console_port}
|
||||
)
|
||||
# docker setup
|
||||
logger.info(
|
||||
f"Container {container.id} started",
|
||||
extra={"worker_id": os.environ.get("PYTEST_XDIST_WORKER")},
|
||||
@@ -97,23 +112,13 @@ def init_vega(request=None):
|
||||
finally:
|
||||
logger.info(f"Stopping container {container.id}")
|
||||
container.stop()
|
||||
# Remove the container
|
||||
logger.info(f"Removing container {container.id}")
|
||||
container.remove()
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption(
|
||||
"--local-server", action="store_true", default=False,
|
||||
help="Build and serve locally instead of using a container"
|
||||
)
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def local_server(pytestconfig):
|
||||
return pytestconfig.getoption("--local-server")
|
||||
|
||||
@contextmanager
|
||||
def init_page(vega: VegaServiceNull, browser: Browser, request: pytest.FixtureRequest, local_server: bool):
|
||||
def init_page(vega: VegaServiceNull, browser: Browser, request: pytest.FixtureRequest):
|
||||
local_server = os.getenv("LOCAL_SERVER", "false").lower() == "true"
|
||||
server_port = "4200" if local_server else str(vega.console_port)
|
||||
with browser.new_context(
|
||||
viewport={"width": 1920, "height": 1080},
|
||||
@@ -125,9 +130,7 @@ def init_page(vega: VegaServiceNull, browser: Browser, request: pytest.FixtureRe
|
||||
attempts = 0
|
||||
while attempts < 100:
|
||||
try:
|
||||
code = requests.get(
|
||||
f"http://localhost:{server_port}/"
|
||||
).status_code
|
||||
code = requests.get(f"http://localhost:{server_port}/").status_code
|
||||
if code == 200:
|
||||
break
|
||||
except requests.exceptions.ConnectionError as e:
|
||||
@@ -172,8 +175,8 @@ def vega(request):
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def page(vega, browser, request, local_server):
|
||||
with init_page(vega, browser, request, local_server) as page_instance:
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page_instance:
|
||||
yield page_instance
|
||||
|
||||
|
||||
|
||||
Generated
+2
-2
@@ -1,4 +1,4 @@
|
||||
# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
|
||||
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
@@ -1161,7 +1161,7 @@ profile = ["pytest-profiling", "snakeviz"]
|
||||
type = "git"
|
||||
url = "https://github.com/vegaprotocol/vega-market-sim.git/"
|
||||
reference = "fix/genesis_panic"
|
||||
resolved_reference = "7ab04931924380db8000544b7f3d65fcb39b5467"
|
||||
resolved_reference = "de30d2d4c7a1b81a830527ca76473e23ef59de12"
|
||||
|
||||
[[package]]
|
||||
name = "websocket-client"
|
||||
|
||||
@@ -641,7 +641,7 @@ def test_fills_maker_fee_tooltip_discount_program(
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
row.locator(COL_FEE).hover()
|
||||
expect(page.get_by_test_id(FEE_BREAKDOWN_TOOLTIP)).to_have_text(
|
||||
f"If the market was activeThe maker will receive the maker fee.If the market is active the maker will pay zero infrastructure and liquidity fees.Infrastructure fee0.00 tDAILiquidity fee0.00 tDAIMaker fee-{fee} tDAITotal fees-{fee} tDAI"
|
||||
f"If the market was activeFee revenue to be received by the maker, takers' fee discounts already applied.During continuous trading the maker pays no infrastructure and liquidity fees.Infrastructure fee0.00 tDAILiquidity fee0.00 tDAIMaker fee-{fee} tDAITotal fees-{fee} tDAI"
|
||||
)
|
||||
|
||||
|
||||
@@ -678,5 +678,5 @@ def test_fills_taker_fee_tooltip_discount_program(
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
row.locator(COL_FEE).hover()
|
||||
expect(page.get_by_test_id(FEE_BREAKDOWN_TOOLTIP)).to_have_text(
|
||||
f"If the market was activeFees to be paid by the taker.Infrastructure fee{infra_fee} tDAILiquidity fee0.00 tDAIMaker fee{maker_fee} tDAITotal fees{total_fee} tDAI"
|
||||
f"If the market was activeFees to be paid by the taker; discounts are already applied.Infrastructure fee{infra_fee} tDAILiquidity fee0.00 tDAIMaker fee{maker_fee} tDAITotal fees{total_fee} tDAI"
|
||||
)
|
||||
|
||||
@@ -208,11 +208,11 @@ def test_auction_uncross_fees(continuous_market, vega: VegaService, page: Page):
|
||||
expect(page.locator(COL_ID_FEE)).to_have_text("0.00 tDAI")
|
||||
page.locator(COL_ID_FEE).hover()
|
||||
expect(page.get_by_test_id("fee-breakdown-tooltip")).to_have_text(
|
||||
"If the market was suspendedIf the market is in monitoring auction, half of the infrastructure and liquidity fees will be paid.Infrastructure fee0.00 tDAILiquidity fee0.00 tDAIMaker fee0.00 tDAITotal fees0.00 tDAI"
|
||||
"If the market was suspendedDuring auction, half the infrastructure and liquidity fees will be paid.Infrastructure fee0.00 tDAILiquidity fee0.00 tDAIMaker fee0.00 tDAITotal fees0.00 tDAI"
|
||||
)
|
||||
change_keys(page, vega, "market_maker")
|
||||
expect(page.locator(COL_ID_FEE)).to_have_text("0.00 tDAI")
|
||||
page.locator(COL_ID_FEE).hover()
|
||||
expect(page.get_by_test_id("fee-breakdown-tooltip")).to_have_text(
|
||||
"If the market was suspendedIf the market is in monitoring auction, half of the infrastructure and liquidity fees will be paid.Infrastructure fee0.00 tDAILiquidity fee0.00 tDAIMaker fee0.00 tDAITotal fees0.00 tDAI"
|
||||
"If the market was suspendedDuring auction, half the infrastructure and liquidity fees will be paid.Infrastructure fee0.00 tDAILiquidity fee0.00 tDAIMaker fee0.00 tDAITotal fees0.00 tDAI"
|
||||
)
|
||||
|
||||
@@ -15,8 +15,8 @@ def vega():
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def page(vega, browser, request, local_server):
|
||||
with init_page(vega, browser, request, local_server) as page:
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page:
|
||||
setup_continuous_market(vega)
|
||||
risk_accepted_setup(page)
|
||||
page.goto("/")
|
||||
@@ -280,7 +280,7 @@ def test_market_info_proposal(page: Page, vega: VegaService):
|
||||
"href", re.compile(r"(\/proposals\/propose\/update-market)")
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skip("tbd-market-sim")
|
||||
def test_market_info_succession_line(page: Page, vega: VegaService):
|
||||
page.get_by_test_id(market_title_test_id).get_by_text("Succession line").click()
|
||||
market_id = vega.find_market_id("BTC:DAI_2023")
|
||||
|
||||
@@ -11,8 +11,8 @@ def vega(request):
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def page(vega, browser, request, local_server):
|
||||
with init_page(vega, browser, request, local_server) as page:
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
page.goto("/#/markets/all")
|
||||
yield page
|
||||
|
||||
@@ -12,8 +12,8 @@ def vega():
|
||||
|
||||
# we can reuse single page instance in all tests
|
||||
@pytest.fixture(scope="module")
|
||||
def page(vega, browser, request, local_server):
|
||||
with init_page(vega, browser, request, local_server) as page:
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page:
|
||||
yield page
|
||||
|
||||
|
||||
|
||||
@@ -223,8 +223,8 @@ def markets(vega: VegaService):
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def page(vega, browser, request, local_server):
|
||||
with init_page(vega, browser, request, local_server) as page:
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
auth_setup(vega, page)
|
||||
page.goto("/")
|
||||
|
||||
@@ -141,8 +141,8 @@ def test_perps_market_terminated(page: Page, vega: VegaService):
|
||||
page.goto(f"/#/markets/{perpetual_market}")
|
||||
# TODO change back to have text once bug #5465 is fixed
|
||||
expect(page.get_by_test_id("market-price")).to_have_text("Mark Price100.00")
|
||||
expect(page.get_by_test_id("market-change")).to_contain_text("Change (24h)-")
|
||||
expect(page.get_by_test_id("market-volume")).to_contain_text("Volume (24h)-")
|
||||
expect(page.get_by_test_id("market-change")).to_contain_text("Change (24h)")
|
||||
expect(page.get_by_test_id("market-volume")).to_contain_text("Volume (24h)")
|
||||
expect(page.get_by_test_id("market-trading-mode")).to_have_text(
|
||||
"Trading modeNo trading"
|
||||
)
|
||||
|
||||
@@ -7,6 +7,7 @@ import type {
|
||||
FetchResult,
|
||||
ErrorPolicy,
|
||||
ApolloQueryResult,
|
||||
QueryOptions,
|
||||
} from '@apollo/client';
|
||||
import type { GraphQLErrors } from '@apollo/client/errors';
|
||||
import type { Subscription } from 'zen-observable-ts';
|
||||
@@ -158,6 +159,7 @@ interface DataProviderParams<
|
||||
};
|
||||
fetchPolicy?: FetchPolicy;
|
||||
resetDelay?: number;
|
||||
pollInterval?: number;
|
||||
additionalContext?: Record<string, unknown>;
|
||||
errorPolicyGuard?: (graphqlErrors: GraphQLErrors) => boolean;
|
||||
getQueryVariables?: (variables: Variables) => QueryVariables;
|
||||
@@ -198,6 +200,7 @@ function makeDataProviderInternal<
|
||||
errorPolicyGuard,
|
||||
getQueryVariables,
|
||||
getSubscriptionVariables,
|
||||
pollInterval,
|
||||
}: DataProviderParams<
|
||||
QueryData,
|
||||
Data,
|
||||
@@ -222,6 +225,7 @@ function makeDataProviderInternal<
|
||||
let client: ApolloClient<object>;
|
||||
let subscription: Subscription[] | undefined;
|
||||
let pageInfo: PageInfo | null = null;
|
||||
let watchQuerySubscription: Subscription | null = null;
|
||||
|
||||
// notify single callback about current state, delta is passes optionally only if notify was invoked onNext
|
||||
const notify = (
|
||||
@@ -243,34 +247,100 @@ function makeDataProviderInternal<
|
||||
callbacks.forEach((callback) => notify(callback, updateData));
|
||||
};
|
||||
|
||||
const call = (
|
||||
const getQueryOptions = (
|
||||
pagination?: Pagination,
|
||||
policy?: ErrorPolicy
|
||||
): QueryOptions<OperationVariables, QueryData> => ({
|
||||
query,
|
||||
variables: {
|
||||
...(getQueryVariables ? getQueryVariables(variables) : variables),
|
||||
...(pagination && {
|
||||
// let the variables pagination be prior to provider param
|
||||
pagination: {
|
||||
...pagination,
|
||||
...(variables?.['pagination'] ?? null),
|
||||
},
|
||||
}),
|
||||
},
|
||||
fetchPolicy: fetchPolicy || 'no-cache',
|
||||
context: additionalContext,
|
||||
errorPolicy: policy || 'none',
|
||||
pollInterval,
|
||||
});
|
||||
|
||||
const onNext = (res: ApolloQueryResult<QueryData>) => {
|
||||
data = getData(res.data, variables);
|
||||
if (data && pagination) {
|
||||
if (!(data instanceof Array)) {
|
||||
throw new Error(
|
||||
'data needs to be instance of Edge[] when using pagination'
|
||||
);
|
||||
}
|
||||
pageInfo = pagination.getPageInfo(res.data);
|
||||
}
|
||||
// if there was some updates received from subscription during initial query loading apply them on just received data
|
||||
if (update && data && updateQueue && updateQueue.length > 0) {
|
||||
while (updateQueue.length) {
|
||||
const delta = updateQueue.shift();
|
||||
if (delta) {
|
||||
setData(update(data, delta, reload, variables));
|
||||
}
|
||||
}
|
||||
}
|
||||
loaded = true;
|
||||
};
|
||||
|
||||
const onError = (e: Error) => {
|
||||
if (isNotFoundGraphQLError(e, ['party'])) {
|
||||
data = getData(null, variables);
|
||||
loaded = true;
|
||||
return;
|
||||
}
|
||||
// if error will occur data provider stops subscription
|
||||
error = e;
|
||||
subscriptionUnsubscribe();
|
||||
};
|
||||
|
||||
const onComplete = (isUpdate?: boolean) => {
|
||||
loading = false;
|
||||
notifyAll({ isUpdate });
|
||||
};
|
||||
|
||||
const callWatchQuery = (pagination?: Pagination, policy?: ErrorPolicy) => {
|
||||
let onNextCalled = false;
|
||||
try {
|
||||
watchQuerySubscription = client
|
||||
.watchQuery(getQueryOptions(pagination, policy))
|
||||
.subscribe(
|
||||
(res) => {
|
||||
onNext(res);
|
||||
onComplete(onNextCalled);
|
||||
onNextCalled = true;
|
||||
},
|
||||
(error) => {
|
||||
onError(error as Error);
|
||||
onComplete();
|
||||
}
|
||||
);
|
||||
} catch (e) {
|
||||
onError(e as Error);
|
||||
onComplete();
|
||||
}
|
||||
};
|
||||
|
||||
const callQuery = (
|
||||
pagination?: Pagination,
|
||||
policy?: ErrorPolicy
|
||||
): Promise<ApolloQueryResult<QueryData>> =>
|
||||
client
|
||||
.query<QueryData>({
|
||||
query,
|
||||
variables: {
|
||||
...(getQueryVariables ? getQueryVariables(variables) : variables),
|
||||
...(pagination && {
|
||||
// let the variables pagination be prior to provider param
|
||||
pagination: {
|
||||
...pagination,
|
||||
...(variables?.['pagination'] ?? null),
|
||||
},
|
||||
}),
|
||||
},
|
||||
fetchPolicy: fetchPolicy || 'no-cache',
|
||||
context: additionalContext,
|
||||
errorPolicy: policy || 'none',
|
||||
})
|
||||
.query<QueryData>(getQueryOptions(pagination, policy))
|
||||
.catch((err) => {
|
||||
if (
|
||||
err.graphQLErrors &&
|
||||
errorPolicyGuard &&
|
||||
errorPolicyGuard(err.graphQLErrors)
|
||||
) {
|
||||
return call(pagination, 'ignore');
|
||||
return callQuery(pagination, 'ignore');
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
@@ -294,7 +364,7 @@ function makeDataProviderInternal<
|
||||
}
|
||||
}
|
||||
|
||||
const res = await call(paginationVariables);
|
||||
const res = await callQuery(paginationVariables);
|
||||
|
||||
const insertionData = getData(res.data, variables);
|
||||
const insertionPageInfo = pagination.getPageInfo(res.data);
|
||||
@@ -329,7 +399,7 @@ function makeDataProviderInternal<
|
||||
variables,
|
||||
fetchPolicy,
|
||||
})
|
||||
.subscribe(onNext, onError)
|
||||
.subscribe(subscriptionOnNext, subscriptionOnError)
|
||||
);
|
||||
};
|
||||
|
||||
@@ -347,39 +417,16 @@ function makeDataProviderInternal<
|
||||
const paginationVariables = pagination
|
||||
? { first: pagination.first }
|
||||
: undefined;
|
||||
if (pollInterval) {
|
||||
callWatchQuery();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await call(paginationVariables);
|
||||
data = getData(res.data, variables);
|
||||
if (data && pagination) {
|
||||
if (!(data instanceof Array)) {
|
||||
throw new Error(
|
||||
'data needs to be instance of Edge[] when using pagination'
|
||||
);
|
||||
}
|
||||
pageInfo = pagination.getPageInfo(res.data);
|
||||
}
|
||||
// if there was some updates received from subscription during initial query loading apply them on just received data
|
||||
if (update && data && updateQueue && updateQueue.length > 0) {
|
||||
while (updateQueue.length) {
|
||||
const delta = updateQueue.shift();
|
||||
if (delta) {
|
||||
setData(update(data, delta, reload, variables));
|
||||
}
|
||||
}
|
||||
}
|
||||
loaded = true;
|
||||
onNext(await callQuery(paginationVariables));
|
||||
} catch (e) {
|
||||
if (isNotFoundGraphQLError(e as Error, ['party'])) {
|
||||
data = getData(null, variables);
|
||||
loaded = true;
|
||||
return;
|
||||
}
|
||||
// if error will occur data provider stops subscription
|
||||
error = e as Error;
|
||||
subscriptionUnsubscribe();
|
||||
onError(e as Error);
|
||||
} finally {
|
||||
loading = false;
|
||||
notifyAll({ isUpdate });
|
||||
onComplete(isUpdate);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -399,7 +446,7 @@ function makeDataProviderInternal<
|
||||
}
|
||||
};
|
||||
|
||||
const onNext = ({
|
||||
const subscriptionOnNext = ({
|
||||
data: subscriptionData,
|
||||
}: FetchResult<SubscriptionData>) => {
|
||||
if (!subscriptionData || !getDelta || !update) {
|
||||
@@ -418,7 +465,7 @@ function makeDataProviderInternal<
|
||||
}
|
||||
};
|
||||
|
||||
const onError = (e: Error) => {
|
||||
const subscriptionOnError = (e: Error) => {
|
||||
error = e;
|
||||
subscriptionUnsubscribe();
|
||||
notifyAll();
|
||||
@@ -442,6 +489,9 @@ function makeDataProviderInternal<
|
||||
};
|
||||
|
||||
const reset = () => {
|
||||
if (watchQuerySubscription) {
|
||||
watchQuerySubscription.unsubscribe();
|
||||
}
|
||||
subscriptionUnsubscribe();
|
||||
initialized = false;
|
||||
data = null;
|
||||
|
||||
@@ -87,9 +87,9 @@ export const FillsTable = forwardRef<AgGridReact, Props>(
|
||||
colId: 'fee',
|
||||
field: 'market',
|
||||
valueFormatter: formatFee(partyId),
|
||||
tooltipComponent: FeesBreakdownTooltip,
|
||||
type: 'rightAligned',
|
||||
tooltipField: 'market',
|
||||
tooltipComponent: FeesBreakdownTooltip,
|
||||
tooltipComponentParams: { partyId },
|
||||
},
|
||||
{
|
||||
@@ -97,13 +97,13 @@ export const FillsTable = forwardRef<AgGridReact, Props>(
|
||||
colId: 'fee-discount',
|
||||
field: 'market',
|
||||
valueFormatter: formatFeeDiscount(partyId),
|
||||
type: 'rightAligned',
|
||||
// return null to disable tooltip if fee discount is 0 or empty
|
||||
tooltipValueGetter: ({ valueFormatted, value }) => {
|
||||
return valueFormatted && /[1-9]/.test(valueFormatted)
|
||||
? valueFormatted
|
||||
: null;
|
||||
},
|
||||
type: 'rightAligned',
|
||||
// return null to disable tooltip if fee discount is 0 or empty
|
||||
cellRenderer: ({
|
||||
value,
|
||||
valueFormatted,
|
||||
@@ -146,7 +146,7 @@ export const FillsTable = forwardRef<AgGridReact, Props>(
|
||||
overlayNoRowsTemplate={t('No fills')}
|
||||
getRowId={({ data }) => data?.id}
|
||||
tooltipShowDelay={0}
|
||||
tooltipHideDelay={2000}
|
||||
tooltipHideDelay={10000}
|
||||
components={{ MarketNameCell }}
|
||||
{...props}
|
||||
/>
|
||||
@@ -292,21 +292,27 @@ const FeesBreakdownTooltip = ({
|
||||
)}
|
||||
{role === MAKER && (
|
||||
<>
|
||||
<p className="mb-1">{t('The maker will receive the maker fee.')}</p>
|
||||
<p className="mb-1">
|
||||
{t(
|
||||
'If the market is active the maker will pay zero infrastructure and liquidity fees.'
|
||||
`Fee revenue to be received by the maker, takers' fee discounts already applied.`
|
||||
)}
|
||||
</p>
|
||||
<p className="mb-1">
|
||||
{t(
|
||||
'During continuous trading the maker pays no infrastructure and liquidity fees.'
|
||||
)}
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
{role === TAKER && (
|
||||
<p className="mb-1">{t('Fees to be paid by the taker.')}</p>
|
||||
<p className="mb-1">
|
||||
{t('Fees to be paid by the taker; discounts are already applied.')}
|
||||
</p>
|
||||
)}
|
||||
{(role === '-' || marketState === Schema.MarketState.STATE_SUSPENDED) && (
|
||||
<p className="mb-1">
|
||||
{t(
|
||||
'If the market is in monitoring auction, half of the infrastructure and liquidity fees will be paid.'
|
||||
'During auction, half the infrastructure and liquidity fees will be paid.'
|
||||
)}
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
"Date": "Date",
|
||||
"Fee": "Fee",
|
||||
"Fee Discount": "Fee Discount",
|
||||
"Fees to be paid by the taker.": "Fees to be paid by the taker.",
|
||||
"If the market is active the maker will pay zero infrastructure and liquidity fees.": "If the market is active the maker will pay zero infrastructure and liquidity fees.",
|
||||
"If the market is in monitoring auction, half of the infrastructure and liquidity fees will be paid.": "If the market is in monitoring auction, half of the infrastructure and liquidity fees will be paid.",
|
||||
"Fees to be paid by the taker; discounts are already applied.": "Fees to be paid by the taker; discounts are already applied.",
|
||||
"During continuous trading the maker pays no infrastructure and liquidity fees.": "During continuous trading the maker pays no infrastructure and liquidity fees.",
|
||||
"During auction, half the infrastructure and liquidity fees will be paid.": "During auction, half the infrastructure and liquidity fees will be paid.",
|
||||
"Infrastructure Fee": "Infrastructure Fee",
|
||||
"Market": "Market",
|
||||
"No fills": "No fills",
|
||||
|
||||
@@ -298,8 +298,8 @@
|
||||
"liquidityOnsenIntro": "Earn rewards for providing liquidity on the",
|
||||
"liquidityOnsenLinkText": "SushiSwap Onsen Menu",
|
||||
"liquidityProviderVote": "Liquidity provider vote",
|
||||
"liquidityProviderVotesAgainst": "LP votes against",
|
||||
"liquidityProviderVotesFor": "LP votes for",
|
||||
"liquidityProviderVotesAgainst": "LP share against",
|
||||
"liquidityProviderVotesFor": "LP share for",
|
||||
"liquidityRewardsTitle": "Active liquidity rewards",
|
||||
"liquidityRewardsTitlePrevious": "Previous liquidity rewards",
|
||||
"liquidityStakedBalance": "SLP token balance",
|
||||
@@ -759,7 +759,7 @@
|
||||
"Total stake": "Total stake",
|
||||
"Total supply": "Total supply",
|
||||
"totalDistributed": "Total distributed",
|
||||
"totalLiquidityProviderTokensVoted": "Total LP tokens voted",
|
||||
"totalLiquidityProviderTokensVoted": "Total LP share voted",
|
||||
"totalPenalties": "Total penalties",
|
||||
"TotalPenaltiesDescription": "Total of penalties taking into account performance (considering proportion of blocks proposed against the number of blocks the validator was expected to propose) and any overstaking.",
|
||||
"totalStake": "Total stake",
|
||||
|
||||
@@ -34,6 +34,7 @@ export const marketInfoProvider = makeDataProvider<
|
||||
query: MarketInfoDocument,
|
||||
getData,
|
||||
errorPolicyGuard: marketDataErrorPolicyGuard,
|
||||
pollInterval: 5000,
|
||||
});
|
||||
|
||||
export const marketInfoWithDataProvider = makeDerivedDataProvider<
|
||||
|
||||
@@ -68,10 +68,13 @@ export const useBlockRising = (skip = false) => {
|
||||
}
|
||||
);
|
||||
|
||||
const heights = compact([
|
||||
...results.map((r) => r?.blockHeight),
|
||||
blockInfo?.result.block.header.height,
|
||||
]);
|
||||
const heights = compact([...results.map((r) => r?.blockHeight)]);
|
||||
|
||||
// Handles TendermintErrorResponses
|
||||
if (blockInfo && 'result' in blockInfo) {
|
||||
heights.push(blockInfo.result.block.header.height);
|
||||
}
|
||||
|
||||
const current = max(heights);
|
||||
if (current && Number(current) > prev) {
|
||||
setBlock(Number(current));
|
||||
|
||||
@@ -76,16 +76,26 @@ export const useFetch = <T>(
|
||||
...options,
|
||||
body: body ? body : options?.body,
|
||||
});
|
||||
if (!response.ok) {
|
||||
|
||||
data = (await response.json()) as T;
|
||||
|
||||
if (!response.ok && !data) {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
|
||||
data = (await response.json()) as T;
|
||||
// @ts-ignore - 'error' in data
|
||||
if (data && 'error' in data) {
|
||||
if (data && data.error) {
|
||||
// Explicit check for TendermintErrorResponse style error
|
||||
// @ts-ignore - 'error' in data
|
||||
if (data.error.data) {
|
||||
// @ts-ignore - 'error' in data
|
||||
|
||||
throw new Error(data.error.data);
|
||||
}
|
||||
// @ts-ignore - data.error
|
||||
throw new Error(data.error);
|
||||
}
|
||||
|
||||
if (cancelRequest.current) return;
|
||||
|
||||
dispatch({ type: ActionType.FETCHED, payload: data });
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import { useEnvironment } from '@vegaprotocol/environment';
|
||||
import { useFetch } from '@vegaprotocol/react-helpers';
|
||||
import { type TendermintBlockResponse } from '../types';
|
||||
import type {
|
||||
TendermintBlockResponse,
|
||||
TendermintErrorResponse,
|
||||
} from '../types';
|
||||
|
||||
type TendermintResponse = TendermintBlockResponse | TendermintErrorResponse;
|
||||
|
||||
export const useBlockInfo = (blockHeight?: number, canFetch = true) => {
|
||||
const { TENDERMINT_URL } = useEnvironment();
|
||||
@@ -10,7 +15,7 @@ export const useBlockInfo = (blockHeight?: number, canFetch = true) => {
|
||||
TENDERMINT_URL && blockHeight && !isNaN(blockHeight) && canFetch
|
||||
);
|
||||
|
||||
const { state, refetch } = useFetch<TendermintBlockResponse>(
|
||||
const { state, refetch } = useFetch<TendermintResponse>(
|
||||
url,
|
||||
{ cache: 'force-cache' },
|
||||
canFetchData
|
||||
|
||||
@@ -7,6 +7,16 @@ export type TendermintBlockResponse = {
|
||||
};
|
||||
};
|
||||
|
||||
export type TendermintErrorResponse = {
|
||||
jsonrpc: string;
|
||||
id: number;
|
||||
error: {
|
||||
code: number;
|
||||
message: string;
|
||||
data: string;
|
||||
};
|
||||
};
|
||||
|
||||
type Id = {
|
||||
hash: string;
|
||||
parts: {
|
||||
@@ -34,7 +44,7 @@ type Header = {
|
||||
proposer_address: string;
|
||||
};
|
||||
|
||||
type Block = {
|
||||
export type Block = {
|
||||
header: Header;
|
||||
data: {
|
||||
txs: string[];
|
||||
|
||||
Reference in New Issue
Block a user