@metamask/connect-multichain 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +8 -1
  2. package/dist/browser/es/connect-multichain.d.mts +25 -1
  3. package/dist/browser/es/connect-multichain.mjs +437 -234
  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 +25 -1
  7. package/dist/browser/iife/connect-multichain.js +21353 -14490
  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 +25 -1
  11. package/dist/browser/umd/connect-multichain.js +434 -231
  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 +25 -1
  15. package/dist/node/cjs/connect-multichain.js +437 -232
  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 +25 -1
  19. package/dist/node/es/connect-multichain.mjs +438 -235
  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 +25 -1
  23. package/dist/react-native/es/connect-multichain.mjs +437 -234
  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/utils/index.d.ts +1 -0
  27. package/dist/src/domain/utils/index.d.ts.map +1 -1
  28. package/dist/src/domain/utils/index.js +1 -0
  29. package/dist/src/domain/utils/index.js.map +1 -1
  30. package/dist/src/multichain/index.d.ts.map +1 -1
  31. package/dist/src/multichain/index.js +73 -17
  32. package/dist/src/multichain/index.js.map +1 -1
  33. package/dist/src/multichain/rpc/requestRouter.d.ts +1 -0
  34. package/dist/src/multichain/rpc/requestRouter.d.ts.map +1 -1
  35. package/dist/src/multichain/rpc/requestRouter.js +69 -13
  36. package/dist/src/multichain/rpc/requestRouter.js.map +1 -1
  37. package/dist/src/multichain/utils/analytics.d.ts +39 -0
  38. package/dist/src/multichain/utils/analytics.d.ts.map +1 -0
  39. package/dist/src/multichain/utils/analytics.js +83 -0
  40. package/dist/src/multichain/utils/analytics.js.map +1 -0
  41. package/dist/types/connect-multichain.d.ts +25 -1
  42. package/package.json +2 -2
@@ -583,13 +583,265 @@ var init_ui = __esm({
583
583
  }
584
584
  });
585
585
 
586
+ // src/multichain/utils/index.ts
587
+ import { deflate } from "pako";
588
+ import {
589
+ parseCaipAccountId,
590
+ parseCaipChainId
591
+ } from "@metamask/utils";
592
+ function base64Encode(str) {
593
+ if (typeof btoa !== "undefined") {
594
+ return btoa(str);
595
+ } else if (typeof Buffer !== "undefined") {
596
+ return Buffer.from(str).toString("base64");
597
+ }
598
+ throw new Error("No base64 encoding method available");
599
+ }
600
+ function compressString(str) {
601
+ const compressed = deflate(str);
602
+ const binaryString = String.fromCharCode.apply(null, Array.from(compressed));
603
+ return base64Encode(binaryString);
604
+ }
605
+ function getDappId(dapp) {
606
+ var _a, _b;
607
+ if (typeof window === "undefined" || typeof window.location === "undefined") {
608
+ return (_b = (_a = dapp == null ? void 0 : dapp.name) != null ? _a : dapp == null ? void 0 : dapp.url) != null ? _b : "N/A";
609
+ }
610
+ return window.location.hostname;
611
+ }
612
+ function openDeeplink(options, deeplink, universalLink) {
613
+ const { mobile } = options;
614
+ const useDeeplink = mobile && mobile.useDeeplink !== void 0 ? mobile.useDeeplink : true;
615
+ if (useDeeplink) {
616
+ if (typeof window !== "undefined") {
617
+ window.location.href = deeplink;
618
+ }
619
+ } else if (typeof document !== "undefined") {
620
+ const link = document.createElement("a");
621
+ link.href = universalLink;
622
+ link.target = "_self";
623
+ link.rel = "noreferrer noopener";
624
+ link.click();
625
+ }
626
+ }
627
+ function getOptionalScopes(scopes) {
628
+ return scopes.reduce(
629
+ (prev, scope) => __spreadProps(__spreadValues({}, prev), {
630
+ [scope]: {
631
+ methods: [],
632
+ notifications: [],
633
+ accounts: []
634
+ }
635
+ }),
636
+ {}
637
+ );
638
+ }
639
+ function setupDappMetadata(options) {
640
+ var _a;
641
+ const platform = getPlatformType();
642
+ const isBrowser = platform === "web-desktop" /* DesktopWeb */ || platform === "web-mobile" /* MobileWeb */ || platform === "in-app-browser" /* MetaMaskMobileWebview */;
643
+ if (!((_a = options.dapp) == null ? void 0 : _a.url)) {
644
+ if (isBrowser) {
645
+ options.dapp = __spreadProps(__spreadValues({}, options.dapp), {
646
+ url: `${window.location.protocol}//${window.location.host}`
647
+ });
648
+ } else {
649
+ throw new Error("You must provide dapp url");
650
+ }
651
+ }
652
+ const BASE_64_ICON_MAX_LENGTH = 163400;
653
+ const urlPattern = /^(http|https):\/\/[^\s]*$/;
654
+ if (options.dapp) {
655
+ if ("iconUrl" in options.dapp) {
656
+ if (options.dapp.iconUrl && !urlPattern.test(options.dapp.iconUrl)) {
657
+ console.warn(
658
+ "Invalid dappMetadata.iconUrl: URL must start with http:// or https://"
659
+ );
660
+ options.dapp.iconUrl = void 0;
661
+ }
662
+ }
663
+ if ("base64Icon" in options.dapp) {
664
+ if (options.dapp.base64Icon && options.dapp.base64Icon.length > BASE_64_ICON_MAX_LENGTH) {
665
+ console.warn(
666
+ "Invalid dappMetadata.base64Icon: Base64-encoded icon string length must be less than 163400 characters"
667
+ );
668
+ options.dapp.base64Icon = void 0;
669
+ }
670
+ }
671
+ if (options.dapp.url && !urlPattern.test(options.dapp.url)) {
672
+ console.warn(
673
+ "Invalid dappMetadata.url: URL must start with http:// or https://"
674
+ );
675
+ }
676
+ const favicon = extractFavicon();
677
+ if (favicon && !("iconUrl" in options.dapp) && !("base64Icon" in options.dapp)) {
678
+ const faviconUrl = `${window.location.protocol}//${window.location.host}${favicon}`;
679
+ options.dapp.iconUrl = faviconUrl;
680
+ }
681
+ }
682
+ return options;
683
+ }
684
+ function isSameScopesAndAccounts(currentScopes, proposedScopes, walletSession, proposedCaipAccountIds) {
685
+ const isSameScopes = currentScopes.every((scope) => proposedScopes.includes(scope)) && proposedScopes.every((scope) => currentScopes.includes(scope));
686
+ if (!isSameScopes) {
687
+ return false;
688
+ }
689
+ const existingAccountIds = Object.values(
690
+ walletSession.sessionScopes
691
+ ).filter(({ accounts }) => Boolean(accounts)).flatMap(({ accounts }) => accounts != null ? accounts : []);
692
+ const allProposedAccountsIncluded = proposedCaipAccountIds.every(
693
+ (proposedAccountId) => existingAccountIds.includes(proposedAccountId)
694
+ );
695
+ return allProposedAccountsIncluded;
696
+ }
697
+ function getValidAccounts(caipAccountIds) {
698
+ return caipAccountIds.reduce(
699
+ (caipAccounts, caipAccountId) => {
700
+ try {
701
+ return [...caipAccounts, parseCaipAccountId(caipAccountId)];
702
+ } catch (err) {
703
+ const stringifiedAccountId = JSON.stringify(caipAccountId);
704
+ console.error(`Invalid CAIP account ID: ${stringifiedAccountId}`, err);
705
+ return caipAccounts;
706
+ }
707
+ },
708
+ []
709
+ );
710
+ }
711
+ function addValidAccounts(optionalScopes, validAccounts) {
712
+ var _a;
713
+ if (!optionalScopes || !(validAccounts == null ? void 0 : validAccounts.length)) {
714
+ return optionalScopes;
715
+ }
716
+ const result = Object.fromEntries(
717
+ Object.entries(optionalScopes).map(([scope, scopeData]) => {
718
+ var _a2, _b, _c;
719
+ return [
720
+ scope,
721
+ {
722
+ methods: [...(_a2 = scopeData == null ? void 0 : scopeData.methods) != null ? _a2 : []],
723
+ notifications: [...(_b = scopeData == null ? void 0 : scopeData.notifications) != null ? _b : []],
724
+ accounts: [...(_c = scopeData == null ? void 0 : scopeData.accounts) != null ? _c : []]
725
+ }
726
+ ];
727
+ })
728
+ );
729
+ const accountsByChain = /* @__PURE__ */ new Map();
730
+ for (const account of validAccounts) {
731
+ const chainKey = `${account.chain.namespace}:${account.chain.reference}`;
732
+ const accountId = `${account.chainId}:${account.address}`;
733
+ if (!accountsByChain.has(chainKey)) {
734
+ accountsByChain.set(chainKey, []);
735
+ }
736
+ (_a = accountsByChain.get(chainKey)) == null ? void 0 : _a.push(accountId);
737
+ }
738
+ for (const [scopeKey, scopeData] of Object.entries(result)) {
739
+ if (!(scopeData == null ? void 0 : scopeData.accounts)) {
740
+ continue;
741
+ }
742
+ try {
743
+ const scope = scopeKey;
744
+ const scopeDetails = parseCaipChainId(scope);
745
+ const chainKey = `${scopeDetails.namespace}:${scopeDetails.reference}`;
746
+ const matchingAccounts = accountsByChain.get(chainKey);
747
+ if (matchingAccounts) {
748
+ const existingAccounts = new Set(scopeData.accounts);
749
+ const newAccounts = matchingAccounts.filter(
750
+ (account) => !existingAccounts.has(account)
751
+ );
752
+ scopeData.accounts.push(...newAccounts);
753
+ }
754
+ } catch (error) {
755
+ console.error(`Invalid scope format: ${scopeKey}`, error);
756
+ }
757
+ }
758
+ return result;
759
+ }
760
+ var extractFavicon;
761
+ var init_utils = __esm({
762
+ "src/multichain/utils/index.ts"() {
763
+ "use strict";
764
+ init_domain();
765
+ extractFavicon = () => {
766
+ var _a;
767
+ if (typeof document === "undefined") {
768
+ return void 0;
769
+ }
770
+ let favicon;
771
+ const nodeList = document.getElementsByTagName("link");
772
+ for (let i = 0; i < nodeList.length; i++) {
773
+ if (nodeList[i].getAttribute("rel") === "icon" || nodeList[i].getAttribute("rel") === "shortcut icon") {
774
+ favicon = (_a = nodeList[i].getAttribute("href")) != null ? _a : void 0;
775
+ }
776
+ }
777
+ return favicon;
778
+ };
779
+ }
780
+ });
781
+
782
+ // src/multichain/utils/analytics.ts
783
+ function isRejectionError(error) {
784
+ var _a, _b;
785
+ if (typeof error !== "object" || error === null) {
786
+ return false;
787
+ }
788
+ const errorObj = error;
789
+ const errorCode = errorObj.code;
790
+ const errorMessage = (_b = (_a = errorObj.message) == null ? void 0 : _a.toLowerCase()) != null ? _b : "";
791
+ return errorCode === 4001 || // User rejected request (common EIP-1193 code)
792
+ errorCode === 4100 || // Unauthorized (common rejection code)
793
+ errorMessage.includes("reject") || errorMessage.includes("denied") || errorMessage.includes("cancel") || errorMessage.includes("user");
794
+ }
795
+ function getBaseAnalyticsProperties(options, storage) {
796
+ return __async(this, null, function* () {
797
+ var _a, _b;
798
+ const version = getVersion();
799
+ const dappId = getDappId(options.dapp);
800
+ const platform = getPlatformType();
801
+ const anonId = yield storage.getAnonId();
802
+ const integrationType = (_b = (_a = options.analytics) == null ? void 0 : _a.integrationType) != null ? _b : "unknown" /* UNKNOWN */;
803
+ return {
804
+ mmconnect_version: version,
805
+ dapp_id: dappId,
806
+ platform,
807
+ integration_type: integrationType,
808
+ anon_id: anonId
809
+ };
810
+ });
811
+ }
812
+ function getWalletActionAnalyticsProperties(options, storage, invokeOptions) {
813
+ return __async(this, null, function* () {
814
+ var _a, _b;
815
+ const version = getVersion();
816
+ const dappId = getDappId(options.dapp);
817
+ const anonId = yield storage.getAnonId();
818
+ const integrationType = (_b = (_a = options.analytics) == null ? void 0 : _a.integrationType) != null ? _b : "unknown";
819
+ return {
820
+ mmconnect_version: version,
821
+ dapp_id: dappId,
822
+ method: invokeOptions.request.method,
823
+ integration_type: integrationType,
824
+ caip_chain_id: invokeOptions.scope,
825
+ anon_id: anonId
826
+ };
827
+ });
828
+ }
829
+ var init_analytics = __esm({
830
+ "src/multichain/utils/analytics.ts"() {
831
+ "use strict";
832
+ init_utils();
833
+ init_domain();
834
+ }
835
+ });
836
+
586
837
  // src/domain/utils/index.ts
587
838
  function getVersion() {
588
839
  return "0.0.0";
589
840
  }
590
- var init_utils = __esm({
841
+ var init_utils2 = __esm({
591
842
  "src/domain/utils/index.ts"() {
592
843
  "use strict";
844
+ init_analytics();
593
845
  }
594
846
  });
595
847
 
@@ -604,7 +856,7 @@ var init_domain = __esm({
604
856
  init_platform();
605
857
  init_store();
606
858
  init_ui();
607
- init_utils();
859
+ init_utils2();
608
860
  }
609
861
  });
610
862
 
@@ -651,7 +903,7 @@ function shouldLogCountdown(remainingSeconds) {
651
903
  return remainingSeconds % 60 === 0;
652
904
  }
653
905
  }
654
- var init_utils2 = __esm({
906
+ var init_utils3 = __esm({
655
907
  "src/ui/modals/base/utils.ts"() {
656
908
  "use strict";
657
909
  }
@@ -663,7 +915,7 @@ var init_AbstractInstallModal = __esm({
663
915
  "src/ui/modals/base/AbstractInstallModal.ts"() {
664
916
  "use strict";
665
917
  init_domain();
666
- init_utils2();
918
+ init_utils3();
667
919
  logger3 = createLogger("metamask-sdk:ui");
668
920
  AbstractInstallModal = class extends Modal {
669
921
  constructor() {
@@ -757,7 +1009,7 @@ var init_install = __esm({
757
1009
  init_domain();
758
1010
  init_qr();
759
1011
  init_AbstractInstallModal();
760
- init_utils2();
1012
+ init_utils3();
761
1013
  logger4 = createLogger("metamask-sdk:ui");
762
1014
  InstallModal = class extends AbstractInstallModal {
763
1015
  displayQRWithCountdown(qrCodeLink, expiresInMs) {
@@ -890,7 +1142,7 @@ var init_node2 = __esm({
890
1142
  });
891
1143
 
892
1144
  // src/multichain/index.ts
893
- import { analytics } from "@metamask/analytics";
1145
+ import { analytics as analytics2 } from "@metamask/analytics";
894
1146
  import {
895
1147
  ErrorCode,
896
1148
  ProtocolError,
@@ -909,6 +1161,7 @@ var METAMASK_DEEPLINK_BASE = "metamask://connect";
909
1161
 
910
1162
  // src/multichain/index.ts
911
1163
  init_domain();
1164
+ init_analytics();
912
1165
  init_logger();
913
1166
  init_multichain();
914
1167
  init_platform();
@@ -1009,204 +1262,17 @@ var RpcClient = class {
1009
1262
  };
1010
1263
 
1011
1264
  // src/multichain/rpc/requestRouter.ts
1265
+ import { analytics } from "@metamask/analytics";
1012
1266
  init_domain();
1013
-
1014
- // src/multichain/utils/index.ts
1015
- init_domain();
1016
- import { deflate } from "pako";
1017
- import {
1018
- parseCaipAccountId,
1019
- parseCaipChainId
1020
- } from "@metamask/utils";
1021
- function base64Encode(str) {
1022
- if (typeof btoa !== "undefined") {
1023
- return btoa(str);
1024
- } else if (typeof Buffer !== "undefined") {
1025
- return Buffer.from(str).toString("base64");
1026
- }
1027
- throw new Error("No base64 encoding method available");
1028
- }
1029
- function compressString(str) {
1030
- const compressed = deflate(str);
1031
- const binaryString = String.fromCharCode.apply(null, Array.from(compressed));
1032
- return base64Encode(binaryString);
1033
- }
1034
- function getDappId(dapp) {
1035
- var _a, _b;
1036
- if (typeof window === "undefined" || typeof window.location === "undefined") {
1037
- return (_b = (_a = dapp == null ? void 0 : dapp.name) != null ? _a : dapp == null ? void 0 : dapp.url) != null ? _b : "N/A";
1038
- }
1039
- return window.location.hostname;
1040
- }
1041
- function openDeeplink(options, deeplink, universalLink) {
1042
- const { mobile } = options;
1043
- const useDeeplink = mobile && mobile.useDeeplink !== void 0 ? mobile.useDeeplink : true;
1044
- if (useDeeplink) {
1045
- if (typeof window !== "undefined") {
1046
- window.location.href = deeplink;
1047
- }
1048
- } else if (typeof document !== "undefined") {
1049
- const link = document.createElement("a");
1050
- link.href = universalLink;
1051
- link.target = "_self";
1052
- link.rel = "noreferrer noopener";
1053
- link.click();
1054
- }
1055
- }
1056
- function getOptionalScopes(scopes) {
1057
- return scopes.reduce(
1058
- (prev, scope) => __spreadProps(__spreadValues({}, prev), {
1059
- [scope]: {
1060
- methods: [],
1061
- notifications: [],
1062
- accounts: []
1063
- }
1064
- }),
1065
- {}
1066
- );
1067
- }
1068
- var extractFavicon = () => {
1069
- var _a;
1070
- if (typeof document === "undefined") {
1071
- return void 0;
1072
- }
1073
- let favicon;
1074
- const nodeList = document.getElementsByTagName("link");
1075
- for (let i = 0; i < nodeList.length; i++) {
1076
- if (nodeList[i].getAttribute("rel") === "icon" || nodeList[i].getAttribute("rel") === "shortcut icon") {
1077
- favicon = (_a = nodeList[i].getAttribute("href")) != null ? _a : void 0;
1078
- }
1079
- }
1080
- return favicon;
1081
- };
1082
- function setupDappMetadata(options) {
1083
- var _a;
1084
- const platform = getPlatformType();
1085
- const isBrowser = platform === "web-desktop" /* DesktopWeb */ || platform === "web-mobile" /* MobileWeb */ || platform === "in-app-browser" /* MetaMaskMobileWebview */;
1086
- if (!((_a = options.dapp) == null ? void 0 : _a.url)) {
1087
- if (isBrowser) {
1088
- options.dapp = __spreadProps(__spreadValues({}, options.dapp), {
1089
- url: `${window.location.protocol}//${window.location.host}`
1090
- });
1091
- } else {
1092
- throw new Error("You must provide dapp url");
1093
- }
1094
- }
1095
- const BASE_64_ICON_MAX_LENGTH = 163400;
1096
- const urlPattern = /^(http|https):\/\/[^\s]*$/;
1097
- if (options.dapp) {
1098
- if ("iconUrl" in options.dapp) {
1099
- if (options.dapp.iconUrl && !urlPattern.test(options.dapp.iconUrl)) {
1100
- console.warn(
1101
- "Invalid dappMetadata.iconUrl: URL must start with http:// or https://"
1102
- );
1103
- options.dapp.iconUrl = void 0;
1104
- }
1105
- }
1106
- if ("base64Icon" in options.dapp) {
1107
- if (options.dapp.base64Icon && options.dapp.base64Icon.length > BASE_64_ICON_MAX_LENGTH) {
1108
- console.warn(
1109
- "Invalid dappMetadata.base64Icon: Base64-encoded icon string length must be less than 163400 characters"
1110
- );
1111
- options.dapp.base64Icon = void 0;
1112
- }
1113
- }
1114
- if (options.dapp.url && !urlPattern.test(options.dapp.url)) {
1115
- console.warn(
1116
- "Invalid dappMetadata.url: URL must start with http:// or https://"
1117
- );
1118
- }
1119
- const favicon = extractFavicon();
1120
- if (favicon && !("iconUrl" in options.dapp) && !("base64Icon" in options.dapp)) {
1121
- const faviconUrl = `${window.location.protocol}//${window.location.host}${favicon}`;
1122
- options.dapp.iconUrl = faviconUrl;
1123
- }
1124
- }
1125
- return options;
1126
- }
1127
- function isSameScopesAndAccounts(currentScopes, proposedScopes, walletSession, proposedCaipAccountIds) {
1128
- const isSameScopes = currentScopes.every((scope) => proposedScopes.includes(scope)) && proposedScopes.every((scope) => currentScopes.includes(scope));
1129
- if (!isSameScopes) {
1130
- return false;
1131
- }
1132
- const existingAccountIds = Object.values(
1133
- walletSession.sessionScopes
1134
- ).filter(({ accounts }) => Boolean(accounts)).flatMap(({ accounts }) => accounts != null ? accounts : []);
1135
- const allProposedAccountsIncluded = proposedCaipAccountIds.every(
1136
- (proposedAccountId) => existingAccountIds.includes(proposedAccountId)
1137
- );
1138
- return allProposedAccountsIncluded;
1139
- }
1140
- function getValidAccounts(caipAccountIds) {
1141
- return caipAccountIds.reduce(
1142
- (caipAccounts, caipAccountId) => {
1143
- try {
1144
- return [...caipAccounts, parseCaipAccountId(caipAccountId)];
1145
- } catch (err) {
1146
- const stringifiedAccountId = JSON.stringify(caipAccountId);
1147
- console.error(`Invalid CAIP account ID: ${stringifiedAccountId}`, err);
1148
- return caipAccounts;
1149
- }
1150
- },
1151
- []
1152
- );
1153
- }
1154
- function addValidAccounts(optionalScopes, validAccounts) {
1155
- var _a;
1156
- if (!optionalScopes || !(validAccounts == null ? void 0 : validAccounts.length)) {
1157
- return optionalScopes;
1158
- }
1159
- const result = Object.fromEntries(
1160
- Object.entries(optionalScopes).map(([scope, scopeData]) => {
1161
- var _a2, _b, _c;
1162
- return [
1163
- scope,
1164
- {
1165
- methods: [...(_a2 = scopeData == null ? void 0 : scopeData.methods) != null ? _a2 : []],
1166
- notifications: [...(_b = scopeData == null ? void 0 : scopeData.notifications) != null ? _b : []],
1167
- accounts: [...(_c = scopeData == null ? void 0 : scopeData.accounts) != null ? _c : []]
1168
- }
1169
- ];
1170
- })
1171
- );
1172
- const accountsByChain = /* @__PURE__ */ new Map();
1173
- for (const account of validAccounts) {
1174
- const chainKey = `${account.chain.namespace}:${account.chain.reference}`;
1175
- const accountId = `${account.chainId}:${account.address}`;
1176
- if (!accountsByChain.has(chainKey)) {
1177
- accountsByChain.set(chainKey, []);
1178
- }
1179
- (_a = accountsByChain.get(chainKey)) == null ? void 0 : _a.push(accountId);
1180
- }
1181
- for (const [scopeKey, scopeData] of Object.entries(result)) {
1182
- if (!(scopeData == null ? void 0 : scopeData.accounts)) {
1183
- continue;
1184
- }
1185
- try {
1186
- const scope = scopeKey;
1187
- const scopeDetails = parseCaipChainId(scope);
1188
- const chainKey = `${scopeDetails.namespace}:${scopeDetails.reference}`;
1189
- const matchingAccounts = accountsByChain.get(chainKey);
1190
- if (matchingAccounts) {
1191
- const existingAccounts = new Set(scopeData.accounts);
1192
- const newAccounts = matchingAccounts.filter(
1193
- (account) => !existingAccounts.has(account)
1194
- );
1195
- scopeData.accounts.push(...newAccounts);
1196
- }
1197
- } catch (error) {
1198
- console.error(`Invalid scope format: ${scopeKey}`, error);
1199
- }
1200
- }
1201
- return result;
1202
- }
1203
-
1204
- // src/multichain/rpc/requestRouter.ts
1267
+ init_utils();
1268
+ init_analytics();
1269
+ var _RequestRouter_instances, withAnalyticsTracking_fn, trackWalletActionRequested_fn, trackWalletActionSucceeded_fn, trackWalletActionFailed_fn, trackWalletActionRejected_fn;
1205
1270
  var RequestRouter = class {
1206
1271
  constructor(transport, rpcClient, config) {
1207
1272
  this.transport = transport;
1208
1273
  this.rpcClient = rpcClient;
1209
1274
  this.config = config;
1275
+ __privateAdd(this, _RequestRouter_instances);
1210
1276
  }
1211
1277
  /**
1212
1278
  * The main entry point for invoking an RPC method.
@@ -1230,7 +1296,7 @@ var RequestRouter = class {
1230
1296
  */
1231
1297
  handleWithWallet(options) {
1232
1298
  return __async(this, null, function* () {
1233
- try {
1299
+ return __privateMethod(this, _RequestRouter_instances, withAnalyticsTracking_fn).call(this, options, () => __async(this, null, function* () {
1234
1300
  const request = this.transport.request({
1235
1301
  method: "wallet_invokeMethod",
1236
1302
  params: options
@@ -1253,9 +1319,7 @@ var RequestRouter = class {
1253
1319
  throw new RPCInvokeMethodErr(`RPC Request failed with code ${response.error.code}: ${response.error.message}`);
1254
1320
  }
1255
1321
  return response.result;
1256
- } catch (error) {
1257
- throw new RPCInvokeMethodErr(error.message);
1258
- }
1322
+ }));
1259
1323
  });
1260
1324
  }
1261
1325
  /**
@@ -1263,14 +1327,16 @@ var RequestRouter = class {
1263
1327
  */
1264
1328
  handleWithRpcNode(options) {
1265
1329
  return __async(this, null, function* () {
1266
- try {
1267
- return yield this.rpcClient.request(options);
1268
- } catch (error) {
1269
- if (error instanceof MissingRpcEndpointErr) {
1270
- return this.handleWithWallet(options);
1330
+ return __privateMethod(this, _RequestRouter_instances, withAnalyticsTracking_fn).call(this, options, () => __async(this, null, function* () {
1331
+ try {
1332
+ return yield this.rpcClient.request(options);
1333
+ } catch (error) {
1334
+ if (error instanceof MissingRpcEndpointErr) {
1335
+ return this.handleWithWallet(options);
1336
+ }
1337
+ throw error;
1271
1338
  }
1272
- throw error;
1273
- }
1339
+ }));
1274
1340
  });
1275
1341
  }
1276
1342
  /**
@@ -1283,8 +1349,59 @@ var RequestRouter = class {
1283
1349
  });
1284
1350
  }
1285
1351
  };
1352
+ _RequestRouter_instances = new WeakSet();
1353
+ withAnalyticsTracking_fn = function(options, execute) {
1354
+ return __async(this, null, function* () {
1355
+ var _a, _b, _c;
1356
+ if ((_a = this.config.analytics) == null ? void 0 : _a.enabled) {
1357
+ yield __privateMethod(this, _RequestRouter_instances, trackWalletActionRequested_fn).call(this, options);
1358
+ }
1359
+ try {
1360
+ const result = yield execute();
1361
+ if ((_b = this.config.analytics) == null ? void 0 : _b.enabled) {
1362
+ yield __privateMethod(this, _RequestRouter_instances, trackWalletActionSucceeded_fn).call(this, options);
1363
+ }
1364
+ return result;
1365
+ } catch (error) {
1366
+ if ((_c = this.config.analytics) == null ? void 0 : _c.enabled) {
1367
+ const isRejection = isRejectionError(error);
1368
+ if (isRejection) {
1369
+ yield __privateMethod(this, _RequestRouter_instances, trackWalletActionRejected_fn).call(this, options);
1370
+ } else {
1371
+ yield __privateMethod(this, _RequestRouter_instances, trackWalletActionFailed_fn).call(this, options);
1372
+ }
1373
+ }
1374
+ throw new RPCInvokeMethodErr(error.message);
1375
+ }
1376
+ });
1377
+ };
1378
+ trackWalletActionRequested_fn = function(options) {
1379
+ return __async(this, null, function* () {
1380
+ const props = yield getWalletActionAnalyticsProperties(this.config, this.config.storage, options);
1381
+ analytics.track("mmconnect_wallet_action_requested", props);
1382
+ });
1383
+ };
1384
+ trackWalletActionSucceeded_fn = function(options) {
1385
+ return __async(this, null, function* () {
1386
+ const props = yield getWalletActionAnalyticsProperties(this.config, this.config.storage, options);
1387
+ analytics.track("mmconnect_wallet_action_succeeded", props);
1388
+ });
1389
+ };
1390
+ trackWalletActionFailed_fn = function(options) {
1391
+ return __async(this, null, function* () {
1392
+ const props = yield getWalletActionAnalyticsProperties(this.config, this.config.storage, options);
1393
+ analytics.track("mmconnect_wallet_action_failed", props);
1394
+ });
1395
+ };
1396
+ trackWalletActionRejected_fn = function(options) {
1397
+ return __async(this, null, function* () {
1398
+ const props = yield getWalletActionAnalyticsProperties(this.config, this.config.storage, options);
1399
+ analytics.track("mmconnect_wallet_action_rejected", props);
1400
+ });
1401
+ };
1286
1402
 
1287
1403
  // src/multichain/transports/default/index.ts
1404
+ init_utils();
1288
1405
  import {
1289
1406
  getDefaultTransport
1290
1407
  } from "@metamask/multichain-api-client";
@@ -1514,6 +1631,7 @@ setupMessageListener_fn = function() {
1514
1631
 
1515
1632
  // src/multichain/transports/mwp/index.ts
1516
1633
  init_domain();
1634
+ init_utils();
1517
1635
  import { SessionStore } from "@metamask/mobile-wallet-protocol-core";
1518
1636
  import {
1519
1637
  TransportTimeoutError
@@ -1991,20 +2109,22 @@ var KeyManager = class {
1991
2109
  var keymanager = new KeyManager();
1992
2110
 
1993
2111
  // src/multichain/index.ts
2112
+ init_utils();
1994
2113
  var logger2 = createLogger("metamask-sdk:core");
1995
2114
  var MultichainSDK = class _MultichainSDK extends MultichainCore {
1996
2115
  constructor(options) {
1997
- var _a, _b, _c, _d, _e, _f;
2116
+ var _a, _b, _c, _d, _e, _f, _g;
1998
2117
  const withDappMetadata = setupDappMetadata(options);
2118
+ const integrationType = ((_a = options.analytics) == null ? void 0 : _a.enabled) ? options.analytics.integrationType : "direct";
1999
2119
  const allOptions = __spreadProps(__spreadValues({}, withDappMetadata), {
2000
2120
  ui: __spreadProps(__spreadValues({}, withDappMetadata.ui), {
2001
- preferExtension: (_a = withDappMetadata.ui.preferExtension) != null ? _a : true,
2002
- showInstallModal: (_b = withDappMetadata.ui.showInstallModal) != null ? _b : false,
2003
- headless: (_c = withDappMetadata.ui.headless) != null ? _c : false
2121
+ preferExtension: (_b = withDappMetadata.ui.preferExtension) != null ? _b : true,
2122
+ showInstallModal: (_c = withDappMetadata.ui.showInstallModal) != null ? _c : false,
2123
+ headless: (_d = withDappMetadata.ui.headless) != null ? _d : false
2004
2124
  }),
2005
- analytics: __spreadProps(__spreadValues({}, (_d = options.analytics) != null ? _d : {}), {
2006
- enabled: (_f = (_e = options.analytics) == null ? void 0 : _e.enabled) != null ? _f : true,
2007
- integrationType: "unknown"
2125
+ analytics: __spreadProps(__spreadValues({}, (_e = options.analytics) != null ? _e : {}), {
2126
+ enabled: (_g = (_f = options.analytics) == null ? void 0 : _f.enabled) != null ? _g : true,
2127
+ integrationType
2008
2128
  })
2009
2129
  });
2010
2130
  super(allOptions);
@@ -2088,12 +2208,12 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
2088
2208
  const { integrationType } = (_b = this.options.analytics) != null ? _b : {
2089
2209
  integrationType: ""
2090
2210
  };
2091
- analytics.setGlobalProperty("sdk_version", version);
2092
- analytics.setGlobalProperty("dapp_id", dappId);
2093
- analytics.setGlobalProperty("anon_id", anonId);
2094
- analytics.setGlobalProperty("platform", platform);
2095
- analytics.setGlobalProperty("integration_type", integrationType);
2096
- analytics.enable();
2211
+ analytics2.setGlobalProperty("mmconnect_version", version);
2212
+ analytics2.setGlobalProperty("dapp_id", dappId);
2213
+ analytics2.setGlobalProperty("anon_id", anonId);
2214
+ analytics2.setGlobalProperty("platform", platform);
2215
+ analytics2.setGlobalProperty("integration_type", integrationType);
2216
+ analytics2.enable();
2097
2217
  });
2098
2218
  }
2099
2219
  onTransportNotification(payload) {
@@ -2155,14 +2275,24 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
2155
2275
  }
2156
2276
  init() {
2157
2277
  return __async(this, null, function* () {
2158
- var _a;
2278
+ var _a, _b;
2159
2279
  try {
2160
2280
  if (typeof window !== "undefined" && ((_a = window.mmsdk) == null ? void 0 : _a.isInitialized)) {
2161
2281
  logger2("MetaMaskSDK: init already initialized");
2162
2282
  } else {
2163
2283
  yield this.setupAnalytics();
2164
2284
  yield this.setupTransport();
2165
- analytics.track("sdk_initialized", {});
2285
+ if ((_b = this.options.analytics) == null ? void 0 : _b.enabled) {
2286
+ try {
2287
+ const baseProps = yield getBaseAnalyticsProperties(
2288
+ this.options,
2289
+ this.storage
2290
+ );
2291
+ analytics2.track("mmconnect_initialized", baseProps);
2292
+ } catch (error) {
2293
+ logger2("Error tracking initialized event", error);
2294
+ }
2295
+ }
2166
2296
  if (typeof window !== "undefined") {
2167
2297
  window.mmsdk = this;
2168
2298
  }
@@ -2364,27 +2494,87 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
2364
2494
  }));
2365
2495
  });
2366
2496
  }
2367
- handleConnection(promise) {
2497
+ handleConnection(promise, scopes, transportType) {
2368
2498
  return __async(this, null, function* () {
2369
2499
  this.state = "connecting";
2370
- return promise.then(() => {
2500
+ return promise.then(() => __async(this, null, function* () {
2501
+ var _a;
2371
2502
  this.state = "connected";
2372
- }).catch((error) => {
2503
+ if ((_a = this.options.analytics) == null ? void 0 : _a.enabled) {
2504
+ try {
2505
+ const baseProps = yield getBaseAnalyticsProperties(
2506
+ this.options,
2507
+ this.storage
2508
+ );
2509
+ analytics2.track("mmconnect_connection_established", __spreadProps(__spreadValues({}, baseProps), {
2510
+ transport_type: transportType,
2511
+ user_permissioned_chains: scopes
2512
+ }));
2513
+ } catch (error) {
2514
+ logger2("Error tracking connection_established event", error);
2515
+ }
2516
+ }
2517
+ })).catch((error) => __async(this, null, function* () {
2518
+ var _a;
2373
2519
  this.state = "disconnected";
2520
+ if ((_a = this.options.analytics) == null ? void 0 : _a.enabled) {
2521
+ try {
2522
+ const baseProps = yield getBaseAnalyticsProperties(
2523
+ this.options,
2524
+ this.storage
2525
+ );
2526
+ const isRejection = isRejectionError(error);
2527
+ if (isRejection) {
2528
+ analytics2.track("mmconnect_connection_rejected", __spreadProps(__spreadValues({}, baseProps), {
2529
+ transport_type: transportType
2530
+ }));
2531
+ } else {
2532
+ analytics2.track("mmconnect_connection_failed", __spreadProps(__spreadValues({}, baseProps), {
2533
+ transport_type: transportType
2534
+ }));
2535
+ }
2536
+ } catch (e) {
2537
+ logger2("Error tracking connection failed/rejected event", error);
2538
+ }
2539
+ }
2374
2540
  return Promise.reject(error);
2375
- });
2541
+ }));
2376
2542
  });
2377
2543
  }
2378
2544
  connect(scopes, caipAccountIds, forceRequest) {
2379
2545
  return __async(this, null, function* () {
2380
- var _a;
2546
+ var _a, _b;
2381
2547
  const { ui } = this.options;
2382
2548
  const platformType = getPlatformType();
2383
2549
  const isWeb = platformType === "in-app-browser" /* MetaMaskMobileWebview */ || platformType === "web-desktop" /* DesktopWeb */;
2384
2550
  const { preferExtension = true, showInstallModal = false } = ui;
2385
2551
  const secure = isSecure();
2386
2552
  const hasExtensionInstalled = yield hasExtension();
2387
- if (((_a = this.__transport) == null ? void 0 : _a.isConnected()) && !secure) {
2553
+ let transportType;
2554
+ if (platformType === "in-app-browser" /* MetaMaskMobileWebview */ || isWeb && hasExtensionInstalled && preferExtension) {
2555
+ transportType = "browser" /* Browser */;
2556
+ } else {
2557
+ transportType = "mwp" /* MWP */;
2558
+ }
2559
+ if ((_a = this.options.analytics) == null ? void 0 : _a.enabled) {
2560
+ try {
2561
+ const baseProps = yield getBaseAnalyticsProperties(
2562
+ this.options,
2563
+ this.storage
2564
+ );
2565
+ const dappConfiguredChains = Object.keys(
2566
+ this.options.api.supportedNetworks
2567
+ );
2568
+ analytics2.track("mmconnect_connection_initiated", __spreadProps(__spreadValues({}, baseProps), {
2569
+ transport_type: transportType,
2570
+ dapp_configured_chains: dappConfiguredChains,
2571
+ dapp_requested_chains: scopes
2572
+ }));
2573
+ } catch (error) {
2574
+ logger2("Error tracking connection_initiated event", error);
2575
+ }
2576
+ }
2577
+ if (((_b = this.__transport) == null ? void 0 : _b.isConnected()) && !secure) {
2388
2578
  return this.handleConnection(
2389
2579
  this.__transport.connect({ scopes, caipAccountIds, forceRequest }).then(() => {
2390
2580
  if (this.__transport instanceof MWPTransport) {
@@ -2392,30 +2582,40 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
2392
2582
  } else {
2393
2583
  return this.storage.setTransport("browser" /* Browser */);
2394
2584
  }
2395
- })
2585
+ }),
2586
+ scopes,
2587
+ transportType
2396
2588
  );
2397
2589
  }
2398
2590
  if (platformType === "in-app-browser" /* MetaMaskMobileWebview */) {
2399
2591
  const defaultTransport = yield this.setupDefaultTransport();
2400
2592
  return this.handleConnection(
2401
- defaultTransport.connect({ scopes, caipAccountIds, forceRequest })
2593
+ defaultTransport.connect({ scopes, caipAccountIds, forceRequest }),
2594
+ scopes,
2595
+ transportType
2402
2596
  );
2403
2597
  }
2404
2598
  if (isWeb && hasExtensionInstalled && preferExtension) {
2405
2599
  const defaultTransport = yield this.setupDefaultTransport();
2406
2600
  return this.handleConnection(
2407
- defaultTransport.connect({ scopes, caipAccountIds, forceRequest })
2601
+ defaultTransport.connect({ scopes, caipAccountIds, forceRequest }),
2602
+ scopes,
2603
+ transportType
2408
2604
  );
2409
2605
  }
2410
2606
  yield this.setupMWP();
2411
2607
  const shouldShowInstallModal = hasExtensionInstalled ? showInstallModal : !preferExtension || showInstallModal;
2412
2608
  if (secure && !shouldShowInstallModal) {
2413
2609
  return this.handleConnection(
2414
- this.deeplinkConnect(scopes, caipAccountIds)
2610
+ this.deeplinkConnect(scopes, caipAccountIds),
2611
+ scopes,
2612
+ transportType
2415
2613
  );
2416
2614
  }
2417
2615
  return this.handleConnection(
2418
- this.showInstallModal(shouldShowInstallModal, scopes, caipAccountIds)
2616
+ this.showInstallModal(shouldShowInstallModal, scopes, caipAccountIds),
2617
+ scopes,
2618
+ transportType
2419
2619
  );
2420
2620
  });
2421
2621
  }
@@ -2655,6 +2855,7 @@ var Store = class extends StoreClient {
2655
2855
  import MetaMaskOnboarding from "@metamask/onboarding";
2656
2856
  init_domain();
2657
2857
  init_qr();
2858
+ init_utils();
2658
2859
  var __instance;
2659
2860
  function preload() {
2660
2861
  return __async(this, null, function* () {
@@ -2863,10 +3064,12 @@ export {
2863
3064
  getPlatformType,
2864
3065
  getTransportType,
2865
3066
  getVersion,
3067
+ getWalletActionAnalyticsProperties,
2866
3068
  hasExtension,
2867
3069
  infuraRpcUrls,
2868
3070
  isEnabled,
2869
3071
  isMetamaskExtensionInstalled,
3072
+ isRejectionError,
2870
3073
  isSecure
2871
3074
  };
2872
3075
  //# sourceMappingURL=connect-multichain.mjs.map