@0xsequence/provider 0.42.9 → 0.43.0
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/dist/0xsequence-provider.cjs.dev.js +422 -869
- package/dist/0xsequence-provider.cjs.prod.js +422 -869
- package/dist/0xsequence-provider.esm.js +423 -870
- package/dist/declarations/src/provider.d.ts +7 -6
- package/dist/declarations/src/transports/base-provider-transport.d.ts +1 -1
- package/dist/declarations/src/transports/base-wallet-transport.d.ts +1 -1
- package/dist/declarations/src/transports/mux-transport/mux-message-provider.d.ts +2 -2
- package/dist/declarations/src/transports/proxy-transport/proxy-message-provider.d.ts +1 -1
- package/dist/declarations/src/transports/unreal-transport/unreal-message-provider.d.ts +1 -1
- package/dist/declarations/src/transports/wallet-request-handler.d.ts +10 -4
- package/dist/declarations/src/transports/window-transport/window-message-provider.d.ts +1 -1
- package/dist/declarations/src/types.d.ts +1 -1
- package/dist/declarations/src/utils/index.d.ts +4 -5
- package/dist/declarations/src/utils.d.ts +4 -4
- package/dist/declarations/src/wallet.d.ts +5 -5
- package/package.json +14 -15
- package/src/provider.ts +10 -14
- package/src/transports/wallet-request-handler.ts +17 -2
- package/src/types.ts +1 -2
- package/src/utils/index.ts +2 -9
- package/src/wallet.ts +2 -3
|
@@ -6,41 +6,36 @@ var eventemitter2 = require('eventemitter2');
|
|
|
6
6
|
var utils = require('@0xsequence/utils');
|
|
7
7
|
var ethers = require('ethers');
|
|
8
8
|
var config = require('@0xsequence/config');
|
|
9
|
-
var providers = require('@ethersproject/providers');
|
|
10
9
|
var network = require('@0xsequence/network');
|
|
11
10
|
var wallet = require('@0xsequence/wallet');
|
|
12
11
|
var transactions = require('@0xsequence/transactions');
|
|
13
12
|
var auth = require('@0xsequence/auth');
|
|
14
13
|
|
|
15
14
|
function _extends() {
|
|
16
|
-
_extends = Object.assign
|
|
15
|
+
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
17
16
|
for (var i = 1; i < arguments.length; i++) {
|
|
18
17
|
var source = arguments[i];
|
|
19
|
-
|
|
20
18
|
for (var key in source) {
|
|
21
19
|
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
22
20
|
target[key] = source[key];
|
|
23
21
|
}
|
|
24
22
|
}
|
|
25
23
|
}
|
|
26
|
-
|
|
27
24
|
return target;
|
|
28
25
|
};
|
|
29
|
-
|
|
30
26
|
return _extends.apply(this, arguments);
|
|
31
27
|
}
|
|
32
28
|
|
|
33
29
|
// ProviderMessageCallback is used to respond to ProviderMessage requests. The error
|
|
34
30
|
// argument is for exceptions during the execution, and response is the response payload
|
|
35
31
|
// which may contain the result or an error payload from the wallet.
|
|
32
|
+
|
|
36
33
|
class WindowSessionParams extends URLSearchParams {
|
|
37
34
|
static new(init) {
|
|
38
35
|
return new URLSearchParams(init);
|
|
39
36
|
}
|
|
40
|
-
|
|
41
37
|
}
|
|
42
38
|
exports.EventType = void 0;
|
|
43
|
-
|
|
44
39
|
(function (EventType) {
|
|
45
40
|
EventType["OPEN"] = "open";
|
|
46
41
|
EventType["CLOSE"] = "close";
|
|
@@ -54,31 +49,27 @@ exports.EventType = void 0;
|
|
|
54
49
|
EventType["INIT"] = "init";
|
|
55
50
|
EventType["DEBUG"] = "_debug";
|
|
56
51
|
})(exports.EventType || (exports.EventType = {}));
|
|
57
|
-
|
|
58
52
|
exports.OpenState = void 0;
|
|
59
|
-
|
|
60
53
|
(function (OpenState) {
|
|
61
54
|
OpenState[OpenState["CLOSED"] = 0] = "CLOSED";
|
|
62
55
|
OpenState[OpenState["OPENING"] = 1] = "OPENING";
|
|
63
56
|
OpenState[OpenState["OPENED"] = 2] = "OPENED";
|
|
64
57
|
})(exports.OpenState || (exports.OpenState = {}));
|
|
65
|
-
|
|
66
58
|
exports.InitState = void 0;
|
|
67
|
-
|
|
68
59
|
(function (InitState) {
|
|
69
60
|
InitState[InitState["NIL"] = 0] = "NIL";
|
|
70
61
|
InitState[InitState["SENT_NONCE"] = 1] = "SENT_NONCE";
|
|
71
62
|
InitState[InitState["OK"] = 2] = "OK";
|
|
72
63
|
})(exports.InitState || (exports.InitState = {}));
|
|
73
|
-
|
|
74
64
|
class ProviderError extends Error {
|
|
75
65
|
constructor(message) {
|
|
76
66
|
super(message);
|
|
77
67
|
this.name = 'ProviderError';
|
|
78
68
|
}
|
|
79
|
-
|
|
80
69
|
}
|
|
81
|
-
const ErrSignedInRequired = new ProviderError('Wallet is not signed in. Connect a wallet and try again.');
|
|
70
|
+
const ErrSignedInRequired = new ProviderError('Wallet is not signed in. Connect a wallet and try again.');
|
|
71
|
+
|
|
72
|
+
// TODO: lets build some nice error handling tools, prob in /utils ...
|
|
82
73
|
|
|
83
74
|
const PROVIDER_OPEN_TIMEOUT = 30000; // in ms
|
|
84
75
|
|
|
@@ -87,7 +78,6 @@ const nextMessageIdx = () => ++_messageIdx;
|
|
|
87
78
|
class BaseProviderTransport {
|
|
88
79
|
constructor() {
|
|
89
80
|
var _this = this;
|
|
90
|
-
|
|
91
81
|
this.pendingMessageRequests = [];
|
|
92
82
|
this.responseCallbacks = new Map();
|
|
93
83
|
this.state = void 0;
|
|
@@ -101,27 +91,27 @@ class BaseProviderTransport {
|
|
|
101
91
|
this._sessionId = void 0;
|
|
102
92
|
this._init = void 0;
|
|
103
93
|
this._registered = void 0;
|
|
104
|
-
|
|
105
94
|
this.sendAsync = async function (request, callback, chainId) {
|
|
106
95
|
// here, we receive the message from the dapp provider call
|
|
96
|
+
|
|
107
97
|
if (_this.state === exports.OpenState.CLOSED) {
|
|
108
98
|
// flag the wallet to auto-close once user submits input. ie.
|
|
109
99
|
// prompting to sign a message or transaction
|
|
110
100
|
_this.confirmationOnly = true;
|
|
111
|
-
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// open/focus the wallet.
|
|
112
104
|
// automatically open the wallet when a provider request makes it here.
|
|
113
105
|
//
|
|
114
106
|
// NOTE: if we're not signed in, then the provider will fail, users must first connect+sign in.
|
|
115
107
|
//
|
|
116
108
|
// TODO: how does this behave with a session has expired?
|
|
117
|
-
|
|
118
|
-
|
|
119
109
|
_this.openWallet(undefined, {
|
|
120
110
|
type: 'jsonRpcRequest',
|
|
121
111
|
method: request.method
|
|
122
|
-
}, chainId);
|
|
123
|
-
|
|
112
|
+
}, chainId);
|
|
124
113
|
|
|
114
|
+
// send message request, await, and then execute callback after receiving the response
|
|
125
115
|
try {
|
|
126
116
|
if (!_this.isOpened()) {
|
|
127
117
|
await _this.waitUntilOpened(); // will throw on timeout
|
|
@@ -138,13 +128,11 @@ class BaseProviderTransport {
|
|
|
138
128
|
callback(err);
|
|
139
129
|
}
|
|
140
130
|
};
|
|
141
|
-
|
|
142
131
|
this.sendMessageRequest = async function (message) {
|
|
143
132
|
return new Promise((resolve, reject) => {
|
|
144
133
|
if ((!message.idx || message.idx <= 0) && message.type !== 'init') {
|
|
145
134
|
reject(new Error('message idx not set'));
|
|
146
135
|
}
|
|
147
|
-
|
|
148
136
|
const responseCallback = (error, response) => {
|
|
149
137
|
if (error) {
|
|
150
138
|
reject(error);
|
|
@@ -154,51 +142,42 @@ class BaseProviderTransport {
|
|
|
154
142
|
throw new Error('no valid response to return');
|
|
155
143
|
}
|
|
156
144
|
};
|
|
157
|
-
|
|
158
145
|
const idx = message.idx;
|
|
159
|
-
|
|
160
146
|
if (!_this.responseCallbacks.get(idx)) {
|
|
161
147
|
_this.responseCallbacks.set(idx, responseCallback);
|
|
162
148
|
} else {
|
|
163
149
|
reject(new Error('duplicate message idx, should never happen'));
|
|
164
150
|
}
|
|
165
|
-
|
|
166
151
|
if (!_this.isOpened()) {
|
|
167
152
|
utils.logger.debug('pushing to pending requests', message);
|
|
168
|
-
|
|
169
153
|
_this.pendingMessageRequests.push(message);
|
|
170
154
|
} else {
|
|
171
155
|
_this.sendMessage(message);
|
|
172
156
|
}
|
|
173
157
|
});
|
|
174
158
|
};
|
|
175
|
-
|
|
176
159
|
this.waitUntilOpened = async function (openTimeout = PROVIDER_OPEN_TIMEOUT) {
|
|
177
160
|
let opened = false;
|
|
178
161
|
return Promise.race([new Promise((_, reject) => {
|
|
179
162
|
const timeout = setTimeout(() => {
|
|
180
|
-
clearTimeout(timeout);
|
|
181
|
-
|
|
163
|
+
clearTimeout(timeout);
|
|
164
|
+
// only emit close if the timeout wins the race
|
|
182
165
|
if (!opened) {
|
|
183
166
|
_this.state = exports.OpenState.CLOSED;
|
|
184
|
-
|
|
185
167
|
_this.events.emit('close', {
|
|
186
168
|
code: 1005,
|
|
187
169
|
message: 'opening wallet timed out'
|
|
188
170
|
});
|
|
189
171
|
}
|
|
190
|
-
|
|
191
172
|
reject(new Error('opening wallet timed out'));
|
|
192
173
|
}, openTimeout);
|
|
193
174
|
}), new Promise(resolve => {
|
|
194
175
|
if (_this.isOpened()) {
|
|
195
176
|
var _this$openPayload;
|
|
196
|
-
|
|
197
177
|
opened = true;
|
|
198
178
|
resolve((_this$openPayload = _this.openPayload) == null ? void 0 : _this$openPayload.session);
|
|
199
179
|
return;
|
|
200
180
|
}
|
|
201
|
-
|
|
202
181
|
_this.events.once('open', openInfo => {
|
|
203
182
|
_this.openPayload = openInfo;
|
|
204
183
|
opened = true;
|
|
@@ -206,7 +185,6 @@ class BaseProviderTransport {
|
|
|
206
185
|
});
|
|
207
186
|
})]);
|
|
208
187
|
};
|
|
209
|
-
|
|
210
188
|
this.waitUntilConnected = async function () {
|
|
211
189
|
await _this.waitUntilOpened();
|
|
212
190
|
const connect = new Promise(resolve => {
|
|
@@ -214,7 +192,6 @@ class BaseProviderTransport {
|
|
|
214
192
|
resolve(_this.connectPayload);
|
|
215
193
|
return;
|
|
216
194
|
}
|
|
217
|
-
|
|
218
195
|
_this.events.once('connect', connectDetails => {
|
|
219
196
|
_this.connectPayload = connectDetails;
|
|
220
197
|
resolve(connectDetails);
|
|
@@ -231,48 +208,37 @@ class BaseProviderTransport {
|
|
|
231
208
|
});
|
|
232
209
|
return Promise.race([connect, closeWallet]);
|
|
233
210
|
};
|
|
234
|
-
|
|
235
211
|
this.state = exports.OpenState.CLOSED;
|
|
236
212
|
this._registered = false;
|
|
237
213
|
this._init = exports.InitState.NIL;
|
|
238
214
|
}
|
|
239
|
-
|
|
240
215
|
get registered() {
|
|
241
216
|
return this._registered;
|
|
242
217
|
}
|
|
243
|
-
|
|
244
218
|
register() {
|
|
245
219
|
throw new Error('abstract method');
|
|
246
220
|
}
|
|
247
|
-
|
|
248
221
|
unregister() {
|
|
249
222
|
throw new Error('abstract method');
|
|
250
223
|
}
|
|
251
|
-
|
|
252
224
|
openWallet(path, intent, networkId) {
|
|
253
225
|
throw new Error('abstract method');
|
|
254
226
|
}
|
|
255
|
-
|
|
256
227
|
closeWallet() {
|
|
257
228
|
throw new Error('abstract method');
|
|
258
229
|
}
|
|
259
|
-
|
|
260
230
|
isOpened() {
|
|
261
231
|
return this.registered && this.state === exports.OpenState.OPENED;
|
|
262
232
|
}
|
|
263
|
-
|
|
264
233
|
isConnected() {
|
|
265
234
|
var _this$openPayload2;
|
|
266
|
-
|
|
267
235
|
// if we're registered, and we have the account details, then we are connected
|
|
268
236
|
const session = (_this$openPayload2 = this.openPayload) == null ? void 0 : _this$openPayload2.session;
|
|
269
237
|
return this.registered && session !== undefined && !!session.accountAddress && session.accountAddress.length === 42 && !!session.networks && session.networks.length > 0;
|
|
270
238
|
}
|
|
271
|
-
|
|
272
239
|
// handleMessage will handle message received from the remote wallet
|
|
273
240
|
handleMessage(message) {
|
|
274
241
|
var _this2 = this;
|
|
275
|
-
|
|
276
242
|
// init incoming for initial handshake with transport.
|
|
277
243
|
// always respond to INIT messages, e.g. on popup window reload
|
|
278
244
|
if (message.type === exports.EventType.INIT) {
|
|
@@ -280,12 +246,10 @@ class BaseProviderTransport {
|
|
|
280
246
|
const {
|
|
281
247
|
nonce
|
|
282
248
|
} = message.data;
|
|
283
|
-
|
|
284
249
|
if (!nonce || nonce.length == 0) {
|
|
285
250
|
utils.logger.error('invalid init nonce');
|
|
286
251
|
return;
|
|
287
252
|
}
|
|
288
|
-
|
|
289
253
|
this._init = exports.InitState.OK;
|
|
290
254
|
this.sendMessage({
|
|
291
255
|
idx: -1,
|
|
@@ -296,59 +260,55 @@ class BaseProviderTransport {
|
|
|
296
260
|
}
|
|
297
261
|
});
|
|
298
262
|
}
|
|
299
|
-
|
|
300
263
|
if (this._init !== exports.InitState.OK) {
|
|
301
264
|
// if provider is not init'd, then we drop any received messages. the only
|
|
302
265
|
// message we will process is of event type 'init', as our acknowledgement
|
|
303
266
|
return;
|
|
304
|
-
}
|
|
305
|
-
|
|
267
|
+
}
|
|
306
268
|
|
|
269
|
+
// message is either a notification, or its a ProviderMessageResponse
|
|
307
270
|
utils.logger.debug('RECEIVED MESSAGE FROM WALLET', message.idx, message);
|
|
308
271
|
const requestIdx = message.idx;
|
|
309
272
|
const responseCallback = this.responseCallbacks.get(requestIdx);
|
|
310
|
-
|
|
311
273
|
if (requestIdx) {
|
|
312
274
|
this.responseCallbacks.delete(requestIdx);
|
|
313
|
-
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// OPEN response
|
|
314
278
|
//
|
|
315
279
|
// Flip opened flag, and flush the pending queue
|
|
316
|
-
|
|
317
|
-
|
|
318
280
|
if (message.type === exports.EventType.OPEN && !this.isOpened()) {
|
|
319
281
|
var _message$data, _message$data2;
|
|
320
|
-
|
|
321
282
|
if (this._sessionId && this._sessionId !== ((_message$data = message.data) == null ? void 0 : _message$data.sessionId)) {
|
|
322
283
|
utils.logger.debug('open event received from wallet, but does not match sessionId', this._sessionId);
|
|
323
284
|
return;
|
|
324
|
-
}
|
|
325
|
-
|
|
285
|
+
}
|
|
326
286
|
|
|
287
|
+
// check if open error occured due to invalid defaultNetworkId
|
|
327
288
|
if ((_message$data2 = message.data) != null && _message$data2.error) {
|
|
328
289
|
var _message$data3;
|
|
329
|
-
|
|
330
290
|
const err = new Error(`opening wallet failed: received ${(_message$data3 = message.data) == null ? void 0 : _message$data3.error}`);
|
|
331
291
|
utils.logger.error(err);
|
|
332
292
|
this.close();
|
|
333
293
|
throw err;
|
|
334
|
-
}
|
|
335
|
-
|
|
294
|
+
}
|
|
336
295
|
|
|
296
|
+
// success!
|
|
337
297
|
this.state = exports.OpenState.OPENED;
|
|
338
298
|
this.openPayload = message.data;
|
|
339
|
-
this.events.emit('open', this.openPayload);
|
|
299
|
+
this.events.emit('open', this.openPayload);
|
|
340
300
|
|
|
301
|
+
// flush pending requests when connected
|
|
341
302
|
if (this.pendingMessageRequests.length !== 0) {
|
|
342
303
|
const pendingMessageRequests = this.pendingMessageRequests.splice(0, this.pendingMessageRequests.length);
|
|
343
304
|
pendingMessageRequests.forEach(async function (pendingMessageRequest) {
|
|
344
305
|
_this2.sendMessage(pendingMessageRequest);
|
|
345
306
|
});
|
|
346
307
|
}
|
|
347
|
-
|
|
348
308
|
return;
|
|
349
|
-
}
|
|
350
|
-
|
|
309
|
+
}
|
|
351
310
|
|
|
311
|
+
// MESSAGE resposne
|
|
352
312
|
if (message.type === exports.EventType.MESSAGE) {
|
|
353
313
|
// Require user confirmation, bring up wallet to prompt for input then close
|
|
354
314
|
// TODO: perhaps apply technique like in multicall to queue messages within
|
|
@@ -366,22 +326,21 @@ class BaseProviderTransport {
|
|
|
366
326
|
// or when we register two handler, or duplicate messages with the same idx are sent,
|
|
367
327
|
// all of which should be prevented prior to getting to this point
|
|
368
328
|
throw new Error('impossible state');
|
|
369
|
-
}
|
|
370
|
-
|
|
329
|
+
}
|
|
371
330
|
|
|
331
|
+
// Callback to original caller
|
|
372
332
|
if (responseCallback) {
|
|
373
333
|
this.events.emit('message', message);
|
|
374
334
|
responseCallback(message.data.error, message);
|
|
375
335
|
return;
|
|
376
336
|
}
|
|
377
|
-
}
|
|
378
|
-
|
|
337
|
+
}
|
|
379
338
|
|
|
339
|
+
// ACCOUNTS_CHANGED -- when a user logs in or out
|
|
380
340
|
if (message.type === exports.EventType.ACCOUNTS_CHANGED) {
|
|
381
341
|
this.accountsChangedPayload = {
|
|
382
342
|
accounts: []
|
|
383
343
|
};
|
|
384
|
-
|
|
385
344
|
if (message.data && message.data.length > 0) {
|
|
386
345
|
this.accountsChangedPayload = {
|
|
387
346
|
accounts: [ethers.ethers.utils.getAddress(message.data[0])],
|
|
@@ -391,76 +350,73 @@ class BaseProviderTransport {
|
|
|
391
350
|
} else {
|
|
392
351
|
this.events.emit('accountsChanged', [], message.origin);
|
|
393
352
|
}
|
|
394
|
-
|
|
395
353
|
return;
|
|
396
|
-
}
|
|
397
|
-
|
|
354
|
+
}
|
|
398
355
|
|
|
356
|
+
// CHAIN_CHANGED -- when a user changes their default chain
|
|
399
357
|
if (message.type === exports.EventType.CHAIN_CHANGED) {
|
|
400
358
|
this.events.emit('chainChanged', message.data);
|
|
401
359
|
return;
|
|
402
|
-
}
|
|
403
|
-
|
|
360
|
+
}
|
|
404
361
|
|
|
362
|
+
// NOTIFY NETWORKS -- when a user connects or logs in
|
|
405
363
|
if (message.type === exports.EventType.NETWORKS) {
|
|
406
364
|
this.networksPayload = message.data;
|
|
407
365
|
this.events.emit('networks', this.networksPayload);
|
|
408
366
|
return;
|
|
409
|
-
}
|
|
410
|
-
|
|
367
|
+
}
|
|
411
368
|
|
|
369
|
+
// NOTIFY WALLET_CONTEXT -- when a user connects or logs in
|
|
412
370
|
if (message.type === exports.EventType.WALLET_CONTEXT) {
|
|
413
371
|
this.walletContextPayload = message.data;
|
|
414
372
|
this.events.emit('walletContext', this.walletContextPayload);
|
|
415
373
|
return;
|
|
416
|
-
}
|
|
417
|
-
|
|
374
|
+
}
|
|
418
375
|
|
|
376
|
+
// NOTIFY CLOSE -- when wallet instructs to close
|
|
419
377
|
if (message.type === exports.EventType.CLOSE) {
|
|
420
378
|
if (this.state !== exports.OpenState.CLOSED) {
|
|
421
379
|
this.close(message.data);
|
|
422
380
|
}
|
|
423
|
-
}
|
|
424
|
-
|
|
381
|
+
}
|
|
425
382
|
|
|
383
|
+
// NOTIFY CONNECT -- when wallet instructs we've connected
|
|
426
384
|
if (message.type === exports.EventType.CONNECT) {
|
|
427
385
|
this.connectPayload = message.data;
|
|
428
386
|
this.events.emit('connect', this.connectPayload);
|
|
429
|
-
}
|
|
430
|
-
|
|
387
|
+
}
|
|
431
388
|
|
|
389
|
+
// NOTIFY DISCONNECT -- when wallet instructs to disconnect
|
|
432
390
|
if (message.type === exports.EventType.DISCONNECT) {
|
|
433
391
|
if (this.isConnected()) {
|
|
434
392
|
this.events.emit('disconnect', message.data);
|
|
435
393
|
this.close();
|
|
436
394
|
}
|
|
437
395
|
}
|
|
438
|
-
}
|
|
396
|
+
}
|
|
439
397
|
|
|
398
|
+
// sendMessageRequest sends a ProviderMessageRequest over the wire to the wallet
|
|
440
399
|
|
|
441
400
|
sendMessage(message) {
|
|
442
401
|
throw new Error('abstract method');
|
|
443
402
|
}
|
|
444
|
-
|
|
445
403
|
on(event, fn) {
|
|
446
404
|
this.events.on(event, fn);
|
|
447
405
|
}
|
|
448
|
-
|
|
449
406
|
once(event, fn) {
|
|
450
407
|
this.events.once(event, fn);
|
|
451
408
|
}
|
|
452
|
-
|
|
453
409
|
emit(event, ...args) {
|
|
454
410
|
return this.events.emit(event, ...args);
|
|
455
411
|
}
|
|
456
|
-
|
|
457
412
|
close(error) {
|
|
458
413
|
if (this.state === exports.OpenState.CLOSED) return;
|
|
459
414
|
this.state = exports.OpenState.CLOSED;
|
|
460
415
|
this.confirmationOnly = false;
|
|
461
416
|
this._sessionId = undefined;
|
|
462
|
-
utils.logger.info('closing wallet and flushing!');
|
|
417
|
+
utils.logger.info('closing wallet and flushing!');
|
|
463
418
|
|
|
419
|
+
// flush pending requests and return error to all callbacks
|
|
464
420
|
this.pendingMessageRequests.length = 0;
|
|
465
421
|
this.responseCallbacks.forEach(responseCallback => {
|
|
466
422
|
responseCallback(_extends({}, new Error('wallet closed'), {
|
|
@@ -475,7 +431,6 @@ class BaseProviderTransport {
|
|
|
475
431
|
this.walletContextPayload = undefined;
|
|
476
432
|
this.events.emit('close', error);
|
|
477
433
|
}
|
|
478
|
-
|
|
479
434
|
}
|
|
480
435
|
|
|
481
436
|
const SIGNER_READY_TIMEOUT = 10000;
|
|
@@ -483,12 +438,13 @@ class WalletRequestHandler {
|
|
|
483
438
|
// signer interface of the wallet. A null value means there is no signer (ie. user not signed in). An undefined
|
|
484
439
|
// value means the signer state is unknown, usually meaning the wallet app is booting up and initializing. Of course
|
|
485
440
|
// a Signer value is the actually interface to a signed-in account
|
|
486
|
-
constructor(_signer, prompter, mainnetNetworks, testnetNetworks = []) {
|
|
487
|
-
var _this = this;
|
|
488
441
|
|
|
442
|
+
constructor(_signer, prompter, auxDataProvider, mainnetNetworks, testnetNetworks = []) {
|
|
443
|
+
var _this = this;
|
|
489
444
|
this.signer = void 0;
|
|
490
445
|
this.signerReadyCallbacks = [];
|
|
491
446
|
this.prompter = void 0;
|
|
447
|
+
this.auxDataProvider = void 0;
|
|
492
448
|
this.mainnetNetworks = void 0;
|
|
493
449
|
this.testnetNetworks = void 0;
|
|
494
450
|
this._openIntent = void 0;
|
|
@@ -496,32 +452,26 @@ class WalletRequestHandler {
|
|
|
496
452
|
this._defaultNetworkId = void 0;
|
|
497
453
|
this._chainId = void 0;
|
|
498
454
|
this.events = new eventemitter2.EventEmitter2();
|
|
499
|
-
|
|
500
455
|
this.promptConnect = async function (options) {
|
|
501
456
|
if (!options && !_this._connectOptions) {
|
|
502
457
|
// this is an unexpected state and should not happen
|
|
503
458
|
throw new Error('prompter connect options are empty');
|
|
504
459
|
}
|
|
505
|
-
|
|
506
460
|
if (!_this.prompter) {
|
|
507
461
|
// if prompter is null, we'll auto connect
|
|
508
462
|
return _this.connect(options);
|
|
509
463
|
}
|
|
510
|
-
|
|
511
464
|
const promptConnectDetails = await _this.prompter.promptConnect(options || _this._connectOptions).catch(_ => {
|
|
512
465
|
return {
|
|
513
466
|
connected: false
|
|
514
467
|
};
|
|
515
468
|
});
|
|
516
469
|
const connectDetails = promptConnectDetails;
|
|
517
|
-
|
|
518
470
|
if (connectDetails.connected && !connectDetails.session) {
|
|
519
471
|
connectDetails.session = await _this.walletSession();
|
|
520
472
|
}
|
|
521
|
-
|
|
522
473
|
return promptConnectDetails;
|
|
523
474
|
};
|
|
524
|
-
|
|
525
475
|
this.sendAsync = async function (request, callback, chainId) {
|
|
526
476
|
const response = {
|
|
527
477
|
jsonrpc: '2.0',
|
|
@@ -529,21 +479,20 @@ class WalletRequestHandler {
|
|
|
529
479
|
result: null
|
|
530
480
|
};
|
|
531
481
|
await _this.getSigner();
|
|
532
|
-
|
|
533
482
|
try {
|
|
534
483
|
// only allow public json rpc method to the provider when user is not logged in, aka signer is not set
|
|
535
484
|
if ((!_this.signer || _this.signer === null) && !permittedJsonRpcMethods.includes(request.method)) {
|
|
536
485
|
// throw new Error(`not logged in. ${request.method} is unavailable`)
|
|
537
486
|
throw ErrSignedInRequired;
|
|
538
|
-
}
|
|
539
|
-
|
|
487
|
+
}
|
|
540
488
|
|
|
489
|
+
// wallet signer
|
|
541
490
|
const signer = _this.signer;
|
|
542
|
-
if (!signer) throw new Error('WalletRequestHandler: wallet signer is not configured');
|
|
491
|
+
if (!signer) throw new Error('WalletRequestHandler: wallet signer is not configured');
|
|
543
492
|
|
|
493
|
+
// fetch the provider for the specific chain, or undefined will select defaultChain
|
|
544
494
|
const provider = await signer.getProvider(chainId);
|
|
545
495
|
if (!provider) throw new Error(`WalletRequestHandler: wallet provider is not configured for chainId ${chainId}`);
|
|
546
|
-
|
|
547
496
|
switch (request.method) {
|
|
548
497
|
case 'net_version':
|
|
549
498
|
{
|
|
@@ -551,21 +500,18 @@ class WalletRequestHandler {
|
|
|
551
500
|
response.result = result;
|
|
552
501
|
break;
|
|
553
502
|
}
|
|
554
|
-
|
|
555
503
|
case 'eth_chainId':
|
|
556
504
|
{
|
|
557
505
|
const result = await provider.send('eth_chainId', []);
|
|
558
506
|
response.result = result;
|
|
559
507
|
break;
|
|
560
508
|
}
|
|
561
|
-
|
|
562
509
|
case 'eth_accounts':
|
|
563
510
|
{
|
|
564
511
|
const walletAddress = await signer.getAddress();
|
|
565
512
|
response.result = [walletAddress];
|
|
566
513
|
break;
|
|
567
514
|
}
|
|
568
|
-
|
|
569
515
|
case 'eth_getBalance':
|
|
570
516
|
{
|
|
571
517
|
const [accountAddress, blockTag] = request.params;
|
|
@@ -573,15 +519,15 @@ class WalletRequestHandler {
|
|
|
573
519
|
response.result = walletBalance.toHexString();
|
|
574
520
|
break;
|
|
575
521
|
}
|
|
576
|
-
|
|
577
522
|
case 'personal_sign':
|
|
578
523
|
case 'eth_sign':
|
|
579
524
|
{
|
|
580
525
|
// note: message from json-rpc input is in hex format
|
|
581
|
-
let message;
|
|
526
|
+
let message;
|
|
527
|
+
|
|
528
|
+
// there is a difference in the order of the params:
|
|
582
529
|
// personal_sign: [data, address]
|
|
583
530
|
// eth_sign: [address, data]
|
|
584
|
-
|
|
585
531
|
if (request.method === 'personal_sign') {
|
|
586
532
|
const [data, address] = request.params;
|
|
587
533
|
message = data;
|
|
@@ -589,19 +535,19 @@ class WalletRequestHandler {
|
|
|
589
535
|
const [address, data] = request.params;
|
|
590
536
|
message = data;
|
|
591
537
|
}
|
|
538
|
+
let sig = '';
|
|
592
539
|
|
|
593
|
-
|
|
540
|
+
// Message must be prefixed with "\x19Ethereum Signed Message:\n"
|
|
594
541
|
// as defined by EIP-191
|
|
542
|
+
const prefixedMessage = prefixEIP191Message(message);
|
|
595
543
|
|
|
596
|
-
|
|
544
|
+
// TODO:
|
|
597
545
|
// if (process.env.TEST_MODE === 'true' && this.prompter === null) {
|
|
598
|
-
|
|
599
546
|
if (_this.prompter === null) {
|
|
600
547
|
// prompter is null, so we'll sign from here
|
|
601
548
|
sig = await signer.signMessage(prefixedMessage, chainId);
|
|
602
549
|
} else {
|
|
603
550
|
const promptResultForDeployment = await _this.handleConfirmWalletDeployPrompt(_this.prompter, signer, chainId);
|
|
604
|
-
|
|
605
551
|
if (promptResultForDeployment) {
|
|
606
552
|
sig = await _this.prompter.promptSignMessage({
|
|
607
553
|
chainId: chainId,
|
|
@@ -609,17 +555,14 @@ class WalletRequestHandler {
|
|
|
609
555
|
}, _this.connectOptions);
|
|
610
556
|
}
|
|
611
557
|
}
|
|
612
|
-
|
|
613
558
|
if (sig && sig.length > 0) {
|
|
614
559
|
response.result = sig;
|
|
615
560
|
} else {
|
|
616
561
|
// The user has declined the request when value is null
|
|
617
562
|
throw new Error('declined by user');
|
|
618
563
|
}
|
|
619
|
-
|
|
620
564
|
break;
|
|
621
565
|
}
|
|
622
|
-
|
|
623
566
|
case 'eth_signTypedData':
|
|
624
567
|
case 'eth_signTypedData_v4':
|
|
625
568
|
{
|
|
@@ -627,7 +570,6 @@ class WalletRequestHandler {
|
|
|
627
570
|
// should be an object, but in some instances may be double string encoded
|
|
628
571
|
const [signingAddress, typedDataObject] = request.params;
|
|
629
572
|
let typedData = undefined;
|
|
630
|
-
|
|
631
573
|
if (typeof typedDataObject === 'string') {
|
|
632
574
|
try {
|
|
633
575
|
typedData = JSON.parse(typedDataObject);
|
|
@@ -635,19 +577,15 @@ class WalletRequestHandler {
|
|
|
635
577
|
} else {
|
|
636
578
|
typedData = typedDataObject;
|
|
637
579
|
}
|
|
638
|
-
|
|
639
580
|
if (!typedData || !typedData.domain || !typedData.types || !typedData.message) {
|
|
640
581
|
throw new Error('invalid typedData object');
|
|
641
582
|
}
|
|
642
|
-
|
|
643
583
|
let sig = '';
|
|
644
|
-
|
|
645
584
|
if (_this.prompter === null) {
|
|
646
585
|
// prompter is null, so we'll sign from here
|
|
647
586
|
sig = await signer.signTypedData(typedData.domain, typedData.types, typedData.message, chainId);
|
|
648
587
|
} else {
|
|
649
588
|
const promptResultForDeployment = await _this.handleConfirmWalletDeployPrompt(_this.prompter, signer, chainId);
|
|
650
|
-
|
|
651
589
|
if (promptResultForDeployment) {
|
|
652
590
|
sig = await _this.prompter.promptSignMessage({
|
|
653
591
|
chainId: chainId,
|
|
@@ -655,30 +593,26 @@ class WalletRequestHandler {
|
|
|
655
593
|
}, _this.connectOptions);
|
|
656
594
|
}
|
|
657
595
|
}
|
|
658
|
-
|
|
659
596
|
if (sig && sig.length > 0) {
|
|
660
597
|
response.result = sig;
|
|
661
598
|
} else {
|
|
662
599
|
// The user has declined the request when value is null
|
|
663
600
|
throw new Error('declined by user');
|
|
664
601
|
}
|
|
665
|
-
|
|
666
602
|
break;
|
|
667
603
|
}
|
|
668
|
-
|
|
669
604
|
case 'eth_sendTransaction':
|
|
670
605
|
{
|
|
671
606
|
// https://eth.wiki/json-rpc/API#eth_sendtransaction
|
|
672
|
-
const [transactionParams] = request.params;
|
|
673
|
-
// ethers and sequence use 'gasLimit'
|
|
607
|
+
const [transactionParams] = request.params;
|
|
674
608
|
|
|
609
|
+
// eth_sendTransaction uses 'gas'
|
|
610
|
+
// ethers and sequence use 'gasLimit'
|
|
675
611
|
if ('gas' in transactionParams && transactionParams.gasLimit === undefined) {
|
|
676
612
|
transactionParams.gasLimit = transactionParams.gas;
|
|
677
613
|
delete transactionParams.gas;
|
|
678
614
|
}
|
|
679
|
-
|
|
680
615
|
let txnHash = '';
|
|
681
|
-
|
|
682
616
|
if (_this.prompter === null) {
|
|
683
617
|
// prompter is null, so we'll send from here
|
|
684
618
|
const txnResponse = await signer.sendTransaction(transactionParams, chainId);
|
|
@@ -687,27 +621,22 @@ class WalletRequestHandler {
|
|
|
687
621
|
// prompt user to provide the response
|
|
688
622
|
txnHash = await _this.prompter.promptSendTransaction(transactionParams, chainId, _this.connectOptions);
|
|
689
623
|
}
|
|
690
|
-
|
|
691
624
|
if (txnHash) {
|
|
692
625
|
response.result = txnHash;
|
|
693
626
|
} else {
|
|
694
627
|
// The user has declined the request when value is null
|
|
695
628
|
throw new Error('declined by user');
|
|
696
629
|
}
|
|
697
|
-
|
|
698
630
|
break;
|
|
699
631
|
}
|
|
700
|
-
|
|
701
632
|
case 'eth_signTransaction':
|
|
702
633
|
{
|
|
703
634
|
// https://eth.wiki/json-rpc/API#eth_signTransaction
|
|
704
635
|
const [transaction] = request.params;
|
|
705
636
|
const sender = ethers.ethers.utils.getAddress(transaction.from);
|
|
706
|
-
|
|
707
637
|
if (sender !== (await signer.getAddress())) {
|
|
708
638
|
throw new Error('sender address does not match wallet');
|
|
709
639
|
}
|
|
710
|
-
|
|
711
640
|
if (_this.prompter === null) {
|
|
712
641
|
// The eth_signTransaction method expects a `string` return value we instead return a `SignedTransactions` object,
|
|
713
642
|
// this can only be broadcasted using an RPC provider with support for signed Sequence transactions, like this one.
|
|
@@ -718,14 +647,13 @@ class WalletRequestHandler {
|
|
|
718
647
|
} else {
|
|
719
648
|
response.result = await _this.prompter.promptSignTransaction(transaction, chainId, _this.connectOptions);
|
|
720
649
|
}
|
|
721
|
-
|
|
722
650
|
break;
|
|
723
651
|
}
|
|
724
|
-
|
|
725
652
|
case 'eth_sendRawTransaction':
|
|
726
653
|
{
|
|
727
654
|
// NOTE: we're not using a prompter here as the transaction is already signed
|
|
728
655
|
// and would have prompted the user upon signing.
|
|
656
|
+
|
|
729
657
|
// https://eth.wiki/json-rpc/API#eth_sendRawTransaction
|
|
730
658
|
if (transactions.isSignedTransactions(request.params[0])) {
|
|
731
659
|
const txChainId = ethers.BigNumber.from(request.params[0].chainId).toNumber();
|
|
@@ -735,16 +663,13 @@ class WalletRequestHandler {
|
|
|
735
663
|
const tx = await provider.sendTransaction(request.params[0]);
|
|
736
664
|
response.result = tx.hash;
|
|
737
665
|
}
|
|
738
|
-
|
|
739
666
|
break;
|
|
740
667
|
}
|
|
741
|
-
|
|
742
668
|
case 'eth_getTransactionCount':
|
|
743
669
|
{
|
|
744
670
|
const address = ethers.ethers.utils.getAddress(request.params[0]);
|
|
745
671
|
const tag = request.params[1];
|
|
746
672
|
const walletAddress = ethers.ethers.utils.getAddress(await signer.getAddress());
|
|
747
|
-
|
|
748
673
|
if (address === walletAddress) {
|
|
749
674
|
const count = await signer.getTransactionCount(tag);
|
|
750
675
|
response.result = ethers.ethers.BigNumber.from(count).toHexString();
|
|
@@ -752,111 +677,91 @@ class WalletRequestHandler {
|
|
|
752
677
|
const count = await provider.getTransactionCount(address, tag);
|
|
753
678
|
response.result = ethers.ethers.BigNumber.from(count).toHexString();
|
|
754
679
|
}
|
|
755
|
-
|
|
756
680
|
break;
|
|
757
681
|
}
|
|
758
|
-
|
|
759
682
|
case 'eth_blockNumber':
|
|
760
683
|
{
|
|
761
684
|
response.result = await provider.getBlockNumber();
|
|
762
685
|
break;
|
|
763
686
|
}
|
|
764
|
-
|
|
765
687
|
case 'eth_getBlockByNumber':
|
|
766
688
|
{
|
|
767
|
-
response.result = await provider.getBlock(request.params[0]
|
|
768
|
-
/* , jsonRpcRequest.params[1] */
|
|
769
|
-
);
|
|
689
|
+
response.result = await provider.getBlock(request.params[0] /* , jsonRpcRequest.params[1] */);
|
|
770
690
|
break;
|
|
771
691
|
}
|
|
772
|
-
|
|
773
692
|
case 'eth_getBlockByHash':
|
|
774
693
|
{
|
|
775
|
-
response.result = await provider.getBlock(request.params[0]
|
|
776
|
-
/* , jsonRpcRequest.params[1] */
|
|
777
|
-
);
|
|
694
|
+
response.result = await provider.getBlock(request.params[0] /* , jsonRpcRequest.params[1] */);
|
|
778
695
|
break;
|
|
779
696
|
}
|
|
780
|
-
|
|
781
697
|
case 'eth_getTransactionByHash':
|
|
782
698
|
{
|
|
783
699
|
response.result = await provider.getTransaction(request.params[0]);
|
|
784
700
|
break;
|
|
785
701
|
}
|
|
786
|
-
|
|
787
702
|
case 'eth_call':
|
|
788
703
|
{
|
|
789
704
|
const [transactionObject, blockTag] = request.params;
|
|
790
705
|
response.result = await provider.call(transactionObject, blockTag);
|
|
791
706
|
break;
|
|
792
707
|
}
|
|
793
|
-
|
|
794
708
|
case 'eth_getCode':
|
|
795
709
|
{
|
|
796
710
|
const [contractAddress, blockTag] = request.params;
|
|
797
711
|
response.result = await provider.getCode(contractAddress, blockTag);
|
|
798
712
|
break;
|
|
799
713
|
}
|
|
800
|
-
|
|
801
714
|
case 'eth_estimateGas':
|
|
802
715
|
{
|
|
803
716
|
const [transactionObject] = request.params;
|
|
804
717
|
response.result = await provider.estimateGas(transactionObject);
|
|
805
718
|
break;
|
|
806
719
|
}
|
|
807
|
-
|
|
808
720
|
case 'eth_gasPrice':
|
|
809
721
|
{
|
|
810
722
|
const gasPrice = await provider.getGasPrice();
|
|
811
723
|
response.result = gasPrice.toHexString();
|
|
812
724
|
break;
|
|
813
725
|
}
|
|
814
|
-
|
|
815
726
|
case 'wallet_switchEthereumChain':
|
|
816
727
|
{
|
|
817
728
|
const [switchParams] = request.params;
|
|
818
|
-
|
|
819
729
|
if (!switchParams.chainId || switchParams.chainId.length === 0) {
|
|
820
730
|
throw new Error('invalid chainId');
|
|
821
731
|
}
|
|
822
|
-
|
|
823
732
|
const _chainId = ethers.ethers.BigNumber.from(switchParams.chainId);
|
|
824
|
-
|
|
825
733
|
const ok = await _this.setDefaultNetwork(_chainId.toString(), true);
|
|
826
|
-
|
|
827
734
|
if (!ok) {
|
|
828
735
|
throw new Error(`unable to set chainId ${_chainId}`);
|
|
829
736
|
}
|
|
830
|
-
|
|
831
737
|
response.result = null; // success
|
|
832
|
-
|
|
833
738
|
break;
|
|
834
739
|
}
|
|
835
|
-
// smart wallet method
|
|
836
740
|
|
|
741
|
+
// smart wallet method
|
|
837
742
|
case 'sequence_getWalletContext':
|
|
838
743
|
{
|
|
839
744
|
response.result = await signer.getWalletContext();
|
|
840
745
|
break;
|
|
841
746
|
}
|
|
842
|
-
// smart wallet method
|
|
843
747
|
|
|
748
|
+
// smart wallet method
|
|
844
749
|
case 'sequence_getWalletConfig':
|
|
845
750
|
{
|
|
846
751
|
const [_chainId2] = request.params;
|
|
847
752
|
response.result = await signer.getWalletConfig(_chainId2);
|
|
848
753
|
break;
|
|
849
754
|
}
|
|
850
|
-
// smart wallet method
|
|
851
755
|
|
|
756
|
+
// smart wallet method
|
|
852
757
|
case 'sequence_getWalletState':
|
|
853
758
|
{
|
|
854
759
|
const [_chainId3] = request.params;
|
|
855
760
|
response.result = await signer.getWalletState(_chainId3);
|
|
856
761
|
break;
|
|
857
762
|
}
|
|
858
|
-
// smart wallet method
|
|
859
763
|
|
|
764
|
+
// smart wallet method
|
|
860
765
|
case 'sequence_getNetworks':
|
|
861
766
|
{
|
|
862
767
|
// NOTE: must ensure that the response result below returns clean serialized data, which is to omit
|
|
@@ -865,67 +770,62 @@ class WalletRequestHandler {
|
|
|
865
770
|
response.result = await _this.getNetworks(true);
|
|
866
771
|
break;
|
|
867
772
|
}
|
|
868
|
-
// smart wallet method
|
|
869
773
|
|
|
774
|
+
// smart wallet method
|
|
870
775
|
case 'sequence_updateConfig':
|
|
871
776
|
{
|
|
872
|
-
throw new Error('sequence_updateConfig method is not allowed from a dapp');
|
|
777
|
+
throw new Error('sequence_updateConfig method is not allowed from a dapp');
|
|
778
|
+
// NOTE: method is disabled as we don't need a dapp to request to update a config.
|
|
873
779
|
// However, if we ever want this, we can enable it but must also use the prompter
|
|
874
780
|
// for confirmation.
|
|
875
781
|
//
|
|
876
782
|
// const [newConfig] = request.params
|
|
877
783
|
// response.result = await signer.updateConfig(newConfig)
|
|
878
|
-
|
|
879
784
|
break;
|
|
880
785
|
}
|
|
881
|
-
// smart wallet method
|
|
882
786
|
|
|
787
|
+
// smart wallet method
|
|
883
788
|
case 'sequence_publishConfig':
|
|
884
789
|
{
|
|
885
790
|
throw new Error('sequence_publishConfig method is not allowed from a dapp');
|
|
886
791
|
break;
|
|
887
792
|
}
|
|
888
|
-
// relayer method
|
|
889
793
|
|
|
794
|
+
// relayer method
|
|
890
795
|
case 'sequence_gasRefundOptions':
|
|
891
796
|
{
|
|
892
797
|
// TODO
|
|
893
798
|
break;
|
|
894
799
|
}
|
|
895
|
-
// relayer method
|
|
896
800
|
|
|
801
|
+
// relayer method
|
|
897
802
|
case 'sequence_getNonce':
|
|
898
803
|
{
|
|
899
804
|
// TODO
|
|
900
805
|
break;
|
|
901
806
|
}
|
|
902
|
-
// relayer method
|
|
903
807
|
|
|
808
|
+
// relayer method
|
|
904
809
|
case 'sequence_relay':
|
|
905
810
|
{
|
|
906
811
|
// TODO
|
|
907
812
|
break;
|
|
908
813
|
}
|
|
909
|
-
// set default network of wallet
|
|
910
814
|
|
|
815
|
+
// set default network of wallet
|
|
911
816
|
case 'sequence_setDefaultNetwork':
|
|
912
817
|
{
|
|
913
818
|
const [defaultNetworkId] = request.params;
|
|
914
|
-
|
|
915
819
|
if (!defaultNetworkId) {
|
|
916
820
|
throw new Error('invalid request, method argument defaultNetworkId cannot be empty');
|
|
917
821
|
}
|
|
918
|
-
|
|
919
822
|
const ok = await _this.setDefaultNetwork(defaultNetworkId);
|
|
920
|
-
|
|
921
823
|
if (!ok) {
|
|
922
824
|
throw new Error(`unable to set default network ${defaultNetworkId}`);
|
|
923
825
|
}
|
|
924
|
-
|
|
925
826
|
response.result = await _this.getNetworks(true);
|
|
926
827
|
break;
|
|
927
828
|
}
|
|
928
|
-
|
|
929
829
|
default:
|
|
930
830
|
{
|
|
931
831
|
// NOTE: provider here will be chain-bound if chainId is provided
|
|
@@ -934,38 +834,33 @@ class WalletRequestHandler {
|
|
|
934
834
|
}
|
|
935
835
|
}
|
|
936
836
|
} catch (err) {
|
|
937
|
-
utils.logger.error(err);
|
|
837
|
+
utils.logger.error(err);
|
|
938
838
|
|
|
839
|
+
// See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1193.md#rpc-errors
|
|
939
840
|
response.result = null;
|
|
940
841
|
response.error = _extends({}, new Error(err), {
|
|
941
842
|
code: 4001
|
|
942
843
|
});
|
|
943
844
|
}
|
|
944
|
-
|
|
945
845
|
callback(undefined, response);
|
|
946
846
|
};
|
|
947
|
-
|
|
948
847
|
this.isSignedIn = async function () {
|
|
949
848
|
await _this.signerReady();
|
|
950
849
|
return !!_this.signer;
|
|
951
850
|
};
|
|
952
|
-
|
|
953
851
|
this.getSigner = async function () {
|
|
954
852
|
await _this.signerReady();
|
|
955
|
-
|
|
956
853
|
if (_this.signer === undefined) {
|
|
957
854
|
throw new Error('signerReady failed resolve');
|
|
958
855
|
}
|
|
959
|
-
|
|
960
856
|
return _this.signer;
|
|
961
857
|
};
|
|
962
|
-
|
|
963
858
|
this.signer = _signer;
|
|
964
859
|
this.prompter = prompter;
|
|
860
|
+
this.auxDataProvider = auxDataProvider;
|
|
965
861
|
this.mainnetNetworks = mainnetNetworks;
|
|
966
862
|
this.testnetNetworks = testnetNetworks;
|
|
967
863
|
}
|
|
968
|
-
|
|
969
864
|
async signIn(signer, options = {}) {
|
|
970
865
|
this.setSigner(signer);
|
|
971
866
|
const {
|
|
@@ -974,26 +869,23 @@ class WalletRequestHandler {
|
|
|
974
869
|
testnetNetworks,
|
|
975
870
|
defaultNetworkId
|
|
976
871
|
} = options;
|
|
977
|
-
|
|
978
872
|
if (mainnetNetworks && mainnetNetworks.length > 0) {
|
|
979
873
|
this.mainnetNetworks = mainnetNetworks;
|
|
980
874
|
}
|
|
981
|
-
|
|
982
875
|
if (testnetNetworks && testnetNetworks.length > 0) {
|
|
983
876
|
this.testnetNetworks = testnetNetworks;
|
|
984
877
|
}
|
|
985
|
-
|
|
986
878
|
if ((!this.mainnetNetworks || this.mainnetNetworks.length === 0) && (!this.testnetNetworks || this.testnetNetworks.length === 0)) {
|
|
987
879
|
throw new Error('signIn failed as network configuration is empty');
|
|
988
880
|
}
|
|
989
|
-
|
|
990
881
|
const networkId = defaultNetworkId || this._defaultNetworkId;
|
|
991
|
-
|
|
992
882
|
if (networkId) {
|
|
993
883
|
if (!(await this.setDefaultNetwork(networkId, false))) {
|
|
994
884
|
throw new Error(`WalletRequestHandler setup unable to set defaultNetworkId ${networkId}`);
|
|
995
885
|
}
|
|
996
|
-
}
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
// Optionally, connect the dapp and wallet. In case connectOptions are provided, we will perform
|
|
997
889
|
// necessary auth request, and then notify the dapp of the 'connect' details.
|
|
998
890
|
//
|
|
999
891
|
// NOTE: if a user is signing into a dapp from a fresh state, and and auth request is made
|
|
@@ -1001,30 +893,24 @@ class WalletRequestHandler {
|
|
|
1001
893
|
// for this dapp, so its safe to authorize in the connect() method without the prompt.
|
|
1002
894
|
//
|
|
1003
895
|
// NOTE: signIn can optionally connect and notify dapp at this time for new signIn flows
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
896
|
if (connect) {
|
|
1007
897
|
const connectOptions = this._connectOptions;
|
|
1008
898
|
const connectDetails = await this.connect(connectOptions);
|
|
1009
899
|
this.notifyConnect(connectDetails);
|
|
1010
|
-
|
|
1011
900
|
if (!connectOptions || connectOptions.keepWalletOpened !== true) {
|
|
1012
901
|
this.notifyClose();
|
|
1013
902
|
}
|
|
1014
903
|
}
|
|
1015
904
|
}
|
|
1016
|
-
|
|
1017
905
|
signOut() {
|
|
1018
906
|
// signed out state
|
|
1019
907
|
this.setSigner(null);
|
|
1020
908
|
}
|
|
1021
|
-
|
|
1022
909
|
signerReset() {
|
|
1023
910
|
// resetting signer puts the wallet in an uninitialized state, which requires the app to
|
|
1024
911
|
// re-initiatize and set the signer either as "null" (ie. no signer) or "Signer" (ie. signed in).
|
|
1025
912
|
this.signer = undefined;
|
|
1026
913
|
}
|
|
1027
|
-
|
|
1028
914
|
signerReady(timeout = SIGNER_READY_TIMEOUT) {
|
|
1029
915
|
return new Promise((resolve, reject) => {
|
|
1030
916
|
if (this.signer !== undefined) {
|
|
@@ -1040,7 +926,6 @@ class WalletRequestHandler {
|
|
|
1040
926
|
}
|
|
1041
927
|
});
|
|
1042
928
|
}
|
|
1043
|
-
|
|
1044
929
|
async connect(options) {
|
|
1045
930
|
if (!this.signer) {
|
|
1046
931
|
return {
|
|
@@ -1049,12 +934,17 @@ class WalletRequestHandler {
|
|
|
1049
934
|
error: 'unable to connect without signed in account'
|
|
1050
935
|
};
|
|
1051
936
|
}
|
|
1052
|
-
|
|
1053
937
|
const connectDetails = {
|
|
1054
938
|
connected: true,
|
|
1055
939
|
chainId: ethers.ethers.utils.hexlify(await this.getChainId())
|
|
1056
940
|
};
|
|
1057
|
-
|
|
941
|
+
if (options && options.askForEmail) {
|
|
942
|
+
var _this$auxDataProvider;
|
|
943
|
+
const email = await ((_this$auxDataProvider = this.auxDataProvider) == null ? void 0 : _this$auxDataProvider.get('email'));
|
|
944
|
+
if (email) {
|
|
945
|
+
connectDetails.email = email;
|
|
946
|
+
}
|
|
947
|
+
}
|
|
1058
948
|
if (options && options.authorize) {
|
|
1059
949
|
// Perform ethauth eip712 request and construct the ConnectDetails response
|
|
1060
950
|
// including the auth proof
|
|
@@ -1062,7 +952,8 @@ class WalletRequestHandler {
|
|
|
1062
952
|
app: options.app,
|
|
1063
953
|
origin: options.origin,
|
|
1064
954
|
expiry: options.expiry
|
|
1065
|
-
};
|
|
955
|
+
};
|
|
956
|
+
// if (typeof(options.authorize) === 'object') {
|
|
1066
957
|
// authOptions = { ...authOptions, ...options.authorize }
|
|
1067
958
|
// }
|
|
1068
959
|
|
|
@@ -1076,13 +967,12 @@ class WalletRequestHandler {
|
|
|
1076
967
|
error: `signAuthorization failed: ${err.message}`
|
|
1077
968
|
};
|
|
1078
969
|
}
|
|
1079
|
-
}
|
|
1080
|
-
|
|
970
|
+
}
|
|
1081
971
|
|
|
972
|
+
// Build session response for connect details
|
|
1082
973
|
connectDetails.session = await this.walletSession();
|
|
1083
974
|
return connectDetails;
|
|
1084
975
|
}
|
|
1085
|
-
|
|
1086
976
|
// sendMessageRequest will unwrap the ProviderMessageRequest and send it to the JsonRpcHandler
|
|
1087
977
|
// (aka, the signer in this instance) and then responds with a wrapped response of
|
|
1088
978
|
// ProviderMessageResponse to be sent over the transport
|
|
@@ -1090,26 +980,26 @@ class WalletRequestHandler {
|
|
|
1090
980
|
return new Promise(resolve => {
|
|
1091
981
|
this.sendAsync(message.data, (error, response) => {
|
|
1092
982
|
// TODO: if response includes data.error, why do we need a separate error argument here?
|
|
983
|
+
|
|
1093
984
|
const responseMessage = _extends({}, message, {
|
|
1094
985
|
data: response
|
|
1095
|
-
});
|
|
1096
|
-
// in the error field of the response to ensure we send back to the user
|
|
1097
|
-
|
|
986
|
+
});
|
|
1098
987
|
|
|
988
|
+
// NOTE: we always resolve here, are the sendAsync call will wrap any exceptions
|
|
989
|
+
// in the error field of the response to ensure we send back to the user
|
|
1099
990
|
resolve(responseMessage);
|
|
1100
991
|
}, message.chainId);
|
|
1101
992
|
});
|
|
1102
|
-
}
|
|
993
|
+
}
|
|
1103
994
|
|
|
995
|
+
// sendAsync implements the JsonRpcHandler interface for sending JsonRpcRequests to the wallet
|
|
1104
996
|
|
|
1105
997
|
on(event, fn) {
|
|
1106
998
|
this.events.on(event, fn);
|
|
1107
999
|
}
|
|
1108
|
-
|
|
1109
1000
|
once(event, fn) {
|
|
1110
1001
|
this.events.once(event, fn);
|
|
1111
1002
|
}
|
|
1112
|
-
|
|
1113
1003
|
async getAddress() {
|
|
1114
1004
|
if (!this.signer) {
|
|
1115
1005
|
return '';
|
|
@@ -1117,69 +1007,54 @@ class WalletRequestHandler {
|
|
|
1117
1007
|
return this.signer.getAddress();
|
|
1118
1008
|
}
|
|
1119
1009
|
}
|
|
1120
|
-
|
|
1121
1010
|
async getChainId() {
|
|
1122
1011
|
if (!this.signer) {
|
|
1123
1012
|
return 0;
|
|
1124
1013
|
} else {
|
|
1125
1014
|
if (this._chainId) return this._chainId; // memoized
|
|
1126
|
-
|
|
1127
1015
|
this._chainId = await this.signer.getChainId();
|
|
1128
1016
|
return this._chainId;
|
|
1129
1017
|
}
|
|
1130
1018
|
}
|
|
1131
|
-
|
|
1132
1019
|
get openIntent() {
|
|
1133
1020
|
return this._openIntent;
|
|
1134
1021
|
}
|
|
1135
|
-
|
|
1136
1022
|
setOpenIntent(intent) {
|
|
1137
1023
|
this._openIntent = intent;
|
|
1138
1024
|
}
|
|
1139
|
-
|
|
1140
1025
|
get connectOptions() {
|
|
1141
1026
|
return this._connectOptions;
|
|
1142
1027
|
}
|
|
1143
|
-
|
|
1144
1028
|
setConnectOptions(options) {
|
|
1145
1029
|
this._connectOptions = options;
|
|
1146
1030
|
}
|
|
1147
|
-
|
|
1148
1031
|
get defaultNetworkId() {
|
|
1149
1032
|
return this._defaultNetworkId;
|
|
1150
1033
|
}
|
|
1151
|
-
|
|
1152
1034
|
async setDefaultNetwork(chainId, notifyNetworks = true) {
|
|
1153
1035
|
if (!chainId) return undefined;
|
|
1154
1036
|
this._defaultNetworkId = chainId;
|
|
1155
1037
|
this._chainId = undefined;
|
|
1156
|
-
|
|
1157
1038
|
if (this.signer && this.signer.setNetworks) {
|
|
1158
1039
|
const defaultChainId = this.signer.setNetworks(this.mainnetNetworks, this.testnetNetworks, chainId);
|
|
1159
|
-
|
|
1160
1040
|
if (defaultChainId && notifyNetworks) {
|
|
1161
1041
|
await this.notifyNetworks();
|
|
1162
1042
|
}
|
|
1163
|
-
|
|
1164
1043
|
return defaultChainId;
|
|
1165
1044
|
} else {
|
|
1166
1045
|
return undefined;
|
|
1167
1046
|
}
|
|
1168
1047
|
}
|
|
1169
|
-
|
|
1170
1048
|
async getNetworks(jsonRpcResponse) {
|
|
1171
1049
|
if (!this.signer) {
|
|
1172
1050
|
utils.logger.warn('signer not set: getNetworks is returning an empty list');
|
|
1173
1051
|
return [];
|
|
1174
1052
|
}
|
|
1175
|
-
|
|
1176
1053
|
const networks = await this.signer.getNetworks();
|
|
1177
|
-
|
|
1178
1054
|
if (jsonRpcResponse) {
|
|
1179
1055
|
// omit provider and relayer objects as they are not serializable
|
|
1180
1056
|
return networks.map(n => {
|
|
1181
1057
|
const network = _extends({}, n);
|
|
1182
|
-
|
|
1183
1058
|
network.provider = undefined;
|
|
1184
1059
|
network.relayer = undefined;
|
|
1185
1060
|
return network;
|
|
@@ -1188,7 +1063,6 @@ class WalletRequestHandler {
|
|
|
1188
1063
|
return networks;
|
|
1189
1064
|
}
|
|
1190
1065
|
}
|
|
1191
|
-
|
|
1192
1066
|
async walletSession() {
|
|
1193
1067
|
return !this.signer ? undefined : {
|
|
1194
1068
|
walletContext: await this.signer.getWalletContext(),
|
|
@@ -1196,31 +1070,23 @@ class WalletRequestHandler {
|
|
|
1196
1070
|
networks: await this.getNetworks(true)
|
|
1197
1071
|
};
|
|
1198
1072
|
}
|
|
1199
|
-
|
|
1200
1073
|
notifyConnect(connectDetails, origin) {
|
|
1201
1074
|
var _connectDetails$sessi;
|
|
1202
|
-
|
|
1203
1075
|
this.events.emit('connect', connectDetails);
|
|
1204
|
-
|
|
1205
1076
|
if ((_connectDetails$sessi = connectDetails.session) != null && _connectDetails$sessi.accountAddress) {
|
|
1206
1077
|
var _connectDetails$sessi2;
|
|
1207
|
-
|
|
1208
1078
|
this.events.emit('accountsChanged', [(_connectDetails$sessi2 = connectDetails.session) == null ? void 0 : _connectDetails$sessi2.accountAddress], origin);
|
|
1209
1079
|
}
|
|
1210
1080
|
}
|
|
1211
|
-
|
|
1212
1081
|
notifyDisconnect(origin) {
|
|
1213
1082
|
this.events.emit('accountsChanged', [], origin);
|
|
1214
1083
|
this.events.emit('disconnect');
|
|
1215
1084
|
}
|
|
1216
|
-
|
|
1217
1085
|
async notifyNetworks(networks) {
|
|
1218
1086
|
const n = networks || (await this.getNetworks(true));
|
|
1219
1087
|
this.events.emit('networks', n);
|
|
1220
|
-
|
|
1221
1088
|
if (n.length > 0) {
|
|
1222
1089
|
const defaultNetwork = n.find(network => network.isDefaultChain);
|
|
1223
|
-
|
|
1224
1090
|
if (defaultNetwork) {
|
|
1225
1091
|
this.events.emit('chainChanged', ethers.ethers.utils.hexlify(defaultNetwork.chainId));
|
|
1226
1092
|
}
|
|
@@ -1228,51 +1094,40 @@ class WalletRequestHandler {
|
|
|
1228
1094
|
this.events.emit('chainChanged', '0x0');
|
|
1229
1095
|
}
|
|
1230
1096
|
}
|
|
1231
|
-
|
|
1232
1097
|
async notifyWalletContext() {
|
|
1233
1098
|
if (!this.signer) {
|
|
1234
1099
|
utils.logger.warn('signer not set: skipping to notify wallet context');
|
|
1235
1100
|
return;
|
|
1236
1101
|
}
|
|
1237
|
-
|
|
1238
1102
|
const walletContext = await this.signer.getWalletContext();
|
|
1239
1103
|
this.events.emit('walletContext', walletContext);
|
|
1240
1104
|
}
|
|
1241
|
-
|
|
1242
1105
|
notifyClose(error) {
|
|
1243
1106
|
this.events.emit('close', error);
|
|
1244
1107
|
}
|
|
1245
|
-
|
|
1246
1108
|
setSigner(signer) {
|
|
1247
1109
|
this.signer = signer;
|
|
1248
|
-
|
|
1249
1110
|
if (signer !== undefined) {
|
|
1250
1111
|
for (let i = 0; i < this.signerReadyCallbacks.length; i++) {
|
|
1251
1112
|
this.signerReadyCallbacks[i]();
|
|
1252
1113
|
}
|
|
1253
|
-
|
|
1254
1114
|
this.signerReadyCallbacks = [];
|
|
1255
1115
|
}
|
|
1256
1116
|
}
|
|
1257
|
-
|
|
1258
1117
|
async handleConfirmWalletDeployPrompt(prompter, signer, chainId) {
|
|
1259
1118
|
// check if wallet is deployed and up to date, if not, prompt user to deploy
|
|
1260
1119
|
// if no chainId is provided, we'll assume the wallet is auth chain wallet and is up to date
|
|
1261
1120
|
if (!chainId) {
|
|
1262
1121
|
return true;
|
|
1263
1122
|
}
|
|
1264
|
-
|
|
1265
1123
|
const isUpToDate = await isWalletUpToDate(signer, chainId);
|
|
1266
|
-
|
|
1267
1124
|
if (isUpToDate) {
|
|
1268
1125
|
return true;
|
|
1269
1126
|
}
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1127
|
+
const promptResult = await prompter.promptConfirmWalletDeploy(chainId, this.connectOptions);
|
|
1128
|
+
// if client returned true, check again to make sure wallet is deployed and up to date
|
|
1273
1129
|
if (promptResult) {
|
|
1274
1130
|
const isPromptResultCorrect = await isWalletUpToDate(signer, chainId);
|
|
1275
|
-
|
|
1276
1131
|
if (!isPromptResultCorrect) {
|
|
1277
1132
|
utils.logger.error('WalletRequestHandler: result for promptConfirmWalletDeploy is not correct');
|
|
1278
1133
|
return false;
|
|
@@ -1280,18 +1135,15 @@ class WalletRequestHandler {
|
|
|
1280
1135
|
return true;
|
|
1281
1136
|
}
|
|
1282
1137
|
}
|
|
1283
|
-
|
|
1284
1138
|
return false;
|
|
1285
1139
|
}
|
|
1286
|
-
|
|
1287
1140
|
}
|
|
1288
1141
|
const permittedJsonRpcMethods = ['net_version', 'eth_chainId', 'eth_getBalance', 'eth_getTransactionCount', 'eth_blockNumber', 'eth_getBlockByNumber', 'eth_getBlockByHash', 'eth_getTransactionByHash', 'eth_getCode', 'eth_estimateGas', 'eth_gasPrice', 'sequence_getWalletContext', 'sequence_getNetworks', 'sequence_setDefaultNetwork'];
|
|
1289
1142
|
|
|
1290
|
-
class Web3Provider extends providers.Web3Provider {
|
|
1143
|
+
class Web3Provider extends ethers.providers.Web3Provider {
|
|
1291
1144
|
static isSequenceProvider(cand) {
|
|
1292
1145
|
return isSequenceProvider(cand);
|
|
1293
1146
|
}
|
|
1294
|
-
|
|
1295
1147
|
constructor(provider, defaultChainId) {
|
|
1296
1148
|
const sender = new network.JsonRpcSender(provider, network.maybeChainId(defaultChainId));
|
|
1297
1149
|
provider = sender;
|
|
@@ -1303,35 +1155,27 @@ class Web3Provider extends providers.Web3Provider {
|
|
|
1303
1155
|
this._isSequenceProvider = true;
|
|
1304
1156
|
this._defaultChainId = network.maybeChainId(defaultChainId);
|
|
1305
1157
|
}
|
|
1306
|
-
|
|
1307
1158
|
sendAsync(request, callback, chainId) {
|
|
1308
1159
|
this._sender.sendAsync(request, callback, chainId);
|
|
1309
1160
|
}
|
|
1310
|
-
|
|
1311
1161
|
send(method, params, chainId) {
|
|
1312
1162
|
return this._sender.send(method, params, chainId);
|
|
1313
1163
|
}
|
|
1314
|
-
|
|
1315
1164
|
request(request) {
|
|
1316
1165
|
return this.send(request.method, request.params || [], request.chainId);
|
|
1317
1166
|
}
|
|
1318
|
-
|
|
1319
1167
|
getSigner() {
|
|
1320
1168
|
return new Web3Signer(this, this._defaultChainId);
|
|
1321
1169
|
}
|
|
1322
|
-
|
|
1323
1170
|
async getChainId() {
|
|
1324
1171
|
// TODO: is it safe to memoize this?
|
|
1325
1172
|
const result = await this.send('eth_chainId', []);
|
|
1326
1173
|
const chainId = ethers.ethers.BigNumber.from(result).toNumber();
|
|
1327
|
-
|
|
1328
1174
|
if (this._defaultChainId && this._defaultChainId !== chainId) {
|
|
1329
1175
|
throw new Error(`provider chainId (${chainId}) does not match provider-bound chainId ${this._defaultChainId}`);
|
|
1330
1176
|
}
|
|
1331
|
-
|
|
1332
1177
|
return chainId;
|
|
1333
1178
|
}
|
|
1334
|
-
|
|
1335
1179
|
}
|
|
1336
1180
|
function isSequenceProvider(provider) {
|
|
1337
1181
|
const cand = provider;
|
|
@@ -1339,11 +1183,13 @@ function isSequenceProvider(provider) {
|
|
|
1339
1183
|
}
|
|
1340
1184
|
class LocalWeb3Provider extends Web3Provider {
|
|
1341
1185
|
constructor(signer, networks) {
|
|
1342
|
-
const walletRequestHandler = new WalletRequestHandler(signer, null, networks || []);
|
|
1186
|
+
const walletRequestHandler = new WalletRequestHandler(signer, null, null, networks || []);
|
|
1343
1187
|
super(walletRequestHandler);
|
|
1344
1188
|
}
|
|
1345
|
-
|
|
1346
1189
|
}
|
|
1190
|
+
|
|
1191
|
+
// TODO: in the future with ethers v6 we can remove/change this type name
|
|
1192
|
+
|
|
1347
1193
|
class Web3Signer extends wallet.Signer {
|
|
1348
1194
|
constructor(provider, defaultChainId) {
|
|
1349
1195
|
super();
|
|
@@ -1356,12 +1202,14 @@ class Web3Signer extends wallet.Signer {
|
|
|
1356
1202
|
this._providers = {};
|
|
1357
1203
|
this.provider = provider;
|
|
1358
1204
|
this.defaultChainId = defaultChainId;
|
|
1359
|
-
}
|
|
1205
|
+
}
|
|
1360
1206
|
|
|
1207
|
+
// memoized
|
|
1361
1208
|
|
|
1362
1209
|
//
|
|
1363
1210
|
// ethers AbstractSigner methods
|
|
1364
1211
|
//
|
|
1212
|
+
|
|
1365
1213
|
async getAddress() {
|
|
1366
1214
|
if (this._address) return this._address;
|
|
1367
1215
|
const accounts = await this.provider.send('eth_accounts', []);
|
|
@@ -1369,53 +1217,47 @@ class Web3Signer extends wallet.Signer {
|
|
|
1369
1217
|
this._index = 0;
|
|
1370
1218
|
return ethers.ethers.utils.getAddress(this._address);
|
|
1371
1219
|
}
|
|
1372
|
-
|
|
1373
1220
|
signTransaction(transaction) {
|
|
1374
1221
|
// TODO .. since ethers isn't using this method, perhaps we will?
|
|
1375
1222
|
throw new Error('signTransaction is unsupported, use signTransactions instead');
|
|
1376
1223
|
}
|
|
1377
|
-
|
|
1378
1224
|
connect(provider) {
|
|
1379
1225
|
throw new Error('unsupported: cannot alter JSON-RPC Signer connection');
|
|
1380
|
-
}
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
//
|
|
1381
1229
|
// Sequence Signer methods
|
|
1382
1230
|
//
|
|
1231
|
+
|
|
1383
1232
|
// getProvider returns a Web3Provider instance for the current chain. Note that this method
|
|
1384
1233
|
// and signer is bound to a particular chain to prevent misuse. If you'd like a provider
|
|
1385
1234
|
// for a specific chain, try getSender(chainId), or wallet.getProvider(chainId).
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
1235
|
async getProvider(chainId) {
|
|
1389
1236
|
if (chainId) {
|
|
1390
1237
|
const currentChainId = await this.getChainId();
|
|
1391
|
-
|
|
1392
1238
|
if (currentChainId !== chainId) {
|
|
1393
1239
|
throw new Error(`signer is attempting to access chain ${chainId}, but is already bound to chain ${currentChainId}`);
|
|
1394
1240
|
}
|
|
1395
1241
|
}
|
|
1396
|
-
|
|
1397
1242
|
return this.provider;
|
|
1398
|
-
}
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
// getSender returns a Web3Provider instance via the signer transport. Note: for our case
|
|
1399
1246
|
// the of sequence wallet, this will bring up the wallet window whenever using it, as the json-rpc
|
|
1400
1247
|
// requests are sent to the window transport. Therefore, for anything non-signing related
|
|
1401
1248
|
// you can write a higher-order JsonRpcRouter sender to route to the public provider endpoints
|
|
1402
1249
|
// as we do in the WalletProvider.
|
|
1403
1250
|
//
|
|
1404
1251
|
// This method is primarily utilized internally when routing requests to a particular chainId.
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
1252
|
async getSender(chainId) {
|
|
1408
1253
|
if (!chainId || chainId && chainId === this.defaultChainId) {
|
|
1409
1254
|
return this.provider;
|
|
1410
1255
|
}
|
|
1411
|
-
|
|
1412
1256
|
if (!this._providers[chainId]) {
|
|
1413
1257
|
this._providers[chainId] = new Web3Provider(new network.JsonRpcSender(this.provider, chainId), chainId);
|
|
1414
1258
|
}
|
|
1415
|
-
|
|
1416
1259
|
return this._providers[chainId];
|
|
1417
1260
|
}
|
|
1418
|
-
|
|
1419
1261
|
getRelayer(chainId) {
|
|
1420
1262
|
// TODO: JsonRpcRelayer ......? or, Web3Relayer.. or SequenceRelayer?
|
|
1421
1263
|
// sequence_gasRefundOptions
|
|
@@ -1423,72 +1265,63 @@ class Web3Signer extends wallet.Signer {
|
|
|
1423
1265
|
// sequence_relay
|
|
1424
1266
|
throw new Error('TODO');
|
|
1425
1267
|
}
|
|
1426
|
-
|
|
1427
1268
|
async getWalletContext() {
|
|
1428
1269
|
if (!this._context) {
|
|
1429
1270
|
this._context = await this.provider.send('sequence_getWalletContext', []);
|
|
1430
1271
|
}
|
|
1431
|
-
|
|
1432
1272
|
return this._context;
|
|
1433
1273
|
}
|
|
1434
|
-
|
|
1435
1274
|
async getWalletConfig(chainId) {
|
|
1436
1275
|
return await this.provider.send('sequence_getWalletConfig', [network.maybeChainId(chainId)], network.maybeChainId(chainId) || this.defaultChainId);
|
|
1437
1276
|
}
|
|
1438
|
-
|
|
1439
1277
|
async getWalletState(chainId) {
|
|
1440
1278
|
return await this.provider.send('sequence_getWalletState', [network.maybeChainId(chainId)], network.maybeChainId(chainId) || this.defaultChainId);
|
|
1441
1279
|
}
|
|
1442
|
-
|
|
1443
1280
|
async getNetworks() {
|
|
1444
1281
|
if (!this._networks) {
|
|
1445
1282
|
this._networks = await this.provider.send('sequence_getNetworks', []);
|
|
1446
1283
|
}
|
|
1447
|
-
|
|
1448
1284
|
return this._networks;
|
|
1449
1285
|
}
|
|
1450
|
-
|
|
1451
1286
|
async getSigners() {
|
|
1452
1287
|
const networks = await this.getNetworks();
|
|
1453
1288
|
const authChainId = networks.find(n => n.isAuthChain);
|
|
1454
|
-
|
|
1455
1289
|
if (!authChainId) {
|
|
1456
1290
|
throw new Error('authChainId could not be determined from network list');
|
|
1457
1291
|
}
|
|
1458
|
-
|
|
1459
1292
|
const walletConfig = await this.getWalletConfig(authChainId);
|
|
1460
|
-
|
|
1461
1293
|
if (!walletConfig || walletConfig.length === 0) {
|
|
1462
1294
|
throw new Error(`walletConfig returned zero results for authChainId {authChainId}`);
|
|
1463
1295
|
}
|
|
1464
|
-
|
|
1465
1296
|
return walletConfig[0].signers.map(s => s.address);
|
|
1466
|
-
}
|
|
1467
|
-
// multi-chain support.
|
|
1468
|
-
|
|
1297
|
+
}
|
|
1469
1298
|
|
|
1299
|
+
// signMessage matches implementation from ethers JsonRpcSigner for compatibility, but with
|
|
1300
|
+
// multi-chain support.
|
|
1470
1301
|
async signMessage(message, chainId, allSigners) {
|
|
1471
1302
|
const provider = await this.getSender(network.maybeChainId(chainId) || this.defaultChainId);
|
|
1472
1303
|
const data = typeof message === 'string' ? ethers.ethers.utils.toUtf8Bytes(message) : message;
|
|
1473
|
-
const address = await this.getAddress();
|
|
1304
|
+
const address = await this.getAddress();
|
|
1305
|
+
|
|
1306
|
+
// NOTE: as of ethers v5.5, it switched to using personal_sign, see
|
|
1474
1307
|
// https://github.com/ethers-io/ethers.js/pull/1542 and see
|
|
1475
1308
|
// https://github.com/WalletConnect/walletconnect-docs/issues/32 for additional info.
|
|
1476
|
-
|
|
1477
1309
|
return await provider.send('personal_sign', [ethers.ethers.utils.hexlify(data), address]);
|
|
1478
|
-
}
|
|
1479
|
-
// multi-chain support.
|
|
1480
|
-
|
|
1310
|
+
}
|
|
1481
1311
|
|
|
1312
|
+
// signTypedData matches implementation from ethers JsonRpcSigner for compatibility, but with
|
|
1313
|
+
// multi-chain support.
|
|
1482
1314
|
async signTypedData(domain, types, message, chainId, allSigners) {
|
|
1483
1315
|
// Populate any ENS names (in-place)
|
|
1484
1316
|
// const populated = await ethers.utils._TypedDataEncoder.resolveNames(domain, types, message, (name: string) => {
|
|
1485
1317
|
// return this.provider.resolveName(name)
|
|
1486
1318
|
// })
|
|
1487
|
-
return await this.provider.send('eth_signTypedData_v4', [await this.getAddress(), ethers.ethers.utils._TypedDataEncoder.getPayload(domain, types, message)], network.maybeChainId(chainId) || this.defaultChainId);
|
|
1488
|
-
} // sendTransaction matches implementation from ethers JsonRpcSigner for compatibility, but with
|
|
1489
|
-
// multi-chain support.
|
|
1490
1319
|
|
|
1320
|
+
return await this.provider.send('eth_signTypedData_v4', [await this.getAddress(), ethers.ethers.utils._TypedDataEncoder.getPayload(domain, types, message)], network.maybeChainId(chainId) || this.defaultChainId);
|
|
1321
|
+
}
|
|
1491
1322
|
|
|
1323
|
+
// sendTransaction matches implementation from ethers JsonRpcSigner for compatibility, but with
|
|
1324
|
+
// multi-chain support.
|
|
1492
1325
|
async sendTransaction(transaction, chainId, allSigners) {
|
|
1493
1326
|
const provider = await this.getSender(network.maybeChainId(chainId) || this.defaultChainId);
|
|
1494
1327
|
const tx = this.sendUncheckedTransaction(transaction, chainId).then(hash => {
|
|
@@ -1497,7 +1330,6 @@ class Web3Signer extends wallet.Signer {
|
|
|
1497
1330
|
if (tx === null) {
|
|
1498
1331
|
return undefined;
|
|
1499
1332
|
}
|
|
1500
|
-
|
|
1501
1333
|
return provider._wrapTransaction(tx, hash);
|
|
1502
1334
|
});
|
|
1503
1335
|
}, {
|
|
@@ -1506,98 +1338,90 @@ class Web3Signer extends wallet.Signer {
|
|
|
1506
1338
|
error.transactionHash = hash;
|
|
1507
1339
|
throw error;
|
|
1508
1340
|
});
|
|
1509
|
-
});
|
|
1341
|
+
});
|
|
1510
1342
|
|
|
1343
|
+
// @ts-ignore
|
|
1511
1344
|
return tx;
|
|
1512
|
-
}
|
|
1513
|
-
// send multiple transaction as a single payload and just one on-chain transaction.
|
|
1514
|
-
|
|
1345
|
+
}
|
|
1515
1346
|
|
|
1347
|
+
// sendTransactionBatch is a convenience method to call sendTransaction in a batch format, allowing you to
|
|
1348
|
+
// send multiple transaction as a single payload and just one on-chain transaction.
|
|
1516
1349
|
async sendTransactionBatch(transactions, chainId, allSigners) {
|
|
1517
1350
|
const batch = await wallet.resolveArrayProperties(transactions);
|
|
1518
|
-
|
|
1519
1351
|
if (!batch || batch.length === 0) {
|
|
1520
1352
|
throw new Error('cannot send empty batch');
|
|
1521
|
-
}
|
|
1522
|
-
|
|
1353
|
+
}
|
|
1523
1354
|
|
|
1355
|
+
// sendTransactionBatch only accepts TransactionRequest, not TransactionResponses
|
|
1524
1356
|
if (batch.find(v => v.wait !== undefined && v.wait !== null)) {
|
|
1525
1357
|
throw new Error('transaction request expected for sendTransactionBatch, transaction response found');
|
|
1526
1358
|
}
|
|
1527
|
-
|
|
1528
1359
|
const tx = _extends({}, batch[0]);
|
|
1529
|
-
|
|
1530
1360
|
if (batch.length > 1) {
|
|
1531
1361
|
tx.auxiliary = batch.splice(1);
|
|
1532
1362
|
}
|
|
1533
|
-
|
|
1534
1363
|
return this.sendTransaction(tx, chainId, allSigners);
|
|
1535
1364
|
}
|
|
1536
|
-
|
|
1537
1365
|
signTransactions(transaction, chainId, allSigners) {
|
|
1538
|
-
transaction = utils.shallowCopy(transaction);
|
|
1366
|
+
transaction = utils.shallowCopy(transaction);
|
|
1367
|
+
// TODO: transaction argument..? make sure to resolve any properties and serialize property before sending over
|
|
1539
1368
|
// the wire.. see sendUncheckedTransaction and resolveProperties
|
|
1540
|
-
|
|
1541
1369
|
return this.provider.send('eth_signTransaction', [transaction], network.maybeChainId(chainId) || this.defaultChainId);
|
|
1542
1370
|
}
|
|
1543
|
-
|
|
1544
1371
|
sendSignedTransactions(signedTxs, chainId) {
|
|
1545
1372
|
// sequence_relay
|
|
1546
1373
|
throw new Error('TODO');
|
|
1547
|
-
}
|
|
1548
|
-
// NOTE: this is not supported by the remote wallet by default.
|
|
1549
|
-
|
|
1374
|
+
}
|
|
1550
1375
|
|
|
1376
|
+
// updateConfig..
|
|
1377
|
+
// NOTE: this is not supported by the remote wallet by default.
|
|
1551
1378
|
async updateConfig(newConfig) {
|
|
1552
1379
|
// sequence_updateConfig
|
|
1553
1380
|
const [config, tx] = await this.provider.send('sequence_updateConfig', [newConfig], this.defaultChainId);
|
|
1554
|
-
|
|
1555
1381
|
if (tx === null) {
|
|
1556
1382
|
return [config, undefined];
|
|
1557
1383
|
}
|
|
1558
|
-
|
|
1559
1384
|
const provider = await this.getSender(this.defaultChainId);
|
|
1560
1385
|
return [config, provider._wrapTransaction(tx, tx.hash)];
|
|
1561
|
-
}
|
|
1562
|
-
// NOTE: this is not supported by the remote wallet by default.
|
|
1563
|
-
|
|
1386
|
+
}
|
|
1564
1387
|
|
|
1388
|
+
// publishConfig..
|
|
1389
|
+
// NOTE: this is not supported by the remote wallet by default.
|
|
1565
1390
|
async publishConfig() {
|
|
1566
1391
|
const provider = await this.getSender(this.defaultChainId);
|
|
1567
1392
|
const tx = await provider.send('sequence_publishConfig', []);
|
|
1568
|
-
|
|
1569
1393
|
if (tx === null) {
|
|
1570
1394
|
return undefined;
|
|
1571
1395
|
}
|
|
1572
|
-
|
|
1573
1396
|
return provider._wrapTransaction(tx, tx.hash);
|
|
1574
1397
|
}
|
|
1575
|
-
|
|
1576
1398
|
async isDeployed(chainId) {
|
|
1577
1399
|
const provider = await this.getSender(network.maybeChainId(chainId));
|
|
1578
1400
|
const walletCode = await provider.getCode(await this.getAddress());
|
|
1579
1401
|
return !!walletCode && walletCode !== '0x';
|
|
1580
|
-
}
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
//
|
|
1581
1405
|
// ethers JsonRpcSigner methods
|
|
1582
1406
|
//
|
|
1583
1407
|
|
|
1584
|
-
|
|
1585
1408
|
async _legacySignMessage(message, chainId, allSigners) {
|
|
1586
1409
|
const provider = await this.getSender(network.maybeChainId(chainId) || this.defaultChainId);
|
|
1587
1410
|
const data = typeof message === 'string' ? ethers.ethers.utils.toUtf8Bytes(message) : message;
|
|
1588
|
-
const address = await this.getAddress();
|
|
1589
|
-
// NOTE: ethers since 5.5 has switched to using personal_sign, we should review, etc.
|
|
1411
|
+
const address = await this.getAddress();
|
|
1590
1412
|
|
|
1413
|
+
// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign
|
|
1414
|
+
// NOTE: ethers since 5.5 has switched to using personal_sign, we should review, etc.
|
|
1591
1415
|
return await provider.send('eth_sign', [address, ethers.ethers.utils.hexlify(data)]);
|
|
1592
1416
|
}
|
|
1593
|
-
|
|
1594
1417
|
async _signTypedData(domain, types, message, chainId, allSigners) {
|
|
1595
1418
|
return this.signTypedData(domain, types, message, chainId, allSigners);
|
|
1596
1419
|
}
|
|
1597
|
-
|
|
1598
1420
|
async sendUncheckedTransaction(transaction, chainId) {
|
|
1599
1421
|
transaction = utils.shallowCopy(transaction);
|
|
1600
|
-
const fromAddress = this.getAddress();
|
|
1422
|
+
const fromAddress = this.getAddress();
|
|
1423
|
+
|
|
1424
|
+
// NOTE: we do not use provider estimation, and instead rely on our relayer to determine the gasLimit and gasPrice
|
|
1601
1425
|
//
|
|
1602
1426
|
// TODO: alternatively/one day, we could write a provider middleware to eth_estimateGas
|
|
1603
1427
|
// and send it to our relayer url instead for estimation..
|
|
@@ -1624,7 +1448,6 @@ class Web3Signer extends wallet.Signer {
|
|
|
1624
1448
|
} else {
|
|
1625
1449
|
tx.from = sender;
|
|
1626
1450
|
}
|
|
1627
|
-
|
|
1628
1451
|
const hexTx = hexlifyTransaction(tx);
|
|
1629
1452
|
return provider.send('eth_sendTransaction', [hexTx]).then(hash => {
|
|
1630
1453
|
return hash;
|
|
@@ -1634,17 +1457,16 @@ class Web3Signer extends wallet.Signer {
|
|
|
1634
1457
|
});
|
|
1635
1458
|
});
|
|
1636
1459
|
}
|
|
1637
|
-
|
|
1638
1460
|
connectUnchecked() {
|
|
1639
1461
|
throw new Error('connectUnchecked is unsupported');
|
|
1640
1462
|
}
|
|
1641
|
-
|
|
1642
1463
|
async unlock(password) {
|
|
1643
1464
|
const address = await this.getAddress();
|
|
1644
1465
|
return this.provider.send('personal_unlockAccount', [address, password, null]);
|
|
1645
1466
|
}
|
|
1467
|
+
}
|
|
1646
1468
|
|
|
1647
|
-
|
|
1469
|
+
// NOTE: method has been copied + modified from ethers.js JsonRpcProvider
|
|
1648
1470
|
// Convert an ethers.js transaction into a JSON-RPC transaction
|
|
1649
1471
|
|
|
1650
1472
|
const allowedTransactionKeys = {
|
|
@@ -1662,11 +1484,9 @@ const allowedTransactionKeys = {
|
|
|
1662
1484
|
delegateCall: true,
|
|
1663
1485
|
revertOnError: true
|
|
1664
1486
|
};
|
|
1665
|
-
|
|
1666
1487
|
const hexlifyTransaction = (transaction, allowExtra) => {
|
|
1667
1488
|
// Check only allowed properties are given
|
|
1668
1489
|
const allowed = utils.shallowCopy(allowedTransactionKeys);
|
|
1669
|
-
|
|
1670
1490
|
if (allowExtra) {
|
|
1671
1491
|
for (const key in allowExtra) {
|
|
1672
1492
|
if (allowExtra[key]) {
|
|
@@ -1674,59 +1494,54 @@ const hexlifyTransaction = (transaction, allowExtra) => {
|
|
|
1674
1494
|
}
|
|
1675
1495
|
}
|
|
1676
1496
|
}
|
|
1677
|
-
|
|
1678
1497
|
ethers.ethers.utils.checkProperties(transaction, allowed);
|
|
1679
|
-
const result = {}
|
|
1498
|
+
const result = {}
|
|
1499
|
+
|
|
1500
|
+
// Some nodes (INFURA ropsten; INFURA mainnet is fine) do not like leading zeros.
|
|
1680
1501
|
;
|
|
1681
1502
|
['gasLimit', 'gasPrice', 'nonce', 'value'].forEach(key => {
|
|
1682
1503
|
const value = transaction[key];
|
|
1683
|
-
|
|
1684
1504
|
if (value === null || value === undefined) {
|
|
1685
1505
|
return;
|
|
1686
1506
|
}
|
|
1687
|
-
|
|
1688
1507
|
const hexValue = ethers.ethers.utils.hexValue(value);
|
|
1689
|
-
|
|
1690
1508
|
if (key === 'gasLimit') {
|
|
1691
1509
|
key = 'gas';
|
|
1692
1510
|
}
|
|
1693
|
-
|
|
1694
1511
|
result[key] = hexValue;
|
|
1695
1512
|
});
|
|
1696
1513
|
['from', 'to', 'data'].forEach(key => {
|
|
1697
1514
|
if (!transaction[key]) {
|
|
1698
1515
|
return;
|
|
1699
1516
|
}
|
|
1700
|
-
|
|
1701
1517
|
result[key] = ethers.ethers.utils.hexlify(transaction[key]);
|
|
1702
1518
|
});
|
|
1703
1519
|
['delegateCall', 'revertOnError'].forEach(key => {
|
|
1704
1520
|
const value = transaction[key];
|
|
1705
|
-
|
|
1706
1521
|
if (value !== undefined && value !== null) {
|
|
1707
1522
|
result[key] = value;
|
|
1708
1523
|
}
|
|
1709
1524
|
});
|
|
1710
1525
|
const auxiliary = transaction['auxiliary'];
|
|
1711
|
-
|
|
1712
1526
|
if (auxiliary && auxiliary.length > 0) {
|
|
1713
1527
|
result['auxiliary'] = [];
|
|
1714
1528
|
auxiliary.forEach(a => {
|
|
1715
1529
|
result['auxiliary'].push(hexlifyTransaction(a));
|
|
1716
1530
|
});
|
|
1717
1531
|
}
|
|
1718
|
-
|
|
1719
1532
|
return result;
|
|
1720
1533
|
};
|
|
1721
1534
|
|
|
1722
1535
|
function messageIsExemptFromEIP191Prefix(message) {
|
|
1723
1536
|
return EIP_191_PREFIX_EXCEPTIONS.some(e => e.predicate(message));
|
|
1724
1537
|
}
|
|
1725
|
-
const EIP_191_PREFIX_EXCEPTIONS = [
|
|
1538
|
+
const EIP_191_PREFIX_EXCEPTIONS = [
|
|
1539
|
+
// NOTE: Decentraland does not support 191 correctly.
|
|
1726
1540
|
{
|
|
1727
1541
|
name: 'Decentraland Exception',
|
|
1728
1542
|
predicate: isDecentralandLoginMessage
|
|
1729
|
-
},
|
|
1543
|
+
},
|
|
1544
|
+
// NOTE: 0x v3 does not support 191 correctly.
|
|
1730
1545
|
// See https://gov.0x.org/t/zeip-proposal-fix-v3-eip-191-non-compliance-when-validating-eip-1271-signatures/3396 for more info.
|
|
1731
1546
|
{
|
|
1732
1547
|
name: '0x v3 Exception',
|
|
@@ -1740,12 +1555,12 @@ function isDecentralandLoginMessage(bytes) {
|
|
|
1740
1555
|
} catch (_unused) {
|
|
1741
1556
|
return false;
|
|
1742
1557
|
}
|
|
1743
|
-
}
|
|
1744
|
-
// see https://github.com/0xProject/0x-protocol-specification/blob/master/v3/v3-specification.md
|
|
1558
|
+
}
|
|
1745
1559
|
|
|
1560
|
+
// try to interpret bytes as abi-encoded 0x v3 OrderWithHash -
|
|
1561
|
+
// see https://github.com/0xProject/0x-protocol-specification/blob/master/v3/v3-specification.md
|
|
1746
1562
|
function isZeroExV3Order(bytes) {
|
|
1747
1563
|
const abi = new ethers.ethers.utils.Interface(ZeroXV3EIP1271OrderWithHashAbi);
|
|
1748
|
-
|
|
1749
1564
|
try {
|
|
1750
1565
|
abi.decodeFunctionData('OrderWithHash', bytes);
|
|
1751
1566
|
return true;
|
|
@@ -1832,12 +1647,10 @@ const messageToBytes = message => {
|
|
|
1832
1647
|
if (ethers.ethers.utils.isBytes(message) || ethers.ethers.utils.isHexString(message)) {
|
|
1833
1648
|
return ethers.ethers.utils.arrayify(message);
|
|
1834
1649
|
}
|
|
1835
|
-
|
|
1836
1650
|
return ethers.ethers.utils.toUtf8Bytes(message);
|
|
1837
1651
|
};
|
|
1838
1652
|
const prefixEIP191Message = message => {
|
|
1839
1653
|
const messageBytes = messageToBytes(message);
|
|
1840
|
-
|
|
1841
1654
|
if (messageIsExemptFromEIP191Prefix(messageBytes)) {
|
|
1842
1655
|
return messageBytes;
|
|
1843
1656
|
} else {
|
|
@@ -1847,14 +1660,11 @@ const prefixEIP191Message = message => {
|
|
|
1847
1660
|
const isValidSignature = async (address, digest, sig, provider, chainId, walletContext) => {
|
|
1848
1661
|
if (!chainId) {
|
|
1849
1662
|
var _await$provider$getNe;
|
|
1850
|
-
|
|
1851
1663
|
chainId = (_await$provider$getNe = await provider.getNetwork()) == null ? void 0 : _await$provider$getNe.chainId;
|
|
1852
1664
|
}
|
|
1853
|
-
|
|
1854
1665
|
if (!walletContext && Web3Provider.isSequenceProvider(provider)) {
|
|
1855
1666
|
walletContext = await provider.getSigner().getWalletContext();
|
|
1856
1667
|
}
|
|
1857
|
-
|
|
1858
1668
|
return wallet.isValidSignature(address, digest, sig, provider, walletContext, chainId);
|
|
1859
1669
|
};
|
|
1860
1670
|
const isValidMessageSignature = async (address, message, signature, provider, chainId, walletContext) => {
|
|
@@ -1868,21 +1678,19 @@ const isValidTypedDataSignature = (address, typedData, signature, provider, chai
|
|
|
1868
1678
|
const recoverWalletConfig = async (address, digest, signature, chainId, walletContext) => {
|
|
1869
1679
|
const subDigest = utils.packMessageData(address, chainId, digest);
|
|
1870
1680
|
const config$1 = await wallet.recoverConfig(subDigest, signature);
|
|
1871
|
-
|
|
1872
1681
|
if (walletContext) {
|
|
1873
1682
|
const recoveredWalletAddress = config.addressOf(config$1, walletContext);
|
|
1874
|
-
|
|
1875
1683
|
if (config$1.address && config$1.address !== recoveredWalletAddress) {
|
|
1876
1684
|
throw new Error('recovered address does not match the WalletConfig address, check the WalletContext');
|
|
1877
1685
|
} else {
|
|
1878
1686
|
config$1.address = recoveredWalletAddress;
|
|
1879
1687
|
}
|
|
1880
1688
|
}
|
|
1881
|
-
|
|
1882
1689
|
return config$1;
|
|
1883
1690
|
};
|
|
1884
1691
|
const isBrowserExtension = () => window.location.protocol === 'chrome-extension:' || window.location.protocol === 'moz-extension:';
|
|
1885
1692
|
const isUnityPlugin = () => !!navigator.userAgent.match(/UnitySequence/i);
|
|
1693
|
+
|
|
1886
1694
|
/**
|
|
1887
1695
|
* Returns the status of a signer's wallet on given chain by checking wallet deployment and config status
|
|
1888
1696
|
*
|
|
@@ -1890,49 +1698,36 @@ const isUnityPlugin = () => !!navigator.userAgent.match(/UnitySequence/i);
|
|
|
1890
1698
|
* @param {number} chainId
|
|
1891
1699
|
* @return {Promise<boolean>} Promise that returns true if the wallet is up to date, false otherwise
|
|
1892
1700
|
*/
|
|
1893
|
-
|
|
1894
1701
|
const isWalletUpToDate = async (signer, chainId) => {
|
|
1895
1702
|
var _walletState$find;
|
|
1896
|
-
|
|
1897
1703
|
const walletState = await signer.getWalletState();
|
|
1898
1704
|
const networks = await signer.getNetworks();
|
|
1899
1705
|
const walletStateForRequiredChain = walletState.find(state => state.chainId === chainId);
|
|
1900
|
-
|
|
1901
1706
|
if (!walletStateForRequiredChain) {
|
|
1902
1707
|
throw new Error(`WalletRequestHandler: could not find wallet state for chainId ${chainId}`);
|
|
1903
1708
|
}
|
|
1904
|
-
|
|
1905
1709
|
const isDeployed = walletStateForRequiredChain.deployed;
|
|
1906
|
-
|
|
1907
1710
|
if (!networks) {
|
|
1908
1711
|
throw new Error(`isWalletUpToDate util: could not get networks from signer`);
|
|
1909
1712
|
}
|
|
1910
|
-
|
|
1911
1713
|
const authChain = networks.find(network => network.isAuthChain);
|
|
1912
|
-
|
|
1913
1714
|
if (!authChain) {
|
|
1914
1715
|
throw new Error(`isWalletUpToDate util: could not get auth chain network information`);
|
|
1915
1716
|
}
|
|
1916
|
-
|
|
1917
1717
|
const authChainId = authChain.chainId;
|
|
1918
1718
|
const authChainConfig = (_walletState$find = walletState.find(state => state.chainId === authChainId)) == null ? void 0 : _walletState$find.config;
|
|
1919
|
-
|
|
1920
1719
|
if (!authChainConfig) {
|
|
1921
1720
|
throw new Error(`isWalletUpToDate util: could not get auth chain config`);
|
|
1922
1721
|
}
|
|
1923
|
-
|
|
1924
1722
|
const requiredChainConfig = walletStateForRequiredChain.config;
|
|
1925
|
-
|
|
1926
1723
|
if (!requiredChainConfig) {
|
|
1927
1724
|
throw new Error(`isWalletUpToDate util: could not get config for chainId ${chainId}`);
|
|
1928
1725
|
}
|
|
1929
|
-
|
|
1930
1726
|
const isUpToDate = config.isConfigEqual(authChainConfig, requiredChainConfig);
|
|
1931
1727
|
return isDeployed && isUpToDate;
|
|
1932
1728
|
};
|
|
1933
1729
|
class LocalStorage {
|
|
1934
1730
|
constructor() {}
|
|
1935
|
-
|
|
1936
1731
|
static getInstance() {
|
|
1937
1732
|
if (!LocalStorage._instance) {
|
|
1938
1733
|
LocalStorage._instance = {
|
|
@@ -1941,16 +1736,14 @@ class LocalStorage {
|
|
|
1941
1736
|
removeItem: key => Promise.resolve(window.localStorage.removeItem(key))
|
|
1942
1737
|
};
|
|
1943
1738
|
}
|
|
1944
|
-
|
|
1945
1739
|
return this._instance;
|
|
1946
1740
|
}
|
|
1947
|
-
|
|
1948
1741
|
static use(instance) {
|
|
1949
1742
|
LocalStorage._instance = instance;
|
|
1950
1743
|
}
|
|
1744
|
+
}
|
|
1951
1745
|
|
|
1952
|
-
|
|
1953
|
-
|
|
1746
|
+
// window.localstorage helper
|
|
1954
1747
|
LocalStorage._instance = void 0;
|
|
1955
1748
|
class LocalStore {
|
|
1956
1749
|
constructor(key, def) {
|
|
@@ -1958,31 +1751,24 @@ class LocalStore {
|
|
|
1958
1751
|
this.key = void 0;
|
|
1959
1752
|
this.key = key;
|
|
1960
1753
|
}
|
|
1961
|
-
|
|
1962
1754
|
async get() {
|
|
1963
1755
|
const val = await LocalStorage.getInstance().getItem(this.key);
|
|
1964
|
-
|
|
1965
1756
|
if (val === null) {
|
|
1966
1757
|
return this.def;
|
|
1967
1758
|
}
|
|
1968
|
-
|
|
1969
1759
|
try {
|
|
1970
1760
|
return JSON.parse(val);
|
|
1971
1761
|
} catch (err) {
|
|
1972
1762
|
console.error(err);
|
|
1973
1763
|
}
|
|
1974
|
-
|
|
1975
1764
|
return;
|
|
1976
1765
|
}
|
|
1977
|
-
|
|
1978
1766
|
set(val) {
|
|
1979
1767
|
val ? LocalStorage.getInstance().setItem(this.key, JSON.stringify(val)) : LocalStorage.getInstance().removeItem(this.key);
|
|
1980
1768
|
}
|
|
1981
|
-
|
|
1982
1769
|
del() {
|
|
1983
1770
|
LocalStorage.getInstance().removeItem(this.key);
|
|
1984
1771
|
}
|
|
1985
|
-
|
|
1986
1772
|
}
|
|
1987
1773
|
|
|
1988
1774
|
const TRANSPORT_SESSION_LS_KEY = '@sequence.transportSession';
|
|
@@ -1990,9 +1776,9 @@ class BaseWalletTransport {
|
|
|
1990
1776
|
// appOrigin identifies the dapp's origin which opened the app. A transport
|
|
1991
1777
|
// will auto-detect and set this value if it can. This is determined
|
|
1992
1778
|
// as the parent app/window which opened the wallet.
|
|
1779
|
+
|
|
1993
1780
|
constructor(walletRequestHandler) {
|
|
1994
1781
|
var _this = this;
|
|
1995
|
-
|
|
1996
1782
|
this.walletRequestHandler = void 0;
|
|
1997
1783
|
this._sessionId = void 0;
|
|
1998
1784
|
this._registered = void 0;
|
|
@@ -2000,15 +1786,14 @@ class BaseWalletTransport {
|
|
|
2000
1786
|
this._initNonce = void 0;
|
|
2001
1787
|
this._initCallback = void 0;
|
|
2002
1788
|
this.appOrigin = void 0;
|
|
2003
|
-
|
|
2004
1789
|
this.sendAsync = async function (request, callback, chainId) {
|
|
2005
1790
|
throw new Error('abstract method');
|
|
2006
1791
|
};
|
|
2007
|
-
|
|
2008
1792
|
this.handleMessage = async function (message) {
|
|
2009
|
-
const request = message;
|
|
2010
|
-
// other kinds of messages.
|
|
1793
|
+
const request = message;
|
|
2011
1794
|
|
|
1795
|
+
// ensure initial handshake is complete before accepting
|
|
1796
|
+
// other kinds of messages.
|
|
2012
1797
|
if (_this._init !== exports.InitState.OK) {
|
|
2013
1798
|
if (request.type === exports.EventType.INIT) {
|
|
2014
1799
|
if (_this.isValidInitAck(message)) {
|
|
@@ -2020,15 +1805,15 @@ class BaseWalletTransport {
|
|
|
2020
1805
|
return;
|
|
2021
1806
|
}
|
|
2022
1807
|
}
|
|
2023
|
-
|
|
2024
1808
|
return;
|
|
2025
|
-
}
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
// ensure signer is ready to handle requests
|
|
2026
1812
|
// if (this.walletRequestHandler.getSigner() === undefined) {
|
|
2027
1813
|
// await this.walletRequestHandler.signerReady()
|
|
2028
1814
|
// }
|
|
2029
|
-
// handle request
|
|
2030
|
-
|
|
2031
1815
|
|
|
1816
|
+
// handle request
|
|
2032
1817
|
switch (request.type) {
|
|
2033
1818
|
case exports.EventType.OPEN:
|
|
2034
1819
|
{
|
|
@@ -2041,65 +1826,57 @@ class BaseWalletTransport {
|
|
|
2041
1826
|
await _this.open(session);
|
|
2042
1827
|
return;
|
|
2043
1828
|
}
|
|
2044
|
-
|
|
2045
1829
|
case exports.EventType.CLOSE:
|
|
2046
1830
|
{
|
|
2047
|
-
if (_this._init !== exports.InitState.OK) return;
|
|
2048
|
-
|
|
1831
|
+
if (_this._init !== exports.InitState.OK) return;
|
|
1832
|
+
// noop. just here to capture the message so event emitters may be notified
|
|
2049
1833
|
return;
|
|
2050
1834
|
}
|
|
2051
|
-
|
|
2052
1835
|
case exports.EventType.MESSAGE:
|
|
2053
1836
|
{
|
|
2054
1837
|
const response = await _this.walletRequestHandler.sendMessageRequest(request);
|
|
2055
|
-
|
|
2056
1838
|
_this.sendMessage(response);
|
|
2057
|
-
|
|
2058
1839
|
if (response.data.error) ;
|
|
2059
|
-
|
|
2060
1840
|
return;
|
|
2061
1841
|
}
|
|
2062
|
-
|
|
2063
1842
|
default:
|
|
2064
1843
|
{
|
|
2065
1844
|
utils.logger.error(`unexpected payload type ${request.type}`);
|
|
2066
1845
|
}
|
|
2067
1846
|
}
|
|
2068
1847
|
};
|
|
2069
|
-
|
|
2070
1848
|
this.sendMessageRequest = async function (message) {
|
|
2071
1849
|
return _this.walletRequestHandler.sendMessageRequest(message);
|
|
2072
1850
|
};
|
|
2073
|
-
|
|
2074
1851
|
this.open = async function ({
|
|
2075
1852
|
sessionId,
|
|
2076
1853
|
intent,
|
|
2077
1854
|
networkId
|
|
2078
1855
|
}) {
|
|
2079
1856
|
if (sessionId) {
|
|
2080
|
-
_this._sessionId = utils.sanitizeNumberString(sessionId);
|
|
2081
|
-
|
|
1857
|
+
_this._sessionId = utils.sanitizeNumberString(sessionId);
|
|
1858
|
+
// persist transport session in localstorage for restoring after redirect/reload
|
|
2082
1859
|
_this.saveTransportSession({
|
|
2083
1860
|
sessionId,
|
|
2084
1861
|
intent,
|
|
2085
1862
|
networkId
|
|
2086
1863
|
});
|
|
2087
1864
|
}
|
|
1865
|
+
_this.walletRequestHandler.setOpenIntent(intent);
|
|
2088
1866
|
|
|
2089
|
-
|
|
1867
|
+
// init handshake for certain transports, before we can open the communication.
|
|
2090
1868
|
//
|
|
2091
1869
|
// for example, with the window-transport, we have to exchange messages to determine the
|
|
2092
1870
|
// origin host of the dapp.
|
|
1871
|
+
await _this.init();
|
|
2093
1872
|
|
|
2094
|
-
|
|
2095
|
-
await _this.init(); // Prepare connect options from intent
|
|
2096
|
-
|
|
1873
|
+
// Prepare connect options from intent
|
|
2097
1874
|
if (intent && intent.type === 'connect' && intent.options) {
|
|
2098
1875
|
const connectOptions = intent.options;
|
|
2099
1876
|
const authorizeOptions = connectOptions; // overlapping types
|
|
1877
|
+
|
|
2100
1878
|
// Sanity/integrity check the intent payload, and set authorization origin
|
|
2101
1879
|
// if its been determined as part of the init handshake from earlier.
|
|
2102
|
-
|
|
2103
1880
|
if (_this.appOrigin && authorizeOptions != null && authorizeOptions.origin) {
|
|
2104
1881
|
if (!isBrowserExtension()) {
|
|
2105
1882
|
if (authorizeOptions.origin !== _this.appOrigin) {
|
|
@@ -2114,36 +1891,33 @@ class BaseWalletTransport {
|
|
|
2114
1891
|
// ie. when we auto-determine the origin such as in window-transport
|
|
2115
1892
|
connectOptions.origin = _this.appOrigin;
|
|
2116
1893
|
}
|
|
2117
|
-
|
|
2118
1894
|
if (connectOptions.app) {
|
|
2119
1895
|
connectOptions.app = utils.sanitizeAlphanumeric(connectOptions.app);
|
|
2120
|
-
}
|
|
2121
|
-
// wallet controller
|
|
2122
|
-
|
|
1896
|
+
}
|
|
2123
1897
|
|
|
1898
|
+
// Set connect options on the walletRequestHandler as our primary
|
|
1899
|
+
// wallet controller
|
|
2124
1900
|
_this.walletRequestHandler.setConnectOptions(connectOptions);
|
|
2125
|
-
|
|
2126
1901
|
if (connectOptions.networkId) {
|
|
2127
1902
|
networkId = connectOptions.networkId;
|
|
2128
1903
|
}
|
|
2129
1904
|
} else {
|
|
2130
1905
|
_this.walletRequestHandler.setConnectOptions(undefined);
|
|
2131
|
-
}
|
|
2132
|
-
|
|
1906
|
+
}
|
|
2133
1907
|
|
|
2134
|
-
|
|
1908
|
+
// ensure signer is ready
|
|
1909
|
+
await _this.walletRequestHandler.getSigner();
|
|
2135
1910
|
|
|
1911
|
+
// Notify open and proceed to prompt for connection if intended
|
|
2136
1912
|
if (!(await _this.walletRequestHandler.isSignedIn())) {
|
|
2137
1913
|
// open wallet without a specific connected chainId, as the user is not signed in
|
|
2138
1914
|
_this.notifyOpen({
|
|
2139
1915
|
sessionId: _this._sessionId
|
|
2140
1916
|
});
|
|
2141
|
-
|
|
2142
1917
|
return true;
|
|
2143
1918
|
} else {
|
|
2144
1919
|
// Set default network, in case of error chainId will be undefined or 0
|
|
2145
1920
|
let chainId = undefined;
|
|
2146
|
-
|
|
2147
1921
|
try {
|
|
2148
1922
|
if (networkId) {
|
|
2149
1923
|
chainId = await _this.walletRequestHandler.setDefaultNetwork(networkId, false);
|
|
@@ -2152,30 +1926,28 @@ class BaseWalletTransport {
|
|
|
2152
1926
|
}
|
|
2153
1927
|
} catch (err) {
|
|
2154
1928
|
console.error(err);
|
|
2155
|
-
}
|
|
2156
|
-
|
|
1929
|
+
}
|
|
2157
1930
|
|
|
1931
|
+
// Failed to set default network on open -- quit + close
|
|
2158
1932
|
if (!chainId || chainId <= 0) {
|
|
2159
1933
|
_this.notifyOpen({
|
|
2160
1934
|
sessionId: _this._sessionId,
|
|
2161
1935
|
error: `failed to open wallet on network ${networkId}`
|
|
2162
1936
|
});
|
|
2163
|
-
|
|
2164
1937
|
return false;
|
|
2165
|
-
}
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
// prompt user with a connect request. the options will be used as previously set above.
|
|
2166
1941
|
// upon success, the walletRequestHandler will notify the dapp with the ConnectDetails.
|
|
2167
1942
|
// upon cancellation by user, the walletRequestHandler will throw an error
|
|
2168
1943
|
|
|
2169
|
-
|
|
2170
1944
|
if (intent && intent.type === 'connect') {
|
|
2171
1945
|
// notify wallet is opened, without session details
|
|
2172
1946
|
_this.notifyOpen({
|
|
2173
1947
|
sessionId: _this._sessionId
|
|
2174
1948
|
});
|
|
2175
|
-
|
|
2176
1949
|
try {
|
|
2177
1950
|
const connectDetails = await _this.walletRequestHandler.promptConnect(intent.options);
|
|
2178
|
-
|
|
2179
1951
|
if (connectDetails.connected) {
|
|
2180
1952
|
_this.walletRequestHandler.notifyConnect(connectDetails);
|
|
2181
1953
|
}
|
|
@@ -2198,17 +1970,13 @@ class BaseWalletTransport {
|
|
|
2198
1970
|
});
|
|
2199
1971
|
}
|
|
2200
1972
|
}
|
|
2201
|
-
|
|
2202
1973
|
return true;
|
|
2203
1974
|
};
|
|
2204
|
-
|
|
2205
1975
|
this.saveTransportSession = session => {
|
|
2206
1976
|
LocalStorage.getInstance().setItem(TRANSPORT_SESSION_LS_KEY, JSON.stringify(session));
|
|
2207
1977
|
};
|
|
2208
|
-
|
|
2209
1978
|
this.getCachedTransportSession = async function () {
|
|
2210
1979
|
const session = await LocalStorage.getInstance().getItem(TRANSPORT_SESSION_LS_KEY);
|
|
2211
|
-
|
|
2212
1980
|
try {
|
|
2213
1981
|
return session ? JSON.parse(session) : null;
|
|
2214
1982
|
} catch (err) {
|
|
@@ -2216,17 +1984,16 @@ class BaseWalletTransport {
|
|
|
2216
1984
|
return null;
|
|
2217
1985
|
}
|
|
2218
1986
|
};
|
|
2219
|
-
|
|
2220
1987
|
this.walletRequestHandler = walletRequestHandler;
|
|
2221
1988
|
this._init = exports.InitState.NIL;
|
|
2222
1989
|
this.walletRequestHandler.on('connect', connectDetails => {
|
|
2223
|
-
if (!this.registered) return;
|
|
2224
|
-
|
|
1990
|
+
if (!this.registered) return;
|
|
1991
|
+
// means user has logged in and wallet is connected to the app
|
|
2225
1992
|
this.notifyConnect(connectDetails);
|
|
2226
1993
|
});
|
|
2227
1994
|
this.walletRequestHandler.on('disconnect', error => {
|
|
2228
|
-
if (!this.registered) return;
|
|
2229
|
-
|
|
1995
|
+
if (!this.registered) return;
|
|
1996
|
+
// means user has logged out the app / disconnected wallet from the app
|
|
2230
1997
|
this.notifyDisconnect(error);
|
|
2231
1998
|
});
|
|
2232
1999
|
this.walletRequestHandler.on('accountsChanged', (accounts, origin) => {
|
|
@@ -2236,7 +2003,6 @@ class BaseWalletTransport {
|
|
|
2236
2003
|
this.walletRequestHandler.on('networks', networks => {
|
|
2237
2004
|
if (!this.registered) return;
|
|
2238
2005
|
this.notifyNetworks(networks);
|
|
2239
|
-
|
|
2240
2006
|
if (!networks || networks.length === 0) {
|
|
2241
2007
|
this.notifyChainChanged('0x0');
|
|
2242
2008
|
} else {
|
|
@@ -2252,23 +2018,18 @@ class BaseWalletTransport {
|
|
|
2252
2018
|
this.notifyClose(error);
|
|
2253
2019
|
});
|
|
2254
2020
|
}
|
|
2255
|
-
|
|
2256
2021
|
get registered() {
|
|
2257
2022
|
return this._registered;
|
|
2258
2023
|
}
|
|
2259
|
-
|
|
2260
2024
|
register() {
|
|
2261
2025
|
throw new Error('abstract method');
|
|
2262
2026
|
}
|
|
2263
|
-
|
|
2264
2027
|
unregister() {
|
|
2265
2028
|
throw new Error('abstract method');
|
|
2266
2029
|
}
|
|
2267
|
-
|
|
2268
2030
|
sendMessage(message) {
|
|
2269
2031
|
throw new Error('abstract method');
|
|
2270
2032
|
}
|
|
2271
|
-
|
|
2272
2033
|
notifyOpen(openInfo) {
|
|
2273
2034
|
const {
|
|
2274
2035
|
chainId,
|
|
@@ -2287,7 +2048,6 @@ class BaseWalletTransport {
|
|
|
2287
2048
|
}
|
|
2288
2049
|
});
|
|
2289
2050
|
}
|
|
2290
|
-
|
|
2291
2051
|
notifyClose(error) {
|
|
2292
2052
|
this.sendMessage({
|
|
2293
2053
|
idx: -1,
|
|
@@ -2297,7 +2057,6 @@ class BaseWalletTransport {
|
|
|
2297
2057
|
} : null
|
|
2298
2058
|
});
|
|
2299
2059
|
}
|
|
2300
|
-
|
|
2301
2060
|
notifyConnect(connectDetails) {
|
|
2302
2061
|
this.sendMessage({
|
|
2303
2062
|
idx: -1,
|
|
@@ -2305,7 +2064,6 @@ class BaseWalletTransport {
|
|
|
2305
2064
|
data: connectDetails
|
|
2306
2065
|
});
|
|
2307
2066
|
}
|
|
2308
|
-
|
|
2309
2067
|
notifyDisconnect(error) {
|
|
2310
2068
|
this.sendMessage({
|
|
2311
2069
|
idx: -1,
|
|
@@ -2315,7 +2073,6 @@ class BaseWalletTransport {
|
|
|
2315
2073
|
} : null
|
|
2316
2074
|
});
|
|
2317
2075
|
}
|
|
2318
|
-
|
|
2319
2076
|
notifyAccountsChanged(accounts, origin) {
|
|
2320
2077
|
this.sendMessage({
|
|
2321
2078
|
idx: -1,
|
|
@@ -2324,7 +2081,6 @@ class BaseWalletTransport {
|
|
|
2324
2081
|
origin: origin
|
|
2325
2082
|
});
|
|
2326
2083
|
}
|
|
2327
|
-
|
|
2328
2084
|
notifyChainChanged(chainIdHex) {
|
|
2329
2085
|
this.sendMessage({
|
|
2330
2086
|
idx: -1,
|
|
@@ -2332,7 +2088,6 @@ class BaseWalletTransport {
|
|
|
2332
2088
|
data: chainIdHex
|
|
2333
2089
|
});
|
|
2334
2090
|
}
|
|
2335
|
-
|
|
2336
2091
|
notifyNetworks(networks) {
|
|
2337
2092
|
this.sendMessage({
|
|
2338
2093
|
idx: -1,
|
|
@@ -2340,7 +2095,6 @@ class BaseWalletTransport {
|
|
|
2340
2095
|
data: networks
|
|
2341
2096
|
});
|
|
2342
2097
|
}
|
|
2343
|
-
|
|
2344
2098
|
notifyWalletContext(walletContext) {
|
|
2345
2099
|
this.sendMessage({
|
|
2346
2100
|
idx: -1,
|
|
@@ -2348,38 +2102,32 @@ class BaseWalletTransport {
|
|
|
2348
2102
|
data: walletContext
|
|
2349
2103
|
});
|
|
2350
2104
|
}
|
|
2351
|
-
|
|
2352
2105
|
isValidInitAck(message) {
|
|
2353
2106
|
if (this._init === exports.InitState.OK) {
|
|
2354
2107
|
// we're already in init state, we shouldn't handle this message
|
|
2355
2108
|
utils.logger.warn("isValidInitAck, already in init'd state, so inquiry is invalid.");
|
|
2356
2109
|
return false;
|
|
2357
2110
|
}
|
|
2358
|
-
|
|
2359
2111
|
if (message.type !== exports.EventType.INIT) {
|
|
2360
2112
|
utils.logger.warn('isValidInitAck, invalid message type, expecting init');
|
|
2361
2113
|
return false;
|
|
2362
2114
|
}
|
|
2363
|
-
|
|
2364
2115
|
const {
|
|
2365
2116
|
sessionId,
|
|
2366
2117
|
nonce
|
|
2367
2118
|
} = message.data;
|
|
2368
|
-
|
|
2369
2119
|
if (!sessionId || sessionId.length === 0 || !nonce || nonce.length === 0) {
|
|
2370
2120
|
utils.logger.error('invalid init ack');
|
|
2371
2121
|
return false;
|
|
2372
2122
|
}
|
|
2373
|
-
|
|
2374
2123
|
if (sessionId !== this._sessionId || nonce !== this._initNonce) {
|
|
2375
2124
|
utils.logger.error('invalid init ack match');
|
|
2376
2125
|
return false;
|
|
2377
|
-
}
|
|
2378
|
-
|
|
2126
|
+
}
|
|
2379
2127
|
|
|
2128
|
+
// all checks pass, its true
|
|
2380
2129
|
return true;
|
|
2381
2130
|
}
|
|
2382
|
-
|
|
2383
2131
|
init() {
|
|
2384
2132
|
return new Promise((resolve, reject) => {
|
|
2385
2133
|
// avoid re-init`ing, or if there is a transport which doesn't require
|
|
@@ -2388,37 +2136,34 @@ class BaseWalletTransport {
|
|
|
2388
2136
|
resolve();
|
|
2389
2137
|
return;
|
|
2390
2138
|
}
|
|
2391
|
-
|
|
2392
2139
|
if (this._init !== exports.InitState.NIL || this._initCallback) {
|
|
2393
2140
|
reject('transport init is in progress');
|
|
2394
2141
|
return;
|
|
2395
|
-
}
|
|
2396
|
-
// from provider within this amount of time, then we timeout
|
|
2397
|
-
|
|
2142
|
+
}
|
|
2398
2143
|
|
|
2144
|
+
// start init timeout, if we don't receive confirmation
|
|
2145
|
+
// from provider within this amount of time, then we timeout
|
|
2399
2146
|
const initTimeout = setTimeout(() => {
|
|
2400
2147
|
utils.logger.warn('transport init timed out');
|
|
2401
|
-
|
|
2402
2148
|
if (this._initCallback) {
|
|
2403
2149
|
this._initCallback('transport init timed out');
|
|
2404
2150
|
}
|
|
2405
|
-
}, PROVIDER_OPEN_TIMEOUT / 2);
|
|
2151
|
+
}, PROVIDER_OPEN_TIMEOUT / 2);
|
|
2406
2152
|
|
|
2153
|
+
// setup callback as we receive the init message async in the handleMessage function
|
|
2407
2154
|
this._initCallback = error => {
|
|
2408
2155
|
this._initCallback = undefined; // reset
|
|
2409
|
-
|
|
2410
2156
|
clearTimeout(initTimeout);
|
|
2411
|
-
|
|
2412
2157
|
if (error) {
|
|
2413
2158
|
reject(error);
|
|
2414
2159
|
} else {
|
|
2415
2160
|
this._init = exports.InitState.OK;
|
|
2416
2161
|
resolve();
|
|
2417
2162
|
}
|
|
2418
|
-
};
|
|
2419
|
-
// for the provider to echo it back to us as complete handshake
|
|
2420
|
-
|
|
2163
|
+
};
|
|
2421
2164
|
|
|
2165
|
+
// send init request with random nonce to the provider, where we expect
|
|
2166
|
+
// for the provider to echo it back to us as complete handshake
|
|
2422
2167
|
this._initNonce = `${performance.now()}`;
|
|
2423
2168
|
this.sendMessage({
|
|
2424
2169
|
idx: -1,
|
|
@@ -2427,11 +2172,12 @@ class BaseWalletTransport {
|
|
|
2427
2172
|
nonce: this._initNonce
|
|
2428
2173
|
}
|
|
2429
2174
|
});
|
|
2430
|
-
this._init = exports.InitState.SENT_NONCE;
|
|
2175
|
+
this._init = exports.InitState.SENT_NONCE;
|
|
2176
|
+
|
|
2177
|
+
// NOTE: the promise will resolve in the _initCallback method
|
|
2431
2178
|
// which will be called from either handleMessage or the initTimeout
|
|
2432
2179
|
});
|
|
2433
2180
|
}
|
|
2434
|
-
|
|
2435
2181
|
}
|
|
2436
2182
|
|
|
2437
2183
|
class ProxyMessageChannel {
|
|
@@ -2445,58 +2191,48 @@ class ProxyMessageChannel {
|
|
|
2445
2191
|
this.app = port1;
|
|
2446
2192
|
this.wallet = port2;
|
|
2447
2193
|
}
|
|
2448
|
-
|
|
2449
2194
|
}
|
|
2450
2195
|
class ProxyMessageChannelPort {
|
|
2451
2196
|
constructor() {
|
|
2452
2197
|
this.conn = void 0;
|
|
2453
2198
|
this.events = new eventemitter2.EventEmitter2();
|
|
2454
|
-
|
|
2455
2199
|
this.handleMessage = message => {
|
|
2456
2200
|
throw new Error('ProxyMessageChannelPort is not registered');
|
|
2457
2201
|
};
|
|
2458
|
-
|
|
2459
2202
|
this.sendMessage = message => {
|
|
2460
|
-
this.conn.handleMessage(message);
|
|
2203
|
+
this.conn.handleMessage(message);
|
|
2461
2204
|
|
|
2205
|
+
// trigger events
|
|
2462
2206
|
if (message.type === 'open') {
|
|
2463
2207
|
this.events.emit('open', message);
|
|
2464
2208
|
}
|
|
2465
|
-
|
|
2466
2209
|
if (message.type === 'close') {
|
|
2467
2210
|
this.events.emit('close', message);
|
|
2468
2211
|
}
|
|
2469
|
-
|
|
2470
2212
|
if (message.type === 'connect') {
|
|
2471
2213
|
this.events.emit('connect', message);
|
|
2472
2214
|
}
|
|
2473
|
-
|
|
2474
2215
|
if (message.type === 'disconnect') {
|
|
2475
2216
|
this.events.emit('disconnect', message);
|
|
2476
2217
|
}
|
|
2477
2218
|
};
|
|
2478
2219
|
}
|
|
2479
|
-
|
|
2480
2220
|
on(event, fn) {
|
|
2481
2221
|
this.events.on(event, fn);
|
|
2482
2222
|
}
|
|
2483
|
-
|
|
2484
2223
|
once(event, fn) {
|
|
2485
2224
|
this.events.once(event, fn);
|
|
2486
2225
|
}
|
|
2487
|
-
|
|
2488
2226
|
}
|
|
2489
2227
|
|
|
2490
2228
|
class ProxyMessageProvider extends BaseProviderTransport {
|
|
2491
2229
|
constructor(port) {
|
|
2492
2230
|
super();
|
|
2493
2231
|
this.port = void 0;
|
|
2494
|
-
|
|
2495
2232
|
this.register = () => {
|
|
2496
2233
|
this.port.handleMessage = message => {
|
|
2497
2234
|
this.handleMessage(message);
|
|
2498
2235
|
};
|
|
2499
|
-
|
|
2500
2236
|
this.on('open', (...args) => {
|
|
2501
2237
|
this.port.events.emit('open', ...args);
|
|
2502
2238
|
});
|
|
@@ -2511,15 +2247,13 @@ class ProxyMessageProvider extends BaseProviderTransport {
|
|
|
2511
2247
|
});
|
|
2512
2248
|
this._registered = true;
|
|
2513
2249
|
};
|
|
2514
|
-
|
|
2515
2250
|
this.unregister = () => {
|
|
2516
2251
|
this._registered = false;
|
|
2517
2252
|
this.closeWallet();
|
|
2518
|
-
this.events.removeAllListeners();
|
|
2519
|
-
|
|
2253
|
+
this.events.removeAllListeners();
|
|
2254
|
+
// @ts-ignore
|
|
2520
2255
|
this.port.handleMessage = undefined;
|
|
2521
2256
|
};
|
|
2522
|
-
|
|
2523
2257
|
this.openWallet = (path, intent, networkId) => {
|
|
2524
2258
|
if (this.state === exports.OpenState.CLOSED) {
|
|
2525
2259
|
this.state = exports.OpenState.OPENING;
|
|
@@ -2537,19 +2271,16 @@ class ProxyMessageProvider extends BaseProviderTransport {
|
|
|
2537
2271
|
});
|
|
2538
2272
|
}
|
|
2539
2273
|
};
|
|
2540
|
-
|
|
2541
2274
|
this.state = exports.OpenState.CLOSED;
|
|
2542
2275
|
this.port = port;
|
|
2543
|
-
|
|
2544
2276
|
if (!port) {
|
|
2545
2277
|
throw new Error('port argument cannot be empty');
|
|
2546
|
-
}
|
|
2547
|
-
// consider it in completed state.
|
|
2548
|
-
|
|
2278
|
+
}
|
|
2549
2279
|
|
|
2280
|
+
// disable init handshake for proxy-transport, we set it to OK, to
|
|
2281
|
+
// consider it in completed state.
|
|
2550
2282
|
this._init = exports.InitState.OK;
|
|
2551
2283
|
}
|
|
2552
|
-
|
|
2553
2284
|
closeWallet() {
|
|
2554
2285
|
this.sendMessage({
|
|
2555
2286
|
idx: -1,
|
|
@@ -2558,15 +2289,12 @@ class ProxyMessageProvider extends BaseProviderTransport {
|
|
|
2558
2289
|
});
|
|
2559
2290
|
this.close();
|
|
2560
2291
|
}
|
|
2561
|
-
|
|
2562
2292
|
sendMessage(message) {
|
|
2563
2293
|
if (!message.idx) {
|
|
2564
2294
|
throw new Error('message idx is empty');
|
|
2565
2295
|
}
|
|
2566
|
-
|
|
2567
2296
|
this.port.sendMessage(message);
|
|
2568
2297
|
}
|
|
2569
|
-
|
|
2570
2298
|
}
|
|
2571
2299
|
|
|
2572
2300
|
class ProxyMessageHandler extends BaseWalletTransport {
|
|
@@ -2576,66 +2304,59 @@ class ProxyMessageHandler extends BaseWalletTransport {
|
|
|
2576
2304
|
this.port = port;
|
|
2577
2305
|
this._init = exports.InitState.OK;
|
|
2578
2306
|
}
|
|
2579
|
-
|
|
2580
2307
|
register() {
|
|
2581
2308
|
this.port.handleMessage = message => {
|
|
2582
2309
|
this.handleMessage(message);
|
|
2583
2310
|
};
|
|
2584
|
-
|
|
2585
2311
|
this._registered = true;
|
|
2586
|
-
}
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
// note: we can't decide whether to restore the session within register(), because session info is
|
|
2587
2315
|
// received asyncronously via EventType.OPEN after register() is executed.
|
|
2588
2316
|
// And in the case of a redirect/reload, EventType.OPEN is not sent at all,
|
|
2589
2317
|
// because the wallet is already open.
|
|
2590
2318
|
//
|
|
2591
2319
|
// call this method from wallet redirect hander when a session restore is needed
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
2320
|
async restoreSession() {
|
|
2595
2321
|
const cachedSession = await this.getCachedTransportSession();
|
|
2596
|
-
|
|
2597
2322
|
if (cachedSession) {
|
|
2598
2323
|
this.open(cachedSession);
|
|
2599
2324
|
}
|
|
2600
2325
|
}
|
|
2601
|
-
|
|
2602
2326
|
unregister() {
|
|
2603
2327
|
// @ts-ignore
|
|
2604
2328
|
this.port.handleMessage = undefined;
|
|
2605
2329
|
this._registered = false;
|
|
2606
2330
|
}
|
|
2607
|
-
|
|
2608
2331
|
sendMessage(message) {
|
|
2609
2332
|
this.port.sendMessage(message);
|
|
2610
2333
|
}
|
|
2611
|
-
|
|
2612
2334
|
}
|
|
2613
2335
|
|
|
2614
2336
|
class MuxMessageProvider {
|
|
2615
2337
|
constructor(...messageProviders) {
|
|
2616
2338
|
var _this = this;
|
|
2617
|
-
|
|
2618
2339
|
this.messageProviders = void 0;
|
|
2619
2340
|
this.provider = void 0;
|
|
2620
|
-
|
|
2621
2341
|
this.register = () => {
|
|
2622
2342
|
if (this.messageProviders.length === 1) {
|
|
2623
2343
|
this.provider = this.messageProviders[0];
|
|
2624
2344
|
this.provider.register();
|
|
2625
2345
|
return;
|
|
2626
|
-
}
|
|
2346
|
+
}
|
|
2347
|
+
|
|
2348
|
+
// REVIEW/NOTE: ........ this method does not work for the chrome-extension. The issue becomes
|
|
2627
2349
|
// when the browser quits or restarts, the "open" event is never triggered. Perhaps the code here is fine,
|
|
2628
2350
|
// or maybe its not. What should happen is when a dapp makes a request, it will call openWallet
|
|
2629
2351
|
// below, in which case one of the events will register. So perhaps this is fine.
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
2352
|
this.messageProviders.forEach(m => {
|
|
2633
2353
|
m.register();
|
|
2634
2354
|
m.once('open', () => {
|
|
2635
2355
|
// the first one to open is the winner, and others will be unregistered
|
|
2636
2356
|
if (!this.provider) {
|
|
2637
|
-
this.provider = m;
|
|
2357
|
+
this.provider = m;
|
|
2638
2358
|
|
|
2359
|
+
// unregister other providers
|
|
2639
2360
|
this.messageProviders.forEach(m => {
|
|
2640
2361
|
if (this.provider !== m) {
|
|
2641
2362
|
m.unregister();
|
|
@@ -2645,160 +2366,130 @@ class MuxMessageProvider {
|
|
|
2645
2366
|
});
|
|
2646
2367
|
});
|
|
2647
2368
|
};
|
|
2648
|
-
|
|
2649
2369
|
this.unregister = () => {
|
|
2650
2370
|
this.messageProviders.forEach(m => m.unregister());
|
|
2651
2371
|
this.provider = undefined;
|
|
2652
2372
|
};
|
|
2653
|
-
|
|
2654
2373
|
this.openWallet = (path, intent, networkId) => {
|
|
2655
2374
|
if (this.provider) {
|
|
2656
2375
|
this.provider.openWallet(path, intent, networkId);
|
|
2657
2376
|
return;
|
|
2658
2377
|
}
|
|
2659
|
-
|
|
2660
2378
|
this.messageProviders.forEach(m => m.openWallet(path, intent, networkId));
|
|
2661
2379
|
};
|
|
2662
|
-
|
|
2663
2380
|
this.sendAsync = async function (request, callback, chainId) {
|
|
2664
2381
|
if (_this.provider) {
|
|
2665
2382
|
_this.provider.sendAsync(request, callback, chainId);
|
|
2666
|
-
|
|
2667
2383
|
return;
|
|
2668
2384
|
}
|
|
2669
|
-
|
|
2670
2385
|
throw new Error('impossible state, wallet must be opened first');
|
|
2671
2386
|
};
|
|
2672
|
-
|
|
2673
2387
|
this.sendMessageRequest = async function (message) {
|
|
2674
2388
|
if (_this.provider) {
|
|
2675
2389
|
return _this.provider.sendMessageRequest(message);
|
|
2676
2390
|
}
|
|
2677
|
-
|
|
2678
2391
|
throw new Error('impossible state, wallet must be opened first');
|
|
2679
2392
|
};
|
|
2680
|
-
|
|
2681
2393
|
this.waitUntilOpened = async function () {
|
|
2682
2394
|
if (_this.provider) {
|
|
2683
2395
|
return _this.provider.waitUntilOpened();
|
|
2684
2396
|
}
|
|
2685
|
-
|
|
2686
2397
|
return Promise.race(_this.messageProviders.map(p => p.waitUntilOpened()));
|
|
2687
2398
|
};
|
|
2688
|
-
|
|
2689
2399
|
this.waitUntilConnected = async function () {
|
|
2690
2400
|
if (_this.provider) {
|
|
2691
2401
|
return _this.provider.waitUntilConnected();
|
|
2692
2402
|
}
|
|
2693
|
-
|
|
2694
2403
|
throw new Error('impossible state, wallet must be opened first');
|
|
2695
2404
|
};
|
|
2696
|
-
|
|
2697
2405
|
this.messageProviders = messageProviders;
|
|
2698
2406
|
this.provider = undefined;
|
|
2699
2407
|
}
|
|
2700
|
-
|
|
2701
2408
|
add(...messageProviders) {
|
|
2702
2409
|
this.messageProviders.push(...messageProviders);
|
|
2703
2410
|
}
|
|
2704
|
-
|
|
2705
2411
|
closeWallet() {
|
|
2706
2412
|
if (this.provider) {
|
|
2707
2413
|
this.provider.closeWallet();
|
|
2708
2414
|
}
|
|
2709
2415
|
}
|
|
2710
|
-
|
|
2711
2416
|
isOpened() {
|
|
2712
2417
|
if (this.provider) {
|
|
2713
2418
|
return this.provider.isOpened();
|
|
2714
2419
|
}
|
|
2715
|
-
|
|
2716
2420
|
return false;
|
|
2717
2421
|
}
|
|
2718
|
-
|
|
2719
2422
|
isConnected() {
|
|
2720
2423
|
if (this.provider) {
|
|
2721
2424
|
return this.provider.isConnected();
|
|
2722
2425
|
}
|
|
2723
|
-
|
|
2724
2426
|
return false;
|
|
2725
2427
|
}
|
|
2726
|
-
|
|
2727
2428
|
on(event, fn) {
|
|
2728
2429
|
if (this.provider) {
|
|
2729
2430
|
this.provider.on(event, fn);
|
|
2730
2431
|
return;
|
|
2731
2432
|
}
|
|
2732
|
-
|
|
2733
2433
|
this.messageProviders.forEach(m => {
|
|
2734
2434
|
m.on(event, fn);
|
|
2735
2435
|
});
|
|
2736
2436
|
}
|
|
2737
|
-
|
|
2738
2437
|
once(event, fn) {
|
|
2739
2438
|
if (this.provider) {
|
|
2740
2439
|
this.provider.once(event, fn);
|
|
2741
2440
|
return;
|
|
2742
2441
|
}
|
|
2743
|
-
|
|
2744
2442
|
this.messageProviders.forEach(m => {
|
|
2745
2443
|
m.once(event, fn);
|
|
2746
2444
|
});
|
|
2747
2445
|
}
|
|
2748
|
-
|
|
2749
2446
|
emit(event, ...args) {
|
|
2750
2447
|
if (this.provider) {
|
|
2751
2448
|
return this.provider.emit(event, ...args);
|
|
2752
2449
|
}
|
|
2753
|
-
|
|
2754
2450
|
for (let i = 0; i < this.messageProviders.length; i++) {
|
|
2755
2451
|
this.messageProviders[i].emit(event, ...args);
|
|
2756
2452
|
}
|
|
2757
|
-
|
|
2758
2453
|
return true;
|
|
2759
2454
|
}
|
|
2760
|
-
|
|
2761
2455
|
sendMessage(message) {
|
|
2762
2456
|
if (!message.idx || message.idx <= 0) {
|
|
2763
2457
|
throw new Error('message idx is empty');
|
|
2764
2458
|
}
|
|
2765
|
-
|
|
2766
2459
|
if (this.provider) {
|
|
2767
2460
|
this.provider.sendMessage(message);
|
|
2768
2461
|
} else {
|
|
2769
2462
|
throw new Error('impossible state, wallet must be opened first');
|
|
2770
2463
|
}
|
|
2771
2464
|
}
|
|
2772
|
-
|
|
2773
2465
|
handleMessage(message) {
|
|
2774
2466
|
if (this.provider) {
|
|
2775
2467
|
this.provider.handleMessage(message);
|
|
2776
2468
|
return;
|
|
2777
2469
|
}
|
|
2778
|
-
|
|
2779
2470
|
throw new Error('impossible state, wallet must be opened first');
|
|
2780
2471
|
}
|
|
2781
|
-
|
|
2782
2472
|
}
|
|
2783
2473
|
|
|
2474
|
+
// ..
|
|
2784
2475
|
let registeredWindowMessageProvider;
|
|
2785
2476
|
class WindowMessageProvider extends BaseProviderTransport {
|
|
2786
2477
|
constructor(walletAppURL) {
|
|
2787
2478
|
super();
|
|
2788
2479
|
this.walletURL = void 0;
|
|
2789
2480
|
this.walletWindow = void 0;
|
|
2790
|
-
|
|
2791
2481
|
this.register = () => {
|
|
2792
2482
|
if (registeredWindowMessageProvider) {
|
|
2793
2483
|
// overriding the registered message provider
|
|
2794
2484
|
registeredWindowMessageProvider.unregister();
|
|
2795
2485
|
registeredWindowMessageProvider = this;
|
|
2796
|
-
}
|
|
2797
|
-
|
|
2486
|
+
}
|
|
2798
2487
|
|
|
2488
|
+
// listen for incoming messages from wallet
|
|
2799
2489
|
window.addEventListener('message', this.onWindowEvent);
|
|
2800
|
-
registeredWindowMessageProvider = this;
|
|
2490
|
+
registeredWindowMessageProvider = this;
|
|
2801
2491
|
|
|
2492
|
+
// open heartbeat
|
|
2802
2493
|
this.on('open', () => {
|
|
2803
2494
|
// Heartbeat to track if window closed
|
|
2804
2495
|
const popup = this.walletWindow;
|
|
@@ -2808,8 +2499,9 @@ class WindowMessageProvider extends BaseProviderTransport {
|
|
|
2808
2499
|
this.close();
|
|
2809
2500
|
}
|
|
2810
2501
|
}, 500);
|
|
2811
|
-
});
|
|
2502
|
+
});
|
|
2812
2503
|
|
|
2504
|
+
// close clean up
|
|
2813
2505
|
this.on('close', () => {
|
|
2814
2506
|
if (this.walletWindow) {
|
|
2815
2507
|
this.walletWindow.close();
|
|
@@ -2818,65 +2510,60 @@ class WindowMessageProvider extends BaseProviderTransport {
|
|
|
2818
2510
|
});
|
|
2819
2511
|
this._registered = true;
|
|
2820
2512
|
};
|
|
2821
|
-
|
|
2822
2513
|
this.unregister = () => {
|
|
2823
2514
|
this._registered = false;
|
|
2824
|
-
this.closeWallet();
|
|
2515
|
+
this.closeWallet();
|
|
2825
2516
|
|
|
2517
|
+
// disable message listener
|
|
2826
2518
|
if (registeredWindowMessageProvider === this) {
|
|
2827
2519
|
registeredWindowMessageProvider = undefined;
|
|
2828
2520
|
}
|
|
2521
|
+
window.removeEventListener('message', this.onWindowEvent);
|
|
2829
2522
|
|
|
2830
|
-
|
|
2831
|
-
|
|
2523
|
+
// clear event listeners
|
|
2832
2524
|
this.events.removeAllListeners();
|
|
2833
2525
|
};
|
|
2834
|
-
|
|
2835
2526
|
this.openWallet = (path, intent, networkId) => {
|
|
2836
2527
|
if (this.walletWindow && this.isOpened()) {
|
|
2837
2528
|
// TODO: update the location of window to path
|
|
2838
2529
|
this.walletWindow.focus();
|
|
2839
2530
|
return;
|
|
2840
|
-
}
|
|
2841
|
-
|
|
2531
|
+
}
|
|
2842
2532
|
|
|
2533
|
+
// Instantiate new walletURL for this call
|
|
2843
2534
|
const walletURL = new URL(this.walletURL.href);
|
|
2844
2535
|
const windowSessionParams = new WindowSessionParams();
|
|
2845
|
-
|
|
2846
2536
|
if (path && path !== '') {
|
|
2847
2537
|
walletURL.pathname = path.toLowerCase();
|
|
2848
|
-
}
|
|
2849
|
-
|
|
2538
|
+
}
|
|
2850
2539
|
|
|
2540
|
+
// Set session, intent and network id on walletURL
|
|
2851
2541
|
this._init = exports.InitState.NIL;
|
|
2852
2542
|
this._sessionId = `${performance.now()}`;
|
|
2853
2543
|
windowSessionParams.set('sid', this._sessionId);
|
|
2854
|
-
|
|
2855
2544
|
if (intent) {
|
|
2856
2545
|
// for the window-transport, we eagerly/optimistically set the origin host
|
|
2857
2546
|
// when connecting to the wallet, however, this will be verified and enforced
|
|
2858
2547
|
// on the wallet-side, so if a dapp provides the wrong origin, it will be dropped.
|
|
2859
2548
|
if (intent.type === 'connect') {
|
|
2860
|
-
if (!intent.options) intent.options = {};
|
|
2861
|
-
// allow origin that is passed in
|
|
2549
|
+
if (!intent.options) intent.options = {};
|
|
2862
2550
|
|
|
2551
|
+
// skip setting origin host if we're in an browser extension execution context
|
|
2552
|
+
// allow origin that is passed in
|
|
2863
2553
|
if (!isBrowserExtension() && !isUnityPlugin()) {
|
|
2864
2554
|
intent.options.origin = window.location.origin;
|
|
2865
2555
|
}
|
|
2866
|
-
}
|
|
2867
|
-
|
|
2868
|
-
|
|
2556
|
+
}
|
|
2557
|
+
// encode intent as base64 url-encoded param
|
|
2869
2558
|
windowSessionParams.set('intent', utils.base64EncodeObject(intent));
|
|
2870
2559
|
}
|
|
2871
|
-
|
|
2872
2560
|
if (networkId) {
|
|
2873
2561
|
windowSessionParams.set('net', `${networkId}`);
|
|
2874
|
-
}
|
|
2875
|
-
|
|
2562
|
+
}
|
|
2876
2563
|
|
|
2564
|
+
// Open popup window on center of the app window
|
|
2877
2565
|
let windowSize;
|
|
2878
2566
|
let windowPos;
|
|
2879
|
-
|
|
2880
2567
|
if (isBrowserExtension()) {
|
|
2881
2568
|
windowSize = [450, 750];
|
|
2882
2569
|
windowPos = [Math.abs(window.screen.width / 2 - windowSize[0] / 2), Math.abs(window.screen.height / 2 - windowSize[1] / 2)];
|
|
@@ -2884,12 +2571,15 @@ class WindowMessageProvider extends BaseProviderTransport {
|
|
|
2884
2571
|
windowSize = [450, 750];
|
|
2885
2572
|
windowPos = [Math.abs(window.screenX + window.innerWidth / 2 - windowSize[0] / 2), Math.abs(window.screenY + window.innerHeight / 2 - windowSize[1] / 2)];
|
|
2886
2573
|
}
|
|
2574
|
+
const windowFeatures = `toolbar=0,location=0,menubar=0,scrollbars=yes,status=yes` + `,width=${windowSize[0]},height=${windowSize[1]}` + `,left=${windowPos[0]},top=${windowPos[1]}`;
|
|
2887
2575
|
|
|
2888
|
-
|
|
2889
|
-
|
|
2576
|
+
// serialize params
|
|
2890
2577
|
walletURL.search = windowSessionParams.toString();
|
|
2891
|
-
this.walletWindow = window.open(walletURL.href, 'sequence.app', windowFeatures);
|
|
2578
|
+
this.walletWindow = window.open(walletURL.href, 'sequence.app', windowFeatures);
|
|
2579
|
+
|
|
2580
|
+
// TODO: move this somewhere else
|
|
2892
2581
|
// TODO: perhaps we trigger a .on('openTimeout') event..? maybe.. could help.
|
|
2582
|
+
|
|
2893
2583
|
// Popup blocking detection and notice
|
|
2894
2584
|
// let warned = false
|
|
2895
2585
|
// const warnPopupBlocked = () => {
|
|
@@ -2898,112 +2588,100 @@ class WindowMessageProvider extends BaseProviderTransport {
|
|
|
2898
2588
|
// // alert('popup is blocked! hey yo') // NOTE: for debug purposes only
|
|
2899
2589
|
// throw new Error('popup is blocked')
|
|
2900
2590
|
// }
|
|
2591
|
+
|
|
2901
2592
|
// const popupCheck = setTimeout(() => {
|
|
2902
2593
|
// if (!popup || popup.closed || typeof popup.closed === 'undefined') {
|
|
2903
2594
|
// // popup is definitely blocked if we reach here.
|
|
2904
2595
|
// warnPopupBlocked()
|
|
2905
2596
|
// }
|
|
2906
2597
|
// }, 1000)
|
|
2598
|
+
|
|
2907
2599
|
// const popupBlocked = popup === null || popup === undefined
|
|
2908
2600
|
// if (popupBlocked) {
|
|
2909
2601
|
// warnPopupBlocked()
|
|
2910
2602
|
// return
|
|
2911
2603
|
// }
|
|
2912
2604
|
};
|
|
2913
|
-
|
|
2914
2605
|
this.onWindowEvent = event => {
|
|
2915
2606
|
// Security check, ensure message is coming from wallet origin url
|
|
2916
2607
|
if (event.origin !== this.walletURL.origin) {
|
|
2917
2608
|
// Safetly can skip events not from the wallet
|
|
2918
2609
|
return;
|
|
2919
2610
|
}
|
|
2920
|
-
|
|
2921
2611
|
let message;
|
|
2922
|
-
|
|
2923
2612
|
try {
|
|
2924
2613
|
message = JSON.parse(event.data);
|
|
2925
2614
|
} catch (err) {
|
|
2926
2615
|
// event is not a ProviderMessage JSON object, skip
|
|
2927
2616
|
return;
|
|
2928
2617
|
}
|
|
2929
|
-
|
|
2930
2618
|
if (!message) {
|
|
2931
2619
|
throw new Error('ProviderMessage object is empty');
|
|
2932
|
-
}
|
|
2933
|
-
|
|
2620
|
+
}
|
|
2934
2621
|
|
|
2622
|
+
// handle message with base message provider
|
|
2935
2623
|
this.handleMessage(message);
|
|
2936
2624
|
};
|
|
2937
|
-
|
|
2938
2625
|
this.walletURL = new URL(walletAppURL);
|
|
2939
2626
|
}
|
|
2940
|
-
|
|
2941
2627
|
closeWallet() {
|
|
2942
2628
|
var _this$walletWindow;
|
|
2943
|
-
|
|
2944
2629
|
this.close();
|
|
2945
2630
|
(_this$walletWindow = this.walletWindow) == null ? void 0 : _this$walletWindow.close();
|
|
2946
|
-
}
|
|
2631
|
+
}
|
|
2947
2632
|
|
|
2633
|
+
// onmessage, receives ProviderMessageResponse from the wallet post-message transport
|
|
2948
2634
|
|
|
2949
2635
|
sendMessage(message) {
|
|
2950
2636
|
if (!this.walletWindow) {
|
|
2951
2637
|
utils.logger.warn('WindowMessageProvider: sendMessage failed as walletWindow is unavailable');
|
|
2952
2638
|
return;
|
|
2953
2639
|
}
|
|
2954
|
-
|
|
2955
2640
|
const postedMessage = typeof message !== 'string' ? JSON.stringify(message) : message;
|
|
2956
2641
|
this.walletWindow.postMessage(postedMessage, this.walletURL.origin);
|
|
2957
2642
|
}
|
|
2958
|
-
|
|
2959
2643
|
}
|
|
2960
2644
|
|
|
2961
2645
|
class WindowMessageHandler extends BaseWalletTransport {
|
|
2962
2646
|
constructor(walletRequestHandler) {
|
|
2963
2647
|
var _this;
|
|
2964
|
-
|
|
2965
2648
|
super(walletRequestHandler);
|
|
2966
2649
|
_this = this;
|
|
2967
2650
|
this.parentWindow = void 0;
|
|
2968
2651
|
this._isPopup = false;
|
|
2969
|
-
|
|
2970
2652
|
this.onWindowEvent = async function (event) {
|
|
2971
2653
|
if (!event.origin || event.origin === '') {
|
|
2972
2654
|
// skip same-origin or when event.origin is empty/undefined
|
|
2973
2655
|
return;
|
|
2974
2656
|
}
|
|
2975
|
-
|
|
2976
2657
|
if (_this.appOrigin && event.origin !== _this.appOrigin) {
|
|
2977
2658
|
// skip message as not from expected app origin
|
|
2978
2659
|
return;
|
|
2979
|
-
}
|
|
2980
|
-
|
|
2660
|
+
}
|
|
2981
2661
|
|
|
2662
|
+
// Wallet always expects json-rpc request messages from a dapp
|
|
2982
2663
|
let request;
|
|
2983
|
-
|
|
2984
2664
|
try {
|
|
2985
2665
|
request = JSON.parse(event.data);
|
|
2986
2666
|
} catch (err) {
|
|
2987
2667
|
// event is not a ProviderMessage JSON object, skip
|
|
2988
2668
|
return;
|
|
2989
2669
|
}
|
|
2670
|
+
utils.logger.debug('RECEIVED MESSAGE', request);
|
|
2990
2671
|
|
|
2991
|
-
|
|
2992
|
-
|
|
2672
|
+
// Record event origin for valid init ack
|
|
2993
2673
|
if (_this._init !== exports.InitState.OK && _this.isValidInitAck(request)) {
|
|
2994
2674
|
_this.appOrigin = event.origin;
|
|
2995
2675
|
}
|
|
2996
|
-
|
|
2997
2676
|
if (_this._init === exports.InitState.OK && (!_this.appOrigin || _this.appOrigin.length < 8)) {
|
|
2998
2677
|
// impossible state
|
|
2999
2678
|
utils.logger.error('impossible state, init.OK and appOrigin required');
|
|
3000
2679
|
return;
|
|
3001
|
-
}
|
|
3002
|
-
|
|
2680
|
+
}
|
|
3003
2681
|
|
|
2682
|
+
// Handle message via the base transport
|
|
3004
2683
|
_this.handleMessage(request);
|
|
3005
2684
|
};
|
|
3006
|
-
|
|
3007
2685
|
this.getWindowTransportSession = windowParams => {
|
|
3008
2686
|
const params = new WindowSessionParams(windowParams);
|
|
3009
2687
|
return {
|
|
@@ -3012,46 +2690,45 @@ class WindowMessageHandler extends BaseWalletTransport {
|
|
|
3012
2690
|
intent: utils.base64DecodeObject(params.get('intent'))
|
|
3013
2691
|
};
|
|
3014
2692
|
};
|
|
3015
|
-
|
|
3016
2693
|
this._init = exports.InitState.NIL;
|
|
3017
2694
|
}
|
|
3018
|
-
|
|
3019
2695
|
async register(windowHref) {
|
|
3020
2696
|
const isPopup = parent.window.opener !== null;
|
|
3021
2697
|
this._isPopup = isPopup;
|
|
3022
|
-
|
|
3023
2698
|
if (isPopup !== true) {
|
|
3024
2699
|
return;
|
|
3025
|
-
}
|
|
3026
|
-
|
|
2700
|
+
}
|
|
3027
2701
|
|
|
2702
|
+
// record open details (sessionId + default network) from the window url
|
|
3028
2703
|
const {
|
|
3029
2704
|
pathname,
|
|
3030
2705
|
search: rawParams
|
|
3031
2706
|
} = new URL(windowHref || window.location.href);
|
|
3032
|
-
let session = this.getWindowTransportSession(rawParams);
|
|
2707
|
+
let session = this.getWindowTransportSession(rawParams);
|
|
3033
2708
|
|
|
3034
|
-
|
|
2709
|
+
// provider should always include sid when opening a new window
|
|
2710
|
+
const isNewWindowSession = !!session.sessionId;
|
|
3035
2711
|
|
|
2712
|
+
// attempt to restore previous session in the case of a redirect or window reload
|
|
3036
2713
|
if (!isNewWindowSession) {
|
|
3037
2714
|
session = await this.getCachedTransportSession();
|
|
3038
2715
|
}
|
|
3039
|
-
|
|
3040
2716
|
if (!session) {
|
|
3041
2717
|
utils.logger.error('window session is undefined');
|
|
3042
2718
|
return;
|
|
3043
|
-
}
|
|
3044
|
-
|
|
2719
|
+
}
|
|
3045
2720
|
|
|
3046
|
-
|
|
2721
|
+
// record parent window instance for communication
|
|
2722
|
+
this.parentWindow = parent.window.opener;
|
|
3047
2723
|
|
|
2724
|
+
// listen for window-transport requests
|
|
3048
2725
|
window.addEventListener('message', this.onWindowEvent, false);
|
|
3049
|
-
this._registered = true;
|
|
2726
|
+
this._registered = true;
|
|
3050
2727
|
|
|
2728
|
+
// send open event to the app which opened us
|
|
3051
2729
|
this.open(session).then(opened => {
|
|
3052
2730
|
if (!opened) {
|
|
3053
2731
|
var _session;
|
|
3054
|
-
|
|
3055
2732
|
const err = `failed to open to network ${(_session = session) == null ? void 0 : _session.networkId}`;
|
|
3056
2733
|
utils.logger.error(err);
|
|
3057
2734
|
this.notifyClose({
|
|
@@ -3061,7 +2738,6 @@ class WindowMessageHandler extends BaseWalletTransport {
|
|
|
3061
2738
|
}
|
|
3062
2739
|
}).catch(e => {
|
|
3063
2740
|
var _session2;
|
|
3064
|
-
|
|
3065
2741
|
const err = `failed to open to network ${(_session2 = session) == null ? void 0 : _session2.networkId}, due to: ${e}`;
|
|
3066
2742
|
utils.logger.error(err);
|
|
3067
2743
|
this.notifyClose({
|
|
@@ -3070,37 +2746,35 @@ class WindowMessageHandler extends BaseWalletTransport {
|
|
|
3070
2746
|
window.close();
|
|
3071
2747
|
});
|
|
3072
2748
|
}
|
|
3073
|
-
|
|
3074
2749
|
unregister() {
|
|
3075
2750
|
window.removeEventListener('message', this.onWindowEvent);
|
|
3076
2751
|
this._registered = false;
|
|
3077
|
-
}
|
|
3078
|
-
// over the window post-messaging transport
|
|
2752
|
+
}
|
|
3079
2753
|
|
|
2754
|
+
// onmessage is called when (the wallet) receives request messages from the dapp
|
|
2755
|
+
// over the window post-messaging transport
|
|
3080
2756
|
|
|
3081
2757
|
// postMessage sends message to the dapp window
|
|
3082
2758
|
sendMessage(message) {
|
|
3083
2759
|
// prepare payload
|
|
3084
|
-
const payload = JSON.stringify(message);
|
|
3085
|
-
// only for init requests, we send to '*' origin
|
|
2760
|
+
const payload = JSON.stringify(message);
|
|
3086
2761
|
|
|
2762
|
+
// post-message to app.
|
|
2763
|
+
// only for init requests, we send to '*' origin
|
|
3087
2764
|
if (message.type === exports.EventType.INIT) {
|
|
3088
2765
|
this.postMessage(payload, true);
|
|
3089
2766
|
} else {
|
|
3090
2767
|
this.postMessage(payload);
|
|
3091
2768
|
}
|
|
3092
2769
|
}
|
|
3093
|
-
|
|
3094
2770
|
get isPopup() {
|
|
3095
2771
|
return this._isPopup;
|
|
3096
2772
|
}
|
|
3097
|
-
|
|
3098
2773
|
postMessage(message, init = false) {
|
|
3099
2774
|
if (init !== true && this._init !== exports.InitState.OK) {
|
|
3100
2775
|
utils.logger.error('impossible state, should not be calling postMessage until inited');
|
|
3101
2776
|
return;
|
|
3102
2777
|
}
|
|
3103
|
-
|
|
3104
2778
|
if (init) {
|
|
3105
2779
|
// init message transmission to global target -- for 'init' payloads only
|
|
3106
2780
|
this.parentWindow.postMessage(message, '*');
|
|
@@ -3114,7 +2788,6 @@ class WindowMessageHandler extends BaseWalletTransport {
|
|
|
3114
2788
|
}
|
|
3115
2789
|
}
|
|
3116
2790
|
}
|
|
3117
|
-
|
|
3118
2791
|
}
|
|
3119
2792
|
|
|
3120
2793
|
const CHANNEL_ID = 'sequence-extension-message-handler';
|
|
@@ -3125,29 +2798,24 @@ class ExtensionMessageHandler extends BaseWalletTransport {
|
|
|
3125
2798
|
this.port = void 0;
|
|
3126
2799
|
this._init = exports.InitState.OK;
|
|
3127
2800
|
}
|
|
3128
|
-
|
|
3129
2801
|
register() {
|
|
3130
2802
|
this._registered = true;
|
|
3131
2803
|
this.port = this.runtime.connect({
|
|
3132
2804
|
name: CHANNEL_ID
|
|
3133
2805
|
});
|
|
3134
2806
|
}
|
|
3135
|
-
|
|
3136
2807
|
sendMessage(message) {
|
|
3137
2808
|
utils.logger.info('[ExtensionMessageHandler send]', message);
|
|
3138
2809
|
this.port.postMessage(message);
|
|
3139
2810
|
}
|
|
3140
|
-
|
|
3141
2811
|
}
|
|
3142
2812
|
|
|
3143
2813
|
class ExtensionMessageProvider extends BaseProviderTransport {
|
|
3144
2814
|
constructor(runtime) {
|
|
3145
2815
|
super();
|
|
3146
|
-
|
|
3147
2816
|
this.register = () => {
|
|
3148
2817
|
this._registered = true;
|
|
3149
2818
|
};
|
|
3150
|
-
|
|
3151
2819
|
runtime.onConnect.addListener(port => {
|
|
3152
2820
|
if (port.name === CHANNEL_ID) {
|
|
3153
2821
|
this._init = exports.InitState.OK;
|
|
@@ -3157,47 +2825,40 @@ class ExtensionMessageProvider extends BaseProviderTransport {
|
|
|
3157
2825
|
}
|
|
3158
2826
|
});
|
|
3159
2827
|
}
|
|
3160
|
-
|
|
3161
|
-
|
|
2828
|
+
sendMessage(message) {
|
|
2829
|
+
//noop
|
|
3162
2830
|
}
|
|
3163
|
-
|
|
3164
|
-
|
|
2831
|
+
unregister() {
|
|
2832
|
+
//noop
|
|
3165
2833
|
}
|
|
3166
|
-
|
|
3167
|
-
|
|
2834
|
+
openWallet(path, intent, networkId) {
|
|
2835
|
+
//noop
|
|
3168
2836
|
}
|
|
3169
|
-
|
|
3170
|
-
|
|
2837
|
+
closeWallet() {
|
|
2838
|
+
//noop
|
|
3171
2839
|
}
|
|
3172
|
-
|
|
3173
2840
|
}
|
|
3174
2841
|
|
|
3175
2842
|
// to be used on injected window.ethereum EIP1193 proxy
|
|
3176
2843
|
class BaseInjectedTransport extends eventemitter2.EventEmitter2 {
|
|
3177
2844
|
constructor(stream) {
|
|
3178
2845
|
var _this;
|
|
3179
|
-
|
|
3180
2846
|
super();
|
|
3181
2847
|
_this = this;
|
|
3182
2848
|
this.stream = stream;
|
|
3183
2849
|
this.responseCallbacks = new Map();
|
|
3184
2850
|
this._messageIdx = 0;
|
|
3185
|
-
|
|
3186
2851
|
this.nextMessageIdx = () => ++this._messageIdx;
|
|
3187
|
-
|
|
3188
2852
|
this.handleMessage = message => {
|
|
3189
2853
|
if (!message.type || !message.data) {
|
|
3190
2854
|
return;
|
|
3191
2855
|
}
|
|
3192
|
-
|
|
3193
2856
|
utils.logger.info('[received message]', message);
|
|
3194
2857
|
const requestIdx = message.idx;
|
|
3195
2858
|
const responseCallback = this.responseCallbacks.get(requestIdx);
|
|
3196
|
-
|
|
3197
2859
|
if (requestIdx) {
|
|
3198
2860
|
this.responseCallbacks.delete(requestIdx);
|
|
3199
2861
|
}
|
|
3200
|
-
|
|
3201
2862
|
switch (message.type) {
|
|
3202
2863
|
case exports.EventType.MESSAGE:
|
|
3203
2864
|
if (responseCallback) {
|
|
@@ -3209,27 +2870,22 @@ class BaseInjectedTransport extends eventemitter2.EventEmitter2 {
|
|
|
3209
2870
|
// all of which should be prevented prior to getting to this point
|
|
3210
2871
|
throw new Error('impossible state');
|
|
3211
2872
|
}
|
|
3212
|
-
|
|
3213
2873
|
break;
|
|
3214
|
-
|
|
3215
2874
|
case exports.EventType.DISCONNECT:
|
|
3216
2875
|
case exports.EventType.ACCOUNTS_CHANGED:
|
|
3217
2876
|
case exports.EventType.CHAIN_CHANGED:
|
|
3218
2877
|
this.emit(message.type, message.data);
|
|
3219
2878
|
break;
|
|
3220
|
-
|
|
3221
2879
|
default:
|
|
3222
2880
|
console.error('unknown message type', message);
|
|
3223
2881
|
break;
|
|
3224
2882
|
}
|
|
3225
2883
|
};
|
|
3226
|
-
|
|
3227
2884
|
this.sendMessageRequest = async function (message) {
|
|
3228
2885
|
return new Promise((resolve, reject) => {
|
|
3229
2886
|
if (!message.idx || message.idx <= 0) {
|
|
3230
2887
|
reject(new Error('message idx not set'));
|
|
3231
2888
|
}
|
|
3232
|
-
|
|
3233
2889
|
const responseCallback = (error, response) => {
|
|
3234
2890
|
if (error) {
|
|
3235
2891
|
reject(error);
|
|
@@ -3239,32 +2895,25 @@ class BaseInjectedTransport extends eventemitter2.EventEmitter2 {
|
|
|
3239
2895
|
throw new Error('no valid response to return');
|
|
3240
2896
|
}
|
|
3241
2897
|
};
|
|
3242
|
-
|
|
3243
2898
|
const {
|
|
3244
2899
|
idx
|
|
3245
2900
|
} = message;
|
|
3246
|
-
|
|
3247
2901
|
if (!_this.responseCallbacks.get(idx)) {
|
|
3248
2902
|
_this.responseCallbacks.set(idx, responseCallback);
|
|
3249
2903
|
} else {
|
|
3250
2904
|
reject(new Error('duplicate message idx, should never happen'));
|
|
3251
2905
|
}
|
|
3252
|
-
|
|
3253
2906
|
_this.sendMessage(message);
|
|
3254
2907
|
});
|
|
3255
2908
|
};
|
|
3256
|
-
|
|
3257
2909
|
this.stream.on('data', this.handleMessage);
|
|
3258
2910
|
}
|
|
3259
|
-
|
|
3260
2911
|
sendMessage(message) {
|
|
3261
2912
|
if (!this.stream.writable) {
|
|
3262
2913
|
console.error('window post message stream is not writable');
|
|
3263
2914
|
}
|
|
3264
|
-
|
|
3265
2915
|
this.stream.write(message);
|
|
3266
2916
|
}
|
|
3267
|
-
|
|
3268
2917
|
}
|
|
3269
2918
|
|
|
3270
2919
|
/**
|
|
@@ -3272,33 +2921,28 @@ class BaseInjectedTransport extends eventemitter2.EventEmitter2 {
|
|
|
3272
2921
|
*/
|
|
3273
2922
|
function overrideLogs(side) {
|
|
3274
2923
|
var _window$ue;
|
|
3275
|
-
|
|
3276
2924
|
if ((_window$ue = window.ue) != null && _window$ue.sequencewallettransport && !window.logsOverriddenForUnreal) {
|
|
3277
2925
|
var _window$ue2;
|
|
3278
|
-
|
|
3279
2926
|
const t = (_window$ue2 = window.ue) == null ? void 0 : _window$ue2.sequencewallettransport;
|
|
3280
|
-
|
|
3281
2927
|
console.log = (...args) => {
|
|
3282
2928
|
t.logfromjs(`${side}: ${stringify(args)}`);
|
|
3283
2929
|
};
|
|
3284
|
-
|
|
3285
2930
|
console.warn = (...args) => {
|
|
3286
2931
|
t.warnfromjs(`${side}: ${stringify(args)}`);
|
|
3287
2932
|
};
|
|
3288
|
-
|
|
3289
2933
|
console.error = (...args) => {
|
|
3290
2934
|
t.errorfromjs(`${side}: ${stringify(args)}`);
|
|
3291
2935
|
};
|
|
3292
|
-
|
|
3293
2936
|
window.logsOverriddenForUnreal = true;
|
|
3294
2937
|
}
|
|
3295
2938
|
}
|
|
3296
|
-
|
|
3297
2939
|
function stringify(things) {
|
|
3298
2940
|
return things.map(a => typeof a === 'object' ? a instanceof Error ? a.message : JSON.stringify(a) : String(a)).join(' ');
|
|
3299
2941
|
}
|
|
3300
2942
|
|
|
3301
|
-
let registeredUnrealMessageProvider;
|
|
2943
|
+
let registeredUnrealMessageProvider;
|
|
2944
|
+
|
|
2945
|
+
// all lowercase is an annoying limitation of Unreal CEF BindUObject
|
|
3302
2946
|
|
|
3303
2947
|
/**
|
|
3304
2948
|
* Initialized on dApp side
|
|
@@ -3307,124 +2951,110 @@ class UnrealMessageProvider extends BaseProviderTransport {
|
|
|
3307
2951
|
constructor(walletAppURL) {
|
|
3308
2952
|
super();
|
|
3309
2953
|
this.walletURL = void 0;
|
|
3310
|
-
|
|
3311
2954
|
this.register = () => {
|
|
3312
2955
|
var _window$ue;
|
|
3313
|
-
|
|
3314
2956
|
overrideLogs('dapp');
|
|
3315
|
-
|
|
3316
2957
|
if (registeredUnrealMessageProvider) {
|
|
3317
2958
|
// overriding the registered message provider
|
|
3318
2959
|
registeredUnrealMessageProvider.unregister();
|
|
3319
2960
|
registeredUnrealMessageProvider = this;
|
|
3320
|
-
}
|
|
3321
|
-
|
|
2961
|
+
}
|
|
3322
2962
|
|
|
2963
|
+
// listen for incoming messages from wallet
|
|
3323
2964
|
if ((_window$ue = window.ue) != null && _window$ue.sequencewallettransport) {
|
|
3324
2965
|
window.ue.sequencewallettransport.onmessagefromwallet = this.onUnrealCallback;
|
|
3325
2966
|
}
|
|
3326
|
-
|
|
3327
2967
|
registeredUnrealMessageProvider = this;
|
|
3328
2968
|
this._registered = true;
|
|
3329
2969
|
console.log('registering transport!');
|
|
3330
2970
|
};
|
|
3331
|
-
|
|
3332
2971
|
this.unregister = () => {
|
|
3333
2972
|
var _window$ue2, _window$ue2$sequencew;
|
|
3334
|
-
|
|
3335
2973
|
this._registered = false;
|
|
3336
|
-
this.closeWallet();
|
|
2974
|
+
this.closeWallet();
|
|
3337
2975
|
|
|
2976
|
+
// disable message listener
|
|
3338
2977
|
if (registeredUnrealMessageProvider === this) {
|
|
3339
2978
|
registeredUnrealMessageProvider = undefined;
|
|
3340
2979
|
}
|
|
3341
|
-
|
|
3342
2980
|
if (((_window$ue2 = window.ue) == null ? void 0 : (_window$ue2$sequencew = _window$ue2.sequencewallettransport) == null ? void 0 : _window$ue2$sequencew.onmessagefromwallet) === this.onUnrealCallback) {
|
|
3343
2981
|
delete window.ue.sequencewallettransport.onmessagefromwallet;
|
|
3344
|
-
}
|
|
3345
|
-
|
|
2982
|
+
}
|
|
3346
2983
|
|
|
2984
|
+
// clear event listeners
|
|
3347
2985
|
this.events.removeAllListeners();
|
|
3348
2986
|
};
|
|
3349
|
-
|
|
3350
2987
|
this.openWallet = (path, intent, networkId) => {
|
|
3351
2988
|
if (this.isOpened()) {
|
|
3352
2989
|
// TODO focus wallet
|
|
3353
2990
|
console.log('wallet already open!');
|
|
3354
2991
|
return;
|
|
3355
2992
|
}
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
2993
|
+
console.log('opening wallet!');
|
|
2994
|
+
// Instantiate new walletURL for this call
|
|
3359
2995
|
const walletURL = new URL(this.walletURL.href);
|
|
3360
2996
|
const windowSessionParams = new WindowSessionParams();
|
|
3361
|
-
|
|
3362
2997
|
if (path) {
|
|
3363
2998
|
walletURL.pathname = path.toLowerCase();
|
|
3364
|
-
}
|
|
3365
|
-
|
|
2999
|
+
}
|
|
3366
3000
|
|
|
3001
|
+
// Set session, intent and network id on walletURL
|
|
3367
3002
|
this._init = exports.InitState.NIL;
|
|
3368
3003
|
this._sessionId = `${performance.now()}`;
|
|
3369
3004
|
windowSessionParams.set('sid', this._sessionId);
|
|
3370
|
-
|
|
3371
3005
|
if (intent) {
|
|
3372
3006
|
// encode intent as base64 url-encoded param
|
|
3373
3007
|
windowSessionParams.set('intent', utils.base64EncodeObject(intent));
|
|
3374
3008
|
}
|
|
3375
|
-
|
|
3376
3009
|
if (networkId) {
|
|
3377
3010
|
windowSessionParams.set('net', `${networkId}`);
|
|
3378
|
-
}
|
|
3379
|
-
|
|
3380
|
-
|
|
3011
|
+
}
|
|
3012
|
+
// serialize params
|
|
3381
3013
|
walletURL.search = windowSessionParams.toString();
|
|
3382
3014
|
console.log('opening wallet to', walletURL.href);
|
|
3383
3015
|
window.open(walletURL.href);
|
|
3384
3016
|
};
|
|
3385
|
-
|
|
3386
3017
|
this.onUnrealCallback = message => {
|
|
3387
3018
|
if (!message) {
|
|
3388
3019
|
throw new Error('ProviderMessage object is empty');
|
|
3389
|
-
}
|
|
3390
|
-
|
|
3020
|
+
}
|
|
3391
3021
|
|
|
3022
|
+
// handle message with base message provider
|
|
3392
3023
|
this.handleMessage(message);
|
|
3393
3024
|
};
|
|
3394
|
-
|
|
3395
3025
|
this.walletURL = new URL(walletAppURL);
|
|
3396
3026
|
}
|
|
3397
|
-
|
|
3398
3027
|
closeWallet() {
|
|
3399
3028
|
this.close();
|
|
3400
|
-
}
|
|
3029
|
+
}
|
|
3401
3030
|
|
|
3031
|
+
// onmessage, receives ProviderMessageResponse from the wallet unreal transport
|
|
3402
3032
|
|
|
3403
3033
|
// all lowercase is an annoying limitation of Unreal CEF BindUObject
|
|
3404
3034
|
sendMessage(message) {
|
|
3405
3035
|
var _window$ue3, _window$ue3$sequencew;
|
|
3406
|
-
|
|
3407
3036
|
const postedMessage = typeof message !== 'string' ? JSON.stringify(message) : message;
|
|
3408
3037
|
console.log('Sending message to wallet:', postedMessage);
|
|
3409
3038
|
(_window$ue3 = window.ue) == null ? void 0 : (_window$ue3$sequencew = _window$ue3.sequencewallettransport) == null ? void 0 : _window$ue3$sequencew.sendmessagetowallet(postedMessage);
|
|
3410
3039
|
}
|
|
3411
|
-
|
|
3412
3040
|
}
|
|
3413
3041
|
|
|
3042
|
+
// all lowercase is an annoying limitation of Unreal CEF BindUObject
|
|
3043
|
+
|
|
3414
3044
|
/**
|
|
3415
3045
|
* Initialized on Wallet side
|
|
3416
3046
|
*/
|
|
3417
3047
|
class UnrealMessageHandler extends BaseWalletTransport {
|
|
3418
3048
|
constructor(walletRequestHandler) {
|
|
3419
3049
|
super(walletRequestHandler);
|
|
3420
|
-
|
|
3421
3050
|
this.onMessageFromUnreal = request => {
|
|
3422
3051
|
// Wallet always expects json-rpc request messages from a dapp
|
|
3423
|
-
utils.logger.debug('RECEIVED MESSAGE', request); // Handle message via the base transport
|
|
3424
3052
|
|
|
3053
|
+
utils.logger.debug('RECEIVED MESSAGE', request);
|
|
3054
|
+
|
|
3055
|
+
// Handle message via the base transport
|
|
3425
3056
|
this.handleMessage(request);
|
|
3426
3057
|
};
|
|
3427
|
-
|
|
3428
3058
|
this.getUnrealTransportSession = windowParams => {
|
|
3429
3059
|
const params = new WindowSessionParams(windowParams);
|
|
3430
3060
|
return {
|
|
@@ -3433,43 +3063,41 @@ class UnrealMessageHandler extends BaseWalletTransport {
|
|
|
3433
3063
|
intent: utils.base64DecodeObject(params.get('intent'))
|
|
3434
3064
|
};
|
|
3435
3065
|
};
|
|
3436
|
-
|
|
3437
3066
|
this._init = exports.InitState.NIL;
|
|
3438
3067
|
}
|
|
3439
|
-
|
|
3440
3068
|
async register(windowHref) {
|
|
3441
3069
|
var _window$ue;
|
|
3442
|
-
|
|
3443
3070
|
if (((_window$ue = window.ue) == null ? void 0 : _window$ue.sequencewallettransport) === undefined) {
|
|
3444
3071
|
return;
|
|
3445
3072
|
}
|
|
3073
|
+
overrideLogs('wallet');
|
|
3446
3074
|
|
|
3447
|
-
|
|
3448
|
-
|
|
3075
|
+
// record open details (sessionId + default network) from the window url
|
|
3449
3076
|
const {
|
|
3450
3077
|
search: rawParams
|
|
3451
3078
|
} = new URL(windowHref || window.location.href);
|
|
3452
|
-
let session = this.getUnrealTransportSession(rawParams);
|
|
3079
|
+
let session = this.getUnrealTransportSession(rawParams);
|
|
3453
3080
|
|
|
3454
|
-
|
|
3081
|
+
// provider should always include sid when opening a new window
|
|
3082
|
+
const isNewWindowSession = !!session.sessionId;
|
|
3455
3083
|
|
|
3084
|
+
// attempt to restore previous session in the case of a redirect or window reload
|
|
3456
3085
|
if (!isNewWindowSession) {
|
|
3457
3086
|
session = await this.getCachedTransportSession();
|
|
3458
3087
|
}
|
|
3459
|
-
|
|
3460
3088
|
if (!session) {
|
|
3461
3089
|
utils.logger.error('unreal session is undefined');
|
|
3462
3090
|
return;
|
|
3463
|
-
}
|
|
3464
|
-
|
|
3091
|
+
}
|
|
3465
3092
|
|
|
3093
|
+
// listen for window-transport requests
|
|
3466
3094
|
window.ue.sequencewallettransport.onmessagefromsequencejs = this.onMessageFromUnreal;
|
|
3467
|
-
this._registered = true;
|
|
3095
|
+
this._registered = true;
|
|
3468
3096
|
|
|
3097
|
+
// send open event to the app which opened us
|
|
3469
3098
|
this.open(session).then(opened => {
|
|
3470
3099
|
if (!opened) {
|
|
3471
3100
|
var _session;
|
|
3472
|
-
|
|
3473
3101
|
const err = `failed to open to network ${(_session = session) == null ? void 0 : _session.networkId}`;
|
|
3474
3102
|
utils.logger.error(err);
|
|
3475
3103
|
this.notifyClose({
|
|
@@ -3479,7 +3107,6 @@ class UnrealMessageHandler extends BaseWalletTransport {
|
|
|
3479
3107
|
}
|
|
3480
3108
|
}).catch(e => {
|
|
3481
3109
|
var _session2;
|
|
3482
|
-
|
|
3483
3110
|
const err = `failed to open to network ${(_session2 = session) == null ? void 0 : _session2.networkId}, due to: ${e}`;
|
|
3484
3111
|
utils.logger.error(err);
|
|
3485
3112
|
this.notifyClose({
|
|
@@ -3488,132 +3115,127 @@ class UnrealMessageHandler extends BaseWalletTransport {
|
|
|
3488
3115
|
window.close();
|
|
3489
3116
|
});
|
|
3490
3117
|
}
|
|
3491
|
-
|
|
3492
3118
|
unregister() {
|
|
3493
3119
|
var _window$ue2, _window$ue2$sequencew;
|
|
3494
|
-
|
|
3495
3120
|
if (((_window$ue2 = window.ue) == null ? void 0 : (_window$ue2$sequencew = _window$ue2.sequencewallettransport) == null ? void 0 : _window$ue2$sequencew.onmessagefromsequencejs) === this.onMessageFromUnreal) {
|
|
3496
3121
|
delete window.ue.sequencewallettransport.onmessagefromsequencejs;
|
|
3497
3122
|
}
|
|
3498
|
-
|
|
3499
3123
|
this._registered = false;
|
|
3500
|
-
}
|
|
3501
|
-
// over the unreal json-messaging transport
|
|
3124
|
+
}
|
|
3502
3125
|
|
|
3126
|
+
// onmessage is called when (the wallet) receives request messages from the dapp
|
|
3127
|
+
// over the unreal json-messaging transport
|
|
3503
3128
|
|
|
3504
3129
|
// sendMessage sends message to the dapp window
|
|
3505
3130
|
sendMessage(message) {
|
|
3506
3131
|
var _window$ue3, _window$ue3$sequencew;
|
|
3507
|
-
|
|
3508
3132
|
if (message.type !== exports.EventType.INIT && this._init !== exports.InitState.OK) {
|
|
3509
3133
|
utils.logger.error('impossible state, should not be calling postMessage until inited');
|
|
3510
3134
|
return;
|
|
3511
|
-
}
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
const payload = JSON.stringify(message); // post-message to app.
|
|
3135
|
+
}
|
|
3136
|
+
// prepare payload
|
|
3137
|
+
const payload = JSON.stringify(message);
|
|
3515
3138
|
|
|
3139
|
+
// post-message to app.
|
|
3516
3140
|
(_window$ue3 = window.ue) == null ? void 0 : (_window$ue3$sequencew = _window$ue3.sequencewallettransport) == null ? void 0 : _window$ue3$sequencew.sendmessagetosequencejs(payload);
|
|
3517
3141
|
}
|
|
3518
|
-
|
|
3519
3142
|
}
|
|
3520
3143
|
|
|
3521
3144
|
class WalletUtils {
|
|
3522
3145
|
constructor(walletProvider) {
|
|
3523
3146
|
var _this = this;
|
|
3524
|
-
|
|
3525
3147
|
this.wallet = void 0;
|
|
3526
|
-
|
|
3527
3148
|
this.recoverWalletConfig = async function (address, digest, signature, chainId, walletContext) {
|
|
3528
3149
|
walletContext = walletContext || (await _this.wallet.getWalletContext());
|
|
3529
3150
|
return recoverWalletConfig(address, digest, signature, chainId, walletContext);
|
|
3530
3151
|
};
|
|
3531
|
-
|
|
3532
3152
|
this.recoverWalletConfigFromMessage = async function (address, message, signature, chainId, walletContext) {
|
|
3533
3153
|
walletContext = walletContext || (await _this.wallet.getWalletContext());
|
|
3534
3154
|
return recoverWalletConfig(address, utils.encodeMessageDigest(prefixEIP191Message(message)), signature, chainId, walletContext);
|
|
3535
3155
|
};
|
|
3536
|
-
|
|
3537
3156
|
this.recoverWalletConfigFromTypedData = async function (address, typedData, signature, chainId, walletContext) {
|
|
3538
3157
|
walletContext = walletContext || (await _this.wallet.getWalletContext());
|
|
3539
3158
|
return recoverWalletConfig(address, utils.encodeTypedDataDigest(typedData), signature, chainId, walletContext);
|
|
3540
3159
|
};
|
|
3541
|
-
|
|
3542
3160
|
this.wallet = walletProvider;
|
|
3543
|
-
}
|
|
3544
|
-
|
|
3161
|
+
}
|
|
3545
3162
|
|
|
3163
|
+
// Sign message on a specified chain, or DefaultChain by default
|
|
3546
3164
|
signMessage(message, chainId, allSigners) {
|
|
3547
3165
|
const signer = this.wallet.getSigner();
|
|
3548
3166
|
if (!signer) throw new Error('unable to get signer');
|
|
3549
3167
|
return signer.signMessage(message, chainId, allSigners);
|
|
3550
|
-
}
|
|
3551
|
-
|
|
3168
|
+
}
|
|
3552
3169
|
|
|
3170
|
+
// Sign message on the AuthChain
|
|
3553
3171
|
async signAuthMessage(message, allSigners) {
|
|
3554
3172
|
const signer = await this.wallet.getAuthSigner();
|
|
3555
3173
|
if (!signer) throw new Error('unable to get AuthChain signer');
|
|
3556
3174
|
return signer.signMessage(message, await signer.getChainId(), allSigners);
|
|
3557
|
-
}
|
|
3558
|
-
|
|
3175
|
+
}
|
|
3559
3176
|
|
|
3177
|
+
// Sign EIP-712 TypedData on a specified chain, or DefaultChain by default
|
|
3560
3178
|
signTypedData(domain, types, message, chainId, allSigners) {
|
|
3561
3179
|
const signer = this.wallet.getSigner();
|
|
3562
3180
|
if (!signer) throw new Error('unable to get signer');
|
|
3563
3181
|
return signer.signTypedData(domain, types, message, chainId, allSigners);
|
|
3564
|
-
}
|
|
3565
|
-
|
|
3182
|
+
}
|
|
3566
3183
|
|
|
3184
|
+
// Sign EIP-712 TypedData on the AuthChain
|
|
3567
3185
|
async signAuthTypedData(domain, types, message, allSigners) {
|
|
3568
3186
|
const signer = await this.wallet.getAuthSigner();
|
|
3569
3187
|
if (!signer) throw new Error('unable to get AuthChain signer');
|
|
3570
3188
|
return signer.signTypedData(domain, types, message, await signer.getChainId(), allSigners);
|
|
3571
|
-
}
|
|
3572
|
-
|
|
3189
|
+
}
|
|
3573
3190
|
|
|
3191
|
+
// Verify signature of a digest, one of a message, typedData or other
|
|
3574
3192
|
async isValidSignature(address, digest, signature, chainId, walletContext) {
|
|
3575
3193
|
const provider = this.wallet.getProvider(chainId);
|
|
3576
3194
|
if (!provider) throw new Error(`unable to get provider for chainId ${chainId}`);
|
|
3577
3195
|
return isValidSignature(address, digest, signature, provider, chainId, walletContext);
|
|
3578
|
-
}
|
|
3579
|
-
|
|
3196
|
+
}
|
|
3580
3197
|
|
|
3198
|
+
// Verify message signature
|
|
3581
3199
|
async isValidMessageSignature(address, message, signature, chainId, walletContext) {
|
|
3582
3200
|
const provider = this.wallet.getProvider(chainId);
|
|
3583
3201
|
if (!provider) throw new Error(`unable to get provider for chainId ${chainId}`);
|
|
3584
3202
|
const prefixed = prefixEIP191Message(message);
|
|
3585
3203
|
const digest = utils.encodeMessageDigest(prefixed);
|
|
3586
3204
|
return isValidSignature(address, digest, signature, provider, chainId, walletContext);
|
|
3587
|
-
}
|
|
3588
|
-
|
|
3205
|
+
}
|
|
3589
3206
|
|
|
3207
|
+
// Verify typedData signature
|
|
3590
3208
|
isValidTypedDataSignature(address, typedData, signature, chainId, walletContext) {
|
|
3591
3209
|
return this.isValidSignature(address, utils.encodeTypedDataDigest(typedData), signature, chainId, walletContext);
|
|
3592
|
-
}
|
|
3210
|
+
}
|
|
3211
|
+
|
|
3212
|
+
// Recover the WalletConfig from a signature + digest combo
|
|
3213
|
+
|
|
3593
3214
|
// sendTransaction()
|
|
3594
3215
|
// sendTransactions()
|
|
3216
|
+
|
|
3595
3217
|
// sendETH()
|
|
3596
3218
|
// sendToken()
|
|
3597
3219
|
// sendCoin() -- sugar for sendToken()
|
|
3598
3220
|
// sendCollectible() -- sugar for sendToken()
|
|
3599
3221
|
// callContract()
|
|
3222
|
+
|
|
3600
3223
|
// transactionHistory()
|
|
3601
3224
|
// getReceipt()
|
|
3602
3225
|
// getLogs()
|
|
3603
3226
|
// // ..
|
|
3227
|
+
|
|
3604
3228
|
// isWalletDeployed()
|
|
3605
3229
|
// deployWallet()
|
|
3230
|
+
|
|
3606
3231
|
// validateSignature()
|
|
3607
3232
|
// recoverWalletConfig()
|
|
3608
3233
|
// recoverAddress()
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
3234
|
}
|
|
3612
3235
|
|
|
3613
3236
|
class Wallet {
|
|
3614
3237
|
constructor(_network, config) {
|
|
3615
3238
|
var _this = this;
|
|
3616
|
-
|
|
3617
3239
|
this.utils = void 0;
|
|
3618
3240
|
this.config = void 0;
|
|
3619
3241
|
this.session = void 0;
|
|
@@ -3621,32 +3243,32 @@ class Wallet {
|
|
|
3621
3243
|
this.transport = void 0;
|
|
3622
3244
|
this.networks = void 0;
|
|
3623
3245
|
this.providers = void 0;
|
|
3624
|
-
|
|
3625
3246
|
this.init = () => {
|
|
3626
3247
|
var _this$config$transpor, _this$config$transpor2, _this$config$transpor3, _this$config$transpor4, _this$config$transpor5, _this$config$transpor6, _this$config$transpor7, _this$config$transpor8;
|
|
3627
|
-
|
|
3628
3248
|
if (this.transport.provider) {
|
|
3629
3249
|
// init must have already been called
|
|
3630
3250
|
return;
|
|
3631
|
-
}
|
|
3251
|
+
}
|
|
3632
3252
|
|
|
3253
|
+
// Setup provider
|
|
3633
3254
|
|
|
3634
|
-
this.transport.messageProvider = new MuxMessageProvider();
|
|
3255
|
+
this.transport.messageProvider = new MuxMessageProvider();
|
|
3635
3256
|
|
|
3257
|
+
// multiple message provider setup, first one to connect will be the main transport
|
|
3636
3258
|
if ((_this$config$transpor = this.config.transports) != null && (_this$config$transpor2 = _this$config$transpor.windowTransport) != null && _this$config$transpor2.enabled) {
|
|
3637
3259
|
this.transport.windowMessageProvider = new WindowMessageProvider(this.config.walletAppURL);
|
|
3638
3260
|
this.transport.messageProvider.add(this.transport.windowMessageProvider);
|
|
3639
3261
|
}
|
|
3640
|
-
|
|
3641
3262
|
if ((_this$config$transpor3 = this.config.transports) != null && (_this$config$transpor4 = _this$config$transpor3.proxyTransport) != null && _this$config$transpor4.enabled) {
|
|
3642
3263
|
this.transport.proxyMessageProvider = new ProxyMessageProvider(this.config.transports.proxyTransport.appPort);
|
|
3643
3264
|
this.transport.messageProvider.add(this.transport.proxyMessageProvider);
|
|
3644
3265
|
}
|
|
3645
|
-
|
|
3646
3266
|
if ((_this$config$transpor5 = this.config.transports) != null && (_this$config$transpor6 = _this$config$transpor5.extensionTransport) != null && _this$config$transpor6.enabled) {
|
|
3647
|
-
this.transport.extensionMessageProvider = new ExtensionMessageProvider(this.config.transports.extensionTransport.runtime);
|
|
3267
|
+
this.transport.extensionMessageProvider = new ExtensionMessageProvider(this.config.transports.extensionTransport.runtime);
|
|
3268
|
+
// this.transport.extensionMessageProvider.register()
|
|
3269
|
+
this.transport.messageProvider.add(this.transport.extensionMessageProvider);
|
|
3648
3270
|
|
|
3649
|
-
|
|
3271
|
+
// NOTE/REVIEW: see note in mux-message-provider
|
|
3650
3272
|
//
|
|
3651
3273
|
// We don't add the extensionMessageProvider here because we don't send requests to it anyways, we seem to
|
|
3652
3274
|
// send all requests to the WindowMessageProvider anyways. By allowing it, if browser restarts, it will break
|
|
@@ -3659,27 +3281,28 @@ class Wallet {
|
|
|
3659
3281
|
this.transport.unrealMessageProvider = new UnrealMessageProvider(this.config.walletAppURL);
|
|
3660
3282
|
this.transport.messageProvider.add(this.transport.unrealMessageProvider);
|
|
3661
3283
|
}
|
|
3284
|
+
this.transport.messageProvider.register();
|
|
3662
3285
|
|
|
3663
|
-
|
|
3664
|
-
|
|
3286
|
+
// .....
|
|
3665
3287
|
this.transport.allowProvider = network.allowProviderMiddleware(request => {
|
|
3666
3288
|
if (request.method === 'sequence_setDefaultNetwork') return true;
|
|
3667
3289
|
const isConnected = this.isConnected();
|
|
3668
|
-
|
|
3669
3290
|
if (!isConnected) {
|
|
3670
3291
|
throw new Error('Sequence: wallet not connected');
|
|
3671
3292
|
}
|
|
3672
|
-
|
|
3673
3293
|
return isConnected;
|
|
3674
|
-
});
|
|
3294
|
+
});
|
|
3675
3295
|
|
|
3296
|
+
// ...
|
|
3676
3297
|
this.transport.networkProvider = network.networkProviderMiddleware(request => {
|
|
3677
3298
|
// return stub chainId of 0 when not connected to any
|
|
3678
|
-
if (!this.networks || this.networks.length === 0) return 0;
|
|
3299
|
+
if (!this.networks || this.networks.length === 0) return 0;
|
|
3679
3300
|
|
|
3301
|
+
// return the default chainId as we're connected
|
|
3680
3302
|
return this.networks.find(network => network.isDefaultChain).chainId;
|
|
3681
|
-
});
|
|
3303
|
+
});
|
|
3682
3304
|
|
|
3305
|
+
// Provider proxy to support middleware stack of logging, caching and read-only rpc calls
|
|
3683
3306
|
this.transport.cachedProvider = new network.CachedProvider();
|
|
3684
3307
|
this.transport.cachedProvider.onUpdate(() => {
|
|
3685
3308
|
if (!this.session) this.session = {
|
|
@@ -3687,33 +3310,35 @@ class Wallet {
|
|
|
3687
3310
|
};
|
|
3688
3311
|
this.session.providerCache = this.transport.cachedProvider.getCache();
|
|
3689
3312
|
this.saveSession(this.session);
|
|
3690
|
-
});
|
|
3313
|
+
});
|
|
3691
3314
|
|
|
3315
|
+
// ..
|
|
3692
3316
|
this.transport.router = new network.JsonRpcRouter([network.loggingProviderMiddleware, this.transport.networkProvider, this.transport.allowProvider, network.exceptionProviderMiddleware, this.transport.cachedProvider], this.transport.messageProvider);
|
|
3693
|
-
this.transport.provider = new Web3Provider(this.transport.router);
|
|
3317
|
+
this.transport.provider = new Web3Provider(this.transport.router);
|
|
3318
|
+
|
|
3319
|
+
// NOTE: we don't listen on 'connect' even here as we handle it within connect() method
|
|
3694
3320
|
// in more synchronous flow.
|
|
3321
|
+
|
|
3695
3322
|
// below will update the wallet session object and persist it. In case the session
|
|
3696
3323
|
// is undefined, we consider the session to have been removed by the user, so we clear it.
|
|
3697
|
-
|
|
3698
3324
|
this.transport.messageProvider.on('open', openInfo => {
|
|
3699
3325
|
const {
|
|
3700
3326
|
session
|
|
3701
3327
|
} = openInfo;
|
|
3702
|
-
|
|
3703
3328
|
if (!session) {
|
|
3704
3329
|
if (this.session && this.session.accountAddress) {
|
|
3705
3330
|
// emit disconnect even if previously we had a session, and now we don't.
|
|
3706
3331
|
this.transport.messageProvider.emit('disconnect');
|
|
3707
3332
|
}
|
|
3708
|
-
|
|
3709
3333
|
this.clearSession();
|
|
3710
3334
|
} else {
|
|
3711
3335
|
this.useSession(session, true);
|
|
3712
3336
|
}
|
|
3713
|
-
});
|
|
3337
|
+
});
|
|
3338
|
+
|
|
3339
|
+
// below will update the account upon wallet connect/disconnect - aka, login/logout.
|
|
3714
3340
|
// if an origin is provided, this operation should be performed only on that origin
|
|
3715
3341
|
// and shouldn't affect the session of the wallet.
|
|
3716
|
-
|
|
3717
3342
|
this.transport.messageProvider.on('accountsChanged', (accounts, origin) => {
|
|
3718
3343
|
if (origin) {
|
|
3719
3344
|
if (accounts.length > 0) {
|
|
@@ -3721,10 +3346,8 @@ class Wallet {
|
|
|
3721
3346
|
accountAddress: accounts[0]
|
|
3722
3347
|
}, true);
|
|
3723
3348
|
}
|
|
3724
|
-
|
|
3725
3349
|
return;
|
|
3726
3350
|
}
|
|
3727
|
-
|
|
3728
3351
|
if (!accounts || accounts.length === 0 || accounts[0] === '') {
|
|
3729
3352
|
this.clearSession();
|
|
3730
3353
|
} else {
|
|
@@ -3732,47 +3355,42 @@ class Wallet {
|
|
|
3732
3355
|
accountAddress: accounts[0]
|
|
3733
3356
|
}, true);
|
|
3734
3357
|
}
|
|
3735
|
-
});
|
|
3358
|
+
});
|
|
3736
3359
|
|
|
3360
|
+
// below will update the networks automatically when the wallet networks change
|
|
3737
3361
|
this.transport.messageProvider.on('networks', networks => {
|
|
3738
3362
|
this.useSession({
|
|
3739
3363
|
networks: networks
|
|
3740
3364
|
}, true);
|
|
3741
|
-
});
|
|
3365
|
+
});
|
|
3742
3366
|
|
|
3367
|
+
// below will update the wallet context automatically
|
|
3743
3368
|
this.transport.messageProvider.on('walletContext', walletContext => {
|
|
3744
3369
|
this.useSession({
|
|
3745
3370
|
walletContext: walletContext
|
|
3746
3371
|
}, true);
|
|
3747
3372
|
});
|
|
3748
3373
|
};
|
|
3749
|
-
|
|
3750
3374
|
this.loadSession = async function () {
|
|
3751
3375
|
const data = await LocalStorage.getInstance().getItem('@sequence.session');
|
|
3752
|
-
|
|
3753
3376
|
if (!data || data === '') {
|
|
3754
3377
|
return undefined;
|
|
3755
3378
|
}
|
|
3756
|
-
|
|
3757
3379
|
try {
|
|
3758
3380
|
const session = JSON.parse(data);
|
|
3759
|
-
|
|
3760
3381
|
if (session) {
|
|
3761
3382
|
_this.useSession(session, false);
|
|
3762
3383
|
}
|
|
3763
|
-
|
|
3764
3384
|
return session;
|
|
3765
3385
|
} catch (err) {
|
|
3766
3386
|
utils.logger.warn('loadSession failed, unable to parse session payload from storage.');
|
|
3767
3387
|
return undefined;
|
|
3768
3388
|
}
|
|
3769
3389
|
};
|
|
3770
|
-
|
|
3771
3390
|
this.connect = async function (options) {
|
|
3772
3391
|
if ((options == null ? void 0 : options.refresh) === true) {
|
|
3773
3392
|
_this.disconnect();
|
|
3774
3393
|
}
|
|
3775
|
-
|
|
3776
3394
|
if (_this.isConnected() && (await _this.isSiteConnected(options == null ? void 0 : options.origin)) && !!_this.session && !(options != null && options.authorize) && !(options != null && options.askForEmail)) {
|
|
3777
3395
|
return {
|
|
3778
3396
|
connected: true,
|
|
@@ -3780,13 +3398,11 @@ class Wallet {
|
|
|
3780
3398
|
chainId: ethers.ethers.utils.hexlify(await _this.getChainId())
|
|
3781
3399
|
};
|
|
3782
3400
|
}
|
|
3783
|
-
|
|
3784
3401
|
if (options) {
|
|
3785
3402
|
if (options.authorize && (!options.app || options.app === '')) {
|
|
3786
3403
|
throw new Error(`connecting with 'authorize' option also requires 'app' to be set`);
|
|
3787
3404
|
}
|
|
3788
3405
|
}
|
|
3789
|
-
|
|
3790
3406
|
await _this.openWallet(undefined, {
|
|
3791
3407
|
type: 'connect',
|
|
3792
3408
|
options
|
|
@@ -3796,163 +3412,131 @@ class Wallet {
|
|
|
3796
3412
|
connected: false
|
|
3797
3413
|
};
|
|
3798
3414
|
});
|
|
3799
|
-
|
|
3800
3415
|
if (connectDetails.connected) {
|
|
3801
3416
|
if (!!connectDetails.session) {
|
|
3802
3417
|
_this.useSession(connectDetails.session, true);
|
|
3803
|
-
|
|
3804
3418
|
_this.addConnectedSite(options == null ? void 0 : options.origin);
|
|
3805
3419
|
} else {
|
|
3806
3420
|
throw new Error('impossible state, connect response is missing session');
|
|
3807
3421
|
}
|
|
3808
3422
|
}
|
|
3809
|
-
|
|
3810
3423
|
return connectDetails;
|
|
3811
3424
|
};
|
|
3812
|
-
|
|
3813
3425
|
this.authorize = async function (options) {
|
|
3814
3426
|
return _this.connect(_extends({}, options, {
|
|
3815
3427
|
authorize: true
|
|
3816
3428
|
}));
|
|
3817
3429
|
};
|
|
3818
|
-
|
|
3819
3430
|
this.getSession = () => {
|
|
3820
3431
|
if (!this.isConnected()) {
|
|
3821
3432
|
return undefined;
|
|
3822
3433
|
}
|
|
3823
|
-
|
|
3824
3434
|
return this.session;
|
|
3825
3435
|
};
|
|
3826
|
-
|
|
3827
3436
|
this.getAddress = async function () {
|
|
3828
3437
|
if (!_this.isConnected()) {
|
|
3829
3438
|
throw new Error('connect first');
|
|
3830
3439
|
}
|
|
3831
|
-
|
|
3832
3440
|
const session = _this.getSession();
|
|
3833
|
-
|
|
3834
3441
|
return session.accountAddress;
|
|
3835
3442
|
};
|
|
3836
|
-
|
|
3837
3443
|
this.getNetworks = async function (chainId) {
|
|
3838
3444
|
if (!_this.isConnected() || !_this.networks) {
|
|
3839
3445
|
throw new Error('connect first');
|
|
3840
3446
|
}
|
|
3841
|
-
|
|
3842
3447
|
if (chainId) {
|
|
3843
3448
|
// filter list to just the specific chain requested
|
|
3844
3449
|
const network$1 = network.findNetworkConfig(_this.networks, chainId);
|
|
3845
3450
|
return network$1 ? [network$1] : [];
|
|
3846
3451
|
}
|
|
3847
|
-
|
|
3848
3452
|
return _this.networks;
|
|
3849
3453
|
};
|
|
3850
|
-
|
|
3851
3454
|
this.getChainId = async function () {
|
|
3852
3455
|
if (!_this.networks || _this.networks.length < 1) {
|
|
3853
3456
|
throw new Error('networks have not been set by session. connect first.');
|
|
3854
3457
|
}
|
|
3855
|
-
|
|
3856
3458
|
const network = _this.networks.find(network => network.isDefaultChain);
|
|
3857
|
-
|
|
3858
3459
|
if (!network) {
|
|
3859
3460
|
throw new Error('networks must have a default chain specified');
|
|
3860
3461
|
}
|
|
3861
|
-
|
|
3862
3462
|
return network.chainId;
|
|
3863
3463
|
};
|
|
3864
|
-
|
|
3865
3464
|
this.getAuthChainId = async function () {
|
|
3866
3465
|
if (!_this.networks || _this.networks.length < 1) {
|
|
3867
3466
|
throw new Error('networks have not been set by session. connect first.');
|
|
3868
3467
|
}
|
|
3869
|
-
|
|
3870
3468
|
const network = _this.networks.find(network => network.isAuthChain);
|
|
3871
|
-
|
|
3872
3469
|
if (!network) {
|
|
3873
3470
|
throw new Error('networks must have an auth chain specified');
|
|
3874
3471
|
}
|
|
3875
|
-
|
|
3876
3472
|
return network.chainId;
|
|
3877
3473
|
};
|
|
3878
|
-
|
|
3879
3474
|
this.openWallet = async function (path, intent, networkId) {
|
|
3880
3475
|
if ((intent == null ? void 0 : intent.type) !== 'connect' && !_this.isConnected()) {
|
|
3881
3476
|
throw new Error('connect first');
|
|
3882
3477
|
}
|
|
3883
|
-
|
|
3884
3478
|
let currentNetworkId;
|
|
3885
|
-
|
|
3886
3479
|
if (!_this.networks || _this.networks.length < 1) {
|
|
3887
3480
|
currentNetworkId = _this.config.defaultNetworkId;
|
|
3888
3481
|
} else {
|
|
3889
3482
|
currentNetworkId = await _this.getChainId();
|
|
3890
3483
|
}
|
|
3891
|
-
|
|
3892
3484
|
_this.transport.messageProvider.openWallet(path, intent, networkId || currentNetworkId);
|
|
3893
|
-
|
|
3894
3485
|
await _this.transport.messageProvider.waitUntilOpened();
|
|
3895
3486
|
return true;
|
|
3896
3487
|
};
|
|
3897
|
-
|
|
3898
3488
|
this.closeWallet = () => {
|
|
3899
3489
|
this.transport.messageProvider.closeWallet();
|
|
3900
3490
|
};
|
|
3901
|
-
|
|
3902
3491
|
this.saveSession = async function (session) {
|
|
3903
3492
|
utils.logger.debug('wallet provider: saving session');
|
|
3904
3493
|
const data = JSON.stringify(session);
|
|
3905
3494
|
await LocalStorage.getInstance().setItem('@sequence.session', data);
|
|
3906
3495
|
};
|
|
3907
|
-
|
|
3908
3496
|
this.useSession = async function (session, autoSave = true) {
|
|
3909
|
-
if (!_this.session) _this.session = {};
|
|
3497
|
+
if (!_this.session) _this.session = {};
|
|
3910
3498
|
|
|
3499
|
+
// setup wallet context
|
|
3911
3500
|
if (_this.config.walletContext) {
|
|
3912
3501
|
_this.session.walletContext = _this.config.walletContext;
|
|
3913
3502
|
} else if (session.walletContext) {
|
|
3914
3503
|
_this.session.walletContext = session.walletContext;
|
|
3915
|
-
}
|
|
3916
|
-
|
|
3504
|
+
}
|
|
3917
3505
|
|
|
3506
|
+
// setup account
|
|
3918
3507
|
if (session.accountAddress) {
|
|
3919
3508
|
_this.useAccountAddress(session.accountAddress);
|
|
3920
|
-
}
|
|
3921
|
-
|
|
3509
|
+
}
|
|
3922
3510
|
|
|
3511
|
+
// setup networks
|
|
3923
3512
|
if (session.networks) {
|
|
3924
3513
|
_this.useNetworks(session.networks);
|
|
3925
|
-
}
|
|
3926
|
-
|
|
3514
|
+
}
|
|
3927
3515
|
|
|
3516
|
+
// setup provider cache
|
|
3928
3517
|
if (session.providerCache) {
|
|
3929
3518
|
_this.transport.cachedProvider.setCache(session.providerCache);
|
|
3930
|
-
}
|
|
3931
|
-
|
|
3519
|
+
}
|
|
3932
3520
|
|
|
3521
|
+
// persist
|
|
3933
3522
|
if (autoSave) {
|
|
3934
3523
|
_this.saveSession(_this.session);
|
|
3935
3524
|
}
|
|
3936
3525
|
};
|
|
3937
|
-
|
|
3938
3526
|
// config is a Partial, so that we may intersect it with the DefaultProviderConfig,
|
|
3939
3527
|
// which allows easy overriding and control of the config.
|
|
3940
3528
|
this.config = _extends({}, DefaultProviderConfig);
|
|
3941
|
-
|
|
3942
3529
|
if (config) {
|
|
3943
3530
|
this.config = _extends({}, this.config, config);
|
|
3944
3531
|
}
|
|
3945
|
-
|
|
3946
3532
|
if (_network) {
|
|
3947
3533
|
this.config.defaultNetworkId = _network;
|
|
3948
3534
|
} else if (!this.config.defaultNetworkId) {
|
|
3949
3535
|
this.config.defaultNetworkId = 'mainnet';
|
|
3950
3536
|
}
|
|
3951
|
-
|
|
3952
3537
|
if (config != null && config.localStorage) {
|
|
3953
3538
|
LocalStorage.use(config.localStorage);
|
|
3954
3539
|
}
|
|
3955
|
-
|
|
3956
3540
|
this.transport = {};
|
|
3957
3541
|
this.networks = [];
|
|
3958
3542
|
this.providers = {};
|
|
@@ -3960,61 +3544,50 @@ class Wallet {
|
|
|
3960
3544
|
this.utils = new WalletUtils(this);
|
|
3961
3545
|
this.init();
|
|
3962
3546
|
}
|
|
3963
|
-
|
|
3964
3547
|
async addConnectedSite(origin) {
|
|
3965
3548
|
origin = origin || window.location.origin;
|
|
3966
3549
|
const connectedSites = await this.connectedSites.get();
|
|
3967
|
-
|
|
3968
3550
|
if (connectedSites) {
|
|
3969
3551
|
if (connectedSites.includes(origin)) {
|
|
3970
3552
|
return;
|
|
3971
3553
|
}
|
|
3972
|
-
|
|
3973
3554
|
this.connectedSites.set([...connectedSites, origin]);
|
|
3974
3555
|
} else {
|
|
3975
3556
|
this.connectedSites.set([origin]);
|
|
3976
3557
|
}
|
|
3977
3558
|
}
|
|
3978
|
-
|
|
3979
3559
|
async removeConnectedSite(origin) {
|
|
3980
3560
|
const authorized = await this.connectedSites.get();
|
|
3981
|
-
|
|
3982
3561
|
if (authorized) {
|
|
3983
3562
|
this.connectedSites.set(authorized.filter(domain => domain !== origin));
|
|
3984
3563
|
}
|
|
3985
3564
|
}
|
|
3986
|
-
|
|
3987
3565
|
getConnectedSites() {
|
|
3988
3566
|
return this.connectedSites.get();
|
|
3989
3567
|
}
|
|
3990
|
-
|
|
3991
3568
|
async isSiteConnected(origin) {
|
|
3992
3569
|
const authorized = await this.connectedSites.get();
|
|
3993
3570
|
return !!authorized && authorized.includes(origin || window.location.origin);
|
|
3994
3571
|
}
|
|
3995
|
-
|
|
3996
3572
|
disconnect() {
|
|
3997
3573
|
if (this.isOpened()) {
|
|
3998
3574
|
this.closeWallet();
|
|
3999
3575
|
}
|
|
4000
|
-
|
|
4001
3576
|
this.clearSession();
|
|
4002
|
-
}
|
|
4003
|
-
// and on successful response, will update the provider info here, etc.
|
|
3577
|
+
}
|
|
4004
3578
|
|
|
3579
|
+
// TODO: add switchNetwork(network: string | number) which will call wallet_switchEthereumChain
|
|
3580
|
+
// and on successful response, will update the provider info here, etc.
|
|
4005
3581
|
|
|
4006
3582
|
getProviderConfig() {
|
|
4007
3583
|
return this.config;
|
|
4008
3584
|
}
|
|
4009
|
-
|
|
4010
3585
|
isOpened() {
|
|
4011
3586
|
return this.transport.messageProvider.isOpened();
|
|
4012
3587
|
}
|
|
4013
|
-
|
|
4014
3588
|
isConnected() {
|
|
4015
3589
|
return this.session !== undefined && this.session.networks !== undefined && this.session.networks.length > 0 && this.networks !== undefined && this.networks.length > 0 && !!this.session.accountAddress && this.session.accountAddress.startsWith('0x');
|
|
4016
3590
|
}
|
|
4017
|
-
|
|
4018
3591
|
getProvider(chainId) {
|
|
4019
3592
|
// return the top-level provider message transport when chainId is unspecified
|
|
4020
3593
|
// and user has not logged in
|
|
@@ -4025,27 +3598,24 @@ class Wallet {
|
|
|
4025
3598
|
return this.transport.provider;
|
|
4026
3599
|
}
|
|
4027
3600
|
}
|
|
4028
|
-
|
|
4029
3601
|
let network$1 = this.networks.find(network => network.isDefaultChain);
|
|
4030
|
-
|
|
4031
3602
|
if (chainId) {
|
|
4032
3603
|
network$1 = network.findNetworkConfig(this.networks, chainId);
|
|
4033
|
-
|
|
4034
3604
|
if (!network$1) {
|
|
4035
3605
|
throw new Error(`network ${chainId} is not in the network list`);
|
|
4036
3606
|
}
|
|
4037
|
-
}
|
|
4038
|
-
|
|
3607
|
+
}
|
|
4039
3608
|
|
|
3609
|
+
// return memoized network provider
|
|
4040
3610
|
if (this.providers[network$1.chainId]) {
|
|
4041
3611
|
return this.providers[network$1.chainId];
|
|
4042
|
-
}
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
let provider; // network.provider may be set by the ProviderConfig override
|
|
3612
|
+
}
|
|
4046
3613
|
|
|
4047
|
-
|
|
3614
|
+
// builder web3 provider stack
|
|
3615
|
+
let provider;
|
|
4048
3616
|
|
|
3617
|
+
// network.provider may be set by the ProviderConfig override
|
|
3618
|
+
const rpcProvider = network$1.provider ? network$1.provider : new ethers.providers.JsonRpcProvider(network$1.rpcUrl, network$1.chainId);
|
|
4049
3619
|
if (network$1.isDefaultChain) {
|
|
4050
3620
|
// communicating with defaultChain will prioritize the wallet message transport
|
|
4051
3621
|
const router = new network.JsonRpcRouter([network.loggingProviderMiddleware, network.exceptionProviderMiddleware, new network.EagerProvider({
|
|
@@ -4063,103 +3633,88 @@ class Wallet {
|
|
|
4063
3633
|
}), new network.SigningProvider(this.transport.provider), new network.CachedProvider(network$1.chainId)], new network.JsonRpcSender(rpcProvider));
|
|
4064
3634
|
provider = new Web3Provider(router, network$1.chainId);
|
|
4065
3635
|
}
|
|
4066
|
-
|
|
4067
3636
|
this.providers[network$1.chainId] = provider;
|
|
4068
3637
|
return provider;
|
|
4069
3638
|
}
|
|
4070
|
-
|
|
4071
3639
|
async getAuthProvider() {
|
|
4072
3640
|
return this.getProvider((await this.getAuthNetwork()).chainId);
|
|
4073
3641
|
}
|
|
4074
|
-
|
|
4075
3642
|
async getAuthNetwork() {
|
|
4076
3643
|
return (await this.getNetworks()).find(n => n.isAuthChain);
|
|
4077
3644
|
}
|
|
4078
|
-
|
|
4079
3645
|
getAllProviders() {
|
|
4080
3646
|
return this.providers;
|
|
4081
3647
|
}
|
|
4082
|
-
|
|
4083
3648
|
getSigner(chainId) {
|
|
4084
3649
|
return this.getProvider(chainId).getSigner();
|
|
4085
3650
|
}
|
|
4086
|
-
|
|
4087
3651
|
async getAuthSigner() {
|
|
4088
3652
|
return (await this.getAuthProvider()).getSigner();
|
|
4089
3653
|
}
|
|
4090
|
-
|
|
4091
3654
|
getWalletConfig(chainId) {
|
|
4092
3655
|
return this.getSigner().getWalletConfig(chainId);
|
|
4093
3656
|
}
|
|
4094
|
-
|
|
4095
3657
|
getWalletState(chainId) {
|
|
4096
3658
|
return this.getSigner().getWalletState(chainId);
|
|
4097
3659
|
}
|
|
4098
|
-
|
|
4099
3660
|
getWalletContext() {
|
|
4100
3661
|
return this.getSigner().getWalletContext();
|
|
4101
3662
|
}
|
|
4102
|
-
|
|
4103
3663
|
isDeployed(chainId) {
|
|
4104
3664
|
return this.getSigner(chainId).isDeployed();
|
|
4105
3665
|
}
|
|
4106
|
-
|
|
4107
3666
|
on(event, fn) {
|
|
4108
3667
|
this.transport.messageProvider.on(event, fn);
|
|
4109
3668
|
}
|
|
4110
|
-
|
|
4111
3669
|
once(event, fn) {
|
|
4112
3670
|
this.transport.messageProvider.once(event, fn);
|
|
4113
3671
|
}
|
|
4114
|
-
|
|
4115
3672
|
useAccountAddress(accountAddress) {
|
|
4116
3673
|
if (!this.session) this.session = {};
|
|
4117
3674
|
this.session.accountAddress = ethers.ethers.utils.getAddress(accountAddress);
|
|
4118
3675
|
}
|
|
4119
|
-
|
|
4120
3676
|
useNetworks(networks) {
|
|
4121
3677
|
// set networks in the session
|
|
4122
|
-
if (!this.session) this.session = {};
|
|
3678
|
+
if (!this.session) this.session = {};
|
|
4123
3679
|
|
|
4124
|
-
|
|
3680
|
+
// set networks on session object
|
|
3681
|
+
this.session.networks = networks;
|
|
4125
3682
|
|
|
3683
|
+
// short-circuit if setting empty network list (aka logged out state)
|
|
4126
3684
|
if (!this.session.networks || this.session.networks.length === 0) {
|
|
4127
3685
|
return;
|
|
4128
|
-
}
|
|
4129
|
-
|
|
3686
|
+
}
|
|
4130
3687
|
|
|
3688
|
+
// check if any custom network settings, otherwise return early
|
|
4131
3689
|
if (!this.config.networks && !this.config.networkRpcUrl) {
|
|
4132
3690
|
this.networks = networks;
|
|
4133
3691
|
return;
|
|
4134
|
-
}
|
|
4135
|
-
|
|
3692
|
+
}
|
|
4136
3693
|
|
|
4137
|
-
|
|
3694
|
+
// init networks
|
|
3695
|
+
this.networks = networks;
|
|
4138
3696
|
|
|
3697
|
+
// combine custom network config with networks in the session
|
|
4139
3698
|
if (this.config.networks) {
|
|
4140
3699
|
this.networks = networks.map(n => _extends({}, n)); // copy
|
|
4141
|
-
|
|
4142
3700
|
this.config.networks.forEach(n => {
|
|
4143
3701
|
const network$1 = network.findNetworkConfig(this.networks, n.chainId || n.name);
|
|
4144
3702
|
if (!network$1) return;
|
|
4145
3703
|
network.updateNetworkConfig(n, network$1);
|
|
4146
3704
|
});
|
|
4147
3705
|
network.ensureValidNetworks(this.networks, true);
|
|
4148
|
-
}
|
|
4149
|
-
|
|
3706
|
+
}
|
|
4150
3707
|
|
|
3708
|
+
// an extra override for convenience
|
|
4151
3709
|
if (this.config.networkRpcUrl) {
|
|
4152
3710
|
const network = this.networks.find(network => network.isDefaultChain);
|
|
4153
|
-
|
|
4154
3711
|
if (network) {
|
|
4155
3712
|
network.rpcUrl = this.config.networkRpcUrl;
|
|
4156
3713
|
}
|
|
4157
3714
|
}
|
|
4158
3715
|
}
|
|
4159
|
-
|
|
4160
3716
|
clearSession() {
|
|
4161
3717
|
var _this$transport$cache;
|
|
4162
|
-
|
|
4163
3718
|
utils.logger.debug('wallet provider: clearing session');
|
|
4164
3719
|
LocalStorage.getInstance().removeItem('@sequence.session');
|
|
4165
3720
|
this.session = undefined;
|
|
@@ -4167,11 +3722,11 @@ class Wallet {
|
|
|
4167
3722
|
this.providers = {};
|
|
4168
3723
|
(_this$transport$cache = this.transport.cachedProvider) == null ? void 0 : _this$transport$cache.clearCache();
|
|
4169
3724
|
}
|
|
4170
|
-
|
|
4171
3725
|
}
|
|
4172
3726
|
const DefaultProviderConfig = {
|
|
4173
3727
|
walletAppURL: 'https://sequence.app',
|
|
4174
3728
|
// walletSessionURL: 'https://session.sequence.app',
|
|
3729
|
+
|
|
4175
3730
|
transports: {
|
|
4176
3731
|
windowTransport: {
|
|
4177
3732
|
enabled: true
|
|
@@ -4186,7 +3741,6 @@ const initWallet = async (network, config) => {
|
|
|
4186
3741
|
if (walletInstance && walletInstance.isOpened()) {
|
|
4187
3742
|
walletInstance.closeWallet();
|
|
4188
3743
|
}
|
|
4189
|
-
|
|
4190
3744
|
walletInstance = new Wallet(network, config);
|
|
4191
3745
|
await walletInstance.loadSession();
|
|
4192
3746
|
return walletInstance;
|
|
@@ -4195,7 +3749,6 @@ const getWallet = () => {
|
|
|
4195
3749
|
if (!walletInstance) {
|
|
4196
3750
|
throw new Error('Wallet has not been initialized, call sequence.initWallet(network, config) first.');
|
|
4197
3751
|
}
|
|
4198
|
-
|
|
4199
3752
|
return walletInstance;
|
|
4200
3753
|
};
|
|
4201
3754
|
|