Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hotfix: Balance display should not show the token and should not format the amount #462

Merged
merged 16 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions chopsticks-config.yml
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
14 changes: 14 additions & 0 deletions packages/ui/cypress/fixtures/extrinsicsDisplayAccounts.ts
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const expander = {
paramExpander: () => cy.get('[data-cy=label-expander]'),
contentExpander: () => cy.get('[data-cy=content-expander]')
}
14 changes: 13 additions & 1 deletion packages/ui/cypress/support/page-objects/sendTxModal.ts
Original file line number Diff line number Diff line change
@@ -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]'),
Expand All @@ -10,5 +11,16 @@ 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]'),
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}]`),
callDataInput: () => cy.get('[data-cy=input-from-call-data]')
}
93 changes: 93 additions & 0 deletions packages/ui/cypress/tests/extrinsic-display.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import {
expectedMultisigAddress,
extrinsicsDisplayAccounts
} 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'

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')
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 creation has input in plank', () => {
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')
})

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)
})
})
})
})
4 changes: 2 additions & 2 deletions packages/ui/src/components/CallInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 })
}

Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/components/EasySetup/FromCallData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ const FromCallData = ({ className, onSetExtrinsic, isProxySelected, onSetErrorMe
</AlertStyled>
)}
<TextField
data-cy="input-from-call-data"
label={`Call data`}
onChange={onCallDataChange}
value={pastedCallData || ''}
Expand Down
19 changes: 15 additions & 4 deletions packages/ui/src/components/EasySetup/ManualExtrinsic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -333,6 +333,7 @@ const ManualExtrinsic = ({
</AlertStyled>
<FormControl>
<Select
data-cy="select-manual-pallet"
className="palletSelection"
displayEmpty
onChange={(event) => onPalletCallableParamChange(event, 'palletRpc')}
Expand All @@ -347,6 +348,7 @@ const ManualExtrinsic = ({
>
{palletRPCs.map(({ text }) => (
<MenuItem
data-cy={`option-pallet-${text}`}
key={text}
value={text}
>
Expand All @@ -357,6 +359,7 @@ const ManualExtrinsic = ({
</FormControl>
<FormControl>
<Select
data-cy="select-manual-method"
displayEmpty
onChange={(event) => onPalletCallableParamChange(event, 'callable')}
value={callable}
Expand All @@ -370,6 +373,7 @@ const ManualExtrinsic = ({
>
{callables.map(({ text }) => (
<MenuItem
data-cy={`option-method-${text}`}
key={text}
value={text}
>
Expand All @@ -381,18 +385,25 @@ const ManualExtrinsic = ({
<ul className="paramInputs">
{paramFields?.map((paramField, ind) => {
return (
<li key={`${paramField.name}-${paramField.type}`}>
<li
key={`${paramField.name}-${paramField.type}`}
data-cy={`param-field-${paramField.name}`}
>
<TextField
placeholder={paramField.type}
type="text"
label={`${paramField.name}${paramField.optional ? ' (optional)' : ''}`}
value={inputParams[ind] ? inputParams[ind].value : ''}
onChange={(event) => onParamChange(event, { ind, paramField })}
InputProps={{
endAdornment: isTypeBalance(paramField.typeName) && (
endAdornment: isTypeBalanceWithBalanceCall(
paramField.typeName,
`${palletRpc}.${callable}`
) && (
<InputAdornment position="end">{chainInfo?.tokenSymbol || ''}</InputAdornment>
)
}}
inputProps={{ 'data-cy': `param-input-${paramField.name}` }}
/>
</li>
)
Expand Down
8 changes: 7 additions & 1 deletion packages/ui/src/components/Expander.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,19 @@ const Expander = ({ className = '', title, content, expanded = false }: Props) =
return (
<Box className={className}>
<div
data-cy="label-expander"
onClick={() => setOpen(!open)}
className="titleWrapper"
>
<ChevronRightIcon className={`${open ? 'rotated' : ''} expanderIcon`} />
{title}
</div>
<Collapse in={open}>{content}</Collapse>
<Collapse
in={open}
data-cy="content-expander"
>
{content}
</Collapse>
</Box>
)
}
Expand Down
5 changes: 4 additions & 1 deletion packages/ui/src/components/modals/Send.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,10 @@ const Send = ({ onClose, className, onSuccess, onFinalized, preselected }: Props
>
<ModalCloseButton onClose={onClose} />
<DialogTitle data-cy="title-send-tx">Send tx</DialogTitle>
<DialogContent className="generalContainer">
<DialogContent
data-cy="modal-send-tx"
className="generalContainer"
>
<Grid
alignItems="center"
container
Expand Down
44 changes: 44 additions & 0 deletions packages/ui/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,47 @@ 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',
'childBounties.addChildBounty',
'claims.mintClaim',
'convictionVoting.delegate',
'convictionVoting.vote',
'crowdloan.contribute',
'crowdloan.create',
'crowdloan.edit',
'democracy.delegate',
'democracy.propose',
'democracy.vote',
'identity.requestJudgement',
'identity.setFee',
'nominationPools.create',
'nominationPools.createWithPoolId',
'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'
]
9 changes: 7 additions & 2 deletions packages/ui/src/utils/isTypeBalance.ts
Original file line number Diff line number Diff line change
@@ -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)
Loading