@metamask/connect-multichain 1.0.0 → 1.1.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.
Files changed (44) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/dist/browser/es/connect-multichain.d.mts +11 -2
  3. package/dist/browser/es/connect-multichain.mjs +111 -14
  4. package/dist/browser/es/connect-multichain.mjs.map +1 -1
  5. package/dist/browser/es/metafile-esm.json +1 -1
  6. package/dist/browser/iife/connect-multichain.d.ts +11 -2
  7. package/dist/browser/iife/connect-multichain.js +110 -13
  8. package/dist/browser/iife/connect-multichain.js.map +1 -1
  9. package/dist/browser/iife/metafile-iife.json +1 -1
  10. package/dist/browser/umd/connect-multichain.d.ts +11 -2
  11. package/dist/browser/umd/connect-multichain.js +119 -22
  12. package/dist/browser/umd/connect-multichain.js.map +1 -1
  13. package/dist/browser/umd/metafile-cjs.json +1 -1
  14. package/dist/node/cjs/connect-multichain.d.ts +11 -2
  15. package/dist/node/cjs/connect-multichain.js +119 -22
  16. package/dist/node/cjs/connect-multichain.js.map +1 -1
  17. package/dist/node/cjs/metafile-cjs.json +1 -1
  18. package/dist/node/es/connect-multichain.d.mts +11 -2
  19. package/dist/node/es/connect-multichain.mjs +111 -14
  20. package/dist/node/es/connect-multichain.mjs.map +1 -1
  21. package/dist/node/es/metafile-esm.json +1 -1
  22. package/dist/react-native/es/connect-multichain.d.mts +11 -2
  23. package/dist/react-native/es/connect-multichain.mjs +111 -14
  24. package/dist/react-native/es/connect-multichain.mjs.map +1 -1
  25. package/dist/react-native/es/metafile-esm.json +1 -1
  26. package/dist/src/domain/errors/rpc.d.ts +11 -1
  27. package/dist/src/domain/errors/rpc.d.ts.map +1 -1
  28. package/dist/src/domain/errors/rpc.js +10 -2
  29. package/dist/src/domain/errors/rpc.js.map +1 -1
  30. package/dist/src/multichain/rpc/invocationError.d.ts +9 -0
  31. package/dist/src/multichain/rpc/invocationError.d.ts.map +1 -0
  32. package/dist/src/multichain/rpc/invocationError.js +99 -0
  33. package/dist/src/multichain/rpc/invocationError.js.map +1 -0
  34. package/dist/src/multichain/rpc/requestRouter.d.ts.map +1 -1
  35. package/dist/src/multichain/rpc/requestRouter.js +10 -18
  36. package/dist/src/multichain/rpc/requestRouter.js.map +1 -1
  37. package/dist/src/multichain/transports/default/index.d.ts.map +1 -1
  38. package/dist/src/multichain/transports/default/index.js +9 -0
  39. package/dist/src/multichain/transports/default/index.js.map +1 -1
  40. package/dist/src/multichain/transports/mwp/index.d.ts.map +1 -1
  41. package/dist/src/multichain/transports/mwp/index.js +9 -3
  42. package/dist/src/multichain/transports/mwp/index.js.map +1 -1
  43. package/dist/types/connect-multichain.d.ts +11 -2
  44. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
+ import { Json, CaipAccountId, CaipChainId } from '@metamask/utils';
1
2
  import debug from 'debug';
2
3
  import { SessionData, Transport, SessionProperties, TransportRequest, TransportResponse, MultichainApiClient } from '@metamask/multichain-api-client';
3
4
  export { SessionData } from '@metamask/multichain-api-client';
4
- import { CaipAccountId, CaipChainId, Json } from '@metamask/utils';
5
5
  import { SessionRequest, Session } from '@metamask/mobile-wallet-protocol-core';
6
6
  import { Components } from '@metamask/multichain-ui';
7
7
 
@@ -39,8 +39,17 @@ declare class RPCInvokeMethodErr extends BaseErr<'RPC', RPCErrorCodes> {
39
39
  readonly reason: string;
40
40
  readonly rpcCode?: number | undefined;
41
41
  readonly rpcMessage?: string | undefined;
42
+ readonly rpcData?: Json | undefined;
42
43
  static readonly code = 53;
43
- constructor(reason: string, rpcCode?: number | undefined, rpcMessage?: string | undefined);
44
+ /**
45
+ * @param reason - MetaMask Connect invokeMethod reason.
46
+ * @param rpcCode - Original wallet JSON-RPC / EIP-1193 error code.
47
+ * @param rpcMessage - Original provider-facing wallet message, sourced only
48
+ * from the wallet's coded error. Unset when the wallet provides no message,
49
+ * so it may differ from `reason`, which can fall back through the cause chain.
50
+ * @param rpcData - Original JSON-RPC error data, when provided by the wallet.
51
+ */
52
+ constructor(reason: string, rpcCode?: number | undefined, rpcMessage?: string | undefined, rpcData?: Json | undefined);
44
53
  }
45
54
 
46
55
  type SDKEvents = {
@@ -133,7 +133,15 @@ var init_rpc = __esm({
133
133
  _RPCReadonlyRequestErr.code = 52;
134
134
  RPCReadonlyRequestErr = _RPCReadonlyRequestErr;
135
135
  _RPCInvokeMethodErr = class _RPCInvokeMethodErr extends BaseErr {
136
- constructor(reason, rpcCode, rpcMessage) {
136
+ /**
137
+ * @param reason - MetaMask Connect invokeMethod reason.
138
+ * @param rpcCode - Original wallet JSON-RPC / EIP-1193 error code.
139
+ * @param rpcMessage - Original provider-facing wallet message, sourced only
140
+ * from the wallet's coded error. Unset when the wallet provides no message,
141
+ * so it may differ from `reason`, which can fall back through the cause chain.
142
+ * @param rpcData - Original JSON-RPC error data, when provided by the wallet.
143
+ */
144
+ constructor(reason, rpcCode, rpcMessage, rpcData) {
137
145
  super(
138
146
  `RPCErr${_RPCInvokeMethodErr.code}: RPC Client invoke method reason (${reason})`,
139
147
  _RPCInvokeMethodErr.code
@@ -141,6 +149,7 @@ var init_rpc = __esm({
141
149
  this.reason = reason;
142
150
  this.rpcCode = rpcCode;
143
151
  this.rpcMessage = rpcMessage;
152
+ this.rpcData = rpcData;
144
153
  }
145
154
  };
146
155
  _RPCInvokeMethodErr.code = 53;
@@ -891,7 +900,7 @@ var init_utils = __esm({
891
900
  "src/domain/utils/index.ts"() {
892
901
  "use strict";
893
902
  init_analytics();
894
- packageVersion = false ? "unknown" : "1.0.0";
903
+ packageVersion = false ? "unknown" : "1.1.0";
895
904
  }
896
905
  });
897
906
 
@@ -1191,13 +1200,13 @@ var mwp_exports = {};
1191
1200
  __export(mwp_exports, {
1192
1201
  MWPTransport: () => MWPTransport
1193
1202
  });
1194
- var import_multichain_api_client2, import_rpc_errors2, import_utils6, 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_instances, onResumeHandler_fn, resumeSession_fn, startSession_fn, MWPTransport;
1203
+ var import_multichain_api_client2, import_rpc_errors2, import_utils8, 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_instances, onResumeHandler_fn, resumeSession_fn, startSession_fn, MWPTransport;
1195
1204
  var init_mwp = __esm({
1196
1205
  "src/multichain/transports/mwp/index.ts"() {
1197
1206
  "use strict";
1198
1207
  import_multichain_api_client2 = require("@metamask/multichain-api-client");
1199
1208
  import_rpc_errors2 = require("@metamask/rpc-errors");
1200
- import_utils6 = require("@metamask/utils");
1209
+ import_utils8 = require("@metamask/utils");
1201
1210
  init_domain();
1202
1211
  init_utils2();
1203
1212
  init_constants2();
@@ -1300,10 +1309,12 @@ var init_mwp = __esm({
1300
1309
  const errorData = errorPayload;
1301
1310
  if (typeof errorData.code === "number" && typeof errorData.message === "string") {
1302
1311
  const { code, message: message2 } = errorData;
1312
+ const rawData = errorData.data;
1313
+ const data = (0, import_utils8.isValidJson)(rawData) ? rawData : void 0;
1303
1314
  if (code >= 1e3 && code <= 4999) {
1304
- return import_rpc_errors2.providerErrors.custom({ code, message: message2 });
1315
+ return import_rpc_errors2.providerErrors.custom({ code, message: message2, data });
1305
1316
  }
1306
- return new import_rpc_errors2.JsonRpcError(code, message2);
1317
+ return new import_rpc_errors2.JsonRpcError(code, message2, data);
1307
1318
  }
1308
1319
  const message = errorPayload instanceof Error ? errorPayload.message : JSON.stringify(errorPayload);
1309
1320
  return import_rpc_errors2.rpcErrors.internal({ message });
@@ -1757,7 +1768,7 @@ var init_mwp = __esm({
1757
1768
  return __async(this, null, function* () {
1758
1769
  var _a3;
1759
1770
  const isContinuingPriorAttempt = (yield this.getStoredPendingSessionRequest()) !== null;
1760
- const resumeDeferred = (0, import_utils6.createDeferredPromise)();
1771
+ const resumeDeferred = (0, import_utils8.createDeferredPromise)();
1761
1772
  const runOnResumeHandler = () => __async(this, null, function* () {
1762
1773
  try {
1763
1774
  resumeDeferred.resolve(yield __privateMethod(this, _MWPTransport_instances, onResumeHandler_fn).call(this, options));
@@ -1771,7 +1782,7 @@ var init_mwp = __esm({
1771
1782
  this.dappClient.once("connected", runOnResumeHandler);
1772
1783
  this.dappClient.resume((_a3 = session.id) != null ? _a3 : "").catch((err) => resumeDeferred.reject(err));
1773
1784
  }
1774
- const timeoutDeferred = (0, import_utils6.createDeferredPromise)();
1785
+ const timeoutDeferred = (0, import_utils8.createDeferredPromise)();
1775
1786
  const timeout = setTimeout(
1776
1787
  () => timeoutDeferred.reject(new import_multichain_api_client2.TransportTimeoutError()),
1777
1788
  isContinuingPriorAttempt ? this.options.resumeTimeout : this.options.connectionTimeout
@@ -1791,7 +1802,7 @@ var init_mwp = __esm({
1791
1802
  var _a3, _b;
1792
1803
  const { dappClient } = this;
1793
1804
  const isContinuingPriorAttempt = (yield this.getStoredPendingSessionRequest()) !== null;
1794
- const connDeferred = (0, import_utils6.createDeferredPromise)();
1805
+ const connDeferred = (0, import_utils8.createDeferredPromise)();
1795
1806
  const optionalScopes = addValidAccounts(
1796
1807
  getOptionalScopes((_a3 = options == null ? void 0 : options.scopes) != null ? _a3 : []),
1797
1808
  getValidAccounts((_b = options == null ? void 0 : options.caipAccountIds) != null ? _b : [])
@@ -1858,7 +1869,7 @@ var init_mwp = __esm({
1858
1869
  }
1859
1870
  return void 0;
1860
1871
  })).catch((error) => connDeferred.reject(error));
1861
- const timeoutDeferred = (0, import_utils6.createDeferredPromise)();
1872
+ const timeoutDeferred = (0, import_utils8.createDeferredPromise)();
1862
1873
  const timeout = setTimeout(
1863
1874
  () => timeoutDeferred.reject(new import_multichain_api_client2.TransportTimeoutError()),
1864
1875
  isContinuingPriorAttempt ? this.options.resumeTimeout : this.options.connectionTimeout
@@ -2274,7 +2285,7 @@ init_domain();
2274
2285
  // src/multichain/index.ts
2275
2286
  var import_analytics4 = require("@metamask/analytics");
2276
2287
  var import_multichain_api_client3 = require("@metamask/multichain-api-client");
2277
- var import_utils8 = require("@metamask/utils");
2288
+ var import_utils10 = require("@metamask/utils");
2278
2289
 
2279
2290
  // src/config/index.ts
2280
2291
  var MWP_RELAY_URL = "wss://mm-sdk-relay.api.cx.metamask.io/connection/websocket";
@@ -2398,17 +2409,93 @@ var import_analytics2 = require("@metamask/analytics");
2398
2409
  init_domain();
2399
2410
  init_utils2();
2400
2411
  init_analytics();
2412
+
2413
+ // src/multichain/rpc/invocationError.ts
2414
+ var import_utils3 = require("@metamask/utils");
2415
+ init_domain();
2416
+ var MAX_ERROR_CAUSE_DEPTH = 5;
2417
+ function getErrorObject(value) {
2418
+ if (typeof value === "object" && value !== null) {
2419
+ return value;
2420
+ }
2421
+ return void 0;
2422
+ }
2423
+ function getNumericCode(value) {
2424
+ return typeof value === "number" ? value : void 0;
2425
+ }
2426
+ function getNonEmptyMessage(value) {
2427
+ return typeof value === "string" && value.length > 0 ? value : void 0;
2428
+ }
2429
+ function getJsonData(value) {
2430
+ return value !== void 0 && (0, import_utils3.isValidJson)(value) ? value : void 0;
2431
+ }
2432
+ function getFirstNonEmptyMessage(values) {
2433
+ for (const value of values) {
2434
+ const message = getNonEmptyMessage(value);
2435
+ if (message !== void 0) {
2436
+ return message;
2437
+ }
2438
+ }
2439
+ return void 0;
2440
+ }
2441
+ function getErrorObjectChain(errorObject) {
2442
+ const chain = [];
2443
+ let currentObject = errorObject;
2444
+ for (let depth = 0; currentObject !== void 0 && depth < MAX_ERROR_CAUSE_DEPTH; depth += 1) {
2445
+ chain.push(currentObject);
2446
+ currentObject = getErrorObject(currentObject.cause);
2447
+ }
2448
+ return chain;
2449
+ }
2450
+ function getCodedErrorDetails(value) {
2451
+ const code = getNumericCode(value == null ? void 0 : value.code);
2452
+ if (code === void 0) {
2453
+ return void 0;
2454
+ }
2455
+ const message = getNonEmptyMessage(value == null ? void 0 : value.message);
2456
+ const data = getJsonData(value == null ? void 0 : value.data);
2457
+ return __spreadValues(__spreadValues({
2458
+ code
2459
+ }, message === void 0 ? {} : { message }), data === void 0 ? {} : { data });
2460
+ }
2461
+ function getInvocationErrorDetails(error) {
2462
+ var _a3, _b, _c, _d;
2463
+ const errorObject = getErrorObject(error);
2464
+ const errorObjectChain = getErrorObjectChain(errorObject);
2465
+ const primitiveMessage = getNonEmptyMessage(error);
2466
+ for (const [index, currentObject] of errorObjectChain.entries()) {
2467
+ const codedDetails = getCodedErrorDetails(currentObject);
2468
+ if (codedDetails) {
2469
+ const descendantObjects = errorObjectChain.slice(index + 1);
2470
+ const ancestorObjects = errorObjectChain.slice(0, index);
2471
+ const descendantMessage = getFirstNonEmptyMessage(
2472
+ descendantObjects.map((object) => object.message)
2473
+ );
2474
+ const ancestorMessage = getFirstNonEmptyMessage([
2475
+ primitiveMessage,
2476
+ ...ancestorObjects.map((object) => object.message)
2477
+ ]);
2478
+ const reason2 = (_c = (_b = (_a3 = codedDetails.message) != null ? _a3 : descendantMessage) != null ? _b : ancestorMessage) != null ? _c : "Unknown error";
2479
+ return __spreadValues(__spreadValues({
2480
+ reason: reason2,
2481
+ rpcCode: codedDetails.code
2482
+ }, codedDetails.message === void 0 ? {} : { rpcMessage: codedDetails.message }), codedDetails.data === void 0 ? {} : { rpcData: codedDetails.data });
2483
+ }
2484
+ }
2485
+ const reason = (_d = primitiveMessage != null ? primitiveMessage : getFirstNonEmptyMessage(errorObjectChain.map((object) => object.message))) != null ? _d : "Unknown error";
2486
+ return {
2487
+ reason
2488
+ };
2489
+ }
2401
2490
  function toRPCInvokeMethodErr(error) {
2402
- var _a3;
2403
2491
  if (error instanceof RPCInvokeMethodErr) {
2404
2492
  return error;
2405
2493
  }
2406
- const castError = error;
2407
- return new RPCInvokeMethodErr(
2408
- (_a3 = castError.message) != null ? _a3 : "Unknown error",
2409
- castError.code
2410
- );
2494
+ const { reason, rpcCode, rpcMessage, rpcData } = getInvocationErrorDetails(error);
2495
+ return new RPCInvokeMethodErr(reason, rpcCode, rpcMessage, rpcData);
2411
2496
  }
2497
+
2498
+ // src/multichain/rpc/requestRouter.ts
2412
2499
  var _RequestRouter_instances, withAnalyticsTracking_fn, trackWalletActionRequested_fn, trackWalletActionSucceeded_fn, trackWalletActionFailed_fn, trackWalletActionRejected_fn;
2413
2500
  var RequestRouter = class {
2414
2501
  constructor(transport, rpcClient, config, transportType) {
@@ -2494,6 +2581,9 @@ var RequestRouter = class {
2494
2581
  }), 10);
2495
2582
  }
2496
2583
  const response = yield request;
2584
+ if (response.error) {
2585
+ throw toRPCInvokeMethodErr(response.error);
2586
+ }
2497
2587
  return response.result;
2498
2588
  }));
2499
2589
  });
@@ -2546,13 +2636,15 @@ withAnalyticsTracking_fn = function(options, execute) {
2546
2636
  yield __privateMethod(this, _RequestRouter_instances, trackWalletActionSucceeded_fn).call(this, options);
2547
2637
  return result;
2548
2638
  } catch (error) {
2549
- const isRejection = isRejectionError(error);
2639
+ const normalizedError = toRPCInvokeMethodErr(error);
2640
+ const analyticsError = normalizedError.rpcCode === void 0 ? error : normalizedError;
2641
+ const isRejection = isRejectionError(analyticsError);
2550
2642
  if (isRejection) {
2551
2643
  yield __privateMethod(this, _RequestRouter_instances, trackWalletActionRejected_fn).call(this, options);
2552
2644
  } else {
2553
- yield __privateMethod(this, _RequestRouter_instances, trackWalletActionFailed_fn).call(this, options, error);
2645
+ yield __privateMethod(this, _RequestRouter_instances, trackWalletActionFailed_fn).call(this, options, analyticsError);
2554
2646
  }
2555
- throw toRPCInvokeMethodErr(error);
2647
+ throw normalizedError;
2556
2648
  }
2557
2649
  });
2558
2650
  };
@@ -2604,6 +2696,7 @@ trackWalletActionRejected_fn = function(options) {
2604
2696
 
2605
2697
  // src/multichain/transports/default/index.ts
2606
2698
  var import_multichain_api_client = require("@metamask/multichain-api-client");
2699
+ var import_utils5 = require("@metamask/utils");
2607
2700
  init_utils2();
2608
2701
  var DEFAULT_REQUEST_TIMEOUT = 60 * 1e3;
2609
2702
  var _notificationCallbacks, _transport, _defaultRequestOptions, _pendingRequests, _handleResponseListener, _handleNotificationListener, _DefaultTransport_instances, notifyCallbacks_fn, parseWalletError_fn, isMetamaskProviderEvent_fn, handleResponse_fn, handleNotification_fn, setupMessageListener_fn, init_fn;
@@ -2798,6 +2891,10 @@ parseWalletError_fn = function(errorPayload) {
2798
2891
  if (typeof errorData.code === "number") {
2799
2892
  error.code = errorData.code;
2800
2893
  }
2894
+ const { data } = errorData;
2895
+ if ((0, import_utils5.isValidJson)(data)) {
2896
+ error.data = data;
2897
+ }
2801
2898
  return error;
2802
2899
  };
2803
2900
  isMetamaskProviderEvent_fn = function(event) {
@@ -3544,12 +3641,12 @@ createBeforeUnloadListener_fn = function() {
3544
3641
  };
3545
3642
  renderInstallModalAsync_fn = function(desktopPreferred, scopes, caipAccountIds, sessionProperties) {
3546
3643
  return __async(this, null, function* () {
3547
- const completion = (0, import_utils8.createDeferredPromise)();
3644
+ const completion = (0, import_utils10.createDeferredPromise)();
3548
3645
  const createConnectionRequest = () => __async(this, null, function* () {
3549
3646
  if (this.dappClient.state === "CONNECTED" || this.dappClient.state === "CONNECTING") {
3550
3647
  yield this.dappClient.disconnect();
3551
3648
  }
3552
- const sessionRequestDeferred = (0, import_utils8.createDeferredPromise)();
3649
+ const sessionRequestDeferred = (0, import_utils10.createDeferredPromise)();
3553
3650
  this.dappClient.on(
3554
3651
  "session_request",
3555
3652
  (sessionRequest) => {