Skip to content

Commit

Permalink
Merge pull request #23 from etherspot/feature/wallet-connect-2.0
Browse files Browse the repository at this point in the history
Feature/wallet connect 2.0
  • Loading branch information
poocart authored Aug 31, 2023
2 parents 51d8d82 + 97d3120 commit dece48a
Show file tree
Hide file tree
Showing 8 changed files with 826 additions and 64 deletions.
786 changes: 728 additions & 58 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@etherspot/prime-sdk",
"version": "1.1.8",
"version": "1.2.0",
"description": "Etherspot Prime (Account Abstraction) SDK",
"keywords": [
"ether",
Expand Down Expand Up @@ -55,6 +55,7 @@
"@nerdwallet/apollo-cache-policies": "1.2.1",
"@thehubbleproject/bls": "0.5.1",
"apollo-link-ws": "^1.0.20",
"@walletconnect/universal-provider": "^2.10.0",
"axios": "1.3.4",
"class-transformer": "0.5.1",
"class-validator": "0.14.0",
Expand Down
17 changes: 13 additions & 4 deletions src/sdk/sdk.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { BehaviorSubject } from 'rxjs';
import { State, StateService } from './state';
import { isWalletProvider, WalletProviderLike } from './wallet';
import {
EthereumProvider,
isWalletConnectProvider,
isWalletProvider,
WalletConnect2WalletProvider,
WalletProviderLike
} from './wallet';
import { SdkOptions } from './interfaces';
import { Network } from "./network";
import { BatchUserOpsRequest, Exception, getGasFee, onRampApiKey, openUrl, UserOpsRequest } from "./common";
Expand Down Expand Up @@ -28,7 +34,10 @@ export class PrimeSdk {

constructor(walletProvider: WalletProviderLike, optionsLike: SdkOptions) {

if (!isWalletProvider(walletProvider)) {
let walletConnectProvider;
if (isWalletConnectProvider(walletProvider)) {
walletConnectProvider = new WalletConnect2WalletProvider(walletProvider as EthereumProvider);
} else if (!isWalletProvider(walletProvider)) {
throw new Exception('Invalid wallet provider');
}

Expand Down Expand Up @@ -60,7 +69,7 @@ export class PrimeSdk {

this.etherspotWallet = new EtherspotWalletAPI({
provider,
walletProvider,
walletProvider: walletConnectProvider ?? walletProvider,
optionsLike,
entryPointAddress: Networks[chainId].contracts.entryPoint,
factoryAddress: Networks[chainId].contracts.walletFactory,
Expand Down Expand Up @@ -256,7 +265,7 @@ export class PrimeSdk {
`${params.onlyFiats ? `&onlyFiats=${params.onlyFiats}` : ``}` +
`${params.excludeFiats ? `&excludeFiats=${params.excludeFiats}` : ``}` +
`&themeName=${params.themeName ?? 'dark'}`;

if (typeof window === 'undefined') {
openUrl(url);
} else {
Expand Down
1 change: 1 addition & 0 deletions src/sdk/wallet/providers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export * from './key.wallet-provider';
export * from './meta-mask.wallet-provider';
export * from './utils';
export * from './wallet-connect.wallet-provider';
export * from './wallet-connect-2.wallet-provider';
export * from './web3.wallet-provider';
export * from './web3eip1193.wallet-provider';
17 changes: 16 additions & 1 deletion src/sdk/wallet/providers/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BytesLike, Wallet } from 'ethers';
import type UniversalProvider from '@walletconnect/universal-provider';
import { UniqueSubject } from '../../common';
import { NetworkNames } from '../../network';

Expand Down Expand Up @@ -36,4 +37,18 @@ export interface WalletLike {
privateKey: string;
}

export type WalletProviderLike = string | WalletLike | WalletProvider;
export declare class EthereumProvider {
accounts: string[];
signer: InstanceType<typeof UniversalProvider>;
chainId: number;
request<T = unknown>(args: RequestArguments): Promise<T>;
sendAsync(args: RequestArguments, callback: (error: Error | null, response: any) => void): void;
disconnect(): Promise<void>;
on(event: string, callback: (error: Error | null, payload: any | null) => void): void;
once(event: string, callback: (error: Error | null, payload: any | null) => void): void;
removeListener(event: string, callback: (error: Error | null, payload: any | null) => void): void;
off(event: string, callback: (error: Error | null, payload: any | null) => void): void;
readonly isWalletConnect?: boolean;
}

export type WalletProviderLike = string | WalletLike | WalletProvider | EthereumProvider;
1 change: 1 addition & 0 deletions src/sdk/wallet/providers/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './is-wallet-provider';
export * from './is-wallet-connect-provider';
5 changes: 5 additions & 0 deletions src/sdk/wallet/providers/utils/is-wallet-connect-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { EthereumProvider, WalletProviderLike } from '../interfaces';

export function isWalletConnectProvider(provider: WalletProviderLike): boolean {
return typeof provider === 'object' && (provider as EthereumProvider)?.isWalletConnect;
}
60 changes: 60 additions & 0 deletions src/sdk/wallet/providers/wallet-connect-2.wallet-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { BytesLike } from 'ethers';
import { toHex } from '../../common';
import { DynamicWalletProvider } from './dynamic.wallet-provider';
import { EthereumProvider } from './interfaces';

export class WalletConnect2WalletProvider extends DynamicWalletProvider {
constructor(readonly provider: EthereumProvider) {
super('WalletConnect2');

try {
const {
accounts: [address],
chainId,
} = provider;

this.setAddress(address);
this.setNetworkName(chainId);
} catch (err) {
//
}

this.updateSessionHandler = this.updateSessionHandler.bind(this);

provider.on('connect', this.updateSessionHandler);
provider.on('session_event', this.updateSessionHandler);
provider.on('disconnect', () => {
this.setAddress(null);
this.setNetworkName(null);
});
}

async signMessage(message: BytesLike): Promise<string> {
const response = await this.provider.signer.request({
method: 'personal_sign',
params: [toHex(message), this.address],
});

return typeof response === 'string' ? response : null;
}

protected updateSessionHandler(error: Error, payload: { params: { accounts: string[]; chainId: number } }): void {
let address: string = null;
let chainId: number = null;

if (!error) {
try {
({
accounts: [address],
chainId,
} = payload.params[0]);
} catch (err) {
address = null;
chainId = null;
}
}

this.setAddress(address);
this.setNetworkName(chainId);
}
}

0 comments on commit dece48a

Please sign in to comment.