@portal-hq/provider 4.1.1 → 4.1.3
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/providers/index.js +12 -11
- package/lib/commonjs/signers/mpc.js +157 -45
- package/lib/esm/providers/index.js +12 -11
- package/lib/esm/signers/mpc.js +154 -45
- package/package.json +6 -4
- package/src/providers/index.ts +1 -0
- package/src/signers/mpc.ts +183 -60
- package/types.d.ts +18 -2
|
@@ -74,6 +74,7 @@ class Provider {
|
|
|
74
74
|
mpcHost,
|
|
75
75
|
keychain,
|
|
76
76
|
version,
|
|
77
|
+
portalApi: this.portalApi,
|
|
77
78
|
featureFlags,
|
|
78
79
|
});
|
|
79
80
|
}
|
|
@@ -187,8 +188,8 @@ class Provider {
|
|
|
187
188
|
* @param args The arguments of the request being made
|
|
188
189
|
* @returns Promise<any>
|
|
189
190
|
*/
|
|
190
|
-
request(
|
|
191
|
-
return __awaiter(this,
|
|
191
|
+
request({ method, params, chainId, connect, }) {
|
|
192
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
192
193
|
chainId = chainId !== null && chainId !== void 0 ? chainId : this.chainId;
|
|
193
194
|
if (!chainId) {
|
|
194
195
|
throw new Error('[PortalProvider] No chainId provided');
|
|
@@ -320,8 +321,8 @@ class Provider {
|
|
|
320
321
|
*
|
|
321
322
|
* @param args The arguments of the request being made
|
|
322
323
|
*/
|
|
323
|
-
getApproval(
|
|
324
|
-
return __awaiter(this,
|
|
324
|
+
getApproval({ method, params, chainId, connect, }) {
|
|
325
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
325
326
|
// If autoApprove is enabled, just resolve to true
|
|
326
327
|
if (this.autoApprove) {
|
|
327
328
|
return true;
|
|
@@ -386,8 +387,8 @@ class Provider {
|
|
|
386
387
|
* @param args The arguments of the request being made
|
|
387
388
|
* @returns Promise<any>
|
|
388
389
|
*/
|
|
389
|
-
handleGatewayRequests(
|
|
390
|
-
return __awaiter(this,
|
|
390
|
+
handleGatewayRequests({ method, params, chainId, }) {
|
|
391
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
391
392
|
const gatewayUrl = this.getGatewayUrl(chainId);
|
|
392
393
|
// Pass request off to the gateway
|
|
393
394
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
@@ -407,9 +408,9 @@ class Provider {
|
|
|
407
408
|
* @param args The arguments of the request being made
|
|
408
409
|
* @returns Promise<any>
|
|
409
410
|
*/
|
|
410
|
-
handleSigningRequests(
|
|
411
|
-
|
|
412
|
-
|
|
411
|
+
handleSigningRequests({ method, params, chainId, connect, }) {
|
|
412
|
+
var _a, _b;
|
|
413
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
413
414
|
const isApproved = passiveSignerMethods.includes(method)
|
|
414
415
|
? true
|
|
415
416
|
: yield this.getApproval({ method, params, chainId, connect });
|
|
@@ -440,7 +441,7 @@ class Provider {
|
|
|
440
441
|
case 'sol_signAndSendTransaction':
|
|
441
442
|
case 'sol_signMessage':
|
|
442
443
|
case 'sol_signTransaction': {
|
|
443
|
-
const result = yield ((
|
|
444
|
+
const result = yield ((_a = this.signer) === null || _a === void 0 ? void 0 : _a.sign({
|
|
444
445
|
chainId: `${namespace}:${reference}`,
|
|
445
446
|
method,
|
|
446
447
|
params,
|
|
@@ -450,7 +451,7 @@ class Provider {
|
|
|
450
451
|
return result;
|
|
451
452
|
}
|
|
452
453
|
case 'raw_sign': {
|
|
453
|
-
const result = yield ((
|
|
454
|
+
const result = yield ((_b = this.signer) === null || _b === void 0 ? void 0 : _b.sign({
|
|
454
455
|
chainId: '',
|
|
455
456
|
method: '',
|
|
456
457
|
params,
|
|
@@ -8,12 +8,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
11
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
15
|
const core_1 = require("@portal-hq/core");
|
|
13
16
|
const utils_1 = require("@portal-hq/utils");
|
|
14
17
|
const react_native_1 = require("react-native");
|
|
18
|
+
const react_native_uuid_1 = __importDefault(require("react-native-uuid"));
|
|
19
|
+
var Operation;
|
|
20
|
+
(function (Operation) {
|
|
21
|
+
Operation["SIGN"] = "sign";
|
|
22
|
+
Operation["RAW_SIGN"] = "raw_sign";
|
|
23
|
+
})(Operation || (Operation = {}));
|
|
15
24
|
class MpcSigner {
|
|
16
|
-
constructor({ keychain, mpcHost = 'mpc.portalhq.io', version = 'v6', featureFlags = {}, }) {
|
|
25
|
+
constructor({ keychain, mpcHost = 'mpc.portalhq.io', version = 'v6', portalApi, featureFlags = {}, }) {
|
|
17
26
|
this.version = 'v6';
|
|
18
27
|
this.buildParams = (method, txParams) => {
|
|
19
28
|
let params = txParams;
|
|
@@ -44,61 +53,164 @@ class MpcSigner {
|
|
|
44
53
|
this.mpc = react_native_1.NativeModules.PortalMobileMpc;
|
|
45
54
|
this.mpcHost = mpcHost;
|
|
46
55
|
this.version = version;
|
|
56
|
+
this.portalApi = portalApi;
|
|
47
57
|
if (!this.mpc) {
|
|
48
58
|
throw new Error(`[Portal.Provider.MpcSigner] The MPC module could not be found by the signer. This is usually an issue with React Native linking. Please verify that the 'PortalReactNative' module is properly linked to this project.`);
|
|
49
59
|
}
|
|
50
60
|
}
|
|
51
61
|
sign(message, provider) {
|
|
52
62
|
return __awaiter(this, void 0, void 0, function* () {
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
let signingShare = shares.secp256k1.share;
|
|
66
|
-
if (curve === core_1.PortalCurve.ED25519) {
|
|
67
|
-
if (!shares.ed25519) {
|
|
68
|
-
throw new Error('[Portal.Provider.MpcSigner] The ED25519 share is missing from the keychain.');
|
|
69
|
-
}
|
|
70
|
-
signingShare = shares.ed25519.share;
|
|
71
|
-
}
|
|
72
|
-
const metadata = {
|
|
73
|
-
clientPlatform: 'REACT_NATIVE',
|
|
74
|
-
clientPlatformVersion: (0, utils_1.getClientPlatformVersion)(),
|
|
75
|
-
isMultiBackupEnabled: this.featureFlags.isMultiBackupEnabled,
|
|
76
|
-
mpcServerVersion: this.version,
|
|
77
|
-
optimized: true,
|
|
78
|
-
curve,
|
|
79
|
-
chainId,
|
|
80
|
-
isRaw,
|
|
63
|
+
// Always track metrics, but only send if feature flag is enabled
|
|
64
|
+
const shouldSendMetrics = this.featureFlags.enableSdkPerformanceMetrics === true;
|
|
65
|
+
const signStartTime = performance.now();
|
|
66
|
+
const preOperationStartTime = performance.now();
|
|
67
|
+
// Generate a traceId for this operation
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
69
|
+
const traceId = react_native_uuid_1.default.v4();
|
|
70
|
+
const metrics = {
|
|
71
|
+
hasError: false,
|
|
72
|
+
operation: Operation.SIGN,
|
|
73
|
+
signingMethod: message.method,
|
|
74
|
+
traceId,
|
|
81
75
|
};
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
76
|
+
try {
|
|
77
|
+
const eip155Address = yield this.keychain.getEip155Address();
|
|
78
|
+
const apiKey = provider.apiKey;
|
|
79
|
+
const { method, chainId, curve, isRaw } = message;
|
|
80
|
+
// Add chainId to metrics
|
|
81
|
+
if (chainId) {
|
|
82
|
+
metrics.chainId = chainId;
|
|
83
|
+
}
|
|
84
|
+
switch (method) {
|
|
85
|
+
case 'eth_requestAccounts':
|
|
86
|
+
return [eip155Address];
|
|
87
|
+
case 'eth_accounts':
|
|
88
|
+
return [eip155Address];
|
|
89
|
+
default:
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
const shares = yield this.keychain.getShares();
|
|
93
|
+
let signingShare = shares.secp256k1.share;
|
|
94
|
+
if (curve === core_1.PortalCurve.ED25519) {
|
|
95
|
+
if (!shares.ed25519) {
|
|
96
|
+
throw new Error('[Portal.Provider.MpcSigner] The ED25519 share is missing from the keychain.');
|
|
97
|
+
}
|
|
98
|
+
signingShare = shares.ed25519.share;
|
|
99
|
+
}
|
|
100
|
+
const metadata = {
|
|
101
|
+
clientPlatform: 'REACT_NATIVE',
|
|
102
|
+
clientPlatformVersion: (0, utils_1.getClientPlatformVersion)(),
|
|
103
|
+
isMultiBackupEnabled: this.featureFlags.isMultiBackupEnabled,
|
|
104
|
+
mpcServerVersion: this.version,
|
|
105
|
+
optimized: true,
|
|
106
|
+
curve,
|
|
107
|
+
chainId,
|
|
108
|
+
isRaw,
|
|
109
|
+
reqId: traceId,
|
|
110
|
+
connectionTracingEnabled: shouldSendMetrics,
|
|
111
|
+
};
|
|
112
|
+
const stringifiedMetadata = JSON.stringify(metadata);
|
|
113
|
+
let formattedParams;
|
|
114
|
+
let rpcUrl;
|
|
115
|
+
if (isRaw) {
|
|
116
|
+
formattedParams = this.buildParams(method, message.params);
|
|
117
|
+
rpcUrl = '';
|
|
118
|
+
metrics.operation = Operation.RAW_SIGN;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
formattedParams = JSON.stringify(this.buildParams(method, message.params));
|
|
122
|
+
rpcUrl = provider.getGatewayUrl(chainId);
|
|
123
|
+
}
|
|
124
|
+
if (typeof formattedParams !== 'string') {
|
|
125
|
+
throw new Error(`[Portal.Provider.MpcSigner] The formatted params for the signing request could not be converted to a string. The params were: ${formattedParams}`);
|
|
126
|
+
}
|
|
127
|
+
// Record pre-operation time
|
|
128
|
+
metrics.sdkPreOperationMs = performance.now() - preOperationStartTime;
|
|
129
|
+
// Measure MPC signing operation time
|
|
130
|
+
const mpcSignStartTime = performance.now();
|
|
131
|
+
const result = yield this.mpc.sign(apiKey, this.mpcHost, JSON.stringify(signingShare), message.method, formattedParams, rpcUrl, chainId, stringifiedMetadata);
|
|
132
|
+
// Post-operation processing time starts
|
|
133
|
+
const postOperationStartTime = performance.now();
|
|
134
|
+
// Record native call time
|
|
135
|
+
metrics.mpcNativeCallMs = performance.now() - mpcSignStartTime;
|
|
136
|
+
// Parse result and extract binary metrics if available
|
|
137
|
+
const parsedResponse = JSON.parse(String(result));
|
|
138
|
+
const { data, error, meta } = parsedResponse;
|
|
139
|
+
// Add binary metrics to our metrics object
|
|
140
|
+
if (meta === null || meta === void 0 ? void 0 : meta.metrics) {
|
|
141
|
+
const binaryMetrics = meta.metrics;
|
|
142
|
+
if (binaryMetrics.wsConnectDurationMs) {
|
|
143
|
+
metrics.sdkBinaryWSConnectMs = binaryMetrics.wsConnectDurationMs;
|
|
144
|
+
}
|
|
145
|
+
if (binaryMetrics.operationDurationMs) {
|
|
146
|
+
metrics.sdkBinaryOperationMs = binaryMetrics.operationDurationMs;
|
|
147
|
+
}
|
|
148
|
+
if (binaryMetrics.tlsHandshakeMs) {
|
|
149
|
+
metrics.sdkBinaryTlsHandshakeMs = binaryMetrics.tlsHandshakeMs;
|
|
150
|
+
}
|
|
151
|
+
if (binaryMetrics.firstResponseMs) {
|
|
152
|
+
metrics.sdkBinaryFirstResponseMs = binaryMetrics.firstResponseMs;
|
|
153
|
+
}
|
|
154
|
+
if (binaryMetrics.dnsLookupMs) {
|
|
155
|
+
metrics.sdkBinaryDnsLookupMs = binaryMetrics.dnsLookupMs;
|
|
156
|
+
}
|
|
157
|
+
if (binaryMetrics.connectMs) {
|
|
158
|
+
metrics.sdkBinaryConnectMs = binaryMetrics.connectMs;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if ((error === null || error === void 0 ? void 0 : error.code) > 0) {
|
|
162
|
+
throw new utils_1.PortalMpcError(error);
|
|
163
|
+
}
|
|
164
|
+
// Record post-operation time
|
|
165
|
+
metrics.sdkPostOperationMs = performance.now() - postOperationStartTime;
|
|
166
|
+
// Calculate total SDK signing time
|
|
167
|
+
metrics.sdkOperationMs = performance.now() - signStartTime;
|
|
168
|
+
// Only send metrics if the feature flag is enabled
|
|
169
|
+
if (shouldSendMetrics && this.portalApi) {
|
|
170
|
+
try {
|
|
171
|
+
yield this.sendMetrics(metrics, apiKey);
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
// No-op
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return data;
|
|
88
178
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
179
|
+
catch (error) {
|
|
180
|
+
// Calculate total time even in error case
|
|
181
|
+
metrics.sdkOperationMs = performance.now() - signStartTime;
|
|
182
|
+
// Only send metrics if the feature flag is enabled
|
|
183
|
+
if (shouldSendMetrics) {
|
|
184
|
+
const apiKey = provider.apiKey;
|
|
185
|
+
metrics.hasError = true;
|
|
186
|
+
try {
|
|
187
|
+
yield this.sendMetrics(metrics, apiKey);
|
|
188
|
+
}
|
|
189
|
+
catch (_a) {
|
|
190
|
+
// No-op
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
throw error;
|
|
92
194
|
}
|
|
93
|
-
|
|
94
|
-
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
// Add debug logs to sendMetrics method too
|
|
198
|
+
sendMetrics(metrics, apiKey) {
|
|
199
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
200
|
+
try {
|
|
201
|
+
if (this.portalApi) {
|
|
202
|
+
yield this.portalApi.post('/api/v3/clients/me/sdk/metrics', {
|
|
203
|
+
headers: {
|
|
204
|
+
Authorization: `Bearer ${apiKey}`,
|
|
205
|
+
'Content-Type': 'application/json',
|
|
206
|
+
},
|
|
207
|
+
body: metrics,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
95
210
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if (error && error.code > 0) {
|
|
99
|
-
throw new utils_1.PortalMpcError(error);
|
|
211
|
+
catch (_a) {
|
|
212
|
+
// No-op
|
|
100
213
|
}
|
|
101
|
-
return data;
|
|
102
214
|
});
|
|
103
215
|
}
|
|
104
216
|
}
|
|
@@ -72,6 +72,7 @@ class Provider {
|
|
|
72
72
|
mpcHost,
|
|
73
73
|
keychain,
|
|
74
74
|
version,
|
|
75
|
+
portalApi: this.portalApi,
|
|
75
76
|
featureFlags,
|
|
76
77
|
});
|
|
77
78
|
}
|
|
@@ -185,8 +186,8 @@ class Provider {
|
|
|
185
186
|
* @param args The arguments of the request being made
|
|
186
187
|
* @returns Promise<any>
|
|
187
188
|
*/
|
|
188
|
-
request(
|
|
189
|
-
return __awaiter(this,
|
|
189
|
+
request({ method, params, chainId, connect, }) {
|
|
190
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
190
191
|
chainId = chainId !== null && chainId !== void 0 ? chainId : this.chainId;
|
|
191
192
|
if (!chainId) {
|
|
192
193
|
throw new Error('[PortalProvider] No chainId provided');
|
|
@@ -318,8 +319,8 @@ class Provider {
|
|
|
318
319
|
*
|
|
319
320
|
* @param args The arguments of the request being made
|
|
320
321
|
*/
|
|
321
|
-
getApproval(
|
|
322
|
-
return __awaiter(this,
|
|
322
|
+
getApproval({ method, params, chainId, connect, }) {
|
|
323
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
323
324
|
// If autoApprove is enabled, just resolve to true
|
|
324
325
|
if (this.autoApprove) {
|
|
325
326
|
return true;
|
|
@@ -384,8 +385,8 @@ class Provider {
|
|
|
384
385
|
* @param args The arguments of the request being made
|
|
385
386
|
* @returns Promise<any>
|
|
386
387
|
*/
|
|
387
|
-
handleGatewayRequests(
|
|
388
|
-
return __awaiter(this,
|
|
388
|
+
handleGatewayRequests({ method, params, chainId, }) {
|
|
389
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
389
390
|
const gatewayUrl = this.getGatewayUrl(chainId);
|
|
390
391
|
// Pass request off to the gateway
|
|
391
392
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
@@ -405,9 +406,9 @@ class Provider {
|
|
|
405
406
|
* @param args The arguments of the request being made
|
|
406
407
|
* @returns Promise<any>
|
|
407
408
|
*/
|
|
408
|
-
handleSigningRequests(
|
|
409
|
-
|
|
410
|
-
|
|
409
|
+
handleSigningRequests({ method, params, chainId, connect, }) {
|
|
410
|
+
var _a, _b;
|
|
411
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
411
412
|
const isApproved = passiveSignerMethods.includes(method)
|
|
412
413
|
? true
|
|
413
414
|
: yield this.getApproval({ method, params, chainId, connect });
|
|
@@ -438,7 +439,7 @@ class Provider {
|
|
|
438
439
|
case 'sol_signAndSendTransaction':
|
|
439
440
|
case 'sol_signMessage':
|
|
440
441
|
case 'sol_signTransaction': {
|
|
441
|
-
const result = yield ((
|
|
442
|
+
const result = yield ((_a = this.signer) === null || _a === void 0 ? void 0 : _a.sign({
|
|
442
443
|
chainId: `${namespace}:${reference}`,
|
|
443
444
|
method,
|
|
444
445
|
params,
|
|
@@ -448,7 +449,7 @@ class Provider {
|
|
|
448
449
|
return result;
|
|
449
450
|
}
|
|
450
451
|
case 'raw_sign': {
|
|
451
|
-
const result = yield ((
|
|
452
|
+
const result = yield ((_b = this.signer) === null || _b === void 0 ? void 0 : _b.sign({
|
|
452
453
|
chainId: '',
|
|
453
454
|
method: '',
|
|
454
455
|
params,
|
package/lib/esm/signers/mpc.js
CHANGED
|
@@ -10,8 +10,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import { PortalCurve } from '@portal-hq/core';
|
|
11
11
|
import { PortalMpcError, getClientPlatformVersion, } from '@portal-hq/utils';
|
|
12
12
|
import { NativeModules } from 'react-native';
|
|
13
|
+
import UUID from 'react-native-uuid';
|
|
14
|
+
var Operation;
|
|
15
|
+
(function (Operation) {
|
|
16
|
+
Operation["SIGN"] = "sign";
|
|
17
|
+
Operation["RAW_SIGN"] = "raw_sign";
|
|
18
|
+
})(Operation || (Operation = {}));
|
|
13
19
|
class MpcSigner {
|
|
14
|
-
constructor({ keychain, mpcHost = 'mpc.portalhq.io', version = 'v6', featureFlags = {}, }) {
|
|
20
|
+
constructor({ keychain, mpcHost = 'mpc.portalhq.io', version = 'v6', portalApi, featureFlags = {}, }) {
|
|
15
21
|
this.version = 'v6';
|
|
16
22
|
this.buildParams = (method, txParams) => {
|
|
17
23
|
let params = txParams;
|
|
@@ -42,61 +48,164 @@ class MpcSigner {
|
|
|
42
48
|
this.mpc = NativeModules.PortalMobileMpc;
|
|
43
49
|
this.mpcHost = mpcHost;
|
|
44
50
|
this.version = version;
|
|
51
|
+
this.portalApi = portalApi;
|
|
45
52
|
if (!this.mpc) {
|
|
46
53
|
throw new Error(`[Portal.Provider.MpcSigner] The MPC module could not be found by the signer. This is usually an issue with React Native linking. Please verify that the 'PortalReactNative' module is properly linked to this project.`);
|
|
47
54
|
}
|
|
48
55
|
}
|
|
49
56
|
sign(message, provider) {
|
|
50
57
|
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
let signingShare = shares.secp256k1.share;
|
|
64
|
-
if (curve === PortalCurve.ED25519) {
|
|
65
|
-
if (!shares.ed25519) {
|
|
66
|
-
throw new Error('[Portal.Provider.MpcSigner] The ED25519 share is missing from the keychain.');
|
|
67
|
-
}
|
|
68
|
-
signingShare = shares.ed25519.share;
|
|
69
|
-
}
|
|
70
|
-
const metadata = {
|
|
71
|
-
clientPlatform: 'REACT_NATIVE',
|
|
72
|
-
clientPlatformVersion: getClientPlatformVersion(),
|
|
73
|
-
isMultiBackupEnabled: this.featureFlags.isMultiBackupEnabled,
|
|
74
|
-
mpcServerVersion: this.version,
|
|
75
|
-
optimized: true,
|
|
76
|
-
curve,
|
|
77
|
-
chainId,
|
|
78
|
-
isRaw,
|
|
58
|
+
// Always track metrics, but only send if feature flag is enabled
|
|
59
|
+
const shouldSendMetrics = this.featureFlags.enableSdkPerformanceMetrics === true;
|
|
60
|
+
const signStartTime = performance.now();
|
|
61
|
+
const preOperationStartTime = performance.now();
|
|
62
|
+
// Generate a traceId for this operation
|
|
63
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
64
|
+
const traceId = UUID.v4();
|
|
65
|
+
const metrics = {
|
|
66
|
+
hasError: false,
|
|
67
|
+
operation: Operation.SIGN,
|
|
68
|
+
signingMethod: message.method,
|
|
69
|
+
traceId,
|
|
79
70
|
};
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
71
|
+
try {
|
|
72
|
+
const eip155Address = yield this.keychain.getEip155Address();
|
|
73
|
+
const apiKey = provider.apiKey;
|
|
74
|
+
const { method, chainId, curve, isRaw } = message;
|
|
75
|
+
// Add chainId to metrics
|
|
76
|
+
if (chainId) {
|
|
77
|
+
metrics.chainId = chainId;
|
|
78
|
+
}
|
|
79
|
+
switch (method) {
|
|
80
|
+
case 'eth_requestAccounts':
|
|
81
|
+
return [eip155Address];
|
|
82
|
+
case 'eth_accounts':
|
|
83
|
+
return [eip155Address];
|
|
84
|
+
default:
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
const shares = yield this.keychain.getShares();
|
|
88
|
+
let signingShare = shares.secp256k1.share;
|
|
89
|
+
if (curve === PortalCurve.ED25519) {
|
|
90
|
+
if (!shares.ed25519) {
|
|
91
|
+
throw new Error('[Portal.Provider.MpcSigner] The ED25519 share is missing from the keychain.');
|
|
92
|
+
}
|
|
93
|
+
signingShare = shares.ed25519.share;
|
|
94
|
+
}
|
|
95
|
+
const metadata = {
|
|
96
|
+
clientPlatform: 'REACT_NATIVE',
|
|
97
|
+
clientPlatformVersion: getClientPlatformVersion(),
|
|
98
|
+
isMultiBackupEnabled: this.featureFlags.isMultiBackupEnabled,
|
|
99
|
+
mpcServerVersion: this.version,
|
|
100
|
+
optimized: true,
|
|
101
|
+
curve,
|
|
102
|
+
chainId,
|
|
103
|
+
isRaw,
|
|
104
|
+
reqId: traceId,
|
|
105
|
+
connectionTracingEnabled: shouldSendMetrics,
|
|
106
|
+
};
|
|
107
|
+
const stringifiedMetadata = JSON.stringify(metadata);
|
|
108
|
+
let formattedParams;
|
|
109
|
+
let rpcUrl;
|
|
110
|
+
if (isRaw) {
|
|
111
|
+
formattedParams = this.buildParams(method, message.params);
|
|
112
|
+
rpcUrl = '';
|
|
113
|
+
metrics.operation = Operation.RAW_SIGN;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
formattedParams = JSON.stringify(this.buildParams(method, message.params));
|
|
117
|
+
rpcUrl = provider.getGatewayUrl(chainId);
|
|
118
|
+
}
|
|
119
|
+
if (typeof formattedParams !== 'string') {
|
|
120
|
+
throw new Error(`[Portal.Provider.MpcSigner] The formatted params for the signing request could not be converted to a string. The params were: ${formattedParams}`);
|
|
121
|
+
}
|
|
122
|
+
// Record pre-operation time
|
|
123
|
+
metrics.sdkPreOperationMs = performance.now() - preOperationStartTime;
|
|
124
|
+
// Measure MPC signing operation time
|
|
125
|
+
const mpcSignStartTime = performance.now();
|
|
126
|
+
const result = yield this.mpc.sign(apiKey, this.mpcHost, JSON.stringify(signingShare), message.method, formattedParams, rpcUrl, chainId, stringifiedMetadata);
|
|
127
|
+
// Post-operation processing time starts
|
|
128
|
+
const postOperationStartTime = performance.now();
|
|
129
|
+
// Record native call time
|
|
130
|
+
metrics.mpcNativeCallMs = performance.now() - mpcSignStartTime;
|
|
131
|
+
// Parse result and extract binary metrics if available
|
|
132
|
+
const parsedResponse = JSON.parse(String(result));
|
|
133
|
+
const { data, error, meta } = parsedResponse;
|
|
134
|
+
// Add binary metrics to our metrics object
|
|
135
|
+
if (meta === null || meta === void 0 ? void 0 : meta.metrics) {
|
|
136
|
+
const binaryMetrics = meta.metrics;
|
|
137
|
+
if (binaryMetrics.wsConnectDurationMs) {
|
|
138
|
+
metrics.sdkBinaryWSConnectMs = binaryMetrics.wsConnectDurationMs;
|
|
139
|
+
}
|
|
140
|
+
if (binaryMetrics.operationDurationMs) {
|
|
141
|
+
metrics.sdkBinaryOperationMs = binaryMetrics.operationDurationMs;
|
|
142
|
+
}
|
|
143
|
+
if (binaryMetrics.tlsHandshakeMs) {
|
|
144
|
+
metrics.sdkBinaryTlsHandshakeMs = binaryMetrics.tlsHandshakeMs;
|
|
145
|
+
}
|
|
146
|
+
if (binaryMetrics.firstResponseMs) {
|
|
147
|
+
metrics.sdkBinaryFirstResponseMs = binaryMetrics.firstResponseMs;
|
|
148
|
+
}
|
|
149
|
+
if (binaryMetrics.dnsLookupMs) {
|
|
150
|
+
metrics.sdkBinaryDnsLookupMs = binaryMetrics.dnsLookupMs;
|
|
151
|
+
}
|
|
152
|
+
if (binaryMetrics.connectMs) {
|
|
153
|
+
metrics.sdkBinaryConnectMs = binaryMetrics.connectMs;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if ((error === null || error === void 0 ? void 0 : error.code) > 0) {
|
|
157
|
+
throw new PortalMpcError(error);
|
|
158
|
+
}
|
|
159
|
+
// Record post-operation time
|
|
160
|
+
metrics.sdkPostOperationMs = performance.now() - postOperationStartTime;
|
|
161
|
+
// Calculate total SDK signing time
|
|
162
|
+
metrics.sdkOperationMs = performance.now() - signStartTime;
|
|
163
|
+
// Only send metrics if the feature flag is enabled
|
|
164
|
+
if (shouldSendMetrics && this.portalApi) {
|
|
165
|
+
try {
|
|
166
|
+
yield this.sendMetrics(metrics, apiKey);
|
|
167
|
+
}
|
|
168
|
+
catch (err) {
|
|
169
|
+
// No-op
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return data;
|
|
86
173
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
174
|
+
catch (error) {
|
|
175
|
+
// Calculate total time even in error case
|
|
176
|
+
metrics.sdkOperationMs = performance.now() - signStartTime;
|
|
177
|
+
// Only send metrics if the feature flag is enabled
|
|
178
|
+
if (shouldSendMetrics) {
|
|
179
|
+
const apiKey = provider.apiKey;
|
|
180
|
+
metrics.hasError = true;
|
|
181
|
+
try {
|
|
182
|
+
yield this.sendMetrics(metrics, apiKey);
|
|
183
|
+
}
|
|
184
|
+
catch (_a) {
|
|
185
|
+
// No-op
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
throw error;
|
|
90
189
|
}
|
|
91
|
-
|
|
92
|
-
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
// Add debug logs to sendMetrics method too
|
|
193
|
+
sendMetrics(metrics, apiKey) {
|
|
194
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
195
|
+
try {
|
|
196
|
+
if (this.portalApi) {
|
|
197
|
+
yield this.portalApi.post('/api/v3/clients/me/sdk/metrics', {
|
|
198
|
+
headers: {
|
|
199
|
+
Authorization: `Bearer ${apiKey}`,
|
|
200
|
+
'Content-Type': 'application/json',
|
|
201
|
+
},
|
|
202
|
+
body: metrics,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
93
205
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (error && error.code > 0) {
|
|
97
|
-
throw new PortalMpcError(error);
|
|
206
|
+
catch (_a) {
|
|
207
|
+
// No-op
|
|
98
208
|
}
|
|
99
|
-
return data;
|
|
100
209
|
});
|
|
101
210
|
}
|
|
102
211
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@portal-hq/provider",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/esm/index",
|
|
@@ -19,8 +19,10 @@
|
|
|
19
19
|
"test": "jest"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@portal-hq/connect": "^4.1.
|
|
23
|
-
"@portal-hq/utils": "^4.1.
|
|
22
|
+
"@portal-hq/connect": "^4.1.3",
|
|
23
|
+
"@portal-hq/utils": "^4.1.3",
|
|
24
|
+
"@types/react-native-uuid": "^2.0.0",
|
|
25
|
+
"react-native-uuid": "^2.0.3"
|
|
24
26
|
},
|
|
25
27
|
"devDependencies": {
|
|
26
28
|
"@babel/preset-typescript": "^7.18.6",
|
|
@@ -30,5 +32,5 @@
|
|
|
30
32
|
"ts-jest": "^29.0.3",
|
|
31
33
|
"typescript": "^4.8.4"
|
|
32
34
|
},
|
|
33
|
-
"gitHead": "
|
|
35
|
+
"gitHead": "912b03f1152f4dbb7e017919c63bdc950ca867cf"
|
|
34
36
|
}
|
package/src/providers/index.ts
CHANGED
package/src/signers/mpc.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { PortalCurve } from '@portal-hq/core'
|
|
2
2
|
import { FeatureFlags } from '@portal-hq/core/types'
|
|
3
3
|
import {
|
|
4
|
+
HttpRequester,
|
|
4
5
|
IPortalProvider,
|
|
5
6
|
KeychainAdapter,
|
|
6
7
|
PortalMpcError,
|
|
@@ -8,6 +9,7 @@ import {
|
|
|
8
9
|
getClientPlatformVersion,
|
|
9
10
|
} from '@portal-hq/utils'
|
|
10
11
|
import { NativeModules } from 'react-native'
|
|
12
|
+
import UUID from 'react-native-uuid'
|
|
11
13
|
|
|
12
14
|
import {
|
|
13
15
|
type MpcSignerOptions,
|
|
@@ -17,17 +19,24 @@ import {
|
|
|
17
19
|
} from '../../types'
|
|
18
20
|
import Signer from './abstract'
|
|
19
21
|
|
|
22
|
+
enum Operation {
|
|
23
|
+
SIGN = 'sign',
|
|
24
|
+
RAW_SIGN = 'raw_sign',
|
|
25
|
+
}
|
|
26
|
+
|
|
20
27
|
class MpcSigner implements Signer {
|
|
21
28
|
private featureFlags: FeatureFlags
|
|
22
29
|
private keychain: KeychainAdapter
|
|
23
30
|
private mpc: PortalMobileMpc
|
|
24
|
-
private mpcHost: string
|
|
31
|
+
private mpcHost: string
|
|
25
32
|
private version = 'v6'
|
|
33
|
+
private portalApi?: HttpRequester
|
|
26
34
|
|
|
27
35
|
constructor({
|
|
28
36
|
keychain,
|
|
29
37
|
mpcHost = 'mpc.portalhq.io',
|
|
30
38
|
version = 'v6',
|
|
39
|
+
portalApi,
|
|
31
40
|
featureFlags = {},
|
|
32
41
|
}: MpcSignerOptions) {
|
|
33
42
|
this.featureFlags = featureFlags
|
|
@@ -35,6 +44,7 @@ class MpcSigner implements Signer {
|
|
|
35
44
|
this.mpc = NativeModules.PortalMobileMpc
|
|
36
45
|
this.mpcHost = mpcHost
|
|
37
46
|
this.version = version
|
|
47
|
+
this.portalApi = portalApi
|
|
38
48
|
|
|
39
49
|
if (!this.mpc) {
|
|
40
50
|
throw new Error(
|
|
@@ -47,82 +57,195 @@ class MpcSigner implements Signer {
|
|
|
47
57
|
message: SigningRequestArguments,
|
|
48
58
|
provider: IPortalProvider,
|
|
49
59
|
): Promise<any> {
|
|
50
|
-
|
|
60
|
+
// Always track metrics, but only send if feature flag is enabled
|
|
61
|
+
const shouldSendMetrics =
|
|
62
|
+
this.featureFlags.enableSdkPerformanceMetrics === true
|
|
63
|
+
const signStartTime = performance.now()
|
|
64
|
+
const preOperationStartTime = performance.now()
|
|
65
|
+
// Generate a traceId for this operation
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
67
|
+
const traceId = (UUID as any).v4() as string
|
|
68
|
+
const metrics: Record<string, number | string | boolean> = {
|
|
69
|
+
hasError: false,
|
|
70
|
+
operation: Operation.SIGN,
|
|
71
|
+
signingMethod: message.method,
|
|
72
|
+
traceId,
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
const eip155Address = await this.keychain.getEip155Address()
|
|
51
76
|
|
|
52
|
-
|
|
77
|
+
const apiKey = provider.apiKey
|
|
53
78
|
|
|
54
|
-
|
|
79
|
+
const { method, chainId, curve, isRaw } = message
|
|
80
|
+
// Add chainId to metrics
|
|
81
|
+
if (chainId) {
|
|
82
|
+
metrics.chainId = chainId
|
|
83
|
+
}
|
|
55
84
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
85
|
+
switch (method) {
|
|
86
|
+
case 'eth_requestAccounts':
|
|
87
|
+
return [eip155Address]
|
|
88
|
+
case 'eth_accounts':
|
|
89
|
+
return [eip155Address]
|
|
90
|
+
default:
|
|
91
|
+
break
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const shares = await this.keychain.getShares()
|
|
64
95
|
|
|
65
|
-
|
|
96
|
+
let signingShare = shares.secp256k1.share
|
|
66
97
|
|
|
67
|
-
|
|
98
|
+
if (curve === PortalCurve.ED25519) {
|
|
99
|
+
if (!shares.ed25519) {
|
|
100
|
+
throw new Error(
|
|
101
|
+
'[Portal.Provider.MpcSigner] The ED25519 share is missing from the keychain.',
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
signingShare = shares.ed25519.share
|
|
105
|
+
}
|
|
68
106
|
|
|
69
|
-
|
|
70
|
-
|
|
107
|
+
const metadata: PortalMobileMpcMetadata = {
|
|
108
|
+
clientPlatform: 'REACT_NATIVE',
|
|
109
|
+
clientPlatformVersion: getClientPlatformVersion(),
|
|
110
|
+
isMultiBackupEnabled: this.featureFlags.isMultiBackupEnabled,
|
|
111
|
+
mpcServerVersion: this.version,
|
|
112
|
+
optimized: true,
|
|
113
|
+
curve,
|
|
114
|
+
chainId,
|
|
115
|
+
isRaw,
|
|
116
|
+
reqId: traceId,
|
|
117
|
+
connectionTracingEnabled: shouldSendMetrics,
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const stringifiedMetadata = JSON.stringify(metadata)
|
|
121
|
+
|
|
122
|
+
let formattedParams: string
|
|
123
|
+
let rpcUrl: string
|
|
124
|
+
|
|
125
|
+
if (isRaw) {
|
|
126
|
+
formattedParams = this.buildParams(method, message.params)
|
|
127
|
+
rpcUrl = ''
|
|
128
|
+
metrics.operation = Operation.RAW_SIGN
|
|
129
|
+
} else {
|
|
130
|
+
formattedParams = JSON.stringify(
|
|
131
|
+
this.buildParams(method, message.params),
|
|
132
|
+
)
|
|
133
|
+
rpcUrl = provider.getGatewayUrl(chainId)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (typeof formattedParams !== 'string') {
|
|
71
137
|
throw new Error(
|
|
72
|
-
|
|
138
|
+
`[Portal.Provider.MpcSigner] The formatted params for the signing request could not be converted to a string. The params were: ${formattedParams}`,
|
|
73
139
|
)
|
|
74
140
|
}
|
|
75
|
-
signingShare = shares.ed25519.share
|
|
76
|
-
}
|
|
77
141
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
clientPlatformVersion: getClientPlatformVersion(),
|
|
81
|
-
isMultiBackupEnabled: this.featureFlags.isMultiBackupEnabled,
|
|
82
|
-
mpcServerVersion: this.version,
|
|
83
|
-
optimized: true,
|
|
84
|
-
curve,
|
|
85
|
-
chainId,
|
|
86
|
-
isRaw,
|
|
87
|
-
}
|
|
142
|
+
// Record pre-operation time
|
|
143
|
+
metrics.sdkPreOperationMs = performance.now() - preOperationStartTime
|
|
88
144
|
|
|
89
|
-
|
|
145
|
+
// Measure MPC signing operation time
|
|
146
|
+
const mpcSignStartTime = performance.now()
|
|
90
147
|
|
|
91
|
-
|
|
92
|
-
|
|
148
|
+
const result = await this.mpc.sign(
|
|
149
|
+
apiKey,
|
|
150
|
+
this.mpcHost,
|
|
151
|
+
JSON.stringify(signingShare),
|
|
152
|
+
message.method,
|
|
153
|
+
formattedParams,
|
|
154
|
+
rpcUrl,
|
|
155
|
+
chainId,
|
|
156
|
+
stringifiedMetadata,
|
|
157
|
+
)
|
|
93
158
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
rpcUrl = ''
|
|
97
|
-
} else {
|
|
98
|
-
formattedParams = JSON.stringify(this.buildParams(method, message.params))
|
|
99
|
-
rpcUrl = provider.getGatewayUrl(chainId)
|
|
100
|
-
}
|
|
159
|
+
// Post-operation processing time starts
|
|
160
|
+
const postOperationStartTime = performance.now()
|
|
101
161
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
162
|
+
// Record native call time
|
|
163
|
+
metrics.mpcNativeCallMs = performance.now() - mpcSignStartTime
|
|
164
|
+
|
|
165
|
+
// Parse result and extract binary metrics if available
|
|
166
|
+
const parsedResponse = JSON.parse(String(result)) as SigningResponse
|
|
167
|
+
const { data, error, meta } = parsedResponse
|
|
168
|
+
|
|
169
|
+
// Add binary metrics to our metrics object
|
|
170
|
+
if (meta?.metrics) {
|
|
171
|
+
const binaryMetrics = meta.metrics
|
|
172
|
+
if (binaryMetrics.wsConnectDurationMs) {
|
|
173
|
+
metrics.sdkBinaryWSConnectMs = binaryMetrics.wsConnectDurationMs
|
|
174
|
+
}
|
|
175
|
+
if (binaryMetrics.operationDurationMs) {
|
|
176
|
+
metrics.sdkBinaryOperationMs = binaryMetrics.operationDurationMs
|
|
177
|
+
}
|
|
178
|
+
if (binaryMetrics.tlsHandshakeMs) {
|
|
179
|
+
metrics.sdkBinaryTlsHandshakeMs = binaryMetrics.tlsHandshakeMs
|
|
180
|
+
}
|
|
181
|
+
if (binaryMetrics.firstResponseMs) {
|
|
182
|
+
metrics.sdkBinaryFirstResponseMs = binaryMetrics.firstResponseMs
|
|
183
|
+
}
|
|
184
|
+
if (binaryMetrics.dnsLookupMs) {
|
|
185
|
+
metrics.sdkBinaryDnsLookupMs = binaryMetrics.dnsLookupMs
|
|
186
|
+
}
|
|
187
|
+
if (binaryMetrics.connectMs) {
|
|
188
|
+
metrics.sdkBinaryConnectMs = binaryMetrics.connectMs
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (error?.code > 0) {
|
|
193
|
+
throw new PortalMpcError(error)
|
|
194
|
+
}
|
|
107
195
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
196
|
+
// Record post-operation time
|
|
197
|
+
metrics.sdkPostOperationMs = performance.now() - postOperationStartTime
|
|
198
|
+
|
|
199
|
+
// Calculate total SDK signing time
|
|
200
|
+
metrics.sdkOperationMs = performance.now() - signStartTime
|
|
201
|
+
|
|
202
|
+
// Only send metrics if the feature flag is enabled
|
|
203
|
+
if (shouldSendMetrics && this.portalApi) {
|
|
204
|
+
try {
|
|
205
|
+
await this.sendMetrics(metrics, apiKey)
|
|
206
|
+
} catch (err) {
|
|
207
|
+
// No-op
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return data
|
|
212
|
+
} catch (error) {
|
|
213
|
+
// Calculate total time even in error case
|
|
214
|
+
metrics.sdkOperationMs = performance.now() - signStartTime
|
|
215
|
+
|
|
216
|
+
// Only send metrics if the feature flag is enabled
|
|
217
|
+
if (shouldSendMetrics) {
|
|
218
|
+
const apiKey = provider.apiKey
|
|
219
|
+
metrics.hasError = true
|
|
220
|
+
try {
|
|
221
|
+
await this.sendMetrics(metrics, apiKey)
|
|
222
|
+
} catch {
|
|
223
|
+
// No-op
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
throw error
|
|
123
228
|
}
|
|
229
|
+
}
|
|
124
230
|
|
|
125
|
-
|
|
231
|
+
// Add debug logs to sendMetrics method too
|
|
232
|
+
private async sendMetrics(
|
|
233
|
+
metrics: Record<string, number | string | boolean>,
|
|
234
|
+
apiKey: string,
|
|
235
|
+
): Promise<void> {
|
|
236
|
+
try {
|
|
237
|
+
if (this.portalApi) {
|
|
238
|
+
await this.portalApi.post('/api/v3/clients/me/sdk/metrics', {
|
|
239
|
+
headers: {
|
|
240
|
+
Authorization: `Bearer ${apiKey}`,
|
|
241
|
+
'Content-Type': 'application/json',
|
|
242
|
+
},
|
|
243
|
+
body: metrics,
|
|
244
|
+
})
|
|
245
|
+
}
|
|
246
|
+
} catch {
|
|
247
|
+
// No-op
|
|
248
|
+
}
|
|
126
249
|
}
|
|
127
250
|
|
|
128
251
|
private buildParams = (method: string, txParams: any) => {
|
package/types.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
// Types
|
|
2
2
|
import PortalConnect from '@portal-hq/connect'
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import {
|
|
4
|
+
KeychainAdapter,
|
|
5
|
+
type PortalError,
|
|
6
|
+
HttpRequester,
|
|
7
|
+
} from '@portal-hq/utils'
|
|
5
8
|
|
|
6
9
|
export type EventHandler = (data: any) => void
|
|
7
10
|
|
|
@@ -21,6 +24,7 @@ export interface MpcSignerOptions extends SignerOptions {
|
|
|
21
24
|
// Optional
|
|
22
25
|
isSimulator?: boolean
|
|
23
26
|
mpcHost?: string
|
|
27
|
+
portalApi?: HttpRequester
|
|
24
28
|
version?: string
|
|
25
29
|
featureFlags?: FeatureFlags
|
|
26
30
|
}
|
|
@@ -41,6 +45,8 @@ export interface PortalMobileMpcMetadata {
|
|
|
41
45
|
mpcServerVersion: string
|
|
42
46
|
optimized: true
|
|
43
47
|
isRaw?: boolean
|
|
48
|
+
reqId?: string
|
|
49
|
+
connectionTracingEnabled?: boolean
|
|
44
50
|
}
|
|
45
51
|
|
|
46
52
|
export interface PortalMobileMpc {
|
|
@@ -120,6 +126,16 @@ export type SigningRequestParams = Eip1559 | LegacyTx
|
|
|
120
126
|
export interface SigningResponse {
|
|
121
127
|
data: string
|
|
122
128
|
error: PortalError
|
|
129
|
+
meta?: {
|
|
130
|
+
metrics?: {
|
|
131
|
+
wsConnectDurationMs?: number
|
|
132
|
+
operationDurationMs?: number
|
|
133
|
+
tlsHandshakeMs?: number
|
|
134
|
+
firstResponseMs?: number
|
|
135
|
+
dnsLookupMs?: number
|
|
136
|
+
connectMs?: number
|
|
137
|
+
}
|
|
138
|
+
}
|
|
123
139
|
}
|
|
124
140
|
|
|
125
141
|
export interface SwitchEthereumChainParameter {
|