Skip to content

Commit

Permalink
add tests and harnest ED calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
Tbaut committed Feb 27, 2025
1 parent 49f1827 commit 5d19716
Show file tree
Hide file tree
Showing 16 changed files with 212 additions and 187 deletions.
19 changes: 0 additions & 19 deletions packages/ui/cypress/fixtures/setIdentity/setIdentityMultisigs.ts

This file was deleted.

41 changes: 0 additions & 41 deletions packages/ui/cypress/fixtures/setIdentity/setIdentitySignatories.ts

This file was deleted.

41 changes: 33 additions & 8 deletions packages/ui/cypress/fixtures/westendAccounts.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
import { InjectedAccountWitMnemonic } from './testAccounts'

const signatory = {
address: '5CPG8FMciJBBE47YwSQHte23tTz91egixJw514g6BCt5nHPz',
publicKey: '0x0e270b0984354e0f6033dee93293dbeaea366220ca59e584ba7614d8bf393040',
name: 'hidden',
type: 'sr25519',
mnemonic: ''
} as InjectedAccountWitMnemonic

const leemo = {
address: '1HGnvAkk9nbfZ58CzUJhjcrLdEDMkr5qNkqqYkyD5BF5v6Y',
publicKey: '0x0c691601793de060491dab143dfae19f5f6413d4ce4c363637e5ceacb2836a4e',
name: 'hidden',
type: 'sr25519',
mnemonic: ''
} as InjectedAccountWitMnemonic

export const westendMemberAccount = {
// this is the member of a multisig and a multisig with Pure
// used in hidden-accounts
// used in identity (it has one on Westend)
hidden: {
account: {
address: '5CPG8FMciJBBE47YwSQHte23tTz91egixJw514g6BCt5nHPz',
publicKey: '0x0e270b0984354e0f6033dee93293dbeaea366220ca59e584ba7614d8bf393040',
name: 'hidden',
type: 'sr25519',
mnemonic: ''
} as InjectedAccountWitMnemonic,
account: signatory,
expectedSingleMultisig: {
westendAddress: '5CvCLBVHufgqTDUVJL3xY6Pd7TVaYtaTGzvYRfGeaAPJLdDS',
paseoAddress: '1rVUWkMmSxJtkV1Fy6xgFDmy5VEFC8bMVf2axG18FQpX7hE',
Expand All @@ -21,5 +30,21 @@ export const westendMemberAccount = {
address: '5DqS9vsnXotmczKu87xb5KMUARCVF5JUUVveZz9R8UvXKExK',
pubKey: '0x4e596aec4922957174ba3f86860cca88fa4664006b511f11260cc34ca303d0dd'
}
},
// this one has no identity
noIdentity: {
account: signatory,
expectedSingleMultisig: {
westendAddress: '5GAvk9wqjHmXxCJB5UtwghLK4UqDzSD4sduSHwfoqhhYwoRS',
pubKey: '0xb5afca4314341bd1048c572e2e358fa00cb02387689a91f20688b9f49f3e64c6'
}
},
polkadotMultisigNoIdentity: {
account: leemo,
// CD event bounty
expectedPure: {
address: '13DxmMjYqto1AWsMUSkN8JYNHX6d2vBhuSmapB5iYnEiYaxX',
pubkey: '0x625b21fc3cfe39c52cf4d753fe8ad5f3b2ace458d9d11d266f080216e5e885e6'
}
}
}
147 changes: 74 additions & 73 deletions packages/ui/cypress/tests/identity.cy.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { SignerPayloadJSON } from 'polkadot-api/pjs-signer'
import { extrinsicsDisplayAccounts } from '../fixtures/extrinsicsDisplayAccounts'
import { landingPageNetwork, landingPageNetworkAddress } from '../fixtures/landingData'
import { setIdentityMultisigs } from '../fixtures/setIdentity/setIdentityMultisigs'
import { identitySignatories } from '../fixtures/setIdentity/setIdentitySignatories'
import { westendMemberAccount } from '../fixtures/westendAccounts'
import { multisigPage } from '../support/page-objects/multisigPage'
import { sendTxModal } from '../support/page-objects/sendTxModal'
import { topMenuItems } from '../support/page-objects/topMenuItems'
import { waitForTxRequest } from '../utils/waitForTxRequests'
// import { waitForTxRequest } from '../utils/waitForTxRequests'

describe('Set an identity', () => {
Expand All @@ -31,16 +30,13 @@ describe('Set an identity', () => {
cy.setupAndVisit({
url: landingPageNetworkAddress({
network: 'polkadot',
address: setIdentityMultisigs['pure-with-polkadot-identity'].address
address: westendMemberAccount.polkadotMultisigNoIdentity.expectedPure.address
}),
extensionConnectionAllowed: true,
injectExtensionWithAccounts: setIdentityMultisigs['pure-with-polkadot-identity'].signatories
injectExtensionWithAccounts: [westendMemberAccount.polkadotMultisigNoIdentity.account]
})
// select the right multisig (Alice has a lot)
const first5DigitsAddress = setIdentityMultisigs['pure-with-polkadot-identity'].address.slice(
0,
4
)
const first5DigitsAddress =
westendMemberAccount.polkadotMultisigNoIdentity.expectedPure.address.slice(0, 4)
multisigPage.accountHeader().should('contain', first5DigitsAddress)

multisigPage.optionsMenuButton().click()
Expand All @@ -53,69 +49,74 @@ describe('Set an identity', () => {
sendTxModal.selectionEasySetupSetIdentity().should('not.exist')
})

// it.skip('Can set an identity from the options menu', () => {
// const multisigSignatoryWithoutIdentity = setIdentitySignatories[1]
// cy.setupAndVisit({
// url: landingPageUrl,
// extensionConnectionAllowed: true,
// injectExtensionWithAccounts: [multisigSignatoryWithoutIdentity]
// })
// multisigPage.optionsMenuButton().click()
// multisigPage.setIdentityMenuOption().should('be.visible').click()
// sendTxModal.sendTxTitle().should('be.visible')
// sendTxModal.setIdentitySection().should('be.visible')

// // every field is empty to start with
// sendTxModal.setIdentityFieldInput('display').should('have.value', '')
// sendTxModal.setIdentityFieldInput('legal').should('have.value', '')

// // typing into legal with empty display should show an error
// sendTxModal.setIdentityField('legal').type('le')
// sendTxModal.sendTxError().should('contain', 'Display name is required')
// sendTxModal.setIdentityFieldElement('display', 'label').should('have.class', 'Mui-error')
// sendTxModal.setIdentityFieldElement('display', 'div').should('have.class', 'Mui-error')
// sendTxModal.buttonSend().should('be.disabled')

// // typing into display should remove the error
// sendTxModal.setIdentityField('display').type('diis')
// sendTxModal.sendTxError().should('not.exist')
// sendTxModal.setIdentityFieldElement('display', 'label').should('not.have.class', 'Mui-error')
// sendTxModal.buttonSend().should('be.enabled')

// // typing a too long field should show another error
// sendTxModal.setIdentityField('legal').type('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
// sendTxModal.sendTxError().should('contain', 'A field exceeds the 32 character limit')
// sendTxModal.setIdentityFieldElement('legal', 'label').should('have.class', 'Mui-error')
// sendTxModal.buttonSend().should('be.disabled')

// // too many bytes should show the From error
// sendTxModal.setIdentityField('legal').type('{selectall}{del}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
// sendTxModal.setIdentityFieldElement('legal', 'label').should('not.have.class', 'Mui-error')
// sendTxModal.sendTxError().should('contain', `The "From" account doesn't have`)
// sendTxModal.buttonSend().should('be.disabled')

// // removing should remove the error
// sendTxModal.setIdentityField('legal').type('{selectall}{del}leeg')
// sendTxModal.sendTxError().should('not.exist')
// sendTxModal.setIdentityFieldElement('legal', 'label').should('not.have.class', 'Mui-error')
// sendTxModal.buttonSend().should('be.enabled')

// // verify the tx it sends
// sendTxModal.buttonSend().click()
// waitForTxRequest()
// cy.getTxRequests().then((req) => {
// const txRequests = Object.values(req)
// cy.wrap(txRequests.length).should('eq', 1)
// cy.wrap(txRequests[0].payload.address).should('eq', multisigSignatoryWithoutIdentity.address)
// sendTxModal.buttonSend().should('not.exist')
// sendTxModal.buttonSending().should('be.visible')
// // expected https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frococo-rpc.polkadot.io#/extrinsics/decode/0x1f0102000412ad770206045069201514711dc2456908b0af226442d475d12a5334e9c4513e001901000564696973056c6565670000000000000000
// cy.wrap(txRequests[0].payload.method).should(
// 'eq',
// '0x1f0102000412ad770206045069201514711dc2456908b0af226442d475d12a5334e9c4513e001901000564696973056c6565670000000000000000'
// )
// })
// })
it('Can set an identity from the options menu', () => {
cy.setupAndVisit({
url: landingPageNetworkAddress({
network: 'westend',
address: westendMemberAccount.noIdentity.expectedSingleMultisig.westendAddress
}),
extensionConnectionAllowed: true,
injectExtensionWithAccounts: [westendMemberAccount.noIdentity.account]
})
multisigPage.optionsMenuButton().click()
multisigPage.setIdentityMenuOption().should('be.visible').click()
sendTxModal.sendTxTitle().should('be.visible')
sendTxModal.setIdentitySection().should('be.visible')

// every field is empty to start with
sendTxModal.setIdentityFieldInput('display').should('have.value', '')
sendTxModal.setIdentityFieldInput('legal').should('have.value', '')

// typing into legal with empty display should show an error
sendTxModal.setIdentityField('legal').type('le')
sendTxModal.sendTxError().should('contain', 'Display name is required')
sendTxModal.setIdentityFieldElement('display', 'label').should('have.class', 'Mui-error')
sendTxModal.setIdentityFieldElement('display', 'div').should('have.class', 'Mui-error')
sendTxModal.buttonSend().should('be.disabled')

// typing into display should remove the error
sendTxModal.setIdentityField('display').type('diis')
sendTxModal.sendTxError().should('not.exist')
sendTxModal.setIdentityFieldElement('display', 'label').should('not.have.class', 'Mui-error')
sendTxModal.buttonSend().should('be.enabled')

// typing a too long field should show another error
sendTxModal.setIdentityField('legal').type('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
sendTxModal.sendTxError().should('contain', 'A field exceeds the 32 character limit')
sendTxModal.setIdentityFieldElement('legal', 'label').should('have.class', 'Mui-error')
sendTxModal.buttonSend().should('be.disabled')

// too many bytes should show the From error
sendTxModal.setIdentityField('legal').type('{selectall}{del}iiiiiiiiiiiiiiiiiii')
sendTxModal.setIdentityFieldElement('legal', 'label').should('not.have.class', 'Mui-error')
sendTxModal.sendTxError().should('contain', `The "From" account doesn't have`)
sendTxModal.sendTxError().should('contain', `People Chain`)
sendTxModal.buttonSend().should('be.disabled')

// removing should remove the error
sendTxModal.setIdentityField('legal').type('{selectall}{del}leeg')
sendTxModal.sendTxError().should('not.exist')
sendTxModal.setIdentityFieldElement('legal', 'label').should('not.have.class', 'Mui-error')
sendTxModal.buttonSend().should('be.enabled')

// verify the tx it sends
sendTxModal.buttonSend().click()
waitForTxRequest()
cy.getTxRequests().then((req) => {
const txRequests = Object.values(req)
cy.wrap(txRequests.length).should('eq', 1)
cy.wrap(txRequests[0].payload.address).should(
'eq',
westendMemberAccount.noIdentity.account.address
)
sendTxModal.buttonSend().should('not.exist')
sendTxModal.buttonSending().should('be.visible')
cy.wrap((txRequests[0].payload as SignerPayloadJSON).method).should(
'eq',
'0x2901020008ecdd548c83457ab43caf7867e2bef91ef783025db9659afd89794ec1220acf29f4a90345684cadbe61ae32508309122d710c30772408b5d8e02973d188b361200032010564696973056c65656700000000000000000000'
)
})
})

it('Can edit an identity from the new tx button', () => {
cy.setupAndVisit({
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/components/EasySetup/BalancesTransfer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export const BalancesTransfer = ({ className, onSetExtrinsic, onSetErrorMessage,
})
return res
}, [fieldInfoMap])
// the assets can be sufficient here so no need to check for the ED
const { hasEnoughFreeBalance: hasEnoughNativeToken } = useCheckBalance({
min: totalPerAsset[0],
address: from,
Expand Down
24 changes: 16 additions & 8 deletions packages/ui/src/components/EasySetup/SetIdentity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { formatBigIntBalance } from '../../utils/formatBnBalance'
import { isPplContextIn } from '../../contexts/PeopleChainApiContext'
import { pplDescriptorKeys } from '../../types'
import { IdentityData } from '@polkadot-api/descriptors'
import { useGetED } from '../../hooks/useGetED'

interface Props {
className?: string
Expand Down Expand Up @@ -133,8 +134,16 @@ const SetIdentity = ({ className, onSetExtrinsic, from, onSetErrorMessage }: Pro
}, [identityFields])

const { reserved: identityReservedFunds } = useSetIdentityReservedFunds(identityFields)
const { existentialDeposit } = useGetED({
withPplApi: true
})
const minBalance = useMemo(() => {
if (!existentialDeposit || !identityReservedFunds) return

return identityReservedFunds + existentialDeposit
}, [existentialDeposit, identityReservedFunds])
const { hasEnoughFreeBalance: hasOriginEnoughFunds } = useCheckBalance({
min: identityReservedFunds,
min: minBalance,
address: from,
withPplApi: true
})
Expand All @@ -154,12 +163,10 @@ const SetIdentity = ({ className, onSetExtrinsic, from, onSetErrorMessage }: Pro
return
}

if (identityReservedFunds !== 0n && !hasOriginEnoughFunds) {
const requiredBalanceString = formatBigIntBalance(
identityReservedFunds,
chainInfo?.tokenDecimals,
{ tokenSymbol: chainInfo?.tokenSymbol }
)
if (!!minBalance && !hasOriginEnoughFunds) {
const requiredBalanceString = formatBigIntBalance(minBalance, chainInfo?.tokenDecimals, {
tokenSymbol: chainInfo?.tokenSymbol
})

const reservedString = formatBigIntBalance(identityReservedFunds, chainInfo?.tokenDecimals, {
tokenSymbol: chainInfo?.tokenSymbol
Expand All @@ -183,7 +190,8 @@ const SetIdentity = ({ className, onSetExtrinsic, from, onSetErrorMessage }: Pro
hasOriginEnoughFunds,
identityFields,
onSetErrorMessage,
identityReservedFunds
identityReservedFunds,
minBalance
])

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const TransactionList = ({ className }: Props) => {
txWithCallDataByDate,
isLoading: isLoadingPendingTxs,
refresh
} = usePendingTx({ multisigAddresses })
} = usePendingTx({ multisigAddresses, withPplChain: false })
const {
txWithCallDataByDate: pplTx,
isLoading: isLoadingPplPendingTxs,
Expand Down
Loading

0 comments on commit 5d19716

Please sign in to comment.