-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
dapp: refactor web3 provider with new design
This commit does not add any new feature to the dApp, but refactors the design how the dApp gets an Ethereum connection and account to instantiate the SDK. This new approach has been developed to prepare the The new design introduces an abstract class which represents an Ethereum connection, holding the actual network/RPC provider and the account to use for signing. This abstract class gets them implemented by all the various connection methods the dApp provides. The intention is to have a nice and clean type system where the logic to instantiate the SDK and connect the dApp does not care about where the connection comes from, but just takes everything that implements this interface. Thereby the logic handling the connection process can be easily decoupled and stays static, no matter how many new connection methods get added or removed. Furthermore is must not care (not yet ready) about how the connections get configured. This allows the user to take interactively control over the configuration instead of a static file served by the web-server. After all, for the moment, the Home view component that handles the connection just gets a connection instance and passes its properties to the SDK. The selection and instantiation of the connection however is now done in the former components was well. This is the part that becomes replaced with the connection manager at a later point. Furthermore the does this approach improves the testability of the touched components. The connection process module is static and independently testable from the connection method. And each connection method can be tested individually. Mocking becomes (theoretically) easy. All by the bounding interface that tights everything together.
- Loading branch information
Showing
16 changed files
with
288 additions
and
149 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export default class WalletConnectProvider { | ||
enable = jest.fn().mockResolvedValue(true); | ||
on = jest.fn(); | ||
} |
13 changes: 13 additions & 0 deletions
13
raiden-dapp/src/services/ethereum-connection/__mocks__/direct-rpc-provider.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
export class DirectRpcProvider { | ||
public readonly account = 0; | ||
|
||
public static connect() { | ||
return new this(); | ||
} | ||
|
||
get provider() { | ||
return { | ||
getNetwork: jest.fn().mockResolvedValue({ chainId: 5 }), | ||
}; | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
raiden-dapp/src/services/ethereum-connection/direct-rpc-provider.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { providers } from 'ethers'; | ||
|
||
import { EthereumConnection } from './types'; | ||
|
||
export class DirectRpcProvider extends EthereumConnection { | ||
public static readonly connection_name = 'direct_rpc_provider'; | ||
public readonly provider: providers.JsonRpcProvider; | ||
public readonly account: string; | ||
|
||
private constructor(rpcUrl: string, privateKey: string) { | ||
super(); | ||
this.provider = new providers.JsonRpcProvider(rpcUrl); | ||
this.account = privateKey; | ||
} | ||
|
||
public static async connect(options: { | ||
rpcUrl: string; | ||
privateKey: string; | ||
}): Promise<DirectRpcProvider> { | ||
return new this(options.rpcUrl, options.privateKey); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export * from './direct-rpc-provider'; | ||
export * from './injected-provider'; | ||
export * from './types'; | ||
export * from './wallet-connect'; |
39 changes: 39 additions & 0 deletions
39
raiden-dapp/src/services/ethereum-connection/injected-provider.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { providers } from 'ethers'; | ||
|
||
import { EthereumConnection } from './types'; | ||
|
||
export class InjectedProvider extends EthereumConnection { | ||
public static readonly connection_name = 'injected_provider'; | ||
public readonly provider: providers.JsonRpcProvider; | ||
public readonly account = 0; // Refers to the currently selected account in the wallet. | ||
|
||
private constructor(injetedProvider: providers.ExternalProvider) { | ||
super(); | ||
this.provider = new providers.Web3Provider(injetedProvider); | ||
} | ||
|
||
public static async connect(): Promise<InjectedProvider> { | ||
if (!window.ethereum && !window.web3) { | ||
throw new Error('No injected provider is available.'); | ||
} | ||
|
||
let injectedProvider; | ||
|
||
if (window.ethereum) { | ||
window.ethereum.autoRefreshOnNetworkChange = false; | ||
await window.ethereum.request({ method: 'eth_requestAccounts' }); | ||
injectedProvider = window.ethereum; | ||
} else { | ||
injectedProvider = window.web3.currentProvider; | ||
} | ||
|
||
injectedProvider.on('chainChanged', resetHandler); | ||
injectedProvider.on('disconnect', resetHandler); | ||
|
||
return new this(injectedProvider); | ||
} | ||
} | ||
|
||
function resetHandler() { | ||
window.location.replace(window.location.origin); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import type { providers } from 'ethers'; | ||
|
||
export abstract class EthereumConnection { | ||
static connection_name: string; | ||
static connect: (options?: any) => Promise<EthereumConnection>; // eslint-disable-line @typescript-eslint/no-explicit-any | ||
abstract provider: providers.JsonRpcProvider; | ||
abstract account: string | number; | ||
} |
35 changes: 35 additions & 0 deletions
35
raiden-dapp/src/services/ethereum-connection/wallet-connect.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import WalletConnectProvider from '@walletconnect/web3-provider'; | ||
import { providers } from 'ethers'; | ||
|
||
import { EthereumConnection } from './types'; | ||
|
||
export class WalletConnect extends EthereumConnection { | ||
public static readonly connection_name = 'wallet_connect'; | ||
public readonly provider: providers.JsonRpcProvider; | ||
public readonly account = 0; // Refers to the currently selected account in the wallet. | ||
|
||
private constructor(walletConnectProvider: providers.ExternalProvider) { | ||
super(); | ||
this.provider = new providers.Web3Provider(walletConnectProvider); | ||
} | ||
|
||
public static async connect(options: { rpcUrl: string }): Promise<WalletConnect> { | ||
const temporaryJsonRpcProvider = new providers.JsonRpcProvider(options.rpcUrl); | ||
const networkOfProvider = await temporaryJsonRpcProvider.getNetwork(); | ||
const walletConnectProvider = new WalletConnectProvider({ | ||
rpc: { | ||
[networkOfProvider.chainId]: options.rpcUrl, | ||
}, | ||
}); | ||
|
||
await walletConnectProvider.enable(); | ||
walletConnectProvider.on('chainChanged', resetHandler); | ||
walletConnectProvider.on('disconnect', resetHandler); | ||
|
||
return new this(walletConnectProvider); | ||
} | ||
} | ||
|
||
function resetHandler() { | ||
window.location.replace(window.location.origin); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
raiden-dapp/tests/unit/services/ethereum-connection/direct-rpc-provider.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { DirectRpcProvider } from '@/services/ethereum-connection/direct-rpc-provider'; | ||
|
||
describe('DirectRpcProvider', () => { | ||
test('it can connect', async () => { | ||
const options = { rpcUrl: 'https://some.rpc.provider', privateKey: 'privateKey' }; | ||
const connection = await DirectRpcProvider.connect(options); | ||
|
||
expect(connection.provider.connection.url).toBe('https://some.rpc.provider'); | ||
expect(connection.account).toBe('privateKey'); | ||
}); | ||
}); |
Oops, something went wrong.