@dynamic-labs/ethereum 0.18.0-RC.7 → 0.18.0-RC.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/package.json +8 -7
- package/src/index.cjs +2 -2
- package/src/index.js +2 -2
- package/src/utils/isString.d.ts +1 -0
- package/src/utils/last.d.ts +1 -0
- package/src/utils/parseIntSafe.cjs +22 -0
- package/src/utils/parseIntSafe.d.ts +1 -0
- package/src/utils/parseIntSafe.js +18 -0
- package/src/walletConnect/client/client.cjs +2 -2
- package/src/walletConnect/client/client.d.ts +1 -1
- package/src/walletConnect/client/client.js +2 -2
- package/src/walletConnect/walletConnect.cjs +6 -2
- package/src/walletConnect/walletConnect.d.ts +3 -1
- package/src/walletConnect/walletConnect.js +6 -2
- package/src/walletConnect/walletConnectV2.cjs +164 -55
- package/src/walletConnect/walletConnectV2.d.ts +12 -1
- package/src/walletConnect/walletConnectV2.js +164 -56
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
|
|
2
|
+
## [0.18.0-RC.8](https://github.com/dynamic-labs/DynamicAuth/compare/v0.18.0-RC.7...v0.18.0-RC.8) (2023-06-29)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* add support for custom walletconnect v1 bridge ([#2487](https://github.com/dynamic-labs/DynamicAuth/issues/2487)) ([5b0ca2e](https://github.com/dynamic-labs/DynamicAuth/commit/5b0ca2e4e8aa241ed13e4f38346c31da8479a6c4))
|
|
8
|
+
* **DYN-2623:** improve error message on sign cancellation for wallets ([#2493](https://github.com/dynamic-labs/DynamicAuth/issues/2493)) ([081c515](https://github.com/dynamic-labs/DynamicAuth/commit/081c515c9d28d6fa4c0eaac388ee421a7b23144b))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* clearing the activeAccount value ([#2469](https://github.com/dynamic-labs/DynamicAuth/issues/2469)) ([ff75bde](https://github.com/dynamic-labs/DynamicAuth/commit/ff75bde938a4178541568b79754f773607b9d87f))
|
|
14
|
+
* don't initialize provider if it's already initialized ([#2490](https://github.com/dynamic-labs/DynamicAuth/issues/2490)) ([878d38f](https://github.com/dynamic-labs/DynamicAuth/commit/878d38f5c8d7d7448c65e58b25cefd9f3518217e))
|
|
15
|
+
* more wcv2 improvements ([#2475](https://github.com/dynamic-labs/DynamicAuth/issues/2475)) ([13baa84](https://github.com/dynamic-labs/DynamicAuth/commit/13baa84218d6259d02df7d8c387b40dc3cb11ce5)), closes [#2469](https://github.com/dynamic-labs/DynamicAuth/issues/2469) [#2470](https://github.com/dynamic-labs/DynamicAuth/issues/2470) [#2471](https://github.com/dynamic-labs/DynamicAuth/issues/2471) [#2477](https://github.com/dynamic-labs/DynamicAuth/issues/2477) [#2479](https://github.com/dynamic-labs/DynamicAuth/issues/2479) [#2471](https://github.com/dynamic-labs/DynamicAuth/issues/2471) [#2476](https://github.com/dynamic-labs/DynamicAuth/issues/2476)
|
|
16
|
+
* multiple improvements for WC2 ([#2458](https://github.com/dynamic-labs/DynamicAuth/issues/2458)) ([0813af2](https://github.com/dynamic-labs/DynamicAuth/commit/0813af2aafa8019868117084efe8ae147ac24581))
|
|
17
|
+
* revert changes since latest wcv2 improvements ([#2473](https://github.com/dynamic-labs/DynamicAuth/issues/2473)) ([3375371](https://github.com/dynamic-labs/DynamicAuth/commit/337537101a13d67b860748b62f172eba01d0b461)), closes [#2471](https://github.com/dynamic-labs/DynamicAuth/issues/2471) [#2470](https://github.com/dynamic-labs/DynamicAuth/issues/2470) [#2469](https://github.com/dynamic-labs/DynamicAuth/issues/2469)
|
|
18
|
+
* sync issue within connect-only mode ([#2496](https://github.com/dynamic-labs/DynamicAuth/issues/2496)) ([44af274](https://github.com/dynamic-labs/DynamicAuth/commit/44af274618c30fe65ec95739cd16a8ddde08e34e))
|
|
19
|
+
* typo in terms of service ([#2401](https://github.com/dynamic-labs/DynamicAuth/issues/2401)) ([5b195e5](https://github.com/dynamic-labs/DynamicAuth/commit/5b195e54479d9a88bd017fc45f2f2455d1caedc4))
|
|
20
|
+
* **wc_v1_bridget:** disable WC v2 when WC v1 bridge is set ([#2505](https://github.com/dynamic-labs/DynamicAuth/issues/2505)) ([b3f0a68](https://github.com/dynamic-labs/DynamicAuth/commit/b3f0a6895095bb37c635984fc970b52446e04f56))
|
|
21
|
+
* wc2 android improvements ([#2488](https://github.com/dynamic-labs/DynamicAuth/issues/2488)) ([f60ef9c](https://github.com/dynamic-labs/DynamicAuth/commit/f60ef9c1dd672f78199eee40edbe2707c043e1b5))
|
|
22
|
+
* **wcv2:** make sure to clear active account when ending session ([#2471](https://github.com/dynamic-labs/DynamicAuth/issues/2471)) ([b766df3](https://github.com/dynamic-labs/DynamicAuth/commit/b766df39a7e4dabc54fda9131b7bd9b53895cf2f))
|
|
23
|
+
* **wcv2:** use native or universal link when signing message ([#2502](https://github.com/dynamic-labs/DynamicAuth/issues/2502)) ([6e3e3fb](https://github.com/dynamic-labs/DynamicAuth/commit/6e3e3fbb58fb9e3eb314e6631ac2123237f41e8c))
|
|
24
|
+
|
|
2
25
|
## [0.18.0-RC.7](https://github.com/dynamic-labs/DynamicAuth/compare/v0.18.0-RC.6...v0.18.0-RC.7) (2023-06-23)
|
|
3
26
|
|
|
4
27
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs/ethereum",
|
|
3
|
-
"version": "0.18.0-RC.
|
|
3
|
+
"version": "0.18.0-RC.8",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/dynamic-labs/DynamicAuth.git",
|
|
@@ -28,14 +28,15 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@walletconnect/client": "1.8.0",
|
|
30
30
|
"@walletconnect/ethereum-provider": "1.8.0",
|
|
31
|
-
"@walletconnect/universal-provider": "2.8.
|
|
31
|
+
"@walletconnect/universal-provider": "2.8.3",
|
|
32
32
|
"ethers": "5.7.2",
|
|
33
|
+
"eventemitter3": "5.0.1",
|
|
33
34
|
"buffer": "6.0.3",
|
|
34
|
-
"@dynamic-labs/rpc-providers": "0.18.0-RC.
|
|
35
|
-
"@dynamic-labs/types": "0.18.0-RC.
|
|
36
|
-
"@dynamic-labs/utils": "0.18.0-RC.
|
|
37
|
-
"@dynamic-labs/wallet-book": "0.18.0-RC.
|
|
38
|
-
"@dynamic-labs/wallet-connector-core": "0.18.0-RC.
|
|
35
|
+
"@dynamic-labs/rpc-providers": "0.18.0-RC.8",
|
|
36
|
+
"@dynamic-labs/types": "0.18.0-RC.8",
|
|
37
|
+
"@dynamic-labs/utils": "0.18.0-RC.8",
|
|
38
|
+
"@dynamic-labs/wallet-book": "0.18.0-RC.8",
|
|
39
|
+
"@dynamic-labs/wallet-connector-core": "0.18.0-RC.8"
|
|
39
40
|
},
|
|
40
41
|
"peerDependencies": {}
|
|
41
42
|
}
|
package/src/index.cjs
CHANGED
|
@@ -4,13 +4,13 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
require('./polyfills.cjs');
|
|
6
6
|
var index = require('./injected/index.cjs');
|
|
7
|
-
require('
|
|
7
|
+
require('./walletConnect/walletConnectV2.cjs');
|
|
8
|
+
require('@walletconnect/ethereum-provider');
|
|
8
9
|
require('ethers');
|
|
9
10
|
require('@dynamic-labs/wallet-connector-core');
|
|
10
11
|
require('@dynamic-labs/wallet-book');
|
|
11
12
|
require('@dynamic-labs/utils');
|
|
12
13
|
var EthWalletConnector = require('./EthWalletConnector.cjs');
|
|
13
|
-
require('@walletconnect/ethereum-provider');
|
|
14
14
|
var constants = require('./constants.cjs');
|
|
15
15
|
require('@walletconnect/client');
|
|
16
16
|
var fetchWalletConnectWallets = require('./walletConnect/fetchWalletConnectWallets.cjs');
|
package/src/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import './polyfills.js';
|
|
2
2
|
import { injectedWallets } from './injected/index.js';
|
|
3
3
|
export { injectedWallets } from './injected/index.js';
|
|
4
|
-
import '
|
|
4
|
+
import './walletConnect/walletConnectV2.js';
|
|
5
|
+
import '@walletconnect/ethereum-provider';
|
|
5
6
|
import 'ethers';
|
|
6
7
|
import '@dynamic-labs/wallet-connector-core';
|
|
7
8
|
import '@dynamic-labs/wallet-book';
|
|
8
9
|
import '@dynamic-labs/utils';
|
|
9
10
|
export { EthWalletConnector } from './EthWalletConnector.js';
|
|
10
|
-
import '@walletconnect/ethereum-provider';
|
|
11
11
|
export { INFURA_ID } from './constants.js';
|
|
12
12
|
import '@walletconnect/client';
|
|
13
13
|
import { fetchWalletConnectWallets, getWalletConnectConnector } from './walletConnect/fetchWalletConnectWallets.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const isString: (value: unknown) => value is string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const last: <T = unknown>(array: T[]) => T | undefined;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
|
|
6
|
+
|
|
7
|
+
const parseIntSafe = (value, radix = 10) => {
|
|
8
|
+
try {
|
|
9
|
+
const int = parseInt(String(value), radix);
|
|
10
|
+
if (isNaN(int)) {
|
|
11
|
+
walletConnectorCore.logger.error(`Error parsing ${value}`);
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
return int;
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
walletConnectorCore.logger.error(`Error parsing ${value} to int: ${e}`);
|
|
18
|
+
}
|
|
19
|
+
return undefined;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
exports.parseIntSafe = parseIntSafe;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const parseIntSafe: (value: string | number, radix?: number) => number | undefined;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { logger } from '@dynamic-labs/wallet-connector-core';
|
|
2
|
+
|
|
3
|
+
const parseIntSafe = (value, radix = 10) => {
|
|
4
|
+
try {
|
|
5
|
+
const int = parseInt(String(value), radix);
|
|
6
|
+
if (isNaN(int)) {
|
|
7
|
+
logger.error(`Error parsing ${value}`);
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
return int;
|
|
11
|
+
}
|
|
12
|
+
catch (e) {
|
|
13
|
+
logger.error(`Error parsing ${value} to int: ${e}`);
|
|
14
|
+
}
|
|
15
|
+
return undefined;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export { parseIntSafe };
|
|
@@ -12,12 +12,12 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
|
|
|
12
12
|
|
|
13
13
|
var Client__default = /*#__PURE__*/_interopDefaultLegacy(Client);
|
|
14
14
|
|
|
15
|
-
const initClient = (name, settings) => {
|
|
15
|
+
const initClient = (name, bridge, settings) => {
|
|
16
16
|
const storageId = `walletconnect-${name}`;
|
|
17
17
|
const session = localStorage.getItem(storageId);
|
|
18
18
|
const clientArgs = session
|
|
19
19
|
? { session: JSON.parse(session), storageId }
|
|
20
|
-
: { bridge
|
|
20
|
+
: { bridge, storageId };
|
|
21
21
|
return new Client__default["default"](Object.assign(Object.assign({}, clientArgs), settings));
|
|
22
22
|
};
|
|
23
23
|
/**
|
|
@@ -2,7 +2,7 @@ import Client from '@walletconnect/client';
|
|
|
2
2
|
import { ethers } from 'ethers';
|
|
3
3
|
import { FetchPublicAddressOpts, PayloadParams, WalletEventListeners } from '@dynamic-labs/wallet-connector-core';
|
|
4
4
|
import { WalletSchema } from '@dynamic-labs/wallet-book';
|
|
5
|
-
export declare const initClient: (name: string, settings?: any) => Client;
|
|
5
|
+
export declare const initClient: (name: string, bridge: string, settings?: any) => Client;
|
|
6
6
|
/**
|
|
7
7
|
* Attach event handlers to WalletConnect events.
|
|
8
8
|
*/
|
|
@@ -4,12 +4,12 @@ import { Contract, ethers } from 'ethers';
|
|
|
4
4
|
import { isSameAddress, logger, performPlatformSpecificConnectionMethod, getDeepLink } from '@dynamic-labs/wallet-connector-core';
|
|
5
5
|
import { isMobile } from '@dynamic-labs/utils';
|
|
6
6
|
|
|
7
|
-
const initClient = (name, settings) => {
|
|
7
|
+
const initClient = (name, bridge, settings) => {
|
|
8
8
|
const storageId = `walletconnect-${name}`;
|
|
9
9
|
const session = localStorage.getItem(storageId);
|
|
10
10
|
const clientArgs = session
|
|
11
11
|
? { session: JSON.parse(session), storageId }
|
|
12
|
-
: { bridge
|
|
12
|
+
: { bridge, storageId };
|
|
13
13
|
return new Client(Object.assign(Object.assign({}, clientArgs), settings));
|
|
14
14
|
};
|
|
15
15
|
/**
|
|
@@ -18,20 +18,24 @@ var WalletConnectProvider__default = /*#__PURE__*/_interopDefaultLegacy(WalletCo
|
|
|
18
18
|
|
|
19
19
|
class WalletConnect extends EthWalletConnector.EthWalletConnector {
|
|
20
20
|
constructor(_a) {
|
|
21
|
-
var { walletName } = _a, props = _tslib.__rest(_a, ["walletName"]);
|
|
21
|
+
var { walletConnectV1Bridge, walletName } = _a, props = _tslib.__rest(_a, ["walletConnectV1Bridge", "walletName"]);
|
|
22
22
|
super(props);
|
|
23
23
|
this.supportedChains = ['EVM', 'ETH'];
|
|
24
24
|
this.connectedChain = 'EVM';
|
|
25
|
+
this.bridge = 'https://bridge.walletconnect.org';
|
|
25
26
|
this.canConnectViaQrCode = true;
|
|
26
27
|
this.isWalletConnect = true;
|
|
27
28
|
this.switchNetworkOnlyFromWallet = false;
|
|
28
29
|
this.name = walletName;
|
|
30
|
+
if (walletConnectV1Bridge) {
|
|
31
|
+
this.bridge = walletConnectV1Bridge;
|
|
32
|
+
}
|
|
29
33
|
}
|
|
30
34
|
getClient() {
|
|
31
35
|
if (this.client) {
|
|
32
36
|
return this.client;
|
|
33
37
|
}
|
|
34
|
-
this.client = client.initClient(walletConnectorCore.normalizeWalletName(this.name), this.clientOptions);
|
|
38
|
+
this.client = client.initClient(walletConnectorCore.normalizeWalletName(this.name), this.bridge, this.clientOptions);
|
|
35
39
|
return this.client;
|
|
36
40
|
}
|
|
37
41
|
supportsNetworkSwitching() {
|
|
@@ -4,18 +4,20 @@ import { Chain, FetchPublicAddressOpts, WalletEventListeners } from '@dynamic-la
|
|
|
4
4
|
import { EvmNetwork } from '@dynamic-labs/types';
|
|
5
5
|
import { EthWalletConnector, EthWalletConnectorOpts } from '../EthWalletConnector';
|
|
6
6
|
export type WalletConnectOpts = EthWalletConnectorOpts & {
|
|
7
|
+
walletConnectV1Bridge: string;
|
|
7
8
|
walletName: string;
|
|
8
9
|
};
|
|
9
10
|
export declare class WalletConnect extends EthWalletConnector {
|
|
10
11
|
supportedChains: Chain[];
|
|
11
12
|
connectedChain: Chain;
|
|
12
13
|
name: string;
|
|
14
|
+
bridge: string;
|
|
13
15
|
canConnectViaQrCode: boolean;
|
|
14
16
|
isWalletConnect: boolean;
|
|
15
17
|
switchNetworkOnlyFromWallet: boolean;
|
|
16
18
|
client?: Client;
|
|
17
19
|
clientOptions?: any;
|
|
18
|
-
constructor({ walletName, ...props }: WalletConnectOpts);
|
|
20
|
+
constructor({ walletConnectV1Bridge, walletName, ...props }: WalletConnectOpts);
|
|
19
21
|
getClient(): Client;
|
|
20
22
|
supportsNetworkSwitching(): boolean;
|
|
21
23
|
setupEventListeners(listeners: WalletEventListeners): void;
|
|
@@ -10,20 +10,24 @@ import { initClient, setupWalletConnectEventListeners, teardownWalletConnectEven
|
|
|
10
10
|
|
|
11
11
|
class WalletConnect extends EthWalletConnector {
|
|
12
12
|
constructor(_a) {
|
|
13
|
-
var { walletName } = _a, props = __rest(_a, ["walletName"]);
|
|
13
|
+
var { walletConnectV1Bridge, walletName } = _a, props = __rest(_a, ["walletConnectV1Bridge", "walletName"]);
|
|
14
14
|
super(props);
|
|
15
15
|
this.supportedChains = ['EVM', 'ETH'];
|
|
16
16
|
this.connectedChain = 'EVM';
|
|
17
|
+
this.bridge = 'https://bridge.walletconnect.org';
|
|
17
18
|
this.canConnectViaQrCode = true;
|
|
18
19
|
this.isWalletConnect = true;
|
|
19
20
|
this.switchNetworkOnlyFromWallet = false;
|
|
20
21
|
this.name = walletName;
|
|
22
|
+
if (walletConnectV1Bridge) {
|
|
23
|
+
this.bridge = walletConnectV1Bridge;
|
|
24
|
+
}
|
|
21
25
|
}
|
|
22
26
|
getClient() {
|
|
23
27
|
if (this.client) {
|
|
24
28
|
return this.client;
|
|
25
29
|
}
|
|
26
|
-
this.client = initClient(normalizeWalletName(this.name), this.clientOptions);
|
|
30
|
+
this.client = initClient(normalizeWalletName(this.name), this.bridge, this.clientOptions);
|
|
27
31
|
return this.client;
|
|
28
32
|
}
|
|
29
33
|
supportsNetworkSwitching() {
|
|
@@ -5,21 +5,27 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var _tslib = require('../../_virtual/_tslib.cjs');
|
|
6
6
|
var Provider = require('@walletconnect/universal-provider');
|
|
7
7
|
var ethers = require('ethers');
|
|
8
|
+
var EventEmitter = require('eventemitter3');
|
|
8
9
|
var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
|
|
9
10
|
var walletBook = require('@dynamic-labs/wallet-book');
|
|
10
11
|
var utils = require('@dynamic-labs/utils');
|
|
11
12
|
var EthWalletConnector = require('../EthWalletConnector.cjs');
|
|
13
|
+
var parseIntSafe = require('../utils/parseIntSafe.cjs');
|
|
12
14
|
|
|
13
15
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
14
16
|
|
|
15
17
|
var Provider__default = /*#__PURE__*/_interopDefaultLegacy(Provider);
|
|
18
|
+
var EventEmitter__default = /*#__PURE__*/_interopDefaultLegacy(EventEmitter);
|
|
16
19
|
|
|
20
|
+
const activeAccountKey = (walletName) => `dynamic-wc2-active-account-${walletName}`;
|
|
17
21
|
const sessionTopicKey = (walletName) => `dynamic-wc2-session-topic-${walletName}`;
|
|
22
|
+
const ee = new EventEmitter__default["default"]();
|
|
18
23
|
class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
|
|
19
24
|
constructor(opts) {
|
|
20
25
|
super(opts);
|
|
21
26
|
this.supportedChains = ['EVM', 'ETH'];
|
|
22
27
|
this.connectedChain = 'EVM';
|
|
28
|
+
this.isInitialized = false;
|
|
23
29
|
this.canConnectViaQrCode = true;
|
|
24
30
|
this.isWalletConnect = true;
|
|
25
31
|
this.name = opts.walletName;
|
|
@@ -35,44 +41,69 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
|
|
|
35
41
|
if (provider === null || provider === void 0 ? void 0 : provider.uri) {
|
|
36
42
|
return;
|
|
37
43
|
}
|
|
38
|
-
|
|
44
|
+
const defaultChain = 1;
|
|
45
|
+
provider
|
|
46
|
+
.connect({
|
|
39
47
|
namespaces: {
|
|
48
|
+
eip155: {
|
|
49
|
+
chains: [`eip155:${defaultChain}`],
|
|
50
|
+
events: ['chainChanged', 'accountsChanged'],
|
|
51
|
+
methods: ['personal_sign', 'eth_sendTransaction'],
|
|
52
|
+
rpcMap: this.evmNetworkRpcMap(),
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
optionalNamespaces: {
|
|
40
56
|
eip155: {
|
|
41
57
|
chains: this.evmNetworks
|
|
42
|
-
//
|
|
43
|
-
.filter((network) => network.chainId !== 11297108109
|
|
58
|
+
// Filters out mainnet which is required and palm that crashes Trust Wallet
|
|
59
|
+
.filter((network) => network.chainId !== 11297108109 &&
|
|
60
|
+
network.chainId !== defaultChain)
|
|
44
61
|
.map((network) => `eip155:${network.chainId}`),
|
|
45
|
-
events: [
|
|
62
|
+
events: [],
|
|
46
63
|
methods: [
|
|
47
|
-
'
|
|
64
|
+
'eth_signTypedData',
|
|
48
65
|
'eth_signTransaction',
|
|
49
66
|
'eth_sign',
|
|
50
67
|
'personal_sign',
|
|
51
|
-
'
|
|
68
|
+
'eth_sendTransaction',
|
|
52
69
|
],
|
|
53
70
|
rpcMap: this.evmNetworkRpcMap(),
|
|
54
71
|
},
|
|
55
72
|
},
|
|
73
|
+
})
|
|
74
|
+
.catch((e) => {
|
|
75
|
+
walletConnectorCore.logger.error(e);
|
|
76
|
+
ee.emit('walletconnect_connection_failed');
|
|
56
77
|
});
|
|
57
78
|
});
|
|
58
79
|
}
|
|
80
|
+
createInitProviderPromise() {
|
|
81
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
82
|
+
const provider = yield Provider__default["default"].init({
|
|
83
|
+
projectId: this.projectId,
|
|
84
|
+
});
|
|
85
|
+
WalletConnectV2.provider = provider;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
59
88
|
initProvider() {
|
|
60
89
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
61
|
-
|
|
90
|
+
const { provider } = WalletConnectV2;
|
|
62
91
|
if (!provider) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
92
|
+
if (this.initializePromise === undefined) {
|
|
93
|
+
this.initializePromise = this.createInitProviderPromise();
|
|
94
|
+
}
|
|
95
|
+
yield this.initializePromise;
|
|
67
96
|
}
|
|
68
97
|
});
|
|
69
98
|
}
|
|
70
99
|
refreshSession() {
|
|
71
|
-
var _a, _b, _c, _d;
|
|
100
|
+
var _a, _b, _c, _d, _e;
|
|
72
101
|
if ((_b = (_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.session) === null || _b === void 0 ? void 0 : _b.topic) {
|
|
73
102
|
if (localStorage.getItem(this.sessionTopicKey) ===
|
|
74
103
|
((_d = (_c = WalletConnectV2.provider) === null || _c === void 0 ? void 0 : _c.session) === null || _d === void 0 ? void 0 : _d.topic)) {
|
|
75
104
|
this.session = WalletConnectV2.provider.session;
|
|
105
|
+
this.activeAccount =
|
|
106
|
+
(_e = localStorage.getItem(this.activeAccountKey)) !== null && _e !== void 0 ? _e : undefined;
|
|
76
107
|
}
|
|
77
108
|
}
|
|
78
109
|
}
|
|
@@ -80,11 +111,15 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
|
|
|
80
111
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
81
112
|
yield this.initProvider();
|
|
82
113
|
yield this.initConnection();
|
|
114
|
+
this.isInitialized = true;
|
|
83
115
|
});
|
|
84
116
|
}
|
|
85
117
|
get sessionTopicKey() {
|
|
86
118
|
return sessionTopicKey(this.key);
|
|
87
119
|
}
|
|
120
|
+
get activeAccountKey() {
|
|
121
|
+
return activeAccountKey(this.key);
|
|
122
|
+
}
|
|
88
123
|
supportsNetworkSwitching() {
|
|
89
124
|
return true;
|
|
90
125
|
}
|
|
@@ -100,23 +135,27 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
|
|
|
100
135
|
}
|
|
101
136
|
const { name, data } = params.event;
|
|
102
137
|
if (name === 'chainChanged') {
|
|
103
|
-
|
|
138
|
+
const chainId = parseIntSafe.parseIntSafe(data);
|
|
139
|
+
if (chainId === undefined) {
|
|
104
140
|
walletConnectorCore.logger.debug(`received unexpected data for chainChanged: ${data} with type ${typeof data}}`);
|
|
105
141
|
return;
|
|
106
142
|
}
|
|
107
|
-
(_a = listeners.onChainChange) === null || _a === void 0 ? void 0 : _a.call(listeners,
|
|
143
|
+
(_a = listeners.onChainChange) === null || _a === void 0 ? void 0 : _a.call(listeners, String(chainId));
|
|
108
144
|
}
|
|
109
145
|
else if (name === 'accountsChanged') {
|
|
110
|
-
if (
|
|
146
|
+
if (!Array.isArray(data)) {
|
|
111
147
|
walletConnectorCore.logger.debug(`received unexpected data for accountsChanged: ${data} with type ${typeof data}}`);
|
|
112
148
|
return;
|
|
113
149
|
}
|
|
114
|
-
|
|
150
|
+
// eslint-disable-next-line prefer-destructuring
|
|
151
|
+
const account = data[0].split(':')[2];
|
|
152
|
+
this.setActiveAccount(account);
|
|
153
|
+
(_b = listeners.onAccountChange) === null || _b === void 0 ? void 0 : _b.call(listeners, [account]);
|
|
115
154
|
}
|
|
116
155
|
});
|
|
117
156
|
WalletConnectV2.provider.client.on('session_delete', () => _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
118
157
|
var _a;
|
|
119
|
-
|
|
158
|
+
this.endSession();
|
|
120
159
|
yield ((_a = listeners.onDisconnect) === null || _a === void 0 ? void 0 : _a.call(listeners));
|
|
121
160
|
}));
|
|
122
161
|
}
|
|
@@ -127,20 +166,6 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
|
|
|
127
166
|
WalletConnectV2.provider.client.removeAllListeners('session_event');
|
|
128
167
|
WalletConnectV2.provider.client.removeAllListeners('session_delete');
|
|
129
168
|
}
|
|
130
|
-
getDeepLink() {
|
|
131
|
-
var _a, _b;
|
|
132
|
-
if (!((_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.uri))
|
|
133
|
-
return;
|
|
134
|
-
const wallet = walletBook.getWalletBookWallet(this.walletBook, this.name);
|
|
135
|
-
if (!utils.isMobile() && !((_b = wallet.desktop) === null || _b === void 0 ? void 0 : _b.native)) {
|
|
136
|
-
return undefined;
|
|
137
|
-
}
|
|
138
|
-
return walletConnectorCore.getDeepLink({
|
|
139
|
-
metadata: wallet,
|
|
140
|
-
mode: 'regular',
|
|
141
|
-
uri: WalletConnectV2.provider.uri,
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
169
|
getWeb3Provider() {
|
|
145
170
|
if (!WalletConnectV2.provider) {
|
|
146
171
|
throw new Error('No provider found');
|
|
@@ -148,15 +173,25 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
|
|
|
148
173
|
return new ethers.ethers.providers.Web3Provider(WalletConnectV2.provider, 'any');
|
|
149
174
|
}
|
|
150
175
|
fetchPublicAddress(opts) {
|
|
176
|
+
var _a, _b;
|
|
151
177
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
152
|
-
if (this.
|
|
153
|
-
return this.
|
|
154
|
-
}
|
|
155
|
-
if (!WalletConnectV2.provider) {
|
|
156
|
-
throw new utils.DynamicError('No provider found');
|
|
178
|
+
if (this.activeAccount) {
|
|
179
|
+
return this.activeAccount;
|
|
157
180
|
}
|
|
158
|
-
if (!WalletConnectV2.provider.uri) {
|
|
159
|
-
|
|
181
|
+
if (!WalletConnectV2.provider || !((_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.uri)) {
|
|
182
|
+
walletConnectorCore.logger.debug('No WC2 provider found, re-initializing...');
|
|
183
|
+
yield this.endSession();
|
|
184
|
+
yield this.init();
|
|
185
|
+
// sleep 1 s to wait for connect call to finish
|
|
186
|
+
// the connect call isn't await-ed because it only resolves once
|
|
187
|
+
// the connection is established, but we need to wait for it to
|
|
188
|
+
// finish setting up the connection URI and making it available
|
|
189
|
+
// on the provider
|
|
190
|
+
yield new Promise((resolve) => setTimeout(resolve, 1000));
|
|
191
|
+
if (!WalletConnectV2.provider || !((_b = WalletConnectV2.provider) === null || _b === void 0 ? void 0 : _b.uri)) {
|
|
192
|
+
walletConnectorCore.logger.debug('No WC2 provider found, escaping and throwing error');
|
|
193
|
+
throw new utils.DynamicError('No provider found');
|
|
194
|
+
}
|
|
160
195
|
}
|
|
161
196
|
const metadata = walletBook.getWalletBookWallet(this.walletBook, this.name);
|
|
162
197
|
walletConnectorCore.performPlatformSpecificConnectionMethod(WalletConnectV2.provider.uri, metadata, {
|
|
@@ -168,18 +203,27 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
|
|
|
168
203
|
reject(new utils.DynamicError('No provider found'));
|
|
169
204
|
return;
|
|
170
205
|
}
|
|
206
|
+
ee.on('walletconnect_connection_failed', () => {
|
|
207
|
+
const error = new utils.DynamicError('Connection rejected. Please try again.');
|
|
208
|
+
error.code = 'connection_rejected';
|
|
209
|
+
if (WalletConnectV2.provider) {
|
|
210
|
+
WalletConnectV2.provider.uri = undefined;
|
|
211
|
+
}
|
|
212
|
+
reject(error);
|
|
213
|
+
});
|
|
171
214
|
WalletConnectV2.provider.on('connect', ({ session }) => {
|
|
172
215
|
if (!session) {
|
|
173
216
|
reject(new utils.DynamicError('No session found'));
|
|
174
217
|
}
|
|
175
|
-
this.session
|
|
176
|
-
|
|
177
|
-
resolve(this.
|
|
218
|
+
this.setSession(session);
|
|
219
|
+
this.setActiveAccount(session.namespaces.eip155.accounts[0].split(':')[2]);
|
|
220
|
+
resolve(this.activeAccount);
|
|
178
221
|
});
|
|
179
222
|
});
|
|
180
223
|
});
|
|
181
224
|
}
|
|
182
225
|
signMessage(messageToSign) {
|
|
226
|
+
var _a, _b;
|
|
183
227
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
184
228
|
if (!this.session) {
|
|
185
229
|
throw new utils.DynamicError('no session');
|
|
@@ -189,39 +233,72 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
|
|
|
189
233
|
}
|
|
190
234
|
const metadata = walletBook.getWalletBookWallet(this.walletBook, this.name);
|
|
191
235
|
if (utils.isMobile()) {
|
|
192
|
-
|
|
193
|
-
// and at this point we are already connected
|
|
194
|
-
const deepLink = walletConnectorCore.getDeepLink({ metadata, mode: 'regular' });
|
|
236
|
+
const deepLink = ((_a = metadata['mobile']) === null || _a === void 0 ? void 0 : _a.native) || ((_b = metadata['mobile']) === null || _b === void 0 ? void 0 : _b.universal) || '';
|
|
195
237
|
window.location.href = deepLink;
|
|
196
238
|
}
|
|
197
|
-
// eslint-disable-next-line prefer-destructuring
|
|
198
|
-
const address = this.session.namespaces.eip155.accounts[0].split(':')[2];
|
|
199
239
|
const web3Provider = this.getWeb3Provider();
|
|
200
|
-
|
|
240
|
+
const response = web3Provider.send('personal_sign', [
|
|
201
241
|
walletConnectorCore.utf8ToHex(messageToSign, true),
|
|
202
|
-
|
|
242
|
+
this.activeAccount,
|
|
203
243
|
]);
|
|
244
|
+
try {
|
|
245
|
+
// A terrible hack to get MM to sign the message when it is on the wrong chain
|
|
246
|
+
// Since MM supports only one chain at a time, it just hangs when we call
|
|
247
|
+
// to sign, and it is not on Mainnet. For some magical reason,
|
|
248
|
+
// when we attempt to call again it just works.
|
|
249
|
+
if (this.key === 'metamask') {
|
|
250
|
+
yield this.promiseWithTimeout(7000, response);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
catch (e) {
|
|
254
|
+
walletConnectorCore.logger.debug('metmask failed to sign message');
|
|
255
|
+
throw e;
|
|
256
|
+
}
|
|
257
|
+
return response;
|
|
204
258
|
});
|
|
205
259
|
}
|
|
260
|
+
clearActiveAccount() {
|
|
261
|
+
localStorage.removeItem(this.activeAccountKey);
|
|
262
|
+
this.activeAccount = undefined;
|
|
263
|
+
}
|
|
264
|
+
clearSession() {
|
|
265
|
+
localStorage.removeItem(this.sessionTopicKey);
|
|
266
|
+
this.session = undefined;
|
|
267
|
+
}
|
|
268
|
+
setActiveAccount(account) {
|
|
269
|
+
localStorage.setItem(this.activeAccountKey, account);
|
|
270
|
+
this.activeAccount = account;
|
|
271
|
+
}
|
|
272
|
+
setSession(session) {
|
|
273
|
+
localStorage.setItem(this.sessionTopicKey, session.topic);
|
|
274
|
+
this.session = session;
|
|
275
|
+
}
|
|
206
276
|
endSession() {
|
|
277
|
+
var _a;
|
|
207
278
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
if (!WalletConnectV2.provider) {
|
|
279
|
+
this.clearActiveAccount();
|
|
280
|
+
this.clearSession();
|
|
281
|
+
if (!((_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.session)) {
|
|
212
282
|
return;
|
|
213
283
|
}
|
|
214
284
|
try {
|
|
215
285
|
yield WalletConnectV2.provider.disconnect();
|
|
216
286
|
WalletConnectV2.provider.uri = undefined;
|
|
217
|
-
localStorage.removeItem(this.sessionTopicKey);
|
|
218
|
-
this.session = undefined;
|
|
219
287
|
}
|
|
220
288
|
catch (e) {
|
|
221
289
|
walletConnectorCore.logger.debug(e);
|
|
222
290
|
}
|
|
223
291
|
});
|
|
224
292
|
}
|
|
293
|
+
getNetwork() {
|
|
294
|
+
const _super = Object.create(null, {
|
|
295
|
+
getNetwork: { get: () => super.getNetwork }
|
|
296
|
+
});
|
|
297
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
298
|
+
yield this.initProvider();
|
|
299
|
+
return _super.getNetwork.call(this);
|
|
300
|
+
});
|
|
301
|
+
}
|
|
225
302
|
providerSwitchNetwork({ network, provider, }) {
|
|
226
303
|
const _super = Object.create(null, {
|
|
227
304
|
providerSwitchNetwork: { get: () => super.providerSwitchNetwork }
|
|
@@ -244,14 +321,46 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
|
|
|
244
321
|
});
|
|
245
322
|
}
|
|
246
323
|
getConnectedAccounts() {
|
|
324
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
325
|
+
yield this.initProvider();
|
|
326
|
+
this.refreshSession();
|
|
327
|
+
this.isInitialized = true;
|
|
328
|
+
if (!this.activeAccount) {
|
|
329
|
+
return [];
|
|
330
|
+
}
|
|
331
|
+
return [this.activeAccount];
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
getSupportedNetworks() {
|
|
247
335
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
248
336
|
yield this.initProvider();
|
|
249
337
|
this.refreshSession();
|
|
250
338
|
if (!this.session) {
|
|
251
339
|
return [];
|
|
252
340
|
}
|
|
253
|
-
|
|
341
|
+
const chains = [];
|
|
342
|
+
// Some wallet (i.e ZenGo) use namespaces.account to list supported chains
|
|
343
|
+
// while others use keys within the namespaces object
|
|
344
|
+
Object.keys(this.session.namespaces).forEach((key) => {
|
|
345
|
+
if (key.startsWith('eip155:')) {
|
|
346
|
+
chains.push(key.split(':')[1]);
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
this.session.namespaces.eip155.accounts.forEach((account) => chains.push(account.split(':')[1]));
|
|
350
|
+
return chains.length ? chains : undefined;
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
// a HACK for MM to sign message when the selected chain is not mainnet
|
|
354
|
+
promiseWithTimeout(ms, promise) {
|
|
355
|
+
// Create a promise that rejects in <ms> milliseconds
|
|
356
|
+
const timeout = new Promise((_, reject) => {
|
|
357
|
+
const id = setTimeout(() => {
|
|
358
|
+
clearTimeout(id);
|
|
359
|
+
reject(new utils.DynamicError(undefined, 'metamask_timeout'));
|
|
360
|
+
}, ms);
|
|
254
361
|
});
|
|
362
|
+
// Returns a race between our timeout and the passed in promise
|
|
363
|
+
return Promise.race([promise, timeout]);
|
|
255
364
|
}
|
|
256
365
|
}
|
|
257
366
|
|
|
@@ -12,27 +12,38 @@ export declare class WalletConnectV2 extends EthWalletConnector {
|
|
|
12
12
|
connectedChain: Chain;
|
|
13
13
|
name: string;
|
|
14
14
|
session: SessionTypes.Struct | undefined;
|
|
15
|
+
activeAccount: string | undefined;
|
|
16
|
+
isInitialized: boolean;
|
|
17
|
+
initializePromise: Promise<void> | undefined;
|
|
15
18
|
canConnectViaQrCode: boolean;
|
|
16
19
|
isWalletConnect: boolean;
|
|
17
20
|
private static provider;
|
|
18
21
|
private projectId?;
|
|
19
22
|
constructor(opts: WalletConnectorV2Opts);
|
|
20
23
|
private initConnection;
|
|
24
|
+
private createInitProviderPromise;
|
|
21
25
|
private initProvider;
|
|
22
26
|
private refreshSession;
|
|
23
27
|
init(): Promise<void>;
|
|
24
28
|
get sessionTopicKey(): string;
|
|
29
|
+
get activeAccountKey(): string;
|
|
25
30
|
supportsNetworkSwitching(): boolean;
|
|
26
31
|
setupEventListeners(listeners: WalletEventListeners): void;
|
|
27
32
|
teardownEventListeners(): void;
|
|
28
|
-
getDeepLink(): string | undefined;
|
|
29
33
|
getWeb3Provider(): ethers.providers.Web3Provider;
|
|
30
34
|
fetchPublicAddress(opts?: FetchPublicAddressOpts): Promise<string | undefined>;
|
|
31
35
|
signMessage(messageToSign: string): Promise<string | undefined>;
|
|
36
|
+
private clearActiveAccount;
|
|
37
|
+
private clearSession;
|
|
38
|
+
private setActiveAccount;
|
|
39
|
+
private setSession;
|
|
32
40
|
endSession(): Promise<void>;
|
|
41
|
+
getNetwork(): Promise<number | undefined>;
|
|
33
42
|
providerSwitchNetwork({ network, provider, }: {
|
|
34
43
|
network: EvmNetwork;
|
|
35
44
|
provider: ethers.providers.Web3Provider;
|
|
36
45
|
}): Promise<void>;
|
|
37
46
|
getConnectedAccounts(): Promise<string[]>;
|
|
47
|
+
getSupportedNetworks(): Promise<string[] | undefined>;
|
|
48
|
+
private promiseWithTimeout;
|
|
38
49
|
}
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import { __awaiter } from '../../_virtual/_tslib.js';
|
|
2
2
|
import Provider from '@walletconnect/universal-provider';
|
|
3
3
|
import { ethers } from 'ethers';
|
|
4
|
-
import
|
|
4
|
+
import EventEmitter from 'eventemitter3';
|
|
5
|
+
import { logger, performPlatformSpecificConnectionMethod, utf8ToHex } from '@dynamic-labs/wallet-connector-core';
|
|
5
6
|
import { getWalletBookWallet } from '@dynamic-labs/wallet-book';
|
|
6
7
|
import { DynamicError, isMobile } from '@dynamic-labs/utils';
|
|
7
8
|
import { EthWalletConnector } from '../EthWalletConnector.js';
|
|
9
|
+
import { parseIntSafe } from '../utils/parseIntSafe.js';
|
|
8
10
|
|
|
11
|
+
const activeAccountKey = (walletName) => `dynamic-wc2-active-account-${walletName}`;
|
|
9
12
|
const sessionTopicKey = (walletName) => `dynamic-wc2-session-topic-${walletName}`;
|
|
13
|
+
const ee = new EventEmitter();
|
|
10
14
|
class WalletConnectV2 extends EthWalletConnector {
|
|
11
15
|
constructor(opts) {
|
|
12
16
|
super(opts);
|
|
13
17
|
this.supportedChains = ['EVM', 'ETH'];
|
|
14
18
|
this.connectedChain = 'EVM';
|
|
19
|
+
this.isInitialized = false;
|
|
15
20
|
this.canConnectViaQrCode = true;
|
|
16
21
|
this.isWalletConnect = true;
|
|
17
22
|
this.name = opts.walletName;
|
|
@@ -27,44 +32,69 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
27
32
|
if (provider === null || provider === void 0 ? void 0 : provider.uri) {
|
|
28
33
|
return;
|
|
29
34
|
}
|
|
30
|
-
|
|
35
|
+
const defaultChain = 1;
|
|
36
|
+
provider
|
|
37
|
+
.connect({
|
|
31
38
|
namespaces: {
|
|
39
|
+
eip155: {
|
|
40
|
+
chains: [`eip155:${defaultChain}`],
|
|
41
|
+
events: ['chainChanged', 'accountsChanged'],
|
|
42
|
+
methods: ['personal_sign', 'eth_sendTransaction'],
|
|
43
|
+
rpcMap: this.evmNetworkRpcMap(),
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
optionalNamespaces: {
|
|
32
47
|
eip155: {
|
|
33
48
|
chains: this.evmNetworks
|
|
34
|
-
//
|
|
35
|
-
.filter((network) => network.chainId !== 11297108109
|
|
49
|
+
// Filters out mainnet which is required and palm that crashes Trust Wallet
|
|
50
|
+
.filter((network) => network.chainId !== 11297108109 &&
|
|
51
|
+
network.chainId !== defaultChain)
|
|
36
52
|
.map((network) => `eip155:${network.chainId}`),
|
|
37
|
-
events: [
|
|
53
|
+
events: [],
|
|
38
54
|
methods: [
|
|
39
|
-
'
|
|
55
|
+
'eth_signTypedData',
|
|
40
56
|
'eth_signTransaction',
|
|
41
57
|
'eth_sign',
|
|
42
58
|
'personal_sign',
|
|
43
|
-
'
|
|
59
|
+
'eth_sendTransaction',
|
|
44
60
|
],
|
|
45
61
|
rpcMap: this.evmNetworkRpcMap(),
|
|
46
62
|
},
|
|
47
63
|
},
|
|
64
|
+
})
|
|
65
|
+
.catch((e) => {
|
|
66
|
+
logger.error(e);
|
|
67
|
+
ee.emit('walletconnect_connection_failed');
|
|
48
68
|
});
|
|
49
69
|
});
|
|
50
70
|
}
|
|
71
|
+
createInitProviderPromise() {
|
|
72
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
73
|
+
const provider = yield Provider.init({
|
|
74
|
+
projectId: this.projectId,
|
|
75
|
+
});
|
|
76
|
+
WalletConnectV2.provider = provider;
|
|
77
|
+
});
|
|
78
|
+
}
|
|
51
79
|
initProvider() {
|
|
52
80
|
return __awaiter(this, void 0, void 0, function* () {
|
|
53
|
-
|
|
81
|
+
const { provider } = WalletConnectV2;
|
|
54
82
|
if (!provider) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
|
|
83
|
+
if (this.initializePromise === undefined) {
|
|
84
|
+
this.initializePromise = this.createInitProviderPromise();
|
|
85
|
+
}
|
|
86
|
+
yield this.initializePromise;
|
|
59
87
|
}
|
|
60
88
|
});
|
|
61
89
|
}
|
|
62
90
|
refreshSession() {
|
|
63
|
-
var _a, _b, _c, _d;
|
|
91
|
+
var _a, _b, _c, _d, _e;
|
|
64
92
|
if ((_b = (_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.session) === null || _b === void 0 ? void 0 : _b.topic) {
|
|
65
93
|
if (localStorage.getItem(this.sessionTopicKey) ===
|
|
66
94
|
((_d = (_c = WalletConnectV2.provider) === null || _c === void 0 ? void 0 : _c.session) === null || _d === void 0 ? void 0 : _d.topic)) {
|
|
67
95
|
this.session = WalletConnectV2.provider.session;
|
|
96
|
+
this.activeAccount =
|
|
97
|
+
(_e = localStorage.getItem(this.activeAccountKey)) !== null && _e !== void 0 ? _e : undefined;
|
|
68
98
|
}
|
|
69
99
|
}
|
|
70
100
|
}
|
|
@@ -72,11 +102,15 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
72
102
|
return __awaiter(this, void 0, void 0, function* () {
|
|
73
103
|
yield this.initProvider();
|
|
74
104
|
yield this.initConnection();
|
|
105
|
+
this.isInitialized = true;
|
|
75
106
|
});
|
|
76
107
|
}
|
|
77
108
|
get sessionTopicKey() {
|
|
78
109
|
return sessionTopicKey(this.key);
|
|
79
110
|
}
|
|
111
|
+
get activeAccountKey() {
|
|
112
|
+
return activeAccountKey(this.key);
|
|
113
|
+
}
|
|
80
114
|
supportsNetworkSwitching() {
|
|
81
115
|
return true;
|
|
82
116
|
}
|
|
@@ -92,23 +126,27 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
92
126
|
}
|
|
93
127
|
const { name, data } = params.event;
|
|
94
128
|
if (name === 'chainChanged') {
|
|
95
|
-
|
|
129
|
+
const chainId = parseIntSafe(data);
|
|
130
|
+
if (chainId === undefined) {
|
|
96
131
|
logger.debug(`received unexpected data for chainChanged: ${data} with type ${typeof data}}`);
|
|
97
132
|
return;
|
|
98
133
|
}
|
|
99
|
-
(_a = listeners.onChainChange) === null || _a === void 0 ? void 0 : _a.call(listeners,
|
|
134
|
+
(_a = listeners.onChainChange) === null || _a === void 0 ? void 0 : _a.call(listeners, String(chainId));
|
|
100
135
|
}
|
|
101
136
|
else if (name === 'accountsChanged') {
|
|
102
|
-
if (
|
|
137
|
+
if (!Array.isArray(data)) {
|
|
103
138
|
logger.debug(`received unexpected data for accountsChanged: ${data} with type ${typeof data}}`);
|
|
104
139
|
return;
|
|
105
140
|
}
|
|
106
|
-
|
|
141
|
+
// eslint-disable-next-line prefer-destructuring
|
|
142
|
+
const account = data[0].split(':')[2];
|
|
143
|
+
this.setActiveAccount(account);
|
|
144
|
+
(_b = listeners.onAccountChange) === null || _b === void 0 ? void 0 : _b.call(listeners, [account]);
|
|
107
145
|
}
|
|
108
146
|
});
|
|
109
147
|
WalletConnectV2.provider.client.on('session_delete', () => __awaiter(this, void 0, void 0, function* () {
|
|
110
148
|
var _a;
|
|
111
|
-
|
|
149
|
+
this.endSession();
|
|
112
150
|
yield ((_a = listeners.onDisconnect) === null || _a === void 0 ? void 0 : _a.call(listeners));
|
|
113
151
|
}));
|
|
114
152
|
}
|
|
@@ -119,20 +157,6 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
119
157
|
WalletConnectV2.provider.client.removeAllListeners('session_event');
|
|
120
158
|
WalletConnectV2.provider.client.removeAllListeners('session_delete');
|
|
121
159
|
}
|
|
122
|
-
getDeepLink() {
|
|
123
|
-
var _a, _b;
|
|
124
|
-
if (!((_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.uri))
|
|
125
|
-
return;
|
|
126
|
-
const wallet = getWalletBookWallet(this.walletBook, this.name);
|
|
127
|
-
if (!isMobile() && !((_b = wallet.desktop) === null || _b === void 0 ? void 0 : _b.native)) {
|
|
128
|
-
return undefined;
|
|
129
|
-
}
|
|
130
|
-
return getDeepLink({
|
|
131
|
-
metadata: wallet,
|
|
132
|
-
mode: 'regular',
|
|
133
|
-
uri: WalletConnectV2.provider.uri,
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
160
|
getWeb3Provider() {
|
|
137
161
|
if (!WalletConnectV2.provider) {
|
|
138
162
|
throw new Error('No provider found');
|
|
@@ -140,15 +164,25 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
140
164
|
return new ethers.providers.Web3Provider(WalletConnectV2.provider, 'any');
|
|
141
165
|
}
|
|
142
166
|
fetchPublicAddress(opts) {
|
|
167
|
+
var _a, _b;
|
|
143
168
|
return __awaiter(this, void 0, void 0, function* () {
|
|
144
|
-
if (this.
|
|
145
|
-
return this.
|
|
146
|
-
}
|
|
147
|
-
if (!WalletConnectV2.provider) {
|
|
148
|
-
throw new DynamicError('No provider found');
|
|
169
|
+
if (this.activeAccount) {
|
|
170
|
+
return this.activeAccount;
|
|
149
171
|
}
|
|
150
|
-
if (!WalletConnectV2.provider.uri) {
|
|
151
|
-
|
|
172
|
+
if (!WalletConnectV2.provider || !((_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.uri)) {
|
|
173
|
+
logger.debug('No WC2 provider found, re-initializing...');
|
|
174
|
+
yield this.endSession();
|
|
175
|
+
yield this.init();
|
|
176
|
+
// sleep 1 s to wait for connect call to finish
|
|
177
|
+
// the connect call isn't await-ed because it only resolves once
|
|
178
|
+
// the connection is established, but we need to wait for it to
|
|
179
|
+
// finish setting up the connection URI and making it available
|
|
180
|
+
// on the provider
|
|
181
|
+
yield new Promise((resolve) => setTimeout(resolve, 1000));
|
|
182
|
+
if (!WalletConnectV2.provider || !((_b = WalletConnectV2.provider) === null || _b === void 0 ? void 0 : _b.uri)) {
|
|
183
|
+
logger.debug('No WC2 provider found, escaping and throwing error');
|
|
184
|
+
throw new DynamicError('No provider found');
|
|
185
|
+
}
|
|
152
186
|
}
|
|
153
187
|
const metadata = getWalletBookWallet(this.walletBook, this.name);
|
|
154
188
|
performPlatformSpecificConnectionMethod(WalletConnectV2.provider.uri, metadata, {
|
|
@@ -160,18 +194,27 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
160
194
|
reject(new DynamicError('No provider found'));
|
|
161
195
|
return;
|
|
162
196
|
}
|
|
197
|
+
ee.on('walletconnect_connection_failed', () => {
|
|
198
|
+
const error = new DynamicError('Connection rejected. Please try again.');
|
|
199
|
+
error.code = 'connection_rejected';
|
|
200
|
+
if (WalletConnectV2.provider) {
|
|
201
|
+
WalletConnectV2.provider.uri = undefined;
|
|
202
|
+
}
|
|
203
|
+
reject(error);
|
|
204
|
+
});
|
|
163
205
|
WalletConnectV2.provider.on('connect', ({ session }) => {
|
|
164
206
|
if (!session) {
|
|
165
207
|
reject(new DynamicError('No session found'));
|
|
166
208
|
}
|
|
167
|
-
this.session
|
|
168
|
-
|
|
169
|
-
resolve(this.
|
|
209
|
+
this.setSession(session);
|
|
210
|
+
this.setActiveAccount(session.namespaces.eip155.accounts[0].split(':')[2]);
|
|
211
|
+
resolve(this.activeAccount);
|
|
170
212
|
});
|
|
171
213
|
});
|
|
172
214
|
});
|
|
173
215
|
}
|
|
174
216
|
signMessage(messageToSign) {
|
|
217
|
+
var _a, _b;
|
|
175
218
|
return __awaiter(this, void 0, void 0, function* () {
|
|
176
219
|
if (!this.session) {
|
|
177
220
|
throw new DynamicError('no session');
|
|
@@ -181,39 +224,72 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
181
224
|
}
|
|
182
225
|
const metadata = getWalletBookWallet(this.walletBook, this.name);
|
|
183
226
|
if (isMobile()) {
|
|
184
|
-
|
|
185
|
-
// and at this point we are already connected
|
|
186
|
-
const deepLink = getDeepLink({ metadata, mode: 'regular' });
|
|
227
|
+
const deepLink = ((_a = metadata['mobile']) === null || _a === void 0 ? void 0 : _a.native) || ((_b = metadata['mobile']) === null || _b === void 0 ? void 0 : _b.universal) || '';
|
|
187
228
|
window.location.href = deepLink;
|
|
188
229
|
}
|
|
189
|
-
// eslint-disable-next-line prefer-destructuring
|
|
190
|
-
const address = this.session.namespaces.eip155.accounts[0].split(':')[2];
|
|
191
230
|
const web3Provider = this.getWeb3Provider();
|
|
192
|
-
|
|
231
|
+
const response = web3Provider.send('personal_sign', [
|
|
193
232
|
utf8ToHex(messageToSign, true),
|
|
194
|
-
|
|
233
|
+
this.activeAccount,
|
|
195
234
|
]);
|
|
235
|
+
try {
|
|
236
|
+
// A terrible hack to get MM to sign the message when it is on the wrong chain
|
|
237
|
+
// Since MM supports only one chain at a time, it just hangs when we call
|
|
238
|
+
// to sign, and it is not on Mainnet. For some magical reason,
|
|
239
|
+
// when we attempt to call again it just works.
|
|
240
|
+
if (this.key === 'metamask') {
|
|
241
|
+
yield this.promiseWithTimeout(7000, response);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
catch (e) {
|
|
245
|
+
logger.debug('metmask failed to sign message');
|
|
246
|
+
throw e;
|
|
247
|
+
}
|
|
248
|
+
return response;
|
|
196
249
|
});
|
|
197
250
|
}
|
|
251
|
+
clearActiveAccount() {
|
|
252
|
+
localStorage.removeItem(this.activeAccountKey);
|
|
253
|
+
this.activeAccount = undefined;
|
|
254
|
+
}
|
|
255
|
+
clearSession() {
|
|
256
|
+
localStorage.removeItem(this.sessionTopicKey);
|
|
257
|
+
this.session = undefined;
|
|
258
|
+
}
|
|
259
|
+
setActiveAccount(account) {
|
|
260
|
+
localStorage.setItem(this.activeAccountKey, account);
|
|
261
|
+
this.activeAccount = account;
|
|
262
|
+
}
|
|
263
|
+
setSession(session) {
|
|
264
|
+
localStorage.setItem(this.sessionTopicKey, session.topic);
|
|
265
|
+
this.session = session;
|
|
266
|
+
}
|
|
198
267
|
endSession() {
|
|
268
|
+
var _a;
|
|
199
269
|
return __awaiter(this, void 0, void 0, function* () {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
if (!WalletConnectV2.provider) {
|
|
270
|
+
this.clearActiveAccount();
|
|
271
|
+
this.clearSession();
|
|
272
|
+
if (!((_a = WalletConnectV2.provider) === null || _a === void 0 ? void 0 : _a.session)) {
|
|
204
273
|
return;
|
|
205
274
|
}
|
|
206
275
|
try {
|
|
207
276
|
yield WalletConnectV2.provider.disconnect();
|
|
208
277
|
WalletConnectV2.provider.uri = undefined;
|
|
209
|
-
localStorage.removeItem(this.sessionTopicKey);
|
|
210
|
-
this.session = undefined;
|
|
211
278
|
}
|
|
212
279
|
catch (e) {
|
|
213
280
|
logger.debug(e);
|
|
214
281
|
}
|
|
215
282
|
});
|
|
216
283
|
}
|
|
284
|
+
getNetwork() {
|
|
285
|
+
const _super = Object.create(null, {
|
|
286
|
+
getNetwork: { get: () => super.getNetwork }
|
|
287
|
+
});
|
|
288
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
289
|
+
yield this.initProvider();
|
|
290
|
+
return _super.getNetwork.call(this);
|
|
291
|
+
});
|
|
292
|
+
}
|
|
217
293
|
providerSwitchNetwork({ network, provider, }) {
|
|
218
294
|
const _super = Object.create(null, {
|
|
219
295
|
providerSwitchNetwork: { get: () => super.providerSwitchNetwork }
|
|
@@ -236,14 +312,46 @@ class WalletConnectV2 extends EthWalletConnector {
|
|
|
236
312
|
});
|
|
237
313
|
}
|
|
238
314
|
getConnectedAccounts() {
|
|
315
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
316
|
+
yield this.initProvider();
|
|
317
|
+
this.refreshSession();
|
|
318
|
+
this.isInitialized = true;
|
|
319
|
+
if (!this.activeAccount) {
|
|
320
|
+
return [];
|
|
321
|
+
}
|
|
322
|
+
return [this.activeAccount];
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
getSupportedNetworks() {
|
|
239
326
|
return __awaiter(this, void 0, void 0, function* () {
|
|
240
327
|
yield this.initProvider();
|
|
241
328
|
this.refreshSession();
|
|
242
329
|
if (!this.session) {
|
|
243
330
|
return [];
|
|
244
331
|
}
|
|
245
|
-
|
|
332
|
+
const chains = [];
|
|
333
|
+
// Some wallet (i.e ZenGo) use namespaces.account to list supported chains
|
|
334
|
+
// while others use keys within the namespaces object
|
|
335
|
+
Object.keys(this.session.namespaces).forEach((key) => {
|
|
336
|
+
if (key.startsWith('eip155:')) {
|
|
337
|
+
chains.push(key.split(':')[1]);
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
this.session.namespaces.eip155.accounts.forEach((account) => chains.push(account.split(':')[1]));
|
|
341
|
+
return chains.length ? chains : undefined;
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
// a HACK for MM to sign message when the selected chain is not mainnet
|
|
345
|
+
promiseWithTimeout(ms, promise) {
|
|
346
|
+
// Create a promise that rejects in <ms> milliseconds
|
|
347
|
+
const timeout = new Promise((_, reject) => {
|
|
348
|
+
const id = setTimeout(() => {
|
|
349
|
+
clearTimeout(id);
|
|
350
|
+
reject(new DynamicError(undefined, 'metamask_timeout'));
|
|
351
|
+
}, ms);
|
|
246
352
|
});
|
|
353
|
+
// Returns a race between our timeout and the passed in promise
|
|
354
|
+
return Promise.race([promise, timeout]);
|
|
247
355
|
}
|
|
248
356
|
}
|
|
249
357
|
|