@portal-hq/connect 1.0.4 → 1.1.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/lib/commonjs/components/scanner/index.js +12 -0
- package/lib/commonjs/index.js +81 -15
- package/lib/esm/components/scanner/index.js +7 -0
- package/lib/esm/index.js +80 -15
- package/package.json +2 -2
- package/src/index.ts +114 -27
- package/types.d.ts +14 -7
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const react_native_1 = require("react-native");
|
|
8
|
+
const WalletScanner = () => {
|
|
9
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
10
|
+
react_1.default.createElement(react_native_1.Text, null, "Yo!")));
|
|
11
|
+
};
|
|
12
|
+
exports.default = WalletScanner;
|
package/lib/commonjs/index.js
CHANGED
|
@@ -9,18 +9,54 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ConnectionStates = void 0;
|
|
13
|
+
const provider_1 = require("@portal-hq/provider");
|
|
12
14
|
class PortalConnect {
|
|
13
|
-
constructor({
|
|
14
|
-
|
|
15
|
+
constructor({ apiKey, chainId, keychain, gatewayConfig,
|
|
16
|
+
// Optional
|
|
17
|
+
isSimulator = false, autoApprove = false, version = 'v4', apiHost = 'api.portalhq.io', mpcHost = 'mpc.portalhq.io', webSocketServer = 'connect.portalhq.io', }) {
|
|
18
|
+
this.connectionState = ConnectionStates.DISCONNECTED;
|
|
19
|
+
this.apiKey = apiKey;
|
|
15
20
|
this.events = {};
|
|
16
|
-
this.
|
|
17
|
-
this.
|
|
21
|
+
this.websocketServer = webSocketServer;
|
|
22
|
+
this.provider = new provider_1.Provider({
|
|
23
|
+
apiKey,
|
|
24
|
+
chainId,
|
|
25
|
+
gatewayConfig,
|
|
26
|
+
keychain,
|
|
27
|
+
isSimulator,
|
|
28
|
+
autoApprove,
|
|
29
|
+
version,
|
|
30
|
+
apiHost,
|
|
31
|
+
mpcHost,
|
|
32
|
+
});
|
|
33
|
+
// Inbound from the Provider
|
|
34
|
+
this.on('portalConnect_signingRequested', (data) => {
|
|
35
|
+
this.emit('portal_signingRequested', data);
|
|
36
|
+
});
|
|
37
|
+
// Inbound from SDK consumers
|
|
38
|
+
this.on('portal_signingApproved', (data) => {
|
|
39
|
+
this.provider.emit('portal_signingApproved', data);
|
|
40
|
+
});
|
|
41
|
+
this.on('portal_signingRejected', (data) => {
|
|
42
|
+
this.provider.emit('portal_signingRejected', data);
|
|
43
|
+
});
|
|
18
44
|
// Do the OG binding trick to preserve the `this` context
|
|
19
45
|
this.handleSessionApproved = this.handleSessionApproved.bind(this);
|
|
20
46
|
this.handleSessionRejected = this.handleSessionRejected.bind(this);
|
|
21
47
|
this.handleSessionRequest = this.handleSessionRequest.bind(this);
|
|
22
48
|
this.handleSigningRejected = this.handleSigningRejected.bind(this);
|
|
23
49
|
}
|
|
50
|
+
get address() {
|
|
51
|
+
return this.provider.address;
|
|
52
|
+
}
|
|
53
|
+
get chainId() {
|
|
54
|
+
return this.provider.chainId;
|
|
55
|
+
}
|
|
56
|
+
get connected() {
|
|
57
|
+
return (this.connectionState === ConnectionStates.CONNECTED ||
|
|
58
|
+
this.connectionState === ConnectionStates.CONNECTING);
|
|
59
|
+
}
|
|
24
60
|
/**
|
|
25
61
|
* Establishes a websocket connection with the Connect Proxy and dispatches the binding
|
|
26
62
|
* of websocket events for the newly established socket
|
|
@@ -38,7 +74,7 @@ class PortalConnect {
|
|
|
38
74
|
// @ts-ignore
|
|
39
75
|
{
|
|
40
76
|
headers: {
|
|
41
|
-
Authorization: `Bearer ${this.
|
|
77
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
42
78
|
},
|
|
43
79
|
});
|
|
44
80
|
this.bindToSocketEvents(this.socket, uri);
|
|
@@ -47,6 +83,9 @@ class PortalConnect {
|
|
|
47
83
|
deinit() {
|
|
48
84
|
this.events = {};
|
|
49
85
|
}
|
|
86
|
+
disconnect() {
|
|
87
|
+
this.sendFinalMessageAndClose();
|
|
88
|
+
}
|
|
50
89
|
/**
|
|
51
90
|
* Invokes all registered event handlers with the data provided
|
|
52
91
|
* - If any `once` handlers exist, they are removed after all handlers are invoked
|
|
@@ -135,7 +174,8 @@ class PortalConnect {
|
|
|
135
174
|
* - Fires a subsequent call over the websocket to notify the proxy of the uri to connect to
|
|
136
175
|
*/
|
|
137
176
|
socket.onopen = () => __awaiter(this, void 0, void 0, function* () {
|
|
138
|
-
const
|
|
177
|
+
const address = yield this.address;
|
|
178
|
+
const { chainId } = this.provider;
|
|
139
179
|
// Tell the proxy server where to connect to downstream
|
|
140
180
|
socket.send(JSON.stringify({
|
|
141
181
|
event: 'connect',
|
|
@@ -168,12 +208,13 @@ class PortalConnect {
|
|
|
168
208
|
this.emit('disconnect', message.data);
|
|
169
209
|
break;
|
|
170
210
|
case 'connected':
|
|
171
|
-
this.
|
|
211
|
+
this.connectionState = ConnectionStates.CONNECTED;
|
|
212
|
+
this.topic = message.data.topic;
|
|
172
213
|
this.emit('connect', message.data);
|
|
173
214
|
break;
|
|
174
215
|
case 'disconnect':
|
|
175
216
|
socket.close();
|
|
176
|
-
this.
|
|
217
|
+
this.connectionState = ConnectionStates.DISCONNECTED;
|
|
177
218
|
this.emit('disconnect', message.data);
|
|
178
219
|
break;
|
|
179
220
|
case 'session_request':
|
|
@@ -203,28 +244,28 @@ class PortalConnect {
|
|
|
203
244
|
handleProviderRequest(method, params, request) {
|
|
204
245
|
return __awaiter(this, void 0, void 0, function* () {
|
|
205
246
|
// Bind to potential signing rejection events
|
|
206
|
-
this.
|
|
247
|
+
this.provider.on('portal_signingRejected', this.handleSigningRejected);
|
|
207
248
|
// Bind to potential signature received events
|
|
208
|
-
this.
|
|
249
|
+
this.provider.on('portal_signatureReceived', ({ method: signedMethod, params: signedParams, signature }) => {
|
|
209
250
|
if (signedMethod === method &&
|
|
210
251
|
JSON.stringify(signedParams) === JSON.stringify(params)) {
|
|
211
252
|
this.handleSignatureReceived(request, signature);
|
|
212
253
|
}
|
|
213
254
|
});
|
|
214
255
|
// Pass the request along to the provider
|
|
215
|
-
yield this.
|
|
256
|
+
yield this.provider.request({ method, params, connect: this });
|
|
216
257
|
});
|
|
217
258
|
}
|
|
218
259
|
handleSessionApproved(data, request) {
|
|
219
260
|
var _a;
|
|
220
261
|
return __awaiter(this, void 0, void 0, function* () {
|
|
221
|
-
const address = yield this.
|
|
262
|
+
const address = yield this.address;
|
|
222
263
|
// Notify the proxy server that the session request was approved
|
|
223
264
|
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.send(JSON.stringify({
|
|
224
265
|
event: 'portal_dappSessionApproved',
|
|
225
266
|
data: {
|
|
226
267
|
address,
|
|
227
|
-
chainId: this.
|
|
268
|
+
chainId: this.chainId,
|
|
228
269
|
topic: request.topic,
|
|
229
270
|
id: request.id,
|
|
230
271
|
params: data,
|
|
@@ -235,13 +276,13 @@ class PortalConnect {
|
|
|
235
276
|
handleSessionRejected(data, request) {
|
|
236
277
|
var _a;
|
|
237
278
|
return __awaiter(this, void 0, void 0, function* () {
|
|
238
|
-
const address = yield this.
|
|
279
|
+
const address = yield this.address;
|
|
239
280
|
// Notify the proxy server that the session request was rejected
|
|
240
281
|
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.send(JSON.stringify({
|
|
241
282
|
event: 'portal_dappSessionRejected',
|
|
242
283
|
data: {
|
|
243
284
|
address,
|
|
244
|
-
chainId: this.
|
|
285
|
+
chainId: this.chainId,
|
|
245
286
|
topic: request.topic,
|
|
246
287
|
id: request.id,
|
|
247
288
|
params: data,
|
|
@@ -272,6 +313,8 @@ class PortalConnect {
|
|
|
272
313
|
transactionId: id,
|
|
273
314
|
},
|
|
274
315
|
}));
|
|
316
|
+
// Let the SDK consumer know the transaction hash
|
|
317
|
+
this.emit('portal_signgatureReceived', txHash);
|
|
275
318
|
});
|
|
276
319
|
}
|
|
277
320
|
handleSigningRejected(data) {
|
|
@@ -288,5 +331,28 @@ class PortalConnect {
|
|
|
288
331
|
}));
|
|
289
332
|
});
|
|
290
333
|
}
|
|
334
|
+
sendFinalMessageAndClose() {
|
|
335
|
+
var _a;
|
|
336
|
+
if (this.socket) {
|
|
337
|
+
this.connectionState = ConnectionStates.DISCONNECTING;
|
|
338
|
+
this.socket.send(JSON.stringify({
|
|
339
|
+
event: 'disconnect',
|
|
340
|
+
data: {
|
|
341
|
+
id: '',
|
|
342
|
+
topic: this.topic,
|
|
343
|
+
},
|
|
344
|
+
}));
|
|
345
|
+
this.topic = undefined;
|
|
346
|
+
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.close();
|
|
347
|
+
this.connectionState = ConnectionStates.DISCONNECTED;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
291
350
|
}
|
|
351
|
+
var ConnectionStates;
|
|
352
|
+
(function (ConnectionStates) {
|
|
353
|
+
ConnectionStates["CONNECTED"] = "CONNECTED";
|
|
354
|
+
ConnectionStates["CONNECTING"] = "CONNECTING";
|
|
355
|
+
ConnectionStates["DISCONNECTED"] = "DISCONNECTED";
|
|
356
|
+
ConnectionStates["DISCONNECTING"] = "DISCONNECTING";
|
|
357
|
+
})(ConnectionStates = exports.ConnectionStates || (exports.ConnectionStates = {}));
|
|
292
358
|
exports.default = PortalConnect;
|
package/lib/esm/index.js
CHANGED
|
@@ -7,18 +7,53 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
+
import { Provider } from '@portal-hq/provider';
|
|
10
11
|
class PortalConnect {
|
|
11
|
-
constructor({
|
|
12
|
-
|
|
12
|
+
constructor({ apiKey, chainId, keychain, gatewayConfig,
|
|
13
|
+
// Optional
|
|
14
|
+
isSimulator = false, autoApprove = false, version = 'v4', apiHost = 'api.portalhq.io', mpcHost = 'mpc.portalhq.io', webSocketServer = 'connect.portalhq.io', }) {
|
|
15
|
+
this.connectionState = ConnectionStates.DISCONNECTED;
|
|
16
|
+
this.apiKey = apiKey;
|
|
13
17
|
this.events = {};
|
|
14
|
-
this.
|
|
15
|
-
this.
|
|
18
|
+
this.websocketServer = webSocketServer;
|
|
19
|
+
this.provider = new Provider({
|
|
20
|
+
apiKey,
|
|
21
|
+
chainId,
|
|
22
|
+
gatewayConfig,
|
|
23
|
+
keychain,
|
|
24
|
+
isSimulator,
|
|
25
|
+
autoApprove,
|
|
26
|
+
version,
|
|
27
|
+
apiHost,
|
|
28
|
+
mpcHost,
|
|
29
|
+
});
|
|
30
|
+
// Inbound from the Provider
|
|
31
|
+
this.on('portalConnect_signingRequested', (data) => {
|
|
32
|
+
this.emit('portal_signingRequested', data);
|
|
33
|
+
});
|
|
34
|
+
// Inbound from SDK consumers
|
|
35
|
+
this.on('portal_signingApproved', (data) => {
|
|
36
|
+
this.provider.emit('portal_signingApproved', data);
|
|
37
|
+
});
|
|
38
|
+
this.on('portal_signingRejected', (data) => {
|
|
39
|
+
this.provider.emit('portal_signingRejected', data);
|
|
40
|
+
});
|
|
16
41
|
// Do the OG binding trick to preserve the `this` context
|
|
17
42
|
this.handleSessionApproved = this.handleSessionApproved.bind(this);
|
|
18
43
|
this.handleSessionRejected = this.handleSessionRejected.bind(this);
|
|
19
44
|
this.handleSessionRequest = this.handleSessionRequest.bind(this);
|
|
20
45
|
this.handleSigningRejected = this.handleSigningRejected.bind(this);
|
|
21
46
|
}
|
|
47
|
+
get address() {
|
|
48
|
+
return this.provider.address;
|
|
49
|
+
}
|
|
50
|
+
get chainId() {
|
|
51
|
+
return this.provider.chainId;
|
|
52
|
+
}
|
|
53
|
+
get connected() {
|
|
54
|
+
return (this.connectionState === ConnectionStates.CONNECTED ||
|
|
55
|
+
this.connectionState === ConnectionStates.CONNECTING);
|
|
56
|
+
}
|
|
22
57
|
/**
|
|
23
58
|
* Establishes a websocket connection with the Connect Proxy and dispatches the binding
|
|
24
59
|
* of websocket events for the newly established socket
|
|
@@ -36,7 +71,7 @@ class PortalConnect {
|
|
|
36
71
|
// @ts-ignore
|
|
37
72
|
{
|
|
38
73
|
headers: {
|
|
39
|
-
Authorization: `Bearer ${this.
|
|
74
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
40
75
|
},
|
|
41
76
|
});
|
|
42
77
|
this.bindToSocketEvents(this.socket, uri);
|
|
@@ -45,6 +80,9 @@ class PortalConnect {
|
|
|
45
80
|
deinit() {
|
|
46
81
|
this.events = {};
|
|
47
82
|
}
|
|
83
|
+
disconnect() {
|
|
84
|
+
this.sendFinalMessageAndClose();
|
|
85
|
+
}
|
|
48
86
|
/**
|
|
49
87
|
* Invokes all registered event handlers with the data provided
|
|
50
88
|
* - If any `once` handlers exist, they are removed after all handlers are invoked
|
|
@@ -133,7 +171,8 @@ class PortalConnect {
|
|
|
133
171
|
* - Fires a subsequent call over the websocket to notify the proxy of the uri to connect to
|
|
134
172
|
*/
|
|
135
173
|
socket.onopen = () => __awaiter(this, void 0, void 0, function* () {
|
|
136
|
-
const
|
|
174
|
+
const address = yield this.address;
|
|
175
|
+
const { chainId } = this.provider;
|
|
137
176
|
// Tell the proxy server where to connect to downstream
|
|
138
177
|
socket.send(JSON.stringify({
|
|
139
178
|
event: 'connect',
|
|
@@ -166,12 +205,13 @@ class PortalConnect {
|
|
|
166
205
|
this.emit('disconnect', message.data);
|
|
167
206
|
break;
|
|
168
207
|
case 'connected':
|
|
169
|
-
this.
|
|
208
|
+
this.connectionState = ConnectionStates.CONNECTED;
|
|
209
|
+
this.topic = message.data.topic;
|
|
170
210
|
this.emit('connect', message.data);
|
|
171
211
|
break;
|
|
172
212
|
case 'disconnect':
|
|
173
213
|
socket.close();
|
|
174
|
-
this.
|
|
214
|
+
this.connectionState = ConnectionStates.DISCONNECTED;
|
|
175
215
|
this.emit('disconnect', message.data);
|
|
176
216
|
break;
|
|
177
217
|
case 'session_request':
|
|
@@ -201,28 +241,28 @@ class PortalConnect {
|
|
|
201
241
|
handleProviderRequest(method, params, request) {
|
|
202
242
|
return __awaiter(this, void 0, void 0, function* () {
|
|
203
243
|
// Bind to potential signing rejection events
|
|
204
|
-
this.
|
|
244
|
+
this.provider.on('portal_signingRejected', this.handleSigningRejected);
|
|
205
245
|
// Bind to potential signature received events
|
|
206
|
-
this.
|
|
246
|
+
this.provider.on('portal_signatureReceived', ({ method: signedMethod, params: signedParams, signature }) => {
|
|
207
247
|
if (signedMethod === method &&
|
|
208
248
|
JSON.stringify(signedParams) === JSON.stringify(params)) {
|
|
209
249
|
this.handleSignatureReceived(request, signature);
|
|
210
250
|
}
|
|
211
251
|
});
|
|
212
252
|
// Pass the request along to the provider
|
|
213
|
-
yield this.
|
|
253
|
+
yield this.provider.request({ method, params, connect: this });
|
|
214
254
|
});
|
|
215
255
|
}
|
|
216
256
|
handleSessionApproved(data, request) {
|
|
217
257
|
var _a;
|
|
218
258
|
return __awaiter(this, void 0, void 0, function* () {
|
|
219
|
-
const address = yield this.
|
|
259
|
+
const address = yield this.address;
|
|
220
260
|
// Notify the proxy server that the session request was approved
|
|
221
261
|
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.send(JSON.stringify({
|
|
222
262
|
event: 'portal_dappSessionApproved',
|
|
223
263
|
data: {
|
|
224
264
|
address,
|
|
225
|
-
chainId: this.
|
|
265
|
+
chainId: this.chainId,
|
|
226
266
|
topic: request.topic,
|
|
227
267
|
id: request.id,
|
|
228
268
|
params: data,
|
|
@@ -233,13 +273,13 @@ class PortalConnect {
|
|
|
233
273
|
handleSessionRejected(data, request) {
|
|
234
274
|
var _a;
|
|
235
275
|
return __awaiter(this, void 0, void 0, function* () {
|
|
236
|
-
const address = yield this.
|
|
276
|
+
const address = yield this.address;
|
|
237
277
|
// Notify the proxy server that the session request was rejected
|
|
238
278
|
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.send(JSON.stringify({
|
|
239
279
|
event: 'portal_dappSessionRejected',
|
|
240
280
|
data: {
|
|
241
281
|
address,
|
|
242
|
-
chainId: this.
|
|
282
|
+
chainId: this.chainId,
|
|
243
283
|
topic: request.topic,
|
|
244
284
|
id: request.id,
|
|
245
285
|
params: data,
|
|
@@ -270,6 +310,8 @@ class PortalConnect {
|
|
|
270
310
|
transactionId: id,
|
|
271
311
|
},
|
|
272
312
|
}));
|
|
313
|
+
// Let the SDK consumer know the transaction hash
|
|
314
|
+
this.emit('portal_signgatureReceived', txHash);
|
|
273
315
|
});
|
|
274
316
|
}
|
|
275
317
|
handleSigningRejected(data) {
|
|
@@ -286,5 +328,28 @@ class PortalConnect {
|
|
|
286
328
|
}));
|
|
287
329
|
});
|
|
288
330
|
}
|
|
331
|
+
sendFinalMessageAndClose() {
|
|
332
|
+
var _a;
|
|
333
|
+
if (this.socket) {
|
|
334
|
+
this.connectionState = ConnectionStates.DISCONNECTING;
|
|
335
|
+
this.socket.send(JSON.stringify({
|
|
336
|
+
event: 'disconnect',
|
|
337
|
+
data: {
|
|
338
|
+
id: '',
|
|
339
|
+
topic: this.topic,
|
|
340
|
+
},
|
|
341
|
+
}));
|
|
342
|
+
this.topic = undefined;
|
|
343
|
+
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.close();
|
|
344
|
+
this.connectionState = ConnectionStates.DISCONNECTED;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
289
347
|
}
|
|
348
|
+
export var ConnectionStates;
|
|
349
|
+
(function (ConnectionStates) {
|
|
350
|
+
ConnectionStates["CONNECTED"] = "CONNECTED";
|
|
351
|
+
ConnectionStates["CONNECTING"] = "CONNECTING";
|
|
352
|
+
ConnectionStates["DISCONNECTED"] = "DISCONNECTED";
|
|
353
|
+
ConnectionStates["DISCONNECTING"] = "DISCONNECTING";
|
|
354
|
+
})(ConnectionStates || (ConnectionStates = {}));
|
|
290
355
|
export default PortalConnect;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@portal-hq/connect",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"main": "lib/commonjs/index",
|
|
5
5
|
"module": "lib/esm/index",
|
|
6
6
|
"source": "src/index",
|
|
@@ -32,5 +32,5 @@
|
|
|
32
32
|
"react": "*",
|
|
33
33
|
"react-native": "*"
|
|
34
34
|
},
|
|
35
|
-
"gitHead": "
|
|
35
|
+
"gitHead": "b65beeaf1dd0423244a099aaa0f3d55734ae676a"
|
|
36
36
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Provider } from '@portal-hq/provider'
|
|
2
2
|
import type {
|
|
3
3
|
EventHandler,
|
|
4
4
|
PortalConnectOptions,
|
|
@@ -10,21 +10,73 @@ import type {
|
|
|
10
10
|
} from '../types.d'
|
|
11
11
|
|
|
12
12
|
class PortalConnect {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
private apiKey: string
|
|
14
|
+
private connectionState: ConnectionStates = ConnectionStates.DISCONNECTED
|
|
15
|
+
private provider: Provider
|
|
16
|
+
private socket?: WebSocket
|
|
17
|
+
private topic?: string
|
|
18
|
+
private websocketServer: string
|
|
17
19
|
|
|
18
20
|
private events: Record<string, RegisteredEventHandler[]>
|
|
19
21
|
|
|
22
|
+
private get address(): Promise<string | undefined> {
|
|
23
|
+
return this.provider.address
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private get chainId(): number {
|
|
27
|
+
return this.provider.chainId
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public get connected(): boolean {
|
|
31
|
+
return (
|
|
32
|
+
this.connectionState === ConnectionStates.CONNECTED ||
|
|
33
|
+
this.connectionState === ConnectionStates.CONNECTING
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
20
37
|
constructor({
|
|
21
|
-
|
|
22
|
-
|
|
38
|
+
apiKey,
|
|
39
|
+
chainId,
|
|
40
|
+
keychain,
|
|
41
|
+
gatewayConfig,
|
|
42
|
+
|
|
43
|
+
// Optional
|
|
44
|
+
isSimulator = false,
|
|
45
|
+
autoApprove = false,
|
|
46
|
+
version = 'v4',
|
|
47
|
+
apiHost = 'api.portalhq.io',
|
|
48
|
+
mpcHost = 'mpc.portalhq.io',
|
|
49
|
+
webSocketServer = 'connect.portalhq.io',
|
|
23
50
|
}: PortalConnectOptions) {
|
|
24
|
-
this.
|
|
51
|
+
this.apiKey = apiKey
|
|
25
52
|
this.events = {}
|
|
26
|
-
this.
|
|
27
|
-
|
|
53
|
+
this.websocketServer = webSocketServer
|
|
54
|
+
|
|
55
|
+
this.provider = new Provider({
|
|
56
|
+
apiKey,
|
|
57
|
+
chainId,
|
|
58
|
+
gatewayConfig,
|
|
59
|
+
keychain,
|
|
60
|
+
isSimulator,
|
|
61
|
+
autoApprove,
|
|
62
|
+
version,
|
|
63
|
+
apiHost,
|
|
64
|
+
mpcHost,
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
// Inbound from the Provider
|
|
68
|
+
this.on('portalConnect_signingRequested', (data) => {
|
|
69
|
+
this.emit('portal_signingRequested', data)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
// Inbound from SDK consumers
|
|
73
|
+
this.on('portal_signingApproved', (data) => {
|
|
74
|
+
this.provider.emit('portal_signingApproved', data)
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
this.on('portal_signingRejected', (data) => {
|
|
78
|
+
this.provider.emit('portal_signingRejected', data)
|
|
79
|
+
})
|
|
28
80
|
|
|
29
81
|
// Do the OG binding trick to preserve the `this` context
|
|
30
82
|
this.handleSessionApproved = this.handleSessionApproved.bind(this)
|
|
@@ -52,16 +104,20 @@ class PortalConnect {
|
|
|
52
104
|
// @ts-ignore
|
|
53
105
|
{
|
|
54
106
|
headers: {
|
|
55
|
-
Authorization: `Bearer ${this.
|
|
107
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
56
108
|
},
|
|
57
109
|
},
|
|
58
110
|
)
|
|
59
111
|
this.bindToSocketEvents(this.socket, uri)
|
|
60
112
|
}
|
|
61
113
|
|
|
62
|
-
public deinit() {
|
|
63
|
-
|
|
64
|
-
}
|
|
114
|
+
public deinit() {
|
|
115
|
+
this.events = {}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
public disconnect() {
|
|
119
|
+
this.sendFinalMessageAndClose()
|
|
120
|
+
}
|
|
65
121
|
|
|
66
122
|
/**
|
|
67
123
|
* Invokes all registered event handlers with the data provided
|
|
@@ -168,7 +224,8 @@ public deinit() {
|
|
|
168
224
|
* - Fires a subsequent call over the websocket to notify the proxy of the uri to connect to
|
|
169
225
|
*/
|
|
170
226
|
socket.onopen = async () => {
|
|
171
|
-
const
|
|
227
|
+
const address = await this.address
|
|
228
|
+
const { chainId } = this.provider
|
|
172
229
|
|
|
173
230
|
// Tell the proxy server where to connect to downstream
|
|
174
231
|
socket.send(
|
|
@@ -209,12 +266,13 @@ public deinit() {
|
|
|
209
266
|
this.emit('disconnect', message.data)
|
|
210
267
|
break
|
|
211
268
|
case 'connected':
|
|
212
|
-
this.
|
|
269
|
+
this.connectionState = ConnectionStates.CONNECTED
|
|
270
|
+
this.topic = message.data.topic
|
|
213
271
|
this.emit('connect', message.data)
|
|
214
272
|
break
|
|
215
273
|
case 'disconnect':
|
|
216
274
|
socket.close()
|
|
217
|
-
this.
|
|
275
|
+
this.connectionState = ConnectionStates.DISCONNECTED
|
|
218
276
|
this.emit('disconnect', message.data)
|
|
219
277
|
|
|
220
278
|
break
|
|
@@ -255,13 +313,10 @@ public deinit() {
|
|
|
255
313
|
request: SessionRequest,
|
|
256
314
|
): Promise<void> {
|
|
257
315
|
// Bind to potential signing rejection events
|
|
258
|
-
this.
|
|
259
|
-
'portal_signingRejected',
|
|
260
|
-
this.handleSigningRejected,
|
|
261
|
-
)
|
|
316
|
+
this.provider.on('portal_signingRejected', this.handleSigningRejected)
|
|
262
317
|
|
|
263
318
|
// Bind to potential signature received events
|
|
264
|
-
this.
|
|
319
|
+
this.provider.on(
|
|
265
320
|
'portal_signatureReceived',
|
|
266
321
|
({ method: signedMethod, params: signedParams, signature }) => {
|
|
267
322
|
if (
|
|
@@ -274,14 +329,14 @@ public deinit() {
|
|
|
274
329
|
)
|
|
275
330
|
|
|
276
331
|
// Pass the request along to the provider
|
|
277
|
-
await this.
|
|
332
|
+
await this.provider.request({ method, params, connect: this })
|
|
278
333
|
}
|
|
279
334
|
|
|
280
335
|
private async handleSessionApproved(
|
|
281
336
|
data: SessionProposalOrMetadata,
|
|
282
337
|
request: SessionRequest,
|
|
283
338
|
): Promise<void> {
|
|
284
|
-
const address = await this.
|
|
339
|
+
const address = await this.address
|
|
285
340
|
|
|
286
341
|
// Notify the proxy server that the session request was approved
|
|
287
342
|
this.socket?.send(
|
|
@@ -289,7 +344,7 @@ public deinit() {
|
|
|
289
344
|
event: 'portal_dappSessionApproved',
|
|
290
345
|
data: {
|
|
291
346
|
address,
|
|
292
|
-
chainId: this.
|
|
347
|
+
chainId: this.chainId,
|
|
293
348
|
topic: request.topic,
|
|
294
349
|
id: request.id,
|
|
295
350
|
params: data,
|
|
@@ -302,7 +357,7 @@ public deinit() {
|
|
|
302
357
|
data: SessionProposalOrMetadata,
|
|
303
358
|
request: SessionRequest,
|
|
304
359
|
): Promise<void> {
|
|
305
|
-
const address = await this.
|
|
360
|
+
const address = await this.address
|
|
306
361
|
|
|
307
362
|
// Notify the proxy server that the session request was rejected
|
|
308
363
|
this.socket?.send(
|
|
@@ -310,7 +365,7 @@ public deinit() {
|
|
|
310
365
|
event: 'portal_dappSessionRejected',
|
|
311
366
|
data: {
|
|
312
367
|
address,
|
|
313
|
-
chainId: this.
|
|
368
|
+
chainId: this.chainId,
|
|
314
369
|
topic: request.topic,
|
|
315
370
|
id: request.id,
|
|
316
371
|
params: data,
|
|
@@ -341,6 +396,7 @@ public deinit() {
|
|
|
341
396
|
txHash: any,
|
|
342
397
|
): Promise<void> {
|
|
343
398
|
const { id, topic } = data
|
|
399
|
+
|
|
344
400
|
// Let the server know the transaction hash
|
|
345
401
|
this.socket?.send(
|
|
346
402
|
JSON.stringify({
|
|
@@ -352,6 +408,9 @@ public deinit() {
|
|
|
352
408
|
},
|
|
353
409
|
}),
|
|
354
410
|
)
|
|
411
|
+
|
|
412
|
+
// Let the SDK consumer know the transaction hash
|
|
413
|
+
this.emit('portal_signgatureReceived', txHash)
|
|
355
414
|
}
|
|
356
415
|
|
|
357
416
|
private async handleSigningRejected(data: SessionRequest): Promise<void> {
|
|
@@ -367,6 +426,34 @@ public deinit() {
|
|
|
367
426
|
} as WebsocketMessage),
|
|
368
427
|
)
|
|
369
428
|
}
|
|
429
|
+
|
|
430
|
+
private sendFinalMessageAndClose() {
|
|
431
|
+
if (this.socket) {
|
|
432
|
+
this.connectionState = ConnectionStates.DISCONNECTING
|
|
433
|
+
this.socket.send(
|
|
434
|
+
JSON.stringify({
|
|
435
|
+
event: 'disconnect',
|
|
436
|
+
data: {
|
|
437
|
+
id: '',
|
|
438
|
+
topic: this.topic,
|
|
439
|
+
},
|
|
440
|
+
} as WebsocketMessage),
|
|
441
|
+
)
|
|
442
|
+
|
|
443
|
+
this.topic = undefined
|
|
444
|
+
|
|
445
|
+
this.socket?.close()
|
|
446
|
+
|
|
447
|
+
this.connectionState = ConnectionStates.DISCONNECTED
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
export enum ConnectionStates {
|
|
453
|
+
CONNECTED = 'CONNECTED',
|
|
454
|
+
CONNECTING = 'CONNECTING',
|
|
455
|
+
DISCONNECTED = 'DISCONNECTED',
|
|
456
|
+
DISCONNECTING = 'DISCONNECTING',
|
|
370
457
|
}
|
|
371
458
|
|
|
372
459
|
export type {
|
package/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Portal from '@portal-hq/core'
|
|
2
|
+
import { KeychainAdapter } from '@portal-hq/utils'
|
|
2
3
|
|
|
3
4
|
export type EventHandler = (data: any) => void
|
|
4
5
|
export type SessionProposalOrMetadata = SessionProposal | PeerMetadata
|
|
@@ -41,8 +42,18 @@ export interface PeerMetadata {
|
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
export interface PortalConnectOptions {
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
apiKey: string
|
|
46
|
+
chainId: number
|
|
47
|
+
keychain: KeychainAdapter
|
|
48
|
+
gatewayConfig: GatewayLike
|
|
49
|
+
|
|
50
|
+
// Optional
|
|
51
|
+
isSimulator?: boolean
|
|
52
|
+
autoApprove?: boolean
|
|
53
|
+
webSocketServer?: string
|
|
54
|
+
apiHost?: string
|
|
55
|
+
mpcHost?: string
|
|
56
|
+
version?: string
|
|
46
57
|
}
|
|
47
58
|
|
|
48
59
|
export interface ProtocolOptions {
|
|
@@ -103,9 +114,5 @@ export interface SigningResult {
|
|
|
103
114
|
|
|
104
115
|
export interface WebsocketMessage {
|
|
105
116
|
event: string
|
|
106
|
-
data:
|
|
107
|
-
| ConnectResult
|
|
108
|
-
| DisconnectResult
|
|
109
|
-
| SessionRequest
|
|
110
|
-
| SigningResult
|
|
117
|
+
data: ConnectResult | DisconnectResult | SessionRequest | SigningResult
|
|
111
118
|
}
|