@portal-hq/web 2.0.1 → 3.0.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.
- package/lib/commonjs/index.js +254 -58
- package/lib/commonjs/mpc/errors/index.js +2 -2
- package/lib/commonjs/mpc/index.js +43 -79
- package/lib/commonjs/provider/index.js +57 -14
- package/lib/esm/index.js +254 -58
- package/lib/esm/mpc/errors/index.js +2 -2
- package/lib/esm/mpc/index.js +43 -79
- package/lib/esm/provider/index.js +57 -14
- package/package.json +4 -1
- package/src/index.ts +323 -67
- package/src/mpc/errors/index.ts +2 -2
- package/src/mpc/index.ts +54 -99
- package/src/provider/index.ts +66 -16
- package/types.d.ts +17 -27
package/lib/esm/mpc/index.js
CHANGED
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { PortalMpcError } from './errors';
|
|
11
11
|
import { BackupMethods } from '../index';
|
|
12
|
-
const WEB_SDK_VERSION = '
|
|
12
|
+
const WEB_SDK_VERSION = '3.0.1';
|
|
13
13
|
class Mpc {
|
|
14
14
|
constructor({ portal }) {
|
|
15
15
|
this.configureIframe = () => {
|
|
@@ -18,11 +18,9 @@ class Mpc {
|
|
|
18
18
|
authToken: this.portal.authToken,
|
|
19
19
|
authUrl: this.portal.authUrl,
|
|
20
20
|
autoApprove: this.portal.autoApprove,
|
|
21
|
-
chainId: this.portal.chainId,
|
|
22
21
|
gdrive: this.portal.gDriveConfig,
|
|
23
22
|
passkey: this.portal.passkeyConfig,
|
|
24
23
|
host: this.portal.host,
|
|
25
|
-
rpcUrl: this.portal.getRpcUrl(),
|
|
26
24
|
mpcHost: this.portal.mpcHost,
|
|
27
25
|
mpcVersion: this.portal.mpcVersion,
|
|
28
26
|
featureFlags: this.portal.featureFlags,
|
|
@@ -258,7 +256,7 @@ class Mpc {
|
|
|
258
256
|
return __awaiter(this, void 0, void 0, function* () {
|
|
259
257
|
return new Promise((resolve, reject) => {
|
|
260
258
|
const handleEject = (message) => {
|
|
261
|
-
const { type, data } = message.data;
|
|
259
|
+
const { type, data: result } = message.data;
|
|
262
260
|
const { origin } = message;
|
|
263
261
|
// ignore any broadcast postMessages
|
|
264
262
|
if (origin !== this.getOrigin()) {
|
|
@@ -267,12 +265,12 @@ class Mpc {
|
|
|
267
265
|
if (type === 'portal:wasm:ejectError') {
|
|
268
266
|
// Remove the event listeners
|
|
269
267
|
window.removeEventListener('message', handleEject);
|
|
270
|
-
reject(new PortalMpcError(
|
|
268
|
+
reject(new PortalMpcError(result));
|
|
271
269
|
}
|
|
272
270
|
else if (type === 'portal:wasm:ejectResult') {
|
|
273
271
|
// Remove the event listeners
|
|
274
272
|
window.removeEventListener('message', handleEject);
|
|
275
|
-
resolve(
|
|
273
|
+
resolve(result);
|
|
276
274
|
}
|
|
277
275
|
};
|
|
278
276
|
window.addEventListener('message', handleEject);
|
|
@@ -287,10 +285,6 @@ class Mpc {
|
|
|
287
285
|
// Noop
|
|
288
286
|
}) {
|
|
289
287
|
return __awaiter(this, void 0, void 0, function* () {
|
|
290
|
-
const message = {
|
|
291
|
-
type: 'portal:wasm:sign',
|
|
292
|
-
data,
|
|
293
|
-
};
|
|
294
288
|
return new Promise((resolve, reject) => {
|
|
295
289
|
// Create a function to be bound when sign is triggered
|
|
296
290
|
const handleSign = (event) => {
|
|
@@ -330,7 +324,43 @@ class Mpc {
|
|
|
330
324
|
window.addEventListener('message', handleSign);
|
|
331
325
|
window.addEventListener('message', handleProgress);
|
|
332
326
|
// Send the request to the iframe
|
|
333
|
-
this.postMessage(
|
|
327
|
+
this.postMessage({
|
|
328
|
+
type: 'portal:wasm:sign',
|
|
329
|
+
data,
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
checkSharesOnDevice() {
|
|
335
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
336
|
+
return new Promise((resolve, reject) => {
|
|
337
|
+
const handleCheckSharesOnDevice = (event) => {
|
|
338
|
+
const { type, data } = event.data;
|
|
339
|
+
const { origin } = event;
|
|
340
|
+
// ignore any broadcast postMessages
|
|
341
|
+
if (origin !== this.getOrigin()) {
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if (type === 'portal:checkSharesOnDeviceError') {
|
|
345
|
+
// Remove the event listener
|
|
346
|
+
window.removeEventListener('message', handleCheckSharesOnDevice);
|
|
347
|
+
// Reject the promise with the error
|
|
348
|
+
return reject(new PortalMpcError(data));
|
|
349
|
+
}
|
|
350
|
+
else if (type === 'portal:checkSharesOnDeviceResult') {
|
|
351
|
+
// Remove the event listener
|
|
352
|
+
window.removeEventListener('message', handleCheckSharesOnDevice);
|
|
353
|
+
// Resolve the promise with the result
|
|
354
|
+
resolve(data);
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
// Bind the function to the message event
|
|
358
|
+
window.addEventListener('message', handleCheckSharesOnDevice);
|
|
359
|
+
// Send the request to the iframe
|
|
360
|
+
this.postMessage({
|
|
361
|
+
type: 'portal:checkSharesOnDevice',
|
|
362
|
+
data: {},
|
|
363
|
+
});
|
|
334
364
|
});
|
|
335
365
|
});
|
|
336
366
|
}
|
|
@@ -509,7 +539,7 @@ class Mpc {
|
|
|
509
539
|
});
|
|
510
540
|
});
|
|
511
541
|
}
|
|
512
|
-
getTransactions(limit, offset, order
|
|
542
|
+
getTransactions(chainId, limit, offset, order) {
|
|
513
543
|
return __awaiter(this, void 0, void 0, function* () {
|
|
514
544
|
return new Promise((resolve, reject) => {
|
|
515
545
|
const handleGetTransactions = (event) => {
|
|
@@ -538,10 +568,10 @@ class Mpc {
|
|
|
538
568
|
this.postMessage({
|
|
539
569
|
type: 'portal:getTransactions',
|
|
540
570
|
data: {
|
|
571
|
+
chainId,
|
|
541
572
|
limit,
|
|
542
573
|
offset,
|
|
543
574
|
order,
|
|
544
|
-
chainId,
|
|
545
575
|
},
|
|
546
576
|
});
|
|
547
577
|
});
|
|
@@ -652,72 +682,6 @@ class Mpc {
|
|
|
652
682
|
});
|
|
653
683
|
});
|
|
654
684
|
}
|
|
655
|
-
getBackupShareMetadata() {
|
|
656
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
657
|
-
return new Promise((resolve, reject) => {
|
|
658
|
-
const handleGetBackupShareMetadata = (event) => {
|
|
659
|
-
const { type, data } = event.data;
|
|
660
|
-
const { origin } = event;
|
|
661
|
-
// ignore any broadcast postMessages
|
|
662
|
-
if (origin !== this.getOrigin()) {
|
|
663
|
-
return;
|
|
664
|
-
}
|
|
665
|
-
if (type === 'portal:getBackupShareMetadataError') {
|
|
666
|
-
// Remove the event listener
|
|
667
|
-
window.removeEventListener('message', handleGetBackupShareMetadata);
|
|
668
|
-
// Reject the promise with the error
|
|
669
|
-
return reject(new PortalMpcError(data));
|
|
670
|
-
}
|
|
671
|
-
else if (type === 'portal:getBackupShareMetadataResult') {
|
|
672
|
-
// Remove the event listener
|
|
673
|
-
window.removeEventListener('message', handleGetBackupShareMetadata);
|
|
674
|
-
// Resolve the promise with the result
|
|
675
|
-
resolve(data);
|
|
676
|
-
}
|
|
677
|
-
};
|
|
678
|
-
// Bind the function to the message event
|
|
679
|
-
window.addEventListener('message', handleGetBackupShareMetadata);
|
|
680
|
-
// Send the request to the iframe
|
|
681
|
-
this.postMessage({
|
|
682
|
-
type: 'portal:getBackupShareMetadata',
|
|
683
|
-
data: {},
|
|
684
|
-
});
|
|
685
|
-
});
|
|
686
|
-
});
|
|
687
|
-
}
|
|
688
|
-
getSigningShareMetadata() {
|
|
689
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
690
|
-
return new Promise((resolve, reject) => {
|
|
691
|
-
const handleGetSigningShareMetadata = (event) => {
|
|
692
|
-
const { type, data } = event.data;
|
|
693
|
-
const { origin } = event;
|
|
694
|
-
// ignore any broadcast postMessages
|
|
695
|
-
if (origin !== this.getOrigin()) {
|
|
696
|
-
return;
|
|
697
|
-
}
|
|
698
|
-
if (type === 'portal:getSigningShareMetadataError') {
|
|
699
|
-
// Remove the event listener
|
|
700
|
-
window.removeEventListener('message', handleGetSigningShareMetadata);
|
|
701
|
-
// Reject the promise with the error
|
|
702
|
-
return reject(new PortalMpcError(data));
|
|
703
|
-
}
|
|
704
|
-
else if (type === 'portal:getSigningShareMetadataResult') {
|
|
705
|
-
// Remove the event listener
|
|
706
|
-
window.removeEventListener('message', handleGetSigningShareMetadata);
|
|
707
|
-
// Resolve the promise with the result
|
|
708
|
-
resolve(data);
|
|
709
|
-
}
|
|
710
|
-
};
|
|
711
|
-
// Bind the function to the message event
|
|
712
|
-
window.addEventListener('message', handleGetSigningShareMetadata);
|
|
713
|
-
// Send the request to the iframe
|
|
714
|
-
this.postMessage({
|
|
715
|
-
type: 'portal:getSigningShareMetadata',
|
|
716
|
-
data: {},
|
|
717
|
-
});
|
|
718
|
-
});
|
|
719
|
-
});
|
|
720
|
-
}
|
|
721
685
|
/***************************
|
|
722
686
|
* Private Methods
|
|
723
687
|
***************************/
|
|
@@ -23,9 +23,29 @@ const signerMethods = [
|
|
|
23
23
|
'eth_signTypedData_v3',
|
|
24
24
|
'eth_signTypedData_v4',
|
|
25
25
|
'personal_sign',
|
|
26
|
+
'sol_signAndConfirmTransaction',
|
|
27
|
+
'sol_signAndSendTransaction',
|
|
28
|
+
'sol_signMessage',
|
|
29
|
+
'sol_signTransaction',
|
|
26
30
|
];
|
|
27
31
|
class Provider {
|
|
28
32
|
constructor({ portal }) {
|
|
33
|
+
this.enforceEip155ChainId = (chainId) => {
|
|
34
|
+
if (!chainId) {
|
|
35
|
+
throw new Error('[PortalProvider] Chain ID is required for the operation');
|
|
36
|
+
}
|
|
37
|
+
if (!chainId.startsWith('eip155:')) {
|
|
38
|
+
throw new Error(`[PortalProvider] Chain ID must be prefixed with "eip155:" for the operation, got ${chainId}`);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
this.enforceSolanaChainId = (chainId) => {
|
|
42
|
+
if (!chainId) {
|
|
43
|
+
throw new Error('[PortalProvider] Chain ID is required for the operation');
|
|
44
|
+
}
|
|
45
|
+
if (!chainId.startsWith('solana:')) {
|
|
46
|
+
throw new Error(`[PortalProvider] Chain ID must be prefixed with "solana:" for the operation, got ${chainId}`);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
29
49
|
this.buildParams = (method, txParams) => {
|
|
30
50
|
let params = txParams;
|
|
31
51
|
switch (method) {
|
|
@@ -33,6 +53,10 @@ class Provider {
|
|
|
33
53
|
case 'personal_sign':
|
|
34
54
|
case 'eth_signTypedData_v3':
|
|
35
55
|
case 'eth_signTypedData_v4':
|
|
56
|
+
case 'sol_signAndConfirmTransaction':
|
|
57
|
+
case 'sol_signAndSendTransaction':
|
|
58
|
+
case 'sol_signMessage':
|
|
59
|
+
case 'sol_signTransaction':
|
|
36
60
|
if (!Array.isArray(txParams)) {
|
|
37
61
|
params = [txParams];
|
|
38
62
|
}
|
|
@@ -110,9 +134,6 @@ class Provider {
|
|
|
110
134
|
*/
|
|
111
135
|
request({ chainId, method, params, }) {
|
|
112
136
|
return __awaiter(this, void 0, void 0, function* () {
|
|
113
|
-
if (method === 'eth_chainId') {
|
|
114
|
-
return chainId ? parseInt(chainId.split(':')[1]) : this.portal.chainId;
|
|
115
|
-
}
|
|
116
137
|
const isSignerMethod = signerMethods.includes(method);
|
|
117
138
|
if (!isSignerMethod && !method.startsWith('wallet_')) {
|
|
118
139
|
// Send to Gateway for RPC calls
|
|
@@ -223,16 +244,21 @@ class Provider {
|
|
|
223
244
|
*/
|
|
224
245
|
handleGatewayRequest({ chainId, method, params, }) {
|
|
225
246
|
return __awaiter(this, void 0, void 0, function* () {
|
|
226
|
-
//
|
|
227
|
-
const
|
|
247
|
+
// Prepare the request body
|
|
248
|
+
const requestBody = {
|
|
228
249
|
body: JSON.stringify({
|
|
229
250
|
jsonrpc: '2.0',
|
|
230
|
-
id:
|
|
251
|
+
id: '0',
|
|
231
252
|
method,
|
|
232
253
|
params,
|
|
233
254
|
}),
|
|
234
255
|
method: 'POST',
|
|
235
|
-
|
|
256
|
+
headers: {
|
|
257
|
+
'Content-Type': 'application/json',
|
|
258
|
+
},
|
|
259
|
+
};
|
|
260
|
+
// Pass request off to the gateway
|
|
261
|
+
const result = yield fetch(this.portal.getRpcUrl(chainId), requestBody);
|
|
236
262
|
return result.json();
|
|
237
263
|
});
|
|
238
264
|
}
|
|
@@ -252,24 +278,41 @@ class Provider {
|
|
|
252
278
|
return;
|
|
253
279
|
}
|
|
254
280
|
switch (method) {
|
|
255
|
-
case 'eth_chainId':
|
|
256
|
-
|
|
281
|
+
case 'eth_chainId': {
|
|
282
|
+
this.enforceEip155ChainId(chainId);
|
|
283
|
+
const chainReferenceId = parseInt(chainId.split(':')[1]);
|
|
284
|
+
return `0x${chainReferenceId.toString(16)}`;
|
|
285
|
+
}
|
|
257
286
|
case 'eth_accounts':
|
|
258
|
-
case 'eth_requestAccounts':
|
|
287
|
+
case 'eth_requestAccounts': {
|
|
288
|
+
this.enforceEip155ChainId(chainId);
|
|
259
289
|
return [this.portal.address];
|
|
290
|
+
}
|
|
260
291
|
case 'eth_sendTransaction':
|
|
261
292
|
case 'eth_sign':
|
|
262
293
|
case 'eth_signTransaction':
|
|
263
294
|
case 'eth_signTypedData_v3':
|
|
264
295
|
case 'eth_signTypedData_v4':
|
|
265
296
|
case 'personal_sign': {
|
|
297
|
+
this.enforceEip155ChainId(chainId);
|
|
298
|
+
const result = yield this.portal.mpc.sign({
|
|
299
|
+
chainId: chainId,
|
|
300
|
+
method,
|
|
301
|
+
params: this.buildParams(method, params),
|
|
302
|
+
rpcUrl: this.portal.getRpcUrl(chainId),
|
|
303
|
+
});
|
|
304
|
+
return result;
|
|
305
|
+
}
|
|
306
|
+
case 'sol_signAndConfirmTransaction':
|
|
307
|
+
case 'sol_signAndSendTransaction':
|
|
308
|
+
case 'sol_signMessage':
|
|
309
|
+
case 'sol_signTransaction': {
|
|
310
|
+
this.enforceSolanaChainId(chainId);
|
|
266
311
|
const result = yield this.portal.mpc.sign({
|
|
267
|
-
chainId: chainId
|
|
268
|
-
? chainId.split(':')[1]
|
|
269
|
-
: this.portal.chainId.toString(),
|
|
312
|
+
chainId: chainId,
|
|
270
313
|
method,
|
|
271
314
|
params: this.buildParams(method, params),
|
|
272
|
-
rpcUrl: this.portal.getRpcUrl(),
|
|
315
|
+
rpcUrl: this.portal.getRpcUrl(chainId),
|
|
273
316
|
});
|
|
274
317
|
return result;
|
|
275
318
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Portal MPC Support for Web",
|
|
4
4
|
"author": "Portal Labs, Inc.",
|
|
5
5
|
"homepage": "https://portalhq.io/",
|
|
6
|
-
"version": "
|
|
6
|
+
"version": "3.0.1",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"main": "lib/commonjs/index",
|
|
9
9
|
"module": "lib/esm/index",
|
|
@@ -45,5 +45,8 @@
|
|
|
45
45
|
"typescript": "^4.8.4",
|
|
46
46
|
"webpack": "^5.87.0",
|
|
47
47
|
"webpack-cli": "^5.1.4"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@solana/web3.js": "^1.91.8"
|
|
48
51
|
}
|
|
49
52
|
}
|