From 2692e783b40ce16207fa1a8e8513ebb5455fd2d0 Mon Sep 17 00:00:00 2001 From: Richard Moore Date: Mon, 30 Mar 2020 15:11:23 -0400 Subject: [PATCH] Fixed Event args keyword access. --- packages/abi/src.ts/coders/abstract-coder.ts | 4 +-- packages/abi/src.ts/coders/array.ts | 2 +- packages/abi/src.ts/interface.ts | 5 +-- packages/contracts/src.ts/index.ts | 3 +- packages/properties/src.ts/index.ts | 35 ++++++++++++-------- 5 files changed, 30 insertions(+), 19 deletions(-) diff --git a/packages/abi/src.ts/coders/abstract-coder.ts b/packages/abi/src.ts/coders/abstract-coder.ts index c3d11e0951..a8468e58a4 100644 --- a/packages/abi/src.ts/coders/abstract-coder.ts +++ b/packages/abi/src.ts/coders/abstract-coder.ts @@ -8,8 +8,8 @@ import { Logger } from "@ethersproject/logger"; import { version } from "../_version"; const logger = new Logger(version); -export interface Result extends Array { - [key: string]: any; +export interface Result extends ReadonlyArray { + readonly [key: string]: any; } export type CoerceFunc = (type: string, value: any) => any; diff --git a/packages/abi/src.ts/coders/array.ts b/packages/abi/src.ts/coders/array.ts index a065183381..12f7d9f435 100644 --- a/packages/abi/src.ts/coders/array.ts +++ b/packages/abi/src.ts/coders/array.ts @@ -102,7 +102,7 @@ export function unpack(reader: Reader, coders: Array): Array { values[name] = values[index]; }); - return values; + return Object.freeze(values); } diff --git a/packages/abi/src.ts/interface.ts b/packages/abi/src.ts/interface.ts index 6c1ad09b55..213c4f57f7 100644 --- a/packages/abi/src.ts/interface.ts +++ b/packages/abi/src.ts/interface.ts @@ -400,7 +400,7 @@ export class Interface { let resultIndexed = (topics != null) ? this._abiCoder.decode(indexed, concat(topics)): null; let resultNonIndexed = this._abiCoder.decode(nonIndexed, data); - let result: Result = [ ]; + let result: (Array & { [ key: string ]: any }) = [ ]; let nonIndexedIndex = 0, indexedIndex = 0; eventFragment.inputs.forEach((param, index) => { if (param.indexed) { @@ -416,10 +416,11 @@ export class Interface { } else { result[index] = resultNonIndexed[nonIndexedIndex++]; } + if (param.name && result[param.name] == null) { result[param.name] = result[index]; } }); - return result; + return Object.freeze(result); } // Given a transaction, find the matching function fragment (if any) and diff --git a/packages/contracts/src.ts/index.ts b/packages/contracts/src.ts/index.ts index b251b99d73..176d9b64f4 100644 --- a/packages/contracts/src.ts/index.ts +++ b/packages/contracts/src.ts/index.ts @@ -244,7 +244,8 @@ function runMethod(contract: Contract, functionName: string, options: RunOptions let parsed: LogDescription = null; try { parsed = contract.interface.parseLog(log); - } catch (e){} + } catch (e){ } + if (parsed) { event.args = parsed.args; event.decode = (data: BytesLike, topics?: Array) => { diff --git a/packages/properties/src.ts/index.ts b/packages/properties/src.ts/index.ts index 6f825147f4..46f08f8634 100644 --- a/packages/properties/src.ts/index.ts +++ b/packages/properties/src.ts/index.ts @@ -72,14 +72,32 @@ export function shallowCopy(object: T): Similar { return result; } -const opaque: { [key: string]: boolean } = { bigint: true, boolean: true, number: true, string: true }; +const opaque: { [key: string]: boolean } = { bigint: true, boolean: true, "function": true, number: true, string: true }; + +function _isFrozen(object: any): boolean { + + // Opaque objects are not mutable, so safe to copy by assignment + if (object === undefined || object === null || opaque[typeof(object)]) { return true; } + + if (Array.isArray(object) || typeof(object) === "object") { + if (!Object.isFrozen(object)) { return false; } + + const keys = Object.keys(object); + for (let i = 0; i < keys.length; i++) { + if (!_isFrozen(object[keys[i]])) { return false; } + } + + return true; + } + + return logger.throwArgumentError(`Cannot deepCopy ${ typeof(object) }`, "object", object); +} // Returns a new copy of object, such that no properties may be replaced. // New properties may be added only to objects. function _deepCopy(object: any): any { - // Opaque objects are not mutable, so safe to copy by assignment - if (object === undefined || object === null || opaque[typeof(object)]) { return object; } + if (_isFrozen(object)) { return object; } // Arrays are mutable, so we need to create a copy if (Array.isArray(object)) { @@ -87,10 +105,6 @@ function _deepCopy(object: any): any { } if (typeof(object) === "object") { - - // Immutable objects are safe to just use - if (Object.isFrozen(object)) { return object; } - const result: { [ key: string ]: any } = {}; for (const key in object) { const value = object[key]; @@ -101,12 +115,7 @@ function _deepCopy(object: any): any { return result; } - // The function type is also immutable, so safe to copy by assignment - if (typeof(object) === "function") { - return object; - } - - logger.throwArgumentError(`Cannot deepCopy ${ typeof(object) }`, "object", object); + return logger.throwArgumentError(`Cannot deepCopy ${ typeof(object) }`, "object", object); } export function deepCopy(object: T): Similar {