Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4aa8f1306f | ||
|
|
a9267de653 | ||
|
|
ce22da1c9a | ||
|
|
2460a62a3e | ||
|
|
f37a8720a2 | ||
|
|
f5fe3cc18d | ||
|
|
288f075cac | ||
|
|
ca46861fd8 | ||
|
|
2cb6ede492 |
@@ -14,7 +14,6 @@ import {
|
||||
SettlementAssetInfoPanel,
|
||||
} from '@vegaprotocol/market-info';
|
||||
import { MarketInfoTable } from '@vegaprotocol/market-info';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
|
||||
if (!market) return null;
|
||||
@@ -97,22 +96,19 @@ export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t('Oracle'),
|
||||
title: t('Settlement Oracle'),
|
||||
content: (
|
||||
<OracleInfoPanel noBorder={false} market={market}>
|
||||
<Link
|
||||
className="text-xs hover:underline"
|
||||
to={`/oracles#${market.tradableInstrument.instrument.product.dataSourceSpecForSettlementData.id}`}
|
||||
>
|
||||
{t('View settlement data oracle specification')}
|
||||
</Link>
|
||||
<Link
|
||||
className="text-xs hover:underline"
|
||||
to={`/oracles#${market.tradableInstrument.instrument.product.dataSourceSpecForTradingTermination.id}`}
|
||||
>
|
||||
{t('View termination oracle specification')}
|
||||
</Link>
|
||||
</OracleInfoPanel>
|
||||
<OracleInfoPanel
|
||||
noBorder={false}
|
||||
market={market}
|
||||
type="settlementData"
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t('Termination Oracle'),
|
||||
content: (
|
||||
<OracleInfoPanel noBorder={false} market={market} type="termination" />
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"name": "Token test market",
|
||||
"code": "Token.24h",
|
||||
"future": {
|
||||
"settlementAsset": "fBTC",
|
||||
"settlementAsset": "73174a6fb1d5802ba0ac7bd7ab79e0a3a4837b262de0a4e80815a55442692bd0",
|
||||
"quoteName": "fBTC",
|
||||
"dataSourceSpecForSettlementData": {
|
||||
"external": {
|
||||
|
||||
@@ -49,6 +49,7 @@ describe(
|
||||
});
|
||||
|
||||
beforeEach('visit proposals tab', function () {
|
||||
cy.clearLocalStorage();
|
||||
cy.reload();
|
||||
waitForSpinner();
|
||||
cy.connectVegaWallet();
|
||||
@@ -217,9 +218,9 @@ describe(
|
||||
vegaWalletSetSpecifiedApprovalAmount('1000');
|
||||
createRawProposal();
|
||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||
getSubmittedProposalFromProposalList(rawProposal.rationale.title)
|
||||
.as('submittedProposal')
|
||||
.within(() => cy.get(viewProposalButton).click());
|
||||
getSubmittedProposalFromProposalList(
|
||||
rawProposal.rationale.title
|
||||
).within(() => cy.get(viewProposalButton).click());
|
||||
});
|
||||
voteForProposal('for');
|
||||
// 3001-VOTE-079
|
||||
@@ -237,9 +238,9 @@ describe(
|
||||
);
|
||||
navigateTo(navigation.proposals);
|
||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||
getSubmittedProposalFromProposalList(rawProposal.rationale.title)
|
||||
.as('submittedProposal')
|
||||
.within(() => cy.get(viewProposalButton).click());
|
||||
getSubmittedProposalFromProposalList(
|
||||
rawProposal.rationale.title
|
||||
).within(() => cy.get(viewProposalButton).click());
|
||||
});
|
||||
cy.get(proposalVoteProgressForPercentage)
|
||||
.contains('100.00%')
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
||||
import { vegaWalletSetSpecifiedApprovalAmount } from '../../support/wallet-teardown.functions';
|
||||
|
||||
const proposalListItem = '[data-testid="proposals-list-item"]';
|
||||
const closedProposals = '[data-testid="closed-proposals"]';
|
||||
const proposalStatus = '[data-testid="proposal-status"]';
|
||||
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
||||
@@ -35,6 +36,7 @@ context(
|
||||
});
|
||||
|
||||
beforeEach('visit proposals', function () {
|
||||
cy.clearLocalStorage();
|
||||
cy.reload();
|
||||
waitForSpinner();
|
||||
cy.connectVegaWallet();
|
||||
@@ -51,7 +53,8 @@ context(
|
||||
waitForSpinner();
|
||||
cy.get(closedProposals).within(() => {
|
||||
cy.contains(proposalTitle)
|
||||
.parentsUntil('[data-testid="proposals-list-item"]')
|
||||
.parentsUntil(proposalListItem)
|
||||
.last()
|
||||
.within(() => {
|
||||
cy.get(proposalStatus).should('have.text', 'Enacted ');
|
||||
cy.get(viewProposalButton).click();
|
||||
@@ -78,7 +81,8 @@ context(
|
||||
waitForSpinner();
|
||||
cy.get(openProposals).within(() => {
|
||||
cy.contains(proposalTitle)
|
||||
.parentsUntil('[data-testid="proposals-list-item"]')
|
||||
.parentsUntil(proposalListItem)
|
||||
.last()
|
||||
.within(() => cy.get(viewProposalButton).click());
|
||||
});
|
||||
getProposalInformationFromTable('State')
|
||||
@@ -111,7 +115,8 @@ context(
|
||||
waitForSpinner();
|
||||
cy.get(openProposals, { timeout: 6000 }).within(() => {
|
||||
cy.contains(proposalTitle)
|
||||
.parentsUntil('[data-testid="proposals-list-item"]')
|
||||
.parentsUntil(proposalListItem)
|
||||
.last()
|
||||
.within(() => cy.get(viewProposalButton).click());
|
||||
});
|
||||
getProposalInformationFromTable('State')
|
||||
@@ -133,7 +138,8 @@ context(
|
||||
waitForSpinner();
|
||||
cy.get(openProposals).within(() => {
|
||||
cy.contains(proposalTitle)
|
||||
.parentsUntil('[data-testid="proposals-list-item"]')
|
||||
.parentsUntil(proposalListItem)
|
||||
.last()
|
||||
.within(() => cy.get(viewProposalButton).click());
|
||||
});
|
||||
getProposalInformationFromTable('State')
|
||||
|
||||
@@ -84,6 +84,7 @@ context(
|
||||
});
|
||||
|
||||
beforeEach('visit governance tab', function () {
|
||||
cy.clearLocalStorage();
|
||||
cy.reload();
|
||||
waitForSpinner();
|
||||
cy.connectVegaWallet();
|
||||
|
||||
@@ -76,6 +76,7 @@ context(
|
||||
});
|
||||
|
||||
beforeEach('visit governance tab', function () {
|
||||
cy.clearLocalStorage();
|
||||
cy.reload();
|
||||
waitForSpinner();
|
||||
cy.connectVegaWallet();
|
||||
@@ -304,7 +305,10 @@ context(
|
||||
cy.get('dd').eq(0).should('have.text', 'Test market 1');
|
||||
cy.get('dd').eq(1).should('have.text', 'TEST.24h');
|
||||
cy.get('dd').eq(2).should('not.be.empty');
|
||||
cy.get('dd').eq(2).invoke('text').as('EnactedMarketId');
|
||||
cy.get('dd')
|
||||
.eq(2)
|
||||
.invoke('text')
|
||||
.as('EnactedMarketId', { type: 'static' });
|
||||
});
|
||||
cy.get('@EnactedMarketId').then((marketId) => {
|
||||
cy.VegaWalletSubmitLiquidityProvision(String(marketId), '1');
|
||||
@@ -322,6 +326,7 @@ context(
|
||||
cy.get('@EnactedMarketId').then((marketId) => {
|
||||
cy.contains(String(marketId))
|
||||
.parentsUntil(proposalListItem)
|
||||
.last()
|
||||
.within(() => {
|
||||
cy.getByTestId(viewProposalBtn).click();
|
||||
});
|
||||
@@ -375,16 +380,19 @@ context(
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
// cannot submit a proposal with ERC20 address already in use
|
||||
cy.contains('Proposal rejected', proposalTimeout).should('be.visible');
|
||||
cy.getByTestId('dialog-content').within(() => {
|
||||
cy.get('p').should(
|
||||
'have.text',
|
||||
'PROPOSAL_ERROR_ERC20_ADDRESS_ALREADY_IN_USE'
|
||||
);
|
||||
});
|
||||
cy.getByTestId('dialog-content')
|
||||
.last()
|
||||
.within(() => {
|
||||
cy.get('p').should(
|
||||
'have.text',
|
||||
'PROPOSAL_ERROR_ERC20_ADDRESS_ALREADY_IN_USE'
|
||||
);
|
||||
});
|
||||
closeDialog();
|
||||
navigateTo(navigation.proposals);
|
||||
cy.contains(proposalTitle)
|
||||
.parentsUntil(proposalListItem)
|
||||
.last()
|
||||
.within(() => {
|
||||
cy.getByTestId(viewProposalBtn).click();
|
||||
});
|
||||
@@ -422,6 +430,7 @@ context(
|
||||
cy.get(proposalType)
|
||||
.contains('Update asset')
|
||||
.parentsUntil(proposalListItem)
|
||||
.last()
|
||||
.within(() => {
|
||||
cy.get(proposalDetails).should('contain.text', assetId); // 3001-VOTE-029
|
||||
cy.getByTestId(viewProposalBtn).click();
|
||||
|
||||
@@ -35,6 +35,7 @@ describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
||||
});
|
||||
|
||||
beforeEach('visit proposals tab', function () {
|
||||
cy.clearLocalStorage();
|
||||
cy.reload();
|
||||
waitForSpinner();
|
||||
cy.connectVegaWallet();
|
||||
@@ -59,7 +60,10 @@ describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
||||
cy.get(openProposals).within(() => {
|
||||
cy.get(proposalClosingDate).first().should('contain.text', 'year');
|
||||
cy.get(proposalClosingDate).should('contain.text', 'months');
|
||||
cy.get(proposalClosingDate).last().should('contain.text', 'days');
|
||||
cy.get(proposalClosingDate)
|
||||
.last()
|
||||
.invoke('text')
|
||||
.should('match', /days|minutes/);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -25,9 +25,10 @@ const rewardsTimeOut = { timeout: 60000 };
|
||||
|
||||
context('rewards - flow', { tags: '@slow' }, function () {
|
||||
before('set up environment to allow rewards', function () {
|
||||
cy.clearLocalStorage();
|
||||
cy.visit('/');
|
||||
waitForSpinner();
|
||||
depositAsset(vegaAssetAddress, '1000');
|
||||
depositAsset(vegaAssetAddress, '1000', 18);
|
||||
cy.validatorsSelfDelegate();
|
||||
ethereumWalletConnect();
|
||||
cy.connectVegaWallet();
|
||||
@@ -56,7 +57,7 @@ context('rewards - flow', { tags: '@slow' }, function () {
|
||||
cy.getByTestId(rewardsTable)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.getByTestId('asset').should('have.text', 'Vega');
|
||||
cy.getByTestId('asset', rewardsTimeOut).should('have.text', 'Vega');
|
||||
cy.getByTestId('ACCOUNT_TYPE_GLOBAL_REWARD').should('have.text', '1');
|
||||
cy.getByTestId('ACCOUNT_TYPE_FEES_INFRASTRUCTURE').should(
|
||||
'have.text',
|
||||
@@ -93,13 +94,13 @@ context('rewards - flow', { tags: '@slow' }, function () {
|
||||
.within(() => {
|
||||
cy.get('h2').first().should('contain.text', 'EPOCH');
|
||||
cy.getByTestId('individual-rewards-asset').should('have.text', 'Vega');
|
||||
cy.getByTestId('ACCOUNT_TYPE_GLOBAL_REWARD')
|
||||
.should('contain.text', '0.1177')
|
||||
.and('contain.text', '(11.7733%)');
|
||||
cy.getByTestId('ACCOUNT_TYPE_GLOBAL_REWARD', rewardsTimeOut)
|
||||
.should('contain.text', '0.4415')
|
||||
.and('contain.text', '(44.15%)');
|
||||
cy.getByTestId('ACCOUNT_TYPE_FEES_INFRASTRUCTURE')
|
||||
.should('contain.text', '0.0001')
|
||||
.and('contain.text', '(11.7733%)');
|
||||
cy.getByTestId('total').should('have.text', '0.1179');
|
||||
.should('contain.text', '0.0004')
|
||||
.and('contain.text', '(44.15%)');
|
||||
cy.getByTestId('total').should('have.text', '0.4419');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -66,7 +66,7 @@ context(
|
||||
beforeEach(
|
||||
'teardown wallet & drill into a specific validator',
|
||||
function () {
|
||||
cy.clearAllLocalStorage();
|
||||
cy.clearLocalStorage();
|
||||
cy.reload();
|
||||
waitForSpinner();
|
||||
cy.connectVegaWallet();
|
||||
|
||||
@@ -53,6 +53,7 @@ context(
|
||||
beforeEach(
|
||||
'teardown wallet & drill into a specific validator',
|
||||
function () {
|
||||
cy.clearLocalStorage();
|
||||
cy.reload();
|
||||
waitForSpinner();
|
||||
cy.connectVegaWallet();
|
||||
@@ -90,9 +91,14 @@ context(
|
||||
|
||||
verifyEthWalletTotalAssociatedBalance('2.0');
|
||||
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 2.0);
|
||||
});
|
||||
cy.get(vegaWallet)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
2.0
|
||||
);
|
||||
});
|
||||
|
||||
cy.get(vegaWalletUnstakedBalance, txTimeout).should('contain', 2.0);
|
||||
});
|
||||
@@ -128,26 +134,38 @@ context(
|
||||
stakingPageAssociateTokens('1001', { approve: true });
|
||||
verifyEthWalletAssociatedBalance('1,001.00');
|
||||
verifyEthWalletTotalAssociatedBalance('1,001.00');
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
'1,001.00'
|
||||
);
|
||||
});
|
||||
cy.get(vegaWallet)
|
||||
.last()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
'1,001.00'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('Able to disassociate a partial amount of tokens currently associated', function () {
|
||||
stakingPageAssociateTokens('2');
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 2.0);
|
||||
});
|
||||
cy.get(vegaWallet)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
2.0
|
||||
);
|
||||
});
|
||||
|
||||
cy.get('button').contains('Select a validator to nominate').click();
|
||||
stakingPageDisassociateTokens('1');
|
||||
verifyEthWalletAssociatedBalance('1.0');
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 1.0);
|
||||
});
|
||||
cy.get(vegaWallet)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
1.0
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('Able to disassociate all tokens - using max', function () {
|
||||
@@ -155,26 +173,40 @@ context(
|
||||
const warningText =
|
||||
'Warning: Any tokens that have been nominated to a node will sacrifice rewards they are due for the current epoch. If you do not wish to sacrifice these, you should remove stake from a node at the end of an epoch before disassociation.';
|
||||
stakingPageAssociateTokens('2');
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 2.0);
|
||||
});
|
||||
cy.get(vegaWallet)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
2.0
|
||||
);
|
||||
});
|
||||
cy.get('button').contains('Select a validator to nominate').click();
|
||||
cy.get(ethWalletDissociateButton).click();
|
||||
cy.get(disassociationWarning).should('contain', warningText);
|
||||
stakingPageDisassociateAllTokens();
|
||||
cy.get(ethWalletContainer).within(() => {
|
||||
cy.contains(vegaWalletPublicKeyShort, { timeout: 20000 }).should(
|
||||
'not.exist'
|
||||
);
|
||||
});
|
||||
cy.get(ethWalletContainer).within(() => {
|
||||
cy.contains(vegaWalletPublicKeyShort, { timeout: 20000 }).should(
|
||||
'not.exist'
|
||||
);
|
||||
});
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 0.0);
|
||||
});
|
||||
cy.get(ethWalletContainer)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.contains(vegaWalletPublicKeyShort, { timeout: 20000 }).should(
|
||||
'not.exist'
|
||||
);
|
||||
});
|
||||
cy.get(ethWalletContainer)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.contains(vegaWalletPublicKeyShort, { timeout: 20000 }).should(
|
||||
'not.exist'
|
||||
);
|
||||
});
|
||||
cy.get(vegaWallet)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
0.0
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('Able to associate and disassociate vesting contract tokens', function () {
|
||||
@@ -200,9 +232,14 @@ context(
|
||||
cy.getByTestId('currency-title', txTimeout).should('have.length', 6);
|
||||
verifyEthWalletAssociatedBalance('2.0');
|
||||
verifyEthWalletTotalAssociatedBalance('2.0');
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 2.0);
|
||||
});
|
||||
cy.get(vegaWallet)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
2.0
|
||||
);
|
||||
});
|
||||
cy.get(vegaWalletUnstakedBalance, txTimeout).should('contain', 2.0);
|
||||
stakingPageDisassociateTokens('1', {
|
||||
type: 'contract',
|
||||
@@ -228,38 +265,61 @@ context(
|
||||
stakingPageAssociateTokens('21', { type: 'wallet' });
|
||||
cy.get('button').contains('Select a validator to nominate').click();
|
||||
stakingPageAssociateTokens('37', { type: 'contract' });
|
||||
cy.get(vestingContractSection).within(() => {
|
||||
cy.get(associatedKey).should(
|
||||
'contain',
|
||||
Cypress.env('vegaWalletPublicKeyShort')
|
||||
);
|
||||
cy.get(associatedAmount, txTimeout).should('contain', 37);
|
||||
});
|
||||
cy.get(vegaInWalletSection).within(() => {
|
||||
cy.get(associatedKey).should(
|
||||
'contain',
|
||||
Cypress.env('vegaWalletPublicKeyShort')
|
||||
);
|
||||
cy.get(associatedAmount, txTimeout).should('contain', 21);
|
||||
});
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 58);
|
||||
});
|
||||
cy.get(vestingContractSection)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(associatedKey).should(
|
||||
'contain',
|
||||
Cypress.env('vegaWalletPublicKeyShort')
|
||||
);
|
||||
cy.get(associatedAmount, txTimeout).should('contain', 37);
|
||||
});
|
||||
cy.get(vegaInWalletSection)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(associatedKey).should(
|
||||
'contain',
|
||||
Cypress.env('vegaWalletPublicKeyShort')
|
||||
);
|
||||
cy.get(associatedAmount, txTimeout).should('contain', 21);
|
||||
});
|
||||
cy.get(vegaWallet)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
58
|
||||
);
|
||||
});
|
||||
stakingPageDisassociateTokens('6', { type: 'contract' });
|
||||
cy.get(vestingContractSection).within(() => {
|
||||
cy.get(associatedAmount, txTimeout).should('contain', 31);
|
||||
});
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 52);
|
||||
});
|
||||
cy.get(vestingContractSection)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(associatedAmount, txTimeout).should('contain', 31);
|
||||
});
|
||||
cy.get(vegaWallet)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
52
|
||||
);
|
||||
});
|
||||
navigateTo(navigation.validators);
|
||||
stakingPageDisassociateTokens('9', { type: 'wallet' });
|
||||
cy.get(vegaInWalletSection).within(() => {
|
||||
cy.get(associatedAmount, txTimeout).should('contain', 12);
|
||||
});
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 43);
|
||||
});
|
||||
cy.get(vegaInWalletSection)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(associatedAmount, txTimeout).should('contain', 12);
|
||||
});
|
||||
cy.get(vegaWallet)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
43
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('Not able to associate more tokens than owned', function () {
|
||||
@@ -318,9 +378,14 @@ context(
|
||||
Cypress.env('vegaWalletPublicKey2')
|
||||
);
|
||||
stakingPageAssociateTokens('2');
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 2.0);
|
||||
});
|
||||
cy.get(vegaWallet)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
2.0
|
||||
);
|
||||
});
|
||||
cy.get(associateCompleteText).should(
|
||||
'have.text',
|
||||
`Vega key ${Cypress.env(
|
||||
|
||||
@@ -4,10 +4,7 @@ import {
|
||||
waitForSpinner,
|
||||
} from '../../support/common.functions';
|
||||
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
||||
import {
|
||||
depositAsset,
|
||||
vegaWalletTeardown,
|
||||
} from '../../support/wallet-teardown.functions';
|
||||
import { depositAsset } from '../../support/wallet-teardown.functions';
|
||||
|
||||
const withdraw = 'withdraw';
|
||||
const withdrawalForm = 'withdraw-form';
|
||||
@@ -25,6 +22,13 @@ const withdrawalAmount = 'withdrawal-amount';
|
||||
const withdrawalRecipient = 'withdrawal-recipient';
|
||||
const withdrawFundsButton = 'withdraw-funds';
|
||||
const completeWithdrawalButton = 'complete-withdrawal';
|
||||
const tableTxHash = '[col-id="txHash"]';
|
||||
const tableAssetSymbol = '[col-id="asset.symbol"]';
|
||||
const tableAmount = '[col-id="amount"]';
|
||||
const tableReceiverAddress = '[col-id="details.receiverAddress"]';
|
||||
const tableWithdrawnTimeStamp = '[col-id="withdrawnTimestamp"]';
|
||||
const tableWithdrawnStatus = '[col-id="status"]';
|
||||
const tableCreatedTimeStamp = '[col-id="createdTimestamp"]';
|
||||
const usdtName = 'USDC (local)';
|
||||
const usdcEthAddress = '0x1b8a1B6CBE5c93609b46D1829Cc7f3Cb8eeE23a0';
|
||||
const usdcSymbol = 'tUSDC';
|
||||
@@ -42,26 +46,23 @@ context(
|
||||
cy.visit('/');
|
||||
// When running tests locally, will fail if run without restarting capsule
|
||||
cy.updateCapsuleMultiSig().then(() => {
|
||||
depositAsset(usdcEthAddress, '100');
|
||||
ethereumWalletConnect();
|
||||
depositAsset(usdcEthAddress, '1000', 5);
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach('Navigate to withdrawal page', function () {
|
||||
cy.clearLocalStorage();
|
||||
cy.reload();
|
||||
waitForSpinner();
|
||||
navigateTo(navigation.withdraw);
|
||||
cy.connectVegaWallet();
|
||||
ethereumWalletConnect();
|
||||
vegaWalletTeardown();
|
||||
});
|
||||
|
||||
it('Able to open withdrawal form with vega wallet connected', function () {
|
||||
// needs to reload page for withdrawal form to be displayed in ci - not reproducible outside of ci
|
||||
cy.reload();
|
||||
waitForSpinner();
|
||||
ethereumWalletConnect();
|
||||
cy.getByTestId(withdraw).should('be.visible').click();
|
||||
cy.getByTestId(withdrawalForm).within(() => {
|
||||
cy.getByTestId(withdrawalForm, txTimeout).within(() => {
|
||||
cy.get('select').find('option').should('have.length.at.least', 2);
|
||||
cy.getByTestId(ethAddressInput).should('be.visible');
|
||||
cy.getByTestId(amountInput).should('be.visible');
|
||||
@@ -70,7 +71,7 @@ context(
|
||||
|
||||
it('Unable to submit withdrawal with invalid fields', function () {
|
||||
cy.getByTestId(withdraw).should('be.visible').click();
|
||||
cy.getByTestId(withdrawalForm).within(() => {
|
||||
cy.getByTestId(withdrawalForm, txTimeout).within(() => {
|
||||
cy.get('select').select(usdtSelectValue, { force: true });
|
||||
cy.getByTestId(balanceAvailable, txTimeout).should('exist');
|
||||
cy.getByTestId(submitWithdrawalButton).click();
|
||||
@@ -94,7 +95,7 @@ context(
|
||||
it('Able to withdraw asset: -eth wallet connected -withdraw funds button', function () {
|
||||
// fill in withdrawal form
|
||||
cy.getByTestId(withdraw).should('be.visible').click();
|
||||
cy.getByTestId(withdrawalForm).within(() => {
|
||||
cy.getByTestId(withdrawalForm, txTimeout).within(() => {
|
||||
cy.get('select').select(usdtSelectValue, { force: true });
|
||||
cy.getByTestId(balanceAvailable, txTimeout).should('exist');
|
||||
cy.getByTestId(withdrawalThreshold).should(
|
||||
@@ -102,7 +103,7 @@ context(
|
||||
'100,000.00000T'
|
||||
);
|
||||
cy.getByTestId(delayTime).should('have.text', 'None');
|
||||
cy.getByTestId(amountInput).click().type('100');
|
||||
cy.getByTestId(amountInput).click().type('120');
|
||||
cy.getByTestId(submitWithdrawalButton).click();
|
||||
});
|
||||
|
||||
@@ -116,7 +117,7 @@ context(
|
||||
.should('have.attr', 'href')
|
||||
.and('contain', '/txs/');
|
||||
cy.getByTestId(withdrawalAssetSymbol).should('have.text', usdcSymbol);
|
||||
cy.getByTestId(withdrawalAmount).should('have.text', '100.00');
|
||||
cy.getByTestId(withdrawalAmount).should('have.text', '120.00');
|
||||
cy.getByTestId(withdrawalRecipient)
|
||||
.should('have.text', truncatedWithdrawalEthAddress)
|
||||
.and('have.attr', 'href')
|
||||
@@ -128,26 +129,20 @@ context(
|
||||
'Withdraw asset complete'
|
||||
);
|
||||
cy.getByTestId(dialogClose).click();
|
||||
|
||||
// need to reload page to see withdrawal history complete
|
||||
cy.reload();
|
||||
waitForAssetsDisplayed(usdtName);
|
||||
|
||||
// withdrawal history for complete withdrawal displayed
|
||||
cy.get('[col-id="txHash"]', txTimeout)
|
||||
.should('have.length.above', 1)
|
||||
.eq(1)
|
||||
cy.get(tableWithdrawnStatus)
|
||||
.eq(1, txTimeout)
|
||||
.should('have.text', 'Completed')
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.get('[col-id="asset.symbol"]').should('have.text', usdcSymbol);
|
||||
cy.get('[col-id="amount"]').should('have.text', '100.00');
|
||||
cy.get('[col-id="details.receiverAddress"]')
|
||||
cy.get(tableAssetSymbol).should('have.text', usdcSymbol);
|
||||
cy.get(tableAmount).should('have.text', '120.00');
|
||||
cy.get(tableReceiverAddress)
|
||||
.find('a')
|
||||
.should('have.attr', 'href')
|
||||
.and('contain', 'https://sepolia.etherscan.io/address/');
|
||||
cy.get('[col-id="withdrawnTimestamp"]').should('not.be.empty');
|
||||
cy.get('[col-id="status"]').should('have.text', 'Completed');
|
||||
cy.get('[col-id="txHash"]')
|
||||
cy.get(tableWithdrawnTimeStamp).should('not.be.empty');
|
||||
cy.get(tableTxHash)
|
||||
.find('a')
|
||||
.should('have.attr', 'href')
|
||||
.and('contain', 'https://sepolia.etherscan.io/tx/');
|
||||
@@ -155,16 +150,16 @@ context(
|
||||
});
|
||||
|
||||
// Skipping because of bug #1857
|
||||
it.skip('Able to withdraw asset: -eth wallet not connected', function () {
|
||||
it('Able to withdraw asset: -eth wallet not connected', function () {
|
||||
const ethWalletAddress = Cypress.env('ethWalletPublicKey');
|
||||
cy.reload();
|
||||
waitForAssetsDisplayed(usdtName);
|
||||
// fill in withdrawal form
|
||||
cy.getByTestId(withdraw).should('be.visible').click();
|
||||
cy.getByTestId(withdrawalForm).within(() => {
|
||||
cy.getByTestId(withdrawalForm, txTimeout).within(() => {
|
||||
cy.get('select').select(usdtSelectValue, { force: true });
|
||||
cy.getByTestId(ethAddressInput).should('be.empty');
|
||||
cy.getByTestId(amountInput).click().type('100');
|
||||
cy.getByTestId(amountInput).click().type('110');
|
||||
cy.getByTestId(submitWithdrawalButton).click();
|
||||
|
||||
// Need eth address to submit withdrawal
|
||||
@@ -180,20 +175,20 @@ context(
|
||||
'Transaction complete'
|
||||
);
|
||||
cy.getByTestId(dialogClose).click();
|
||||
|
||||
cy.getByTestId(completeWithdrawalButton)
|
||||
.eq(0)
|
||||
.parent()
|
||||
cy.get(tableTxHash)
|
||||
.eq(1)
|
||||
.should('have.text', 'Complete withdrawal')
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.get('[col-id="asset.symbol"]').should('have.text', usdcSymbol);
|
||||
cy.get('[col-id="amount"]').should('have.text', '100.00');
|
||||
cy.get('[col-id="details.receiverAddress"]')
|
||||
cy.get(tableAssetSymbol).should('have.text', usdcSymbol);
|
||||
cy.get(tableAmount).should('have.text', '110.00');
|
||||
cy.get(tableReceiverAddress)
|
||||
.find('a')
|
||||
.should('have.attr', 'href')
|
||||
.and('contain', 'https://sepolia.etherscan.io/address/');
|
||||
cy.get('[col-id="createdTimestamp"]').should('not.be.empty');
|
||||
cy.get(tableCreatedTimeStamp).should('not.be.empty');
|
||||
cy.getByTestId(completeWithdrawalButton).click();
|
||||
// Unable to complete withdrawal in Capsule
|
||||
});
|
||||
});
|
||||
|
||||
@@ -202,26 +197,28 @@ context(
|
||||
const expectedErrorTxt = `You are connected in a view only state for public key: ${vegaWalletPubKey}. In order to send transactions you must connect to a real wallet.`;
|
||||
|
||||
// Disconnect vega wallet
|
||||
cy.getByTestId('manage-vega-wallet').click();
|
||||
cy.getByTestId('manage-vega-wallet').last().click();
|
||||
cy.getByTestId('disconnect').click();
|
||||
|
||||
cy.connectPublicKey(vegaWalletPubKey);
|
||||
cy.getByTestId(withdraw).should('be.visible').click();
|
||||
cy.getByTestId(withdrawalForm).within(() => {
|
||||
cy.getByTestId(withdrawalForm, txTimeout).within(() => {
|
||||
cy.get('select').select(usdtSelectValue, { force: true });
|
||||
cy.getByTestId(balanceAvailable, txTimeout).should('exist');
|
||||
cy.getByTestId(amountInput).click().type('100');
|
||||
cy.getByTestId(submitWithdrawalButton).click();
|
||||
});
|
||||
|
||||
cy.getByTestId('dialog-content').within(() => {
|
||||
cy.get('h1').should('have.text', 'Transaction failed');
|
||||
cy.getByTestId('Error').should('have.text', expectedErrorTxt);
|
||||
});
|
||||
cy.getByTestId('dialog-content')
|
||||
.last()
|
||||
.within(() => {
|
||||
cy.get('h1').should('have.text', 'Transaction failed');
|
||||
cy.getByTestId('Error').should('have.text', expectedErrorTxt);
|
||||
});
|
||||
});
|
||||
|
||||
function waitForAssetsDisplayed(expectedAsset: string) {
|
||||
cy.contains(expectedAsset, txTimeout).should('be.visible');
|
||||
cy.getByTestId('currency-title').should('contain.text', expectedAsset);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@@ -90,6 +90,7 @@ export function getSubmittedProposalFromProposalList(proposalTitle: string) {
|
||||
export function getProposalIdFromList(proposalTitle: string) {
|
||||
cy.contains(proposalTitle)
|
||||
.parentsUntil(proposalListItem)
|
||||
.last()
|
||||
.within(() => {
|
||||
cy.get(proposalDetails)
|
||||
.invoke('text')
|
||||
@@ -133,7 +134,7 @@ export function waitForProposalSync() {
|
||||
// before proposal appears in the list - so rather than hard coded wait - we just wait on the
|
||||
// delegation checks that are performed on the governance page.
|
||||
|
||||
cy.intercept('POST', '/query', (req) => {
|
||||
cy.intercept('POST', '/graphql', (req) => {
|
||||
if (req.body.operationName === 'Delegations') {
|
||||
req.alias = 'proposalDelegationsCompletion';
|
||||
}
|
||||
@@ -143,7 +144,7 @@ export function waitForProposalSync() {
|
||||
cy.wait(['@proposalDelegationsCompletion', '@proposalDelegationsCompletion']);
|
||||
|
||||
// Turn off this intercept from here on in
|
||||
cy.intercept('POST', '/query', (req) => {
|
||||
cy.intercept('POST', '/graphql', (req) => {
|
||||
if (req.body.operationName === 'Delegations') {
|
||||
req.continue();
|
||||
}
|
||||
|
||||
@@ -35,18 +35,25 @@ const stakingBridgeContract = new StakingBridge(
|
||||
);
|
||||
const vestingContract = new TokenVesting(vegaTokenContractAddress, signer);
|
||||
|
||||
export async function depositAsset(assetEthAddress: string, amount: string) {
|
||||
export async function depositAsset(
|
||||
assetEthAddress: string,
|
||||
amount: string,
|
||||
decimalPlaces: number
|
||||
) {
|
||||
// Approve asset
|
||||
const faucet = new TokenFaucetable(assetEthAddress, signer);
|
||||
cy.wrap(faucet.approve(Erc20BridgeAddress, amount + '0'.repeat(19)), {
|
||||
timeout: transactionTimeout,
|
||||
log: false,
|
||||
}).then(() => {
|
||||
cy.wrap(
|
||||
faucet.approve(Erc20BridgeAddress, amount + '0'.repeat(decimalPlaces + 1)),
|
||||
{
|
||||
timeout: transactionTimeout,
|
||||
log: false,
|
||||
}
|
||||
).then(() => {
|
||||
const collateralBridge = new CollateralBridge(Erc20BridgeAddress, signer);
|
||||
cy.wrap(
|
||||
collateralBridge.deposit_asset(
|
||||
assetEthAddress,
|
||||
amount + '0'.repeat(18),
|
||||
amount + '0'.repeat(decimalPlaces),
|
||||
'0x' + vegaWalletPubKey
|
||||
),
|
||||
{ timeout: transactionTimeout, log: false }
|
||||
@@ -102,27 +109,49 @@ async function vegaWalletTeardownStaking(stakingBridgeContract: StakingBridge) {
|
||||
cy.highlight('Tearing down staking tokens from vega wallet if present');
|
||||
cy.wrap(
|
||||
stakingBridgeContract.stake_balance(ethWalletPubKey, vegaWalletPubKey),
|
||||
{ timeout: transactionTimeout, log: false }
|
||||
{ timeout: transactionTimeout }
|
||||
).then((stakeBalance) => {
|
||||
if (Number(stakeBalance) != 0) {
|
||||
cy.get('[data-testid="vega-wallet-balance-unstaked"]:visible').within(
|
||||
() => {
|
||||
cy.get(associatedAmountInWallet)
|
||||
.invoke('text')
|
||||
.then(($walletAmount) => {
|
||||
cy.wrap(
|
||||
stakingBridgeContract.remove_stake(
|
||||
String(stakeBalance),
|
||||
vegaWalletPubKey
|
||||
),
|
||||
{ timeout: transactionTimeout, log: false }
|
||||
);
|
||||
cy.get(associatedAmountInWallet, {
|
||||
cy.get(vegaWalletContainer).within(() => {
|
||||
cy.getByTestId('currency-value')
|
||||
.first()
|
||||
.invoke('text')
|
||||
.then(($associatedAmount) => {
|
||||
cy.wrap(
|
||||
stakingBridgeContract.remove_stake(
|
||||
String(stakeBalance),
|
||||
vegaWalletPubKey
|
||||
),
|
||||
{ timeout: transactionTimeout }
|
||||
);
|
||||
cy.wrap(
|
||||
vestingContract.stake_balance(ethWalletPubKey, vegaWalletPubKey),
|
||||
{
|
||||
timeout: transactionTimeout,
|
||||
}).should('not.have.text', $walletAmount);
|
||||
log: false,
|
||||
}
|
||||
).then((vestingAmount) => {
|
||||
if (Number(vestingAmount) != 0) {
|
||||
cy.contains('Associated', {
|
||||
timeout: transactionTimeout,
|
||||
})
|
||||
.parent()
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.getByTestId('currency-value', {
|
||||
timeout: transactionTimeout,
|
||||
})
|
||||
.should('have.length', 1)
|
||||
.invoke('text')
|
||||
.as('displayedAmount');
|
||||
cy.get('@displayedAmount', {
|
||||
timeout: transactionTimeout,
|
||||
}).should('not.eq', $associatedAmount);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -136,7 +165,7 @@ async function vegaWalletTeardownVesting(vestingContract: TokenVesting) {
|
||||
if (Number(vestingAmount) != 0) {
|
||||
cy.wrap(
|
||||
vestingContract.remove_stake(String(vestingAmount), vegaWalletPubKey),
|
||||
{ timeout: transactionTimeout, log: false }
|
||||
{ timeout: transactionTimeout }
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
+10
-14
@@ -1,8 +1,7 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { ProposalRejectionReason, ProposalState } from '@vegaprotocol/types';
|
||||
import { format } from 'date-fns';
|
||||
import { formatDateWithLocalTimezone } from '@vegaprotocol/utils';
|
||||
|
||||
import { DATE_FORMAT_DETAILED } from '../../../../lib/date-formats';
|
||||
import { generateProposal } from '../../test-helpers/generate-proposals';
|
||||
import { ProposalChangeTable } from './proposal-change-table';
|
||||
|
||||
@@ -24,16 +23,15 @@ it('Renders all data for table', () => {
|
||||
expect(screen.getByText('Closes on')).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(
|
||||
format(new Date(proposal?.terms.closingDatetime), DATE_FORMAT_DETAILED)
|
||||
formatDateWithLocalTimezone(new Date(proposal?.terms.closingDatetime))
|
||||
)
|
||||
).toBeInTheDocument();
|
||||
|
||||
expect(screen.getByText('Proposed enactment')).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(
|
||||
format(
|
||||
new Date(proposal?.terms.enactmentDatetime || 0),
|
||||
DATE_FORMAT_DETAILED
|
||||
formatDateWithLocalTimezone(
|
||||
new Date(proposal?.terms.enactmentDatetime || 0)
|
||||
)
|
||||
)
|
||||
).toBeInTheDocument();
|
||||
@@ -43,7 +41,7 @@ it('Renders all data for table', () => {
|
||||
|
||||
expect(screen.getByText('Proposed on')).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(format(new Date(proposal?.datetime), DATE_FORMAT_DETAILED))
|
||||
screen.getByText(formatDateWithLocalTimezone(new Date(proposal?.datetime)))
|
||||
).toBeInTheDocument();
|
||||
|
||||
expect(screen.getByText('Type')).toBeInTheDocument();
|
||||
@@ -62,16 +60,15 @@ it('Changes data based on if data is in future or past', () => {
|
||||
expect(screen.getByText('Closed on')).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(
|
||||
format(new Date(proposal?.terms.closingDatetime), DATE_FORMAT_DETAILED)
|
||||
formatDateWithLocalTimezone(new Date(proposal?.terms.closingDatetime))
|
||||
)
|
||||
).toBeInTheDocument();
|
||||
|
||||
expect(screen.getByText('Enacted on')).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(
|
||||
format(
|
||||
new Date(proposal?.terms.enactmentDatetime || 0),
|
||||
DATE_FORMAT_DETAILED
|
||||
formatDateWithLocalTimezone(
|
||||
new Date(proposal?.terms.enactmentDatetime || 0)
|
||||
)
|
||||
)
|
||||
).toBeInTheDocument();
|
||||
@@ -91,9 +88,8 @@ it('Does not render enactment time for freeform proposal', () => {
|
||||
expect(screen.queryByText('Enacted on')).not.toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByText(
|
||||
format(
|
||||
new Date(proposal?.terms.enactmentDatetime || 0),
|
||||
DATE_FORMAT_DETAILED
|
||||
formatDateWithLocalTimezone(
|
||||
new Date(proposal?.terms.enactmentDatetime || 0)
|
||||
)
|
||||
)
|
||||
).not.toBeInTheDocument();
|
||||
|
||||
+6
-8
@@ -1,12 +1,11 @@
|
||||
import { format, isFuture } from 'date-fns';
|
||||
import { isFuture } from 'date-fns';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { formatDateWithLocalTimezone } from '@vegaprotocol/utils';
|
||||
import {
|
||||
KeyValueTable,
|
||||
KeyValueTableRow,
|
||||
RoundedWrapper,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { DATE_FORMAT_DETAILED } from '../../../../lib/date-formats';
|
||||
import { CurrentProposalState } from '../current-proposal-state';
|
||||
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
|
||||
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
|
||||
@@ -35,16 +34,15 @@ export const ProposalChangeTable = ({ proposal }: ProposalChangeTableProps) => {
|
||||
{isFuture(new Date(terms?.closingDatetime))
|
||||
? t('closesOn')
|
||||
: t('closedOn')}
|
||||
{format(new Date(terms?.closingDatetime), DATE_FORMAT_DETAILED)}
|
||||
{formatDateWithLocalTimezone(new Date(terms?.closingDatetime))}
|
||||
</KeyValueTableRow>
|
||||
{terms?.change.__typename !== 'NewFreeform' ? (
|
||||
<KeyValueTableRow>
|
||||
{isFuture(new Date(terms?.enactmentDatetime || 0))
|
||||
? t('proposedEnactment')
|
||||
: t('enactedOn')}
|
||||
{format(
|
||||
new Date(terms?.enactmentDatetime || 0),
|
||||
DATE_FORMAT_DETAILED
|
||||
{formatDateWithLocalTimezone(
|
||||
new Date(terms?.enactmentDatetime || 0)
|
||||
)}
|
||||
</KeyValueTableRow>
|
||||
) : null}
|
||||
@@ -54,7 +52,7 @@ export const ProposalChangeTable = ({ proposal }: ProposalChangeTableProps) => {
|
||||
</KeyValueTableRow>
|
||||
<KeyValueTableRow>
|
||||
{t('proposedOn')}
|
||||
{format(new Date(proposal?.datetime), DATE_FORMAT_DETAILED)}
|
||||
{formatDateWithLocalTimezone(new Date(proposal?.datetime))}
|
||||
</KeyValueTableRow>
|
||||
{proposal?.rejectionReason ? (
|
||||
<KeyValueTableRow>
|
||||
|
||||
@@ -40,18 +40,6 @@
|
||||
line-height: calc(min(var(--ag-line-height, 26px), 26px) - 4px);
|
||||
}
|
||||
|
||||
/* Light variables */
|
||||
.ag-theme-balham {
|
||||
--ag-background-color: theme(colors.white);
|
||||
--ag-border-color: theme(colors.neutral[300]);
|
||||
--ag-header-background-color: theme(colors.white);
|
||||
--ag-odd-row-background-color: theme(colors.white);
|
||||
--ag-header-column-separator-color: theme(colors.neutral[300]);
|
||||
--ag-row-border-color: theme(colors.white);
|
||||
--ag-row-hover-color: theme(colors.neutral[100]);
|
||||
--ag-font-size: 12px;
|
||||
}
|
||||
|
||||
/* Dark variables */
|
||||
.ag-theme-balham-dark {
|
||||
--ag-background-color: theme(colors.black);
|
||||
@@ -63,3 +51,10 @@
|
||||
--ag-row-hover-color: theme(colors.neutral[800]);
|
||||
--ag-font-size: 12px;
|
||||
}
|
||||
|
||||
.validators-table .ag-theme-balham-dark .ag-body-horizontal-scroll {
|
||||
opacity: 0.75;
|
||||
}
|
||||
.validators-table .ag-theme-balham-dark *:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
"tranche_end": "2023-05-20T00:00:00.000Z",
|
||||
"total_added": "19242.125",
|
||||
"total_removed": "959.3245960538025",
|
||||
"locked_amount": "10740.2904998553229338",
|
||||
"locked_amount": "10418.7792376543211777",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "188",
|
||||
@@ -845,7 +845,7 @@
|
||||
"tranche_end": "2023-05-06T00:00:00.000Z",
|
||||
"total_added": "14520",
|
||||
"total_removed": "5079.76864115505",
|
||||
"locked_amount": "1328.5631944444439712",
|
||||
"locked_amount": "1085.952592592592978",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "111",
|
||||
@@ -1680,7 +1680,7 @@
|
||||
"tranche_start": "2023-03-06T00:00:00.000Z",
|
||||
"tranche_end": "2023-04-06T00:00:00.000Z",
|
||||
"total_added": "14099",
|
||||
"total_removed": "3142.49002352036",
|
||||
"total_removed": "3722.49002352036",
|
||||
"locked_amount": "0",
|
||||
"deposits": [
|
||||
{
|
||||
@@ -2450,6 +2450,11 @@
|
||||
"user": "0xBe9F912Ad481C61B653463E8F1D2b2b310D49861",
|
||||
"tx": "0x191a1901917ada560c9c30efd3d24c0ec116b9dc131a6966cc67ad7e3701df3b"
|
||||
},
|
||||
{
|
||||
"amount": "580",
|
||||
"user": "0xAA4110D07E062bAA025BECb15B795447F58B8d2E",
|
||||
"tx": "0x795e8308c0001ad97f322ea94c382cc1799cfd8231a0c492fa8d54f16d2eef56"
|
||||
},
|
||||
{
|
||||
"amount": "30",
|
||||
"user": "0x8499411Bff99ddE9A02903008F917EEa0E27B42A",
|
||||
@@ -3599,10 +3604,17 @@
|
||||
"tx": "0x46d80a145d2f49ef3152cbfaa6d2bb054deabe21396ab43553a3f076e2db62e1"
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "580",
|
||||
"user": "0xAA4110D07E062bAA025BECb15B795447F58B8d2E",
|
||||
"tranche_id": 53,
|
||||
"tx": "0x795e8308c0001ad97f322ea94c382cc1799cfd8231a0c492fa8d54f16d2eef56"
|
||||
}
|
||||
],
|
||||
"total_tokens": "580",
|
||||
"withdrawn_tokens": "0",
|
||||
"remaining_tokens": "580"
|
||||
"withdrawn_tokens": "580",
|
||||
"remaining_tokens": "0"
|
||||
},
|
||||
{
|
||||
"address": "0x674038f225586317f3959C00D696Cb53cd52c16C",
|
||||
@@ -4703,7 +4715,7 @@
|
||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||
"total_added": "86666.297",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "51226.896539776924515462",
|
||||
"locked_amount": "51107.876034425155701037",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "86666.297",
|
||||
@@ -4769,7 +4781,7 @@
|
||||
"tranche_end": "2023-06-01T00:00:00.000Z",
|
||||
"total_added": "2500",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "394.848424145299",
|
||||
"locked_amount": "387.962962962963",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "2500",
|
||||
@@ -4802,7 +4814,7 @@
|
||||
"tranche_end": "2023-11-01T00:00:00.000Z",
|
||||
"total_added": "15000.000000000000015",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "14816.165647644927014816165647644927",
|
||||
"locked_amount": "14775.301932367149014775301932367149",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "1.5e-14",
|
||||
@@ -4890,7 +4902,7 @@
|
||||
"tranche_end": "2023-09-01T00:00:00.000Z",
|
||||
"total_added": "17500",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "11483.8961541364725",
|
||||
"locked_amount": "11436.2218196457315",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "12500",
|
||||
@@ -5157,7 +5169,7 @@
|
||||
"tranche_end": "2023-08-01T00:00:00.000Z",
|
||||
"total_added": "37500",
|
||||
"total_removed": "17836.1796921",
|
||||
"locked_amount": "18593.57015423572875",
|
||||
"locked_amount": "18489.717618170655",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "7500",
|
||||
@@ -5565,7 +5577,7 @@
|
||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||
"total_added": "129999.45",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "51180.15844229965399674",
|
||||
"locked_amount": "51061.24652818329987399",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "129999.45",
|
||||
@@ -5598,7 +5610,7 @@
|
||||
"tranche_end": "2024-04-01T00:00:00.000Z",
|
||||
"total_added": "54144.7663",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "49373.06871247784644592557",
|
||||
"locked_amount": "49298.9138196269965560045",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "54144.7663",
|
||||
@@ -5631,7 +5643,7 @@
|
||||
"tranche_end": "2023-09-03T00:00:00.000Z",
|
||||
"total_added": "62600",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "21051.60226407915008",
|
||||
"locked_amount": "20965.63247082699134",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "10000",
|
||||
@@ -5824,7 +5836,7 @@
|
||||
"tranche_end": "2023-09-17T00:00:00.000Z",
|
||||
"total_added": "5000",
|
||||
"total_removed": "0",
|
||||
"locked_amount": "1873.218702435312",
|
||||
"locked_amount": "1866.352105530188",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "5000",
|
||||
@@ -6882,7 +6894,7 @@
|
||||
"tranche_end": "2023-06-02T00:00:00.000Z",
|
||||
"total_added": "1939928.38",
|
||||
"total_removed": "1709370.7872515768348",
|
||||
"locked_amount": "158090.6912451388393129414",
|
||||
"locked_amount": "155426.5500030847769098336",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "1852091.69",
|
||||
@@ -40754,7 +40766,7 @@
|
||||
"tranche_end": "2023-06-05T00:00:00.000Z",
|
||||
"total_added": "3732368.4671",
|
||||
"total_removed": "715655.108029600523393",
|
||||
"locked_amount": "267431.675840398797767447499",
|
||||
"locked_amount": "263337.818306825404305623187",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "1998.95815",
|
||||
@@ -42146,8 +42158,8 @@
|
||||
"tranche_start": "2022-06-05T00:00:00.000Z",
|
||||
"tranche_end": "2023-12-05T00:00:00.000Z",
|
||||
"total_added": "15870102.715470999700000001",
|
||||
"total_removed": "866687.25765937723884852",
|
||||
"locked_amount": "6247983.1374161640607671780970752321127332",
|
||||
"total_removed": "867610.78878511272497352",
|
||||
"locked_amount": "6233466.5814528903248765151216390212111382",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "16249.93",
|
||||
@@ -42696,6 +42708,11 @@
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tx": "0x2e3b57da0245aea9164e96cd7421d82a3f34df2ab34bc9a64b91e629fb5cb31c"
|
||||
},
|
||||
{
|
||||
"amount": "923.531125735486125",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tx": "0xc5cea08b124cdf6264d5b0c7494d63d9de264b429822d9a4e4cfadc43e611a1b"
|
||||
},
|
||||
{
|
||||
"amount": "981.387731774910625",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
@@ -44840,6 +44857,12 @@
|
||||
"tranche_id": 2,
|
||||
"tx": "0x2e3b57da0245aea9164e96cd7421d82a3f34df2ab34bc9a64b91e629fb5cb31c"
|
||||
},
|
||||
{
|
||||
"amount": "923.531125735486125",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
"tranche_id": 2,
|
||||
"tx": "0xc5cea08b124cdf6264d5b0c7494d63d9de264b429822d9a4e4cfadc43e611a1b"
|
||||
},
|
||||
{
|
||||
"amount": "981.387731774910625",
|
||||
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
|
||||
@@ -46348,8 +46371,8 @@
|
||||
}
|
||||
],
|
||||
"total_tokens": "259998.8875",
|
||||
"withdrawn_tokens": "156789.08944273708375",
|
||||
"remaining_tokens": "103209.79805726291625"
|
||||
"withdrawn_tokens": "157712.620568472569875",
|
||||
"remaining_tokens": "102286.266931527430125"
|
||||
},
|
||||
{
|
||||
"address": "0x89051CAb67Bc7F8CC44F7e270c6EDaf1EC57676c",
|
||||
@@ -48725,7 +48748,7 @@
|
||||
"tranche_end": "2023-05-05T00:00:00.000Z",
|
||||
"total_added": "14597706.0446472999",
|
||||
"total_removed": "6168897.174282186485373182",
|
||||
"locked_amount": "46652.9124232901388230326056764886",
|
||||
"locked_amount": "33251.32064708015607663338925032586",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "129284.449",
|
||||
@@ -58824,7 +58847,7 @@
|
||||
"tranche_end": "2023-06-05T00:00:00.000Z",
|
||||
"total_added": "472355.6199999996",
|
||||
"total_removed": "44078.8527972103416",
|
||||
"locked_amount": "42376.077741542987921938344901044",
|
||||
"locked_amount": "41727.382613860946149215697311012",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "3000",
|
||||
|
||||
@@ -180,25 +180,21 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
it('oracle displayed', () => {
|
||||
cy.getByTestId(marketTitle).contains('Oracle').click();
|
||||
|
||||
validateMarketDataRow(0, 'Settlement Data Property', 'prices.BTC.value');
|
||||
validateMarketDataRow(
|
||||
1,
|
||||
'Trading Termination Property',
|
||||
'termination.BTC.value'
|
||||
);
|
||||
|
||||
// check that links to github for oracle proofs are shown
|
||||
cy.getByTestId(accordionContent)
|
||||
.getByTestId('oracle-proof-links')
|
||||
.find(`[data-testid="${externalLink}"]`)
|
||||
.should('have.attr', 'href')
|
||||
.and('contain', 'https://github.com/vegaprotocol/well-known');
|
||||
.getByTestId('provider-name')
|
||||
.and('contain', 'Another oracle');
|
||||
|
||||
cy.getByTestId(accordionContent)
|
||||
.getByTestId('oracle-spec-links')
|
||||
.find(`[data-testid="${externalLink}"]`)
|
||||
.should('have.attr', 'href')
|
||||
.and('contain', '/oracles');
|
||||
.getByTestId('signed-proofs')
|
||||
.and('contain', '1');
|
||||
|
||||
cy.getByTestId(accordionContent)
|
||||
.getByTestId('verified-proofs')
|
||||
.and('contain', '1');
|
||||
|
||||
cy.getByTestId(accordionContent)
|
||||
.getByTestId('signed-proofs')
|
||||
.and('contain', '1');
|
||||
});
|
||||
|
||||
it('proposal displayed', () => {
|
||||
|
||||
@@ -85,7 +85,7 @@ describe('fills', { tags: '@regression' }, () => {
|
||||
cy.wrap($role)
|
||||
.invoke('text')
|
||||
.then((text) => {
|
||||
const roles = ['Maker', 'Taker'];
|
||||
const roles = ['Maker', 'Taker', '-'];
|
||||
expect(roles.indexOf(text.trim())).to.be.greaterThan(-1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,7 +6,7 @@ NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/maste
|
||||
NX_VEGA_ENV=VALIDATOR_TESTNET
|
||||
NX_VEGA_EXPLORER_URL=https://validator-testnet.explorer.vega.xyz
|
||||
NX_VEGA_NETWORKS={\"STAGNET3\":\"https://stagnet3.console.vega.xyz\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"TESTNET\":\"https://console.fairground.wtf\"}
|
||||
NX_VEGA_TOKEN_URL=https://validator-testnet.governance.fairground.wtf
|
||||
NX_VEGA_TOKEN_URL=https://validator-testnet.governance.vega.xyz
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
|
||||
|
||||
@@ -1,13 +1,50 @@
|
||||
import { Option } from '@vegaprotocol/ui-toolkit';
|
||||
import type { AssetFieldsFragment } from './__generated__/Asset';
|
||||
import classNames from 'classnames';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
export const AssetOption = ({ asset }: { asset: AssetFieldsFragment }) => {
|
||||
type AssetOptionProps = {
|
||||
asset: AssetFieldsFragment;
|
||||
balance?: ReactNode;
|
||||
};
|
||||
|
||||
export const Balance = ({
|
||||
balance,
|
||||
symbol,
|
||||
}: {
|
||||
balance?: string;
|
||||
symbol: string;
|
||||
}) =>
|
||||
balance ? (
|
||||
<div className="mt-1 font-alpha">
|
||||
{balance} {symbol}
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-vega-orange-500">{t('Fetching balance…')}</div>
|
||||
);
|
||||
|
||||
export const AssetOption = ({ asset, balance }: AssetOptionProps) => {
|
||||
return (
|
||||
<Option key={asset.id} value={asset.id}>
|
||||
<div className="flex flex-col items-start">
|
||||
<span>{asset.name}</span>
|
||||
<div className="text-[10px] font-mono w-full text-left break-all">
|
||||
<span className="text-gray-500">{asset.id} -</span> {asset.symbol}
|
||||
<div className="flex flex-row align-baseline gap-2">
|
||||
<span>{asset.name}</span>{' '}
|
||||
<span
|
||||
className={classNames(
|
||||
'bg-vega-light-200 dark:bg-vega-dark-200',
|
||||
'text-black dark:text-white text-xs',
|
||||
'py-[2px] px-[4px] rounded'
|
||||
)}
|
||||
>
|
||||
{asset.symbol}
|
||||
</span>
|
||||
</div>
|
||||
{balance}
|
||||
<div className="text-[12px] font-mono w-full text-left break-all">
|
||||
<span className="text-vega-light-300 dark:text-vega-dark-300">
|
||||
{asset.id}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</Option>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
export * from './__generated__/Asset';
|
||||
export * from './__generated__/Assets';
|
||||
export * from './asset-data-provider';
|
||||
export * from './assets-data-provider';
|
||||
export * from './asset-details-dialog';
|
||||
export * from './asset-details-table';
|
||||
export * from './asset-option';
|
||||
export * from './assets-data-provider';
|
||||
export * from './constants';
|
||||
export * from './use-balances-store';
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
import type BigNumber from 'bignumber.js';
|
||||
import type { AssetFieldsFragment } from './__generated__/Asset';
|
||||
import { create } from 'zustand';
|
||||
import * as Sentry from '@sentry/react';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
|
||||
type AssetWithBalance = {
|
||||
asset: AssetFieldsFragment;
|
||||
balanceOnEth?: BigNumber;
|
||||
balanceOnVega?: BigNumber;
|
||||
updatedAt: number;
|
||||
};
|
||||
|
||||
type SetBalanceArgs = Omit<AssetWithBalance, 'updatedAt'> & {
|
||||
ethBalanceFetcher?: () => Promise<BigNumber | undefined>;
|
||||
};
|
||||
|
||||
type BalancesStore = {
|
||||
balances: (AssetWithBalance & { fetchFromEth?: () => void })[];
|
||||
getBalance: (assetId: string) => AssetWithBalance | undefined;
|
||||
setBalance: (args: SetBalanceArgs) => void;
|
||||
refetch: (assetId: string) => void;
|
||||
};
|
||||
|
||||
export const useBalancesStore = create(
|
||||
immer<BalancesStore>((set, get) => ({
|
||||
balances: [],
|
||||
getBalance: (assetId) =>
|
||||
get().balances.find(({ asset: a }) => a.id === assetId),
|
||||
setBalance: ({ asset, balanceOnEth, balanceOnVega, ethBalanceFetcher }) => {
|
||||
set((state) => {
|
||||
const found = state.balances.find(({ asset: a }) => a.id === asset.id);
|
||||
const fetchFromEth = ethBalanceFetcher
|
||||
? () => {
|
||||
if (!ethBalanceFetcher) return;
|
||||
ethBalanceFetcher()
|
||||
.then((balance) => {
|
||||
if (balance) {
|
||||
get().setBalance({ asset, balanceOnEth: balance });
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
Sentry.captureException(err);
|
||||
});
|
||||
}
|
||||
: undefined;
|
||||
|
||||
if (found) {
|
||||
if (balanceOnEth) found.balanceOnEth = balanceOnEth;
|
||||
if (balanceOnVega) found.balanceOnVega = balanceOnVega;
|
||||
if (fetchFromEth) found.fetchFromEth = fetchFromEth;
|
||||
found.updatedAt = Date.now();
|
||||
} else {
|
||||
state.balances.push({
|
||||
asset,
|
||||
balanceOnEth,
|
||||
balanceOnVega,
|
||||
fetchFromEth,
|
||||
updatedAt: Date.now(),
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
refetch: (assetId) => {
|
||||
const found = get().balances.find((a) => a.asset.id === assetId);
|
||||
found?.fetchFromEth?.();
|
||||
},
|
||||
}))
|
||||
);
|
||||
@@ -0,0 +1,42 @@
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import { useGetBalanceOfERC20Token } from './use-get-balance-of-erc20-token';
|
||||
import type { AssetFieldsFragment } from '@vegaprotocol/assets';
|
||||
import { useBalancesStore } from '@vegaprotocol/assets';
|
||||
import { Balance } from '@vegaprotocol/assets';
|
||||
import { isAssetTypeERC20 } from '@vegaprotocol/utils';
|
||||
import { useTokenContract } from '@vegaprotocol/web3';
|
||||
|
||||
const REFETCH_DELAY = 5000;
|
||||
|
||||
export const AssetBalance = ({ asset }: { asset: AssetFieldsFragment }) => {
|
||||
const [setBalance, getBalance] = useBalancesStore((state) => [
|
||||
state.setBalance,
|
||||
state.getBalance,
|
||||
]);
|
||||
|
||||
const tokenContract = useTokenContract(
|
||||
isAssetTypeERC20(asset) ? asset.source.contractAddress : undefined
|
||||
);
|
||||
const ethBalanceFetcher = useGetBalanceOfERC20Token(tokenContract, asset);
|
||||
|
||||
const fetchFromEth = useCallback(async () => {
|
||||
const balance = await ethBalanceFetcher();
|
||||
if (balance) {
|
||||
setBalance({ asset, balanceOnEth: balance, ethBalanceFetcher });
|
||||
}
|
||||
}, [asset, ethBalanceFetcher, setBalance]);
|
||||
|
||||
useEffect(() => {
|
||||
const balance = getBalance(asset.id);
|
||||
if (!balance || Date.now() - balance.updatedAt > REFETCH_DELAY) {
|
||||
fetchFromEth();
|
||||
}
|
||||
}, [asset.id, fetchFromEth, getBalance]);
|
||||
|
||||
return (
|
||||
<Balance
|
||||
balance={getBalance(asset.id)?.balanceOnEth?.toString()}
|
||||
symbol={asset.symbol}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -41,6 +41,7 @@ import type { DepositBalances } from './use-deposit-balances';
|
||||
import { FaucetNotification } from './faucet-notification';
|
||||
import { ApproveNotification } from './approve-notification';
|
||||
import { usePersistentDeposit } from './use-persistent-deposit';
|
||||
import { AssetBalance } from './asset-balance';
|
||||
|
||||
interface FormFields {
|
||||
asset: string;
|
||||
@@ -253,9 +254,15 @@ export const DepositForm = ({
|
||||
value={selectedAsset?.id}
|
||||
hasError={Boolean(errors.asset?.message)}
|
||||
>
|
||||
{assets.filter(isAssetTypeERC20).map((a) => (
|
||||
<AssetOption asset={a} key={a.id} />
|
||||
))}
|
||||
{assets
|
||||
.filter((asset) => isAssetTypeERC20(asset))
|
||||
.map((asset) => (
|
||||
<AssetOption
|
||||
asset={asset}
|
||||
key={asset.id}
|
||||
balance={<AssetBalance asset={asset} />}
|
||||
/>
|
||||
))}
|
||||
</RichSelect>
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
export * from './__generated__/Deposit';
|
||||
export * from './asset-balance';
|
||||
export * from './deposit-container';
|
||||
export * from './deposit-dialog';
|
||||
export * from './deposit-form';
|
||||
export * from './deposit-limits';
|
||||
export * from './deposit-manager';
|
||||
export * from './deposits-provider';
|
||||
export * from './deposits-table';
|
||||
export * from './use-deposit-balances';
|
||||
export * from './deposits-provider';
|
||||
export * from './use-get-allowance';
|
||||
export * from './use-get-balance-of-erc20-token';
|
||||
export * from './use-get-deposit-maximum';
|
||||
export * from './use-get-deposited-amount';
|
||||
export * from './use-submit-approval';
|
||||
export * from './use-submit-faucet';
|
||||
export * from './deposit-dialog';
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
} from '@vegaprotocol/web3';
|
||||
import { isAssetTypeERC20 } from '@vegaprotocol/utils';
|
||||
import type { Asset } from '@vegaprotocol/assets';
|
||||
import { useBalancesStore } from '@vegaprotocol/assets';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
export const useSubmitFaucet = (
|
||||
@@ -25,8 +26,9 @@ export const useSubmitFaucet = (
|
||||
useEffect(() => {
|
||||
if (tx?.status === EthTxStatus.Confirmed) {
|
||||
getBalances();
|
||||
if (asset) useBalancesStore.getState().refetch(asset.id);
|
||||
}
|
||||
}, [tx?.status, getBalances]);
|
||||
}, [tx?.status, getBalances, asset]);
|
||||
|
||||
return {
|
||||
id,
|
||||
|
||||
@@ -152,6 +152,16 @@ const fills = (id?: string): FillFieldsFragment[] => [
|
||||
id: id || 'buyer-id',
|
||||
},
|
||||
}),
|
||||
fillFieldsFragment({
|
||||
id: '4',
|
||||
aggressor: Schema.Side.SIDE_UNSPECIFIED,
|
||||
market: {
|
||||
id: 'market-2',
|
||||
},
|
||||
buyer: {
|
||||
id: id || 'buyer-id',
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
export const fillsEventSubscription = (
|
||||
|
||||
@@ -198,4 +198,4 @@ export function useMarketInfoLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions
|
||||
}
|
||||
export type MarketInfoQueryHookResult = ReturnType<typeof useMarketInfoQuery>;
|
||||
export type MarketInfoLazyQueryHookResult = ReturnType<typeof useMarketInfoLazyQuery>;
|
||||
export type MarketInfoQueryResult = Apollo.QueryResult<MarketInfoQuery, MarketInfoQueryVariables>;
|
||||
export type MarketInfoQueryResult = Apollo.QueryResult<MarketInfoQuery, MarketInfoQueryVariables>;
|
||||
|
||||
@@ -103,6 +103,7 @@ const MarketInfoAccordion = ({
|
||||
content: <InsurancePoolInfoPanel market={market} account={a} />,
|
||||
})),
|
||||
];
|
||||
const product = market.tradableInstrument.instrument.product;
|
||||
|
||||
const marketSpecPanels = [
|
||||
{
|
||||
@@ -113,9 +114,13 @@ const MarketInfoAccordion = ({
|
||||
title: t('Instrument'),
|
||||
content: <InstrumentInfoPanel market={market} />,
|
||||
},
|
||||
{
|
||||
title: t('Oracle'),
|
||||
content: <OracleInfoPanel market={market} />,
|
||||
product.dataSourceSpecForSettlementData && {
|
||||
title: t('Settlement Oracle'),
|
||||
content: <OracleInfoPanel market={market} type="settlementData" />,
|
||||
},
|
||||
product.dataSourceSpecForTradingTermination && {
|
||||
title: t('Termination Oracle'),
|
||||
content: <OracleInfoPanel market={market} type="termination" />,
|
||||
},
|
||||
{
|
||||
title: t('Settlement asset'),
|
||||
|
||||
@@ -26,7 +26,7 @@ import { ConditionOperatorMapping } from '@vegaprotocol/types';
|
||||
import { MarketTradingModeMapping } from '@vegaprotocol/types';
|
||||
import { useEnvironment } from '@vegaprotocol/environment';
|
||||
import type { Provider } from '@vegaprotocol/oracles';
|
||||
import { useOracleProofs } from '@vegaprotocol/oracles';
|
||||
import { OracleBasicProfile, useOracleProofs } from '@vegaprotocol/oracles';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
|
||||
type PanelProps = Pick<
|
||||
@@ -449,49 +449,38 @@ export const LiquidityPriceRangeInfoPanel = ({
|
||||
|
||||
export const OracleInfoPanel = ({
|
||||
market,
|
||||
...props
|
||||
}: MarketInfoProps & PanelProps) => {
|
||||
type,
|
||||
}: MarketInfoProps &
|
||||
PanelProps & { type: 'settlementData' | 'termination' }) => {
|
||||
const product = market.tradableInstrument.instrument.product;
|
||||
const { VEGA_EXPLORER_URL, ORACLE_PROOFS_URL } = useEnvironment();
|
||||
const { data } = useOracleProofs(ORACLE_PROOFS_URL);
|
||||
|
||||
return (
|
||||
<MarketInfoTable
|
||||
data={{
|
||||
settlementDataProperty:
|
||||
product.dataSourceSpecBinding.settlementDataProperty,
|
||||
tradingTerminationProperty:
|
||||
product.dataSourceSpecBinding.tradingTerminationProperty,
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
<div
|
||||
className="flex flex-col gap-2 mt-4"
|
||||
<div className="flex flex-col gap-4">
|
||||
<DataSourceProof
|
||||
data-testid="oracle-proof-links"
|
||||
data={
|
||||
type === 'settlementData'
|
||||
? product.dataSourceSpecForSettlementData.data
|
||||
: product.dataSourceSpecForTradingTermination.data
|
||||
}
|
||||
providers={data}
|
||||
type={type}
|
||||
/>
|
||||
<ExternalLink
|
||||
data-testid="oracle-spec-links"
|
||||
href={`${VEGA_EXPLORER_URL}/oracles/${
|
||||
type === 'settlementData'
|
||||
? product.dataSourceSpecForSettlementData.id
|
||||
: product.dataSourceSpecForTradingTermination.id
|
||||
}`}
|
||||
>
|
||||
<DataSourceProof
|
||||
data={product.dataSourceSpecForSettlementData.data}
|
||||
providers={data}
|
||||
type="settlementData"
|
||||
/>
|
||||
<DataSourceProof
|
||||
data={product.dataSourceSpecForTradingTermination.data}
|
||||
providers={data}
|
||||
type="termination"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2" data-testid="oracle-spec-links">
|
||||
<ExternalLink
|
||||
href={`${VEGA_EXPLORER_URL}/oracles#${product.dataSourceSpecForSettlementData.id}`}
|
||||
>
|
||||
{t('View settlement data specification')}
|
||||
</ExternalLink>
|
||||
<ExternalLink
|
||||
href={`${VEGA_EXPLORER_URL}/oracles#${product.dataSourceSpecForTradingTermination.id}`}
|
||||
>
|
||||
{t('View termination specification')}
|
||||
</ExternalLink>
|
||||
</div>
|
||||
</MarketInfoTable>
|
||||
{type === 'settlementData'
|
||||
? t('View settlement data specification')
|
||||
: t('View termination specification')}
|
||||
</ExternalLink>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -551,20 +540,13 @@ const OracleLink = ({
|
||||
providers,
|
||||
signer,
|
||||
type,
|
||||
index,
|
||||
}: {
|
||||
providers: Provider[];
|
||||
signer: SignerKind;
|
||||
type: 'settlementData' | 'termination';
|
||||
index: number;
|
||||
}) => {
|
||||
const text =
|
||||
type === 'settlementData'
|
||||
? t('View settlement oracle details')
|
||||
: t('View termination oracle details');
|
||||
const textWithCount = index > 0 ? `${text} (${index + 1})` : text;
|
||||
|
||||
const provider = providers.find((p) => {
|
||||
const signerProviders = providers.filter((p) => {
|
||||
if (signer.__typename === 'PubKey') {
|
||||
if (
|
||||
p.oracle.type === 'public_key' &&
|
||||
@@ -586,14 +568,19 @@ const OracleLink = ({
|
||||
return false;
|
||||
});
|
||||
|
||||
if (!provider) {
|
||||
if (!signerProviders.length) {
|
||||
return <NoOracleProof type={type} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<p>
|
||||
<ExternalLink href={provider.github_link}>{textWithCount}</ExternalLink>
|
||||
</p>
|
||||
<div>
|
||||
{signerProviders.map((provider) => (
|
||||
<OracleBasicProfile
|
||||
key={provider.name}
|
||||
provider={provider}
|
||||
></OracleBasicProfile>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
const rootMain = require('../../../.storybook/main');
|
||||
|
||||
module.exports = {
|
||||
...rootMain,
|
||||
|
||||
core: { ...rootMain.core, builder: 'webpack5' },
|
||||
|
||||
stories: [
|
||||
...rootMain.stories,
|
||||
'../src/**/*.stories.mdx',
|
||||
'../src/**/*.stories.@(js|jsx|ts|tsx)',
|
||||
],
|
||||
addons: [
|
||||
...rootMain.addons,
|
||||
'@nrwl/react/plugins/storybook',
|
||||
'storybook-addon-themes',
|
||||
],
|
||||
webpackFinal: async (config, { configType }) => {
|
||||
// apply any global webpack configs that might have been specified in .storybook/main.js
|
||||
if (rootMain.webpackFinal) {
|
||||
config = await rootMain.webpackFinal(config, { configType });
|
||||
}
|
||||
|
||||
// add your own webpack tweaks if needed
|
||||
|
||||
return config;
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
<link rel="stylesheet" href="https://static.vega.xyz/fonts.css" />
|
||||
@@ -0,0 +1,90 @@
|
||||
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
||||
import classNames from 'classnames';
|
||||
import { useEffect } from 'react';
|
||||
import '../src/styles.css';
|
||||
export const parameters = {
|
||||
actions: { argTypesRegex: '^on[A-Z].*' },
|
||||
backgrounds: { disable: true },
|
||||
layout: 'fullscreen',
|
||||
a11y: {
|
||||
config: {
|
||||
rules: [
|
||||
{
|
||||
// Disabled only for storybook because we display both the dark and light variants of the components on the same page without differentiating the ids, so it will always error.
|
||||
id: 'duplicate-id-aria',
|
||||
selector: '[data-testid="form-group"] > label',
|
||||
},
|
||||
{
|
||||
// Disabled because we can't control the radix radio group component and it claims to be accessible to begin with, so hopefully no issues.
|
||||
id: 'button-name',
|
||||
selector: '[role=radiogroup] > button',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const globalTypes = {
|
||||
theme: {
|
||||
name: 'Theme',
|
||||
description: 'Global theme for components',
|
||||
defaultValue: 'dark',
|
||||
toolbar: {
|
||||
icon: 'circlehollow',
|
||||
items: [
|
||||
{ value: 'light', title: 'Light' },
|
||||
{ value: 'dark', title: 'Dark' },
|
||||
{ value: 'sideBySide', title: 'Side by side' },
|
||||
],
|
||||
showName: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const StoryWrapper = ({ children, fill }) => {
|
||||
const classes = classNames(
|
||||
'p-4',
|
||||
'bg-white dark:bg-black',
|
||||
'text-neutral-800 dark:text-neutral-200',
|
||||
{
|
||||
'w-screen h-screen': fill,
|
||||
}
|
||||
);
|
||||
return <div className={classes}>{children}</div>;
|
||||
};
|
||||
|
||||
const ThemeWrapper = (Story, context) => {
|
||||
const theme = context.parameters.theme || context.globals.theme;
|
||||
const { setTheme } = useThemeSwitcher();
|
||||
|
||||
useEffect(() => {
|
||||
// in side by side mode a 'dark' class on the html tag will interfere
|
||||
// making the light 'side' dark, so remove it in that case
|
||||
if (theme === 'sideBySide') {
|
||||
document.documentElement.classList.remove('dark');
|
||||
} else {
|
||||
setTheme(theme);
|
||||
}
|
||||
}, [setTheme, theme]);
|
||||
|
||||
return theme === 'sideBySide' ? (
|
||||
<>
|
||||
<div className="bg-white text-black">
|
||||
<StoryWrapper>
|
||||
<Story />
|
||||
</StoryWrapper>
|
||||
</div>
|
||||
<div className="dark bg-black text-white">
|
||||
<StoryWrapper>
|
||||
<Story />
|
||||
</StoryWrapper>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<StoryWrapper fill={true}>
|
||||
<Story />
|
||||
</StoryWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export const decorators = [ThemeWrapper];
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"emitDecoratorMetadata": true,
|
||||
"outDir": ""
|
||||
},
|
||||
"files": [
|
||||
"../../../node_modules/@nrwl/react/typings/styled-jsx.d.ts",
|
||||
"../../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
|
||||
"../../../node_modules/@nrwl/react/typings/image.d.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"../**/*.spec.ts",
|
||||
"../**/*.spec.js",
|
||||
"../**/*.spec.tsx",
|
||||
"../**/*.spec.jsx",
|
||||
"jest.config.ts"
|
||||
],
|
||||
"include": ["../src/**/*", "*.js"]
|
||||
}
|
||||
@@ -7,4 +7,5 @@ export default {
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
|
||||
coverageDirectory: '../../coverage/libs/oracles',
|
||||
setupFilesAfterEnv: ['./src/setup-tests.ts'],
|
||||
};
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
const { join } = require('path');
|
||||
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {
|
||||
config: join(__dirname, 'tailwind.config.js'),
|
||||
},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
||||
@@ -38,6 +38,44 @@
|
||||
"jestConfig": "libs/oracles/jest.config.ts",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
},
|
||||
"storybook": {
|
||||
"executor": "@nrwl/storybook:storybook",
|
||||
"options": {
|
||||
"uiFramework": "@storybook/react",
|
||||
"port": 4400,
|
||||
"config": {
|
||||
"configFolder": "libs/oracles/.storybook"
|
||||
}
|
||||
},
|
||||
"configurations": {
|
||||
"ci": {
|
||||
"quiet": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"build-storybook": {
|
||||
"executor": "@nrwl/storybook:build",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"options": {
|
||||
"uiFramework": "@storybook/react",
|
||||
"outputPath": "dist/storybook/oracles",
|
||||
"config": {
|
||||
"configFolder": "libs/oracles/.storybook"
|
||||
}
|
||||
},
|
||||
"configurations": {
|
||||
"ci": {
|
||||
"quiet": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"build-spec": {
|
||||
"executor": "@nrwl/workspace:run-commands",
|
||||
"outputs": [],
|
||||
"options": {
|
||||
"command": "yarn tsc --project ./libs/oracles/tsconfig.spec.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1 @@
|
||||
export * from './lib/oracle-schema';
|
||||
export * from './lib/use-oracle-proofs';
|
||||
export * from './lib/use-oracle-spec-binding-data';
|
||||
export * from './lib/__generated__/OracleSpecDataConnection';
|
||||
export * from './lib';
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
export * from './OracleSpecDataConnection';
|
||||
@@ -0,0 +1 @@
|
||||
export * from './oracle-basic-profile';
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './oracle-basic-profile.stories';
|
||||
export * from './oracle-basic-profile';
|
||||
@@ -0,0 +1,45 @@
|
||||
import { OracleBasicProfile } from './oracle-basic-profile';
|
||||
import type { Provider } from '../../oracle-schema';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
describe('OracleBasicProfile', () => {
|
||||
const testProvider = {
|
||||
name: 'Test oracle',
|
||||
url: 'https://zombo.com',
|
||||
description_markdown:
|
||||
'Some markdown describing the oracle provider.\n\nTwitter: @FacesPics2\n',
|
||||
oracle: {
|
||||
status: 'GOOD',
|
||||
status_reason: '',
|
||||
first_verified: '2023-02-28T00:00:00.000Z',
|
||||
last_verified: '2023-02-28T00:00:00.000Z',
|
||||
type: 'eth_address',
|
||||
eth_address: '0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC',
|
||||
},
|
||||
proofs: [
|
||||
{
|
||||
format: 'signed_message',
|
||||
available: true,
|
||||
type: 'eth_address',
|
||||
eth_address: '0x949AF81E51D57831AE52591d17fBcdd1014a5f52',
|
||||
message: 'SOMEHEX',
|
||||
},
|
||||
],
|
||||
github_link:
|
||||
'https://github.com/vegaprotocol/well-known/blob/main/oracle-providers/eth_address-0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC.toml',
|
||||
} as Provider;
|
||||
|
||||
it('should render successfully', () => {
|
||||
const component = <OracleBasicProfile provider={testProvider} />;
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should render the name', () => {
|
||||
render(<OracleBasicProfile provider={testProvider} />);
|
||||
expect(screen.getByTestId('provider-name')).toHaveTextContent(
|
||||
'Test oracle'
|
||||
);
|
||||
expect(screen.getByTestId('verified-proofs')).toHaveTextContent('1');
|
||||
expect(screen.getByTestId('signed-proofs')).toHaveTextContent('1');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
import type { Story, Meta } from '@storybook/react';
|
||||
import { OracleBasicProfile } from './oracle-basic-profile';
|
||||
|
||||
export default {
|
||||
component: OracleBasicProfile,
|
||||
title: 'OracleBasicProfile',
|
||||
} as Meta;
|
||||
|
||||
const Template: Story = (args) => (
|
||||
<OracleBasicProfile provider={args['provider']} />
|
||||
);
|
||||
|
||||
export const Default = Template.bind({});
|
||||
|
||||
Default.args = {
|
||||
provider: {
|
||||
name: 'Test oracle',
|
||||
url: 'https://zombo.com',
|
||||
description_markdown:
|
||||
'Some markdown describing the oracle provider.\n\nTwitter: @FacesPics2\n',
|
||||
oracle: {
|
||||
status: 'GOOD',
|
||||
status_reason: '',
|
||||
first_verified: '2023-02-28T00:00:00.000Z',
|
||||
last_verified: '2023-02-28T00:00:00.000Z',
|
||||
type: 'eth_address',
|
||||
eth_address: '0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC',
|
||||
},
|
||||
proofs: [
|
||||
{
|
||||
format: 'signed_message',
|
||||
available: true,
|
||||
type: 'eth_address',
|
||||
eth_address: '0x949AF81E51D57831AE52591d17fBcdd1014a5f52',
|
||||
message: 'SOMEHEX',
|
||||
},
|
||||
],
|
||||
github_link:
|
||||
'https://github.com/vegaprotocol/well-known/blob/main/oracle-providers/eth_address-0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC.toml',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,158 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import type { Provider } from '../../oracle-schema';
|
||||
import {
|
||||
ExternalLink,
|
||||
Icon,
|
||||
Intent,
|
||||
Link,
|
||||
VegaIcon,
|
||||
VegaIconNames,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import type { IconName } from '@blueprintjs/icons';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import classNames from 'classnames';
|
||||
|
||||
const getVerifiedStatusIcon = (provider: Provider) => {
|
||||
const getIconIntent = () => {
|
||||
switch (provider.oracle.status) {
|
||||
case 'GOOD':
|
||||
return { icon: IconNames.TICK_CIRCLE, intent: Intent.Success };
|
||||
case 'RETIRED':
|
||||
return { icon: IconNames.MOON, intent: Intent.None };
|
||||
case 'UNKNOWN':
|
||||
return { icon: IconNames.HELP, intent: Intent.Primary };
|
||||
case 'MALICIOUS':
|
||||
return { icon: IconNames.ERROR, intent: Intent.Danger };
|
||||
case 'SUSPICIOUS':
|
||||
return { icon: IconNames.ERROR, intent: Intent.Danger };
|
||||
case 'COMPROMISED':
|
||||
return { icon: IconNames.ERROR, intent: Intent.Danger };
|
||||
default:
|
||||
return { icon: IconNames.HELP, intent: Intent.Primary };
|
||||
}
|
||||
};
|
||||
|
||||
if (!provider.oracle.first_verified || !provider.oracle.last_verified) {
|
||||
return {
|
||||
message: t('Not verified'),
|
||||
...getIconIntent(),
|
||||
};
|
||||
}
|
||||
|
||||
const lastVerified = provider.oracle.last_verified
|
||||
? new Date(provider.oracle.last_verified)
|
||||
: new Date(provider.oracle.first_verified);
|
||||
return {
|
||||
...getIconIntent(),
|
||||
message: t(
|
||||
'Verified since %s',
|
||||
lastVerified.toLocaleDateString(undefined, {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
})
|
||||
),
|
||||
};
|
||||
};
|
||||
|
||||
export const OracleBasicProfile = ({ provider }: { provider: Provider }) => {
|
||||
const { icon, message, intent } = getVerifiedStatusIcon(provider);
|
||||
|
||||
const verifiedProofs = provider.proofs.filter(
|
||||
(proof) => proof.available === true
|
||||
);
|
||||
|
||||
const signedProofs = provider.proofs.filter(
|
||||
(proof) => proof.format === 'signed_message' && proof.available === true
|
||||
);
|
||||
|
||||
const links = provider.proofs
|
||||
.filter((proof) => proof.format === 'url' && proof.available === true)
|
||||
.map((proof) => ({
|
||||
...proof,
|
||||
url: 'url' in proof ? proof.url : '',
|
||||
icon: getLinkIcon(proof.type),
|
||||
}));
|
||||
|
||||
return (
|
||||
<>
|
||||
<span className="flex gap-1">
|
||||
{provider.url && (
|
||||
<Link
|
||||
href={provider.github_link}
|
||||
className="flex align-items-bottom text-md"
|
||||
target="_blank"
|
||||
>
|
||||
<span>
|
||||
<span data-testid="provider-name" className="underline pr-1">
|
||||
{provider.name}
|
||||
</span>
|
||||
<span
|
||||
data-testid="verified-proofs"
|
||||
className="dark:text-vega-light-300 text-vega-dark-300"
|
||||
>
|
||||
({verifiedProofs.length})
|
||||
</span>
|
||||
</span>
|
||||
</Link>
|
||||
)}
|
||||
<span
|
||||
className={classNames(
|
||||
{
|
||||
'text-gray-700 dark:text-gray-300': intent === Intent.None,
|
||||
'text-vega-blue': intent === Intent.Primary,
|
||||
'text-vega-green dark:text-vega-green': intent === Intent.Success,
|
||||
'text-yellow-600 dark:text-yellow': intent === Intent.Warning,
|
||||
'text-vega-pink': intent === Intent.Danger,
|
||||
},
|
||||
'flex items-start align-text-bottom p-1'
|
||||
)}
|
||||
>
|
||||
<Icon size={3} name={icon as IconName} />
|
||||
</span>
|
||||
</span>
|
||||
<p className="dark:text-vega-light-300 text-vega-dark-300">{message}</p>
|
||||
<p
|
||||
data-testid="signed-proofs"
|
||||
className="dark:text-vega-light-300 text-vega-dark-300"
|
||||
>
|
||||
{t('Involved in %s %s', [
|
||||
signedProofs.length.toString(),
|
||||
signedProofs.length !== 1 ? t('markets') : t('market'),
|
||||
])}
|
||||
</p>
|
||||
{links.length > 0 && (
|
||||
<div className="flex flex-row gap-1">
|
||||
{links.map((link) => (
|
||||
<ExternalLink
|
||||
key={link.url}
|
||||
href={link.url}
|
||||
data-testid={link.url}
|
||||
className="flex align-items-bottom underline text-sm"
|
||||
>
|
||||
<span className="pt-1">
|
||||
<VegaIcon name={getLinkIcon(link.type)} />
|
||||
</span>
|
||||
<span className="underline capitalize">
|
||||
{link.type}{' '}
|
||||
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} size={13} />
|
||||
</span>
|
||||
</ExternalLink>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const getLinkIcon = (type: string) => {
|
||||
switch (type) {
|
||||
case 'twitter':
|
||||
return VegaIconNames.TWITTER;
|
||||
case 'github':
|
||||
return VegaIconNames.GLOBE;
|
||||
case 'linkedin':
|
||||
return VegaIconNames.LINKEDIN;
|
||||
default:
|
||||
return VegaIconNames.GLOBE;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
export * from './__generated__';
|
||||
export * from './components';
|
||||
export * from './oracle-schema';
|
||||
export * from './oracle-spec-data-connection.mock';
|
||||
export * from './use-oracle-proofs';
|
||||
export * from './use-oracle-spec-binding-data';
|
||||
@@ -0,0 +1,73 @@
|
||||
[
|
||||
{
|
||||
"name": "Test oracle",
|
||||
"url": "https://zombo.com",
|
||||
"description_markdown": "Some markdown describing the oracle provider.\n\nTwitter: @FacesPics2\n",
|
||||
"oracle": {
|
||||
"status": "GOOD",
|
||||
"status_reason": "",
|
||||
"first_verified": "2023-02-28T00:00:00.000Z",
|
||||
"last_verified": "2023-02-28T00:00:00.000Z",
|
||||
"type": "eth_address",
|
||||
"eth_address": "0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC"
|
||||
},
|
||||
"proofs": [
|
||||
{
|
||||
"format": "signed_message",
|
||||
"available": true,
|
||||
"type": "eth_address",
|
||||
"eth_address": "0x949AF81E51D57831AE52591d17fBcdd1014a5f52",
|
||||
"message": "SOMEHEX"
|
||||
}
|
||||
],
|
||||
"github_link": "https://github.com/vegaprotocol/well-known/blob/main/oracle-providers/eth_address-0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC.toml"
|
||||
},
|
||||
{
|
||||
"name": "Vega Admin Oracle for Testnet",
|
||||
"url": "https://fairground.wtf",
|
||||
"description_markdown": "The Vega Fairground admin oracle, uses a json file to settle based on Binance Spot price.\nE.g. in case the market is BTC/USDC the spot price for BTC/USDC on Binance will be used.\n\nTwitter: @VegaFairground\n",
|
||||
"oracle": {
|
||||
"status": "GOOD",
|
||||
"status_reason": "",
|
||||
"first_verified": "2022-01-01T00:00:00.000Z",
|
||||
"last_verified": "2022-12-31T00:00:00.000Z",
|
||||
"type": "public_key",
|
||||
"public_key": "69464e35bcb8e8a2900ca0f87acaf252d50cf2ab2fc73694845a16b7c8a0dc6f"
|
||||
},
|
||||
"proofs": [
|
||||
{
|
||||
"format": "url",
|
||||
"available": true,
|
||||
"type": "twitter",
|
||||
"url": "https://twitter.com/vegaprotocol/status/956833487230730241"
|
||||
},
|
||||
{
|
||||
"format": "url",
|
||||
"available": true,
|
||||
"type": "web",
|
||||
"url": "https://fairground.wtf/"
|
||||
},
|
||||
{
|
||||
"format": "url",
|
||||
"available": true,
|
||||
"type": "github",
|
||||
"url": "https://github.com"
|
||||
},
|
||||
{
|
||||
"format": "signed_message",
|
||||
"available": true,
|
||||
"type": "public_key",
|
||||
"public_key": "69464e35bcb8e8a2900ca0f87acaf252d50cf2ab2fc73694845a16b7c8a0dc6f",
|
||||
"message": "SOMEHEX"
|
||||
},
|
||||
{
|
||||
"format": "signed_message",
|
||||
"available": true,
|
||||
"type": "eth_address",
|
||||
"eth_address": "0x0b38D0e7391CF427d309991A110a84daF37114eF",
|
||||
"message": "SOMEHEX"
|
||||
}
|
||||
],
|
||||
"github_link": "https://github.com/vegaprotocol/well-known/blob/main/oracle-providers/public_key-69464e35bcb8e8a2900ca0f87acaf252d50cf2ab2fc73694845a16b7c8a0dc6f.toml"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,4 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import ResizeObserver from 'resize-observer-polyfill';
|
||||
|
||||
global.ResizeObserver = ResizeObserver;
|
||||
@@ -0,0 +1,18 @@
|
||||
const { join } = require('path');
|
||||
const { createGlobPatternsForDependencies } = require('@nrwl/next/tailwind');
|
||||
const theme = require('../tailwindcss-config/src/theme');
|
||||
const vegaCustomClasses = require('../tailwindcss-config/src/vega-custom-classes');
|
||||
|
||||
module.exports = {
|
||||
content: [
|
||||
join(__dirname, 'src/**/*.{ts,tsx,html,mdx}'),
|
||||
join(__dirname, 'src/utils/shared.ts'),
|
||||
join(__dirname, '.storybook/preview.js'),
|
||||
...createGlobPatternsForDependencies(__dirname),
|
||||
],
|
||||
darkMode: 'class',
|
||||
theme: {
|
||||
extend: theme,
|
||||
},
|
||||
plugins: [vegaCustomClasses],
|
||||
};
|
||||
@@ -8,11 +8,10 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
@@ -20,6 +19,9 @@
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
},
|
||||
{
|
||||
"path": "./.storybook/tsconfig.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
"../../node_modules/@nrwl/react/typings/image.d.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"jest.config.ts",
|
||||
"**/*.spec.ts",
|
||||
"**/*.test.ts",
|
||||
"**/*.spec.tsx",
|
||||
@@ -17,7 +16,12 @@
|
||||
"**/*.spec.js",
|
||||
"**/*.test.js",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.test.jsx"
|
||||
"**/*.test.jsx",
|
||||
"**/*.stories.ts",
|
||||
"**/*.stories.js",
|
||||
"**/*.stories.jsx",
|
||||
"**/*.stories.tsx",
|
||||
"jest.config.ts"
|
||||
],
|
||||
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
|
||||
}
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
"types": ["jest", "node", "@testing-library/jest-dom"]
|
||||
},
|
||||
"include": [
|
||||
"jest.config.ts",
|
||||
"**/*.test.ts",
|
||||
"**/*.spec.ts",
|
||||
"**/*.test.tsx",
|
||||
@@ -16,6 +15,8 @@
|
||||
"**/*.test.jsx",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.d.ts",
|
||||
"jest.config.ts",
|
||||
"../../index.d.ts",
|
||||
"src/lib/use-oracle-spec-binding-data.spec.tsx"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.20755 15.7736H6V4H8.20755V15.7736ZM10.4151 17.8585V15.7736H8.20755V17.9811H10.4151V20.066H12.6226V17.9811H14.8302V15.7736H12.6226V17.8585H10.4151ZM16.7925 13.566H14.5849V4H16.7925V13.566ZM16.7925 13.566H19V15.7736H16.7925V13.566Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 401 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.9946 3C10.2165 3.00106 8.47842 3.52883 6.99987 4.51677C5.51983 5.5057 4.36628 6.91131 3.68509 8.55585C3.0039 10.2004 2.82567 12.01 3.17294 13.7558C3.5202 15.5016 4.37737 17.1053 5.63604 18.364C6.89471 19.6226 8.49836 20.4798 10.2442 20.8271C11.99 21.1743 13.7996 20.9961 15.4442 20.3149C17.0887 19.6337 18.4943 18.4802 19.4832 17.0001C20.4722 15.5201 21 13.78 21 12C21 9.61305 20.0518 7.32386 18.364 5.63604C16.6761 3.94821 14.3869 3 12 3C12.0001 3 11.9999 3 12 3M11.9959 3.936C11.9972 3.936 11.9985 3.936 11.9999 3.936C13.2976 3.93617 14.3772 5.83592 14.9515 8.22998H9.04712C9.62068 5.83664 10.6991 3.93971 11.9959 3.936ZM9.8073 4.24157C9.05208 5.16925 8.44481 6.56185 8.07534 8.22998H4.87438C5.24741 7.52551 5.72602 6.87397 6.3 6.3C7.28288 5.31711 8.49319 4.61388 9.8073 4.24157ZM4.42885 9.22998C4.10667 10.1091 3.93685 11.0458 3.936 12C3.936 12.9499 4.10378 13.8872 4.42669 14.77H7.88922C7.75324 13.8973 7.67969 12.9663 7.67969 12C7.67969 11.0336 7.7527 10.1027 7.8879 9.22998H4.42885ZM4.87153 15.77C5.00006 16.013 5.14133 16.2501 5.29503 16.4801C6.18112 17.8062 7.44054 18.8398 8.91404 19.4502C9.20977 19.5727 9.51146 19.677 9.81744 19.763C9.06048 18.8354 8.44956 17.4409 8.07765 15.77H4.87153ZM14.1834 19.7628C15.5101 19.3896 16.7227 18.6815 17.7021 17.7021C18.2744 17.1298 18.7541 16.4778 19.1285 15.77H15.9224C15.5508 17.4416 14.9402 18.8355 14.1834 19.7628ZM19.5733 14.77C19.7153 14.3819 19.8278 13.9819 19.9091 13.5732C20.1981 12.12 20.0808 10.6174 19.5733 9.22998H16.1106C16.2463 10.1024 16.3197 11.0333 16.3197 12C16.3197 12.9667 16.2463 13.8976 16.1106 14.77H19.5733ZM19.1285 8.22998C18.5047 7.05058 17.596 6.04063 16.4801 5.29503C15.7711 4.82129 14.9955 4.46564 14.1834 4.23723C14.9402 5.16453 15.5508 6.55844 15.9224 8.22998H19.1285ZM8.60129 12C8.60129 11.0806 8.68603 10.1352 8.84194 9.22998H15.1569C15.3132 10.1358 15.3981 11.0814 15.3981 12C15.3981 12.9186 15.314 13.8642 15.1588 14.77H8.84003C8.68519 13.8648 8.60129 12.9194 8.60129 12ZM11.9997 20.064C10.6916 20.064 9.61486 18.1657 9.04394 15.77H14.9547C14.3836 18.1642 13.3072 20.064 11.9997 20.064Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M21 4.32353V19.6765C21 20.0275 20.8606 20.3641 20.6123 20.6123C20.3641 20.8606 20.0275 21 19.6765 21H4.32353C3.97251 21 3.63586 20.8606 3.38765 20.6123C3.13944 20.3641 3 20.0275 3 19.6765V4.32353C3 3.97251 3.13944 3.63586 3.38765 3.38765C3.63586 3.13944 3.97251 3 4.32353 3H19.6765C20.0275 3 20.3641 3.13944 20.6123 3.38765C20.8606 3.63586 21 3.97251 21 4.32353V4.32353ZM8.29412 9.88235H5.64706V18.3529H8.29412V9.88235ZM8.53235 6.97059C8.53375 6.77036 8.49569 6.57182 8.42035 6.3863C8.34502 6.20078 8.23387 6.03191 8.09328 5.88935C7.95268 5.74678 7.78537 5.6333 7.60091 5.5554C7.41646 5.47749 7.21846 5.43668 7.01824 5.43529H6.97059C6.5634 5.43529 6.1729 5.59705 5.88497 5.88497C5.59705 6.1729 5.43529 6.5634 5.43529 6.97059C5.43529 7.37777 5.59705 7.76828 5.88497 8.05621C6.1729 8.34413 6.5634 8.50588 6.97059 8.50588V8.50588C7.17083 8.51081 7.37008 8.47623 7.55696 8.40413C7.74383 8.33202 7.91467 8.2238 8.0597 8.08565C8.20474 7.94749 8.32113 7.78212 8.40223 7.59897C8.48333 7.41582 8.52755 7.21848 8.53235 7.01824V6.97059ZM18.3529 13.2071C18.3529 10.6606 16.7329 9.67059 15.1235 9.67059C14.5966 9.6442 14.0719 9.75644 13.6019 9.9961C13.1318 10.2358 12.7328 10.5945 12.4447 11.0365H12.3706V9.88235H9.88235V18.3529H12.5294V13.8476C12.4911 13.3862 12.6365 12.9283 12.9339 12.5735C13.2313 12.2186 13.6567 11.9954 14.1176 11.9524H14.2182C15.06 11.9524 15.6847 12.4818 15.6847 13.8159V18.3529H18.3318L18.3529 13.2071Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,5 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 1C4.13 1 1 4.13 1 8C1 11.87 4.13 15 8 15C11.87 15 15 11.87 15 8C15 4.13 11.87 1 8 1ZM8.66 12.44H7.32V11.1H8.66V12.44ZM10.38 6.78C10.29 7.01 10.18 7.2 10.05 7.36C9.92 7.52 9.75 7.7 9.53 7.91C9.3 8.14 9.11 8.34 8.98 8.51C8.85 8.68 8.73 8.89 8.64 9.14C8.55 9.37 8.51 9.65 8.51 9.96V10.04V10.13H7.3V10.04C7.3 9.61 7.36 9.24 7.47 8.92C7.58 8.61 7.71 8.34 7.87 8.13C8.03 7.92 8.22 7.69 8.47 7.43C8.75 7.13 8.96 6.87 9.09 6.66C9.22 6.46 9.28 6.2 9.28 5.88C9.28 5.47 9.16 5.16 8.93 4.93C8.7 4.7 8.38 4.58 7.96 4.58C7.6 4.58 7.28 4.68 7.01 4.89C6.75 5.09 6.56 5.44 6.45 5.96C6.34 6.48 6.43 6.06 6.43 6.06L5.26 5.62L5.28 5.54C5.47 4.87 5.81 4.35 6.29 4.02C6.77 3.69 7.34 3.53 8 3.53C8.75 3.53 9.37 3.75 9.82 4.18C10.28 4.62 10.5 5.22 10.5 5.97C10.5 6.27 10.46 6.53 10.37 6.76L10.38 6.78Z" fill="white"/>
|
||||
<circle cx="8" cy="8" r="7" fill="white"/>
|
||||
<path d="M6.15393 5.69232C6.15393 5.10304 6.24054 4.5075 6.46161 4C4.99179 4.63982 4 6.14089 4 7.84607C4 10.1402 5.85982 12 8.15393 12C9.85911 12 11.3602 11.0082 12 9.53839C11.4925 9.75946 10.8964 9.84607 10.3077 9.84607C8.01357 9.84607 6.15393 7.98643 6.15393 5.69232Z" fill="black"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 1C4.13 1 1 4.13 1 8C1 11.87 4.13 15 8 15C11.87 15 15 11.87 15 8C15 4.13 11.87 1 8 1ZM8.66 12.44H7.32V11.1H8.66V12.44ZM10.38 6.78C10.29 7.01 10.18 7.2 10.05 7.36C9.92 7.52 9.75 7.7 9.53 7.91C9.3 8.14 9.11 8.34 8.98 8.51C8.85 8.68 8.73 8.89 8.64 9.14C8.55 9.37 8.51 9.65 8.51 9.96V10.04V10.13H7.3V10.04C7.3 9.61 7.36 9.24 7.47 8.92C7.58 8.61 7.71 8.34 7.87 8.13C8.03 7.92 8.22 7.69 8.47 7.43C8.75 7.13 8.96 6.87 9.09 6.66C9.22 6.46 9.28 6.2 9.28 5.88C9.28 5.47 9.16 5.16 8.93 4.93C8.7 4.7 8.38 4.58 7.96 4.58C7.6 4.58 7.28 4.68 7.01 4.89C6.75 5.09 6.56 5.44 6.45 5.96L6.43 6.06L5.26 5.62L5.28 5.54C5.47 4.87 5.81 4.35 6.29 4.02C6.77 3.69 7.34 3.53 8 3.53C8.75 3.53 9.37 3.75 9.82 4.18C10.28 4.62 10.5 5.22 10.5 5.97C10.5 6.27 10.46 6.53 10.37 6.76L10.38 6.78Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 929 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.28743 20.2575C15.8423 20.2575 19.9641 14 19.9641 8.58084C19.9641 8.4012 19.9641 8.22156 19.9541 8.0519C20.7525 7.47305 21.4511 6.74451 22 5.92615C21.2615 6.25549 20.4731 6.47505 19.6447 6.57485C20.493 6.06587 21.1417 5.26747 21.4511 4.2994C20.6627 4.76846 19.7844 5.10778 18.8463 5.29741C18.0978 4.499 17.0299 4 15.8523 4C13.5868 4 11.7505 5.83633 11.7505 8.1018C11.7505 8.42116 11.7904 8.74052 11.8603 9.03992C8.43713 8.86028 5.40319 7.22355 3.38723 4.7485C3.02794 5.34731 2.82834 6.05589 2.82834 6.80439C2.82834 8.23154 3.55689 9.48902 4.65469 10.2176C3.97605 10.2076 3.34731 10.018 2.7984 9.70858C2.7984 9.72854 2.7984 9.73852 2.7984 9.75848C2.7984 11.7445 4.21557 13.4112 6.09182 13.7804C5.74251 13.8703 5.38323 13.9202 5.01397 13.9202C4.75449 13.9202 4.49501 13.8902 4.24551 13.8503C4.76447 15.477 6.28144 16.6647 8.07784 16.7046C6.67066 17.8024 4.90419 18.4611 2.97804 18.4611C2.6487 18.4611 2.31936 18.4411 2 18.4012C3.80639 19.5788 5.96208 20.2575 8.28743 20.2575Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -8,8 +8,8 @@ export const IconGlobe = ({ size = 24 }: { size: number }) => {
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M11.9946 3C10.2165 3.00106 8.47842 3.52883 6.99987 4.51677C5.51983 5.5057 4.36628 6.91131 3.68509 8.55585C3.0039 10.2004 2.82567 12.01 3.17294 13.7558C3.5202 15.5016 4.37737 17.1053 5.63604 18.364C6.89471 19.6226 8.49836 20.4798 10.2442 20.8271C11.99 21.1743 13.7996 20.9961 15.4442 20.3149C17.0887 19.6337 18.4943 18.4802 19.4832 17.0001C20.4722 15.5201 21 13.78 21 12C21 9.61305 20.0518 7.32386 18.364 5.63604C16.6761 3.94821 14.3869 3 12 3C12.0001 3 11.9999 3 12 3M11.9959 3.936C11.9972 3.936 11.9985 3.936 11.9999 3.936C13.2976 3.93617 14.3772 5.83592 14.9515 8.22998H9.04712C9.62068 5.83664 10.6991 3.93971 11.9959 3.936ZM9.8073 4.24157C9.05208 5.16925 8.44481 6.56185 8.07534 8.22998H4.87438C5.24741 7.52551 5.72602 6.87397 6.3 6.3C7.28288 5.31711 8.49319 4.61388 9.8073 4.24157ZM4.42885 9.22998C4.10667 10.1091 3.93685 11.0458 3.936 12C3.936 12.9499 4.10378 13.8872 4.42669 14.77H7.88922C7.75324 13.8973 7.67969 12.9663 7.67969 12C7.67969 11.0336 7.7527 10.1027 7.8879 9.22998H4.42885ZM4.87153 15.77C5.00006 16.013 5.14133 16.2501 5.29503 16.4801C6.18112 17.8062 7.44054 18.8398 8.91404 19.4502C9.20977 19.5727 9.51146 19.677 9.81744 19.763C9.06048 18.8354 8.44956 17.4409 8.07765 15.77H4.87153ZM14.1834 19.7628C15.5101 19.3896 16.7227 18.6815 17.7021 17.7021C18.2744 17.1298 18.7541 16.4778 19.1285 15.77H15.9224C15.5508 17.4416 14.9402 18.8355 14.1834 19.7628ZM19.5733 14.77C19.7153 14.3819 19.8278 13.9819 19.9091 13.5732C20.1981 12.12 20.0808 10.6174 19.5733 9.22998H16.1106C16.2463 10.1024 16.3197 11.0333 16.3197 12C16.3197 12.9667 16.2463 13.8976 16.1106 14.77H19.5733ZM19.1285 8.22998C18.5047 7.05058 17.596 6.04063 16.4801 5.29503C15.7711 4.82129 14.9955 4.46564 14.1834 4.23723C14.9402 5.16453 15.5508 6.55844 15.9224 8.22998H19.1285ZM8.60129 12C8.60129 11.0806 8.68603 10.1352 8.84194 9.22998H15.1569C15.3132 10.1358 15.3981 11.0814 15.3981 12C15.3981 12.9186 15.314 13.8642 15.1588 14.77H8.84003C8.68519 13.8648 8.60129 12.9194 8.60129 12ZM11.9997 20.064C10.6916 20.064 9.61486 18.1657 9.04394 15.77H14.9547C14.3836 18.1642 13.3072 20.064 11.9997 20.064Z"
|
||||
fill="white"
|
||||
/>
|
||||
|
||||
@@ -5,7 +5,7 @@ import { VegaIconNameMap } from './vega-icon-record';
|
||||
|
||||
export interface VegaIconProps {
|
||||
name: VegaIconNames;
|
||||
size?: 16 | 24 | 32;
|
||||
size?: 8 | 10 | 12 | 13 | 14 | 16 | 24 | 32;
|
||||
}
|
||||
|
||||
export const VegaIcon = ({ size = 16, name }: VegaIconProps) => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import once from 'lodash/once';
|
||||
import { getUserLocale } from '../get-user-locale';
|
||||
import { utcToZonedTime, format as tzFormat } from 'date-fns-tz';
|
||||
|
||||
export const isValidDate = (date: Date) =>
|
||||
date instanceof Date && !isNaN(date.getTime());
|
||||
@@ -51,3 +52,16 @@ export const formatForInput = (date: Date) => {
|
||||
|
||||
return `${year}-${month}-${day}T${hours}:${minutes}:${secs}`;
|
||||
};
|
||||
|
||||
/** Format a user's local date and time with the time zone abbreviation */
|
||||
export const formatDateWithLocalTimezone = (
|
||||
date: Date,
|
||||
formatStr = 'dd MMMM yyyy HH:mm (z)'
|
||||
) => {
|
||||
const userTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
const localDatetime = utcToZonedTime(date, userTimeZone);
|
||||
|
||||
return tzFormat(localDatetime, formatStr, {
|
||||
timeZone: userTimeZone,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@ interface Asset {
|
||||
};
|
||||
}
|
||||
|
||||
interface ERC20Asset {
|
||||
export interface ERC20Asset {
|
||||
__typename?: 'Asset';
|
||||
source: {
|
||||
__typename: 'ERC20';
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import ResizeObserver from 'resize-observer-polyfill';
|
||||
|
||||
global.ResizeObserver = ResizeObserver;
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { useAccountBalance } from '@vegaprotocol/accounts';
|
||||
import type { AssetFieldsFragment } from '@vegaprotocol/assets';
|
||||
import { useBalancesStore } from '@vegaprotocol/assets';
|
||||
import { Balance } from '@vegaprotocol/assets';
|
||||
import { addDecimal } from '@vegaprotocol/utils';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
export const AssetBalance = ({ asset }: { asset: AssetFieldsFragment }) => {
|
||||
const [setBalance, getBalance] = useBalancesStore((state) => [
|
||||
state.setBalance,
|
||||
state.getBalance,
|
||||
]);
|
||||
const { accountBalance, accountDecimals } = useAccountBalance(asset?.id);
|
||||
|
||||
useEffect(() => {
|
||||
const balance =
|
||||
accountBalance && accountDecimals
|
||||
? new BigNumber(addDecimal(accountBalance, accountDecimals))
|
||||
: undefined;
|
||||
setBalance({ asset, balanceOnVega: balance });
|
||||
}, [accountBalance, accountDecimals, asset, setBalance]);
|
||||
|
||||
return (
|
||||
<Balance
|
||||
balance={getBalance(asset.id)?.balanceOnVega?.toString()}
|
||||
symbol={asset.symbol}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -1,6 +1,7 @@
|
||||
import { render, screen, act, waitFor } from '@testing-library/react';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import type { Account } from '@vegaprotocol/accounts';
|
||||
import { useAccountBalance } from '@vegaprotocol/accounts';
|
||||
import { WithdrawFormContainer } from './withdraw-form-container';
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
import { useWeb3React } from '@web3-react/core';
|
||||
@@ -12,6 +13,7 @@ jest.mock('@vegaprotocol/react-helpers', () => ({
|
||||
}),
|
||||
}));
|
||||
jest.mock('@web3-react/core');
|
||||
jest.mock('@vegaprotocol/accounts');
|
||||
|
||||
describe('WithdrawFormContainer', () => {
|
||||
const props = {
|
||||
@@ -91,6 +93,10 @@ describe('WithdrawFormContainer', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
(useWeb3React as jest.Mock).mockReturnValue({ account: MOCK_ETH_ADDRESS });
|
||||
(useAccountBalance as jest.Mock).mockReturnValue({
|
||||
accountBalance: 0,
|
||||
accountDecimals: null,
|
||||
});
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
|
||||
@@ -8,6 +8,11 @@ import type { Asset } from '@vegaprotocol/assets';
|
||||
|
||||
jest.mock('@web3-react/core');
|
||||
|
||||
jest.mock('@vegaprotocol/accounts', () => ({
|
||||
...jest.requireActual('@vegaprotocol/accounts'),
|
||||
useAccountBalance: jest.fn(() => ({ accountBalance: 0, accountDecimals: 0 })),
|
||||
}));
|
||||
|
||||
const MOCK_ETH_ADDRESS = '0x72c22822A19D20DE7e426fB84aa047399Ddd8853';
|
||||
|
||||
let assets: Asset[];
|
||||
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
useWeb3ConnectStore,
|
||||
useWeb3Disconnect,
|
||||
} from '@vegaprotocol/web3';
|
||||
import { AssetBalance } from './asset-balance';
|
||||
|
||||
interface FormFields {
|
||||
asset: string;
|
||||
@@ -154,7 +155,11 @@ export const WithdrawForm = ({
|
||||
hasError={Boolean(errors.asset?.message)}
|
||||
>
|
||||
{assets.filter(isAssetTypeERC20).map((a) => (
|
||||
<AssetOption key={a.id} asset={a} />
|
||||
<AssetOption
|
||||
key={a.id}
|
||||
asset={a}
|
||||
balance={<AssetBalance asset={a} />}
|
||||
/>
|
||||
))}
|
||||
</RichSelect>
|
||||
);
|
||||
|
||||
@@ -25,6 +25,11 @@ jest.mock('./use-withdraw-asset', () => ({
|
||||
useWithdrawAsset: () => withdrawAsset,
|
||||
}));
|
||||
|
||||
jest.mock('@vegaprotocol/accounts', () => ({
|
||||
...jest.requireActual('@vegaprotocol/accounts'),
|
||||
useAccountBalance: jest.fn(() => ({ accountBalance: 0, accountDecimals: 0 })),
|
||||
}));
|
||||
|
||||
jest.mock('@vegaprotocol/web3', () => ({
|
||||
...jest.requireActual('@vegaprotocol/web3'),
|
||||
useGetWithdrawThreshold: () => {
|
||||
|
||||
+2
-1
@@ -56,6 +56,7 @@
|
||||
"classnames": "^2.3.1",
|
||||
"core-js": "^3.6.5",
|
||||
"date-fns": "^2.28.0",
|
||||
"date-fns-tz": "^2.0.0",
|
||||
"duration-js": "^4.0.0",
|
||||
"ethers": "^5.6.0",
|
||||
"graphql": "^15.7.2",
|
||||
@@ -154,8 +155,8 @@
|
||||
"autoprefixer": "10.4.8",
|
||||
"babel-jest": "27.5.1",
|
||||
"babel-loader": "8.1.0",
|
||||
"cypress-mochawesome-reporter": "^3.3.0",
|
||||
"cypress": "^12.9.0",
|
||||
"cypress-mochawesome-reporter": "^3.3.0",
|
||||
"cypress-real-events": "^1.7.6",
|
||||
"dotenv": "^16.0.1",
|
||||
"eslint": "8.15.0",
|
||||
|
||||
@@ -12070,6 +12070,11 @@ dataloader@2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-2.1.0.tgz#c69c538235e85e7ac6c6c444bae8ecabf5de9df7"
|
||||
integrity sha512-qTcEYLen3r7ojZNgVUaRggOI+KM7jrKxXeSHhogh/TWxYMeONEMqY+hmkobiYQozsGIyg9OYVzO4ZIfoB4I0pQ==
|
||||
|
||||
date-fns-tz@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/date-fns-tz/-/date-fns-tz-2.0.0.tgz#1b14c386cb8bc16fc56fe333d4fc34ae1d1099d5"
|
||||
integrity sha512-OAtcLdB9vxSXTWHdT8b398ARImVwQMyjfYGkKD2zaGpHseG2UPHbHjXELReErZFxWdSLph3c2zOaaTyHfOhERQ==
|
||||
|
||||
date-fns@^1.27.2:
|
||||
version "1.30.1"
|
||||
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c"
|
||||
|
||||
Reference in New Issue
Block a user