@portal-hq/web 0.0.1-beta-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/README.md +297 -0
- package/lib/commonjs/index.js +201 -0
- package/lib/commonjs/mpc/index.js +353 -0
- package/lib/commonjs/provider/index.js +259 -0
- package/lib/commonjs/storage/index.js +17 -0
- package/lib/esm/index.js +196 -0
- package/lib/esm/mpc/index.js +351 -0
- package/lib/esm/provider/index.js +257 -0
- package/lib/esm/storage/index.js +15 -0
- package/package.json +46 -0
- package/src/index.ts +232 -0
- package/src/mpc/index.ts +443 -0
- package/src/provider/index.ts +314 -0
- package/src/storage/index.ts +29 -0
- package/types.d.ts +341 -0
package/lib/esm/index.js
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import Mpc from './mpc';
|
|
11
|
+
import Provider from './provider';
|
|
12
|
+
import DefaultBackupStorage from './storage';
|
|
13
|
+
class Portal {
|
|
14
|
+
constructor({
|
|
15
|
+
// Required
|
|
16
|
+
apiKey, gatewayConfig,
|
|
17
|
+
// Optional
|
|
18
|
+
apiHost = 'api.portalhq.io', autoApprove = false, backup = { default: new DefaultBackupStorage() }, chainId = 1, mpcHost = 'mpc.portalhq.io', mpcVersion = 'v4', webHost = 'web.portalhq.io', }) {
|
|
19
|
+
this.ready = false;
|
|
20
|
+
this.readyCallbacks = [];
|
|
21
|
+
this.apiHost = apiHost;
|
|
22
|
+
this.apiKey = apiKey;
|
|
23
|
+
this.autoApprove = autoApprove;
|
|
24
|
+
this.backup = backup;
|
|
25
|
+
this.chainId = chainId;
|
|
26
|
+
this.gatewayConfig = gatewayConfig;
|
|
27
|
+
this.mpcHost = mpcHost;
|
|
28
|
+
this.mpcVersion = mpcVersion;
|
|
29
|
+
this.rpcUrl = this.getRpcUrl();
|
|
30
|
+
this.webHost = webHost;
|
|
31
|
+
console.log(`Backup:`, this.backup);
|
|
32
|
+
// Portal Instances
|
|
33
|
+
this.mpc = new Mpc({
|
|
34
|
+
apiHost: this.apiHost,
|
|
35
|
+
apiKey: this.apiKey,
|
|
36
|
+
autoApprove: this.autoApprove,
|
|
37
|
+
chainId: this.chainId,
|
|
38
|
+
mpcHost: this.mpcHost,
|
|
39
|
+
rpcUrl: this.rpcUrl,
|
|
40
|
+
webHost: this.webHost,
|
|
41
|
+
portal: this,
|
|
42
|
+
});
|
|
43
|
+
this.provider = new Provider({
|
|
44
|
+
autoApprove: this.autoApprove,
|
|
45
|
+
mpcHost: this.mpcHost,
|
|
46
|
+
mpcVersion: this.mpcVersion,
|
|
47
|
+
portal: this,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/*****************************
|
|
51
|
+
* Initialization Methods
|
|
52
|
+
*****************************/
|
|
53
|
+
onReady(callback) {
|
|
54
|
+
if (this.ready) {
|
|
55
|
+
callback();
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
this.readyCallbacks.push(callback);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
triggerReady() {
|
|
62
|
+
if (this.ready && this.readyCallbacks.length > 0) {
|
|
63
|
+
this.readyCallbacks.forEach((callback) => {
|
|
64
|
+
callback();
|
|
65
|
+
});
|
|
66
|
+
this.readyCallbacks = [];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/*****************************
|
|
70
|
+
* Wallet Methods
|
|
71
|
+
*****************************/
|
|
72
|
+
createWallet() {
|
|
73
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
74
|
+
const address = yield this.mpc.generate({
|
|
75
|
+
host: this.mpcHost,
|
|
76
|
+
mpcVersion: this.mpcVersion,
|
|
77
|
+
});
|
|
78
|
+
this.address = address;
|
|
79
|
+
return address;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
backupWallet() {
|
|
83
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
84
|
+
yield this.mpc.backup({
|
|
85
|
+
host: this.mpcHost,
|
|
86
|
+
mpcVersion: this.mpcVersion,
|
|
87
|
+
});
|
|
88
|
+
return '';
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
recoverWallet() {
|
|
92
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
93
|
+
yield this.mpc.recover({
|
|
94
|
+
host: this.mpcHost,
|
|
95
|
+
mpcVersion: this.mpcVersion,
|
|
96
|
+
});
|
|
97
|
+
return true;
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
/****************************
|
|
101
|
+
* Provider Methods
|
|
102
|
+
****************************/
|
|
103
|
+
ethSendTransaction(transaction) {
|
|
104
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
105
|
+
return this.provider.request({
|
|
106
|
+
method: 'eth_sendTransaction',
|
|
107
|
+
params: transaction,
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
ethSign(message) {
|
|
112
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
113
|
+
return this.provider.request({
|
|
114
|
+
method: 'eth_sign',
|
|
115
|
+
params: [this.address, this.stringToHex(message)],
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
ethSignTransaction(transaction) {
|
|
120
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
121
|
+
return this.provider.request({
|
|
122
|
+
method: 'eth_signTransaction',
|
|
123
|
+
params: transaction,
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
ethSignTypedData(data) {
|
|
128
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
129
|
+
return this.provider.request({
|
|
130
|
+
method: 'eth_signTypedData',
|
|
131
|
+
params: [this.address, data],
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
ethSignTypedDataV3(data) {
|
|
136
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
137
|
+
return this.provider.request({
|
|
138
|
+
method: 'eth_signTypedData_v3',
|
|
139
|
+
params: [this.address, data],
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
ethSignTypedDataV4(data) {
|
|
144
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
145
|
+
return this.provider.request({
|
|
146
|
+
method: 'eth_signTypedData_v4',
|
|
147
|
+
params: [this.address, data],
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
personalSign(message) {
|
|
152
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
153
|
+
return this.provider.request({
|
|
154
|
+
method: 'personal_sign',
|
|
155
|
+
params: [this.stringToHex(message), this.address],
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
/****************************
|
|
160
|
+
* RPC Methods
|
|
161
|
+
****************************/
|
|
162
|
+
getRpcUrl() {
|
|
163
|
+
if (typeof this.gatewayConfig === 'string') {
|
|
164
|
+
// If the gatewayConfig is just a static URL, return that
|
|
165
|
+
return this.gatewayConfig;
|
|
166
|
+
}
|
|
167
|
+
else if (typeof this.gatewayConfig === 'object' &&
|
|
168
|
+
!this.gatewayConfig.hasOwnProperty(this.chainId)) {
|
|
169
|
+
// If there's no explicit mapping for the current chainId, error out
|
|
170
|
+
throw new Error(`[PortalProvider] No RPC endpoint configured for chainId: ${this.chainId}`);
|
|
171
|
+
}
|
|
172
|
+
// Get the entry for the current chainId from the gatewayConfig
|
|
173
|
+
const config = this.gatewayConfig[this.chainId];
|
|
174
|
+
if (typeof config === 'string') {
|
|
175
|
+
return config;
|
|
176
|
+
}
|
|
177
|
+
// If we got this far, there's no way to support the chain with the current config
|
|
178
|
+
throw new Error(`[PortalProvider] Could not find a valid gatewayConfig entry for chainId: ${this.chainId}`);
|
|
179
|
+
}
|
|
180
|
+
/**************************
|
|
181
|
+
* RPC Encoding Methods
|
|
182
|
+
**************************/
|
|
183
|
+
stringToHex(str) {
|
|
184
|
+
if (str.startsWith('0x')) {
|
|
185
|
+
return str;
|
|
186
|
+
}
|
|
187
|
+
let hex = '0x';
|
|
188
|
+
for (let i = 0; i < str.length; i++) {
|
|
189
|
+
const charCode = str.charCodeAt(i);
|
|
190
|
+
const hexValue = charCode.toString(16);
|
|
191
|
+
hex += hexValue.padStart(2, '0'); // Ensure two-digit hex value
|
|
192
|
+
}
|
|
193
|
+
return hex;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
export default Portal;
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { PortalMpcError } from '@portal-hq/utils';
|
|
11
|
+
const WEB_SDK_VERSION = '0.0.1-beta-1';
|
|
12
|
+
class Mpc {
|
|
13
|
+
constructor({ apiKey, chainId, portal, rpcUrl,
|
|
14
|
+
// Optional
|
|
15
|
+
apiHost = 'api.portalhq.io', autoApprove = false, mpcHost = 'mpc.portalhq.io', webHost = 'web.portalhq.io', }) {
|
|
16
|
+
this.apiHost = apiHost;
|
|
17
|
+
this.apiKey = apiKey;
|
|
18
|
+
this.autoApprove = autoApprove;
|
|
19
|
+
this.chainId = chainId;
|
|
20
|
+
this.mpcHost = mpcHost;
|
|
21
|
+
this.portal = portal;
|
|
22
|
+
this.rpcUrl = rpcUrl;
|
|
23
|
+
this.webHost = webHost;
|
|
24
|
+
// Handle scoping of certain functions
|
|
25
|
+
this.configureIframe = this.configureIframe.bind(this);
|
|
26
|
+
// Create the iFrame for MPC operations
|
|
27
|
+
this.appendIframe();
|
|
28
|
+
}
|
|
29
|
+
// In Progress
|
|
30
|
+
backup(data) {
|
|
31
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
32
|
+
const message = {
|
|
33
|
+
type: 'portal:wasm:backup',
|
|
34
|
+
data,
|
|
35
|
+
};
|
|
36
|
+
return new Promise((resolve, reject) => {
|
|
37
|
+
// Create a function to be bound when backup is triggered
|
|
38
|
+
const handleBackup = (event) => {
|
|
39
|
+
const { type, data: result } = event;
|
|
40
|
+
// Check that the message is the one we're looking for
|
|
41
|
+
if (type === 'portal:wasm:backupResult') {
|
|
42
|
+
// Check if the result is an error
|
|
43
|
+
if (result.error && result.error.code > 0) {
|
|
44
|
+
// Remove the event listener
|
|
45
|
+
window.removeEventListener('message', handleBackup);
|
|
46
|
+
// Reject the promise with the error
|
|
47
|
+
return reject(new PortalMpcError(result.error));
|
|
48
|
+
}
|
|
49
|
+
// Remove the event listener
|
|
50
|
+
window.removeEventListener('message', handleBackup);
|
|
51
|
+
// Resolve the promise with the result
|
|
52
|
+
resolve(result);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
// Bind the function to the message event
|
|
56
|
+
window.addEventListener('message', handleBackup);
|
|
57
|
+
// Send the request to the iframe
|
|
58
|
+
this.postMessage(message);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
// In Progress
|
|
63
|
+
decrypt(data) {
|
|
64
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
65
|
+
const message = {
|
|
66
|
+
type: 'portal:wasm:decrypt',
|
|
67
|
+
data,
|
|
68
|
+
};
|
|
69
|
+
return new Promise((resolve, reject) => {
|
|
70
|
+
const handleDecrypt = (event) => {
|
|
71
|
+
const { type, data: result } = event;
|
|
72
|
+
// Check that the message is the one we're looking for
|
|
73
|
+
if (type === 'portal:wasm:decryptResult') {
|
|
74
|
+
// Check if the result is an error
|
|
75
|
+
if (result.error && result.error.code > 0) {
|
|
76
|
+
// Remove the event listener
|
|
77
|
+
window.removeEventListener('message', handleDecrypt);
|
|
78
|
+
// Reject the promise with the error
|
|
79
|
+
return reject(new PortalMpcError(result.error));
|
|
80
|
+
}
|
|
81
|
+
// Remove the event listener
|
|
82
|
+
window.removeEventListener('message', handleDecrypt);
|
|
83
|
+
// Resolve the promise with the result
|
|
84
|
+
resolve(result);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
// Bind the function to the message event
|
|
88
|
+
window.addEventListener('message', handleDecrypt);
|
|
89
|
+
// Send the request to the iframe
|
|
90
|
+
this.postMessage(message);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
// In Progress
|
|
95
|
+
encrypt(data) {
|
|
96
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
97
|
+
const message = {
|
|
98
|
+
type: 'portal:wasm:encrypt',
|
|
99
|
+
data,
|
|
100
|
+
};
|
|
101
|
+
return new Promise((resolve, reject) => {
|
|
102
|
+
const handleEncrypt = (event) => {
|
|
103
|
+
const { type, data: result } = event;
|
|
104
|
+
// Check that the message is the one we're looking for
|
|
105
|
+
if (type === 'portal:wasm:encryptResult') {
|
|
106
|
+
// Check if the result is an error
|
|
107
|
+
if (result.error && result.error.code > 0) {
|
|
108
|
+
// Remove the event listener
|
|
109
|
+
window.removeEventListener('message', handleEncrypt);
|
|
110
|
+
// Reject the promise with the error
|
|
111
|
+
return reject(new PortalMpcError(result.error));
|
|
112
|
+
}
|
|
113
|
+
// Remove the event listener
|
|
114
|
+
window.removeEventListener('message', handleEncrypt);
|
|
115
|
+
// Resolve the promise with the result
|
|
116
|
+
resolve(result);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
// Bind the function to the message event
|
|
120
|
+
window.addEventListener('message', handleEncrypt);
|
|
121
|
+
// Send the request to the iframe
|
|
122
|
+
this.postMessage(message);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
generate(data) {
|
|
127
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
128
|
+
const message = {
|
|
129
|
+
type: 'portal:wasm:generate',
|
|
130
|
+
data,
|
|
131
|
+
};
|
|
132
|
+
return new Promise((resolve, reject) => {
|
|
133
|
+
// Create a function to be bound when generate is triggered
|
|
134
|
+
const handleGenerate = (event) => {
|
|
135
|
+
console.log(`[MPC] Temporary listener received event: `, event);
|
|
136
|
+
const { type, data: result } = event.data;
|
|
137
|
+
// Handle errors
|
|
138
|
+
if (type === 'portal:wasm:generateError') {
|
|
139
|
+
// Remove the event listener
|
|
140
|
+
window.removeEventListener('message', handleGenerate);
|
|
141
|
+
// Reject the promise with the error
|
|
142
|
+
return reject(new PortalMpcError(result));
|
|
143
|
+
}
|
|
144
|
+
else if (type === 'portal:wasm:generateResult') {
|
|
145
|
+
// Remove the event listener
|
|
146
|
+
window.removeEventListener('message', handleGenerate);
|
|
147
|
+
// Resolve the promise with the result
|
|
148
|
+
resolve(result);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
// Bind the function to the message event
|
|
152
|
+
window.addEventListener('message', handleGenerate);
|
|
153
|
+
// Send the request to the iframe
|
|
154
|
+
this.postMessage(message);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
getAddress() {
|
|
159
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
160
|
+
const message = {
|
|
161
|
+
type: 'portal:address',
|
|
162
|
+
data: {},
|
|
163
|
+
};
|
|
164
|
+
return new Promise((resolve) => {
|
|
165
|
+
// Create a function to be bound when getAddress is triggered
|
|
166
|
+
const handleGetAddress = (event) => {
|
|
167
|
+
const { type, data: result } = event.data;
|
|
168
|
+
// Check that the message is the one we're looking for
|
|
169
|
+
if (type === 'portal:addressResult') {
|
|
170
|
+
// Remove the event listener
|
|
171
|
+
window.removeEventListener('message', handleGetAddress);
|
|
172
|
+
// Resolve the promise with the result
|
|
173
|
+
resolve(result);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
// Bind the function to the message event
|
|
177
|
+
window.addEventListener('message', handleGetAddress);
|
|
178
|
+
// Send the request to the iframe
|
|
179
|
+
this.postMessage(message);
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
// In Progress
|
|
184
|
+
recover(data) {
|
|
185
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
186
|
+
yield this.recoverBackup(data);
|
|
187
|
+
// TODO: Write the DKG Result to local storage
|
|
188
|
+
const cipherText = yield this.recoverSigning(data);
|
|
189
|
+
return JSON.stringify(cipherText);
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
// In Progress
|
|
193
|
+
recoverBackup(data) {
|
|
194
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
195
|
+
const message = {
|
|
196
|
+
type: 'portal:wasm:recoverBackup',
|
|
197
|
+
data,
|
|
198
|
+
};
|
|
199
|
+
return new Promise((resolve, reject) => {
|
|
200
|
+
// Create a function to be bound when recoverSigning is triggered
|
|
201
|
+
const handleRecovery = (event) => {
|
|
202
|
+
const { type, data: result } = event;
|
|
203
|
+
// Check that the message is the one we're looking for
|
|
204
|
+
if (type === 'portal:wasm:recoverBackupResult') {
|
|
205
|
+
// Check if the result is an error
|
|
206
|
+
if (result.error && result.error.code > 0) {
|
|
207
|
+
// Remove the event listener
|
|
208
|
+
window.removeEventListener('message', handleRecovery);
|
|
209
|
+
// Reject the promise with the error
|
|
210
|
+
return reject(new PortalMpcError(result.error));
|
|
211
|
+
}
|
|
212
|
+
// Remove the event listener
|
|
213
|
+
window.removeEventListener('message', handleRecovery);
|
|
214
|
+
// Resolve the promise with the result
|
|
215
|
+
resolve(result);
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
// Bind the function to the message event
|
|
219
|
+
window.addEventListener('message', handleRecovery);
|
|
220
|
+
// Send the request to the iframe
|
|
221
|
+
this.postMessage(message);
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
// In Progress
|
|
226
|
+
recoverSigning(data) {
|
|
227
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
228
|
+
const message = {
|
|
229
|
+
type: 'portal:wasm:recoverSigning',
|
|
230
|
+
data,
|
|
231
|
+
};
|
|
232
|
+
return new Promise((resolve, reject) => {
|
|
233
|
+
// Create a function to be bound when recoverSigning is triggered
|
|
234
|
+
const handleRecovery = (event) => {
|
|
235
|
+
const { type, data: result } = event;
|
|
236
|
+
// Check that the message is the one we're looking for
|
|
237
|
+
if (type === 'portal:wasm:recoverSigningResult') {
|
|
238
|
+
// Check if the result is an error
|
|
239
|
+
if (result.error && result.error.code > 0) {
|
|
240
|
+
// Remove the event listener
|
|
241
|
+
window.removeEventListener('message', handleRecovery);
|
|
242
|
+
// Reject the promise with the error
|
|
243
|
+
return reject(new PortalMpcError(result.error));
|
|
244
|
+
}
|
|
245
|
+
// Remove the event listener
|
|
246
|
+
window.removeEventListener('message', handleRecovery);
|
|
247
|
+
// Resolve the promise with the result
|
|
248
|
+
resolve(result);
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
// Bind the function to the message event
|
|
252
|
+
window.addEventListener('message', handleRecovery);
|
|
253
|
+
// Send the request to the iframe
|
|
254
|
+
this.postMessage(message);
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
sign(data) {
|
|
259
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
260
|
+
const message = {
|
|
261
|
+
type: 'portal:wasm:sign',
|
|
262
|
+
data,
|
|
263
|
+
};
|
|
264
|
+
return new Promise((resolve, reject) => {
|
|
265
|
+
// Create a function to be bound when sign is triggered
|
|
266
|
+
const handleSign = (event) => {
|
|
267
|
+
const { type, data: result } = event.data;
|
|
268
|
+
if (type === 'portal:wasm:signError') {
|
|
269
|
+
// Remove the event listener
|
|
270
|
+
window.removeEventListener('message', handleSign);
|
|
271
|
+
// Reject the promise with the error
|
|
272
|
+
return reject(new PortalMpcError(result));
|
|
273
|
+
}
|
|
274
|
+
else if (type === 'portal:wasm:signResult') {
|
|
275
|
+
// Remove the event listener
|
|
276
|
+
window.removeEventListener('message', handleSign);
|
|
277
|
+
// Resolve the promise with the result
|
|
278
|
+
resolve(result);
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
// Bind the function to the message event
|
|
282
|
+
window.addEventListener('message', handleSign);
|
|
283
|
+
// Send the request to the iframe
|
|
284
|
+
this.postMessage(message);
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
/***************************
|
|
289
|
+
* Private Methods
|
|
290
|
+
***************************/
|
|
291
|
+
/**
|
|
292
|
+
* Appends the iframe to the document body
|
|
293
|
+
*/
|
|
294
|
+
appendIframe() {
|
|
295
|
+
const source = this.webHost.startsWith('locahost:')
|
|
296
|
+
? `http://${this.webHost}/${WEB_SDK_VERSION}/iframe/index.html?t=${Date.now()}`
|
|
297
|
+
: `https://${this.webHost}/${WEB_SDK_VERSION}/iframe/index.html?t=${Date.now()}`;
|
|
298
|
+
const iframe = document.createElement('iframe');
|
|
299
|
+
iframe.height = '0';
|
|
300
|
+
iframe.width = '0';
|
|
301
|
+
iframe.src = source;
|
|
302
|
+
iframe.addEventListener('load', this.configureIframe);
|
|
303
|
+
document.body.appendChild(iframe);
|
|
304
|
+
this.iframe = iframe;
|
|
305
|
+
}
|
|
306
|
+
configureIframe() {
|
|
307
|
+
const config = {
|
|
308
|
+
apiHost: this.apiHost,
|
|
309
|
+
apiKey: this.apiKey,
|
|
310
|
+
autoApprove: this.autoApprove,
|
|
311
|
+
chainId: this.chainId,
|
|
312
|
+
mpcHost: this.mpcHost,
|
|
313
|
+
rpcUrl: this.rpcUrl,
|
|
314
|
+
};
|
|
315
|
+
const message = {
|
|
316
|
+
type: 'portal:configure',
|
|
317
|
+
data: config
|
|
318
|
+
};
|
|
319
|
+
this.postMessage(message);
|
|
320
|
+
this.waitForReadyMessage();
|
|
321
|
+
}
|
|
322
|
+
getOrigin() {
|
|
323
|
+
const origin = this.webHost.startsWith('localhost:')
|
|
324
|
+
? `http://${this.webHost}`
|
|
325
|
+
: `https://${this.webHost}`;
|
|
326
|
+
return origin;
|
|
327
|
+
}
|
|
328
|
+
postMessage(event) {
|
|
329
|
+
var _a, _b, _c;
|
|
330
|
+
console.log(`[MpcProxy] Sending new message: `, event, (_a = this.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow);
|
|
331
|
+
(_c = (_b = this.iframe) === null || _b === void 0 ? void 0 : _b.contentWindow) === null || _c === void 0 ? void 0 : _c.postMessage(event, this.getOrigin());
|
|
332
|
+
}
|
|
333
|
+
waitForReadyMessage() {
|
|
334
|
+
const handleReady = (message) => __awaiter(this, void 0, void 0, function* () {
|
|
335
|
+
const { type, data } = message.data;
|
|
336
|
+
if (type === 'portal:wasm:ready' && data === true) {
|
|
337
|
+
// Unbind the event listener
|
|
338
|
+
window.removeEventListener('message', handleReady);
|
|
339
|
+
// Update ready state
|
|
340
|
+
this.portal.ready = true;
|
|
341
|
+
// Update the address
|
|
342
|
+
const address = yield this.getAddress();
|
|
343
|
+
this.portal.address = address;
|
|
344
|
+
// Trigger the ready callback
|
|
345
|
+
this.portal.triggerReady();
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
window.addEventListener('message', handleReady);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
export default Mpc;
|