@portal-hq/connect 1.0.5 → 1.1.1

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.
@@ -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({ portal, websocketServer = 'connect.portalhq.io', }) {
14
- this.connected = false;
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.portal = portal;
17
- this.websocketServer = websocketServer;
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,15 +74,29 @@ class PortalConnect {
38
74
  // @ts-ignore
39
75
  {
40
76
  headers: {
41
- Authorization: `Bearer ${this.portal.apiKey}`,
77
+ Authorization: `Bearer ${this.apiKey}`,
42
78
  },
43
79
  });
80
+ this.uri = uri;
44
81
  this.bindToSocketEvents(this.socket, uri);
45
82
  });
46
83
  }
47
84
  deinit() {
48
85
  this.events = {};
49
86
  }
87
+ disconnect() {
88
+ this.sendFinalMessageAndClose();
89
+ }
90
+ /**
91
+ * Triggers the chain on the dapp to change to match the chain of the wallet
92
+ *
93
+ * @param chainId The number of the chainId to switch to
94
+ */
95
+ setChainId(chainId) {
96
+ return __awaiter(this, void 0, void 0, function* () {
97
+ this.provider.setChainId(chainId, this);
98
+ });
99
+ }
50
100
  /**
51
101
  * Invokes all registered event handlers with the data provided
52
102
  * - If any `once` handlers exist, they are removed after all handlers are invoked
@@ -135,7 +185,8 @@ class PortalConnect {
135
185
  * - Fires a subsequent call over the websocket to notify the proxy of the uri to connect to
136
186
  */
137
187
  socket.onopen = () => __awaiter(this, void 0, void 0, function* () {
138
- const { address, chainId } = this.portal.provider;
188
+ const address = yield this.address;
189
+ const { chainId } = this.provider;
139
190
  // Tell the proxy server where to connect to downstream
140
191
  socket.send(JSON.stringify({
141
192
  event: 'connect',
@@ -146,6 +197,18 @@ class PortalConnect {
146
197
  },
147
198
  }));
148
199
  });
200
+ this.on('portalConnect_chainChanged', (data) => {
201
+ var _a;
202
+ // Tell the proxy server where to connect to downstream
203
+ (_a = this.socket) === null || _a === void 0 ? void 0 : _a.send(JSON.stringify({
204
+ event: 'portal_chainChanged',
205
+ data: {
206
+ topic: this.topic,
207
+ uri: this.uri,
208
+ chainId: data.chainId,
209
+ },
210
+ }));
211
+ });
149
212
  socket.onerror = (event) => __awaiter(this, void 0, void 0, function* () {
150
213
  let errorMessage = 'An unexpected error occurred.';
151
214
  if (event instanceof ErrorEvent) {
@@ -168,12 +231,13 @@ class PortalConnect {
168
231
  this.emit('disconnect', message.data);
169
232
  break;
170
233
  case 'connected':
171
- this.connected = true;
234
+ this.connectionState = ConnectionStates.CONNECTED;
235
+ this.topic = message.data.topic;
172
236
  this.emit('connect', message.data);
173
237
  break;
174
238
  case 'disconnect':
175
239
  socket.close();
176
- this.connected = false;
240
+ this.connectionState = ConnectionStates.DISCONNECTED;
177
241
  this.emit('disconnect', message.data);
178
242
  break;
179
243
  case 'session_request':
@@ -203,28 +267,28 @@ class PortalConnect {
203
267
  handleProviderRequest(method, params, request) {
204
268
  return __awaiter(this, void 0, void 0, function* () {
205
269
  // Bind to potential signing rejection events
206
- this.portal.provider.on('portal_signingRejected', this.handleSigningRejected);
270
+ this.provider.on('portal_signingRejected', this.handleSigningRejected);
207
271
  // Bind to potential signature received events
208
- this.portal.provider.on('portal_signatureReceived', ({ method: signedMethod, params: signedParams, signature }) => {
272
+ this.provider.on('portal_signatureReceived', ({ method: signedMethod, params: signedParams, signature }) => {
209
273
  if (signedMethod === method &&
210
274
  JSON.stringify(signedParams) === JSON.stringify(params)) {
211
275
  this.handleSignatureReceived(request, signature);
212
276
  }
213
277
  });
214
278
  // Pass the request along to the provider
215
- yield this.portal.provider.request({ method, params });
279
+ yield this.provider.request({ method, params, connect: this });
216
280
  });
217
281
  }
218
282
  handleSessionApproved(data, request) {
219
283
  var _a;
220
284
  return __awaiter(this, void 0, void 0, function* () {
221
- const address = yield this.portal.keychain.getAddress();
285
+ const address = yield this.address;
222
286
  // Notify the proxy server that the session request was approved
223
287
  (_a = this.socket) === null || _a === void 0 ? void 0 : _a.send(JSON.stringify({
224
288
  event: 'portal_dappSessionApproved',
225
289
  data: {
226
290
  address,
227
- chainId: this.portal.chainId,
291
+ chainId: this.chainId,
228
292
  topic: request.topic,
229
293
  id: request.id,
230
294
  params: data,
@@ -235,13 +299,13 @@ class PortalConnect {
235
299
  handleSessionRejected(data, request) {
236
300
  var _a;
237
301
  return __awaiter(this, void 0, void 0, function* () {
238
- const address = yield this.portal.keychain.getAddress();
302
+ const address = yield this.address;
239
303
  // Notify the proxy server that the session request was rejected
240
304
  (_a = this.socket) === null || _a === void 0 ? void 0 : _a.send(JSON.stringify({
241
305
  event: 'portal_dappSessionRejected',
242
306
  data: {
243
307
  address,
244
- chainId: this.portal.chainId,
308
+ chainId: this.chainId,
245
309
  topic: request.topic,
246
310
  id: request.id,
247
311
  params: data,
@@ -272,6 +336,8 @@ class PortalConnect {
272
336
  transactionId: id,
273
337
  },
274
338
  }));
339
+ // Let the SDK consumer know the transaction hash
340
+ this.emit('portal_signgatureReceived', txHash);
275
341
  });
276
342
  }
277
343
  handleSigningRejected(data) {
@@ -288,5 +354,28 @@ class PortalConnect {
288
354
  }));
289
355
  });
290
356
  }
357
+ sendFinalMessageAndClose() {
358
+ var _a;
359
+ if (this.socket) {
360
+ this.connectionState = ConnectionStates.DISCONNECTING;
361
+ this.socket.send(JSON.stringify({
362
+ event: 'disconnect',
363
+ data: {
364
+ id: '',
365
+ topic: this.topic,
366
+ },
367
+ }));
368
+ this.topic = undefined;
369
+ (_a = this.socket) === null || _a === void 0 ? void 0 : _a.close();
370
+ this.connectionState = ConnectionStates.DISCONNECTED;
371
+ }
372
+ }
291
373
  }
374
+ var ConnectionStates;
375
+ (function (ConnectionStates) {
376
+ ConnectionStates["CONNECTED"] = "CONNECTED";
377
+ ConnectionStates["CONNECTING"] = "CONNECTING";
378
+ ConnectionStates["DISCONNECTED"] = "DISCONNECTED";
379
+ ConnectionStates["DISCONNECTING"] = "DISCONNECTING";
380
+ })(ConnectionStates = exports.ConnectionStates || (exports.ConnectionStates = {}));
292
381
  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({ portal, websocketServer = 'connect.portalhq.io', }) {
12
- this.connected = false;
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.portal = portal;
15
- this.websocketServer = websocketServer;
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,15 +71,29 @@ class PortalConnect {
36
71
  // @ts-ignore
37
72
  {
38
73
  headers: {
39
- Authorization: `Bearer ${this.portal.apiKey}`,
74
+ Authorization: `Bearer ${this.apiKey}`,
40
75
  },
41
76
  });
77
+ this.uri = uri;
42
78
  this.bindToSocketEvents(this.socket, uri);
43
79
  });
44
80
  }
45
81
  deinit() {
46
82
  this.events = {};
47
83
  }
84
+ disconnect() {
85
+ this.sendFinalMessageAndClose();
86
+ }
87
+ /**
88
+ * Triggers the chain on the dapp to change to match the chain of the wallet
89
+ *
90
+ * @param chainId The number of the chainId to switch to
91
+ */
92
+ setChainId(chainId) {
93
+ return __awaiter(this, void 0, void 0, function* () {
94
+ this.provider.setChainId(chainId, this);
95
+ });
96
+ }
48
97
  /**
49
98
  * Invokes all registered event handlers with the data provided
50
99
  * - If any `once` handlers exist, they are removed after all handlers are invoked
@@ -133,7 +182,8 @@ class PortalConnect {
133
182
  * - Fires a subsequent call over the websocket to notify the proxy of the uri to connect to
134
183
  */
135
184
  socket.onopen = () => __awaiter(this, void 0, void 0, function* () {
136
- const { address, chainId } = this.portal.provider;
185
+ const address = yield this.address;
186
+ const { chainId } = this.provider;
137
187
  // Tell the proxy server where to connect to downstream
138
188
  socket.send(JSON.stringify({
139
189
  event: 'connect',
@@ -144,6 +194,18 @@ class PortalConnect {
144
194
  },
145
195
  }));
146
196
  });
197
+ this.on('portalConnect_chainChanged', (data) => {
198
+ var _a;
199
+ // Tell the proxy server where to connect to downstream
200
+ (_a = this.socket) === null || _a === void 0 ? void 0 : _a.send(JSON.stringify({
201
+ event: 'portal_chainChanged',
202
+ data: {
203
+ topic: this.topic,
204
+ uri: this.uri,
205
+ chainId: data.chainId,
206
+ },
207
+ }));
208
+ });
147
209
  socket.onerror = (event) => __awaiter(this, void 0, void 0, function* () {
148
210
  let errorMessage = 'An unexpected error occurred.';
149
211
  if (event instanceof ErrorEvent) {
@@ -166,12 +228,13 @@ class PortalConnect {
166
228
  this.emit('disconnect', message.data);
167
229
  break;
168
230
  case 'connected':
169
- this.connected = true;
231
+ this.connectionState = ConnectionStates.CONNECTED;
232
+ this.topic = message.data.topic;
170
233
  this.emit('connect', message.data);
171
234
  break;
172
235
  case 'disconnect':
173
236
  socket.close();
174
- this.connected = false;
237
+ this.connectionState = ConnectionStates.DISCONNECTED;
175
238
  this.emit('disconnect', message.data);
176
239
  break;
177
240
  case 'session_request':
@@ -201,28 +264,28 @@ class PortalConnect {
201
264
  handleProviderRequest(method, params, request) {
202
265
  return __awaiter(this, void 0, void 0, function* () {
203
266
  // Bind to potential signing rejection events
204
- this.portal.provider.on('portal_signingRejected', this.handleSigningRejected);
267
+ this.provider.on('portal_signingRejected', this.handleSigningRejected);
205
268
  // Bind to potential signature received events
206
- this.portal.provider.on('portal_signatureReceived', ({ method: signedMethod, params: signedParams, signature }) => {
269
+ this.provider.on('portal_signatureReceived', ({ method: signedMethod, params: signedParams, signature }) => {
207
270
  if (signedMethod === method &&
208
271
  JSON.stringify(signedParams) === JSON.stringify(params)) {
209
272
  this.handleSignatureReceived(request, signature);
210
273
  }
211
274
  });
212
275
  // Pass the request along to the provider
213
- yield this.portal.provider.request({ method, params });
276
+ yield this.provider.request({ method, params, connect: this });
214
277
  });
215
278
  }
216
279
  handleSessionApproved(data, request) {
217
280
  var _a;
218
281
  return __awaiter(this, void 0, void 0, function* () {
219
- const address = yield this.portal.keychain.getAddress();
282
+ const address = yield this.address;
220
283
  // Notify the proxy server that the session request was approved
221
284
  (_a = this.socket) === null || _a === void 0 ? void 0 : _a.send(JSON.stringify({
222
285
  event: 'portal_dappSessionApproved',
223
286
  data: {
224
287
  address,
225
- chainId: this.portal.chainId,
288
+ chainId: this.chainId,
226
289
  topic: request.topic,
227
290
  id: request.id,
228
291
  params: data,
@@ -233,13 +296,13 @@ class PortalConnect {
233
296
  handleSessionRejected(data, request) {
234
297
  var _a;
235
298
  return __awaiter(this, void 0, void 0, function* () {
236
- const address = yield this.portal.keychain.getAddress();
299
+ const address = yield this.address;
237
300
  // Notify the proxy server that the session request was rejected
238
301
  (_a = this.socket) === null || _a === void 0 ? void 0 : _a.send(JSON.stringify({
239
302
  event: 'portal_dappSessionRejected',
240
303
  data: {
241
304
  address,
242
- chainId: this.portal.chainId,
305
+ chainId: this.chainId,
243
306
  topic: request.topic,
244
307
  id: request.id,
245
308
  params: data,
@@ -270,6 +333,8 @@ class PortalConnect {
270
333
  transactionId: id,
271
334
  },
272
335
  }));
336
+ // Let the SDK consumer know the transaction hash
337
+ this.emit('portal_signgatureReceived', txHash);
273
338
  });
274
339
  }
275
340
  handleSigningRejected(data) {
@@ -286,5 +351,28 @@ class PortalConnect {
286
351
  }));
287
352
  });
288
353
  }
354
+ sendFinalMessageAndClose() {
355
+ var _a;
356
+ if (this.socket) {
357
+ this.connectionState = ConnectionStates.DISCONNECTING;
358
+ this.socket.send(JSON.stringify({
359
+ event: 'disconnect',
360
+ data: {
361
+ id: '',
362
+ topic: this.topic,
363
+ },
364
+ }));
365
+ this.topic = undefined;
366
+ (_a = this.socket) === null || _a === void 0 ? void 0 : _a.close();
367
+ this.connectionState = ConnectionStates.DISCONNECTED;
368
+ }
369
+ }
289
370
  }
371
+ export var ConnectionStates;
372
+ (function (ConnectionStates) {
373
+ ConnectionStates["CONNECTED"] = "CONNECTED";
374
+ ConnectionStates["CONNECTING"] = "CONNECTING";
375
+ ConnectionStates["DISCONNECTED"] = "DISCONNECTED";
376
+ ConnectionStates["DISCONNECTING"] = "DISCONNECTING";
377
+ })(ConnectionStates || (ConnectionStates = {}));
290
378
  export default PortalConnect;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portal-hq/connect",
3
- "version": "1.0.5",
3
+ "version": "1.1.1",
4
4
  "main": "lib/commonjs/index",
5
5
  "module": "lib/esm/index",
6
6
  "source": "src/index",
@@ -31,6 +31,5 @@
31
31
  "@portal-hq/core": "*",
32
32
  "react": "*",
33
33
  "react-native": "*"
34
- },
35
- "gitHead": "acac6640bcad15621912376d95c0bd09509387e1"
34
+ }
36
35
  }
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import Portal from '@portal-hq/core'
1
+ import { Provider } from '@portal-hq/provider'
2
2
  import type {
3
3
  EventHandler,
4
4
  PortalConnectOptions,
@@ -8,23 +8,77 @@ import type {
8
8
  SessionRequest,
9
9
  WebsocketMessage,
10
10
  } from '../types.d'
11
+ import { SwitchEthereumChainParameter } from '@portal-hq/provider/types'
11
12
 
12
13
  class PortalConnect {
13
- public connected: boolean
14
- public portal: Portal
15
- public socket?: WebSocket
16
- public websocketServer: string
14
+ private apiKey: string
15
+ private connectionState: ConnectionStates = ConnectionStates.DISCONNECTED
16
+ private provider: Provider
17
+ private socket?: WebSocket
18
+ private topic?: string
19
+ private uri?: string
20
+ private websocketServer: string
17
21
 
18
22
  private events: Record<string, RegisteredEventHandler[]>
19
23
 
24
+ private get address(): Promise<string | undefined> {
25
+ return this.provider.address
26
+ }
27
+
28
+ private get chainId(): number {
29
+ return this.provider.chainId
30
+ }
31
+
32
+ public get connected(): boolean {
33
+ return (
34
+ this.connectionState === ConnectionStates.CONNECTED ||
35
+ this.connectionState === ConnectionStates.CONNECTING
36
+ )
37
+ }
38
+
20
39
  constructor({
21
- portal,
22
- websocketServer = 'connect.portalhq.io',
40
+ apiKey,
41
+ chainId,
42
+ keychain,
43
+ gatewayConfig,
44
+
45
+ // Optional
46
+ isSimulator = false,
47
+ autoApprove = false,
48
+ version = 'v4',
49
+ apiHost = 'api.portalhq.io',
50
+ mpcHost = 'mpc.portalhq.io',
51
+ webSocketServer = 'connect.portalhq.io',
23
52
  }: PortalConnectOptions) {
24
- this.connected = false
53
+ this.apiKey = apiKey
25
54
  this.events = {}
26
- this.portal = portal
27
- this.websocketServer = websocketServer
55
+ this.websocketServer = webSocketServer
56
+
57
+ this.provider = new Provider({
58
+ apiKey,
59
+ chainId,
60
+ gatewayConfig,
61
+ keychain,
62
+ isSimulator,
63
+ autoApprove,
64
+ version,
65
+ apiHost,
66
+ mpcHost,
67
+ })
68
+
69
+ // Inbound from the Provider
70
+ this.on('portalConnect_signingRequested', (data) => {
71
+ this.emit('portal_signingRequested', data)
72
+ })
73
+
74
+ // Inbound from SDK consumers
75
+ this.on('portal_signingApproved', (data) => {
76
+ this.provider.emit('portal_signingApproved', data)
77
+ })
78
+
79
+ this.on('portal_signingRejected', (data) => {
80
+ this.provider.emit('portal_signingRejected', data)
81
+ })
28
82
 
29
83
  // Do the OG binding trick to preserve the `this` context
30
84
  this.handleSessionApproved = this.handleSessionApproved.bind(this)
@@ -52,16 +106,31 @@ class PortalConnect {
52
106
  // @ts-ignore
53
107
  {
54
108
  headers: {
55
- Authorization: `Bearer ${this.portal.apiKey}`,
109
+ Authorization: `Bearer ${this.apiKey}`,
56
110
  },
57
111
  },
58
112
  )
113
+ this.uri = uri
59
114
  this.bindToSocketEvents(this.socket, uri)
60
115
  }
61
116
 
62
- public deinit() {
63
- this.events = {}
64
- }
117
+ public deinit() {
118
+ this.events = {}
119
+ }
120
+
121
+ public disconnect() {
122
+ this.sendFinalMessageAndClose()
123
+ }
124
+
125
+ /**
126
+ * Triggers the chain on the dapp to change to match the chain of the wallet
127
+ *
128
+ * @param chainId The number of the chainId to switch to
129
+ */
130
+ public async setChainId(chainId: number): Promise<void> {
131
+ this.provider.setChainId(chainId, this)
132
+ }
133
+
65
134
 
66
135
  /**
67
136
  * Invokes all registered event handlers with the data provided
@@ -168,7 +237,8 @@ public deinit() {
168
237
  * - Fires a subsequent call over the websocket to notify the proxy of the uri to connect to
169
238
  */
170
239
  socket.onopen = async () => {
171
- const { address, chainId } = this.portal.provider
240
+ const address = await this.address
241
+ const { chainId } = this.provider
172
242
 
173
243
  // Tell the proxy server where to connect to downstream
174
244
  socket.send(
@@ -183,6 +253,20 @@ public deinit() {
183
253
  )
184
254
  }
185
255
 
256
+ this.on('portalConnect_chainChanged', (data) => {
257
+ // Tell the proxy server where to connect to downstream
258
+ this.socket?.send(
259
+ JSON.stringify({
260
+ event: 'portal_chainChanged',
261
+ data: {
262
+ topic: this.topic,
263
+ uri: this.uri,
264
+ chainId: (data as SwitchEthereumChainParameter).chainId,
265
+ },
266
+ }),
267
+ )
268
+ })
269
+
186
270
  socket.onerror = async (event: Event) => {
187
271
  let errorMessage = 'An unexpected error occurred.'
188
272
 
@@ -209,12 +293,13 @@ public deinit() {
209
293
  this.emit('disconnect', message.data)
210
294
  break
211
295
  case 'connected':
212
- this.connected = true
296
+ this.connectionState = ConnectionStates.CONNECTED
297
+ this.topic = message.data.topic
213
298
  this.emit('connect', message.data)
214
299
  break
215
300
  case 'disconnect':
216
301
  socket.close()
217
- this.connected = false
302
+ this.connectionState = ConnectionStates.DISCONNECTED
218
303
  this.emit('disconnect', message.data)
219
304
 
220
305
  break
@@ -255,13 +340,10 @@ public deinit() {
255
340
  request: SessionRequest,
256
341
  ): Promise<void> {
257
342
  // Bind to potential signing rejection events
258
- this.portal.provider.on(
259
- 'portal_signingRejected',
260
- this.handleSigningRejected,
261
- )
343
+ this.provider.on('portal_signingRejected', this.handleSigningRejected)
262
344
 
263
345
  // Bind to potential signature received events
264
- this.portal.provider.on(
346
+ this.provider.on(
265
347
  'portal_signatureReceived',
266
348
  ({ method: signedMethod, params: signedParams, signature }) => {
267
349
  if (
@@ -274,14 +356,14 @@ public deinit() {
274
356
  )
275
357
 
276
358
  // Pass the request along to the provider
277
- await this.portal.provider.request({ method, params })
359
+ await this.provider.request({ method, params, connect: this })
278
360
  }
279
361
 
280
362
  private async handleSessionApproved(
281
363
  data: SessionProposalOrMetadata,
282
364
  request: SessionRequest,
283
365
  ): Promise<void> {
284
- const address = await this.portal.keychain.getAddress()
366
+ const address = await this.address
285
367
 
286
368
  // Notify the proxy server that the session request was approved
287
369
  this.socket?.send(
@@ -289,7 +371,7 @@ public deinit() {
289
371
  event: 'portal_dappSessionApproved',
290
372
  data: {
291
373
  address,
292
- chainId: this.portal.chainId,
374
+ chainId: this.chainId,
293
375
  topic: request.topic,
294
376
  id: request.id,
295
377
  params: data,
@@ -302,7 +384,7 @@ public deinit() {
302
384
  data: SessionProposalOrMetadata,
303
385
  request: SessionRequest,
304
386
  ): Promise<void> {
305
- const address = await this.portal.keychain.getAddress()
387
+ const address = await this.address
306
388
 
307
389
  // Notify the proxy server that the session request was rejected
308
390
  this.socket?.send(
@@ -310,7 +392,7 @@ public deinit() {
310
392
  event: 'portal_dappSessionRejected',
311
393
  data: {
312
394
  address,
313
- chainId: this.portal.chainId,
395
+ chainId: this.chainId,
314
396
  topic: request.topic,
315
397
  id: request.id,
316
398
  params: data,
@@ -341,6 +423,7 @@ public deinit() {
341
423
  txHash: any,
342
424
  ): Promise<void> {
343
425
  const { id, topic } = data
426
+
344
427
  // Let the server know the transaction hash
345
428
  this.socket?.send(
346
429
  JSON.stringify({
@@ -352,6 +435,9 @@ public deinit() {
352
435
  },
353
436
  }),
354
437
  )
438
+
439
+ // Let the SDK consumer know the transaction hash
440
+ this.emit('portal_signgatureReceived', txHash)
355
441
  }
356
442
 
357
443
  private async handleSigningRejected(data: SessionRequest): Promise<void> {
@@ -367,6 +453,34 @@ public deinit() {
367
453
  } as WebsocketMessage),
368
454
  )
369
455
  }
456
+
457
+ private sendFinalMessageAndClose() {
458
+ if (this.socket) {
459
+ this.connectionState = ConnectionStates.DISCONNECTING
460
+ this.socket.send(
461
+ JSON.stringify({
462
+ event: 'disconnect',
463
+ data: {
464
+ id: '',
465
+ topic: this.topic,
466
+ },
467
+ } as WebsocketMessage),
468
+ )
469
+
470
+ this.topic = undefined
471
+
472
+ this.socket?.close()
473
+
474
+ this.connectionState = ConnectionStates.DISCONNECTED
475
+ }
476
+ }
477
+ }
478
+
479
+ export enum ConnectionStates {
480
+ CONNECTED = 'CONNECTED',
481
+ CONNECTING = 'CONNECTING',
482
+ DISCONNECTED = 'DISCONNECTED',
483
+ DISCONNECTING = 'DISCONNECTING',
370
484
  }
371
485
 
372
486
  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
- portal: Portal
45
- websocketServer?: string
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
  }