@dynamic-labs/multi-wallet 0.16.5 → 0.16.7
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 +16 -0
- package/package.json +3 -3
- package/src/wallets/clients/walletConnect/walletConnect.cjs +54 -2
- package/src/wallets/clients/walletConnect/walletConnect.d.ts +2 -1
- package/src/wallets/clients/walletConnect/walletConnect.js +54 -2
- package/src/wallets/ethereum/ethProviderHelper.cjs +15 -8
- package/src/wallets/ethereum/ethProviderHelper.js +15 -8
- package/src/wallets/walletConnect/walletConnect.cjs +3 -1
- package/src/wallets/walletConnect/walletConnect.js +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
|
|
2
|
+
### [0.16.7](https://github.com/dynamic-labs/DynamicAuth/compare/v0.16.6...v0.16.7) (2023-04-24)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
* **Cypress:** add polyfills ([#1945](https://github.com/dynamic-labs/DynamicAuth/issues/1945)) ([093c9f9](https://github.com/dynamic-labs/DynamicAuth/commit/093c9f98725f90f3dea49328e76c5f126fa6478d))
|
|
8
|
+
* **DYN-2261:** hide authorization flow after network switch ([#1942](https://github.com/dynamic-labs/DynamicAuth/issues/1942)) ([0b44470](https://github.com/dynamic-labs/DynamicAuth/commit/0b444708183ffcbfd5302f3e48f69c0d0de6a0b4))
|
|
9
|
+
* remove listeners properly ([#1940](https://github.com/dynamic-labs/DynamicAuth/issues/1940)) ([aaca308](https://github.com/dynamic-labs/DynamicAuth/commit/aaca308e834149d50322768887c308171f9f767f))
|
|
10
|
+
|
|
11
|
+
### [0.16.6](https://github.com/dynamic-labs/DynamicAuth/compare/v0.16.5...v0.16.6) (2023-04-23)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* wait for safe transaction validation before verify call v16 ([#1930](https://github.com/dynamic-labs/DynamicAuth/issues/1930)) ([6064455](https://github.com/dynamic-labs/DynamicAuth/commit/60644554916100bffc4c5e1090475b3f7b9b79c3))
|
|
17
|
+
|
|
2
18
|
### [0.16.5](https://github.com/dynamic-labs/DynamicAuth/compare/v0.16.4...v0.16.5) (2023-04-22)
|
|
3
19
|
|
|
4
20
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs/multi-wallet",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.7",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/dynamic-labs/DynamicAuth.git",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"magic-sdk": "^16.0.1",
|
|
29
29
|
"@keplr-wallet/provider": "0.11.56",
|
|
30
30
|
"@keplr-wallet/types": "^0.11.51",
|
|
31
|
-
"@dynamic-labs/logger": "0.16.
|
|
32
|
-
"@dynamic-labs/wallet-connector-core": "0.16.
|
|
31
|
+
"@dynamic-labs/logger": "0.16.7",
|
|
32
|
+
"@dynamic-labs/wallet-connector-core": "0.16.7"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@walletconnect/types": "^2.2.1"
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var tslib = require('tslib');
|
|
6
6
|
var Client = require('@walletconnect/client');
|
|
7
|
+
var ethers = require('ethers');
|
|
7
8
|
var isMobile = require('../../../utils/isMobile.cjs');
|
|
8
9
|
var isSameAddress = require('../../../utils/isSameAddress/isSameAddress.cjs');
|
|
9
10
|
var logger = require('../../../utils/logger.cjs');
|
|
@@ -156,7 +157,7 @@ const fetchWalletConnectEVMPublicAddress = (metadata, wcClient, opts) => tslib._
|
|
|
156
157
|
const [accountPublicAddress] = payload.params[0].accounts;
|
|
157
158
|
return accountPublicAddress;
|
|
158
159
|
});
|
|
159
|
-
const signWalletConnectPersonalMessage = (messageToSign, metadata, client) => tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
160
|
+
const signWalletConnectPersonalMessage = (messageToSign, metadata, client, rpcProvider) => tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
160
161
|
var _c, _d;
|
|
161
162
|
const isCryptoWallet = ((_c = client === null || client === void 0 ? void 0 : client.peerMeta) === null || _c === void 0 ? void 0 : _c.name) === 'Crypto.com | DeFi Wallet' ||
|
|
162
163
|
((_d = client === null || client === void 0 ? void 0 : client.peerMeta) === null || _d === void 0 ? void 0 : _d.name) === 'DeFi Wallet';
|
|
@@ -184,12 +185,63 @@ const signWalletConnectPersonalMessage = (messageToSign, metadata, client) => ts
|
|
|
184
185
|
// and not allowing the user to sign the message
|
|
185
186
|
yield sleep(1000);
|
|
186
187
|
}
|
|
187
|
-
|
|
188
|
+
const signature = yield client.signPersonalMessage([
|
|
189
|
+
messageToSign,
|
|
190
|
+
accountPublicAddress,
|
|
191
|
+
]);
|
|
192
|
+
yield waitForSafeTransactionOrTimeout(accountPublicAddress, signature, messageToSign, client, rpcProvider);
|
|
193
|
+
return signature;
|
|
188
194
|
}
|
|
189
195
|
catch (e) {
|
|
190
196
|
logger.logger.debug(e);
|
|
191
197
|
throw e;
|
|
192
198
|
}
|
|
199
|
+
});
|
|
200
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
201
|
+
// Successful value as defined by the EIP
|
|
202
|
+
// https://eips.ethereum.org/EIPS/eip-1271#specification
|
|
203
|
+
const MAGIC_VALUE = '0x1626ba7e';
|
|
204
|
+
const IS_VALID_SIGNATURE_ABI = [
|
|
205
|
+
'function isValidSignature(bytes32 _message, bytes _signature) public view returns (bytes4)',
|
|
206
|
+
];
|
|
207
|
+
const waitForSafeTransactionOrTimeout = (accountPublicAddress, signature, messageToSign, client, rpcProvider) => tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
208
|
+
var _e;
|
|
209
|
+
if (signature === '0x' &&
|
|
210
|
+
// this is what wallet connect client returns there's no `safe` or `Safe`
|
|
211
|
+
// exact string anywhere, so this seems like the best proxy
|
|
212
|
+
((_e = client.peerMeta) === null || _e === void 0 ? void 0 : _e.name) === 'WalletConnect Safe App') {
|
|
213
|
+
if (!rpcProvider) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
const contract = new ethers.Contract(accountPublicAddress, IS_VALID_SIGNATURE_ABI, yield rpcProvider());
|
|
217
|
+
const safeTransactionPromise = waitForSafeTransaction(signature, messageToSign, contract);
|
|
218
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
219
|
+
setTimeout(resolve, 120000);
|
|
220
|
+
});
|
|
221
|
+
yield Promise.race([safeTransactionPromise, timeoutPromise]);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
// this is a hack for safe
|
|
225
|
+
// before sending the signature downstream, we need to make sure
|
|
226
|
+
// the transaction is recorded first on the blockchain
|
|
227
|
+
// redcoast verify WILL fail if it attempts to verify the signature
|
|
228
|
+
// that has not yet been properly processed!
|
|
229
|
+
const waitForSafeTransaction = (signature, messageToSign, contract) => tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
230
|
+
// wait for safe wallet to finish txn on the blockchain contract
|
|
231
|
+
for (let i = 0; i < 120; i++) {
|
|
232
|
+
try {
|
|
233
|
+
// this will result in an exception if the transaction is still not ready
|
|
234
|
+
// we need to catch it below
|
|
235
|
+
const result = yield contract.isValidSignature(ethers.ethers.utils.hashMessage(messageToSign), signature);
|
|
236
|
+
if (result === MAGIC_VALUE)
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
logger.logger.info('Safe transaction cannot be validated yet. Retrying.');
|
|
241
|
+
}
|
|
242
|
+
// try again after 2 seconds
|
|
243
|
+
yield sleep(2000);
|
|
244
|
+
}
|
|
193
245
|
});
|
|
194
246
|
|
|
195
247
|
exports.createSession = createSession;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Client from '@walletconnect/client';
|
|
2
|
+
import { ethers } from 'ethers';
|
|
2
3
|
import { FetchPublicAddressOpts, PayloadParams, WalletEventListeners } from '@dynamic-labs/wallet-connector-core';
|
|
3
4
|
import { WalletSchema } from '@dynamic-labs/wallet-book';
|
|
4
5
|
import { KeplrWalletConnectV1 } from '../../cosmos/wcClient';
|
|
@@ -19,4 +20,4 @@ export declare const createSession: (client: Client) => Promise<PayloadParams>;
|
|
|
19
20
|
export declare const useDeepLink: (metadata: WalletSchema, wcClient: Client, opts?: FetchPublicAddressOpts) => void;
|
|
20
21
|
export declare const fetchWalletConnectCosmosPublicAddress: (metadata: WalletSchema, wcClient: Client, provider: KeplrWalletConnectV1, opts: FetchPublicAddressOpts & Required<Pick<FetchPublicAddressOpts, 'chainId'>>) => Promise<string>;
|
|
21
22
|
export declare const fetchWalletConnectEVMPublicAddress: (metadata: WalletSchema, wcClient: Client, opts?: FetchPublicAddressOpts) => Promise<string | undefined>;
|
|
22
|
-
export declare const signWalletConnectPersonalMessage: (messageToSign: string, metadata: WalletSchema, client: Client) => Promise<string | undefined>;
|
|
23
|
+
export declare const signWalletConnectPersonalMessage: (messageToSign: string, metadata: WalletSchema, client: Client, rpcProvider?: () => Promise<ethers.providers.JsonRpcProvider | undefined>) => Promise<string | undefined>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { __awaiter } from 'tslib';
|
|
2
2
|
import Client from '@walletconnect/client';
|
|
3
|
+
import { Contract, ethers } from 'ethers';
|
|
3
4
|
import { isMobile, isIOS } from '../../../utils/isMobile.js';
|
|
4
5
|
import { isSameAddress } from '../../../utils/isSameAddress/isSameAddress.js';
|
|
5
6
|
import { logger } from '../../../utils/logger.js';
|
|
@@ -148,7 +149,7 @@ const fetchWalletConnectEVMPublicAddress = (metadata, wcClient, opts) => __await
|
|
|
148
149
|
const [accountPublicAddress] = payload.params[0].accounts;
|
|
149
150
|
return accountPublicAddress;
|
|
150
151
|
});
|
|
151
|
-
const signWalletConnectPersonalMessage = (messageToSign, metadata, client) => __awaiter(void 0, void 0, void 0, function* () {
|
|
152
|
+
const signWalletConnectPersonalMessage = (messageToSign, metadata, client, rpcProvider) => __awaiter(void 0, void 0, void 0, function* () {
|
|
152
153
|
var _c, _d;
|
|
153
154
|
const isCryptoWallet = ((_c = client === null || client === void 0 ? void 0 : client.peerMeta) === null || _c === void 0 ? void 0 : _c.name) === 'Crypto.com | DeFi Wallet' ||
|
|
154
155
|
((_d = client === null || client === void 0 ? void 0 : client.peerMeta) === null || _d === void 0 ? void 0 : _d.name) === 'DeFi Wallet';
|
|
@@ -176,12 +177,63 @@ const signWalletConnectPersonalMessage = (messageToSign, metadata, client) => __
|
|
|
176
177
|
// and not allowing the user to sign the message
|
|
177
178
|
yield sleep(1000);
|
|
178
179
|
}
|
|
179
|
-
|
|
180
|
+
const signature = yield client.signPersonalMessage([
|
|
181
|
+
messageToSign,
|
|
182
|
+
accountPublicAddress,
|
|
183
|
+
]);
|
|
184
|
+
yield waitForSafeTransactionOrTimeout(accountPublicAddress, signature, messageToSign, client, rpcProvider);
|
|
185
|
+
return signature;
|
|
180
186
|
}
|
|
181
187
|
catch (e) {
|
|
182
188
|
logger.debug(e);
|
|
183
189
|
throw e;
|
|
184
190
|
}
|
|
191
|
+
});
|
|
192
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
193
|
+
// Successful value as defined by the EIP
|
|
194
|
+
// https://eips.ethereum.org/EIPS/eip-1271#specification
|
|
195
|
+
const MAGIC_VALUE = '0x1626ba7e';
|
|
196
|
+
const IS_VALID_SIGNATURE_ABI = [
|
|
197
|
+
'function isValidSignature(bytes32 _message, bytes _signature) public view returns (bytes4)',
|
|
198
|
+
];
|
|
199
|
+
const waitForSafeTransactionOrTimeout = (accountPublicAddress, signature, messageToSign, client, rpcProvider) => __awaiter(void 0, void 0, void 0, function* () {
|
|
200
|
+
var _e;
|
|
201
|
+
if (signature === '0x' &&
|
|
202
|
+
// this is what wallet connect client returns there's no `safe` or `Safe`
|
|
203
|
+
// exact string anywhere, so this seems like the best proxy
|
|
204
|
+
((_e = client.peerMeta) === null || _e === void 0 ? void 0 : _e.name) === 'WalletConnect Safe App') {
|
|
205
|
+
if (!rpcProvider) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const contract = new Contract(accountPublicAddress, IS_VALID_SIGNATURE_ABI, yield rpcProvider());
|
|
209
|
+
const safeTransactionPromise = waitForSafeTransaction(signature, messageToSign, contract);
|
|
210
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
211
|
+
setTimeout(resolve, 120000);
|
|
212
|
+
});
|
|
213
|
+
yield Promise.race([safeTransactionPromise, timeoutPromise]);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
// this is a hack for safe
|
|
217
|
+
// before sending the signature downstream, we need to make sure
|
|
218
|
+
// the transaction is recorded first on the blockchain
|
|
219
|
+
// redcoast verify WILL fail if it attempts to verify the signature
|
|
220
|
+
// that has not yet been properly processed!
|
|
221
|
+
const waitForSafeTransaction = (signature, messageToSign, contract) => __awaiter(void 0, void 0, void 0, function* () {
|
|
222
|
+
// wait for safe wallet to finish txn on the blockchain contract
|
|
223
|
+
for (let i = 0; i < 120; i++) {
|
|
224
|
+
try {
|
|
225
|
+
// this will result in an exception if the transaction is still not ready
|
|
226
|
+
// we need to catch it below
|
|
227
|
+
const result = yield contract.isValidSignature(ethers.utils.hashMessage(messageToSign), signature);
|
|
228
|
+
if (result === MAGIC_VALUE)
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
logger.info('Safe transaction cannot be validated yet. Retrying.');
|
|
233
|
+
}
|
|
234
|
+
// try again after 2 seconds
|
|
235
|
+
yield sleep(2000);
|
|
236
|
+
}
|
|
185
237
|
});
|
|
186
238
|
|
|
187
239
|
export { createSession, fetchWalletConnectCosmosPublicAddress, fetchWalletConnectEVMPublicAddress, getDeepLink, initClient, killWalletConnectSession, setupWalletConnectEventListeners, signWalletConnectPersonalMessage, teardownWalletConnectEventListeners, useDeepLink };
|
|
@@ -150,7 +150,7 @@ class EthProviderHelper {
|
|
|
150
150
|
// nothing to teardown
|
|
151
151
|
};
|
|
152
152
|
}
|
|
153
|
-
const
|
|
153
|
+
const externalProvider = web3Provider.provider;
|
|
154
154
|
this.handleAccountChange = (accounts) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
155
155
|
var _a, _b;
|
|
156
156
|
if (accounts.length === 0) {
|
|
@@ -171,19 +171,26 @@ class EthProviderHelper {
|
|
|
171
171
|
}
|
|
172
172
|
yield ((_d = listeners.onDisconnect) === null || _d === void 0 ? void 0 : _d.call(listeners));
|
|
173
173
|
});
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
174
|
+
externalProvider.on('accountsChanged', this.handleAccountChange);
|
|
175
|
+
externalProvider.on('chainChanged', this.handleChainChange);
|
|
176
|
+
externalProvider.on('disconnect', this.handleDisconnect);
|
|
177
177
|
return () => { };
|
|
178
178
|
}
|
|
179
179
|
_teardownEventListeners(name) {
|
|
180
180
|
const web3Provider = this.findProvider(name);
|
|
181
|
-
if (!web3Provider) {
|
|
181
|
+
if (!web3Provider || !(web3Provider === null || web3Provider === void 0 ? void 0 : web3Provider.provider)) {
|
|
182
182
|
return;
|
|
183
183
|
}
|
|
184
|
-
web3Provider.
|
|
185
|
-
|
|
186
|
-
|
|
184
|
+
const externalProvider = web3Provider.provider;
|
|
185
|
+
if (this.handleAccountChange) {
|
|
186
|
+
externalProvider.removeListener('accountsChanged', this.handleAccountChange);
|
|
187
|
+
}
|
|
188
|
+
if (this.handleChainChange) {
|
|
189
|
+
externalProvider.removeListener('chainChanged', this.handleChainChange);
|
|
190
|
+
}
|
|
191
|
+
if (this.handleDisconnect) {
|
|
192
|
+
externalProvider.removeListener('disconnect', this.handleDisconnect);
|
|
193
|
+
}
|
|
187
194
|
}
|
|
188
195
|
}
|
|
189
196
|
|
|
@@ -146,7 +146,7 @@ class EthProviderHelper {
|
|
|
146
146
|
// nothing to teardown
|
|
147
147
|
};
|
|
148
148
|
}
|
|
149
|
-
const
|
|
149
|
+
const externalProvider = web3Provider.provider;
|
|
150
150
|
this.handleAccountChange = (accounts) => __awaiter(this, void 0, void 0, function* () {
|
|
151
151
|
var _a, _b;
|
|
152
152
|
if (accounts.length === 0) {
|
|
@@ -167,19 +167,26 @@ class EthProviderHelper {
|
|
|
167
167
|
}
|
|
168
168
|
yield ((_d = listeners.onDisconnect) === null || _d === void 0 ? void 0 : _d.call(listeners));
|
|
169
169
|
});
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
170
|
+
externalProvider.on('accountsChanged', this.handleAccountChange);
|
|
171
|
+
externalProvider.on('chainChanged', this.handleChainChange);
|
|
172
|
+
externalProvider.on('disconnect', this.handleDisconnect);
|
|
173
173
|
return () => { };
|
|
174
174
|
}
|
|
175
175
|
_teardownEventListeners(name) {
|
|
176
176
|
const web3Provider = this.findProvider(name);
|
|
177
|
-
if (!web3Provider) {
|
|
177
|
+
if (!web3Provider || !(web3Provider === null || web3Provider === void 0 ? void 0 : web3Provider.provider)) {
|
|
178
178
|
return;
|
|
179
179
|
}
|
|
180
|
-
web3Provider.
|
|
181
|
-
|
|
182
|
-
|
|
180
|
+
const externalProvider = web3Provider.provider;
|
|
181
|
+
if (this.handleAccountChange) {
|
|
182
|
+
externalProvider.removeListener('accountsChanged', this.handleAccountChange);
|
|
183
|
+
}
|
|
184
|
+
if (this.handleChainChange) {
|
|
185
|
+
externalProvider.removeListener('chainChanged', this.handleChainChange);
|
|
186
|
+
}
|
|
187
|
+
if (this.handleDisconnect) {
|
|
188
|
+
externalProvider.removeListener('disconnect', this.handleDisconnect);
|
|
189
|
+
}
|
|
183
190
|
}
|
|
184
191
|
}
|
|
185
192
|
|
|
@@ -94,7 +94,9 @@ class WalletConnect extends ethProvider.EthProvider {
|
|
|
94
94
|
}
|
|
95
95
|
signMessage(messageToSign) {
|
|
96
96
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
97
|
-
return walletConnect.signWalletConnectPersonalMessage(messageToSign, walletBook.getWalletBookWallet(this.name), this.getClient()
|
|
97
|
+
return walletConnect.signWalletConnectPersonalMessage(messageToSign, walletBook.getWalletBookWallet(this.name), this.getClient(),
|
|
98
|
+
// don't call getRpcProvider until we really need to
|
|
99
|
+
() => tslib.__awaiter(this, void 0, void 0, function* () { return this.getRpcProvider(); }));
|
|
98
100
|
});
|
|
99
101
|
}
|
|
100
102
|
proveOwnership(messageToSign) {
|
|
@@ -88,7 +88,9 @@ class WalletConnect extends EthProvider {
|
|
|
88
88
|
}
|
|
89
89
|
signMessage(messageToSign) {
|
|
90
90
|
return __awaiter(this, void 0, void 0, function* () {
|
|
91
|
-
return signWalletConnectPersonalMessage(messageToSign, getWalletBookWallet(this.name), this.getClient()
|
|
91
|
+
return signWalletConnectPersonalMessage(messageToSign, getWalletBookWallet(this.name), this.getClient(),
|
|
92
|
+
// don't call getRpcProvider until we really need to
|
|
93
|
+
() => __awaiter(this, void 0, void 0, function* () { return this.getRpcProvider(); }));
|
|
92
94
|
});
|
|
93
95
|
}
|
|
94
96
|
proveOwnership(messageToSign) {
|