diff --git a/packages/ui/cypress/tests/hydration-extrinsic-display.cy.ts b/packages/ui/cypress/tests/hydration-extrinsic-display.cy.ts
index 8e7f1f6b..77298bbd 100644
--- a/packages/ui/cypress/tests/hydration-extrinsic-display.cy.ts
+++ b/packages/ui/cypress/tests/hydration-extrinsic-display.cy.ts
@@ -17,7 +17,7 @@ describe('Verify extrinsics display', () => {
})
})
- it('The omnipool.sell extrinsic is displayed in plank', () => {
+ it('The Router.sell extrinsic is displayed in plank', () => {
multisigPage.accountHeader().within(() => {
accountDisplay.addressLabel().should('contain.text', expectedMultisigAddress.slice(0, 6))
})
@@ -28,17 +28,17 @@ describe('Verify extrinsics display', () => {
.within(() => {
multisigPage.pendingTransactionItem().should('have.length', 1)
multisigPage.pendingTransactionItem().within(() => {
- multisigPage.pendingTransactionCallName().should('contain.text', 'omnipool.sell')
+ multisigPage.pendingTransactionCallName().should('contain.text', 'Router.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')
+ expander.contentExpander().should('contain', '"amount_in": "10000000000000"')
+ expander.contentExpander().should('contain', '"min_amount_out": "72179"')
})
})
})
- it('A manual omnipool.sell extrinsic creation has input in plank', () => {
+ it.skip('A manual omnipool.sell extrinsic creation has input in plank', () => {
multisigPage.accountHeader().within(() => {
accountDisplay.addressLabel().should('contain.text', expectedMultisigAddress.slice(0, 6))
})
@@ -56,7 +56,7 @@ describe('Verify extrinsics display', () => {
sendTxModal.paramField('amount').should('not.contain', 'HDX')
})
- it('A manual balances.transferKeepAlive extrinsic has input in HDX', () => {
+ it.skip('A manual balances.transferKeepAlive extrinsic has input in HDX', () => {
multisigPage.accountHeader().within(() => {
accountDisplay.addressLabel().should('contain.text', expectedMultisigAddress.slice(0, 6))
})
@@ -74,7 +74,7 @@ describe('Verify extrinsics display', () => {
sendTxModal.paramField('value').should('contain', 'HDX')
})
- it('A from call data balances.transferKeepAlive extrinsic has balance displayed in HDX and identicon for destination', () => {
+ it.skip('A from call data balances.transferKeepAlive extrinsic has balance displayed in HDX and identicon for destination', () => {
const balanceTransferCallData =
'0x0703d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0b00b04e2bde6f'
const sendingAmount = '123 HDX'
@@ -98,4 +98,25 @@ describe('Verify extrinsics display', () => {
})
})
})
+
+ it('A from call data balances.transferKeepAlive extrinsic is correctly displayed', () => {
+ const balanceTransferCallData =
+ '0x0703d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0b00b04e2bde6f'
+ const sendingAmount = '"value": "123000000000000"'
+ const expectedRecipient = '"dest": "7NPoMQbiA6trJKkjB35uk96MeJD4PGWkLQLH7k7hXEkZpiba"'
+
+ multisigPage.accountHeader().within(() => {
+ accountDisplay.addressLabel().should('contain.text', expectedMultisigAddress.slice(0, 6))
+ })
+
+ 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().should('contain', expectedRecipient)
+ })
+ })
})
diff --git a/packages/ui/package.json b/packages/ui/package.json
index 7af1bf40..47a87c2d 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -10,6 +10,7 @@
"@mui/material": "^5.15.15",
"@mui/styled-engine": "^5.15.14",
"@polkadot-api/descriptors": "portal:.papi/descriptors",
+ "@polkadot-api/tx-utils": "^0.0.4",
"@polkadot-labs/hdkd": "^0.0.8",
"@polkadot-labs/hdkd-helpers": "^0.0.8",
"@polkadot/api": "^13.1.1",
diff --git a/packages/ui/src/components/AccountDisplay/AccountDisplay.tsx b/packages/ui/src/components/AccountDisplay/AccountDisplay.tsx
index 468bdf4b..67281ac6 100644
--- a/packages/ui/src/components/AccountDisplay/AccountDisplay.tsx
+++ b/packages/ui/src/components/AccountDisplay/AccountDisplay.tsx
@@ -100,15 +100,15 @@ const AccountDisplay = ({
className="multisigName"
data-cy="label-account-name"
>
+ {displayName}
{!isLocalNameDisplayed && !!subIdentity && (
- {subIdentity}/
+ /{subIdentity}
)}
- {displayName}
{canEdit && !displayName && (
No Name
diff --git a/packages/ui/src/components/EasySetup/FromCallData.tsx b/packages/ui/src/components/EasySetup/FromCallData.tsx
index aee24825..fc35c438 100644
--- a/packages/ui/src/components/EasySetup/FromCallData.tsx
+++ b/packages/ui/src/components/EasySetup/FromCallData.tsx
@@ -26,19 +26,23 @@ const FromCallData = ({ className, onSetExtrinsic }: Props) => {
setIsProxyProxyRemoved(false)
if (!api) return call
- const decodedCall = (await api.txFromCallData(Binary.fromHex(call))).decodedCall
-
- // check if this call is a proxy.proxy
- if (decodedCall.type === 'Proxy' && decodedCall.value.type === 'proxy') {
- // a proxy.proxy call is encoded with e.g
- // callIndex 1e00
- // real 00 eb53ed54b7f921a438923e6eb52c4d89afc5c0fed5d0d15fb78648c53da227a0
- // forceProxyType 00
- setIsProxyProxyRemoved(true)
- return `0x${call.substring(74)}` as HexString
+ try {
+ const decodedCall = (await api.txFromCallData(Binary.fromHex(call))).decodedCall
+
+ // check if this call is a proxy.proxy
+ if (decodedCall.type === 'Proxy' && decodedCall.value.type === 'proxy') {
+ // a proxy.proxy call is encoded with e.g
+ // callIndex 1e00
+ // real 00 eb53ed54b7f921a438923e6eb52c4d89afc5c0fed5d0d15fb78648c53da227a0
+ // forceProxyType 00
+ setIsProxyProxyRemoved(true)
+ return `0x${call.substring(74)}` as HexString
+ }
+
+ return call
+ } catch (error) {
+ return
}
-
- return call
},
[api]
)
diff --git a/packages/ui/src/hooks/useCallInfoFromCallData.tsx b/packages/ui/src/hooks/useCallInfoFromCallData.tsx
index cfb93ae4..e357e342 100644
--- a/packages/ui/src/hooks/useCallInfoFromCallData.tsx
+++ b/packages/ui/src/hooks/useCallInfoFromCallData.tsx
@@ -25,25 +25,31 @@ export const useCallInfoFromCallData = (callData?: HexString) => {
setIsGettingCallInfo(true)
- const tx = api.txFromCallData(Binary.fromHex(callData), compatibilityToken)
+ try {
+ const tx = api.txFromCallData(Binary.fromHex(callData), compatibilityToken)
- tx.getPaymentInfo(PAYMENT_INFO_ACCOUNT, { at: 'best' })
- .then(({ weight }) => {
- setCallInfo({
- decodedCall: tx?.decodedCall,
- call: tx,
- hash: hashFromTx(callData),
- weight: { proof_size: weight.proof_size, ref_time: weight.ref_time },
- method: tx?.decodedCall.type,
- section: tx?.decodedCall.value.type
+ tx.getPaymentInfo(PAYMENT_INFO_ACCOUNT, { at: 'best' })
+ .then(({ weight }) => {
+ setCallInfo({
+ decodedCall: tx?.decodedCall,
+ call: tx,
+ hash: hashFromTx(callData),
+ weight: { proof_size: weight.proof_size, ref_time: weight.ref_time },
+ method: tx?.decodedCall.type,
+ section: tx?.decodedCall.value.type
+ })
+ setIsGettingCallInfo(false)
})
- setIsGettingCallInfo(false)
- })
- .catch((e) => {
- console.error(e)
- setIsGettingCallInfo(false)
- setCallInfo(undefined)
- })
+ .catch((e) => {
+ console.error(e)
+ setIsGettingCallInfo(false)
+ setCallInfo(undefined)
+ })
+ } catch (e) {
+ console.error(e)
+ setIsGettingCallInfo(false)
+ setCallInfo(undefined)
+ }
}, [api, callData, compatibilityToken])
return { callInfo, isGettingCallInfo }
diff --git a/packages/ui/src/hooks/useGetIdentity.tsx b/packages/ui/src/hooks/useGetIdentity.tsx
index c381cdb5..0a336a4e 100644
--- a/packages/ui/src/hooks/useGetIdentity.tsx
+++ b/packages/ui/src/hooks/useGetIdentity.tsx
@@ -17,7 +17,7 @@ export const useGetIdentity = () => {
return
}
- const { display, parentAddress } = await (
+ const { sub, parentAddress } = await (
api as TypedApi
).query.Identity.SuperOf.getValue(address, { at: 'best' }).then((res) => {
const [parentAddress, parentIdentity] = res || []
@@ -26,13 +26,12 @@ export const useGetIdentity = () => {
return { parentAddress: '', display: '' }
}
- const display =
- (parentIdentity.type !== 'None' &&
- parentIdentity.value &&
- (parentIdentity.value as FixedSizeBinary<3>).asText()) ||
- ''
+ const sub =
+ parentIdentity.type !== 'None' && parentIdentity.value
+ ? (parentIdentity.value as FixedSizeBinary<3>).asText()
+ : ''
- return { display, parentAddress }
+ return { sub, parentAddress }
})
const addressToUse = parentAddress || address
@@ -43,7 +42,7 @@ export const useGetIdentity = () => {
at: 'best'
}
).then((val) => {
- const id: IdentityInfo = { judgements: [], display }
+ const id: IdentityInfo = { judgements: [], sub }
val?.[0].judgements.forEach(([, judgement]) => {
id.judgements.push(judgement.type)
})
@@ -53,13 +52,7 @@ export const useGetIdentity = () => {
// console.log('value', JSONprint(value));
const text = (value as IdentityData)?.value as FixedSizeBinary<2> | undefined
if (text) {
- // if it has a parent this is the sub name
- // as the display name is already set
- if (key === 'display' && !!parentAddress) {
- id['sub'] = text.asText()
- } else {
- id[key] = text.asText()
- }
+ id[key] = text.asText()
}
}
})
diff --git a/packages/ui/src/hooks/usePendingTx.tsx b/packages/ui/src/hooks/usePendingTx.tsx
index 9d13347a..4b6b45e3 100644
--- a/packages/ui/src/hooks/usePendingTx.tsx
+++ b/packages/ui/src/hooks/usePendingTx.tsx
@@ -9,27 +9,11 @@ import { ApiType, useApi } from '../contexts/ApiContext'
import dayjs from 'dayjs'
import localizedFormat from 'dayjs/plugin/localizedFormat'
import { PolkadotClient, Transaction } from 'polkadot-api'
-import { getDynamicBuilder, getLookupFn } from '@polkadot-api/metadata-builders'
-import {
- AccountId,
- Bin,
- Binary,
- compact,
- createDecoder,
- enhanceDecoder,
- HexString,
- metadata as metadataCodec,
- Struct,
- Tuple,
- u8,
- Variant,
- type Decoder,
- type StringRecord,
- type V14
-} from '@polkadot-api/substrate-bindings'
-import { Hex } from '@polkadot-api/substrate-bindings'
+import { Bin, Binary, compact, HexString, Tuple } from '@polkadot-api/substrate-bindings'
import { hashFromTx } from '../utils/txHash'
import { getEncodedCallFromDecodedTx } from '../utils/getEncodedCallFromDecodedTx'
+import { getExtrinsicDecoder } from '@polkadot-api/tx-utils'
+
dayjs.extend(localizedFormat)
export interface PendingTx {
@@ -62,120 +46,11 @@ const getExtDecoderAt = async (api: ApiType, client: PolkadotClient, blockHash?:
.then((x) => opaqueMetadata(x.result)[1])
: api.apis.Metadata.metadata())
- const metadata = metadataCodec.dec(rawMetadata.asBytes()).metadata.value as V14
- const dynBuilder = getDynamicBuilder(getLookupFn(metadata))
-
- const versionDec = enhanceDecoder(u8[1], (value) => ({
- version: value & ~(1 << 7),
- signed: !!(value & (1 << 7))
- }))
-
- const address = Variant({
- Id: AccountId(),
- Raw: Hex(),
- Address32: Hex(32),
- Address20: Hex(20)
- }).dec
- const signature = Variant({
- Ed25519: Hex(64),
- Sr25519: Hex(64),
- Ecdsa: Hex(65)
- }).dec
-
- const extra = Struct.dec(
- Object.fromEntries(
- metadata.extrinsic.signedExtensions.map(
- (x) => [x.identifier, dynBuilder.buildDefinition(x.type)[1]] as [string, Decoder]
- )
- ) as StringRecord>
- )
-
- const allBytesDec = Hex(Infinity).dec
- const signedBody = Struct.dec({
- address,
- signature,
- extra,
- callData: allBytesDec
- })
-
- return createDecoder((data) => {
- const len = compact.dec(data)
- const { signed, version } = versionDec(data)
- const body = signed ? signedBody : allBytesDec
+ const decoder = await getExtrinsicDecoder(rawMetadata.asOpaqueBytes())
- return { len, signed, version, body: body(data) }
- })
+ return decoder
}
-// export const getMultisigInfo = (call: ISanitizedCall): Partial[] => {
-// const result: Partial[] = []
-
-// const getCallResult = ({ args, method }: ISanitizedCall) => {
-// if (typeof method !== 'string' && method.pallet === 'multisig') {
-// if (method.method === 'asMulti' && typeof args.call?.method !== 'string') {
-// result.push({
-// name: `${args.call?.method?.pallet}.${args.call?.method.method}`,
-// hash: args.call?.hash,
-// callData: args.callData as CallDataInfoFromChain['callData']
-// })
-// } else {
-// result.push({
-// name: 'Unknown call',
-// hash: (args?.call_hash as Uint8Array).toString() || undefined,
-// callData: undefined
-// })
-// }
-// // this is not a multisig call
-// // try to dig deeper
-// } else {
-// if (args.calls) {
-// for (const call of args.calls) {
-// getCallResult(call)
-// }
-// } else if (args.call) {
-// getCallResult(args.call)
-// }
-// }
-// }
-
-// getCallResult(call)
-// return result
-// }
-
-// export const getMultisigInfo = (
-// call: Transaction['decodedCall']
-// ): Partial[] => {
-// const result: Partial[] = []
-
-// // result.push({
-// // name: 'Unknown call',
-// // hash: (args?.call_hash as Uint8Array).toString() || undefined,
-// // callData: undefined
-// // })
-
-// const getCallResults = (call: Transaction['decodedCall']) => {
-// if (call.type === 'Multisig') {
-// if (call.value.type === 'as_Multi') {
-
-// result.push({
-// name: `${call.value.value.call.type}.${call.value.value.call.value.type}`,
-// hash: args.call?.hash,
-// callData: args.callData as CallDataInfoFromChain['callData']
-// })
-// } else {
-// result.push({
-// name: 'Unknown call',
-// hash: undefined,
-// callData: undefined
-// })
-// }
-// } else {
-// }
-// }
-// getCallResults(call)
-// return result
-// }
-
const getMultisigInfo = async (
call: Transaction['decodedCall'],
api: ApiType
@@ -252,12 +127,10 @@ const getCallDataFromChainPromise = (
const txPromises = body.map((extrinsics) => {
const decodedExtrinsic = decoder(extrinsics)
- const toDecode = decodedExtrinsic.signed
- ? (decodedExtrinsic.body as any).callData
- : decodedExtrinsic.body
+ const toDecode = decodedExtrinsic.callData
// console.log('-----------------------------')
// console.log(decodedExtrinsic)
- return api.txFromCallData(Binary.fromHex(toDecode))
+ return api.txFromCallData(toDecode)
})
const allDecodedTxs = await Promise.all(txPromises)
@@ -305,13 +178,6 @@ const getCallDataFromChainPromise = (
const { name, hash, callData } = multisigTxInfo
- // let call: false | GenericCall = false
- // try {
- // call = !!callData && !!hash && ext.registry.createType('Call', callData)
- // } catch (error) {
- // console.error('Error in getCallDataFromChainPromise', error)
- // }
-
return {
callData,
hash: hash || pendingTx.hash,
diff --git a/yarn.lock b/yarn.lock
index 9bd2c80e..53961c72 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3444,6 +3444,17 @@ __metadata:
languageName: node
linkType: hard
+"@polkadot-api/tx-utils@npm:^0.0.4":
+ version: 0.0.4
+ resolution: "@polkadot-api/tx-utils@npm:0.0.4"
+ dependencies:
+ "@polkadot-api/metadata-builders": 0.9.1
+ "@polkadot-api/substrate-bindings": 0.9.3
+ "@polkadot-api/utils": 0.1.2
+ checksum: 002439dde254a4ac28db69019086314b521baee942ed4e2289907328e1385153a947277f49c4adb8954e0fc0fb8bc668a0549a8fab0fbb13c7cbe5e0e929f9de
+ languageName: node
+ linkType: hard
+
"@polkadot-api/utils@npm:0.1.0":
version: 0.1.0
resolution: "@polkadot-api/utils@npm:0.1.0"
@@ -10951,6 +10962,7 @@ __metadata:
"@mui/material": ^5.15.15
"@mui/styled-engine": ^5.15.14
"@polkadot-api/descriptors": "portal:.papi/descriptors"
+ "@polkadot-api/tx-utils": ^0.0.4
"@polkadot-labs/hdkd": ^0.0.8
"@polkadot-labs/hdkd-helpers": ^0.0.8
"@polkadot/api": ^13.1.1