From 4e122886bfdb477c1f2563fc0c0c1f9730fecb85 Mon Sep 17 00:00:00 2001 From: Andrew Snaith Date: Thu, 7 Dec 2023 12:49:28 -0800 Subject: [PATCH 01/10] add new test fixtures for unknown transactions --- packages/ui/cypress/fixtures/knownMultisigs.ts | 10 ++++++++++ packages/ui/cypress/fixtures/testAccounts.ts | 14 ++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/packages/ui/cypress/fixtures/knownMultisigs.ts b/packages/ui/cypress/fixtures/knownMultisigs.ts index c07b2c22..efa775fa 100644 --- a/packages/ui/cypress/fixtures/knownMultisigs.ts +++ b/packages/ui/cypress/fixtures/knownMultisigs.ts @@ -8,5 +8,15 @@ export const knownMultisigs = { testAccounts['Multisig Member Account 1'].address, testAccounts['Multisig Member Account 2'].address ] + }, + 'multisig-with-unknown-transaction': { + address: '5CNUH7K6RgXqEo4zK3i9cEDX1CDozJkmvuK6cRZ3z8ovY5CN', + pureAddress: '5GeQBX3xT9oV5PVjnuakx6tRFEwxKGqnohfduWpp4MVt1uC6', + purePublicKey: '0xcaa3c7393cdc0d101797a216222c1d44a92bdc3653f6d0fadfad040adad4e091', + threshold: 2, + signatories: [ + testAccounts['Signatory 1 Of Multisig With Uknown Transaction'].address, + testAccounts['Signatory 2 Of Multisig With Uknown Transaction'].address + ] } } diff --git a/packages/ui/cypress/fixtures/testAccounts.ts b/packages/ui/cypress/fixtures/testAccounts.ts index 57947466..37efb5f4 100644 --- a/packages/ui/cypress/fixtures/testAccounts.ts +++ b/packages/ui/cypress/fixtures/testAccounts.ts @@ -62,4 +62,18 @@ export const testAccounts = { type: 'sr25519', mnemonic: 'bottom drive obey lake curtain smoke basket hold race lonely fit walk//chopsticks/3' } as InjectedAccountWitMnemonic + 'Signatory 1 Of Multisig With Uknown Transaction': { + address: '5C5RWYL7zoV6V2vdwXENSpSzWHXUxyhHBrEzhfySdQmkiF9d', + publicKey: '0x008c37659f858da7ec1416ce01b975af4c6eb5931805047d173d63123174a74e', + name: 'Funded Account 3 Chopsticks', + type: 'sr25519', + mnemonic: 'various sun sell patch follow stove warfare worry cupboard kick wise wild' + } as InjectedAccountWitMnemonic + 'Signatory 2 Of Multisig With Uknown Transaction': { + address: '5DAA5LQP8C4Cus1caXr3rwDa5LuPCJmXeoj3HrCUWEpGUV7g', + publicKey: '0x3064b82d59077c4d2d7b924b72e63fb9b829b5cd0706b9236c35b79ffa89995b', + name: 'Funded Account 3 Chopsticks', + type: 'sr25519', + mnemonic: 'canyon narrow primary zoo purpose double rice faculty critic embark trophy economy' + } as InjectedAccountWitMnemonic } From 05dc7a288a122dd98d515e814fa669217c3281df Mon Sep 17 00:00:00 2001 From: Andrew Snaith Date: Thu, 7 Dec 2023 15:09:18 -0800 Subject: [PATCH 02/10] add new tests for unknown transactions --- .../ui/cypress/fixtures/knownMultisigs.ts | 6 +- packages/ui/cypress/fixtures/testAccounts.ts | 12 ++-- .../page-objects/modals/txSigningModal.ts | 8 +++ .../support/page-objects/multisigPage.ts | 11 +++- .../cypress/tests/unknown-transaction.cy.ts | 55 +++++++++++++++++++ packages/ui/src/components/CallInfo.tsx | 10 +++- .../components/Transactions/Transaction.tsx | 1 + .../src/components/modals/ProposalSigning.tsx | 11 +++- 8 files changed, 100 insertions(+), 14 deletions(-) create mode 100644 packages/ui/cypress/support/page-objects/modals/txSigningModal.ts create mode 100644 packages/ui/cypress/tests/unknown-transaction.cy.ts diff --git a/packages/ui/cypress/fixtures/knownMultisigs.ts b/packages/ui/cypress/fixtures/knownMultisigs.ts index efa775fa..f7d4cd5c 100644 --- a/packages/ui/cypress/fixtures/knownMultisigs.ts +++ b/packages/ui/cypress/fixtures/knownMultisigs.ts @@ -14,9 +14,11 @@ export const knownMultisigs = { pureAddress: '5GeQBX3xT9oV5PVjnuakx6tRFEwxKGqnohfduWpp4MVt1uC6', purePublicKey: '0xcaa3c7393cdc0d101797a216222c1d44a92bdc3653f6d0fadfad040adad4e091', threshold: 2, + hashOfUknownCall: '0x78dde73fae42b1728ce6feef5c1c4eac85efb70edb51eb1bda8cf47bd3f13fec', + callData: '0x00005c556b6e6f776e205472616e73616374696f6e2054657374', signatories: [ - testAccounts['Signatory 1 Of Multisig With Uknown Transaction'].address, - testAccounts['Signatory 2 Of Multisig With Uknown Transaction'].address + testAccounts['Signatory 1 Of Multisig With Unknown Tx'].address, + testAccounts['Signatory 2 Of Multisig With Unknown Tx'].address ] } } diff --git a/packages/ui/cypress/fixtures/testAccounts.ts b/packages/ui/cypress/fixtures/testAccounts.ts index 37efb5f4..42cda194 100644 --- a/packages/ui/cypress/fixtures/testAccounts.ts +++ b/packages/ui/cypress/fixtures/testAccounts.ts @@ -61,18 +61,18 @@ export const testAccounts = { name: 'Funded Account 3 Chopsticks', type: 'sr25519', mnemonic: 'bottom drive obey lake curtain smoke basket hold race lonely fit walk//chopsticks/3' - } as InjectedAccountWitMnemonic - 'Signatory 1 Of Multisig With Uknown Transaction': { + } as InjectedAccountWitMnemonic, + 'Signatory 1 Of Multisig With Unknown Tx': { address: '5C5RWYL7zoV6V2vdwXENSpSzWHXUxyhHBrEzhfySdQmkiF9d', publicKey: '0x008c37659f858da7ec1416ce01b975af4c6eb5931805047d173d63123174a74e', - name: 'Funded Account 3 Chopsticks', + name: 'Signatory 1 Of Multisig With Unknown Tx', type: 'sr25519', mnemonic: 'various sun sell patch follow stove warfare worry cupboard kick wise wild' - } as InjectedAccountWitMnemonic - 'Signatory 2 Of Multisig With Uknown Transaction': { + } as InjectedAccountWitMnemonic, + 'Signatory 2 Of Multisig With Unknown Tx': { address: '5DAA5LQP8C4Cus1caXr3rwDa5LuPCJmXeoj3HrCUWEpGUV7g', publicKey: '0x3064b82d59077c4d2d7b924b72e63fb9b829b5cd0706b9236c35b79ffa89995b', - name: 'Funded Account 3 Chopsticks', + name: 'Signatory 2 Of Multisig With Unknown Tx', type: 'sr25519', mnemonic: 'canyon narrow primary zoo purpose double rice faculty critic embark trophy economy' } as InjectedAccountWitMnemonic diff --git a/packages/ui/cypress/support/page-objects/modals/txSigningModal.ts b/packages/ui/cypress/support/page-objects/modals/txSigningModal.ts new file mode 100644 index 00000000..0ea4986f --- /dev/null +++ b/packages/ui/cypress/support/page-objects/modals/txSigningModal.ts @@ -0,0 +1,8 @@ +export const txSigningModal = { + body: () => cy.get('[data-cy=modal-tx-signing]'), + callHashLabel: () => cy.get('[data-cy=label-call-hash]'), + approveButton: () => cy.get('[data-cy=button-approve-tx]'), + rejectButton: () => cy.get('[data-cy=button-reject-tx]'), + callDataInput: () => cy.get('[data-cy=input-call-data]'), + callInfoContainer: () => cy.get('[data-cy=container-call-info]') +} diff --git a/packages/ui/cypress/support/page-objects/multisigPage.ts b/packages/ui/cypress/support/page-objects/multisigPage.ts index a4c6f42b..13e2d9ff 100644 --- a/packages/ui/cypress/support/page-objects/multisigPage.ts +++ b/packages/ui/cypress/support/page-objects/multisigPage.ts @@ -6,8 +6,6 @@ export const multisigPage = { optionsMenuButton: () => cy.get('[data-cy=button-options-menu]'), editNamesMenuOption: () => cy.get('[data-cy=menu-option-edit-names]'), subscanMenuOption: () => cy.get('[data-cy=menu-option-subscan]'), - transactionList: () => cy.get('[data-cy=container-transaction-list]', { timeout: 20000 }), - pendingTransactionItem: () => cy.get('[data-cy=container-pending-tx-item]'), reviewButton: () => cy.get('[data-cy=button-review-tx]'), setIdentityMenuOption: () => cy.get('[data-cy=menu-option-set-identity]'), @@ -17,5 +15,12 @@ export const multisigPage = { thresholdListItem: () => cy.get('[data-cy=list-item-threshold]'), balanceListItem: () => cy.get('[data-cy=list-item-balance]'), signatoriesAccordion: () => cy.get('[data-cy=accordion-signatories]'), - expandSignatoriesIcon: () => cy.get('[data-cy=icon-expand-signatories-summary]') + expandSignatoriesIcon: () => cy.get('[data-cy=icon-expand-signatories-summary]'), + + // transaction list elements + transactionList: () => cy.get('[data-cy=container-transaction-list]', { timeout: 20000 }), + pendingTransactionItem: () => cy.get('[data-cy=container-pending-tx-item]'), + pendingTransactionCallName: () => cy.get('[data-cy=label-call-name]'), + unknownCallIcon: () => cy.get('[data-cy=icon-unknown-call]'), + unknownCallAlert: () => cy.get('[data-cy=alert-no-call-data]') } diff --git a/packages/ui/cypress/tests/unknown-transaction.cy.ts b/packages/ui/cypress/tests/unknown-transaction.cy.ts new file mode 100644 index 00000000..822d0d06 --- /dev/null +++ b/packages/ui/cypress/tests/unknown-transaction.cy.ts @@ -0,0 +1,55 @@ +import { testAccounts } from '../fixtures/testAccounts' +import { landingPageUrl } from '../fixtures/landingData' +import { multisigPage } from '../support/page-objects/multisigPage' +import { txSigningModal } from '../support/page-objects/modals/txSigningModal' +import { knownMultisigs } from '../fixtures/knownMultisigs' + +describe('Unknown Transaction', () => { + beforeEach(() => { + cy.setupAndVisit({ + url: landingPageUrl, + extensionConnectionAllowed: true, + injectExtensionWithAccounts: [testAccounts['Signatory 2 Of Multisig With Unknown Tx']] + }) + }) + + it('can see an unknown transaction displayed in the transaction list', () => { + multisigPage + .transactionList() + .should('be.visible') + .within(() => { + multisigPage.pendingTransactionItem().should('have.length', 1) + multisigPage.pendingTransactionItem().within(() => { + multisigPage.pendingTransactionCallName().should('contain.text', 'Unknown call') + multisigPage.unknownCallIcon().should('be.visible') + multisigPage.unknownCallAlert().should('be.visible') + }) + }) + }) + + it('can see the expected state of an unknown tx without call data', () => { + const { hashOfUknownCall: expectedCallHash, callData } = + knownMultisigs['multisig-with-unknown-transaction'] + + multisigPage + .transactionList() + .should('be.visible') + .within(() => { + multisigPage.pendingTransactionItem().within(() => { + multisigPage.reviewButton().click() + }) + }) + txSigningModal + .body() + .should('be.visible') + .within(() => { + txSigningModal.callHashLabel().should('contain.text', expectedCallHash) + txSigningModal.approveButton().should('not.be.enabled') + txSigningModal.rejectButton().should('not.exist') + // now provide call data and ensure we see the call info and approve button enabled + txSigningModal.callDataInput().type(callData) + txSigningModal.callInfoContainer().should('be.visible') + txSigningModal.approveButton().should('be.enabled') + }) + }) +}) diff --git a/packages/ui/src/components/CallInfo.tsx b/packages/ui/src/components/CallInfo.tsx index eb3c8aa0..9f9c2a2b 100644 --- a/packages/ui/src/components/CallInfo.tsx +++ b/packages/ui/src/components/CallInfo.tsx @@ -200,8 +200,14 @@ const CallInfo = ({ const hasArgs = useMemo(() => args && Object.keys(args).length > 0, [args]) return ( -
- +
+ {name} {!!aggregatedData.callData && withLink && ( ) : ( Transaction signing @@ -298,7 +299,12 @@ const ProposalSigning = ({ > Call hash
- {proposalData.hash} + + {proposalData.hash} + {!isProposerSelected && !proposalData.callData && ( @@ -319,6 +325,7 @@ const ProposalSigning = ({ onChange={onAddedCallDataChange} value={addedCallData || ''} fullWidth + data-cy="input-call-data" /> onSign(false)} disabled={isSubmitting} + data-cy="button-reject-tx" > Reject @@ -392,6 +400,7 @@ const ProposalSigning = ({ variant="primary" onClick={() => onSign(true)} disabled={!!errorMessage || isSubmitting || (mustSubmitCallData && !callInfo?.call)} + data-cy="button-approve-tx" > Approve From 653b59a99b4c8707a4a437884d9a403811309e88 Mon Sep 17 00:00:00 2001 From: Andrew Snaith Date: Fri, 8 Dec 2023 09:28:16 -0800 Subject: [PATCH 03/10] fix mistake and address pr feedback --- packages/ui/cypress/fixtures/knownMultisigs.ts | 4 ++-- packages/ui/cypress/tests/unknown-transaction.cy.ts | 6 +++++- packages/ui/src/components/CallInfo.tsx | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/ui/cypress/fixtures/knownMultisigs.ts b/packages/ui/cypress/fixtures/knownMultisigs.ts index f7d4cd5c..a6da17dd 100644 --- a/packages/ui/cypress/fixtures/knownMultisigs.ts +++ b/packages/ui/cypress/fixtures/knownMultisigs.ts @@ -14,8 +14,8 @@ export const knownMultisigs = { pureAddress: '5GeQBX3xT9oV5PVjnuakx6tRFEwxKGqnohfduWpp4MVt1uC6', purePublicKey: '0xcaa3c7393cdc0d101797a216222c1d44a92bdc3653f6d0fadfad040adad4e091', threshold: 2, - hashOfUknownCall: '0x78dde73fae42b1728ce6feef5c1c4eac85efb70edb51eb1bda8cf47bd3f13fec', - callData: '0x00005c556b6e6f776e205472616e73616374696f6e2054657374', + hashOfUknownCall: '0x49478dcdda5a328ba4918e8faca68f347462f41903c461122a36b7c51483768f', + callData: '0x000060556e6b6e6f776e205472616e73616374696f6e2054657374', signatories: [ testAccounts['Signatory 1 Of Multisig With Unknown Tx'].address, testAccounts['Signatory 2 Of Multisig With Unknown Tx'].address diff --git a/packages/ui/cypress/tests/unknown-transaction.cy.ts b/packages/ui/cypress/tests/unknown-transaction.cy.ts index 822d0d06..948bac8f 100644 --- a/packages/ui/cypress/tests/unknown-transaction.cy.ts +++ b/packages/ui/cypress/tests/unknown-transaction.cy.ts @@ -48,7 +48,11 @@ describe('Unknown Transaction', () => { txSigningModal.rejectButton().should('not.exist') // now provide call data and ensure we see the call info and approve button enabled txSigningModal.callDataInput().type(callData) - txSigningModal.callInfoContainer().should('be.visible') + txSigningModal + .callInfoContainer() + .should('be.visible') + .should('contain.text', 'system.remark') + .should('contain.text', 'remark: Unknown Transaction Test') txSigningModal.approveButton().should('be.enabled') }) }) diff --git a/packages/ui/src/components/CallInfo.tsx b/packages/ui/src/components/CallInfo.tsx index 9f9c2a2b..2cfa7047 100644 --- a/packages/ui/src/components/CallInfo.tsx +++ b/packages/ui/src/components/CallInfo.tsx @@ -223,6 +223,7 @@ const CallInfo = ({ className={className} severity="info" variant="outlined" + data-cy="alert-no-call-data" > No Call data found on-chain. Use Multix to initiate multisig transactions and avoid this annoyance. From 8d86ff8a09e210bc69ca718ad8bcc3594a53709c Mon Sep 17 00:00:00 2001 From: Andrew Snaith Date: Fri, 8 Dec 2023 09:55:56 -0800 Subject: [PATCH 04/10] increase timeout of toast for more reliability --- packages/ui/cypress/support/page-objects/notifications.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/ui/cypress/support/page-objects/notifications.ts b/packages/ui/cypress/support/page-objects/notifications.ts index dc8a8f36..500fd1f5 100644 --- a/packages/ui/cypress/support/page-objects/notifications.ts +++ b/packages/ui/cypress/support/page-objects/notifications.ts @@ -1,7 +1,7 @@ export const notifications = { - successNotificationIcon: (timeout = 4000) => + successNotificationIcon: (timeout = 8000) => cy.get('[data-cy=notification-icon-success]', { timeout }), errorNotificationIcon: () => cy.get('[data-cy=notification-icon-error]'), loadingNotificationIcon: () => cy.get('[data-cy=notification-icon-loading]'), - notificationWrapper: (timeout = 4000) => cy.get('[data-cy=notification-wrapper]', { timeout }) + notificationWrapper: (timeout = 8000) => cy.get('[data-cy=notification-wrapper]', { timeout }) } From c65e2de0c92fc5c80cc6a472599485fc86275e06 Mon Sep 17 00:00:00 2001 From: Andrew Snaith Date: Fri, 8 Dec 2023 10:17:50 -0800 Subject: [PATCH 05/10] undo timeout changes --- packages/ui/cypress/support/page-objects/notifications.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/ui/cypress/support/page-objects/notifications.ts b/packages/ui/cypress/support/page-objects/notifications.ts index 500fd1f5..dc8a8f36 100644 --- a/packages/ui/cypress/support/page-objects/notifications.ts +++ b/packages/ui/cypress/support/page-objects/notifications.ts @@ -1,7 +1,7 @@ export const notifications = { - successNotificationIcon: (timeout = 8000) => + successNotificationIcon: (timeout = 4000) => cy.get('[data-cy=notification-icon-success]', { timeout }), errorNotificationIcon: () => cy.get('[data-cy=notification-icon-error]'), loadingNotificationIcon: () => cy.get('[data-cy=notification-icon-loading]'), - notificationWrapper: (timeout = 8000) => cy.get('[data-cy=notification-wrapper]', { timeout }) + notificationWrapper: (timeout = 4000) => cy.get('[data-cy=notification-wrapper]', { timeout }) } From 6ad5e99575fc36840641e3edda1830ac42437847 Mon Sep 17 00:00:00 2001 From: Thibaut Sardan Date: Sun, 10 Dec 2023 20:23:08 +0000 Subject: [PATCH 06/10] fix Balance display --- packages/ui/src/components/CallInfo.tsx | 4 +- .../components/EasySetup/ManualExtrinsic.tsx | 9 ++-- packages/ui/src/constants.ts | 41 +++++++++++++++++++ packages/ui/src/utils/isTypeBalance.ts | 9 +++- 4 files changed, 56 insertions(+), 7 deletions(-) diff --git a/packages/ui/src/components/CallInfo.tsx b/packages/ui/src/components/CallInfo.tsx index eb3c8aa0..57cc420d 100644 --- a/packages/ui/src/components/CallInfo.tsx +++ b/packages/ui/src/components/CallInfo.tsx @@ -11,7 +11,7 @@ import { Link } from './library' import { usePjsLinks } from '../hooks/usePjsLinks' import { Alert } from '@mui/material' import { ApiPromise } from '@polkadot/api' -import { isTypeBalance, isTypeAccount } from '../utils' +import { isTypeBalanceWithBalanceCall, isTypeAccount } from '../utils' import { CallDataInfoFromChain } from '../hooks/usePendingTx' interface Props { @@ -128,7 +128,7 @@ const createUlTree = ({ name, args, decimals, unit, api, typeName }: CreateTreeP } // generically show nice value for Balance type - if (isTypeBalance(_typeName)) { + if (isTypeBalanceWithBalanceCall(_typeName, name)) { return handleBalanceDisplay({ value, decimals, unit, key }) } diff --git a/packages/ui/src/components/EasySetup/ManualExtrinsic.tsx b/packages/ui/src/components/EasySetup/ManualExtrinsic.tsx index cf970907..26cf854d 100644 --- a/packages/ui/src/components/EasySetup/ManualExtrinsic.tsx +++ b/packages/ui/src/components/EasySetup/ManualExtrinsic.tsx @@ -16,7 +16,7 @@ import { useApi } from '../../contexts/ApiContext' import paramConversion from '../../utils/paramConversion' import { getGlobalMaxValue, inputToBn } from '../../utils' import BN from 'bn.js' -import { isTypeBalance } from '../../utils/isTypeBalance' +import { isTypeBalanceWithBalanceCall } from '../../utils/isTypeBalance' interface Props { extrinsicIndex?: string @@ -160,7 +160,7 @@ const ManualExtrinsic = ({ // Deal with balance like types where the param needs to // be multiplied by the token decimals - if (isTypeBalance(typeName)) { + if (isTypeBalanceWithBalanceCall(typeName, `${palletRpc}.${callable}`)) { if (!isValidAmountString(value) || !chainInfo?.tokenDecimals) { return previousValue } @@ -389,7 +389,10 @@ const ManualExtrinsic = ({ value={inputParams[ind] ? inputParams[ind].value : ''} onChange={(event) => onParamChange(event, { ind, paramField })} InputProps={{ - endAdornment: isTypeBalance(paramField.typeName) && ( + endAdornment: isTypeBalanceWithBalanceCall( + paramField.typeName, + `${palletRpc}.${callable}` + ) && ( {chainInfo?.tokenSymbol || ''} ) }} diff --git a/packages/ui/src/constants.ts b/packages/ui/src/constants.ts index 0530ab7c..92f02266 100644 --- a/packages/ui/src/constants.ts +++ b/packages/ui/src/constants.ts @@ -231,3 +231,44 @@ export const POLKADOT_SIGNING_METHODS = { POLKADOT_SIGN_TRANSACTION: 'polkadot_signTransaction', POLKADOT_SIGN_MESSAGE: 'polkadot_signMessage' } + +// from https://github.com/polkadot-js/apps/blob/acb87b52e52eda082b3d600abeadfed0f7ca3cc2/packages/react-params/src/overrides.ts#L4 +export const balanceCalls = [ + 'auctions.bid', + 'balances.forceTransfer', + 'balances.forceUnreserve', + 'balances.setBalance', + 'balances.transfer', + 'balances.transferAllowDeath', + 'balances.transferKeepAlive', + 'bounties.proposeBounty', + 'bounties.proposeCurator', + 'childBounties.proposeCurator', + 'claims.mintClaim', + 'convictionVoting.delegate', + 'convictionVoting.vote', + 'crowdloan.contribute', + 'crowdloan.create', + 'crowdloan.edit', + 'democracy.delegate', + 'democracy.propose', + 'democracy.vote', + 'identity.requestJudgement', + 'identity.setFee', + 'nominationPools.bondExtra', + 'nominationPools.join', + 'nominationPools.unbond', + 'phragmenElection.vote', + 'society.bid', + 'society.vouch', + 'staking.bond', + 'staking.bondExtra', + 'staking.rebond', + 'staking.unbond', + 'tips.tip', + 'tips.tipNew', + 'treasury.proposeSpend', + 'treasury.spend', + 'vesting.forceVestedTransfer', + 'vesting.vestedTransfer' +] diff --git a/packages/ui/src/utils/isTypeBalance.ts b/packages/ui/src/utils/isTypeBalance.ts index fb13ff56..697efea8 100644 --- a/packages/ui/src/utils/isTypeBalance.ts +++ b/packages/ui/src/utils/isTypeBalance.ts @@ -1,2 +1,7 @@ -export const isTypeBalance = (typeName?: string) => - !!typeName && ['Balance', 'BalanceOf', 'Amount'].includes(typeName) +import { balanceCalls } from '../constants' + +export const isTypeBalanceWithBalanceCall = (typeName?: string, call?: string) => + !!typeName && + !!call && + ['Balance', 'BalanceOf', 'Amount'].includes(typeName) && + balanceCalls.includes(call) From 6507b85f1968cecfe6d9173db512a5539c4e060e Mon Sep 17 00:00:00 2001 From: Thibaut Sardan Date: Mon, 11 Dec 2023 14:36:07 +0000 Subject: [PATCH 07/10] add tests --- .../fixtures/extrinsicsDisplayAccounts.ts | 14 ++++ .../support/page-objects/multisigPage.ts | 4 +- .../support/page-objects/sendTxModal.ts | 10 ++- .../ui/cypress/tests/extrinsic-display.cy.ts | 75 +++++++++++++++++++ .../components/EasySetup/ManualExtrinsic.tsx | 10 ++- packages/ui/src/components/Expander.tsx | 8 +- packages/ui/src/constants.ts | 3 + 7 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 packages/ui/cypress/fixtures/extrinsicsDisplayAccounts.ts create mode 100644 packages/ui/cypress/tests/extrinsic-display.cy.ts diff --git a/packages/ui/cypress/fixtures/extrinsicsDisplayAccounts.ts b/packages/ui/cypress/fixtures/extrinsicsDisplayAccounts.ts new file mode 100644 index 00000000..9cf6ce95 --- /dev/null +++ b/packages/ui/cypress/fixtures/extrinsicsDisplayAccounts.ts @@ -0,0 +1,14 @@ +import { InjectedAccountWitMnemonic } from './testAccounts' + +export const expectedMultisigAddress = '7J9rSWpjfQjSYr1QDKPr6KjhnC2b2kLWfyBTiTpMgkNvD7vr' + +export const extrinsicsDisplayAccounts = { + // it has no token but is part of a multisig + Alice: { + address: '7NPoMQbiA6trJKkjB35uk96MeJD4PGWkLQLH7k7hXEkZpiba', + publicKey: '0xb4b72576a091c5d691c2fd37f6eaa3d51c7480c2baaeab48737e5a209db4a431', + name: 'Alice', + type: 'sr25519', + mnemonic: 'bottom drive obey lake curtain smoke basket hold race lonely fit walk//Alice' + } as InjectedAccountWitMnemonic +} diff --git a/packages/ui/cypress/support/page-objects/multisigPage.ts b/packages/ui/cypress/support/page-objects/multisigPage.ts index 13e2d9ff..3ad40126 100644 --- a/packages/ui/cypress/support/page-objects/multisigPage.ts +++ b/packages/ui/cypress/support/page-objects/multisigPage.ts @@ -22,5 +22,7 @@ export const multisigPage = { pendingTransactionItem: () => cy.get('[data-cy=container-pending-tx-item]'), pendingTransactionCallName: () => cy.get('[data-cy=label-call-name]'), unknownCallIcon: () => cy.get('[data-cy=icon-unknown-call]'), - unknownCallAlert: () => cy.get('[data-cy=alert-no-call-data]') + unknownCallAlert: () => cy.get('[data-cy=alert-no-call-data]'), + paramExpander: () => cy.get('[data-cy=label-expander]'), + contentExpander: () => cy.get('[data-cy=content-expander]') } diff --git a/packages/ui/cypress/support/page-objects/sendTxModal.ts b/packages/ui/cypress/support/page-objects/sendTxModal.ts index cc7bedd1..c5932cb1 100644 --- a/packages/ui/cypress/support/page-objects/sendTxModal.ts +++ b/packages/ui/cypress/support/page-objects/sendTxModal.ts @@ -10,5 +10,13 @@ export const sendTxModal = { cy.get(`[data-cy=set-identity-field-${field}] > ${element}`), sendTxError: () => cy.get('[data-cy=error-send-tx]'), selectEasySetup: () => cy.get('[data-cy=select-easy-setup]'), - selectionEasySetupSetIdentity: () => cy.get('[data-cy=select-option-easy-setup-set-identity]') + selectionEasySetupSetIdentity: () => cy.get('[data-cy=select-option-easy-setup-set-identity]'), + selectionEasySetupSetupManualExtrinsic: () => + cy.get('[data-cy=select-option-easy-setup-manual-extrinsic]'), + manualPalletSelection: () => cy.get('[data-cy=select-manual-pallet]'), + manualMethodSelection: () => cy.get('[data-cy=select-manual-method]'), + optionPallet: (pallet: string) => cy.get(`[data-cy=option-pallet-${pallet}]`), + optionMethod: (method: string) => cy.get(`[data-cy=option-method-${method}]`), + paramField: (param: string) => cy.get(`[data-cy=param-field-${param}]`), + paramInput: (param: string) => cy.get(`[data-cy=param-input-${param}]`) } diff --git a/packages/ui/cypress/tests/extrinsic-display.cy.ts b/packages/ui/cypress/tests/extrinsic-display.cy.ts new file mode 100644 index 00000000..dae24397 --- /dev/null +++ b/packages/ui/cypress/tests/extrinsic-display.cy.ts @@ -0,0 +1,75 @@ +import { + expectedMultisigAddress, + extrinsicsDisplayAccounts +} from '../fixtures/extrinsicsDisplayAccounts' +import { landingPageNetwork } from '../fixtures/landingData' +import { accountDisplay } from '../support/page-objects/components/accountDisplay' +import { multisigPage } from '../support/page-objects/multisigPage' +import { sendTxModal } from '../support/page-objects/sendTxModal' + +describe('Verify extrinsics display', () => { + beforeEach(() => { + cy.setupAndVisit({ + url: landingPageNetwork('hydradx'), + extensionConnectionAllowed: true, + injectExtensionWithAccounts: [extrinsicsDisplayAccounts['Alice']] + }) + }) + + it('The omnipool.sell extrinsic is displayed in plank', () => { + multisigPage.accountHeader().within(() => { + accountDisplay.addressLabel().should('contain.text', expectedMultisigAddress.slice(0, 6)) + }) + + multisigPage + .transactionList() + .should('be.visible') + .within(() => { + multisigPage.pendingTransactionItem().should('have.length', 1) + multisigPage.pendingTransactionItem().within(() => { + multisigPage.pendingTransactionCallName().should('contain.text', 'omnipool.sell') + multisigPage.unknownCallIcon().should('not.exist') + multisigPage.unknownCallAlert().should('not.exist') + multisigPage.paramExpander().click() + multisigPage.contentExpander().should('contain', 'amount: 10,000,000,000,000') + multisigPage.contentExpander().should('contain', 'min_buy_amount: 59,509') + }) + }) + }) + + it('A manual omnipool.sell extrinsic has input in plank', () => { + multisigPage.accountHeader().within(() => { + accountDisplay.addressLabel().should('contain.text', expectedMultisigAddress.slice(0, 6)) + }) + + multisigPage.newTransactionButton().click() + sendTxModal.sendTxTitle().should('be.visible') + sendTxModal.selectEasySetup().click() + sendTxModal.selectionEasySetupSetupManualExtrinsic().click() + sendTxModal.manualPalletSelection().click() + sendTxModal.optionPallet('omnipool').click() + + sendTxModal.manualMethodSelection().click() + sendTxModal.optionMethod('sell').click() + sendTxModal.paramField('amount').should('be.visible') + sendTxModal.paramField('amount').should('not.contain', 'HDX') + }) + + it('A manual balances.transferKeepAlive extrinsic has input in HDX', () => { + multisigPage.accountHeader().within(() => { + accountDisplay.addressLabel().should('contain.text', expectedMultisigAddress.slice(0, 6)) + }) + + multisigPage.newTransactionButton().click() + sendTxModal.sendTxTitle().should('be.visible') + sendTxModal.selectEasySetup().click() + sendTxModal.selectionEasySetupSetupManualExtrinsic().click() + sendTxModal.manualPalletSelection().click() + sendTxModal.optionPallet('balances').click() + + sendTxModal.manualMethodSelection().click() + sendTxModal.optionMethod('transferKeepAlive').click() + sendTxModal.paramField('value').should('be.visible') + sendTxModal.paramField('value').should('contain', 'HDX') + }) +}) diff --git a/packages/ui/src/components/EasySetup/ManualExtrinsic.tsx b/packages/ui/src/components/EasySetup/ManualExtrinsic.tsx index 26cf854d..45fb64f1 100644 --- a/packages/ui/src/components/EasySetup/ManualExtrinsic.tsx +++ b/packages/ui/src/components/EasySetup/ManualExtrinsic.tsx @@ -333,6 +333,7 @@ const ManualExtrinsic = ({ onPalletCallableParamChange(event, 'callable')} value={callable} @@ -370,6 +373,7 @@ const ManualExtrinsic = ({ > {callables.map(({ text }) => ( @@ -381,7 +385,10 @@ const ManualExtrinsic = ({
    {paramFields?.map((paramField, ind) => { return ( -
  • +
  • {chainInfo?.tokenSymbol || ''} ) }} + inputProps={{ 'data-cy': `param-input-${paramField.name}` }} />
  • ) diff --git a/packages/ui/src/components/Expander.tsx b/packages/ui/src/components/Expander.tsx index 3a4e9566..3d2aa2f1 100644 --- a/packages/ui/src/components/Expander.tsx +++ b/packages/ui/src/components/Expander.tsx @@ -16,13 +16,19 @@ const Expander = ({ className = '', title, content, expanded = false }: Props) = return (
    setOpen(!open)} className="titleWrapper" > {title}
    - {content} + + {content} +
    ) } diff --git a/packages/ui/src/constants.ts b/packages/ui/src/constants.ts index 92f02266..68560389 100644 --- a/packages/ui/src/constants.ts +++ b/packages/ui/src/constants.ts @@ -244,6 +244,7 @@ export const balanceCalls = [ 'bounties.proposeBounty', 'bounties.proposeCurator', 'childBounties.proposeCurator', + 'childBounties.addChildBounty', 'claims.mintClaim', 'convictionVoting.delegate', 'convictionVoting.vote', @@ -255,6 +256,8 @@ export const balanceCalls = [ 'democracy.vote', 'identity.requestJudgement', 'identity.setFee', + 'nominationPools.create', + 'nominationPools.createWithPoolId', 'nominationPools.bondExtra', 'nominationPools.join', 'nominationPools.unbond', From ef9b0b24f372b8531fc9e6b4f128d2b74e880b3e Mon Sep 17 00:00:00 2001 From: Thibaut Sardan Date: Mon, 11 Dec 2023 15:10:51 +0000 Subject: [PATCH 08/10] check display with HDX --- .../page-objects/components/expander.ts | 4 +++ .../support/page-objects/multisigPage.ts | 4 +-- .../support/page-objects/sendTxModal.ts | 6 +++- .../ui/cypress/tests/extrinsic-display.cy.ts | 34 ++++++++++++++----- .../src/components/EasySetup/FromCallData.tsx | 1 + packages/ui/src/components/modals/Send.tsx | 5 ++- 6 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 packages/ui/cypress/support/page-objects/components/expander.ts diff --git a/packages/ui/cypress/support/page-objects/components/expander.ts b/packages/ui/cypress/support/page-objects/components/expander.ts new file mode 100644 index 00000000..7cdac461 --- /dev/null +++ b/packages/ui/cypress/support/page-objects/components/expander.ts @@ -0,0 +1,4 @@ +export const expander = { + paramExpander: () => cy.get('[data-cy=label-expander]'), + contentExpander: () => cy.get('[data-cy=content-expander]') +} diff --git a/packages/ui/cypress/support/page-objects/multisigPage.ts b/packages/ui/cypress/support/page-objects/multisigPage.ts index 3ad40126..13e2d9ff 100644 --- a/packages/ui/cypress/support/page-objects/multisigPage.ts +++ b/packages/ui/cypress/support/page-objects/multisigPage.ts @@ -22,7 +22,5 @@ export const multisigPage = { pendingTransactionItem: () => cy.get('[data-cy=container-pending-tx-item]'), pendingTransactionCallName: () => cy.get('[data-cy=label-call-name]'), unknownCallIcon: () => cy.get('[data-cy=icon-unknown-call]'), - unknownCallAlert: () => cy.get('[data-cy=alert-no-call-data]'), - paramExpander: () => cy.get('[data-cy=label-expander]'), - contentExpander: () => cy.get('[data-cy=content-expander]') + unknownCallAlert: () => cy.get('[data-cy=alert-no-call-data]') } diff --git a/packages/ui/cypress/support/page-objects/sendTxModal.ts b/packages/ui/cypress/support/page-objects/sendTxModal.ts index c5932cb1..de7588c2 100644 --- a/packages/ui/cypress/support/page-objects/sendTxModal.ts +++ b/packages/ui/cypress/support/page-objects/sendTxModal.ts @@ -1,5 +1,6 @@ export const sendTxModal = { sendTxTitle: () => cy.get('[data-cy=title-send-tx]'), + sendTxContent: () => cy.get('[data-cy=modal-send-tx]'), sendTokensFieldTo: () => cy.get('[data-cy=send-tokens-field-to]'), sendTokensFieldAmount: () => cy.get('[data-cy=send-tokens-field-amount]'), buttonSend: () => cy.get('[data-cy=button-send]'), @@ -13,10 +14,13 @@ export const sendTxModal = { selectionEasySetupSetIdentity: () => cy.get('[data-cy=select-option-easy-setup-set-identity]'), selectionEasySetupSetupManualExtrinsic: () => cy.get('[data-cy=select-option-easy-setup-manual-extrinsic]'), + selectionEasySetupSetupFromCallData: () => + cy.get('[data-cy=select-option-easy-setup-from-call-data]'), manualPalletSelection: () => cy.get('[data-cy=select-manual-pallet]'), manualMethodSelection: () => cy.get('[data-cy=select-manual-method]'), optionPallet: (pallet: string) => cy.get(`[data-cy=option-pallet-${pallet}]`), optionMethod: (method: string) => cy.get(`[data-cy=option-method-${method}]`), paramField: (param: string) => cy.get(`[data-cy=param-field-${param}]`), - paramInput: (param: string) => cy.get(`[data-cy=param-input-${param}]`) + paramInput: (param: string) => cy.get(`[data-cy=param-input-${param}]`), + callDataInput: () => cy.get('[data-cy=input-from-call-data]') } diff --git a/packages/ui/cypress/tests/extrinsic-display.cy.ts b/packages/ui/cypress/tests/extrinsic-display.cy.ts index dae24397..a207a38d 100644 --- a/packages/ui/cypress/tests/extrinsic-display.cy.ts +++ b/packages/ui/cypress/tests/extrinsic-display.cy.ts @@ -4,6 +4,7 @@ import { } from '../fixtures/extrinsicsDisplayAccounts' import { landingPageNetwork } from '../fixtures/landingData' import { accountDisplay } from '../support/page-objects/components/accountDisplay' +import { expander } from '../support/page-objects/components/expander' import { multisigPage } from '../support/page-objects/multisigPage' import { sendTxModal } from '../support/page-objects/sendTxModal' @@ -30,18 +31,14 @@ describe('Verify extrinsics display', () => { multisigPage.pendingTransactionCallName().should('contain.text', 'omnipool.sell') multisigPage.unknownCallIcon().should('not.exist') multisigPage.unknownCallAlert().should('not.exist') - multisigPage.paramExpander().click() - multisigPage.contentExpander().should('contain', 'amount: 10,000,000,000,000') - multisigPage.contentExpander().should('contain', 'min_buy_amount: 59,509') + expander.paramExpander().click() + expander.contentExpander().should('contain', 'amount: 10,000,000,000,000') + expander.contentExpander().should('contain', 'min_buy_amount: 59,509') }) }) }) - it('A manual omnipool.sell extrinsic has input in plank', () => { - multisigPage.accountHeader().within(() => { - accountDisplay.addressLabel().should('contain.text', expectedMultisigAddress.slice(0, 6)) - }) - + it('A manual omnipool.sell extrinsic creation has input in plank', () => { multisigPage.newTransactionButton().click() sendTxModal.sendTxTitle().should('be.visible') sendTxModal.selectEasySetup().click() @@ -72,4 +69,25 @@ describe('Verify extrinsics display', () => { sendTxModal.paramField('value').should('be.visible') sendTxModal.paramField('value').should('contain', 'HDX') }) + + it('A from call data balances.transferKeepAlive extrinsic has balance displayed in HDX and identicon for destination', () => { + const balanceTransferCallData = + '0x0703d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0b00b04e2bde6f' + const sendingAmount = '123 HDX' + const expectedRecipient = '7NPoMQ..kZpiba' + + multisigPage.newTransactionButton().click() + sendTxModal.sendTxTitle().should('be.visible') + sendTxModal.selectEasySetup().click() + sendTxModal.selectionEasySetupSetupFromCallData().click() + sendTxModal.callDataInput().click().type(balanceTransferCallData) + sendTxModal.sendTxContent().within(() => { + expander.contentExpander().should('contain', sendingAmount) + expander.contentExpander().within(() => { + accountDisplay.addressLabel().should('contain', expectedRecipient) + accountDisplay.identicon().should('be.visible') + accountDisplay.nameLabel().should('contain', extrinsicsDisplayAccounts['Alice'].name) + }) + }) + }) }) diff --git a/packages/ui/src/components/EasySetup/FromCallData.tsx b/packages/ui/src/components/EasySetup/FromCallData.tsx index c2f08fa8..24f6a500 100644 --- a/packages/ui/src/components/EasySetup/FromCallData.tsx +++ b/packages/ui/src/components/EasySetup/FromCallData.tsx @@ -97,6 +97,7 @@ const FromCallData = ({ className, onSetExtrinsic, isProxySelected, onSetErrorMe )} Send tx - + Date: Mon, 11 Dec 2023 17:50:51 +0000 Subject: [PATCH 09/10] give 40s to multisig creation --- packages/ui/cypress/tests/multisig-creation.cy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui/cypress/tests/multisig-creation.cy.ts b/packages/ui/cypress/tests/multisig-creation.cy.ts index c85cdf79..c1c7c8d5 100644 --- a/packages/ui/cypress/tests/multisig-creation.cy.ts +++ b/packages/ui/cypress/tests/multisig-creation.cy.ts @@ -47,7 +47,7 @@ describe('Multisig creation', () => { notifications.loadingNotificationIcon().should('be.visible') notifications.notificationWrapper().should('contain', 'broadcast') - notifications.successNotificationIcon(30000).should('be.visible') + notifications.successNotificationIcon(40000).should('be.visible') notifications.notificationWrapper().should('contain', 'Tx in block') const expectedMultisigAddress = 'D9b1mkwhCwyRMUQZLyyKPdVkiJfFCuyVuWr3EmYAV6ETXkX' multisigPage.accountHeader(10000).within(() => { From 2358ebd01b506ab9d8556bf60dac23c78e9e89dc Mon Sep 17 00:00:00 2001 From: Thibaut Sardan Date: Mon, 11 Dec 2023 21:11:16 +0000 Subject: [PATCH 10/10] speedup block building tremendously --- chopsticks-config.yml | 4 ++-- packages/ui/cypress/tests/multisig-creation.cy.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/chopsticks-config.yml b/chopsticks-config.yml index 90435ad7..d9d88141 100644 --- a/chopsticks-config.yml +++ b/chopsticks-config.yml @@ -1,4 +1,4 @@ -endpoint: wss://kusama-rpc.dwellir.com +endpoint: wss://rpc.ibp.network/kusama mock-signature-host: true block: 20487320 db: ./db.sqlite @@ -61,4 +61,4 @@ import-storage: - [[5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY], rank: 7] Voting: [] ParasDisputes: - $removePrefix: ['disputes'] # those can makes block building super slow + # $removePrefix: ['disputes'] # those can makes block building super slow diff --git a/packages/ui/cypress/tests/multisig-creation.cy.ts b/packages/ui/cypress/tests/multisig-creation.cy.ts index c1c7c8d5..c85cdf79 100644 --- a/packages/ui/cypress/tests/multisig-creation.cy.ts +++ b/packages/ui/cypress/tests/multisig-creation.cy.ts @@ -47,7 +47,7 @@ describe('Multisig creation', () => { notifications.loadingNotificationIcon().should('be.visible') notifications.notificationWrapper().should('contain', 'broadcast') - notifications.successNotificationIcon(40000).should('be.visible') + notifications.successNotificationIcon(30000).should('be.visible') notifications.notificationWrapper().should('contain', 'Tx in block') const expectedMultisigAddress = 'D9b1mkwhCwyRMUQZLyyKPdVkiJfFCuyVuWr3EmYAV6ETXkX' multisigPage.accountHeader(10000).within(() => {