@metamask/connect-multichain 0.12.1 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -1
- package/dist/browser/es/connect-multichain.d.mts +46 -2
- package/dist/browser/es/connect-multichain.mjs +1733 -1566
- package/dist/browser/es/connect-multichain.mjs.map +1 -1
- package/dist/browser/es/metafile-esm.json +1 -1
- package/dist/browser/iife/connect-multichain.d.ts +46 -2
- package/dist/browser/iife/connect-multichain.js +6279 -5413
- package/dist/browser/iife/connect-multichain.js.map +1 -1
- package/dist/browser/iife/metafile-iife.json +1 -1
- package/dist/browser/umd/connect-multichain.d.ts +46 -2
- package/dist/browser/umd/connect-multichain.js +1761 -1589
- package/dist/browser/umd/connect-multichain.js.map +1 -1
- package/dist/browser/umd/metafile-cjs.json +1 -1
- package/dist/node/cjs/connect-multichain.d.ts +46 -2
- package/dist/node/cjs/connect-multichain.js +892 -719
- package/dist/node/cjs/connect-multichain.js.map +1 -1
- package/dist/node/cjs/metafile-cjs.json +1 -1
- package/dist/node/es/connect-multichain.d.mts +46 -2
- package/dist/node/es/connect-multichain.mjs +890 -723
- package/dist/node/es/connect-multichain.mjs.map +1 -1
- package/dist/node/es/metafile-esm.json +1 -1
- package/dist/react-native/es/connect-multichain.d.mts +46 -2
- package/dist/react-native/es/connect-multichain.mjs +890 -723
- package/dist/react-native/es/connect-multichain.mjs.map +1 -1
- package/dist/react-native/es/metafile-esm.json +1 -1
- package/dist/src/domain/multichain/index.d.ts +1 -1
- package/dist/src/domain/multichain/index.d.ts.map +1 -1
- package/dist/src/domain/utils/index.d.ts +2 -1
- package/dist/src/domain/utils/index.d.ts.map +1 -1
- package/dist/src/domain/utils/index.js +1 -1
- package/dist/src/domain/utils/index.js.map +1 -1
- package/dist/src/multichain/index.d.ts +2 -2
- package/dist/src/multichain/index.d.ts.map +1 -1
- package/dist/src/multichain/index.js +39 -25
- package/dist/src/multichain/index.js.map +1 -1
- package/dist/src/multichain/rpc/requestRouter.d.ts.map +1 -1
- package/dist/src/multichain/rpc/requestRouter.js +4 -4
- package/dist/src/multichain/rpc/requestRouter.js.map +1 -1
- package/dist/src/multichain/transports/multichainApiClientWrapper/index.d.ts +1 -0
- package/dist/src/multichain/transports/multichainApiClientWrapper/index.d.ts.map +1 -1
- package/dist/src/multichain/transports/multichainApiClientWrapper/index.js +10 -10
- package/dist/src/multichain/transports/multichainApiClientWrapper/index.js.map +1 -1
- package/dist/src/multichain/transports/mwp/KeyManager.d.ts +12 -9
- package/dist/src/multichain/transports/mwp/KeyManager.d.ts.map +1 -1
- package/dist/src/multichain/transports/mwp/KeyManager.js +38 -25
- package/dist/src/multichain/transports/mwp/KeyManager.js.map +1 -1
- package/dist/src/multichain/transports/mwp/index.d.ts.map +1 -1
- package/dist/src/multichain/transports/mwp/index.js +18 -6
- package/dist/src/multichain/transports/mwp/index.js.map +1 -1
- package/dist/src/multichain/utils/analytics.d.ts +82 -1
- package/dist/src/multichain/utils/analytics.d.ts.map +1 -1
- package/dist/src/multichain/utils/analytics.js +252 -17
- package/dist/src/multichain/utils/analytics.js.map +1 -1
- package/dist/types/connect-multichain.d.ts +46 -2
- package/package.json +2 -2
|
@@ -967,17 +967,94 @@ var init_utils = __esm({
|
|
|
967
967
|
});
|
|
968
968
|
|
|
969
969
|
// src/multichain/utils/analytics.ts
|
|
970
|
+
function sanitiseErrorMessage(message) {
|
|
971
|
+
if (!message) {
|
|
972
|
+
return void 0;
|
|
973
|
+
}
|
|
974
|
+
let sanitised = message;
|
|
975
|
+
for (const { pattern, replacement } of SANITISE_PATTERNS) {
|
|
976
|
+
sanitised = sanitised.replace(pattern, replacement);
|
|
977
|
+
}
|
|
978
|
+
if (sanitised.length > ERROR_MESSAGE_SAMPLE_MAX_LENGTH) {
|
|
979
|
+
sanitised = `${sanitised.slice(0, ERROR_MESSAGE_SAMPLE_MAX_LENGTH - 1)}\u2026`;
|
|
980
|
+
}
|
|
981
|
+
return sanitised;
|
|
982
|
+
}
|
|
983
|
+
function getUnwrappedErrorDetails(error) {
|
|
984
|
+
var _a2, _b, _c, _d;
|
|
985
|
+
if (typeof error !== "object" || error === null) {
|
|
986
|
+
return { code: void 0, message: "" };
|
|
987
|
+
}
|
|
988
|
+
if (error instanceof RPCInvokeMethodErr) {
|
|
989
|
+
return {
|
|
990
|
+
code: (_a2 = error.rpcCode) != null ? _a2 : error.code,
|
|
991
|
+
message: (_c = (_b = error.rpcMessage) != null ? _b : error.message) != null ? _c : ""
|
|
992
|
+
};
|
|
993
|
+
}
|
|
994
|
+
const errorObj = error;
|
|
995
|
+
return {
|
|
996
|
+
code: errorObj.code,
|
|
997
|
+
message: (_d = errorObj.message) != null ? _d : ""
|
|
998
|
+
};
|
|
999
|
+
}
|
|
970
1000
|
function isRejectionError(error) {
|
|
971
|
-
var _a2, _b;
|
|
972
1001
|
if (typeof error !== "object" || error === null) {
|
|
973
1002
|
return false;
|
|
974
1003
|
}
|
|
1004
|
+
const { code, message } = getUnwrappedErrorDetails(error);
|
|
1005
|
+
const errorMessage = message.toLowerCase();
|
|
1006
|
+
return code === 4001 || errorMessage.includes("reject") || errorMessage.includes("denied") || errorMessage.includes("cancel") || // Narrow "user …" matches — bare "user" is too greedy (catches Account
|
|
1007
|
+
// Abstraction errors like "user operation reverted").
|
|
1008
|
+
errorMessage.includes("user rejected") || errorMessage.includes("user denied") || errorMessage.includes("user cancelled") || errorMessage.includes("user canceled");
|
|
1009
|
+
}
|
|
1010
|
+
function classifyFailureReason(error) {
|
|
1011
|
+
var _a2, _b;
|
|
1012
|
+
if (typeof error !== "object" || error === null) {
|
|
1013
|
+
return "unknown";
|
|
1014
|
+
}
|
|
975
1015
|
const errorObj = error;
|
|
976
|
-
const
|
|
977
|
-
const
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
1016
|
+
const errorName = (_a2 = errorObj.name) != null ? _a2 : "";
|
|
1017
|
+
const errorMessageRaw = (_b = errorObj.message) != null ? _b : "";
|
|
1018
|
+
const errorMessage = errorMessageRaw.toLowerCase();
|
|
1019
|
+
const { code } = getUnwrappedErrorDetails(error);
|
|
1020
|
+
if (typeof code === "number") {
|
|
1021
|
+
if (code === -32601) {
|
|
1022
|
+
return "wallet_method_unsupported";
|
|
1023
|
+
}
|
|
1024
|
+
if (code === -32602) {
|
|
1025
|
+
return "wallet_invalid_params";
|
|
1026
|
+
}
|
|
1027
|
+
if (code === -32603) {
|
|
1028
|
+
return "wallet_internal_error";
|
|
1029
|
+
}
|
|
1030
|
+
if (code <= -32e3 && code >= -32099) {
|
|
1031
|
+
return "wallet_internal_error";
|
|
1032
|
+
}
|
|
1033
|
+
if (code === 4100) {
|
|
1034
|
+
return "wallet_unauthorized";
|
|
1035
|
+
}
|
|
1036
|
+
if (code === 4200) {
|
|
1037
|
+
return "wallet_method_unsupported";
|
|
1038
|
+
}
|
|
1039
|
+
if (code === 4902) {
|
|
1040
|
+
return "unrecognized_chain";
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
if (errorName === "TransportTimeoutError" || errorMessageRaw === "Request timeout" || errorMessage.includes("timed out") || errorMessage.includes("timeout")) {
|
|
1044
|
+
return "transport_timeout";
|
|
1045
|
+
}
|
|
1046
|
+
if (errorName === "TransportError" || errorMessage.includes("not connected") || errorMessage.includes("transport disconnect") || errorMessage.includes("connection lost") || errorMessage.includes("socket closed")) {
|
|
1047
|
+
return "transport_disconnect";
|
|
1048
|
+
}
|
|
1049
|
+
return "unknown";
|
|
1050
|
+
}
|
|
1051
|
+
function extractErrorDiagnostics(error) {
|
|
1052
|
+
const failureReason = classifyFailureReason(error);
|
|
1053
|
+
const { code, message } = getUnwrappedErrorDetails(error);
|
|
1054
|
+
const messageSample = sanitiseErrorMessage(message);
|
|
1055
|
+
return __spreadValues(__spreadValues({
|
|
1056
|
+
failure_reason: failureReason
|
|
1057
|
+
}, typeof code === "number" ? { error_code: code } : {}), messageSample ? { error_message_sample: messageSample } : {});
|
|
981
1058
|
}
|
|
982
1059
|
function getBaseAnalyticsProperties(options, storage) {
|
|
983
1060
|
return __async(this, null, function* () {
|
|
@@ -993,26 +1070,61 @@ function getBaseAnalyticsProperties(options, storage) {
|
|
|
993
1070
|
};
|
|
994
1071
|
});
|
|
995
1072
|
}
|
|
996
|
-
function getWalletActionAnalyticsProperties(options, storage, invokeOptions, transportType) {
|
|
1073
|
+
function getWalletActionAnalyticsProperties(options, storage, invokeOptions, transportType, extra) {
|
|
997
1074
|
return __async(this, null, function* () {
|
|
998
1075
|
var _a2;
|
|
999
1076
|
const dappId = getDappId(options.dapp);
|
|
1000
1077
|
const anonId = yield storage.getAnonId();
|
|
1001
|
-
return {
|
|
1078
|
+
return __spreadValues(__spreadValues(__spreadValues({
|
|
1002
1079
|
mmconnect_versions: (_a2 = options.versions) != null ? _a2 : {},
|
|
1003
1080
|
dapp_id: dappId,
|
|
1004
1081
|
method: invokeOptions.request.method,
|
|
1005
1082
|
caip_chain_id: invokeOptions.scope,
|
|
1006
1083
|
anon_id: anonId,
|
|
1007
1084
|
transport_type: transportType
|
|
1008
|
-
};
|
|
1085
|
+
}, (extra == null ? void 0 : extra.failure_reason) ? { failure_reason: extra.failure_reason } : {}), typeof (extra == null ? void 0 : extra.error_code) === "number" ? { error_code: extra.error_code } : {}), (extra == null ? void 0 : extra.error_message_sample) ? { error_message_sample: extra.error_message_sample } : {});
|
|
1009
1086
|
});
|
|
1010
1087
|
}
|
|
1088
|
+
var ERROR_MESSAGE_SAMPLE_MAX_LENGTH, SANITISE_PATTERNS;
|
|
1011
1089
|
var init_analytics = __esm({
|
|
1012
1090
|
"src/multichain/utils/analytics.ts"() {
|
|
1013
1091
|
"use strict";
|
|
1014
1092
|
init_utils();
|
|
1015
1093
|
init_domain();
|
|
1094
|
+
ERROR_MESSAGE_SAMPLE_MAX_LENGTH = 200;
|
|
1095
|
+
SANITISE_PATTERNS = [
|
|
1096
|
+
// EVM-style 20-byte hex addresses (e.g. `0x` + 40 hex chars).
|
|
1097
|
+
{ pattern: /0x[a-fA-F0-9]{40}/gu, replacement: "<addr>" },
|
|
1098
|
+
// Other long hex blobs: tx hashes, signatures, raw byte strings, large
|
|
1099
|
+
// hex amounts. 16+ hex chars catches 32-byte hashes/signatures without
|
|
1100
|
+
// snagging EVM method selectors (8 chars) or short hex codes.
|
|
1101
|
+
{ pattern: /(?:0x)?[a-fA-F0-9]{16,}/gu, replacement: "<hex>" },
|
|
1102
|
+
// URLs of any scheme up to the first whitespace / quote / closing paren.
|
|
1103
|
+
// Catches RPC endpoints, dapp deeplinks, query strings with secrets.
|
|
1104
|
+
{ pattern: /https?:\/\/[^\s"')]+/gu, replacement: "<url>" },
|
|
1105
|
+
// Bech32 addresses: short HRP (1-10 lowercase chars) + `1` separator +
|
|
1106
|
+
// ≥38 chars of Bech32 data alphabet `[ac-hj-np-z02-9]` (excludes the
|
|
1107
|
+
// look-alike chars `b`, `i`, `o`, `1`). Covers Bitcoin SegWit
|
|
1108
|
+
// (`bc1…`/`tb1…`) and Cosmos-SDK chains (`cosmos1…`, `osmo1…`,
|
|
1109
|
+
// `juno1…`, `inj1…`, etc.) without enumerating every HRP. Runs before
|
|
1110
|
+
// the Base58 pattern below — see header comment for why.
|
|
1111
|
+
{
|
|
1112
|
+
pattern: /\b[a-z]{1,10}1[ac-hj-np-z02-9]{38,}\b/gu,
|
|
1113
|
+
replacement: "<addr>"
|
|
1114
|
+
},
|
|
1115
|
+
// Base58 tokens (32+ chars, Base58 alphabet `[1-9A-HJ-NP-Za-km-z]`).
|
|
1116
|
+
// Covers Solana pubkeys (32-44 chars), Solana tx signatures (~88 chars),
|
|
1117
|
+
// and Bitcoin Base58 addresses ≥32 chars. The 32-char floor and `\b`
|
|
1118
|
+
// word boundary keep English words and shorter alphanumerics safe.
|
|
1119
|
+
{
|
|
1120
|
+
pattern: /\b[1-9A-HJ-NP-Za-km-z]{32,}\b/gu,
|
|
1121
|
+
replacement: "<addr>"
|
|
1122
|
+
},
|
|
1123
|
+
// Long decimal numbers — token amounts, gas units, timestamps, lamports.
|
|
1124
|
+
// 10+ digits catches typical chain quantities without affecting JSON-RPC
|
|
1125
|
+
// codes (-32601, 4001, etc.) or short numeric IDs.
|
|
1126
|
+
{ pattern: /\d{10,}/gu, replacement: "<num>" }
|
|
1127
|
+
];
|
|
1016
1128
|
}
|
|
1017
1129
|
});
|
|
1018
1130
|
|
|
@@ -1042,6 +1154,717 @@ var init_domain = __esm({
|
|
|
1042
1154
|
}
|
|
1043
1155
|
});
|
|
1044
1156
|
|
|
1157
|
+
// src/multichain/transports/constants.ts
|
|
1158
|
+
var MULTICHAIN_PROVIDER_STREAM_NAME;
|
|
1159
|
+
var init_constants2 = __esm({
|
|
1160
|
+
"src/multichain/transports/constants.ts"() {
|
|
1161
|
+
"use strict";
|
|
1162
|
+
MULTICHAIN_PROVIDER_STREAM_NAME = "metamask-multichain-provider";
|
|
1163
|
+
}
|
|
1164
|
+
});
|
|
1165
|
+
|
|
1166
|
+
// src/multichain/transports/mwp/index.ts
|
|
1167
|
+
var mwp_exports = {};
|
|
1168
|
+
__export(mwp_exports, {
|
|
1169
|
+
MWPTransport: () => MWPTransport
|
|
1170
|
+
});
|
|
1171
|
+
var import_multichain_api_client2, import_rpc_errors2, DEFAULT_REQUEST_TIMEOUT2, CONNECTION_GRACE_PERIOD, DEFAULT_CONNECTION_TIMEOUT, DEFAULT_RESUME_TIMEOUT, SESSION_STORE_KEY, ACCOUNTS_STORE_KEY, CHAIN_STORE_KEY, PENDING_SESSION_REQUEST_KEY, CACHED_METHOD_LIST, CACHED_RESET_METHOD_LIST, logger, MWPTransport;
|
|
1172
|
+
var init_mwp = __esm({
|
|
1173
|
+
"src/multichain/transports/mwp/index.ts"() {
|
|
1174
|
+
"use strict";
|
|
1175
|
+
import_multichain_api_client2 = require("@metamask/multichain-api-client");
|
|
1176
|
+
import_rpc_errors2 = require("@metamask/rpc-errors");
|
|
1177
|
+
init_domain();
|
|
1178
|
+
init_utils();
|
|
1179
|
+
init_constants2();
|
|
1180
|
+
DEFAULT_REQUEST_TIMEOUT2 = 60 * 1e3;
|
|
1181
|
+
CONNECTION_GRACE_PERIOD = 60 * 1e3;
|
|
1182
|
+
DEFAULT_CONNECTION_TIMEOUT = DEFAULT_REQUEST_TIMEOUT2 + CONNECTION_GRACE_PERIOD;
|
|
1183
|
+
DEFAULT_RESUME_TIMEOUT = 10 * 1e3;
|
|
1184
|
+
SESSION_STORE_KEY = "cache_wallet_getSession";
|
|
1185
|
+
ACCOUNTS_STORE_KEY = "cache_eth_accounts";
|
|
1186
|
+
CHAIN_STORE_KEY = "cache_eth_chainId";
|
|
1187
|
+
PENDING_SESSION_REQUEST_KEY = "pending_session_request";
|
|
1188
|
+
CACHED_METHOD_LIST = [
|
|
1189
|
+
"wallet_getSession",
|
|
1190
|
+
"wallet_createSession",
|
|
1191
|
+
"wallet_sessionChanged"
|
|
1192
|
+
];
|
|
1193
|
+
CACHED_RESET_METHOD_LIST = [
|
|
1194
|
+
"wallet_revokeSession",
|
|
1195
|
+
"wallet_revokePermissions"
|
|
1196
|
+
];
|
|
1197
|
+
logger = createLogger("metamask-sdk:transport");
|
|
1198
|
+
MWPTransport = class {
|
|
1199
|
+
constructor(dappClient, kvstore, options = {
|
|
1200
|
+
requestTimeout: DEFAULT_REQUEST_TIMEOUT2,
|
|
1201
|
+
connectionTimeout: DEFAULT_CONNECTION_TIMEOUT,
|
|
1202
|
+
resumeTimeout: DEFAULT_RESUME_TIMEOUT
|
|
1203
|
+
}) {
|
|
1204
|
+
this.dappClient = dappClient;
|
|
1205
|
+
this.kvstore = kvstore;
|
|
1206
|
+
this.options = options;
|
|
1207
|
+
this.__pendingRequests = /* @__PURE__ */ new Map();
|
|
1208
|
+
this.notificationCallbacks = /* @__PURE__ */ new Set();
|
|
1209
|
+
this.dappClient.on("message", this.handleMessage.bind(this));
|
|
1210
|
+
this.dappClient.on("session_request", (sessionRequest) => {
|
|
1211
|
+
this.currentSessionRequest = sessionRequest;
|
|
1212
|
+
this.kvstore.set(PENDING_SESSION_REQUEST_KEY, JSON.stringify(sessionRequest)).catch((err) => {
|
|
1213
|
+
logger("Failed to store pending session request", err);
|
|
1214
|
+
});
|
|
1215
|
+
});
|
|
1216
|
+
if (typeof window !== "undefined" && typeof window.addEventListener !== "undefined") {
|
|
1217
|
+
this.windowFocusHandler = this.onWindowFocus.bind(this);
|
|
1218
|
+
window.addEventListener("focus", this.windowFocusHandler);
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
get pendingRequests() {
|
|
1222
|
+
return this.__pendingRequests;
|
|
1223
|
+
}
|
|
1224
|
+
set pendingRequests(pendingRequests) {
|
|
1225
|
+
this.__pendingRequests = pendingRequests;
|
|
1226
|
+
}
|
|
1227
|
+
get sessionRequest() {
|
|
1228
|
+
return this.currentSessionRequest;
|
|
1229
|
+
}
|
|
1230
|
+
/**
|
|
1231
|
+
* Returns the stored pending session request from the dappClient session_request event, if any.
|
|
1232
|
+
*
|
|
1233
|
+
* @returns The stored SessionRequest, or null if none or invalid.
|
|
1234
|
+
*/
|
|
1235
|
+
getStoredPendingSessionRequest() {
|
|
1236
|
+
return __async(this, null, function* () {
|
|
1237
|
+
try {
|
|
1238
|
+
const raw = yield this.kvstore.get(PENDING_SESSION_REQUEST_KEY);
|
|
1239
|
+
if (!raw) {
|
|
1240
|
+
return null;
|
|
1241
|
+
}
|
|
1242
|
+
return JSON.parse(raw);
|
|
1243
|
+
} catch (e) {
|
|
1244
|
+
return null;
|
|
1245
|
+
}
|
|
1246
|
+
});
|
|
1247
|
+
}
|
|
1248
|
+
/**
|
|
1249
|
+
* Removes the stored pending session request from the KVStore.
|
|
1250
|
+
* This is necessary to ensure that ConnectMultichain is able to correctly
|
|
1251
|
+
* infer the MWP Transport connection attempt status.
|
|
1252
|
+
*/
|
|
1253
|
+
removeStoredPendingSessionRequest() {
|
|
1254
|
+
return __async(this, null, function* () {
|
|
1255
|
+
yield this.kvstore.delete(PENDING_SESSION_REQUEST_KEY);
|
|
1256
|
+
});
|
|
1257
|
+
}
|
|
1258
|
+
onWindowFocus() {
|
|
1259
|
+
if (!this.isConnected()) {
|
|
1260
|
+
this.dappClient.reconnect();
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
notifyCallbacks(data) {
|
|
1264
|
+
this.notificationCallbacks.forEach((callback) => callback(data));
|
|
1265
|
+
}
|
|
1266
|
+
rejectRequest(id, error = new Error("Request rejected")) {
|
|
1267
|
+
const request = this.pendingRequests.get(id);
|
|
1268
|
+
if (request) {
|
|
1269
|
+
this.pendingRequests.delete(id);
|
|
1270
|
+
clearTimeout(request.timeout);
|
|
1271
|
+
request.reject(error);
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
parseWalletError(errorPayload) {
|
|
1275
|
+
const errorData = errorPayload;
|
|
1276
|
+
if (typeof errorData.code === "number" && typeof errorData.message === "string") {
|
|
1277
|
+
const { code, message: message2 } = errorData;
|
|
1278
|
+
if (code >= 1e3 && code <= 4999) {
|
|
1279
|
+
return import_rpc_errors2.providerErrors.custom({ code, message: message2 });
|
|
1280
|
+
}
|
|
1281
|
+
return new import_rpc_errors2.JsonRpcError(code, message2);
|
|
1282
|
+
}
|
|
1283
|
+
const message = errorPayload instanceof Error ? errorPayload.message : JSON.stringify(errorPayload);
|
|
1284
|
+
return import_rpc_errors2.rpcErrors.internal({ message });
|
|
1285
|
+
}
|
|
1286
|
+
handleMessage(message) {
|
|
1287
|
+
if (typeof message === "object" && message !== null) {
|
|
1288
|
+
if ("data" in message) {
|
|
1289
|
+
const messagePayload = message.data;
|
|
1290
|
+
if ("id" in messagePayload && typeof messagePayload.id === "string") {
|
|
1291
|
+
const request = this.pendingRequests.get(messagePayload.id);
|
|
1292
|
+
if (request) {
|
|
1293
|
+
clearTimeout(request.timeout);
|
|
1294
|
+
if ("error" in messagePayload && messagePayload.error) {
|
|
1295
|
+
this.pendingRequests.delete(messagePayload.id);
|
|
1296
|
+
request.reject(this.parseWalletError(messagePayload.error));
|
|
1297
|
+
return;
|
|
1298
|
+
}
|
|
1299
|
+
const requestWithName = __spreadProps(__spreadValues({}, messagePayload), {
|
|
1300
|
+
method: request.method === "wallet_getSession" || request.method === "wallet_createSession" ? "wallet_sessionChanged" : request.method
|
|
1301
|
+
});
|
|
1302
|
+
const notification = __spreadProps(__spreadValues({}, messagePayload), {
|
|
1303
|
+
method: request.method === "wallet_getSession" || request.method === "wallet_createSession" ? "wallet_sessionChanged" : request.method,
|
|
1304
|
+
params: requestWithName.result
|
|
1305
|
+
});
|
|
1306
|
+
this.notifyCallbacks(notification);
|
|
1307
|
+
request.resolve(requestWithName);
|
|
1308
|
+
this.pendingRequests.delete(messagePayload.id);
|
|
1309
|
+
}
|
|
1310
|
+
} else {
|
|
1311
|
+
if (message.data.method === "metamask_chainChanged") {
|
|
1312
|
+
this.kvstore.set(
|
|
1313
|
+
CHAIN_STORE_KEY,
|
|
1314
|
+
JSON.stringify(
|
|
1315
|
+
message.data.params.chainId
|
|
1316
|
+
)
|
|
1317
|
+
);
|
|
1318
|
+
}
|
|
1319
|
+
if (message.data.method === "metamask_accountsChanged") {
|
|
1320
|
+
this.kvstore.set(
|
|
1321
|
+
ACCOUNTS_STORE_KEY,
|
|
1322
|
+
JSON.stringify(
|
|
1323
|
+
message.data.params
|
|
1324
|
+
)
|
|
1325
|
+
);
|
|
1326
|
+
}
|
|
1327
|
+
if (message.data.method === "wallet_sessionChanged") {
|
|
1328
|
+
const notification = message.data;
|
|
1329
|
+
const response = {
|
|
1330
|
+
result: notification.params
|
|
1331
|
+
};
|
|
1332
|
+
this.kvstore.set(SESSION_STORE_KEY, JSON.stringify(response));
|
|
1333
|
+
}
|
|
1334
|
+
this.notifyCallbacks(message.data);
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
onResumeSuccess(resumeResolve, resumeReject, options) {
|
|
1340
|
+
return __async(this, null, function* () {
|
|
1341
|
+
var _a2, _b, _c, _d, _e, _f, _g;
|
|
1342
|
+
try {
|
|
1343
|
+
yield this.waitForWalletSessionIfNotCached();
|
|
1344
|
+
const sessionRequest = yield this.request({
|
|
1345
|
+
method: "wallet_getSession"
|
|
1346
|
+
});
|
|
1347
|
+
if (sessionRequest.error) {
|
|
1348
|
+
return resumeReject(new Error(sessionRequest.error.message));
|
|
1349
|
+
}
|
|
1350
|
+
let walletSession = sessionRequest.result;
|
|
1351
|
+
if (walletSession && options) {
|
|
1352
|
+
const currentScopes = Object.keys(
|
|
1353
|
+
(_a2 = walletSession == null ? void 0 : walletSession.sessionScopes) != null ? _a2 : {}
|
|
1354
|
+
);
|
|
1355
|
+
const proposedScopes = (_b = options == null ? void 0 : options.scopes) != null ? _b : [];
|
|
1356
|
+
const proposedCaipAccountIds = (_c = options == null ? void 0 : options.caipAccountIds) != null ? _c : [];
|
|
1357
|
+
const hasSameScopesAndAccounts = isSameScopesAndAccounts(
|
|
1358
|
+
currentScopes,
|
|
1359
|
+
proposedScopes,
|
|
1360
|
+
walletSession,
|
|
1361
|
+
proposedCaipAccountIds
|
|
1362
|
+
);
|
|
1363
|
+
if (options.forceRequest || !hasSameScopesAndAccounts) {
|
|
1364
|
+
const optionalScopes = addValidAccounts(
|
|
1365
|
+
getOptionalScopes((_d = options == null ? void 0 : options.scopes) != null ? _d : []),
|
|
1366
|
+
getValidAccounts((_e = options == null ? void 0 : options.caipAccountIds) != null ? _e : [])
|
|
1367
|
+
);
|
|
1368
|
+
const sessionRequest2 = {
|
|
1369
|
+
optionalScopes
|
|
1370
|
+
};
|
|
1371
|
+
const response = yield this.request({
|
|
1372
|
+
method: "wallet_createSession",
|
|
1373
|
+
params: sessionRequest2
|
|
1374
|
+
});
|
|
1375
|
+
if (response.error) {
|
|
1376
|
+
return resumeReject(new Error(response.error.message));
|
|
1377
|
+
}
|
|
1378
|
+
walletSession = response.result;
|
|
1379
|
+
}
|
|
1380
|
+
} else if (!walletSession) {
|
|
1381
|
+
const optionalScopes = addValidAccounts(
|
|
1382
|
+
getOptionalScopes((_f = options == null ? void 0 : options.scopes) != null ? _f : []),
|
|
1383
|
+
getValidAccounts((_g = options == null ? void 0 : options.caipAccountIds) != null ? _g : [])
|
|
1384
|
+
);
|
|
1385
|
+
const sessionRequest2 = { optionalScopes };
|
|
1386
|
+
const response = yield this.request({
|
|
1387
|
+
method: "wallet_createSession",
|
|
1388
|
+
params: sessionRequest2
|
|
1389
|
+
});
|
|
1390
|
+
if (response.error) {
|
|
1391
|
+
return resumeReject(new Error(response.error.message));
|
|
1392
|
+
}
|
|
1393
|
+
walletSession = response.result;
|
|
1394
|
+
}
|
|
1395
|
+
yield this.removeStoredPendingSessionRequest();
|
|
1396
|
+
this.notifyCallbacks({
|
|
1397
|
+
method: "wallet_sessionChanged",
|
|
1398
|
+
params: walletSession
|
|
1399
|
+
});
|
|
1400
|
+
return resumeResolve();
|
|
1401
|
+
} catch (err) {
|
|
1402
|
+
return resumeReject(err);
|
|
1403
|
+
}
|
|
1404
|
+
});
|
|
1405
|
+
}
|
|
1406
|
+
init() {
|
|
1407
|
+
return __async(this, null, function* () {
|
|
1408
|
+
});
|
|
1409
|
+
}
|
|
1410
|
+
// TODO: Rename this
|
|
1411
|
+
sendEip1193Message(payload, options) {
|
|
1412
|
+
return __async(this, null, function* () {
|
|
1413
|
+
const request = __spreadValues({
|
|
1414
|
+
jsonrpc: "2.0",
|
|
1415
|
+
id: String(getUniqueRequestId())
|
|
1416
|
+
}, payload);
|
|
1417
|
+
const cachedWalletSession = yield this.getCachedResponse(request);
|
|
1418
|
+
if (cachedWalletSession) {
|
|
1419
|
+
this.notifyCallbacks(cachedWalletSession);
|
|
1420
|
+
return cachedWalletSession;
|
|
1421
|
+
}
|
|
1422
|
+
return new Promise((resolve, reject) => {
|
|
1423
|
+
var _a2;
|
|
1424
|
+
const timeout = setTimeout(() => {
|
|
1425
|
+
this.rejectRequest(request.id, new import_multichain_api_client2.TransportTimeoutError());
|
|
1426
|
+
}, (_a2 = options == null ? void 0 : options.timeout) != null ? _a2 : this.options.requestTimeout);
|
|
1427
|
+
this.pendingRequests.set(request.id, {
|
|
1428
|
+
request,
|
|
1429
|
+
method: request.method,
|
|
1430
|
+
resolve: (response) => __async(this, null, function* () {
|
|
1431
|
+
yield this.storeWalletSession(request, response);
|
|
1432
|
+
return resolve(response);
|
|
1433
|
+
}),
|
|
1434
|
+
reject,
|
|
1435
|
+
timeout
|
|
1436
|
+
});
|
|
1437
|
+
this.dappClient.sendRequest({
|
|
1438
|
+
name: "metamask-provider",
|
|
1439
|
+
data: request
|
|
1440
|
+
}).catch(reject);
|
|
1441
|
+
});
|
|
1442
|
+
});
|
|
1443
|
+
}
|
|
1444
|
+
connect(options) {
|
|
1445
|
+
return __async(this, null, function* () {
|
|
1446
|
+
const { dappClient } = this;
|
|
1447
|
+
const session = yield this.getActiveSession();
|
|
1448
|
+
if (session) {
|
|
1449
|
+
logger("active session found", {
|
|
1450
|
+
id: session.id,
|
|
1451
|
+
channel: session.channel,
|
|
1452
|
+
expiresAt: session.expiresAt
|
|
1453
|
+
});
|
|
1454
|
+
}
|
|
1455
|
+
const storedSessionRequestBeforeConnectionAttempt = yield this.getStoredPendingSessionRequest();
|
|
1456
|
+
let timeout;
|
|
1457
|
+
let initialConnectionMessageHandler;
|
|
1458
|
+
const connectionPromise = new Promise((resolve, reject) => __async(this, null, function* () {
|
|
1459
|
+
let connection;
|
|
1460
|
+
if (session) {
|
|
1461
|
+
connection = new Promise((resumeResolve, resumeReject) => {
|
|
1462
|
+
var _a2;
|
|
1463
|
+
if (this.dappClient.state === "CONNECTED") {
|
|
1464
|
+
this.onResumeSuccess(resumeResolve, resumeReject, options);
|
|
1465
|
+
} else {
|
|
1466
|
+
this.dappClient.once("connected", () => __async(this, null, function* () {
|
|
1467
|
+
this.onResumeSuccess(resumeResolve, resumeReject, options);
|
|
1468
|
+
}));
|
|
1469
|
+
dappClient.resume((_a2 = session == null ? void 0 : session.id) != null ? _a2 : "");
|
|
1470
|
+
}
|
|
1471
|
+
});
|
|
1472
|
+
} else {
|
|
1473
|
+
connection = new Promise(
|
|
1474
|
+
(resolveConnection, rejectConnection) => {
|
|
1475
|
+
var _a2, _b;
|
|
1476
|
+
const optionalScopes = addValidAccounts(
|
|
1477
|
+
getOptionalScopes((_a2 = options == null ? void 0 : options.scopes) != null ? _a2 : []),
|
|
1478
|
+
getValidAccounts((_b = options == null ? void 0 : options.caipAccountIds) != null ? _b : [])
|
|
1479
|
+
);
|
|
1480
|
+
const sessionRequest = {
|
|
1481
|
+
optionalScopes,
|
|
1482
|
+
sessionProperties: options == null ? void 0 : options.sessionProperties
|
|
1483
|
+
};
|
|
1484
|
+
const request = {
|
|
1485
|
+
jsonrpc: "2.0",
|
|
1486
|
+
id: String(getUniqueRequestId()),
|
|
1487
|
+
method: "wallet_createSession",
|
|
1488
|
+
params: sessionRequest
|
|
1489
|
+
};
|
|
1490
|
+
initialConnectionMessageHandler = (message) => __async(this, null, function* () {
|
|
1491
|
+
if (typeof message !== "object" || message === null) {
|
|
1492
|
+
return;
|
|
1493
|
+
}
|
|
1494
|
+
if (!("data" in message)) {
|
|
1495
|
+
return;
|
|
1496
|
+
}
|
|
1497
|
+
const messagePayload = message.data;
|
|
1498
|
+
const isMatchingId = messagePayload.id === request.id;
|
|
1499
|
+
const isMatchingMethod = messagePayload.method === "wallet_createSession" || messagePayload.method === "wallet_sessionChanged";
|
|
1500
|
+
if (!isMatchingId && !isMatchingMethod) {
|
|
1501
|
+
return;
|
|
1502
|
+
}
|
|
1503
|
+
if (messagePayload.error) {
|
|
1504
|
+
return rejectConnection(
|
|
1505
|
+
this.parseWalletError(messagePayload.error)
|
|
1506
|
+
);
|
|
1507
|
+
}
|
|
1508
|
+
yield this.storeWalletSession(
|
|
1509
|
+
request,
|
|
1510
|
+
messagePayload
|
|
1511
|
+
);
|
|
1512
|
+
yield this.removeStoredPendingSessionRequest();
|
|
1513
|
+
this.notifyCallbacks(messagePayload);
|
|
1514
|
+
return resolveConnection();
|
|
1515
|
+
});
|
|
1516
|
+
this.dappClient.on("message", initialConnectionMessageHandler);
|
|
1517
|
+
const platformType = getPlatformType();
|
|
1518
|
+
const isQRCodeFlow = [
|
|
1519
|
+
"web-desktop" /* DesktopWeb */,
|
|
1520
|
+
"nodejs" /* NonBrowser */
|
|
1521
|
+
].includes(platformType);
|
|
1522
|
+
const initialPayload = {
|
|
1523
|
+
name: MULTICHAIN_PROVIDER_STREAM_NAME,
|
|
1524
|
+
data: request
|
|
1525
|
+
};
|
|
1526
|
+
dappClient.connect({
|
|
1527
|
+
mode: "trusted",
|
|
1528
|
+
initialPayload: isQRCodeFlow ? void 0 : initialPayload
|
|
1529
|
+
}).then(() => __async(this, null, function* () {
|
|
1530
|
+
if (isQRCodeFlow) {
|
|
1531
|
+
return dappClient.sendRequest(initialPayload);
|
|
1532
|
+
}
|
|
1533
|
+
return void 0;
|
|
1534
|
+
})).catch((error) => {
|
|
1535
|
+
if (initialConnectionMessageHandler) {
|
|
1536
|
+
this.dappClient.off(
|
|
1537
|
+
"message",
|
|
1538
|
+
initialConnectionMessageHandler
|
|
1539
|
+
);
|
|
1540
|
+
}
|
|
1541
|
+
rejectConnection(error);
|
|
1542
|
+
});
|
|
1543
|
+
}
|
|
1544
|
+
);
|
|
1545
|
+
}
|
|
1546
|
+
timeout = setTimeout(
|
|
1547
|
+
() => {
|
|
1548
|
+
reject(new import_multichain_api_client2.TransportTimeoutError());
|
|
1549
|
+
},
|
|
1550
|
+
storedSessionRequestBeforeConnectionAttempt ? this.options.resumeTimeout : this.options.connectionTimeout
|
|
1551
|
+
);
|
|
1552
|
+
connection.then(resolve).catch(reject);
|
|
1553
|
+
}));
|
|
1554
|
+
return connectionPromise.catch((error) => __async(this, null, function* () {
|
|
1555
|
+
yield this.dappClient.disconnect();
|
|
1556
|
+
throw error;
|
|
1557
|
+
})).finally(() => {
|
|
1558
|
+
if (timeout) {
|
|
1559
|
+
clearTimeout(timeout);
|
|
1560
|
+
}
|
|
1561
|
+
if (initialConnectionMessageHandler) {
|
|
1562
|
+
this.dappClient.off("message", initialConnectionMessageHandler);
|
|
1563
|
+
initialConnectionMessageHandler = void 0;
|
|
1564
|
+
}
|
|
1565
|
+
this.removeStoredPendingSessionRequest();
|
|
1566
|
+
});
|
|
1567
|
+
});
|
|
1568
|
+
}
|
|
1569
|
+
/**
|
|
1570
|
+
* Disconnects from the Mobile Wallet Protocol
|
|
1571
|
+
*
|
|
1572
|
+
* @param [scopes] - The scopes to revoke. If not provided or empty, all scopes will be revoked.
|
|
1573
|
+
* @returns Nothing
|
|
1574
|
+
*/
|
|
1575
|
+
disconnect() {
|
|
1576
|
+
return __async(this, arguments, function* (scopes = []) {
|
|
1577
|
+
var _a2, _b;
|
|
1578
|
+
const cachedSession = yield this.getCachedResponse({
|
|
1579
|
+
jsonrpc: "2.0",
|
|
1580
|
+
id: "0",
|
|
1581
|
+
method: "wallet_getSession"
|
|
1582
|
+
});
|
|
1583
|
+
const cachedSessionScopes = (_b = (_a2 = cachedSession == null ? void 0 : cachedSession.result) == null ? void 0 : _a2.sessionScopes) != null ? _b : {};
|
|
1584
|
+
const remainingScopes = scopes.length === 0 ? [] : Object.keys(cachedSessionScopes).filter(
|
|
1585
|
+
(scope) => !scopes.includes(scope)
|
|
1586
|
+
);
|
|
1587
|
+
const newSessionScopes = Object.fromEntries(
|
|
1588
|
+
Object.entries(cachedSessionScopes).filter(
|
|
1589
|
+
([key]) => remainingScopes.includes(key)
|
|
1590
|
+
)
|
|
1591
|
+
);
|
|
1592
|
+
this.request({ method: "wallet_revokeSession", params: { scopes } }).catch(
|
|
1593
|
+
(err) => {
|
|
1594
|
+
console.error("error revoking session", err);
|
|
1595
|
+
}
|
|
1596
|
+
);
|
|
1597
|
+
const remainingScopesIncludeEip155 = remainingScopes.some(
|
|
1598
|
+
(scope) => scope.includes("eip155")
|
|
1599
|
+
);
|
|
1600
|
+
if (!remainingScopesIncludeEip155) {
|
|
1601
|
+
this.kvstore.delete(ACCOUNTS_STORE_KEY);
|
|
1602
|
+
this.kvstore.delete(CHAIN_STORE_KEY);
|
|
1603
|
+
}
|
|
1604
|
+
if (remainingScopes.length > 0) {
|
|
1605
|
+
this.kvstore.set(
|
|
1606
|
+
SESSION_STORE_KEY,
|
|
1607
|
+
JSON.stringify({
|
|
1608
|
+
result: {
|
|
1609
|
+
sessionScopes: newSessionScopes
|
|
1610
|
+
}
|
|
1611
|
+
})
|
|
1612
|
+
);
|
|
1613
|
+
} else {
|
|
1614
|
+
this.kvstore.delete(SESSION_STORE_KEY);
|
|
1615
|
+
if (typeof window !== "undefined" && typeof window.removeEventListener !== "undefined" && this.windowFocusHandler) {
|
|
1616
|
+
window.removeEventListener("focus", this.windowFocusHandler);
|
|
1617
|
+
this.windowFocusHandler = void 0;
|
|
1618
|
+
}
|
|
1619
|
+
yield this.dappClient.disconnect();
|
|
1620
|
+
}
|
|
1621
|
+
this.notifyCallbacks({
|
|
1622
|
+
method: "wallet_sessionChanged",
|
|
1623
|
+
params: {
|
|
1624
|
+
sessionScopes: newSessionScopes
|
|
1625
|
+
}
|
|
1626
|
+
});
|
|
1627
|
+
});
|
|
1628
|
+
}
|
|
1629
|
+
/**
|
|
1630
|
+
* Checks if the transport is connected
|
|
1631
|
+
*
|
|
1632
|
+
* @returns True if transport is connected, false otherwise
|
|
1633
|
+
*/
|
|
1634
|
+
isConnected() {
|
|
1635
|
+
return this.dappClient.state === "CONNECTED";
|
|
1636
|
+
}
|
|
1637
|
+
/**
|
|
1638
|
+
* Attempts to re-establish a connection via DappClient
|
|
1639
|
+
*
|
|
1640
|
+
* @returns Nothing
|
|
1641
|
+
*/
|
|
1642
|
+
// TODO: We should re-evaluate adding this to the WebSocketTransport layer from `@metamask/mobile-wallet-protocol-core`
|
|
1643
|
+
// ticket: https://consensyssoftware.atlassian.net/browse/WAPI-862
|
|
1644
|
+
attemptResumeSession() {
|
|
1645
|
+
return __async(this, null, function* () {
|
|
1646
|
+
try {
|
|
1647
|
+
yield this.dappClient.reconnect();
|
|
1648
|
+
yield new Promise((resolve, reject) => {
|
|
1649
|
+
const timeout = setTimeout(() => {
|
|
1650
|
+
reject(new Error("Resume timeout"));
|
|
1651
|
+
}, 2e3);
|
|
1652
|
+
if (this.isConnected()) {
|
|
1653
|
+
clearTimeout(timeout);
|
|
1654
|
+
resolve();
|
|
1655
|
+
} else {
|
|
1656
|
+
this.dappClient.once("connected", () => {
|
|
1657
|
+
clearTimeout(timeout);
|
|
1658
|
+
resolve();
|
|
1659
|
+
});
|
|
1660
|
+
}
|
|
1661
|
+
});
|
|
1662
|
+
} catch (error) {
|
|
1663
|
+
return Promise.reject(
|
|
1664
|
+
new Error(`Failed to resume session: ${error.message}`)
|
|
1665
|
+
);
|
|
1666
|
+
}
|
|
1667
|
+
});
|
|
1668
|
+
}
|
|
1669
|
+
getCachedResponse(request) {
|
|
1670
|
+
return __async(this, null, function* () {
|
|
1671
|
+
var _a2;
|
|
1672
|
+
if (request.method === "wallet_getSession") {
|
|
1673
|
+
const walletGetSession = yield this.kvstore.get(SESSION_STORE_KEY);
|
|
1674
|
+
if (walletGetSession) {
|
|
1675
|
+
const walletSession = JSON.parse(walletGetSession);
|
|
1676
|
+
return {
|
|
1677
|
+
id: request.id,
|
|
1678
|
+
jsonrpc: "2.0",
|
|
1679
|
+
result: (_a2 = walletSession.params) != null ? _a2 : walletSession.result,
|
|
1680
|
+
// "what?... why walletSession.params?.."
|
|
1681
|
+
method: request.method
|
|
1682
|
+
};
|
|
1683
|
+
}
|
|
1684
|
+
} else if (request.method === "eth_accounts") {
|
|
1685
|
+
const ethAccounts = yield this.kvstore.get(ACCOUNTS_STORE_KEY);
|
|
1686
|
+
if (ethAccounts) {
|
|
1687
|
+
return {
|
|
1688
|
+
id: request.id,
|
|
1689
|
+
jsonrpc: "2.0",
|
|
1690
|
+
result: JSON.parse(ethAccounts),
|
|
1691
|
+
method: request.method
|
|
1692
|
+
};
|
|
1693
|
+
}
|
|
1694
|
+
} else if (request.method === "eth_chainId") {
|
|
1695
|
+
const ethChainId = yield this.kvstore.get(CHAIN_STORE_KEY);
|
|
1696
|
+
if (ethChainId) {
|
|
1697
|
+
return {
|
|
1698
|
+
id: request.id,
|
|
1699
|
+
jsonrpc: "2.0",
|
|
1700
|
+
result: JSON.parse(ethChainId),
|
|
1701
|
+
method: request.method
|
|
1702
|
+
};
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
});
|
|
1706
|
+
}
|
|
1707
|
+
storeWalletSession(request, response) {
|
|
1708
|
+
return __async(this, null, function* () {
|
|
1709
|
+
if (response.error) {
|
|
1710
|
+
return;
|
|
1711
|
+
}
|
|
1712
|
+
if (CACHED_METHOD_LIST.includes(request.method)) {
|
|
1713
|
+
yield this.kvstore.set(SESSION_STORE_KEY, JSON.stringify(response));
|
|
1714
|
+
} else if (request.method === "eth_accounts") {
|
|
1715
|
+
yield this.kvstore.set(
|
|
1716
|
+
ACCOUNTS_STORE_KEY,
|
|
1717
|
+
JSON.stringify(response.result)
|
|
1718
|
+
);
|
|
1719
|
+
} else if (request.method === "eth_chainId") {
|
|
1720
|
+
yield this.kvstore.set(CHAIN_STORE_KEY, JSON.stringify(response.result));
|
|
1721
|
+
} else if (CACHED_RESET_METHOD_LIST.includes(request.method)) {
|
|
1722
|
+
yield this.kvstore.delete(SESSION_STORE_KEY);
|
|
1723
|
+
yield this.kvstore.delete(ACCOUNTS_STORE_KEY);
|
|
1724
|
+
yield this.kvstore.delete(CHAIN_STORE_KEY);
|
|
1725
|
+
}
|
|
1726
|
+
});
|
|
1727
|
+
}
|
|
1728
|
+
request(payload, options) {
|
|
1729
|
+
return __async(this, null, function* () {
|
|
1730
|
+
const request = __spreadValues({
|
|
1731
|
+
jsonrpc: "2.0",
|
|
1732
|
+
id: String(getUniqueRequestId())
|
|
1733
|
+
}, payload);
|
|
1734
|
+
const cachedWalletSession = yield this.getCachedResponse(request);
|
|
1735
|
+
if (cachedWalletSession) {
|
|
1736
|
+
this.notifyCallbacks(cachedWalletSession);
|
|
1737
|
+
return cachedWalletSession;
|
|
1738
|
+
}
|
|
1739
|
+
if (!this.isConnected()) {
|
|
1740
|
+
yield this.attemptResumeSession();
|
|
1741
|
+
}
|
|
1742
|
+
return new Promise((resolve, reject) => {
|
|
1743
|
+
var _a2;
|
|
1744
|
+
const timeout = setTimeout(() => {
|
|
1745
|
+
this.rejectRequest(request.id, new import_multichain_api_client2.TransportTimeoutError());
|
|
1746
|
+
}, (_a2 = options == null ? void 0 : options.timeout) != null ? _a2 : this.options.requestTimeout);
|
|
1747
|
+
this.pendingRequests.set(request.id, {
|
|
1748
|
+
request,
|
|
1749
|
+
method: request.method,
|
|
1750
|
+
resolve: (response) => __async(this, null, function* () {
|
|
1751
|
+
yield this.storeWalletSession(request, response);
|
|
1752
|
+
return resolve(response);
|
|
1753
|
+
}),
|
|
1754
|
+
reject,
|
|
1755
|
+
timeout
|
|
1756
|
+
});
|
|
1757
|
+
this.dappClient.sendRequest({
|
|
1758
|
+
name: MULTICHAIN_PROVIDER_STREAM_NAME,
|
|
1759
|
+
data: request
|
|
1760
|
+
}).catch(reject);
|
|
1761
|
+
});
|
|
1762
|
+
});
|
|
1763
|
+
}
|
|
1764
|
+
onNotification(callback) {
|
|
1765
|
+
this.notificationCallbacks.add(callback);
|
|
1766
|
+
return () => {
|
|
1767
|
+
this.notificationCallbacks.delete(callback);
|
|
1768
|
+
};
|
|
1769
|
+
}
|
|
1770
|
+
getActiveSession() {
|
|
1771
|
+
return __async(this, null, function* () {
|
|
1772
|
+
const { kvstore } = this;
|
|
1773
|
+
const { SessionStore } = yield import("@metamask/mobile-wallet-protocol-core");
|
|
1774
|
+
const sessionStore = yield SessionStore.create(kvstore);
|
|
1775
|
+
try {
|
|
1776
|
+
const [activeSession] = yield sessionStore.list();
|
|
1777
|
+
return activeSession;
|
|
1778
|
+
} catch (error) {
|
|
1779
|
+
logger("error getting active session", error);
|
|
1780
|
+
return void 0;
|
|
1781
|
+
}
|
|
1782
|
+
});
|
|
1783
|
+
}
|
|
1784
|
+
// This method checks if an existing CAIP session response is cached or waits for one
|
|
1785
|
+
// to be received from the wallet if not cached. This is necessary because there is an edge
|
|
1786
|
+
// case during the initial connection flow where after the user has accepted the permission approval
|
|
1787
|
+
// and returned back to the dapp from the wallet, the dapp page may have gotten unloaded and refreshed.
|
|
1788
|
+
// When it is unloaded and refreshed, it will try to resume the session by making a request for wallet_getSession
|
|
1789
|
+
// which should resolve from cache, but because a race condition makes it possible for the response from the wallet
|
|
1790
|
+
// for the initial wallet_createSession connection request to not have been handled and cached yet. This results
|
|
1791
|
+
// in the wallet_getSession request never resolving unless we wait for it explicitly as done in this method.
|
|
1792
|
+
waitForWalletSessionIfNotCached() {
|
|
1793
|
+
return __async(this, null, function* () {
|
|
1794
|
+
const cachedWalletGetSessionResponse = yield this.kvstore.get(SESSION_STORE_KEY);
|
|
1795
|
+
if (cachedWalletGetSessionResponse) {
|
|
1796
|
+
return;
|
|
1797
|
+
}
|
|
1798
|
+
let unsubscribe;
|
|
1799
|
+
const responsePromise = new Promise((resolve) => {
|
|
1800
|
+
unsubscribe = this.onNotification((message) => {
|
|
1801
|
+
if (typeof message === "object" && message !== null) {
|
|
1802
|
+
if ("data" in message) {
|
|
1803
|
+
const messagePayload = message.data;
|
|
1804
|
+
if (messagePayload.method === "wallet_getSession" || messagePayload.method === "wallet_sessionChanged") {
|
|
1805
|
+
unsubscribe();
|
|
1806
|
+
resolve();
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
});
|
|
1811
|
+
});
|
|
1812
|
+
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
1813
|
+
setTimeout(() => {
|
|
1814
|
+
unsubscribe();
|
|
1815
|
+
this.removeStoredPendingSessionRequest();
|
|
1816
|
+
reject(new import_multichain_api_client2.TransportTimeoutError());
|
|
1817
|
+
}, this.options.resumeTimeout);
|
|
1818
|
+
});
|
|
1819
|
+
return Promise.race([responsePromise, timeoutPromise]);
|
|
1820
|
+
});
|
|
1821
|
+
}
|
|
1822
|
+
};
|
|
1823
|
+
}
|
|
1824
|
+
});
|
|
1825
|
+
|
|
1826
|
+
// src/multichain/transports/mwp/KeyManager.ts
|
|
1827
|
+
var KeyManager_exports = {};
|
|
1828
|
+
__export(KeyManager_exports, {
|
|
1829
|
+
createKeyManager: () => createKeyManager
|
|
1830
|
+
});
|
|
1831
|
+
function createKeyManager() {
|
|
1832
|
+
return __async(this, null, function* () {
|
|
1833
|
+
const { decrypt, encrypt, PrivateKey, PublicKey } = yield import("eciesjs");
|
|
1834
|
+
return {
|
|
1835
|
+
generateKeyPair() {
|
|
1836
|
+
const privateKey = new PrivateKey();
|
|
1837
|
+
return {
|
|
1838
|
+
privateKey: new Uint8Array(privateKey.secret),
|
|
1839
|
+
publicKey: privateKey.publicKey.toBytes(true)
|
|
1840
|
+
};
|
|
1841
|
+
},
|
|
1842
|
+
encrypt(plaintext, theirPublicKey) {
|
|
1843
|
+
return __async(this, null, function* () {
|
|
1844
|
+
const plaintextBuffer = Buffer.from(plaintext, "utf8");
|
|
1845
|
+
const encryptedBuffer = encrypt(theirPublicKey, plaintextBuffer);
|
|
1846
|
+
return encryptedBuffer.toString("base64");
|
|
1847
|
+
});
|
|
1848
|
+
},
|
|
1849
|
+
decrypt(encryptedB64, myPrivateKey) {
|
|
1850
|
+
return __async(this, null, function* () {
|
|
1851
|
+
const encryptedBuffer = Buffer.from(encryptedB64, "base64");
|
|
1852
|
+
const decryptedBuffer = yield decrypt(myPrivateKey, encryptedBuffer);
|
|
1853
|
+
return Buffer.from(decryptedBuffer).toString("utf8");
|
|
1854
|
+
});
|
|
1855
|
+
},
|
|
1856
|
+
validatePeerKey(key) {
|
|
1857
|
+
PublicKey.fromHex(Buffer.from(key).toString("hex"));
|
|
1858
|
+
}
|
|
1859
|
+
};
|
|
1860
|
+
});
|
|
1861
|
+
}
|
|
1862
|
+
var init_KeyManager = __esm({
|
|
1863
|
+
"src/multichain/transports/mwp/KeyManager.ts"() {
|
|
1864
|
+
"use strict";
|
|
1865
|
+
}
|
|
1866
|
+
});
|
|
1867
|
+
|
|
1045
1868
|
// src/ui/modals/base/utils.ts
|
|
1046
1869
|
function formatRemainingTime(milliseconds) {
|
|
1047
1870
|
if (milliseconds <= 0) {
|
|
@@ -1314,6 +2137,7 @@ __export(index_node_exports, {
|
|
|
1314
2137
|
StoreAdapter: () => StoreAdapter,
|
|
1315
2138
|
StoreClient: () => StoreClient,
|
|
1316
2139
|
TransportType: () => TransportType,
|
|
2140
|
+
classifyFailureReason: () => classifyFailureReason,
|
|
1317
2141
|
createLogger: () => createLogger,
|
|
1318
2142
|
createMultichainClient: () => createMultichainClient,
|
|
1319
2143
|
enableDebug: () => enableDebug,
|
|
@@ -1334,8 +2158,6 @@ init_domain();
|
|
|
1334
2158
|
|
|
1335
2159
|
// src/multichain/index.ts
|
|
1336
2160
|
var import_analytics4 = require("@metamask/analytics");
|
|
1337
|
-
var import_mobile_wallet_protocol_core2 = require("@metamask/mobile-wallet-protocol-core");
|
|
1338
|
-
var import_mobile_wallet_protocol_dapp_client = require("@metamask/mobile-wallet-protocol-dapp-client");
|
|
1339
2161
|
var import_multichain_api_client3 = require("@metamask/multichain-api-client");
|
|
1340
2162
|
|
|
1341
2163
|
// src/config/index.ts
|
|
@@ -1576,7 +2398,7 @@ withAnalyticsTracking_fn = function(options, execute) {
|
|
|
1576
2398
|
if (isRejection) {
|
|
1577
2399
|
yield __privateMethod(this, _RequestRouter_instances, trackWalletActionRejected_fn).call(this, options);
|
|
1578
2400
|
} else {
|
|
1579
|
-
yield __privateMethod(this, _RequestRouter_instances, trackWalletActionFailed_fn).call(this, options);
|
|
2401
|
+
yield __privateMethod(this, _RequestRouter_instances, trackWalletActionFailed_fn).call(this, options, error);
|
|
1580
2402
|
}
|
|
1581
2403
|
if (error instanceof RPCInvokeMethodErr) {
|
|
1582
2404
|
throw error;
|
|
@@ -1611,13 +2433,14 @@ trackWalletActionSucceeded_fn = function(options) {
|
|
|
1611
2433
|
import_analytics2.analytics.track("mmconnect_wallet_action_succeeded", props);
|
|
1612
2434
|
});
|
|
1613
2435
|
};
|
|
1614
|
-
trackWalletActionFailed_fn = function(options) {
|
|
2436
|
+
trackWalletActionFailed_fn = function(options, error) {
|
|
1615
2437
|
return __async(this, null, function* () {
|
|
1616
2438
|
const props = yield getWalletActionAnalyticsProperties(
|
|
1617
2439
|
this.config,
|
|
1618
2440
|
this.config.storage,
|
|
1619
2441
|
options,
|
|
1620
|
-
this.transportType
|
|
2442
|
+
this.transportType,
|
|
2443
|
+
extractErrorDiagnostics(error)
|
|
1621
2444
|
);
|
|
1622
2445
|
import_analytics2.analytics.track("mmconnect_wallet_action_failed", props);
|
|
1623
2446
|
});
|
|
@@ -1898,6 +2721,9 @@ var MultichainApiClientWrapperTransport = class {
|
|
|
1898
2721
|
return false;
|
|
1899
2722
|
}
|
|
1900
2723
|
}
|
|
2724
|
+
isTransportConnected() {
|
|
2725
|
+
return this.isTransportDefined() && this.metamaskConnectMultichain.transport.isConnected();
|
|
2726
|
+
}
|
|
1901
2727
|
clearNotificationCallbacks() {
|
|
1902
2728
|
__privateGet(this, _notificationCallbacks2).clear();
|
|
1903
2729
|
}
|
|
@@ -1919,17 +2745,19 @@ var MultichainApiClientWrapperTransport = class {
|
|
|
1919
2745
|
this.notifyCallbacks.bind(this)
|
|
1920
2746
|
);
|
|
1921
2747
|
}
|
|
2748
|
+
// Purposely noop, resolves successfully. Actual connection is handled by the underlying client/transport.
|
|
1922
2749
|
connect() {
|
|
1923
2750
|
return __async(this, null, function* () {
|
|
1924
|
-
|
|
1925
|
-
yield this.metamaskConnectMultichain.emitSessionChanged();
|
|
2751
|
+
return Promise.resolve();
|
|
1926
2752
|
});
|
|
1927
2753
|
}
|
|
2754
|
+
// Purposely noop, resolves successfully. Actual connection is handled by the underlying client/transport.
|
|
1928
2755
|
disconnect() {
|
|
1929
2756
|
return __async(this, null, function* () {
|
|
1930
2757
|
return Promise.resolve();
|
|
1931
2758
|
});
|
|
1932
2759
|
}
|
|
2760
|
+
// Purposely hardcoded to true. Actual connection is handled by the underlying client/transport.
|
|
1933
2761
|
isConnected() {
|
|
1934
2762
|
return true;
|
|
1935
2763
|
}
|
|
@@ -1952,7 +2780,6 @@ var MultichainApiClientWrapperTransport = class {
|
|
|
1952
2780
|
default:
|
|
1953
2781
|
throw new Error(`Unsupported method: ${requestPayload.method}`);
|
|
1954
2782
|
}
|
|
1955
|
-
throw new Error(`Unknown method: ${requestPayload.method}`);
|
|
1956
2783
|
});
|
|
1957
2784
|
}
|
|
1958
2785
|
onNotification(callback) {
|
|
@@ -1982,13 +2809,11 @@ walletCreateSession_fn = function(request) {
|
|
|
1982
2809
|
}
|
|
1983
2810
|
});
|
|
1984
2811
|
const accounts = [...new Set(scopeAccounts)];
|
|
1985
|
-
console.log("\u{1F4DA} SDK connect");
|
|
1986
2812
|
yield this.metamaskConnectMultichain.connect(
|
|
1987
2813
|
scopes,
|
|
1988
2814
|
accounts,
|
|
1989
2815
|
createSessionParams.sessionProperties
|
|
1990
2816
|
);
|
|
1991
|
-
console.log("\u{1F4DA} SDK connected");
|
|
1992
2817
|
return this.metamaskConnectMultichain.transport.request({
|
|
1993
2818
|
method: "wallet_getSession"
|
|
1994
2819
|
});
|
|
@@ -1996,7 +2821,7 @@ walletCreateSession_fn = function(request) {
|
|
|
1996
2821
|
};
|
|
1997
2822
|
walletGetSession_fn = function(request) {
|
|
1998
2823
|
return __async(this, null, function* () {
|
|
1999
|
-
if (!this.
|
|
2824
|
+
if (!this.isTransportConnected()) {
|
|
2000
2825
|
return {
|
|
2001
2826
|
jsonrpc: "2.0",
|
|
2002
2827
|
id: request.id,
|
|
@@ -2013,9 +2838,6 @@ walletGetSession_fn = function(request) {
|
|
|
2013
2838
|
walletRevokeSession_fn = function(request) {
|
|
2014
2839
|
return __async(this, null, function* () {
|
|
2015
2840
|
var _a2;
|
|
2016
|
-
if (!this.isTransportDefined()) {
|
|
2017
|
-
return { jsonrpc: "2.0", id: request.id, result: true };
|
|
2018
|
-
}
|
|
2019
2841
|
const revokeSessionParams = request.params;
|
|
2020
2842
|
const scopes = (_a2 = revokeSessionParams == null ? void 0 : revokeSessionParams.scopes) != null ? _a2 : [];
|
|
2021
2843
|
try {
|
|
@@ -2028,7 +2850,7 @@ walletRevokeSession_fn = function(request) {
|
|
|
2028
2850
|
};
|
|
2029
2851
|
walletInvokeMethod_fn = function(request) {
|
|
2030
2852
|
return __async(this, null, function* () {
|
|
2031
|
-
if (!this.
|
|
2853
|
+
if (!this.isTransportConnected()) {
|
|
2032
2854
|
return { error: import_rpc_errors.providerErrors.unauthorized() };
|
|
2033
2855
|
}
|
|
2034
2856
|
const result = this.metamaskConnectMultichain.invokeMethod(
|
|
@@ -2040,684 +2862,11 @@ walletInvokeMethod_fn = function(request) {
|
|
|
2040
2862
|
});
|
|
2041
2863
|
};
|
|
2042
2864
|
|
|
2043
|
-
// src/multichain/transports/mwp/index.ts
|
|
2044
|
-
var import_mobile_wallet_protocol_core = require("@metamask/mobile-wallet-protocol-core");
|
|
2045
|
-
var import_multichain_api_client2 = require("@metamask/multichain-api-client");
|
|
2046
|
-
var import_rpc_errors2 = require("@metamask/rpc-errors");
|
|
2047
|
-
init_domain();
|
|
2048
|
-
init_utils();
|
|
2049
|
-
|
|
2050
|
-
// src/multichain/transports/constants.ts
|
|
2051
|
-
var MULTICHAIN_PROVIDER_STREAM_NAME = "metamask-multichain-provider";
|
|
2052
|
-
|
|
2053
|
-
// src/multichain/transports/mwp/index.ts
|
|
2054
|
-
var DEFAULT_REQUEST_TIMEOUT2 = 60 * 1e3;
|
|
2055
|
-
var CONNECTION_GRACE_PERIOD = 60 * 1e3;
|
|
2056
|
-
var DEFAULT_CONNECTION_TIMEOUT = DEFAULT_REQUEST_TIMEOUT2 + CONNECTION_GRACE_PERIOD;
|
|
2057
|
-
var DEFAULT_RESUME_TIMEOUT = 10 * 1e3;
|
|
2058
|
-
var SESSION_STORE_KEY = "cache_wallet_getSession";
|
|
2059
|
-
var ACCOUNTS_STORE_KEY = "cache_eth_accounts";
|
|
2060
|
-
var CHAIN_STORE_KEY = "cache_eth_chainId";
|
|
2061
|
-
var PENDING_SESSION_REQUEST_KEY = "pending_session_request";
|
|
2062
|
-
var CACHED_METHOD_LIST = [
|
|
2063
|
-
"wallet_getSession",
|
|
2064
|
-
"wallet_createSession",
|
|
2065
|
-
"wallet_sessionChanged"
|
|
2066
|
-
];
|
|
2067
|
-
var CACHED_RESET_METHOD_LIST = [
|
|
2068
|
-
"wallet_revokeSession",
|
|
2069
|
-
"wallet_revokePermissions"
|
|
2070
|
-
];
|
|
2071
|
-
var logger = createLogger("metamask-sdk:transport");
|
|
2072
|
-
var MWPTransport = class {
|
|
2073
|
-
constructor(dappClient, kvstore, options = {
|
|
2074
|
-
requestTimeout: DEFAULT_REQUEST_TIMEOUT2,
|
|
2075
|
-
connectionTimeout: DEFAULT_CONNECTION_TIMEOUT,
|
|
2076
|
-
resumeTimeout: DEFAULT_RESUME_TIMEOUT
|
|
2077
|
-
}) {
|
|
2078
|
-
this.dappClient = dappClient;
|
|
2079
|
-
this.kvstore = kvstore;
|
|
2080
|
-
this.options = options;
|
|
2081
|
-
this.__pendingRequests = /* @__PURE__ */ new Map();
|
|
2082
|
-
this.notificationCallbacks = /* @__PURE__ */ new Set();
|
|
2083
|
-
this.dappClient.on("message", this.handleMessage.bind(this));
|
|
2084
|
-
this.dappClient.on("session_request", (sessionRequest) => {
|
|
2085
|
-
this.currentSessionRequest = sessionRequest;
|
|
2086
|
-
this.kvstore.set(PENDING_SESSION_REQUEST_KEY, JSON.stringify(sessionRequest)).catch((err) => {
|
|
2087
|
-
logger("Failed to store pending session request", err);
|
|
2088
|
-
});
|
|
2089
|
-
});
|
|
2090
|
-
if (typeof window !== "undefined" && typeof window.addEventListener !== "undefined") {
|
|
2091
|
-
this.windowFocusHandler = this.onWindowFocus.bind(this);
|
|
2092
|
-
window.addEventListener("focus", this.windowFocusHandler);
|
|
2093
|
-
}
|
|
2094
|
-
}
|
|
2095
|
-
get pendingRequests() {
|
|
2096
|
-
return this.__pendingRequests;
|
|
2097
|
-
}
|
|
2098
|
-
set pendingRequests(pendingRequests) {
|
|
2099
|
-
this.__pendingRequests = pendingRequests;
|
|
2100
|
-
}
|
|
2101
|
-
get sessionRequest() {
|
|
2102
|
-
return this.currentSessionRequest;
|
|
2103
|
-
}
|
|
2104
|
-
/**
|
|
2105
|
-
* Returns the stored pending session request from the dappClient session_request event, if any.
|
|
2106
|
-
*
|
|
2107
|
-
* @returns The stored SessionRequest, or null if none or invalid.
|
|
2108
|
-
*/
|
|
2109
|
-
getStoredPendingSessionRequest() {
|
|
2110
|
-
return __async(this, null, function* () {
|
|
2111
|
-
try {
|
|
2112
|
-
const raw = yield this.kvstore.get(PENDING_SESSION_REQUEST_KEY);
|
|
2113
|
-
if (!raw) {
|
|
2114
|
-
return null;
|
|
2115
|
-
}
|
|
2116
|
-
return JSON.parse(raw);
|
|
2117
|
-
} catch (e) {
|
|
2118
|
-
return null;
|
|
2119
|
-
}
|
|
2120
|
-
});
|
|
2121
|
-
}
|
|
2122
|
-
/**
|
|
2123
|
-
* Removes the stored pending session request from the KVStore.
|
|
2124
|
-
* This is necessary to ensure that ConnectMultichain is able to correctly
|
|
2125
|
-
* infer the MWP Transport connection attempt status.
|
|
2126
|
-
*/
|
|
2127
|
-
removeStoredPendingSessionRequest() {
|
|
2128
|
-
return __async(this, null, function* () {
|
|
2129
|
-
yield this.kvstore.delete(PENDING_SESSION_REQUEST_KEY);
|
|
2130
|
-
});
|
|
2131
|
-
}
|
|
2132
|
-
onWindowFocus() {
|
|
2133
|
-
if (!this.isConnected()) {
|
|
2134
|
-
this.dappClient.reconnect();
|
|
2135
|
-
}
|
|
2136
|
-
}
|
|
2137
|
-
notifyCallbacks(data) {
|
|
2138
|
-
this.notificationCallbacks.forEach((callback) => callback(data));
|
|
2139
|
-
}
|
|
2140
|
-
rejectRequest(id, error = new Error("Request rejected")) {
|
|
2141
|
-
const request = this.pendingRequests.get(id);
|
|
2142
|
-
if (request) {
|
|
2143
|
-
this.pendingRequests.delete(id);
|
|
2144
|
-
clearTimeout(request.timeout);
|
|
2145
|
-
request.reject(error);
|
|
2146
|
-
}
|
|
2147
|
-
}
|
|
2148
|
-
parseWalletError(errorPayload) {
|
|
2149
|
-
const errorData = errorPayload;
|
|
2150
|
-
if (typeof errorData.code === "number" && typeof errorData.message === "string") {
|
|
2151
|
-
const { code, message: message2 } = errorData;
|
|
2152
|
-
if (code >= 1e3 && code <= 4999) {
|
|
2153
|
-
return import_rpc_errors2.providerErrors.custom({ code, message: message2 });
|
|
2154
|
-
}
|
|
2155
|
-
return new import_rpc_errors2.JsonRpcError(code, message2);
|
|
2156
|
-
}
|
|
2157
|
-
const message = errorPayload instanceof Error ? errorPayload.message : JSON.stringify(errorPayload);
|
|
2158
|
-
return import_rpc_errors2.rpcErrors.internal({ message });
|
|
2159
|
-
}
|
|
2160
|
-
handleMessage(message) {
|
|
2161
|
-
if (typeof message === "object" && message !== null) {
|
|
2162
|
-
if ("data" in message) {
|
|
2163
|
-
const messagePayload = message.data;
|
|
2164
|
-
if ("id" in messagePayload && typeof messagePayload.id === "string") {
|
|
2165
|
-
const request = this.pendingRequests.get(messagePayload.id);
|
|
2166
|
-
if (request) {
|
|
2167
|
-
clearTimeout(request.timeout);
|
|
2168
|
-
if ("error" in messagePayload && messagePayload.error) {
|
|
2169
|
-
this.pendingRequests.delete(messagePayload.id);
|
|
2170
|
-
request.reject(this.parseWalletError(messagePayload.error));
|
|
2171
|
-
return;
|
|
2172
|
-
}
|
|
2173
|
-
const requestWithName = __spreadProps(__spreadValues({}, messagePayload), {
|
|
2174
|
-
method: request.method === "wallet_getSession" || request.method === "wallet_createSession" ? "wallet_sessionChanged" : request.method
|
|
2175
|
-
});
|
|
2176
|
-
const notification = __spreadProps(__spreadValues({}, messagePayload), {
|
|
2177
|
-
method: request.method === "wallet_getSession" || request.method === "wallet_createSession" ? "wallet_sessionChanged" : request.method,
|
|
2178
|
-
params: requestWithName.result
|
|
2179
|
-
});
|
|
2180
|
-
this.notifyCallbacks(notification);
|
|
2181
|
-
request.resolve(requestWithName);
|
|
2182
|
-
this.pendingRequests.delete(messagePayload.id);
|
|
2183
|
-
}
|
|
2184
|
-
} else {
|
|
2185
|
-
if (message.data.method === "metamask_chainChanged") {
|
|
2186
|
-
this.kvstore.set(
|
|
2187
|
-
CHAIN_STORE_KEY,
|
|
2188
|
-
JSON.stringify(
|
|
2189
|
-
message.data.params.chainId
|
|
2190
|
-
)
|
|
2191
|
-
);
|
|
2192
|
-
}
|
|
2193
|
-
if (message.data.method === "metamask_accountsChanged") {
|
|
2194
|
-
this.kvstore.set(
|
|
2195
|
-
ACCOUNTS_STORE_KEY,
|
|
2196
|
-
JSON.stringify(
|
|
2197
|
-
message.data.params
|
|
2198
|
-
)
|
|
2199
|
-
);
|
|
2200
|
-
}
|
|
2201
|
-
if (message.data.method === "wallet_sessionChanged") {
|
|
2202
|
-
const notification = message.data;
|
|
2203
|
-
const response = {
|
|
2204
|
-
result: notification.params
|
|
2205
|
-
};
|
|
2206
|
-
this.kvstore.set(SESSION_STORE_KEY, JSON.stringify(response));
|
|
2207
|
-
}
|
|
2208
|
-
this.notifyCallbacks(message.data);
|
|
2209
|
-
}
|
|
2210
|
-
}
|
|
2211
|
-
}
|
|
2212
|
-
}
|
|
2213
|
-
onResumeSuccess(resumeResolve, resumeReject, options) {
|
|
2214
|
-
return __async(this, null, function* () {
|
|
2215
|
-
var _a2, _b, _c, _d, _e, _f, _g;
|
|
2216
|
-
try {
|
|
2217
|
-
yield this.waitForWalletSessionIfNotCached();
|
|
2218
|
-
const sessionRequest = yield this.request({
|
|
2219
|
-
method: "wallet_getSession"
|
|
2220
|
-
});
|
|
2221
|
-
if (sessionRequest.error) {
|
|
2222
|
-
return resumeReject(new Error(sessionRequest.error.message));
|
|
2223
|
-
}
|
|
2224
|
-
let walletSession = sessionRequest.result;
|
|
2225
|
-
if (walletSession && options) {
|
|
2226
|
-
const currentScopes = Object.keys(
|
|
2227
|
-
(_a2 = walletSession == null ? void 0 : walletSession.sessionScopes) != null ? _a2 : {}
|
|
2228
|
-
);
|
|
2229
|
-
const proposedScopes = (_b = options == null ? void 0 : options.scopes) != null ? _b : [];
|
|
2230
|
-
const proposedCaipAccountIds = (_c = options == null ? void 0 : options.caipAccountIds) != null ? _c : [];
|
|
2231
|
-
const hasSameScopesAndAccounts = isSameScopesAndAccounts(
|
|
2232
|
-
currentScopes,
|
|
2233
|
-
proposedScopes,
|
|
2234
|
-
walletSession,
|
|
2235
|
-
proposedCaipAccountIds
|
|
2236
|
-
);
|
|
2237
|
-
if (options.forceRequest || !hasSameScopesAndAccounts) {
|
|
2238
|
-
const optionalScopes = addValidAccounts(
|
|
2239
|
-
getOptionalScopes((_d = options == null ? void 0 : options.scopes) != null ? _d : []),
|
|
2240
|
-
getValidAccounts((_e = options == null ? void 0 : options.caipAccountIds) != null ? _e : [])
|
|
2241
|
-
);
|
|
2242
|
-
const sessionRequest2 = {
|
|
2243
|
-
optionalScopes
|
|
2244
|
-
};
|
|
2245
|
-
const response = yield this.request({
|
|
2246
|
-
method: "wallet_createSession",
|
|
2247
|
-
params: sessionRequest2
|
|
2248
|
-
});
|
|
2249
|
-
if (response.error) {
|
|
2250
|
-
return resumeReject(new Error(response.error.message));
|
|
2251
|
-
}
|
|
2252
|
-
walletSession = response.result;
|
|
2253
|
-
}
|
|
2254
|
-
} else if (!walletSession) {
|
|
2255
|
-
const optionalScopes = addValidAccounts(
|
|
2256
|
-
getOptionalScopes((_f = options == null ? void 0 : options.scopes) != null ? _f : []),
|
|
2257
|
-
getValidAccounts((_g = options == null ? void 0 : options.caipAccountIds) != null ? _g : [])
|
|
2258
|
-
);
|
|
2259
|
-
const sessionRequest2 = { optionalScopes };
|
|
2260
|
-
const response = yield this.request({
|
|
2261
|
-
method: "wallet_createSession",
|
|
2262
|
-
params: sessionRequest2
|
|
2263
|
-
});
|
|
2264
|
-
if (response.error) {
|
|
2265
|
-
return resumeReject(new Error(response.error.message));
|
|
2266
|
-
}
|
|
2267
|
-
walletSession = response.result;
|
|
2268
|
-
}
|
|
2269
|
-
yield this.removeStoredPendingSessionRequest();
|
|
2270
|
-
this.notifyCallbacks({
|
|
2271
|
-
method: "wallet_sessionChanged",
|
|
2272
|
-
params: walletSession
|
|
2273
|
-
});
|
|
2274
|
-
return resumeResolve();
|
|
2275
|
-
} catch (err) {
|
|
2276
|
-
return resumeReject(err);
|
|
2277
|
-
}
|
|
2278
|
-
});
|
|
2279
|
-
}
|
|
2280
|
-
init() {
|
|
2281
|
-
return __async(this, null, function* () {
|
|
2282
|
-
});
|
|
2283
|
-
}
|
|
2284
|
-
// TODO: Rename this
|
|
2285
|
-
sendEip1193Message(payload, options) {
|
|
2286
|
-
return __async(this, null, function* () {
|
|
2287
|
-
const request = __spreadValues({
|
|
2288
|
-
jsonrpc: "2.0",
|
|
2289
|
-
id: String(getUniqueRequestId())
|
|
2290
|
-
}, payload);
|
|
2291
|
-
const cachedWalletSession = yield this.getCachedResponse(request);
|
|
2292
|
-
if (cachedWalletSession) {
|
|
2293
|
-
this.notifyCallbacks(cachedWalletSession);
|
|
2294
|
-
return cachedWalletSession;
|
|
2295
|
-
}
|
|
2296
|
-
return new Promise((resolve, reject) => {
|
|
2297
|
-
var _a2;
|
|
2298
|
-
const timeout = setTimeout(() => {
|
|
2299
|
-
this.rejectRequest(request.id, new import_multichain_api_client2.TransportTimeoutError());
|
|
2300
|
-
}, (_a2 = options == null ? void 0 : options.timeout) != null ? _a2 : this.options.requestTimeout);
|
|
2301
|
-
this.pendingRequests.set(request.id, {
|
|
2302
|
-
request,
|
|
2303
|
-
method: request.method,
|
|
2304
|
-
resolve: (response) => __async(this, null, function* () {
|
|
2305
|
-
yield this.storeWalletSession(request, response);
|
|
2306
|
-
return resolve(response);
|
|
2307
|
-
}),
|
|
2308
|
-
reject,
|
|
2309
|
-
timeout
|
|
2310
|
-
});
|
|
2311
|
-
this.dappClient.sendRequest({
|
|
2312
|
-
name: "metamask-provider",
|
|
2313
|
-
data: request
|
|
2314
|
-
}).catch(reject);
|
|
2315
|
-
});
|
|
2316
|
-
});
|
|
2317
|
-
}
|
|
2318
|
-
connect(options) {
|
|
2319
|
-
return __async(this, null, function* () {
|
|
2320
|
-
const { dappClient } = this;
|
|
2321
|
-
const session = yield this.getActiveSession();
|
|
2322
|
-
if (session) {
|
|
2323
|
-
logger("active session found", {
|
|
2324
|
-
id: session.id,
|
|
2325
|
-
channel: session.channel,
|
|
2326
|
-
expiresAt: session.expiresAt
|
|
2327
|
-
});
|
|
2328
|
-
}
|
|
2329
|
-
const storedSessionRequestBeforeConnectionAttempt = yield this.getStoredPendingSessionRequest();
|
|
2330
|
-
let timeout;
|
|
2331
|
-
let initialConnectionMessageHandler;
|
|
2332
|
-
const connectionPromise = new Promise((resolve, reject) => __async(this, null, function* () {
|
|
2333
|
-
let connection;
|
|
2334
|
-
if (session) {
|
|
2335
|
-
connection = new Promise((resumeResolve, resumeReject) => {
|
|
2336
|
-
var _a2;
|
|
2337
|
-
if (this.dappClient.state === "CONNECTED") {
|
|
2338
|
-
this.onResumeSuccess(resumeResolve, resumeReject, options);
|
|
2339
|
-
} else {
|
|
2340
|
-
this.dappClient.once("connected", () => __async(this, null, function* () {
|
|
2341
|
-
this.onResumeSuccess(resumeResolve, resumeReject, options);
|
|
2342
|
-
}));
|
|
2343
|
-
dappClient.resume((_a2 = session == null ? void 0 : session.id) != null ? _a2 : "");
|
|
2344
|
-
}
|
|
2345
|
-
});
|
|
2346
|
-
} else {
|
|
2347
|
-
connection = new Promise(
|
|
2348
|
-
(resolveConnection, rejectConnection) => {
|
|
2349
|
-
var _a2, _b;
|
|
2350
|
-
const optionalScopes = addValidAccounts(
|
|
2351
|
-
getOptionalScopes((_a2 = options == null ? void 0 : options.scopes) != null ? _a2 : []),
|
|
2352
|
-
getValidAccounts((_b = options == null ? void 0 : options.caipAccountIds) != null ? _b : [])
|
|
2353
|
-
);
|
|
2354
|
-
const sessionRequest = {
|
|
2355
|
-
optionalScopes,
|
|
2356
|
-
sessionProperties: options == null ? void 0 : options.sessionProperties
|
|
2357
|
-
};
|
|
2358
|
-
const request = {
|
|
2359
|
-
jsonrpc: "2.0",
|
|
2360
|
-
id: String(getUniqueRequestId()),
|
|
2361
|
-
method: "wallet_createSession",
|
|
2362
|
-
params: sessionRequest
|
|
2363
|
-
};
|
|
2364
|
-
initialConnectionMessageHandler = (message) => __async(this, null, function* () {
|
|
2365
|
-
if (typeof message !== "object" || message === null) {
|
|
2366
|
-
return;
|
|
2367
|
-
}
|
|
2368
|
-
if (!("data" in message)) {
|
|
2369
|
-
return;
|
|
2370
|
-
}
|
|
2371
|
-
const messagePayload = message.data;
|
|
2372
|
-
const isMatchingId = messagePayload.id === request.id;
|
|
2373
|
-
const isMatchingMethod = messagePayload.method === "wallet_createSession" || messagePayload.method === "wallet_sessionChanged";
|
|
2374
|
-
if (!isMatchingId && !isMatchingMethod) {
|
|
2375
|
-
return;
|
|
2376
|
-
}
|
|
2377
|
-
if (messagePayload.error) {
|
|
2378
|
-
return rejectConnection(
|
|
2379
|
-
this.parseWalletError(messagePayload.error)
|
|
2380
|
-
);
|
|
2381
|
-
}
|
|
2382
|
-
yield this.storeWalletSession(
|
|
2383
|
-
request,
|
|
2384
|
-
messagePayload
|
|
2385
|
-
);
|
|
2386
|
-
yield this.removeStoredPendingSessionRequest();
|
|
2387
|
-
this.notifyCallbacks(messagePayload);
|
|
2388
|
-
return resolveConnection();
|
|
2389
|
-
});
|
|
2390
|
-
this.dappClient.on("message", initialConnectionMessageHandler);
|
|
2391
|
-
dappClient.connect({
|
|
2392
|
-
mode: "trusted",
|
|
2393
|
-
initialPayload: {
|
|
2394
|
-
name: MULTICHAIN_PROVIDER_STREAM_NAME,
|
|
2395
|
-
data: request
|
|
2396
|
-
}
|
|
2397
|
-
}).catch((error) => {
|
|
2398
|
-
if (initialConnectionMessageHandler) {
|
|
2399
|
-
this.dappClient.off(
|
|
2400
|
-
"message",
|
|
2401
|
-
initialConnectionMessageHandler
|
|
2402
|
-
);
|
|
2403
|
-
}
|
|
2404
|
-
rejectConnection(error);
|
|
2405
|
-
});
|
|
2406
|
-
}
|
|
2407
|
-
);
|
|
2408
|
-
}
|
|
2409
|
-
timeout = setTimeout(
|
|
2410
|
-
() => {
|
|
2411
|
-
reject(new import_multichain_api_client2.TransportTimeoutError());
|
|
2412
|
-
},
|
|
2413
|
-
storedSessionRequestBeforeConnectionAttempt ? this.options.resumeTimeout : this.options.connectionTimeout
|
|
2414
|
-
);
|
|
2415
|
-
connection.then(resolve).catch(reject);
|
|
2416
|
-
}));
|
|
2417
|
-
return connectionPromise.catch((error) => __async(this, null, function* () {
|
|
2418
|
-
yield this.dappClient.disconnect();
|
|
2419
|
-
throw error;
|
|
2420
|
-
})).finally(() => {
|
|
2421
|
-
if (timeout) {
|
|
2422
|
-
clearTimeout(timeout);
|
|
2423
|
-
}
|
|
2424
|
-
if (initialConnectionMessageHandler) {
|
|
2425
|
-
this.dappClient.off("message", initialConnectionMessageHandler);
|
|
2426
|
-
initialConnectionMessageHandler = void 0;
|
|
2427
|
-
}
|
|
2428
|
-
this.removeStoredPendingSessionRequest();
|
|
2429
|
-
});
|
|
2430
|
-
});
|
|
2431
|
-
}
|
|
2432
|
-
/**
|
|
2433
|
-
* Disconnects from the Mobile Wallet Protocol
|
|
2434
|
-
*
|
|
2435
|
-
* @param [scopes] - The scopes to revoke. If not provided or empty, all scopes will be revoked.
|
|
2436
|
-
* @returns Nothing
|
|
2437
|
-
*/
|
|
2438
|
-
disconnect() {
|
|
2439
|
-
return __async(this, arguments, function* (scopes = []) {
|
|
2440
|
-
var _a2, _b;
|
|
2441
|
-
const cachedSession = yield this.getCachedResponse({
|
|
2442
|
-
jsonrpc: "2.0",
|
|
2443
|
-
id: "0",
|
|
2444
|
-
method: "wallet_getSession"
|
|
2445
|
-
});
|
|
2446
|
-
const cachedSessionScopes = (_b = (_a2 = cachedSession == null ? void 0 : cachedSession.result) == null ? void 0 : _a2.sessionScopes) != null ? _b : {};
|
|
2447
|
-
const remainingScopes = scopes.length === 0 ? [] : Object.keys(cachedSessionScopes).filter(
|
|
2448
|
-
(scope) => !scopes.includes(scope)
|
|
2449
|
-
);
|
|
2450
|
-
const newSessionScopes = Object.fromEntries(
|
|
2451
|
-
Object.entries(cachedSessionScopes).filter(
|
|
2452
|
-
([key]) => remainingScopes.includes(key)
|
|
2453
|
-
)
|
|
2454
|
-
);
|
|
2455
|
-
this.request({ method: "wallet_revokeSession", params: { scopes } }).catch(
|
|
2456
|
-
(err) => {
|
|
2457
|
-
console.error("error revoking session", err);
|
|
2458
|
-
}
|
|
2459
|
-
);
|
|
2460
|
-
const remainingScopesIncludeEip155 = remainingScopes.some(
|
|
2461
|
-
(scope) => scope.includes("eip155")
|
|
2462
|
-
);
|
|
2463
|
-
if (!remainingScopesIncludeEip155) {
|
|
2464
|
-
this.kvstore.delete(ACCOUNTS_STORE_KEY);
|
|
2465
|
-
this.kvstore.delete(CHAIN_STORE_KEY);
|
|
2466
|
-
}
|
|
2467
|
-
if (remainingScopes.length > 0) {
|
|
2468
|
-
this.kvstore.set(
|
|
2469
|
-
SESSION_STORE_KEY,
|
|
2470
|
-
JSON.stringify({
|
|
2471
|
-
result: {
|
|
2472
|
-
sessionScopes: newSessionScopes
|
|
2473
|
-
}
|
|
2474
|
-
})
|
|
2475
|
-
);
|
|
2476
|
-
} else {
|
|
2477
|
-
this.kvstore.delete(SESSION_STORE_KEY);
|
|
2478
|
-
if (typeof window !== "undefined" && typeof window.removeEventListener !== "undefined" && this.windowFocusHandler) {
|
|
2479
|
-
window.removeEventListener("focus", this.windowFocusHandler);
|
|
2480
|
-
this.windowFocusHandler = void 0;
|
|
2481
|
-
}
|
|
2482
|
-
yield this.dappClient.disconnect();
|
|
2483
|
-
}
|
|
2484
|
-
this.notifyCallbacks({
|
|
2485
|
-
method: "wallet_sessionChanged",
|
|
2486
|
-
params: {
|
|
2487
|
-
sessionScopes: newSessionScopes
|
|
2488
|
-
}
|
|
2489
|
-
});
|
|
2490
|
-
});
|
|
2491
|
-
}
|
|
2492
|
-
/**
|
|
2493
|
-
* Checks if the transport is connected
|
|
2494
|
-
*
|
|
2495
|
-
* @returns True if transport is connected, false otherwise
|
|
2496
|
-
*/
|
|
2497
|
-
isConnected() {
|
|
2498
|
-
return this.dappClient.state === "CONNECTED";
|
|
2499
|
-
}
|
|
2500
|
-
/**
|
|
2501
|
-
* Attempts to re-establish a connection via DappClient
|
|
2502
|
-
*
|
|
2503
|
-
* @returns Nothing
|
|
2504
|
-
*/
|
|
2505
|
-
// TODO: We should re-evaluate adding this to the WebSocketTransport layer from `@metamask/mobile-wallet-protocol-core`
|
|
2506
|
-
// ticket: https://consensyssoftware.atlassian.net/browse/WAPI-862
|
|
2507
|
-
attemptResumeSession() {
|
|
2508
|
-
return __async(this, null, function* () {
|
|
2509
|
-
try {
|
|
2510
|
-
yield this.dappClient.reconnect();
|
|
2511
|
-
yield new Promise((resolve, reject) => {
|
|
2512
|
-
const timeout = setTimeout(() => {
|
|
2513
|
-
reject(new Error("Resume timeout"));
|
|
2514
|
-
}, 2e3);
|
|
2515
|
-
if (this.isConnected()) {
|
|
2516
|
-
clearTimeout(timeout);
|
|
2517
|
-
resolve();
|
|
2518
|
-
} else {
|
|
2519
|
-
this.dappClient.once("connected", () => {
|
|
2520
|
-
clearTimeout(timeout);
|
|
2521
|
-
resolve();
|
|
2522
|
-
});
|
|
2523
|
-
}
|
|
2524
|
-
});
|
|
2525
|
-
} catch (error) {
|
|
2526
|
-
return Promise.reject(
|
|
2527
|
-
new Error(`Failed to resume session: ${error.message}`)
|
|
2528
|
-
);
|
|
2529
|
-
}
|
|
2530
|
-
});
|
|
2531
|
-
}
|
|
2532
|
-
getCachedResponse(request) {
|
|
2533
|
-
return __async(this, null, function* () {
|
|
2534
|
-
var _a2;
|
|
2535
|
-
if (request.method === "wallet_getSession") {
|
|
2536
|
-
const walletGetSession = yield this.kvstore.get(SESSION_STORE_KEY);
|
|
2537
|
-
if (walletGetSession) {
|
|
2538
|
-
const walletSession = JSON.parse(walletGetSession);
|
|
2539
|
-
return {
|
|
2540
|
-
id: request.id,
|
|
2541
|
-
jsonrpc: "2.0",
|
|
2542
|
-
result: (_a2 = walletSession.params) != null ? _a2 : walletSession.result,
|
|
2543
|
-
// "what?... why walletSession.params?.."
|
|
2544
|
-
method: request.method
|
|
2545
|
-
};
|
|
2546
|
-
}
|
|
2547
|
-
} else if (request.method === "eth_accounts") {
|
|
2548
|
-
const ethAccounts = yield this.kvstore.get(ACCOUNTS_STORE_KEY);
|
|
2549
|
-
if (ethAccounts) {
|
|
2550
|
-
return {
|
|
2551
|
-
id: request.id,
|
|
2552
|
-
jsonrpc: "2.0",
|
|
2553
|
-
result: JSON.parse(ethAccounts),
|
|
2554
|
-
method: request.method
|
|
2555
|
-
};
|
|
2556
|
-
}
|
|
2557
|
-
} else if (request.method === "eth_chainId") {
|
|
2558
|
-
const ethChainId = yield this.kvstore.get(CHAIN_STORE_KEY);
|
|
2559
|
-
if (ethChainId) {
|
|
2560
|
-
return {
|
|
2561
|
-
id: request.id,
|
|
2562
|
-
jsonrpc: "2.0",
|
|
2563
|
-
result: JSON.parse(ethChainId),
|
|
2564
|
-
method: request.method
|
|
2565
|
-
};
|
|
2566
|
-
}
|
|
2567
|
-
}
|
|
2568
|
-
});
|
|
2569
|
-
}
|
|
2570
|
-
storeWalletSession(request, response) {
|
|
2571
|
-
return __async(this, null, function* () {
|
|
2572
|
-
if (response.error) {
|
|
2573
|
-
return;
|
|
2574
|
-
}
|
|
2575
|
-
if (CACHED_METHOD_LIST.includes(request.method)) {
|
|
2576
|
-
yield this.kvstore.set(SESSION_STORE_KEY, JSON.stringify(response));
|
|
2577
|
-
} else if (request.method === "eth_accounts") {
|
|
2578
|
-
yield this.kvstore.set(
|
|
2579
|
-
ACCOUNTS_STORE_KEY,
|
|
2580
|
-
JSON.stringify(response.result)
|
|
2581
|
-
);
|
|
2582
|
-
} else if (request.method === "eth_chainId") {
|
|
2583
|
-
yield this.kvstore.set(CHAIN_STORE_KEY, JSON.stringify(response.result));
|
|
2584
|
-
} else if (CACHED_RESET_METHOD_LIST.includes(request.method)) {
|
|
2585
|
-
yield this.kvstore.delete(SESSION_STORE_KEY);
|
|
2586
|
-
yield this.kvstore.delete(ACCOUNTS_STORE_KEY);
|
|
2587
|
-
yield this.kvstore.delete(CHAIN_STORE_KEY);
|
|
2588
|
-
}
|
|
2589
|
-
});
|
|
2590
|
-
}
|
|
2591
|
-
request(payload, options) {
|
|
2592
|
-
return __async(this, null, function* () {
|
|
2593
|
-
const request = __spreadValues({
|
|
2594
|
-
jsonrpc: "2.0",
|
|
2595
|
-
id: String(getUniqueRequestId())
|
|
2596
|
-
}, payload);
|
|
2597
|
-
const cachedWalletSession = yield this.getCachedResponse(request);
|
|
2598
|
-
if (cachedWalletSession) {
|
|
2599
|
-
this.notifyCallbacks(cachedWalletSession);
|
|
2600
|
-
return cachedWalletSession;
|
|
2601
|
-
}
|
|
2602
|
-
if (!this.isConnected()) {
|
|
2603
|
-
yield this.attemptResumeSession();
|
|
2604
|
-
}
|
|
2605
|
-
return new Promise((resolve, reject) => {
|
|
2606
|
-
var _a2;
|
|
2607
|
-
const timeout = setTimeout(() => {
|
|
2608
|
-
this.rejectRequest(request.id, new import_multichain_api_client2.TransportTimeoutError());
|
|
2609
|
-
}, (_a2 = options == null ? void 0 : options.timeout) != null ? _a2 : this.options.requestTimeout);
|
|
2610
|
-
this.pendingRequests.set(request.id, {
|
|
2611
|
-
request,
|
|
2612
|
-
method: request.method,
|
|
2613
|
-
resolve: (response) => __async(this, null, function* () {
|
|
2614
|
-
yield this.storeWalletSession(request, response);
|
|
2615
|
-
return resolve(response);
|
|
2616
|
-
}),
|
|
2617
|
-
reject,
|
|
2618
|
-
timeout
|
|
2619
|
-
});
|
|
2620
|
-
this.dappClient.sendRequest({
|
|
2621
|
-
name: MULTICHAIN_PROVIDER_STREAM_NAME,
|
|
2622
|
-
data: request
|
|
2623
|
-
}).catch(reject);
|
|
2624
|
-
});
|
|
2625
|
-
});
|
|
2626
|
-
}
|
|
2627
|
-
onNotification(callback) {
|
|
2628
|
-
this.notificationCallbacks.add(callback);
|
|
2629
|
-
return () => {
|
|
2630
|
-
this.notificationCallbacks.delete(callback);
|
|
2631
|
-
};
|
|
2632
|
-
}
|
|
2633
|
-
getActiveSession() {
|
|
2634
|
-
return __async(this, null, function* () {
|
|
2635
|
-
const { kvstore } = this;
|
|
2636
|
-
const sessionStore = yield import_mobile_wallet_protocol_core.SessionStore.create(kvstore);
|
|
2637
|
-
try {
|
|
2638
|
-
const [activeSession] = yield sessionStore.list();
|
|
2639
|
-
return activeSession;
|
|
2640
|
-
} catch (error) {
|
|
2641
|
-
logger("error getting active session", error);
|
|
2642
|
-
return void 0;
|
|
2643
|
-
}
|
|
2644
|
-
});
|
|
2645
|
-
}
|
|
2646
|
-
// This method checks if an existing CAIP session response is cached or waits for one
|
|
2647
|
-
// to be received from the wallet if not cached. This is necessary because there is an edge
|
|
2648
|
-
// case during the initial connection flow where after the user has accepted the permission approval
|
|
2649
|
-
// and returned back to the dapp from the wallet, the dapp page may have gotten unloaded and refreshed.
|
|
2650
|
-
// When it is unloaded and refreshed, it will try to resume the session by making a request for wallet_getSession
|
|
2651
|
-
// which should resolve from cache, but because a race condition makes it possible for the response from the wallet
|
|
2652
|
-
// for the initial wallet_createSession connection request to not have been handled and cached yet. This results
|
|
2653
|
-
// in the wallet_getSession request never resolving unless we wait for it explicitly as done in this method.
|
|
2654
|
-
waitForWalletSessionIfNotCached() {
|
|
2655
|
-
return __async(this, null, function* () {
|
|
2656
|
-
const cachedWalletGetSessionResponse = yield this.kvstore.get(SESSION_STORE_KEY);
|
|
2657
|
-
if (cachedWalletGetSessionResponse) {
|
|
2658
|
-
return;
|
|
2659
|
-
}
|
|
2660
|
-
let unsubscribe;
|
|
2661
|
-
const responsePromise = new Promise((resolve) => {
|
|
2662
|
-
unsubscribe = this.onNotification((message) => {
|
|
2663
|
-
if (typeof message === "object" && message !== null) {
|
|
2664
|
-
if ("data" in message) {
|
|
2665
|
-
const messagePayload = message.data;
|
|
2666
|
-
if (messagePayload.method === "wallet_getSession" || messagePayload.method === "wallet_sessionChanged") {
|
|
2667
|
-
unsubscribe();
|
|
2668
|
-
resolve();
|
|
2669
|
-
}
|
|
2670
|
-
}
|
|
2671
|
-
}
|
|
2672
|
-
});
|
|
2673
|
-
});
|
|
2674
|
-
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
2675
|
-
setTimeout(() => {
|
|
2676
|
-
unsubscribe();
|
|
2677
|
-
this.removeStoredPendingSessionRequest();
|
|
2678
|
-
reject(new import_multichain_api_client2.TransportTimeoutError());
|
|
2679
|
-
}, this.options.resumeTimeout);
|
|
2680
|
-
});
|
|
2681
|
-
return Promise.race([responsePromise, timeoutPromise]);
|
|
2682
|
-
});
|
|
2683
|
-
}
|
|
2684
|
-
};
|
|
2685
|
-
|
|
2686
|
-
// src/multichain/transports/mwp/KeyManager.ts
|
|
2687
|
-
var import_eciesjs = require("eciesjs");
|
|
2688
|
-
var KeyManager = class {
|
|
2689
|
-
generateKeyPair() {
|
|
2690
|
-
const privateKey = new import_eciesjs.PrivateKey();
|
|
2691
|
-
return {
|
|
2692
|
-
privateKey: new Uint8Array(privateKey.secret),
|
|
2693
|
-
publicKey: privateKey.publicKey.toBytes(true)
|
|
2694
|
-
};
|
|
2695
|
-
}
|
|
2696
|
-
encrypt(plaintext, theirPublicKey) {
|
|
2697
|
-
return __async(this, null, function* () {
|
|
2698
|
-
const plaintextBuffer = Buffer.from(plaintext, "utf8");
|
|
2699
|
-
const encryptedBuffer = (0, import_eciesjs.encrypt)(theirPublicKey, plaintextBuffer);
|
|
2700
|
-
return encryptedBuffer.toString("base64");
|
|
2701
|
-
});
|
|
2702
|
-
}
|
|
2703
|
-
decrypt(encryptedB64, myPrivateKey) {
|
|
2704
|
-
return __async(this, null, function* () {
|
|
2705
|
-
const encryptedBuffer = Buffer.from(encryptedB64, "base64");
|
|
2706
|
-
const decryptedBuffer = yield (0, import_eciesjs.decrypt)(myPrivateKey, encryptedBuffer);
|
|
2707
|
-
return Buffer.from(decryptedBuffer).toString("utf8");
|
|
2708
|
-
});
|
|
2709
|
-
}
|
|
2710
|
-
validatePeerKey(key) {
|
|
2711
|
-
import_eciesjs.PublicKey.fromHex(Buffer.from(key).toString("hex"));
|
|
2712
|
-
}
|
|
2713
|
-
};
|
|
2714
|
-
var keymanager = new KeyManager();
|
|
2715
|
-
|
|
2716
2865
|
// src/multichain/index.ts
|
|
2717
2866
|
init_utils();
|
|
2718
2867
|
var logger2 = createLogger("metamask-sdk:core");
|
|
2719
2868
|
var SINGLETON_KEY = "__METAMASK_CONNECT_MULTICHAIN_SINGLETON__";
|
|
2720
|
-
var _a, _provider, _providerTransportWrapper, _transport2, _dappClient, _beforeUnloadListener, _listener, _anonId, _sdkInfo, _MetaMaskConnectMultichain_instances, setupAnalytics_fn, onTransportNotification_fn, getStoredTransport_fn, setupTransport_fn, buildConnectionMetadata_fn, init_fn2, createDappClient_fn, setupMWP_fn, onBeforeUnload_fn, createBeforeUnloadListener_fn, renderInstallModalAsync_fn, showInstallModal_fn, headlessConnect_fn, setupDefaultTransport_fn, deeplinkConnect_fn, handleConnection_fn, getCaipSession_fn, openConnectDeeplinkIfNeeded_fn;
|
|
2869
|
+
var _a, _provider, _providerTransportWrapper, _transport2, _dappClient, _beforeUnloadListener, _transportType, _listener, _anonId, _sdkInfo, _MetaMaskConnectMultichain_instances, setupAnalytics_fn, onTransportNotification_fn, getStoredTransport_fn, setupTransport_fn, buildConnectionMetadata_fn, init_fn2, createDappClient_fn, setupMWP_fn, onBeforeUnload_fn, createBeforeUnloadListener_fn, renderInstallModalAsync_fn, showInstallModal_fn, headlessConnect_fn, setupDefaultTransport_fn, deeplinkConnect_fn, handleConnection_fn, getCaipSession_fn, openConnectDeeplinkIfNeeded_fn;
|
|
2721
2870
|
var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends MultichainCore {
|
|
2722
2871
|
constructor(options) {
|
|
2723
2872
|
var _a2, _b, _c, _d, _e, _f;
|
|
@@ -2735,7 +2884,7 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
|
|
|
2735
2884
|
versions: __spreadValues({
|
|
2736
2885
|
// typeof guard needed: Metro (React Native) bundles TS source directly,
|
|
2737
2886
|
// bypassing the tsup build that substitutes __PACKAGE_VERSION__.
|
|
2738
|
-
"connect-multichain": false ? "unknown" : "0.
|
|
2887
|
+
"connect-multichain": false ? "unknown" : "0.14.0"
|
|
2739
2888
|
}, (_f = options.versions) != null ? _f : {})
|
|
2740
2889
|
});
|
|
2741
2890
|
super(allOptions);
|
|
@@ -2745,6 +2894,7 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
|
|
|
2745
2894
|
__privateAdd(this, _transport2);
|
|
2746
2895
|
__privateAdd(this, _dappClient);
|
|
2747
2896
|
__privateAdd(this, _beforeUnloadListener);
|
|
2897
|
+
__privateAdd(this, _transportType);
|
|
2748
2898
|
this._status = "pending";
|
|
2749
2899
|
__privateAdd(this, _listener);
|
|
2750
2900
|
__privateAdd(this, _anonId);
|
|
@@ -2781,12 +2931,13 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
|
|
|
2781
2931
|
}
|
|
2782
2932
|
return __privateGet(this, _dappClient);
|
|
2783
2933
|
}
|
|
2934
|
+
get transportType() {
|
|
2935
|
+
var _a2;
|
|
2936
|
+
return (_a2 = __privateGet(this, _transportType)) != null ? _a2 : "unknown" /* UNKNOWN */;
|
|
2937
|
+
}
|
|
2784
2938
|
get storage() {
|
|
2785
2939
|
return this.options.storage;
|
|
2786
2940
|
}
|
|
2787
|
-
get transportType() {
|
|
2788
|
-
return __privateGet(this, _transport2) instanceof MWPTransport ? "mwp" /* MWP */ : "browser" /* Browser */;
|
|
2789
|
-
}
|
|
2790
2941
|
// Creates a singleton instance of MetaMaskConnectMultichain.
|
|
2791
2942
|
// If the singleton already exists, it merges the incoming options with the
|
|
2792
2943
|
// existing singleton options for the following keys: `api.supportedNetworks`,
|
|
@@ -2840,7 +2991,7 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
|
|
|
2840
2991
|
connect(scopes, caipAccountIds, sessionProperties, forceRequest) {
|
|
2841
2992
|
return __async(this, null, function* () {
|
|
2842
2993
|
var _a2;
|
|
2843
|
-
if (this.status === "connecting" && this
|
|
2994
|
+
if (this.status === "connecting" && __privateGet(this, _transportType) === "mwp" /* MWP */) {
|
|
2844
2995
|
yield __privateMethod(this, _MetaMaskConnectMultichain_instances, openConnectDeeplinkIfNeeded_fn).call(this);
|
|
2845
2996
|
throw new Error(
|
|
2846
2997
|
"Existing connection is pending. Please check your MetaMask Mobile app to continue."
|
|
@@ -2889,7 +3040,7 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
|
|
|
2889
3040
|
sessionProperties: nonEmptySessionProperties,
|
|
2890
3041
|
forceRequest
|
|
2891
3042
|
}).then(() => __async(this, null, function* () {
|
|
2892
|
-
if (__privateGet(this,
|
|
3043
|
+
if (__privateGet(this, _transportType) === "mwp" /* MWP */) {
|
|
2893
3044
|
return this.storage.setTransport("mwp" /* MWP */);
|
|
2894
3045
|
}
|
|
2895
3046
|
return this.storage.setTransport("browser" /* Browser */);
|
|
@@ -2936,12 +3087,13 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
|
|
|
2936
3087
|
yield (_a2 = __privateGet(this, _transport2)) == null ? void 0 : _a2.disconnect(scopes);
|
|
2937
3088
|
if (remainingScopes.length === 0) {
|
|
2938
3089
|
yield this.storage.removeTransport();
|
|
2939
|
-
if (this
|
|
3090
|
+
if (__privateGet(this, _transportType) !== "browser" /* Browser */) {
|
|
2940
3091
|
yield (_b = __privateGet(this, _listener)) == null ? void 0 : _b.call(this);
|
|
2941
3092
|
(_c = __privateGet(this, _beforeUnloadListener)) == null ? void 0 : _c.call(this);
|
|
2942
3093
|
__privateSet(this, _listener, void 0);
|
|
2943
3094
|
__privateSet(this, _beforeUnloadListener, void 0);
|
|
2944
3095
|
__privateSet(this, _transport2, void 0);
|
|
3096
|
+
__privateSet(this, _transportType, void 0);
|
|
2945
3097
|
__privateGet(this, _providerTransportWrapper).clearTransportNotificationListener();
|
|
2946
3098
|
__privateSet(this, _dappClient, void 0);
|
|
2947
3099
|
}
|
|
@@ -2951,13 +3103,14 @@ var _MetaMaskConnectMultichain = class _MetaMaskConnectMultichain extends Multic
|
|
|
2951
3103
|
}
|
|
2952
3104
|
invokeMethod(request) {
|
|
2953
3105
|
return __async(this, null, function* () {
|
|
3106
|
+
var _a2;
|
|
2954
3107
|
const { transport, options } = this;
|
|
2955
3108
|
const rpcClient = new RpcClient(options, __privateGet(this, _sdkInfo));
|
|
2956
3109
|
const requestRouter = new RequestRouter(
|
|
2957
3110
|
transport,
|
|
2958
3111
|
rpcClient,
|
|
2959
3112
|
options,
|
|
2960
|
-
this
|
|
3113
|
+
(_a2 = __privateGet(this, _transportType)) != null ? _a2 : "unknown" /* UNKNOWN */
|
|
2961
3114
|
);
|
|
2962
3115
|
return requestRouter.invokeMethod(request);
|
|
2963
3116
|
});
|
|
@@ -3006,6 +3159,7 @@ _providerTransportWrapper = new WeakMap();
|
|
|
3006
3159
|
_transport2 = new WeakMap();
|
|
3007
3160
|
_dappClient = new WeakMap();
|
|
3008
3161
|
_beforeUnloadListener = new WeakMap();
|
|
3162
|
+
_transportType = new WeakMap();
|
|
3009
3163
|
_listener = new WeakMap();
|
|
3010
3164
|
_anonId = new WeakMap();
|
|
3011
3165
|
_sdkInfo = new WeakMap();
|
|
@@ -3063,6 +3217,7 @@ getStoredTransport_fn = function() {
|
|
|
3063
3217
|
if (hasExtensionInstalled) {
|
|
3064
3218
|
const apiTransport = new DefaultTransport();
|
|
3065
3219
|
__privateSet(this, _transport2, apiTransport);
|
|
3220
|
+
__privateSet(this, _transportType, "browser" /* Browser */);
|
|
3066
3221
|
__privateGet(this, _providerTransportWrapper).setupTransportNotificationListener();
|
|
3067
3222
|
__privateSet(this, _listener, apiTransport.onNotification(
|
|
3068
3223
|
__privateMethod(this, _MetaMaskConnectMultichain_instances, onTransportNotification_fn).bind(this)
|
|
@@ -3072,9 +3227,11 @@ getStoredTransport_fn = function() {
|
|
|
3072
3227
|
} else if (transportType === "mwp" /* MWP */) {
|
|
3073
3228
|
const { adapter: kvstore } = this.options.storage;
|
|
3074
3229
|
const dappClient = yield __privateMethod(this, _MetaMaskConnectMultichain_instances, createDappClient_fn).call(this);
|
|
3075
|
-
const
|
|
3230
|
+
const { MWPTransport: MWPTransport2 } = yield Promise.resolve().then(() => (init_mwp(), mwp_exports));
|
|
3231
|
+
const apiTransport = new MWPTransport2(dappClient, kvstore);
|
|
3076
3232
|
__privateSet(this, _dappClient, dappClient);
|
|
3077
3233
|
__privateSet(this, _transport2, apiTransport);
|
|
3234
|
+
__privateSet(this, _transportType, "mwp" /* MWP */);
|
|
3078
3235
|
__privateGet(this, _providerTransportWrapper).setupTransportNotificationListener();
|
|
3079
3236
|
__privateSet(this, _listener, apiTransport.onNotification(
|
|
3080
3237
|
__privateMethod(this, _MetaMaskConnectMultichain_instances, onTransportNotification_fn).bind(this)
|
|
@@ -3096,7 +3253,7 @@ setupTransport_fn = function() {
|
|
|
3096
3253
|
yield this.transport.connect();
|
|
3097
3254
|
}
|
|
3098
3255
|
this.status = "connected";
|
|
3099
|
-
if (this
|
|
3256
|
+
if (__privateGet(this, _transportType) === "mwp" /* MWP */) {
|
|
3100
3257
|
yield this.storage.setTransport("mwp" /* MWP */);
|
|
3101
3258
|
} else {
|
|
3102
3259
|
yield this.storage.setTransport("browser" /* Browser */);
|
|
@@ -3140,31 +3297,43 @@ init_fn2 = function() {
|
|
|
3140
3297
|
};
|
|
3141
3298
|
createDappClient_fn = function() {
|
|
3142
3299
|
return __async(this, null, function* () {
|
|
3300
|
+
const [mwpCore, { DappClient: DappClientClass }, { createKeyManager: createKeyManager2 }] = yield Promise.all([
|
|
3301
|
+
import("@metamask/mobile-wallet-protocol-core"),
|
|
3302
|
+
import("@metamask/mobile-wallet-protocol-dapp-client"),
|
|
3303
|
+
Promise.resolve().then(() => (init_KeyManager(), KeyManager_exports))
|
|
3304
|
+
]);
|
|
3305
|
+
const keymanager = yield createKeyManager2();
|
|
3143
3306
|
const { adapter: kvstore } = this.options.storage;
|
|
3144
|
-
const sessionstore = yield
|
|
3307
|
+
const sessionstore = yield mwpCore.SessionStore.create(kvstore);
|
|
3145
3308
|
const websocket = (
|
|
3146
3309
|
// eslint-disable-next-line no-negated-condition
|
|
3147
3310
|
typeof window !== "undefined" ? WebSocket : (yield import("ws")).WebSocket
|
|
3148
3311
|
);
|
|
3149
|
-
const transport = yield
|
|
3312
|
+
const transport = yield mwpCore.WebSocketTransport.create({
|
|
3150
3313
|
url: MWP_RELAY_URL,
|
|
3151
3314
|
kvstore,
|
|
3152
3315
|
websocket
|
|
3153
3316
|
});
|
|
3154
|
-
const dappClient = new
|
|
3317
|
+
const dappClient = new DappClientClass({
|
|
3318
|
+
transport,
|
|
3319
|
+
sessionstore,
|
|
3320
|
+
keymanager
|
|
3321
|
+
});
|
|
3155
3322
|
return dappClient;
|
|
3156
3323
|
});
|
|
3157
3324
|
};
|
|
3158
3325
|
setupMWP_fn = function() {
|
|
3159
3326
|
return __async(this, null, function* () {
|
|
3160
|
-
if (__privateGet(this,
|
|
3327
|
+
if (__privateGet(this, _transportType) === "mwp" /* MWP */) {
|
|
3161
3328
|
return;
|
|
3162
3329
|
}
|
|
3163
3330
|
const { adapter: kvstore } = this.options.storage;
|
|
3164
3331
|
const dappClient = yield __privateMethod(this, _MetaMaskConnectMultichain_instances, createDappClient_fn).call(this);
|
|
3165
3332
|
__privateSet(this, _dappClient, dappClient);
|
|
3166
|
-
const
|
|
3333
|
+
const { MWPTransport: MWPTransport2 } = yield Promise.resolve().then(() => (init_mwp(), mwp_exports));
|
|
3334
|
+
const apiTransport = new MWPTransport2(dappClient, kvstore);
|
|
3167
3335
|
__privateSet(this, _transport2, apiTransport);
|
|
3336
|
+
__privateSet(this, _transportType, "mwp" /* MWP */);
|
|
3168
3337
|
__privateGet(this, _providerTransportWrapper).setupTransportNotificationListener();
|
|
3169
3338
|
__privateSet(this, _listener, this.transport.onNotification(
|
|
3170
3339
|
__privateMethod(this, _MetaMaskConnectMultichain_instances, onTransportNotification_fn).bind(this)
|
|
@@ -3223,8 +3392,9 @@ renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds,
|
|
|
3223
3392
|
this.status = "connected";
|
|
3224
3393
|
yield this.storage.setTransport("mwp" /* MWP */);
|
|
3225
3394
|
} catch (error) {
|
|
3226
|
-
|
|
3227
|
-
|
|
3395
|
+
const { ProtocolError, ErrorCode } = yield import("@metamask/mobile-wallet-protocol-core");
|
|
3396
|
+
if (error instanceof ProtocolError) {
|
|
3397
|
+
if (error.code !== ErrorCode.REQUEST_EXPIRED) {
|
|
3228
3398
|
this.status = "disconnected";
|
|
3229
3399
|
yield this.options.ui.factory.unload(error);
|
|
3230
3400
|
reject(error);
|
|
@@ -3292,7 +3462,8 @@ headlessConnect_fn = function(scopes, caipAccountIds, sessionProperties) {
|
|
|
3292
3462
|
yield this.storage.setTransport("mwp" /* MWP */);
|
|
3293
3463
|
resolve();
|
|
3294
3464
|
})).catch((error) => __async(this, null, function* () {
|
|
3295
|
-
|
|
3465
|
+
const { ProtocolError } = yield import("@metamask/mobile-wallet-protocol-core");
|
|
3466
|
+
if (error instanceof ProtocolError) {
|
|
3296
3467
|
this.status = "disconnected";
|
|
3297
3468
|
yield this.storage.removeTransport();
|
|
3298
3469
|
reject(error);
|
|
@@ -3307,7 +3478,7 @@ headlessConnect_fn = function(scopes, caipAccountIds, sessionProperties) {
|
|
|
3307
3478
|
};
|
|
3308
3479
|
setupDefaultTransport_fn = function() {
|
|
3309
3480
|
return __async(this, arguments, function* (options = { persist: true }) {
|
|
3310
|
-
if (__privateGet(this,
|
|
3481
|
+
if (__privateGet(this, _transportType) === "browser" /* Browser */) {
|
|
3311
3482
|
return __privateGet(this, _transport2);
|
|
3312
3483
|
}
|
|
3313
3484
|
if (options == null ? void 0 : options.persist) {
|
|
@@ -3318,6 +3489,7 @@ setupDefaultTransport_fn = function() {
|
|
|
3318
3489
|
__privateMethod(this, _MetaMaskConnectMultichain_instances, onTransportNotification_fn).bind(this)
|
|
3319
3490
|
));
|
|
3320
3491
|
__privateSet(this, _transport2, transport);
|
|
3492
|
+
__privateSet(this, _transportType, "browser" /* Browser */);
|
|
3321
3493
|
__privateGet(this, _providerTransportWrapper).setupTransportNotificationListener();
|
|
3322
3494
|
return transport;
|
|
3323
3495
|
});
|
|
@@ -3414,9 +3586,9 @@ handleConnection_fn = function(promise, scopes, transportType) {
|
|
|
3414
3586
|
transport_type: transportType
|
|
3415
3587
|
}));
|
|
3416
3588
|
} else {
|
|
3417
|
-
import_analytics4.analytics.track("mmconnect_connection_failed", __spreadProps(__spreadValues({}, baseProps), {
|
|
3589
|
+
import_analytics4.analytics.track("mmconnect_connection_failed", __spreadValues(__spreadProps(__spreadValues({}, baseProps), {
|
|
3418
3590
|
transport_type: transportType
|
|
3419
|
-
}));
|
|
3591
|
+
}), extractErrorDiagnostics(error)));
|
|
3420
3592
|
}
|
|
3421
3593
|
} catch (e) {
|
|
3422
3594
|
logger2("Error tracking connection failed/rejected event", error);
|
|
@@ -3862,6 +4034,7 @@ var createMultichainClient = (options) => __async(null, null, function* () {
|
|
|
3862
4034
|
StoreAdapter,
|
|
3863
4035
|
StoreClient,
|
|
3864
4036
|
TransportType,
|
|
4037
|
+
classifyFailureReason,
|
|
3865
4038
|
createLogger,
|
|
3866
4039
|
createMultichainClient,
|
|
3867
4040
|
enableDebug,
|