@dynamic-labs/multi-wallet 0.16.4 → 0.16.6
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 +14 -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/walletConnect/walletConnect.cjs +3 -1
- package/src/wallets/walletConnect/walletConnect.js +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
|
|
2
|
+
### [0.16.6](https://github.com/dynamic-labs/DynamicAuth/compare/v0.16.5...v0.16.6) (2023-04-23)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
* 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))
|
|
8
|
+
|
|
9
|
+
### [0.16.5](https://github.com/dynamic-labs/DynamicAuth/compare/v0.16.4...v0.16.5) (2023-04-22)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
* lock qrcode to 1.5.1 (since 1.5.2 breaks cjs) ([#1924](https://github.com/dynamic-labs/DynamicAuth/issues/1924)) ([abec1aa](https://github.com/dynamic-labs/DynamicAuth/commit/abec1aa66a33d1ff50fafcaa2a87cef80b286801))
|
|
15
|
+
|
|
2
16
|
### [0.16.4](https://github.com/dynamic-labs/DynamicAuth/compare/v0.16.3...v0.16.4) (2023-04-19)
|
|
3
17
|
|
|
4
18
|
|
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.6",
|
|
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.6",
|
|
32
|
+
"@dynamic-labs/wallet-connector-core": "0.16.6"
|
|
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 };
|
|
@@ -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) {
|