Contract event decoding (#3914)

* Contract event decoding

* Update packages/apps/src/Content/Status.tsx

* Update packages/react-components/src/Status/Queue.tsx

* Bump API
This commit is contained in:
Jaco Greeff 2020-10-22 16:34:11 +02:00 committed by GitHub
parent 302c26d830
commit 3dd77c8393
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 146 additions and 83 deletions

View File

@ -33,11 +33,11 @@
"afterSign": "electron-builder-notarize"
},
"resolutions": {
"@polkadot/api": "^2.3.2-2",
"@polkadot/api-contract": "^2.3.2-2",
"@polkadot/api": "^2.3.2-7",
"@polkadot/api-contract": "^2.3.2-7",
"@polkadot/keyring": "^3.6.1",
"@polkadot/networks": "^3.6.1",
"@polkadot/types": "^2.3.2-2",
"@polkadot/types": "^2.3.2-7",
"@polkadot/util": "^3.6.1",
"@polkadot/util-crypto": "^3.6.1",
"@polkadot/wasm-crypto": "^1.4.1",

View File

@ -12,6 +12,6 @@
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime": "^7.12.1",
"@polkadot/api-contract": "^2.3.2-2"
"@polkadot/api-contract": "^2.3.2-7"
}
}

View File

@ -49,8 +49,6 @@ function Call ({ className = '', contract, messageIndex, onCallResult, onChangeM
useEffect((): void => {
value && message.isMutating && setExecTx((): SubmittableExtrinsic<'promise'> | null => {
console.error(weight.weight.toString());
try {
return contract.exec(message, message.isPayable ? value : 0, weight.weight, ...params);
} catch (error) {

View File

@ -31,7 +31,7 @@
"homepage": "https://github.com/polkadot-js/ui/tree/master/packages/ui-reactive#readme",
"dependencies": {
"@babel/runtime": "^7.12.1",
"@polkadot/api": "^2.3.2-2",
"@polkadot/api": "^2.3.2-7",
"@polkadot/extension-dapp": "^0.35.0-beta.30",
"rxjs-compat": "^6.6.3"
}

View File

@ -1,14 +1,17 @@
// Copyright 2017-2020 @polkadot/react-components authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { DecodedEvent } from '@polkadot/api-contract/types';
import { Event } from '@polkadot/types/interfaces';
import { Codec, TypeDef } from '@polkadot/types/types';
import { Codec } from '@polkadot/types/types';
import React from 'react';
import { getTypeDef } from '@polkadot/types';
import React, { useMemo } from 'react';
import { Input } from '@polkadot/react-components';
import Params from '@polkadot/react-params';
import { getTypeDef } from '@polkadot/types';
import { classes } from './util';
import { useTranslation } from './translate';
import { classes, getContractAbi } from './util';
export interface Props {
children?: React.ReactNode;
@ -16,14 +19,42 @@ export interface Props {
value: Event;
}
interface Value {
isValid: boolean;
value: Codec;
}
interface AbiEvent extends DecodedEvent {
values: Value[];
}
function EventDisplay ({ children, className = '', value }: Props): React.ReactElement<Props> {
const params = value.typeDef.map(({ type }): { type: TypeDef } => ({
type: getTypeDef(type)
}));
const values = value.data.map((value): { isValid: boolean; value: Codec } => ({
isValid: true,
value
}));
const { t } = useTranslation();
const params = value.typeDef.map(({ type }) => ({ type: getTypeDef(type) }));
const values = value.data.map((value) => ({ isValid: true, value }));
const abiEvent = useMemo(
(): AbiEvent | null => {
// for contracts, we decode the actual event
if (value.section === 'contracts' && value.method === 'ContractExecution' && value.data.length === 2) {
// see if we have info for this contract
const [accountId, encoded] = value.data;
const abi = getContractAbi(accountId.toString());
if (abi) {
const decoded = abi.decodeEvent(encoded.toU8a(true));
return {
...decoded,
values: decoded.args.map((value) => ({ isValid: true, value }))
};
}
}
return null;
},
[value]
);
return (
<div className={classes('ui--Event', className)}>
@ -32,7 +63,22 @@ function EventDisplay ({ children, className = '', value }: Props): React.ReactE
isDisabled
params={params}
values={values}
/>
>
{abiEvent && (
<>
<Input
isDisabled
label={t<string>('contract event')}
value={abiEvent.event.identifier}
/>
<Params
isDisabled
params={abiEvent.event.args}
values={abiEvent.values}
/>
</>
)}
</Params>
</div>
);
}

View File

@ -12,6 +12,7 @@ import { registry } from '@polkadot/react-api';
import jsonrpc from '@polkadot/types/interfaces/jsonrpc';
import { createType } from '@polkadot/types';
import { getContractAbi } from '../util';
import { QueueProvider } from './Context';
import { STATUS_COMPLETE } from './constants';
@ -103,6 +104,20 @@ function extractEvents (result?: SubmittableResult): ActionStatus[] {
message,
status: 'error'
};
} else if (section === 'contracts' && method === 'ContractExecution' && data.length === 2) {
// see if we have info for this contract
const [accountId, encoded] = data;
const abi = getContractAbi(accountId.toString());
if (abi) {
const decoded = abi.decodeEvent(encoded.toU8a(true));
return {
action: decoded.event.identifier,
message: 'contract event',
status: 'event'
};
}
}
return {

View File

@ -4,6 +4,7 @@
import { AnyJson } from '@polkadot/types/types';
import { Abi } from '@polkadot/api-contract';
import { api } from '@polkadot/react-api';
import getAddressMeta from './getAddressMeta';
@ -18,7 +19,7 @@ export default function getContractAbi (address: string | null): Abi | null {
try {
const data = meta.contract && JSON.parse(meta.contract.abi) as AnyJson;
abi = new Abi(data);
abi = new Abi(data, api.registry.getChainProperties());
} catch (error) {
console.error(error);
}

View File

@ -28,7 +28,7 @@ function Option ({ className = '', defaultValue, isDisabled, name, onChange, onE
defaultValue={defaultValue}
isDisabled={isDisabled || !isActive}
isInOption
isOptional={!isActive}
isOptional={!isActive && !isDisabled}
name={name}
onChange={onChange}
onEnter={onEnter}

View File

@ -3,7 +3,7 @@
import { Props, Props as CProps } from '../types';
import React, { useRef } from 'react';
import React, { useMemo, useRef } from 'react';
import { classes } from '@polkadot/react-components/util';
import { encodeTypeDef } from '@polkadot/types';
import { isUndefined } from '@polkadot/util';
@ -14,14 +14,17 @@ import Static from './Static';
function Param ({ className = '', defaultValue, isDisabled, isInOption, isOptional, name, onChange, onEnter, onEscape, overrides, type }: Props): React.ReactElement<Props> | null {
const compRef = useRef<React.ComponentType<CProps> | null>(findComponent(type, overrides));
const label = useMemo(
() => isUndefined(name)
? encodeTypeDef(type)
: `${name}: ${encodeTypeDef(type)}`,
[name, type]
);
if (!compRef.current) {
return null;
}
const label = isUndefined(name)
? encodeTypeDef(type)
: `${name}: ${encodeTypeDef(type)}`;
return isOptional
? (
<Static

View File

@ -103,8 +103,8 @@ class Params extends React.PureComponent<Props, State> {
type={type}
/>
))}
{children}
</div>
{children}
</ErrorBoundary>
</Holder>
);

112
yarn.lock
View File

@ -2099,57 +2099,57 @@ __metadata:
languageName: node
linkType: hard
"@polkadot/api-contract@npm:^2.3.2-2":
version: 2.3.2-2
resolution: "@polkadot/api-contract@npm:2.3.2-2"
"@polkadot/api-contract@npm:^2.3.2-7":
version: 2.3.2-7
resolution: "@polkadot/api-contract@npm:2.3.2-7"
dependencies:
"@babel/runtime": ^7.12.1
"@polkadot/api": 2.3.2-2
"@polkadot/rpc-core": 2.3.2-2
"@polkadot/types": 2.3.2-2
"@polkadot/api": 2.3.2-7
"@polkadot/rpc-core": 2.3.2-7
"@polkadot/types": 2.3.2-7
"@polkadot/util": ^3.6.1
bn.js: ^5.1.3
rxjs: ^6.6.3
checksum: 42305d27b75941a4d1c1be71f1ce417dd01dca8cd9f8774817abf3350b446874c0f59cec518ba41eb0ff7989b5d3f870deb2a468969b638d93e0c737ee3affa8
checksum: 90767f748ecd9ce4fd135f021122b93bfec3eee13114947760783f4785d5d63d77e1bf417aa0c1e81e623565ff19efe757dd48302b6278c5ed0e9686853ff13a
languageName: node
linkType: hard
"@polkadot/api-derive@npm:2.3.2-2":
version: 2.3.2-2
resolution: "@polkadot/api-derive@npm:2.3.2-2"
"@polkadot/api-derive@npm:2.3.2-7":
version: 2.3.2-7
resolution: "@polkadot/api-derive@npm:2.3.2-7"
dependencies:
"@babel/runtime": ^7.12.1
"@polkadot/api": 2.3.2-2
"@polkadot/rpc-core": 2.3.2-2
"@polkadot/rpc-provider": 2.3.2-2
"@polkadot/types": 2.3.2-2
"@polkadot/api": 2.3.2-7
"@polkadot/rpc-core": 2.3.2-7
"@polkadot/rpc-provider": 2.3.2-7
"@polkadot/types": 2.3.2-7
"@polkadot/util": ^3.6.1
"@polkadot/util-crypto": ^3.6.1
bn.js: ^5.1.3
memoizee: ^0.4.14
rxjs: ^6.6.3
checksum: cc6f2e8fcc19ee8e05ce19961e911954a4906157d0d8940c66abf5fc738c5fea66902125452d55fb1ba7f2811550f9f37c2737b29c36f24c5af8316dd0666cbd
checksum: ea9812922048387214dc68bbf0fe6d630b09580129a2501d6688b199f57063d4d935d4c28994b5bf2dbf26f49b69138655cccfa38f02dbad89a2251fe1d068b9
languageName: node
linkType: hard
"@polkadot/api@npm:^2.3.2-2":
version: 2.3.2-2
resolution: "@polkadot/api@npm:2.3.2-2"
"@polkadot/api@npm:^2.3.2-7":
version: 2.3.2-7
resolution: "@polkadot/api@npm:2.3.2-7"
dependencies:
"@babel/runtime": ^7.12.1
"@polkadot/api-derive": 2.3.2-2
"@polkadot/api-derive": 2.3.2-7
"@polkadot/keyring": ^3.6.1
"@polkadot/metadata": 2.3.2-2
"@polkadot/rpc-core": 2.3.2-2
"@polkadot/rpc-provider": 2.3.2-2
"@polkadot/types": 2.3.2-2
"@polkadot/types-known": 2.3.2-2
"@polkadot/metadata": 2.3.2-7
"@polkadot/rpc-core": 2.3.2-7
"@polkadot/rpc-provider": 2.3.2-7
"@polkadot/types": 2.3.2-7
"@polkadot/types-known": 2.3.2-7
"@polkadot/util": ^3.6.1
"@polkadot/util-crypto": ^3.6.1
bn.js: ^5.1.3
eventemitter3: ^4.0.7
rxjs: ^6.6.3
checksum: 07473c4c24343e2700a91c2d95fd2f103146180dd0158eba766859c923718213ca2300f2563a3c0f15a767bb225e9e9f6397cd73aa8a2129515db07e0820ec2d
checksum: f169383c41daa781592f5e85bc2ca53f91d3a7c074b8cd99548a9f53265d60399803c7f260017d308ea93bc66647c5a01445be58353a296b476ce2695ba4d301
languageName: node
linkType: hard
@ -2205,7 +2205,7 @@ __metadata:
resolution: "@polkadot/app-contracts@workspace:packages/page-contracts"
dependencies:
"@babel/runtime": ^7.12.1
"@polkadot/api-contract": ^2.3.2-2
"@polkadot/api-contract": ^2.3.2-7
languageName: unknown
linkType: soft
@ -2586,17 +2586,17 @@ __metadata:
languageName: node
linkType: hard
"@polkadot/metadata@npm:2.3.2-2":
version: 2.3.2-2
resolution: "@polkadot/metadata@npm:2.3.2-2"
"@polkadot/metadata@npm:2.3.2-7":
version: 2.3.2-7
resolution: "@polkadot/metadata@npm:2.3.2-7"
dependencies:
"@babel/runtime": ^7.12.1
"@polkadot/types": 2.3.2-2
"@polkadot/types-known": 2.3.2-2
"@polkadot/types": 2.3.2-7
"@polkadot/types-known": 2.3.2-7
"@polkadot/util": ^3.6.1
"@polkadot/util-crypto": ^3.6.1
bn.js: ^5.1.3
checksum: 14f246804be9206756893ef0d430cb8efb4c61463dd8ac865319cec212354f081d9425a0f328f56f7754f2adf866bc3cfdf20d7184ec3ab4bd731910296a1838
checksum: d606dfaa190b0f8d673e315c017cfa69ab3d23492ba71b5d7861703df2b2377d2d9952442f9174f5beb60dd07c25e42056f5bcb7587fb6333f44185e72853413
languageName: node
linkType: hard
@ -2614,7 +2614,7 @@ __metadata:
resolution: "@polkadot/react-api@workspace:packages/react-api"
dependencies:
"@babel/runtime": ^7.12.1
"@polkadot/api": ^2.3.2-2
"@polkadot/api": ^2.3.2-7
"@polkadot/extension-dapp": ^0.35.0-beta.30
rxjs-compat: ^6.6.3
languageName: unknown
@ -2744,35 +2744,35 @@ __metadata:
languageName: unknown
linkType: soft
"@polkadot/rpc-core@npm:2.3.2-2":
version: 2.3.2-2
resolution: "@polkadot/rpc-core@npm:2.3.2-2"
"@polkadot/rpc-core@npm:2.3.2-7":
version: 2.3.2-7
resolution: "@polkadot/rpc-core@npm:2.3.2-7"
dependencies:
"@babel/runtime": ^7.12.1
"@polkadot/metadata": 2.3.2-2
"@polkadot/rpc-provider": 2.3.2-2
"@polkadot/types": 2.3.2-2
"@polkadot/metadata": 2.3.2-7
"@polkadot/rpc-provider": 2.3.2-7
"@polkadot/types": 2.3.2-7
"@polkadot/util": ^3.6.1
memoizee: ^0.4.14
rxjs: ^6.6.3
checksum: a3093965c913c321f0daaf019e8d0786d7680aafdc582e152bd7ec7e8ed94ec6ad2bb9c40b8458b06313ae47137b19ba1e70707c8fe891d0ed34610a38f5e7eb
checksum: 4c7485e75b38cbf20ae50e3ed76bb941672437770c72fef9e169b64d6995b76ff00f780646220606576875787c1093a5c7514d32a34f9cbcb8d73b58664dc603
languageName: node
linkType: hard
"@polkadot/rpc-provider@npm:2.3.2-2":
version: 2.3.2-2
resolution: "@polkadot/rpc-provider@npm:2.3.2-2"
"@polkadot/rpc-provider@npm:2.3.2-7":
version: 2.3.2-7
resolution: "@polkadot/rpc-provider@npm:2.3.2-7"
dependencies:
"@babel/runtime": ^7.12.1
"@polkadot/metadata": 2.3.2-2
"@polkadot/types": 2.3.2-2
"@polkadot/metadata": 2.3.2-7
"@polkadot/types": 2.3.2-7
"@polkadot/util": ^3.6.1
"@polkadot/util-crypto": ^3.6.1
"@polkadot/x-fetch": ^0.3.3
"@polkadot/x-ws": ^0.3.3
bn.js: ^5.1.3
eventemitter3: ^4.0.7
checksum: c2c6f1dbb9ecc301d2f2e21cc96a51b631837d6d6f6555312006cdffd6f6e102cfdf6b809dad7e787347bb926557c1af509a54f7e78c656ff64c563aa10f30aa
checksum: 30f2fadeabcaa7c110a41a03659be7ec5b349fa4e8fa2871af47ae95a6389badc5ee0dd301a2ff5a8ce3622faef8f81c49692d1484e68d4e0b504d245cbdd459
languageName: node
linkType: hard
@ -2785,31 +2785,31 @@ __metadata:
languageName: node
linkType: hard
"@polkadot/types-known@npm:2.3.2-2":
version: 2.3.2-2
resolution: "@polkadot/types-known@npm:2.3.2-2"
"@polkadot/types-known@npm:2.3.2-7":
version: 2.3.2-7
resolution: "@polkadot/types-known@npm:2.3.2-7"
dependencies:
"@babel/runtime": ^7.12.1
"@polkadot/types": 2.3.2-2
"@polkadot/types": 2.3.2-7
"@polkadot/util": ^3.6.1
bn.js: ^5.1.3
checksum: 9d1b114d1ca720373ae0b878049aafbb42e12a84821b97e736592e1873cf0dc7b92223cffa13b1289afd77e7a7d87bd97ccf86dabda56f318bc775eef6b6e7d5
checksum: 57c8009faf83208ce9c719a0cbee8745c795f46ede6bbd88e3254ad94bd381a9e9ff3eef7723ce449ff554d58e298c8d653c173d233916bf086bfdcf0ff1cc6a
languageName: node
linkType: hard
"@polkadot/types@npm:^2.3.2-2":
version: 2.3.2-2
resolution: "@polkadot/types@npm:2.3.2-2"
"@polkadot/types@npm:^2.3.2-7":
version: 2.3.2-7
resolution: "@polkadot/types@npm:2.3.2-7"
dependencies:
"@babel/runtime": ^7.12.1
"@polkadot/metadata": 2.3.2-2
"@polkadot/metadata": 2.3.2-7
"@polkadot/util": ^3.6.1
"@polkadot/util-crypto": ^3.6.1
"@types/bn.js": ^4.11.6
bn.js: ^5.1.3
memoizee: ^0.4.14
rxjs: ^6.6.3
checksum: 3b92c234b2400048c8ce29295aaf8ea85c6fbca4d2a65cde05f9de9afe5f004f795424fdbfe94cb65154b1522c64b6f21622166795e4637020256b9b082d8709
checksum: ff05ce6a5a9637c63eea6bdec96021916b4450eb34d393f2dde61314b00930c2e1e38c8e3864ce72349f9aaf2fbcba88b79d0f32ac70c3de7447300e75869e06
languageName: node
linkType: hard