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