From 0c8536a7d537be0d85d11ce4005dbd0bd2cd273a Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Fri, 23 Apr 2021 18:53:37 +0400 Subject: [PATCH 1/9] make safe-app-provider follow eip1193 --- packages/safe-apps-provider/package.json | 3 +- packages/safe-apps-provider/src/provider.ts | 53 +++++++++++---------- packages/safe-apps-provider/src/types.ts | 51 ++++++++++++++++++++ 3 files changed, 81 insertions(+), 26 deletions(-) create mode 100644 packages/safe-apps-provider/src/types.ts diff --git a/packages/safe-apps-provider/package.json b/packages/safe-apps-provider/package.json index 748dd9d9..45b4694a 100644 --- a/packages/safe-apps-provider/package.json +++ b/packages/safe-apps-provider/package.json @@ -20,6 +20,7 @@ }, "homepage": "https://github.com/gnosis/safe-apps-sdk#readme", "dependencies": { - "@gnosis.pm/safe-apps-sdk": "2.2.0" + "@gnosis.pm/safe-apps-sdk": "2.2.0", + "events": "^3.3.0" } } diff --git a/packages/safe-apps-provider/src/provider.ts b/packages/safe-apps-provider/src/provider.ts index 374eb71a..eb8d004d 100644 --- a/packages/safe-apps-provider/src/provider.ts +++ b/packages/safe-apps-provider/src/provider.ts @@ -1,4 +1,8 @@ +/* eslint @typescript-eslint/explicit-module-boundary-types: 1, @typescript-eslint/no-explicit-any: 1*/ + import SafeAppsSDK, { SafeInfo, Web3TransactionObject } from '@gnosis.pm/safe-apps-sdk'; +import { EventEmitter } from 'events'; +import { EIP1193Provider } from './types'; import { getLowerCase } from './utils'; const NETWORK_CHAIN_ID: Record = { @@ -7,44 +11,43 @@ const NETWORK_CHAIN_ID: Record = { XDAI: 100, }; -// taken from ethers.js, compatible interface with web3 provider -type AsyncSendable = { - isMetaMask?: boolean; - host?: string; - path?: string; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - sendAsync?: (request: any, callback: (error: any, response: any) => void) => void; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - send?: (request: any, callback: (error: any, response: any) => void) => void; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - request?: (request: { method: string; params?: Array }) => Promise; -}; - -export class SafeAppProvider implements AsyncSendable { +export class SafeAppProvider implements EIP1193Provider { private readonly safe: SafeInfo; private readonly sdk: SafeAppsSDK; private submittedTxs = new Map(); + private events = new EventEmitter(); constructor(safe: SafeInfo, sdk: SafeAppsSDK) { this.safe = safe; this.sdk = sdk; } - public get chainId(): number { - return NETWORK_CHAIN_ID[this.safe.network]; + async connect(): Promise { + return; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any - sendAsync(request: any, callback: (error: any, response: any) => void): void { - this.send(request, callback); + async disconnect(): Promise { + return; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any - send(request: any, callback: (error: any, response?: any) => void): void { - if (!request) callback('Undefined request'); - this.request(request) - .then((result) => callback(null, { jsonrpc: '2.0', id: request.id, result })) - .catch((error) => callback(error, null)); + public on(event: string, listener: any): void { + this.events.on(event, listener); + } + + public once(event: string, listener: any): void { + this.events.once(event, listener); + } + + public off(event: string, listener: any): void { + this.events.off(event, listener); + } + + public removeListener(event: string, listener: any): void { + this.events.removeListener(event, listener); + } + + public get chainId(): number { + return NETWORK_CHAIN_ID[this.safe.network]; } // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/packages/safe-apps-provider/src/types.ts b/packages/safe-apps-provider/src/types.ts new file mode 100644 index 00000000..feeb697b --- /dev/null +++ b/packages/safe-apps-provider/src/types.ts @@ -0,0 +1,51 @@ +export interface ProviderRpcError extends Error { + message: string; + code: number; + data?: unknown; +} + +export interface ProviderMessage { + type: string; + data: unknown; +} + +export interface ProviderInfo { + chainId: string; +} + +export interface RequestArguments { + method: string; + params?: unknown[] | Record; +} + +export type ProviderChainId = string; + +export type ProviderAccounts = string[]; + +export interface SimpleEventEmitter { + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any + on(event: string, listener: any): void; + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any + once(event: string, listener: any): void; + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any + removeListener(event: string, listener: any): void; + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any + off(event: string, listener: any): void; +} + +export interface EIP1193Provider extends SimpleEventEmitter { + connect(params?: any): Promise; + disconnect(): Promise; + // connection event + on(event: 'connect', listener: (info: ProviderInfo) => void): void; + // disconnection event + on(event: 'disconnect', listener: (error: ProviderRpcError) => void): void; + // arbitrary messages + on(event: 'message', listener: (message: ProviderMessage) => void): void; + // chain changed event + on(event: 'chainChanged', listener: (chainId: ProviderChainId) => void): void; + // accounts changed event + on(event: 'accountsChanged', listener: (accounts: ProviderAccounts) => void): void; + // make an Ethereum RPC method call. + request(args: RequestArguments): Promise; +} From 90a42687dba3eac8c804e509f0bbaad33cdeeafb Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Mon, 26 Apr 2021 13:45:05 +0400 Subject: [PATCH 2/9] add link to eip1193 --- packages/safe-apps-provider/src/provider.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/safe-apps-provider/src/provider.ts b/packages/safe-apps-provider/src/provider.ts index eb8d004d..646cf5ac 100644 --- a/packages/safe-apps-provider/src/provider.ts +++ b/packages/safe-apps-provider/src/provider.ts @@ -11,6 +11,7 @@ const NETWORK_CHAIN_ID: Record = { XDAI: 100, }; +// The API is based on Ethereum JavaScript API Provider Standard. Link: https://eips.ethereum.org/EIPS/eip-1193 export class SafeAppProvider implements EIP1193Provider { private readonly safe: SafeInfo; private readonly sdk: SafeAppsSDK; From b7cbfd3070126d8abab0001a8d0e6cbff4340f3d Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Mon, 26 Apr 2021 14:07:08 +0400 Subject: [PATCH 3/9] fix --- packages/safe-apps-provider/src/provider.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/safe-apps-provider/src/provider.ts b/packages/safe-apps-provider/src/provider.ts index 646cf5ac..690aa83e 100644 --- a/packages/safe-apps-provider/src/provider.ts +++ b/packages/safe-apps-provider/src/provider.ts @@ -1,5 +1,3 @@ -/* eslint @typescript-eslint/explicit-module-boundary-types: 1, @typescript-eslint/no-explicit-any: 1*/ - import SafeAppsSDK, { SafeInfo, Web3TransactionObject } from '@gnosis.pm/safe-apps-sdk'; import { EventEmitter } from 'events'; import { EIP1193Provider } from './types'; From fd025900f5d337a2730bb6afd89d1f07263c3c2b Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Mon, 26 Apr 2021 14:14:04 +0400 Subject: [PATCH 4/9] remove eslint-disable as they're warnings and dont block compilation --- packages/safe-apps-provider/src/types.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/safe-apps-provider/src/types.ts b/packages/safe-apps-provider/src/types.ts index feeb697b..e712af8b 100644 --- a/packages/safe-apps-provider/src/types.ts +++ b/packages/safe-apps-provider/src/types.ts @@ -23,13 +23,9 @@ export type ProviderChainId = string; export type ProviderAccounts = string[]; export interface SimpleEventEmitter { - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any on(event: string, listener: any): void; - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any once(event: string, listener: any): void; - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any removeListener(event: string, listener: any): void; - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any off(event: string, listener: any): void; } From a49b56a9c54df076450c9c5155745b84b9db7cae Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Mon, 26 Apr 2021 14:22:45 +0400 Subject: [PATCH 5/9] fix types --- packages/safe-apps-provider/src/types.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/safe-apps-provider/src/types.ts b/packages/safe-apps-provider/src/types.ts index e712af8b..138bde48 100644 --- a/packages/safe-apps-provider/src/types.ts +++ b/packages/safe-apps-provider/src/types.ts @@ -23,10 +23,10 @@ export type ProviderChainId = string; export type ProviderAccounts = string[]; export interface SimpleEventEmitter { - on(event: string, listener: any): void; - once(event: string, listener: any): void; - removeListener(event: string, listener: any): void; - off(event: string, listener: any): void; + on(event: string, listener: (...args: any[]) => void): void; + once(event: string, listener: (...args: any[]) => void): void; + removeListener(event: string, listener: (...args: any[]) => void): void; + off(event: string, listener: (...args: any[]) => void): void; } export interface EIP1193Provider extends SimpleEventEmitter { From d4ef23ef0d8790ccf34d1acd595a8eeb36734a46 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Mon, 26 Apr 2021 15:07:02 +0400 Subject: [PATCH 6/9] Emit events in connect/disconnect --- packages/safe-apps-provider/src/provider.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/safe-apps-provider/src/provider.ts b/packages/safe-apps-provider/src/provider.ts index 690aa83e..408d7981 100644 --- a/packages/safe-apps-provider/src/provider.ts +++ b/packages/safe-apps-provider/src/provider.ts @@ -22,10 +22,12 @@ export class SafeAppProvider implements EIP1193Provider { } async connect(): Promise { + this.events.emit('connect'); return; } async disconnect(): Promise { + this.events.emit('disconnect'); return; } From 149ab3baa287baa20733f80a162a3a25f41545f4 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Mon, 26 Apr 2021 15:42:24 +0400 Subject: [PATCH 7/9] emit event with a chainid --- packages/safe-apps-provider/src/provider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/safe-apps-provider/src/provider.ts b/packages/safe-apps-provider/src/provider.ts index 408d7981..fa661a35 100644 --- a/packages/safe-apps-provider/src/provider.ts +++ b/packages/safe-apps-provider/src/provider.ts @@ -22,7 +22,7 @@ export class SafeAppProvider implements EIP1193Provider { } async connect(): Promise { - this.events.emit('connect'); + this.events.emit('connect', { chainId: this.chainId }); return; } From 0b0dfe14fad75c251b6a1903a849d95f45b0f141 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Mon, 26 Apr 2021 15:51:11 +0400 Subject: [PATCH 8/9] dep version bumps --- packages/safe-apps-onboard/package.json | 4 ++-- packages/safe-apps-provider/package.json | 2 +- packages/safe-apps-web3-react/package.json | 4 ++-- packages/safe-apps-web3modal/package.json | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/safe-apps-onboard/package.json b/packages/safe-apps-onboard/package.json index 95d0b8b8..8f485f56 100644 --- a/packages/safe-apps-onboard/package.json +++ b/packages/safe-apps-onboard/package.json @@ -1,6 +1,6 @@ { "name": "@gnosis.pm/safe-apps-onboard", - "version": "0.2.2", + "version": "0.3.0", "description": "An Onboard.js wrapper for Safe App support", "main": "dist/index.js", "typings": "dist/index.d.ts", @@ -33,6 +33,6 @@ "bnc-onboard": "^1.20.0" }, "dependencies": { - "@gnosis.pm/safe-apps-provider": "0.2.4" + "@gnosis.pm/safe-apps-provider": "0.3.0" } } diff --git a/packages/safe-apps-provider/package.json b/packages/safe-apps-provider/package.json index 45b4694a..a489e678 100644 --- a/packages/safe-apps-provider/package.json +++ b/packages/safe-apps-provider/package.json @@ -1,6 +1,6 @@ { "name": "@gnosis.pm/safe-apps-provider", - "version": "0.2.4", + "version": "0.3.0", "description": "A provider wrapper of Safe Apps SDK", "main": "dist/index.js", "typings": "dist/index.d.ts", diff --git a/packages/safe-apps-web3-react/package.json b/packages/safe-apps-web3-react/package.json index cb17922a..e5b93355 100644 --- a/packages/safe-apps-web3-react/package.json +++ b/packages/safe-apps-web3-react/package.json @@ -1,6 +1,6 @@ { "name": "@gnosis.pm/safe-apps-web3-react", - "version": "0.1.2", + "version": "0.2.0", "description": "Web3-react connector for Safe Apps", "main": "dist/index.js", "typings": "dist/index.d.ts", @@ -24,7 +24,7 @@ "license": "MIT", "dependencies": { "@web3-react/abstract-connector": "6.0.7", - "@gnosis.pm/safe-apps-provider": "0.2.4", + "@gnosis.pm/safe-apps-provider": "0.3.0", "@gnosis.pm/safe-apps-sdk": "2.2.0" }, "peerDependencies": { diff --git a/packages/safe-apps-web3modal/package.json b/packages/safe-apps-web3modal/package.json index d326a2f6..62754385 100644 --- a/packages/safe-apps-web3modal/package.json +++ b/packages/safe-apps-web3modal/package.json @@ -1,6 +1,6 @@ { "name": "@gnosis.pm/safe-apps-web3modal", - "version": "0.2.2", + "version": "0.3.0", "description": "A web3modal wrapper for Safe App support", "main": "dist/index.js", "typings": "dist/index.d.ts", @@ -33,6 +33,6 @@ "web3modal": "^1.9.3" }, "dependencies": { - "@gnosis.pm/safe-apps-provider": "0.2.4" + "@gnosis.pm/safe-apps-provider": "0.3.0" } } From 5fc79032031f3b73d63d2d1a5852a9f111f437d5 Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Mon, 26 Apr 2021 17:42:03 +0400 Subject: [PATCH 9/9] dont emit disconnect event --- packages/safe-apps-provider/src/provider.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/safe-apps-provider/src/provider.ts b/packages/safe-apps-provider/src/provider.ts index fa661a35..901d50f7 100644 --- a/packages/safe-apps-provider/src/provider.ts +++ b/packages/safe-apps-provider/src/provider.ts @@ -27,7 +27,6 @@ export class SafeAppProvider implements EIP1193Provider { } async disconnect(): Promise { - this.events.emit('disconnect'); return; }