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 748dd9d9..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", @@ -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..901d50f7 100644 --- a/packages/safe-apps-provider/src/provider.ts +++ b/packages/safe-apps-provider/src/provider.ts @@ -1,4 +1,6 @@ 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 +9,45 @@ 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 { +// 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; 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 { + this.events.emit('connect', { chainId: this.chainId }); + 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..138bde48 --- /dev/null +++ b/packages/safe-apps-provider/src/types.ts @@ -0,0 +1,47 @@ +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 { + 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 { + 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; +} 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" } }