From ffa6b45fab9ec067d4bed3b81f5097f03861b876 Mon Sep 17 00:00:00 2001 From: josemarinas <36479864+josemarinas@users.noreply.github.com> Date: Tue, 23 Apr 2024 13:29:07 +0200 Subject: [PATCH 1/2] fix(sdk): `getProtocolVersion` function (#77) * add: getProtocolVersion function * fix: prettier * fix: linting * Update sdk/src/introspection.ts Co-authored-by: Carles <75954325+banasa44@users.noreply.github.com> * Update sdk/src/introspection.ts Co-authored-by: Michael Heuer <20623991+Michael-A-Heuer@users.noreply.github.com> * Update sdk/test/unit/introspection.test.ts Co-authored-by: Michael Heuer <20623991+Michael-A-Heuer@users.noreply.github.com> * remove: constant ADDRESS_ONE * fix: prettier * fix: export of addres one * fix: update getProtocolVersion return comment * chore: add ADDRESS_ONE to constants * feat: add getProtocolVersion * update pacakge.json --------- Co-authored-by: Carles <75954325+banasa44@users.noreply.github.com> Co-authored-by: Michael Heuer <20623991+Michael-A-Heuer@users.noreply.github.com> --- sdk/package.json | 5 +-- sdk/src/introspection.ts | 39 +++++++++----------- sdk/test/mocks.ts | 18 +++++++++- sdk/test/unit/introspection.test.ts | 55 +++++++++++++++++------------ 4 files changed, 68 insertions(+), 49 deletions(-) diff --git a/sdk/package.json b/sdk/package.json index df2480a7..450cdf02 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -1,7 +1,7 @@ { "name": "@aragon/osx-commons-sdk", "author": "Aragon Association", - "version": "0.0.1-alpha.9", + "version": "0.0.1-alpha.10", "license": "MIT", "main": "dist/index.js", "module": "dist/osx-commons-sdk.esm.js", @@ -54,11 +54,12 @@ }, "dependencies": { "@aragon/osx-commons-configs": "^0.4.0", + "@ethersproject/address": "^5.7.0", "@ethersproject/bignumber": "^5.7.0", "@ethersproject/contracts": "^5.7.0", "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", "@ethersproject/providers": "^5.7.0", - "@ethersproject/address": "^5.7.0", "ipfs-http-client": "^51.0.0" } } diff --git a/sdk/src/introspection.ts b/sdk/src/introspection.ts index 3b39d481..1b9e91c4 100644 --- a/sdk/src/introspection.ts +++ b/sdk/src/introspection.ts @@ -1,9 +1,12 @@ -import {InvalidAddressError} from './errors'; import {Interface} from '@ethersproject/abi'; -import {isAddress} from '@ethersproject/address'; import {BigNumber} from '@ethersproject/bignumber'; import {Contract} from '@ethersproject/contracts'; -import {JsonRpcProvider} from '@ethersproject/providers'; +import {ErrorCode} from '@ethersproject/logger'; + +// The protocol version number of contracts not having a `getProtocolVersion()` function because they don't inherit from `ProtocolVersion.sol` yet. +export const IMPLICIT_INITIAL_PROTOCOL_VERSION: [number, number, number] = [ + 1, 0, 0, +]; /** * Gets the interfaceId of a given interface @@ -26,31 +29,21 @@ export function getInterfaceId(iface: Interface): string { * protocolVersion function, it will return [1, 0, 0] * * @export - * @param {string} rpc - * @param {string} contractAddress + * @param {Contract} contract * @return {*} {Promise<[number, number, number]>} */ export async function getProtocolVersion( - rpc: string, - contractAddress: string + contract: Contract ): Promise<[number, number, number]> { - if (!isAddress(contractAddress)) { - throw new InvalidAddressError(contractAddress); - } - const provider = new JsonRpcProvider(rpc); - const iface = new Interface([ - 'function protocolVersion() public pure returns (uint8[3] memory)', - ]); - const contract = new Contract(contractAddress, iface, provider); - let version: [number, number, number]; + let protocolVersion: [number, number, number]; try { - version = await contract.protocolVersion(); + contract.interface.getFunction('protocolVersion'); + protocolVersion = await contract.protocolVersion(); } catch (e) { - // version 1.0.0 of the contract does not have a protocolVersion function - // so if we receive an error we cannot differentiate between a call exception - // and a contract that does not have the function. So we assume that is - // a version 1.0.0 contract that does not have the function and return [1, 0, 0] - version = [1, 0, 0]; + if ((e as any).code === ErrorCode.INVALID_ARGUMENT) { + return IMPLICIT_INITIAL_PROTOCOL_VERSION; + } + throw e; } - return version; + return protocolVersion; } diff --git a/sdk/test/mocks.ts b/sdk/test/mocks.ts index e4f0443a..37f8776a 100644 --- a/sdk/test/mocks.ts +++ b/sdk/test/mocks.ts @@ -1,3 +1,6 @@ +import {FunctionFragment} from '@ethersproject/abi'; +import {ErrorCode, Logger} from '@ethersproject/logger'; + export function mockContractProtocolVersion( version: [number, number, number] = [1, 0, 0], throwException: boolean = false @@ -8,10 +11,23 @@ export function mockContractProtocolVersion( return { protocolVersion: () => { if (throwException) { - throw new Error('Error'); + const logger = new Logger('5.7.0'); + logger.throwError( + 'Protocol version not found', + ErrorCode.INVALID_ARGUMENT + ); } return Promise.resolve(version); }, + interface: { + getFunction: (name: string): FunctionFragment => { + return FunctionFragment.from({ + name: name, + type: 'function', + stateMutability: 'pure', + }); + }, + }, }; }); } diff --git a/sdk/test/unit/introspection.test.ts b/sdk/test/unit/introspection.test.ts index 7950794b..ea0e38b9 100644 --- a/sdk/test/unit/introspection.test.ts +++ b/sdk/test/unit/introspection.test.ts @@ -1,11 +1,13 @@ import { - InvalidAddressError, + IMPLICIT_INITIAL_PROTOCOL_VERSION, getInterfaceId, getProtocolVersion, } from '../../src'; import {ADDRESS_ONE, TEST_HTTP_URI} from '../constants'; -import {mockContractProtocolVersion, mockJSONRPCProvider} from '../mocks'; +import {mockJSONRPCProvider, mockContractProtocolVersion} from '../mocks'; import {Interface} from '@ethersproject/abi'; +import {Contract} from '@ethersproject/contracts'; +import {JsonRpcProvider} from '@ethersproject/providers'; describe('introspection', () => { describe('getInterfaceId', () => { @@ -21,33 +23,40 @@ describe('introspection', () => { }); describe('getProtocolVersion', () => { - it('should return the correct protocol version', async () => { - const expectedVersion: [number, number, number] = [1, 3, 0]; - // mock call to the contract + let iface: Interface; + let contract: Contract; + let provider: JsonRpcProvider; + beforeAll(() => { + // mock JSONRPCProvider to return chainId 1 and blockNumber 1 mockJSONRPCProvider(); - // mock the call to the contract - mockContractProtocolVersion(expectedVersion); - const version = await getProtocolVersion(TEST_HTTP_URI, ADDRESS_ONE); - expect(version).toEqual(expectedVersion); }); - it('should fail when an invalid address is passed', async () => { + it('should return the correct protocol version', async () => { + // Expected protocol version const expectedVersion: [number, number, number] = [1, 3, 0]; - // mock call to the contract - mockJSONRPCProvider(); - // mock the call to the contract + // mock Contract to return the expected protocol version mockContractProtocolVersion(expectedVersion); - await expect(() => - getProtocolVersion(TEST_HTTP_URI, '0x') - ).rejects.toThrow(new InvalidAddressError('0x')); + // Initialize the contract + provider = new JsonRpcProvider(TEST_HTTP_URI); + iface = new Interface([ + 'function protocolVersion() public pure returns (uint8[3] memory)', + ]); + contract = new Contract(ADDRESS_ONE, iface, provider); + // Call getProtocolVersion + const version = await getProtocolVersion(contract); + expect(version).toEqual(expectedVersion); }); it('should return [1,0,0] when the call throws an error', async () => { - const expectedVersion: [number, number, number] = [1, 0, 0]; - // mock call to the contract - mockJSONRPCProvider(); - // mock the call to the contract - mockContractProtocolVersion(expectedVersion, true); - const version = await getProtocolVersion(TEST_HTTP_URI, ADDRESS_ONE); - expect(version).toEqual(expectedVersion); + // mock Contract to throw an error + mockContractProtocolVersion(IMPLICIT_INITIAL_PROTOCOL_VERSION, true); + // Initialize the contract + const iface = new Interface([ + 'function protocolVersion() public pure returns (uint8[3] memory)', + ]); + const provider = new JsonRpcProvider(TEST_HTTP_URI); + const contract = new Contract(ADDRESS_ONE, iface, provider); + // Call getProtocolVersion + const version = await getProtocolVersion(contract); + expect(version).toEqual(IMPLICIT_INITIAL_PROTOCOL_VERSION); }); }); }); From 5c9ac9a92c2d9313796201ea56b9d57307077a13 Mon Sep 17 00:00:00 2001 From: Michael Heuer <20623991+Michael-A-Heuer@users.noreply.github.com> Date: Tue, 23 Apr 2024 15:19:52 +0200 Subject: [PATCH 2/2] feat(sdk): add back `PluginType` enum and fix npm dependencies (#78) * feat: add back plugin type enum * chore: bump version and maintain changelog * chore: update lockfile --- sdk/CHANGELOG.md | 1 + sdk/package.json | 14 +++++++------- sdk/src/introspection.ts | 13 +++++++++++++ sdk/src/permission.ts | 2 +- sdk/yarn.lock | 4 ++-- 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/sdk/CHANGELOG.md b/sdk/CHANGELOG.md index 5995346a..79c20e38 100644 --- a/sdk/CHANGELOG.md +++ b/sdk/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Add `PluginType` enum - Add `resolveEnsName` functions - Add `getProtocolVersion` function diff --git a/sdk/package.json b/sdk/package.json index 450cdf02..8d46f27d 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -1,7 +1,7 @@ { "name": "@aragon/osx-commons-sdk", "author": "Aragon Association", - "version": "0.0.1-alpha.10", + "version": "0.0.1-alpha.11", "license": "MIT", "main": "dist/index.js", "module": "dist/osx-commons-sdk.esm.js", @@ -54,12 +54,12 @@ }, "dependencies": { "@aragon/osx-commons-configs": "^0.4.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/contracts": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/providers": "^5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/providers": "5.7.2", "ipfs-http-client": "^51.0.0" } } diff --git a/sdk/src/introspection.ts b/sdk/src/introspection.ts index 1b9e91c4..95e5aa9d 100644 --- a/sdk/src/introspection.ts +++ b/sdk/src/introspection.ts @@ -47,3 +47,16 @@ export async function getProtocolVersion( } return protocolVersion; } + +/** + * Enum for PluginType + * Reference: https://github.com/aragon/osx-commons/blob/ffa6b45fab9ec067d4bed3b81f5097f03861b876/contracts/src/plugin/IPlugin.sol + * + * @export + * @enum {number} + */ +export enum PluginType { + UUPS = 0, + Cloneable = 1, + Constructable = 2, +} diff --git a/sdk/src/permission.ts b/sdk/src/permission.ts index a6f9731e..e0d0bfe4 100644 --- a/sdk/src/permission.ts +++ b/sdk/src/permission.ts @@ -2,7 +2,7 @@ import {id} from '@ethersproject/hash'; /** * Enum for PermissionType - * Reference: + * Reference: https://github.com/aragon/osx-commons/blob/ffa6b45fab9ec067d4bed3b81f5097f03861b876/contracts/src/permission/PermissionLib.sol * * @export * @enum {number} diff --git a/sdk/yarn.lock b/sdk/yarn.lock index 2a4e08cc..1fc8368d 100644 --- a/sdk/yarn.lock +++ b/sdk/yarn.lock @@ -1139,7 +1139,7 @@ dependencies: "@ethersproject/bignumber" "^5.7.0" -"@ethersproject/contracts@5.7.0", "@ethersproject/contracts@^5.7.0": +"@ethersproject/contracts@5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.7.0.tgz#c305e775abd07e48aa590e1a877ed5c316f8bd1e" integrity sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg== @@ -1242,7 +1242,7 @@ dependencies: "@ethersproject/logger" "^5.7.0" -"@ethersproject/providers@5.7.2", "@ethersproject/providers@^5.7.0": +"@ethersproject/providers@5.7.2": version "5.7.2" resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==