diff --git a/apps/token-e2e/cypress.config.js b/apps/token-e2e/cypress.config.js index 72f5a6654..9122d4985 100644 --- a/apps/token-e2e/cypress.config.js +++ b/apps/token-e2e/cypress.config.js @@ -5,7 +5,7 @@ module.exports = defineConfig({ e2e: { baseUrl: 'http://localhost:4210', fileServerFolder: '.', - fixturesFolder: false, + fixturesFolder: './src/fixtures', specPattern: process.env.CYPRESS_INCLUDE_FLOWS === 'true' || process.env.CYPRESS_INCLUDE_FLOWS === true @@ -40,7 +40,7 @@ module.exports = defineConfig({ vegaWalletPublicKeyShort: '02ecea…2f65', vegaTokenContractAddress: '0xF41bD86d462D36b997C0bbb4D97a0a3382f205B7', vegaTokenAddress: '0x67175Da1D5e966e40D11c4B2519392B2058373de', - epochTimeout: { timeout: 10000 }, txTimeout: { timeout: 40000 }, + epochTimeout: { timeout: 10000 }, }, }); diff --git a/apps/token-e2e/src/fixtures/proposals/freeform.json b/apps/token-e2e/src/fixtures/proposals/freeform.json new file mode 100644 index 000000000..c3eddfe9b --- /dev/null +++ b/apps/token-e2e/src/fixtures/proposals/freeform.json @@ -0,0 +1,11 @@ +{ + "rationale": { + "url": "https://dweb.link/ipfs/bafybeigwwctpv37xdcwacqxvekr6e4kaemqsrv34em6glkbiceo3fcy4si", + "hash": "bafybeigwwctpv37xdcwacqxvekr6e4kaemqsrv34em6glkbiceo3fcy4si", + "description": "Freeform Proposal with unique id of: " + }, + "terms": { + "newFreeform": {}, + "closingTimestamp": 1657721401 + } +} diff --git a/apps/token-e2e/src/integration/flow/governance-flow.cy.js b/apps/token-e2e/src/integration/flow/governance-flow.cy.js new file mode 100644 index 000000000..7fa17179a --- /dev/null +++ b/apps/token-e2e/src/integration/flow/governance-flow.cy.js @@ -0,0 +1,407 @@ +/// +const newProposalButton = '[data-testid="new-proposal-link"]'; +const newProposalDatabox = '[data-testid="proposal-data"]'; +const newProposalSubmitButton = '[data-testid="proposal-submit"]'; +const dialogCloseButton = '[data-testid="dialog-close"]'; +const viewProposalButton = '[data-testid="view-proposal-btn"]'; +const proposalInformationTableRows = '[data-testid="key-value-table-row"]'; +const openProposals = '[data-testid="open-proposals"]'; +const vegaWalletAssociatedBalance = '[data-testid="currency-value"]'; +const proposalResponseIdPath = 'response.body.data.busEvents.0.event.id'; +const txTimeout = Cypress.env('txTimeout'); + +context('Governance flow - with eth and vega wallets connected', function () { + before('connect wallets and set approval limit', function () { + cy.vega_wallet_import(); + cy.visit('/'); + cy.verify_page_header('The $VEGA token'); + cy.get_network_parameters().then((network_parameters) => { + cy.wrap( + network_parameters['governance.proposal.freeform.minProposerBalance'] + ).as('minProposerBalance'); + cy.wrap( + network_parameters['governance.proposal.freeform.minClose'].split( + 'h' + )[0] / 24 + ).as('minCloseDays'); + cy.wrap( + network_parameters['governance.proposal.freeform.maxClose'].split( + 'h' + )[0] / 24 + ).as('maxCloseDays'); + }); + cy.vega_wallet_connect(); + cy.vega_wallet_set_specified_approval_amount('1000'); + cy.reload(); + cy.verify_page_header('The $VEGA token'); + cy.ethereum_wallet_connect(); + }); + + describe('Eth wallet - contains VEGA tokens', function () { + beforeEach('visit staking tab', function () { + cy.navigate_to('staking'); + cy.wait_for_spinner(); + cy.intercept('POST', '/query', (req) => { + if (req.body.operationName === 'ProposalEvent') { + req.alias = 'proposalSubmissionCompletion'; + } + }); + }); + + it('Able to submit a valid freeform proposal - with minimum tokens associated', function () { + cy.ensure_specified_unstaked_tokens_are_associated( + this.minProposerBalance + ); + cy.navigate_to('governance'); + cy.wait_for_spinner(); + cy.get(newProposalButton).should('be.visible').click(); + cy.get(newProposalDatabox).click(); + cy.create_ten_digit_unix_timestamp_for_specified_days('7').then( + (closingDateTimestamp) => { + cy.enter_unique_freeform_proposal_body(closingDateTimestamp); + } + ); + cy.get(newProposalSubmitButton).should('be.visible').click(); + cy.contains('Proposal submitted').should('be.visible'); + cy.get(dialogCloseButton).click(); + }); + + it('Newly created freeform proposal - shows in an open state', function () { + cy.ensure_specified_unstaked_tokens_are_associated( + this.minProposerBalance + ); + cy.navigate_to('governance'); + cy.wait_for_spinner(); + cy.get(newProposalButton).should('be.visible').click(); + cy.get(newProposalDatabox).click(); + cy.create_ten_digit_unix_timestamp_for_specified_days('8').then( + (closingDateTimestamp) => { + cy.enter_unique_freeform_proposal_body(closingDateTimestamp); + } + ); + cy.get(newProposalSubmitButton).should('be.visible').click(); + cy.contains('Proposal submitted').should('be.visible'); + cy.get(dialogCloseButton).click(); + cy.wait('@proposalSubmissionCompletion') + .its(proposalResponseIdPath) + .then((proposalId) => { + cy.navigate_to('governance'); + cy.wait_for_spinner(); + cy.get(openProposals).within(() => { + cy.get(`#${proposalId}`) + .should('contain', `Freeform proposal: ${proposalId}`) + .and('contain', 'Open') + .and('be.visible') + .within(() => { + cy.get(viewProposalButton).should('be.visible').click(); + }); + }); + cy.get(proposalInformationTableRows) + .contains('ID') + .siblings() + .contains(proposalId) + .should('be.visible'); + cy.get(proposalInformationTableRows) + .contains('State') + .siblings() + .contains('Open') + .should('be.visible'); + cy.get(proposalInformationTableRows) + .contains('Type') + .siblings() + .contains('NewFreeform'); + }); + }); + + it('Newly created freeform proposal - shows proposed and closing dates', function () { + cy.ensure_specified_unstaked_tokens_are_associated( + this.minProposerBalance + ); + cy.navigate_to('governance'); + cy.wait_for_spinner(); + cy.get(newProposalButton).should('be.visible').click(); + cy.get(newProposalDatabox).click(); + cy.create_ten_digit_unix_timestamp_for_specified_days('9').then( + (closingDateTimestamp) => { + cy.enter_unique_freeform_proposal_body(closingDateTimestamp); + cy.get(newProposalSubmitButton).should('be.visible').click(); + cy.contains('Proposal submitted').should('be.visible'); + cy.get(dialogCloseButton).click(); + cy.navigate_to('governance'); + cy.wait_for_spinner(); + cy.get_submitted_proposal().within(() => + cy.get(viewProposalButton).click() + ); + cy.convert_unix_timestamp_to_governance_data_table_date_format( + closingDateTimestamp + ).then((closingDate) => { + cy.get(proposalInformationTableRows) + .contains('Closes on') + .siblings() + .contains(closingDate) + .should('be.visible'); + }); + cy.create_ten_digit_unix_timestamp_for_specified_days('0').then( + (now) => { + cy.convert_unix_timestamp_to_governance_data_table_date_format( + now + ).then((proposalDate) => { + cy.get(proposalInformationTableRows) + .contains('Proposed on') + .siblings() + .contains(proposalDate) + .should('be.visible'); + }); + } + ); + cy.contains('9 days left to vote').should('be.visible'); + } + ); + }); + + it('Newly created freeform proposal - shows default status set to fail', function () { + cy.ensure_specified_unstaked_tokens_are_associated( + this.minProposerBalance + ); + cy.navigate_to('governance'); + cy.wait_for_spinner(); + cy.get(newProposalButton).should('be.visible').click(); + cy.get(newProposalDatabox).click(); + cy.create_ten_digit_unix_timestamp_for_specified_days('7').then( + (closingDateTimestamp) => { + cy.enter_unique_freeform_proposal_body(closingDateTimestamp); + } + ); + cy.get(newProposalSubmitButton).should('be.visible').click(); + cy.contains('Proposal submitted').should('be.visible'); + cy.get(dialogCloseButton).click(); + cy.navigate_to('governance'); + cy.wait_for_spinner(); + cy.get_submitted_proposal().within(() => + cy.get(viewProposalButton).click() + ); + cy.contains('Currently set to fail').should('be.visible'); + cy.contains('Participation: Not Met 0.00 0.00%(0.00% Required)').should( + 'be.visible' + ); + cy.get(proposalInformationTableRows) + .contains('Will pass') + .siblings() + .contains('👎') + .should('be.visible'); + cy.get(proposalInformationTableRows) + .contains('Majority met') + .siblings() + .contains('👎') + .should('be.visible'); + cy.get(proposalInformationTableRows) + .contains('Participation met') + .siblings() + .contains('👎') + .should('be.visible'); + }); + + it('Creating a proposal - proposal rejected - when closing time sooner than system default', function () { + cy.ensure_specified_unstaked_tokens_are_associated( + this.minProposerBalance + ); + cy.navigate_to('governance'); + cy.wait_for_spinner(); + cy.get(newProposalButton).should('be.visible').click(); + cy.get(newProposalDatabox).click(); + cy.create_ten_digit_unix_timestamp_for_specified_days( + this.minCloseDays - 1 + ).then((closingDateTimestamp) => { + cy.enter_unique_freeform_proposal_body(closingDateTimestamp); + }); + cy.get(newProposalSubmitButton).should('be.visible').click(); + cy.contains('Proposal rejected').should('be.visible'); + cy.get(dialogCloseButton).click(); + cy.navigate_to('governance'); + cy.wait_for_spinner(); + cy.get_submitted_proposal().within(() => { + cy.contains('Rejected').should('be.visible'); + cy.contains('Close time too soon').should('be.visible'); + cy.get(viewProposalButton).click(); + }); + cy.get(proposalInformationTableRows) + .contains('State') + .siblings() + .contains('Rejected') + .should('be.visible'); + cy.get(proposalInformationTableRows) + .contains('Rejection reason') + .siblings() + .contains('CloseTimeTooSoon') + .should('be.visible'); + cy.get(proposalInformationTableRows) + .contains('Error details') + .siblings() + .contains('proposal closing time too soon') + .should('be.visible'); + }); + + it('Creating a proposal - proposal rejected - when closing time later than system default', function () { + cy.ensure_specified_unstaked_tokens_are_associated( + this.minProposerBalance + ); + cy.navigate_to('governance'); + cy.wait_for_spinner(); + cy.get(newProposalButton).should('be.visible').click(); + cy.get(newProposalDatabox).click(); + cy.create_ten_digit_unix_timestamp_for_specified_days( + this.maxCloseDays + 1 + ).then((closingDateTimestamp) => { + cy.enter_unique_freeform_proposal_body(closingDateTimestamp); + }); + cy.get(newProposalSubmitButton).should('be.visible').click(); + cy.contains('Proposal rejected').should('be.visible'); + cy.get(dialogCloseButton).click(); + cy.navigate_to('governance'); + cy.wait_for_spinner(); + cy.get_submitted_proposal().within(() => { + cy.contains('Rejected').should('be.visible'); + cy.contains('Close time too late').should('be.visible'); + cy.get(viewProposalButton).click(); + }); + cy.get(proposalInformationTableRows) + .contains('State') + .siblings() + .contains('Rejected') + .should('be.visible'); + cy.get(proposalInformationTableRows) + .contains('Rejection reason') + .siblings() + .contains('CloseTimeTooLate') + .should('be.visible'); + cy.get(proposalInformationTableRows) + .contains('Error details') + .siblings() + .contains('proposal closing time too late') + .should('be.visible'); + }); + + it('Unable to create a freeform proposal - when no tokens are associated', function () { + cy.vega_wallet_teardown(); + cy.get(vegaWalletAssociatedBalance, txTimeout).contains( + '0.000000000000000000', + txTimeout + ); + cy.navigate_to('governance'); + cy.wait_for_spinner(); + cy.get(newProposalButton).should('be.visible').click(); + cy.get(newProposalDatabox).click(); + cy.create_ten_digit_unix_timestamp_for_specified_days('1').then( + (closingDateTimestamp) => { + cy.enter_unique_freeform_proposal_body(closingDateTimestamp); + } + ); + cy.get(newProposalSubmitButton).should('be.visible').click(); + cy.wait('@proposalSubmissionCompletion'); + cy.contains( + 'party has insufficient tokens to submit proposal request in this epoch' + ).should('be.visible'); + cy.get(dialogCloseButton).click(); + }); + + it('Unable to create a freeform proposal - when some but not enough tokens are associated', function () { + cy.ensure_specified_unstaked_tokens_are_associated( + this.minProposerBalance - 0.1 + ); + cy.navigate_to('governance'); + cy.wait_for_spinner(); + cy.get(newProposalButton).should('be.visible').click(); + cy.get(newProposalDatabox).click(); + cy.create_ten_digit_unix_timestamp_for_specified_days('1').then( + (closingDateTimestamp) => { + cy.enter_unique_freeform_proposal_body(closingDateTimestamp); + } + ); + cy.get(newProposalSubmitButton).should('be.visible').click(); + cy.wait('@proposalSubmissionCompletion'); + cy.contains( + 'party has insufficient tokens to submit proposal request in this epoch' + ).should('be.visible'); + cy.get(dialogCloseButton).click(); + }); + + Cypress.Commands.add( + 'convert_unix_timestamp_to_governance_data_table_date_format', + (unixTimestamp) => { + let dateSupplied = new Date(unixTimestamp * 1000), + year = dateSupplied.getFullYear(), + months = [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December', + ], + month = months[dateSupplied.getMonth()], + date = dateSupplied.getDate(); + + return `${date} ${month} ${year}`; + } + ); + + Cypress.Commands.add( + 'create_ten_digit_unix_timestamp_for_specified_days', + (durationDays) => { + let today = new Date(); + let timestamp = today.setDate(today.getDate() + parseInt(durationDays)); + timestamp = Math.floor(timestamp / 1000); + + return timestamp; + } + ); + + Cypress.Commands.add('enter_unique_freeform_proposal_body', (timestamp) => { + cy.fixture('/proposals/freeform.json').then((freeformProposal) => { + freeformProposal.terms.closingTimestamp = timestamp; + freeformProposal.rationale.description += timestamp; + let proposalPayload = JSON.stringify(freeformProposal); + + cy.get(newProposalDatabox).type(proposalPayload, { + parseSpecialCharSequences: false, + delay: 2, + }); + }); + }); + + Cypress.Commands.add('get_network_parameters', () => { + let mutation = '{networkParameters {key value}}'; + cy.request({ + method: 'POST', + url: `http://localhost:3028/query`, + body: { + query: mutation, + }, + headers: { 'content-type': 'application/json' }, + }) + .its('body.data.networkParameters') + .then(function (response) { + let object = response.reduce(function (r, e) { + r[e.key] = e.value; + return r; + }, {}); + + return object; + }); + }); + + Cypress.Commands.add('get_submitted_proposal', () => { + cy.wait('@proposalSubmissionCompletion') + .its(proposalResponseIdPath) + .then((proposalId) => { + cy.get(`#${proposalId}`); + }); + }); + }); +}); diff --git a/apps/token-e2e/src/integration/flow/staking-flow.cy.js b/apps/token-e2e/src/integration/flow/staking-flow.cy.js index 494087c90..0d278ec75 100644 --- a/apps/token-e2e/src/integration/flow/staking-flow.cy.js +++ b/apps/token-e2e/src/integration/flow/staking-flow.cy.js @@ -69,7 +69,7 @@ context('Staking Tab - with eth and vega wallets connected', function () { .should('be.visible'); cy.get(ethWalletAssociatedBalances, txTimeout) - .contains(vegaWalletPublicKeyShort) + .contains(vegaWalletPublicKeyShort, txTimeout) .parent() .should('contain', 3.0, txTimeout); @@ -453,9 +453,7 @@ context('Staking Tab - with eth and vega wallets connected', function () { cy.staking_page_disassociate_all_tokens(); cy.get(ethWalletContainer).within(() => { - cy.contains(vegaWalletPublicKeyShort, { timeout: 20000 }).should( - 'not.exist' - ); + cy.contains(vegaWalletPublicKeyShort, txTimeout).should('not.exist'); }); cy.get(ethWalletTotalAssociatedBalance, txTimeout) diff --git a/apps/token-e2e/src/support/staking.functions.js b/apps/token-e2e/src/support/staking.functions.js index 82f868d34..5e0f80841 100644 --- a/apps/token-e2e/src/support/staking.functions.js +++ b/apps/token-e2e/src/support/staking.functions.js @@ -5,6 +5,9 @@ const addStakeRadioButton = '[data-testid="add-stake-radio"]'; const removeStakeRadioButton = '[data-testid="remove-stake-radio"]'; const ethWalletAssociateButton = '[href="/staking/associate"]'; const ethWalletDissociateButton = '[href="/staking/disassociate"]'; +const vegaWalletUnstakedBalance = + '[data-testid="vega-wallet-balance-unstaked"]'; +const vegaWalletAssociatedBalance = '[data-testid="currency-value"]'; const associateWalletRadioButton = '[data-testid="associate-radio-wallet"]'; const stakeMaximumTokens = '[data-testid="token-amount-use-maximum"]'; const stakeValidatorListPendingStake = '[col-id="pendingStake"]'; @@ -12,12 +15,13 @@ const stakeValidatorListTotalStake = '[col-id="totalStakeThisEpoch"]'; const stakeValidatorListTotalShare = '[col-id="share"]'; const stakeValidatorListName = '[col-id="validator"]'; const txTimeout = Cypress.env('txTimeout'); +const epochTimeout = Cypress.env('epochTimeout'); Cypress.Commands.add('wait_for_begining_of_epoch', () => { - cy.contains('Waiting for next epoch to start', { timeout: 10000 }).should( + cy.contains('Waiting for next epoch to start', epochTimeout).should( 'not.exist' ); - cy.contains('Waiting for next epoch to start', { timeout: 20000 }); + cy.contains('Waiting for next epoch to start', epochTimeout); }); Cypress.Commands.add('staking_validator_page_add_stake', (stake) => { @@ -25,7 +29,7 @@ Cypress.Commands.add('staking_validator_page_add_stake', (stake) => { cy.get(addStakeRadioButton, { timeout: 8000 }).click({ force: true }); cy.get(tokenAmountInputBox).type(stake); cy.wait_for_begining_of_epoch(); - cy.get(tokenSubmitButton, { timeout: 8000 }) + cy.get(tokenSubmitButton, epochTimeout) .should('be.enabled') .and('contain', `Add ${stake} $VEGA tokens`) .and('be.visible') @@ -38,7 +42,7 @@ Cypress.Commands.add('staking_validator_page_remove_stake', (stake) => { cy.get(tokenAmountInputBox).type(stake); cy.wait_for_begining_of_epoch(); cy.get(tokenSubmitButton) - .should('be.enabled', { timeout: 8000 }) + .should('be.enabled', epochTimeout) .and('contain', `Remove ${stake} $VEGA tokens at the end of epoch`) .and('be.visible') .click(); @@ -50,44 +54,48 @@ Cypress.Commands.add( cy.highlight(`Associating ${amount} tokens`); cy.get(ethWalletAssociateButton).first().click(); cy.get(associateWalletRadioButton, { timeout: 30000 }).click(); - cy.get(tokenAmountInputBox, { timeout: 10000 }).type(amount); + cy.get(tokenAmountInputBox, epochTimeout).type(amount); if (approve) { cy.get(tokenInputApprove, txTimeout).should('be.enabled').click(); cy.contains('Approve $VEGA Tokens for staking on Vega').should( 'be.visible' ); - cy.contains('Approve $VEGA Tokens for staking on Vega', { - timeout: 40000, - }).should('not.exist'); + cy.contains( + 'Approve $VEGA Tokens for staking on Vega', + epochTimeout + ).should('not.exist'); } - cy.get(tokenSubmitButton, txTimeout).should('be.enabled').click(); - cy.contains('can now participate in governance and nominate a validator', { - timeout: 60000, - }).should('be.visible'); + cy.get(tokenSubmitButton, epochTimeout).should('be.enabled').click(); + cy.contains( + 'can now participate in governance and nominate a validator', + txTimeout + ).should('be.visible'); } ); Cypress.Commands.add('staking_page_disassociate_tokens', (amount) => { cy.highlight(`Disassociating ${amount} tokens via Staking Page`); cy.get(ethWalletDissociateButton).first().click(); - cy.get(associateWalletRadioButton, { timeout: 30000 }).click(); - cy.get(tokenAmountInputBox, { timeout: 10000 }).type(amount); + cy.get(associateWalletRadioButton, epochTimeout).click(); + cy.get(tokenAmountInputBox, epochTimeout).type(amount); - cy.get(tokenSubmitButton, txTimeout).should('be.enabled').click(); - cy.contains(`${amount} $VEGA tokens have been returned to Ethereum wallet`, { - timeout: 60000, - }).should('be.visible'); + cy.get(tokenSubmitButton, epochTimeout).should('be.enabled').click(); + cy.contains( + `${amount} $VEGA tokens have been returned to Ethereum wallet`, + txTimeout + ).should('be.visible'); }); Cypress.Commands.add('staking_page_disassociate_all_tokens', () => { cy.highlight(`Disassociating all tokens via Staking Page`); cy.get(ethWalletDissociateButton).first().click(); - cy.get(associateWalletRadioButton, { timeout: 20000 }).click(); - cy.get(stakeMaximumTokens, { timeout: 60000 }).click(); - cy.get(tokenSubmitButton, { timeout: 10000 }).click(); - cy.contains('$VEGA tokens have been returned to Ethereum wallet', { - timeout: 60000, - }).should('be.visible'); + cy.get(associateWalletRadioButton, epochTimeout).click(); + cy.get(stakeMaximumTokens, epochTimeout).click(); + cy.get(tokenSubmitButton, epochTimeout).click(); + cy.contains( + '$VEGA tokens have been returned to Ethereum wallet', + txTimeout + ).should('be.visible'); }); Cypress.Commands.add( @@ -131,3 +139,25 @@ Cypress.Commands.add( }); } ); + +Cypress.Commands.add( + 'ensure_specified_unstaked_tokens_are_associated', + (tokenAmount) => { + cy.highlight(`Ensuring ${tokenAmount} token(s) associated`); + cy.get(vegaWalletUnstakedBalance) + .children() + .children() + .eq(1) + .invoke('text') + .then((unstakedBalance) => { + if (parseFloat(unstakedBalance) != parseFloat(tokenAmount)) { + cy.vega_wallet_teardown(); + cy.get(vegaWalletAssociatedBalance, txTimeout).contains( + '0.000000000000000000', + txTimeout + ); + cy.staking_page_associate_tokens(tokenAmount); + } + }); + } +); diff --git a/apps/token/.env b/apps/token/.env index 127c44b63..1006a709c 100644 --- a/apps/token/.env +++ b/apps/token/.env @@ -4,6 +4,7 @@ NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json NX_VEGA_URL=https://lb.testnet.vega.xyz/query NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8 NX_ETHERSCAN_URL=https://ropsten.etherscan.io +NX_VEGA_REST=https://lb.testnet.vega.xyz/datanode/rest NX_FAIRGROUND=false NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev.token.vega.xyz","STAGNET2":"staging2.token.vega.xyz","TESTNET":"token.fairground.wtf","MAINNET":"token.vega.xyz"}' NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions diff --git a/apps/token/.env.devnet b/apps/token/.env.devnet index 58df9161f..d382c6a58 100644 --- a/apps/token/.env.devnet +++ b/apps/token/.env.devnet @@ -2,6 +2,7 @@ NX_VEGA_ENV=DEVNET NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/devnet-network.json NX_VEGA_URL=https://n04.d.vega.xyz/query +NX_VEGA_REST=https://n04.d.vega.xyz/datanode/rest NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev.token.vega.xyz","STAGNET2":"staging2.token.vega.xyz","TESTNET":"token.fairground.wtf","MAINNET":"token.vega.xyz"}' NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8 NX_ETHERSCAN_URL=https://ropsten.etherscan.io diff --git a/apps/token/.env.mainnet b/apps/token/.env.mainnet index 989eb5192..dcfd45f1b 100644 --- a/apps/token/.env.mainnet +++ b/apps/token/.env.mainnet @@ -6,3 +6,4 @@ NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev. NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8 NX_ETHERSCAN_URL=https://etherscan.io NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions +NX_VEGA_REST=https://api.token.vega.xyz/ diff --git a/apps/token/.env.stagnet1 b/apps/token/.env.stagnet1 index b2a941f51..c4761fbff 100644 --- a/apps/token/.env.stagnet1 +++ b/apps/token/.env.stagnet1 @@ -6,3 +6,4 @@ NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev. NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8 NX_ETHERSCAN_URL=https://ropsten.etherscan.io NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions +NX_VEGA_REST=https://n03.s.vega.xyz/datanode/rest diff --git a/apps/token/.env.stagnet2 b/apps/token/.env.stagnet2 index 51816c6b4..4b29fc41d 100644 --- a/apps/token/.env.stagnet2 +++ b/apps/token/.env.stagnet2 @@ -6,3 +6,4 @@ NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev. NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8 NX_ETHERSCAN_URL=https://ropsten.etherscan.io NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions +NX_VEGA_REST=https://n01.stagnet2.vega.xyz/datanode/rest diff --git a/apps/token/.env.testnet b/apps/token/.env.testnet index 3de17188b..57c002ec7 100644 --- a/apps/token/.env.testnet +++ b/apps/token/.env.testnet @@ -6,3 +6,4 @@ NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev. NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8 NX_ETHERSCAN_URL=https://ropsten.etherscan.io NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions +NX_VEGA_REST=https://lb.testnet.vega.xyz/datanode/rest diff --git a/apps/token/src/config/env.ts b/apps/token/src/config/env.ts index 972b34557..ab0387b3a 100644 --- a/apps/token/src/config/env.ts +++ b/apps/token/src/config/env.ts @@ -55,6 +55,7 @@ export const ENV = { commit: windowOrDefault('NX_COMMIT_REF'), branch: windowOrDefault('NX_BRANCH'), vegaUrl: windowOrDefault('NX_VEGA_URL'), + restUrl: windowOrDefault('NX_VEGA_REST'), urlConnect: TRUTHY.includes(windowOrDefault('NX_ETH_URL_CONNECT')), ethWalletMnemonic: windowOrDefault('NX_ETH_WALLET_MNEMONIC'), localProviderUrl: windowOrDefault('NX_LOCAL_PROVIDER_URL'), diff --git a/apps/token/src/routes/governance/proposal/proposal-container.tsx b/apps/token/src/routes/governance/proposal/proposal-container.tsx index 75724f4ef..8af319078 100644 --- a/apps/token/src/routes/governance/proposal/proposal-container.tsx +++ b/apps/token/src/routes/governance/proposal/proposal-container.tsx @@ -6,13 +6,13 @@ import { useParams } from 'react-router-dom'; import { SplashLoader } from '../../../components/splash-loader'; import { useFetch } from '@vegaprotocol/react-helpers'; -import { getDataNodeUrl } from '../../../lib/get-data-node-url'; import { Proposal } from '../components/proposal'; import { PROPOSALS_FRAGMENT } from '../proposal-fragment'; import type { Proposal as ProposalQueryResult, ProposalVariables, } from './__generated__/Proposal'; +import { ENV } from '../../../config/env'; /** * TODO: how do we do this properly to ensure that it is kept up to date? @@ -38,12 +38,9 @@ export const PROPOSAL_QUERY = gql` export const ProposalContainer = () => { const { t } = useTranslation(); const params = useParams<{ proposalId: string }>(); - const { base } = getDataNodeUrl(); const proposalUrl = React.useMemo( - () => - new URL(`datanode/rest/governance/proposal/${params.proposalId}`, base) - .href, - [base, params.proposalId] + () => new URL(`governance/proposal/${params.proposalId}`, ENV.restUrl).href, + [params.proposalId] ); const { diff --git a/apps/token/src/routes/governance/proposals/proposals-container.tsx b/apps/token/src/routes/governance/proposals/proposals-container.tsx index fba6c3243..6465d33a4 100644 --- a/apps/token/src/routes/governance/proposals/proposals-container.tsx +++ b/apps/token/src/routes/governance/proposals/proposals-container.tsx @@ -24,6 +24,7 @@ export const ProposalsContainer = () => { const { t } = useTranslation(); const { data, loading, error } = useQuery(PROPOSALS_QUERY, { pollInterval: 5000, + fetchPolicy: 'network-only', errorPolicy: 'ignore', // this is to get around some backend issues and should be removed in future });