fix(api-contracts): correctly decode pallet_revive events (#6181)
* fix: revive events * chore: format
This commit is contained in:
@@ -194,12 +194,55 @@ export class Abi {
|
||||
// earlier version are hoisted to v4
|
||||
case '4':
|
||||
return this.#decodeEventV4(record);
|
||||
case '5':
|
||||
return this.#decodeEventV5(record);
|
||||
// Latest
|
||||
default:
|
||||
return this.#decodeEventV5(record);
|
||||
return this.#decodeEventV6(record);
|
||||
}
|
||||
}
|
||||
|
||||
#decodeEventV6 = (record: EventRecord): DecodedEvent => {
|
||||
const topics = record.event.data[2] as unknown as { toHex: () => string }[];
|
||||
// Try to match by signature topic (first topic)
|
||||
const signatureTopic = topics[0];
|
||||
const data = record.event.data[1] as Bytes;
|
||||
|
||||
if (signatureTopic) {
|
||||
const event = this.events.find((e) => e.signatureTopic !== undefined && e.signatureTopic !== null && e.signatureTopic === signatureTopic.toHex());
|
||||
|
||||
// Early return if event found by signature topic
|
||||
if (event) {
|
||||
return event.fromU8a(data);
|
||||
}
|
||||
}
|
||||
|
||||
// If no event returned yet, it might be anonymous
|
||||
const amountOfTopics = topics.length;
|
||||
const potentialEvents = this.events.filter((e) => {
|
||||
// event can't have a signature topic
|
||||
if (e.signatureTopic !== null && e.signatureTopic !== undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// event should have same amount of indexed fields as emitted topics
|
||||
const amountIndexed = e.args.filter((a) => a.indexed).length;
|
||||
|
||||
if (amountIndexed !== amountOfTopics) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If all conditions met, it's a potential event
|
||||
return true;
|
||||
});
|
||||
|
||||
if (potentialEvents.length === 1) {
|
||||
return potentialEvents[0].fromU8a(data);
|
||||
}
|
||||
|
||||
throw new Error('Unable to determine event');
|
||||
};
|
||||
|
||||
#decodeEventV5 = (record: EventRecord): DecodedEvent => {
|
||||
// Find event by first topic, which potentially is the signature_topic
|
||||
const signatureTopic = record.topics[0];
|
||||
|
||||
@@ -85,7 +85,7 @@ export class Blueprint<ApiType extends ApiTypes> extends Base<ApiType> {
|
||||
: undefined
|
||||
)
|
||||
: applyOnEvent(result, ['Instantiated'], ([record]: EventRecord[]) =>
|
||||
new Contract<ApiType>(this.api, this.abi, record.event.data[1] as AccountId, this._decorateMethod)
|
||||
new Contract<ApiType>(this.api, this.abi, record.event.data[1] as AccountId, this._decorateMethod), this._isRevive
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -110,7 +110,7 @@ export class Code<ApiType extends ApiTypes> extends Base<ApiType> {
|
||||
: this.api.events.contracts.CodeStored.is(event)
|
||||
? [new Blueprint<ApiType>(this.api, this.abi, (event as unknown as { data: [AccountId] }).data[0], this._decorateMethod), contract]
|
||||
: [blueprint, contract],
|
||||
[undefined, undefined])
|
||||
[undefined, undefined]), this._isRevive
|
||||
) || [undefined, undefined]))
|
||||
);
|
||||
};
|
||||
|
||||
@@ -125,7 +125,7 @@ export class Contract<ApiType extends ApiTypes> extends Base<ApiType> {
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.filter((decoded): decoded is DecodedEvent => !!decoded)
|
||||
.filter((decoded): decoded is DecodedEvent => !!decoded), this._isRevive
|
||||
))
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,9 +6,10 @@ import type { EventRecord } from '@polkadot/types/interfaces';
|
||||
|
||||
type ContractEvents = 'CodeStored' | 'ContractEmitted' | 'ContractExecution' | 'Instantiated';
|
||||
|
||||
export function applyOnEvent <T> (result: SubmittableResult, types: ContractEvents[], fn: (records: EventRecord[]) => T): T | undefined {
|
||||
export function applyOnEvent <T> (result: SubmittableResult, types: ContractEvents[], fn: (records: EventRecord[]) => T, isRevive: boolean): T | undefined {
|
||||
if (result.isInBlock || result.isFinalized) {
|
||||
const records = result.filterRecords('contracts', types);
|
||||
const section = isRevive ? 'revive' : 'contracts';
|
||||
const records = result.filterRecords(section, types);
|
||||
|
||||
if (records.length) {
|
||||
return fn(records);
|
||||
|
||||
Reference in New Issue
Block a user