@metamask/connect-multichain 0.2.0 → 0.3.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 (50) hide show
  1. package/CHANGELOG.md +20 -1
  2. package/dist/browser/es/connect-multichain.d.mts +26 -2
  3. package/dist/browser/es/connect-multichain.mjs +437 -246
  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 +26 -2
  7. package/dist/browser/iife/connect-multichain.js +21359 -14508
  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 +26 -2
  11. package/dist/browser/umd/connect-multichain.js +434 -243
  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 +26 -2
  15. package/dist/node/cjs/connect-multichain.js +437 -244
  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 +26 -2
  19. package/dist/node/es/connect-multichain.mjs +438 -247
  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 +26 -2
  23. package/dist/react-native/es/connect-multichain.mjs +437 -246
  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/multichain/types.d.ts +1 -1
  27. package/dist/src/domain/multichain/types.d.ts.map +1 -1
  28. package/dist/src/domain/utils/index.d.ts +1 -0
  29. package/dist/src/domain/utils/index.d.ts.map +1 -1
  30. package/dist/src/domain/utils/index.js +1 -0
  31. package/dist/src/domain/utils/index.js.map +1 -1
  32. package/dist/src/multichain/index.d.ts.map +1 -1
  33. package/dist/src/multichain/index.js +73 -30
  34. package/dist/src/multichain/index.js.map +1 -1
  35. package/dist/src/multichain/rpc/requestRouter.d.ts +1 -0
  36. package/dist/src/multichain/rpc/requestRouter.d.ts.map +1 -1
  37. package/dist/src/multichain/rpc/requestRouter.js +69 -13
  38. package/dist/src/multichain/rpc/requestRouter.js.map +1 -1
  39. package/dist/src/multichain/utils/analytics.d.ts +39 -0
  40. package/dist/src/multichain/utils/analytics.d.ts.map +1 -0
  41. package/dist/src/multichain/utils/analytics.js +83 -0
  42. package/dist/src/multichain/utils/analytics.js.map +1 -0
  43. package/dist/src/multichain/utils/index.d.ts +1 -1
  44. package/dist/src/multichain/utils/index.d.ts.map +1 -1
  45. package/dist/src/multichain/utils/index.js +11 -14
  46. package/dist/src/multichain/utils/index.js.map +1 -1
  47. package/dist/src/ui/index.js +1 -1
  48. package/dist/src/ui/index.js.map +1 -1
  49. package/dist/types/connect-multichain.d.ts +26 -2
  50. package/package.json +2 -2
@@ -583,13 +583,264 @@ 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;
607
+ return (_a = dapp.url) != null ? _a : dapp.name;
608
+ }
609
+ function openDeeplink(options, deeplink, universalLink) {
610
+ const { mobile } = options;
611
+ const useDeeplink = mobile && mobile.useDeeplink !== void 0 ? mobile.useDeeplink : true;
612
+ if (useDeeplink) {
613
+ if (typeof window !== "undefined") {
614
+ window.location.href = deeplink;
615
+ }
616
+ } else if (typeof document !== "undefined") {
617
+ const link = document.createElement("a");
618
+ link.href = universalLink;
619
+ link.target = "_self";
620
+ link.rel = "noreferrer noopener";
621
+ link.click();
622
+ }
623
+ }
624
+ function getOptionalScopes(scopes) {
625
+ return scopes.reduce(
626
+ (prev, scope) => __spreadProps(__spreadValues({}, prev), {
627
+ [scope]: {
628
+ methods: [],
629
+ notifications: [],
630
+ accounts: []
631
+ }
632
+ }),
633
+ {}
634
+ );
635
+ }
636
+ function setupDappMetadata(options) {
637
+ var _a, _b;
638
+ const platform = getPlatformType();
639
+ const isBrowser = platform === "web-desktop" /* DesktopWeb */ || platform === "web-mobile" /* MobileWeb */ || platform === "in-app-browser" /* MetaMaskMobileWebview */;
640
+ if (!((_a = options.dapp) == null ? void 0 : _a.name)) {
641
+ throw new Error("You must provide dapp name");
642
+ }
643
+ if (isBrowser) {
644
+ options.dapp = __spreadProps(__spreadValues({}, options.dapp), {
645
+ url: `${window.location.protocol}//${window.location.host}`
646
+ });
647
+ }
648
+ if (!((_b = options.dapp) == null ? void 0 : _b.url)) {
649
+ throw new Error("You must provide dapp url");
650
+ }
651
+ const BASE_64_ICON_MAX_LENGTH = 163400;
652
+ const urlPattern = /^(http|https):\/\/[^\s]*$/;
653
+ if (options.dapp) {
654
+ if ("iconUrl" in options.dapp) {
655
+ if (options.dapp.iconUrl && !urlPattern.test(options.dapp.iconUrl)) {
656
+ console.warn(
657
+ "Invalid dappMetadata.iconUrl: URL must start with http:// or https://"
658
+ );
659
+ options.dapp.iconUrl = void 0;
660
+ }
661
+ }
662
+ if ("base64Icon" in options.dapp) {
663
+ if (options.dapp.base64Icon && options.dapp.base64Icon.length > BASE_64_ICON_MAX_LENGTH) {
664
+ console.warn(
665
+ "Invalid dappMetadata.base64Icon: Base64-encoded icon string length must be less than 163400 characters"
666
+ );
667
+ options.dapp.base64Icon = void 0;
668
+ }
669
+ }
670
+ if (options.dapp.url && !urlPattern.test(options.dapp.url)) {
671
+ console.warn(
672
+ "Invalid dappMetadata.url: URL must start with http:// or https://"
673
+ );
674
+ }
675
+ const favicon = extractFavicon();
676
+ if (favicon && !("iconUrl" in options.dapp) && !("base64Icon" in options.dapp)) {
677
+ const faviconUrl = `${window.location.protocol}//${window.location.host}${favicon}`;
678
+ options.dapp.iconUrl = faviconUrl;
679
+ }
680
+ }
681
+ return options;
682
+ }
683
+ function isSameScopesAndAccounts(currentScopes, proposedScopes, walletSession, proposedCaipAccountIds) {
684
+ const isSameScopes = currentScopes.every((scope) => proposedScopes.includes(scope)) && proposedScopes.every((scope) => currentScopes.includes(scope));
685
+ if (!isSameScopes) {
686
+ return false;
687
+ }
688
+ const existingAccountIds = Object.values(
689
+ walletSession.sessionScopes
690
+ ).filter(({ accounts }) => Boolean(accounts)).flatMap(({ accounts }) => accounts != null ? accounts : []);
691
+ const allProposedAccountsIncluded = proposedCaipAccountIds.every(
692
+ (proposedAccountId) => existingAccountIds.includes(proposedAccountId)
693
+ );
694
+ return allProposedAccountsIncluded;
695
+ }
696
+ function getValidAccounts(caipAccountIds) {
697
+ return caipAccountIds.reduce(
698
+ (caipAccounts, caipAccountId) => {
699
+ try {
700
+ return [...caipAccounts, parseCaipAccountId(caipAccountId)];
701
+ } catch (err) {
702
+ const stringifiedAccountId = JSON.stringify(caipAccountId);
703
+ console.error(`Invalid CAIP account ID: ${stringifiedAccountId}`, err);
704
+ return caipAccounts;
705
+ }
706
+ },
707
+ []
708
+ );
709
+ }
710
+ function addValidAccounts(optionalScopes, validAccounts) {
711
+ var _a;
712
+ if (!optionalScopes || !(validAccounts == null ? void 0 : validAccounts.length)) {
713
+ return optionalScopes;
714
+ }
715
+ const result = Object.fromEntries(
716
+ Object.entries(optionalScopes).map(([scope, scopeData]) => {
717
+ var _a2, _b, _c;
718
+ return [
719
+ scope,
720
+ {
721
+ methods: [...(_a2 = scopeData == null ? void 0 : scopeData.methods) != null ? _a2 : []],
722
+ notifications: [...(_b = scopeData == null ? void 0 : scopeData.notifications) != null ? _b : []],
723
+ accounts: [...(_c = scopeData == null ? void 0 : scopeData.accounts) != null ? _c : []]
724
+ }
725
+ ];
726
+ })
727
+ );
728
+ const accountsByChain = /* @__PURE__ */ new Map();
729
+ for (const account of validAccounts) {
730
+ const chainKey = `${account.chain.namespace}:${account.chain.reference}`;
731
+ const accountId = `${account.chainId}:${account.address}`;
732
+ if (!accountsByChain.has(chainKey)) {
733
+ accountsByChain.set(chainKey, []);
734
+ }
735
+ (_a = accountsByChain.get(chainKey)) == null ? void 0 : _a.push(accountId);
736
+ }
737
+ for (const [scopeKey, scopeData] of Object.entries(result)) {
738
+ if (!(scopeData == null ? void 0 : scopeData.accounts)) {
739
+ continue;
740
+ }
741
+ try {
742
+ const scope = scopeKey;
743
+ const scopeDetails = parseCaipChainId(scope);
744
+ const chainKey = `${scopeDetails.namespace}:${scopeDetails.reference}`;
745
+ const matchingAccounts = accountsByChain.get(chainKey);
746
+ if (matchingAccounts) {
747
+ const existingAccounts = new Set(scopeData.accounts);
748
+ const newAccounts = matchingAccounts.filter(
749
+ (account) => !existingAccounts.has(account)
750
+ );
751
+ scopeData.accounts.push(...newAccounts);
752
+ }
753
+ } catch (error) {
754
+ console.error(`Invalid scope format: ${scopeKey}`, error);
755
+ }
756
+ }
757
+ return result;
758
+ }
759
+ var extractFavicon;
760
+ var init_utils = __esm({
761
+ "src/multichain/utils/index.ts"() {
762
+ "use strict";
763
+ init_domain();
764
+ extractFavicon = () => {
765
+ var _a;
766
+ if (typeof document === "undefined") {
767
+ return void 0;
768
+ }
769
+ let favicon;
770
+ const nodeList = document.getElementsByTagName("link");
771
+ for (let i = 0; i < nodeList.length; i++) {
772
+ if (nodeList[i].getAttribute("rel") === "icon" || nodeList[i].getAttribute("rel") === "shortcut icon") {
773
+ favicon = (_a = nodeList[i].getAttribute("href")) != null ? _a : void 0;
774
+ }
775
+ }
776
+ return favicon;
777
+ };
778
+ }
779
+ });
780
+
781
+ // src/multichain/utils/analytics.ts
782
+ function isRejectionError(error) {
783
+ var _a, _b;
784
+ if (typeof error !== "object" || error === null) {
785
+ return false;
786
+ }
787
+ const errorObj = error;
788
+ const errorCode = errorObj.code;
789
+ const errorMessage = (_b = (_a = errorObj.message) == null ? void 0 : _a.toLowerCase()) != null ? _b : "";
790
+ return errorCode === 4001 || // User rejected request (common EIP-1193 code)
791
+ errorCode === 4100 || // Unauthorized (common rejection code)
792
+ errorMessage.includes("reject") || errorMessage.includes("denied") || errorMessage.includes("cancel") || errorMessage.includes("user");
793
+ }
794
+ function getBaseAnalyticsProperties(options, storage) {
795
+ return __async(this, null, function* () {
796
+ var _a, _b;
797
+ const version = getVersion();
798
+ const dappId = getDappId(options.dapp);
799
+ const platform = getPlatformType();
800
+ const anonId = yield storage.getAnonId();
801
+ const integrationType = (_b = (_a = options.analytics) == null ? void 0 : _a.integrationType) != null ? _b : "unknown" /* UNKNOWN */;
802
+ return {
803
+ mmconnect_version: version,
804
+ dapp_id: dappId,
805
+ platform,
806
+ integration_type: integrationType,
807
+ anon_id: anonId
808
+ };
809
+ });
810
+ }
811
+ function getWalletActionAnalyticsProperties(options, storage, invokeOptions) {
812
+ return __async(this, null, function* () {
813
+ var _a, _b;
814
+ const version = getVersion();
815
+ const dappId = getDappId(options.dapp);
816
+ const anonId = yield storage.getAnonId();
817
+ const integrationType = (_b = (_a = options.analytics) == null ? void 0 : _a.integrationType) != null ? _b : "unknown";
818
+ return {
819
+ mmconnect_version: version,
820
+ dapp_id: dappId,
821
+ method: invokeOptions.request.method,
822
+ integration_type: integrationType,
823
+ caip_chain_id: invokeOptions.scope,
824
+ anon_id: anonId
825
+ };
826
+ });
827
+ }
828
+ var init_analytics = __esm({
829
+ "src/multichain/utils/analytics.ts"() {
830
+ "use strict";
831
+ init_utils();
832
+ init_domain();
833
+ }
834
+ });
835
+
586
836
  // src/domain/utils/index.ts
587
837
  function getVersion() {
588
838
  return "0.0.0";
589
839
  }
590
- var init_utils = __esm({
840
+ var init_utils2 = __esm({
591
841
  "src/domain/utils/index.ts"() {
592
842
  "use strict";
843
+ init_analytics();
593
844
  }
594
845
  });
595
846
 
@@ -604,7 +855,7 @@ var init_domain = __esm({
604
855
  init_platform();
605
856
  init_store();
606
857
  init_ui();
607
- init_utils();
858
+ init_utils2();
608
859
  }
609
860
  });
610
861
 
@@ -627,7 +878,7 @@ function shouldLogCountdown(remainingSeconds) {
627
878
  return remainingSeconds % 60 === 0;
628
879
  }
629
880
  }
630
- var init_utils2 = __esm({
881
+ var init_utils3 = __esm({
631
882
  "src/ui/modals/base/utils.ts"() {
632
883
  "use strict";
633
884
  }
@@ -639,7 +890,7 @@ var init_AbstractInstallModal = __esm({
639
890
  "src/ui/modals/base/AbstractInstallModal.ts"() {
640
891
  "use strict";
641
892
  init_domain();
642
- init_utils2();
893
+ init_utils3();
643
894
  logger3 = createLogger("metamask-sdk:ui");
644
895
  AbstractInstallModal = class extends Modal {
645
896
  constructor() {
@@ -922,7 +1173,7 @@ var init_web2 = __esm({
922
1173
  });
923
1174
 
924
1175
  // src/multichain/index.ts
925
- import { analytics } from "@metamask/analytics";
1176
+ import { analytics as analytics2 } from "@metamask/analytics";
926
1177
  import {
927
1178
  ErrorCode,
928
1179
  ProtocolError,
@@ -941,6 +1192,7 @@ var METAMASK_DEEPLINK_BASE = "metamask://connect";
941
1192
 
942
1193
  // src/multichain/index.ts
943
1194
  init_domain();
1195
+ init_analytics();
944
1196
  init_logger();
945
1197
  init_multichain();
946
1198
  init_platform();
@@ -1041,204 +1293,17 @@ var RpcClient = class {
1041
1293
  };
1042
1294
 
1043
1295
  // src/multichain/rpc/requestRouter.ts
1296
+ import { analytics } from "@metamask/analytics";
1044
1297
  init_domain();
1045
-
1046
- // src/multichain/utils/index.ts
1047
- init_domain();
1048
- import { deflate } from "pako";
1049
- import {
1050
- parseCaipAccountId,
1051
- parseCaipChainId
1052
- } from "@metamask/utils";
1053
- function base64Encode(str) {
1054
- if (typeof btoa !== "undefined") {
1055
- return btoa(str);
1056
- } else if (typeof Buffer !== "undefined") {
1057
- return Buffer.from(str).toString("base64");
1058
- }
1059
- throw new Error("No base64 encoding method available");
1060
- }
1061
- function compressString(str) {
1062
- const compressed = deflate(str);
1063
- const binaryString = String.fromCharCode.apply(null, Array.from(compressed));
1064
- return base64Encode(binaryString);
1065
- }
1066
- function getDappId(dapp) {
1067
- var _a, _b;
1068
- if (typeof window === "undefined" || typeof window.location === "undefined") {
1069
- return (_b = (_a = dapp == null ? void 0 : dapp.name) != null ? _a : dapp == null ? void 0 : dapp.url) != null ? _b : "N/A";
1070
- }
1071
- return window.location.hostname;
1072
- }
1073
- function openDeeplink(options, deeplink, universalLink) {
1074
- const { mobile } = options;
1075
- const useDeeplink = mobile && mobile.useDeeplink !== void 0 ? mobile.useDeeplink : true;
1076
- if (useDeeplink) {
1077
- if (typeof window !== "undefined") {
1078
- window.location.href = deeplink;
1079
- }
1080
- } else if (typeof document !== "undefined") {
1081
- const link = document.createElement("a");
1082
- link.href = universalLink;
1083
- link.target = "_self";
1084
- link.rel = "noreferrer noopener";
1085
- link.click();
1086
- }
1087
- }
1088
- function getOptionalScopes(scopes) {
1089
- return scopes.reduce(
1090
- (prev, scope) => __spreadProps(__spreadValues({}, prev), {
1091
- [scope]: {
1092
- methods: [],
1093
- notifications: [],
1094
- accounts: []
1095
- }
1096
- }),
1097
- {}
1098
- );
1099
- }
1100
- var extractFavicon = () => {
1101
- var _a;
1102
- if (typeof document === "undefined") {
1103
- return void 0;
1104
- }
1105
- let favicon;
1106
- const nodeList = document.getElementsByTagName("link");
1107
- for (let i = 0; i < nodeList.length; i++) {
1108
- if (nodeList[i].getAttribute("rel") === "icon" || nodeList[i].getAttribute("rel") === "shortcut icon") {
1109
- favicon = (_a = nodeList[i].getAttribute("href")) != null ? _a : void 0;
1110
- }
1111
- }
1112
- return favicon;
1113
- };
1114
- function setupDappMetadata(options) {
1115
- var _a;
1116
- const platform = getPlatformType();
1117
- const isBrowser = platform === "web-desktop" /* DesktopWeb */ || platform === "web-mobile" /* MobileWeb */ || platform === "in-app-browser" /* MetaMaskMobileWebview */;
1118
- if (!((_a = options.dapp) == null ? void 0 : _a.url)) {
1119
- if (isBrowser) {
1120
- options.dapp = __spreadProps(__spreadValues({}, options.dapp), {
1121
- url: `${window.location.protocol}//${window.location.host}`
1122
- });
1123
- } else {
1124
- throw new Error("You must provide dapp url");
1125
- }
1126
- }
1127
- const BASE_64_ICON_MAX_LENGTH = 163400;
1128
- const urlPattern = /^(http|https):\/\/[^\s]*$/;
1129
- if (options.dapp) {
1130
- if ("iconUrl" in options.dapp) {
1131
- if (options.dapp.iconUrl && !urlPattern.test(options.dapp.iconUrl)) {
1132
- console.warn(
1133
- "Invalid dappMetadata.iconUrl: URL must start with http:// or https://"
1134
- );
1135
- options.dapp.iconUrl = void 0;
1136
- }
1137
- }
1138
- if ("base64Icon" in options.dapp) {
1139
- if (options.dapp.base64Icon && options.dapp.base64Icon.length > BASE_64_ICON_MAX_LENGTH) {
1140
- console.warn(
1141
- "Invalid dappMetadata.base64Icon: Base64-encoded icon string length must be less than 163400 characters"
1142
- );
1143
- options.dapp.base64Icon = void 0;
1144
- }
1145
- }
1146
- if (options.dapp.url && !urlPattern.test(options.dapp.url)) {
1147
- console.warn(
1148
- "Invalid dappMetadata.url: URL must start with http:// or https://"
1149
- );
1150
- }
1151
- const favicon = extractFavicon();
1152
- if (favicon && !("iconUrl" in options.dapp) && !("base64Icon" in options.dapp)) {
1153
- const faviconUrl = `${window.location.protocol}//${window.location.host}${favicon}`;
1154
- options.dapp.iconUrl = faviconUrl;
1155
- }
1156
- }
1157
- return options;
1158
- }
1159
- function isSameScopesAndAccounts(currentScopes, proposedScopes, walletSession, proposedCaipAccountIds) {
1160
- const isSameScopes = currentScopes.every((scope) => proposedScopes.includes(scope)) && proposedScopes.every((scope) => currentScopes.includes(scope));
1161
- if (!isSameScopes) {
1162
- return false;
1163
- }
1164
- const existingAccountIds = Object.values(
1165
- walletSession.sessionScopes
1166
- ).filter(({ accounts }) => Boolean(accounts)).flatMap(({ accounts }) => accounts != null ? accounts : []);
1167
- const allProposedAccountsIncluded = proposedCaipAccountIds.every(
1168
- (proposedAccountId) => existingAccountIds.includes(proposedAccountId)
1169
- );
1170
- return allProposedAccountsIncluded;
1171
- }
1172
- function getValidAccounts(caipAccountIds) {
1173
- return caipAccountIds.reduce(
1174
- (caipAccounts, caipAccountId) => {
1175
- try {
1176
- return [...caipAccounts, parseCaipAccountId(caipAccountId)];
1177
- } catch (err) {
1178
- const stringifiedAccountId = JSON.stringify(caipAccountId);
1179
- console.error(`Invalid CAIP account ID: ${stringifiedAccountId}`, err);
1180
- return caipAccounts;
1181
- }
1182
- },
1183
- []
1184
- );
1185
- }
1186
- function addValidAccounts(optionalScopes, validAccounts) {
1187
- var _a;
1188
- if (!optionalScopes || !(validAccounts == null ? void 0 : validAccounts.length)) {
1189
- return optionalScopes;
1190
- }
1191
- const result = Object.fromEntries(
1192
- Object.entries(optionalScopes).map(([scope, scopeData]) => {
1193
- var _a2, _b, _c;
1194
- return [
1195
- scope,
1196
- {
1197
- methods: [...(_a2 = scopeData == null ? void 0 : scopeData.methods) != null ? _a2 : []],
1198
- notifications: [...(_b = scopeData == null ? void 0 : scopeData.notifications) != null ? _b : []],
1199
- accounts: [...(_c = scopeData == null ? void 0 : scopeData.accounts) != null ? _c : []]
1200
- }
1201
- ];
1202
- })
1203
- );
1204
- const accountsByChain = /* @__PURE__ */ new Map();
1205
- for (const account of validAccounts) {
1206
- const chainKey = `${account.chain.namespace}:${account.chain.reference}`;
1207
- const accountId = `${account.chainId}:${account.address}`;
1208
- if (!accountsByChain.has(chainKey)) {
1209
- accountsByChain.set(chainKey, []);
1210
- }
1211
- (_a = accountsByChain.get(chainKey)) == null ? void 0 : _a.push(accountId);
1212
- }
1213
- for (const [scopeKey, scopeData] of Object.entries(result)) {
1214
- if (!(scopeData == null ? void 0 : scopeData.accounts)) {
1215
- continue;
1216
- }
1217
- try {
1218
- const scope = scopeKey;
1219
- const scopeDetails = parseCaipChainId(scope);
1220
- const chainKey = `${scopeDetails.namespace}:${scopeDetails.reference}`;
1221
- const matchingAccounts = accountsByChain.get(chainKey);
1222
- if (matchingAccounts) {
1223
- const existingAccounts = new Set(scopeData.accounts);
1224
- const newAccounts = matchingAccounts.filter(
1225
- (account) => !existingAccounts.has(account)
1226
- );
1227
- scopeData.accounts.push(...newAccounts);
1228
- }
1229
- } catch (error) {
1230
- console.error(`Invalid scope format: ${scopeKey}`, error);
1231
- }
1232
- }
1233
- return result;
1234
- }
1235
-
1236
- // src/multichain/rpc/requestRouter.ts
1298
+ init_utils();
1299
+ init_analytics();
1300
+ var _RequestRouter_instances, withAnalyticsTracking_fn, trackWalletActionRequested_fn, trackWalletActionSucceeded_fn, trackWalletActionFailed_fn, trackWalletActionRejected_fn;
1237
1301
  var RequestRouter = class {
1238
1302
  constructor(transport, rpcClient, config) {
1239
1303
  this.transport = transport;
1240
1304
  this.rpcClient = rpcClient;
1241
1305
  this.config = config;
1306
+ __privateAdd(this, _RequestRouter_instances);
1242
1307
  }
1243
1308
  /**
1244
1309
  * The main entry point for invoking an RPC method.
@@ -1262,7 +1327,7 @@ var RequestRouter = class {
1262
1327
  */
1263
1328
  handleWithWallet(options) {
1264
1329
  return __async(this, null, function* () {
1265
- try {
1330
+ return __privateMethod(this, _RequestRouter_instances, withAnalyticsTracking_fn).call(this, options, () => __async(this, null, function* () {
1266
1331
  const request = this.transport.request({
1267
1332
  method: "wallet_invokeMethod",
1268
1333
  params: options
@@ -1285,9 +1350,7 @@ var RequestRouter = class {
1285
1350
  throw new RPCInvokeMethodErr(`RPC Request failed with code ${response.error.code}: ${response.error.message}`);
1286
1351
  }
1287
1352
  return response.result;
1288
- } catch (error) {
1289
- throw new RPCInvokeMethodErr(error.message);
1290
- }
1353
+ }));
1291
1354
  });
1292
1355
  }
1293
1356
  /**
@@ -1295,14 +1358,16 @@ var RequestRouter = class {
1295
1358
  */
1296
1359
  handleWithRpcNode(options) {
1297
1360
  return __async(this, null, function* () {
1298
- try {
1299
- return yield this.rpcClient.request(options);
1300
- } catch (error) {
1301
- if (error instanceof MissingRpcEndpointErr) {
1302
- return this.handleWithWallet(options);
1361
+ return __privateMethod(this, _RequestRouter_instances, withAnalyticsTracking_fn).call(this, options, () => __async(this, null, function* () {
1362
+ try {
1363
+ return yield this.rpcClient.request(options);
1364
+ } catch (error) {
1365
+ if (error instanceof MissingRpcEndpointErr) {
1366
+ return this.handleWithWallet(options);
1367
+ }
1368
+ throw error;
1303
1369
  }
1304
- throw error;
1305
- }
1370
+ }));
1306
1371
  });
1307
1372
  }
1308
1373
  /**
@@ -1315,8 +1380,59 @@ var RequestRouter = class {
1315
1380
  });
1316
1381
  }
1317
1382
  };
1383
+ _RequestRouter_instances = new WeakSet();
1384
+ withAnalyticsTracking_fn = function(options, execute) {
1385
+ return __async(this, null, function* () {
1386
+ var _a, _b, _c;
1387
+ if ((_a = this.config.analytics) == null ? void 0 : _a.enabled) {
1388
+ yield __privateMethod(this, _RequestRouter_instances, trackWalletActionRequested_fn).call(this, options);
1389
+ }
1390
+ try {
1391
+ const result = yield execute();
1392
+ if ((_b = this.config.analytics) == null ? void 0 : _b.enabled) {
1393
+ yield __privateMethod(this, _RequestRouter_instances, trackWalletActionSucceeded_fn).call(this, options);
1394
+ }
1395
+ return result;
1396
+ } catch (error) {
1397
+ if ((_c = this.config.analytics) == null ? void 0 : _c.enabled) {
1398
+ const isRejection = isRejectionError(error);
1399
+ if (isRejection) {
1400
+ yield __privateMethod(this, _RequestRouter_instances, trackWalletActionRejected_fn).call(this, options);
1401
+ } else {
1402
+ yield __privateMethod(this, _RequestRouter_instances, trackWalletActionFailed_fn).call(this, options);
1403
+ }
1404
+ }
1405
+ throw new RPCInvokeMethodErr(error.message);
1406
+ }
1407
+ });
1408
+ };
1409
+ trackWalletActionRequested_fn = function(options) {
1410
+ return __async(this, null, function* () {
1411
+ const props = yield getWalletActionAnalyticsProperties(this.config, this.config.storage, options);
1412
+ analytics.track("mmconnect_wallet_action_requested", props);
1413
+ });
1414
+ };
1415
+ trackWalletActionSucceeded_fn = function(options) {
1416
+ return __async(this, null, function* () {
1417
+ const props = yield getWalletActionAnalyticsProperties(this.config, this.config.storage, options);
1418
+ analytics.track("mmconnect_wallet_action_succeeded", props);
1419
+ });
1420
+ };
1421
+ trackWalletActionFailed_fn = function(options) {
1422
+ return __async(this, null, function* () {
1423
+ const props = yield getWalletActionAnalyticsProperties(this.config, this.config.storage, options);
1424
+ analytics.track("mmconnect_wallet_action_failed", props);
1425
+ });
1426
+ };
1427
+ trackWalletActionRejected_fn = function(options) {
1428
+ return __async(this, null, function* () {
1429
+ const props = yield getWalletActionAnalyticsProperties(this.config, this.config.storage, options);
1430
+ analytics.track("mmconnect_wallet_action_rejected", props);
1431
+ });
1432
+ };
1318
1433
 
1319
1434
  // src/multichain/transports/default/index.ts
1435
+ init_utils();
1320
1436
  import {
1321
1437
  getDefaultTransport
1322
1438
  } from "@metamask/multichain-api-client";
@@ -1546,6 +1662,7 @@ setupMessageListener_fn = function() {
1546
1662
 
1547
1663
  // src/multichain/transports/mwp/index.ts
1548
1664
  init_domain();
1665
+ init_utils();
1549
1666
  import { SessionStore } from "@metamask/mobile-wallet-protocol-core";
1550
1667
  import {
1551
1668
  TransportTimeoutError
@@ -2023,20 +2140,22 @@ var KeyManager = class {
2023
2140
  var keymanager = new KeyManager();
2024
2141
 
2025
2142
  // src/multichain/index.ts
2143
+ init_utils();
2026
2144
  var logger2 = createLogger("metamask-sdk:core");
2027
2145
  var MultichainSDK = class _MultichainSDK extends MultichainCore {
2028
2146
  constructor(options) {
2029
- var _a, _b, _c, _d, _e, _f;
2147
+ var _a, _b, _c, _d, _e, _f, _g;
2030
2148
  const withDappMetadata = setupDappMetadata(options);
2149
+ const integrationType = ((_a = options.analytics) == null ? void 0 : _a.enabled) ? options.analytics.integrationType : "direct";
2031
2150
  const allOptions = __spreadProps(__spreadValues({}, withDappMetadata), {
2032
2151
  ui: __spreadProps(__spreadValues({}, withDappMetadata.ui), {
2033
- preferExtension: (_a = withDappMetadata.ui.preferExtension) != null ? _a : true,
2034
- showInstallModal: (_b = withDappMetadata.ui.showInstallModal) != null ? _b : false,
2035
- headless: (_c = withDappMetadata.ui.headless) != null ? _c : false
2152
+ preferExtension: (_b = withDappMetadata.ui.preferExtension) != null ? _b : true,
2153
+ showInstallModal: (_c = withDappMetadata.ui.showInstallModal) != null ? _c : false,
2154
+ headless: (_d = withDappMetadata.ui.headless) != null ? _d : false
2036
2155
  }),
2037
- analytics: __spreadProps(__spreadValues({}, (_d = options.analytics) != null ? _d : {}), {
2038
- enabled: (_f = (_e = options.analytics) == null ? void 0 : _e.enabled) != null ? _f : true,
2039
- integrationType: "unknown"
2156
+ analytics: __spreadProps(__spreadValues({}, (_e = options.analytics) != null ? _e : {}), {
2157
+ enabled: (_g = (_f = options.analytics) == null ? void 0 : _f.enabled) != null ? _g : true,
2158
+ integrationType
2040
2159
  })
2041
2160
  });
2042
2161
  super(allOptions);
@@ -2120,12 +2239,12 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
2120
2239
  const { integrationType } = (_b = this.options.analytics) != null ? _b : {
2121
2240
  integrationType: ""
2122
2241
  };
2123
- analytics.setGlobalProperty("sdk_version", version);
2124
- analytics.setGlobalProperty("dapp_id", dappId);
2125
- analytics.setGlobalProperty("anon_id", anonId);
2126
- analytics.setGlobalProperty("platform", platform);
2127
- analytics.setGlobalProperty("integration_type", integrationType);
2128
- analytics.enable();
2242
+ analytics2.setGlobalProperty("mmconnect_version", version);
2243
+ analytics2.setGlobalProperty("dapp_id", dappId);
2244
+ analytics2.setGlobalProperty("anon_id", anonId);
2245
+ analytics2.setGlobalProperty("platform", platform);
2246
+ analytics2.setGlobalProperty("integration_type", integrationType);
2247
+ analytics2.enable();
2129
2248
  });
2130
2249
  }
2131
2250
  onTransportNotification(payload) {
@@ -2187,14 +2306,24 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
2187
2306
  }
2188
2307
  init() {
2189
2308
  return __async(this, null, function* () {
2190
- var _a;
2309
+ var _a, _b;
2191
2310
  try {
2192
2311
  if (typeof window !== "undefined" && ((_a = window.mmsdk) == null ? void 0 : _a.isInitialized)) {
2193
2312
  logger2("MetaMaskSDK: init already initialized");
2194
2313
  } else {
2195
2314
  yield this.setupAnalytics();
2196
2315
  yield this.setupTransport();
2197
- analytics.track("sdk_initialized", {});
2316
+ if ((_b = this.options.analytics) == null ? void 0 : _b.enabled) {
2317
+ try {
2318
+ const baseProps = yield getBaseAnalyticsProperties(
2319
+ this.options,
2320
+ this.storage
2321
+ );
2322
+ analytics2.track("mmconnect_initialized", baseProps);
2323
+ } catch (error) {
2324
+ logger2("Error tracking initialized event", error);
2325
+ }
2326
+ }
2198
2327
  if (typeof window !== "undefined") {
2199
2328
  window.mmsdk = this;
2200
2329
  }
@@ -2373,17 +2502,6 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
2373
2502
  }
2374
2503
  }
2375
2504
  );
2376
- } else {
2377
- timeout = setTimeout(() => {
2378
- var _a;
2379
- const deeplink = this.options.ui.factory.createDeeplink();
2380
- const universalLink = this.options.ui.factory.createUniversalLink();
2381
- if ((_a = this.options.mobile) == null ? void 0 : _a.preferredOpenLink) {
2382
- this.options.mobile.preferredOpenLink(deeplink, "_self");
2383
- } else {
2384
- openDeeplink(this.options, deeplink, universalLink);
2385
- }
2386
- }, 250);
2387
2505
  }
2388
2506
  this.transport.connect({ scopes, caipAccountIds }).then(resolve).catch((error) => {
2389
2507
  this.storage.removeTransport();
@@ -2396,27 +2514,87 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
2396
2514
  }));
2397
2515
  });
2398
2516
  }
2399
- handleConnection(promise) {
2517
+ handleConnection(promise, scopes, transportType) {
2400
2518
  return __async(this, null, function* () {
2401
2519
  this.state = "connecting";
2402
- return promise.then(() => {
2520
+ return promise.then(() => __async(this, null, function* () {
2521
+ var _a;
2403
2522
  this.state = "connected";
2404
- }).catch((error) => {
2523
+ if ((_a = this.options.analytics) == null ? void 0 : _a.enabled) {
2524
+ try {
2525
+ const baseProps = yield getBaseAnalyticsProperties(
2526
+ this.options,
2527
+ this.storage
2528
+ );
2529
+ analytics2.track("mmconnect_connection_established", __spreadProps(__spreadValues({}, baseProps), {
2530
+ transport_type: transportType,
2531
+ user_permissioned_chains: scopes
2532
+ }));
2533
+ } catch (error) {
2534
+ logger2("Error tracking connection_established event", error);
2535
+ }
2536
+ }
2537
+ })).catch((error) => __async(this, null, function* () {
2538
+ var _a;
2405
2539
  this.state = "disconnected";
2540
+ if ((_a = this.options.analytics) == null ? void 0 : _a.enabled) {
2541
+ try {
2542
+ const baseProps = yield getBaseAnalyticsProperties(
2543
+ this.options,
2544
+ this.storage
2545
+ );
2546
+ const isRejection = isRejectionError(error);
2547
+ if (isRejection) {
2548
+ analytics2.track("mmconnect_connection_rejected", __spreadProps(__spreadValues({}, baseProps), {
2549
+ transport_type: transportType
2550
+ }));
2551
+ } else {
2552
+ analytics2.track("mmconnect_connection_failed", __spreadProps(__spreadValues({}, baseProps), {
2553
+ transport_type: transportType
2554
+ }));
2555
+ }
2556
+ } catch (e) {
2557
+ logger2("Error tracking connection failed/rejected event", error);
2558
+ }
2559
+ }
2406
2560
  return Promise.reject(error);
2407
- });
2561
+ }));
2408
2562
  });
2409
2563
  }
2410
2564
  connect(scopes, caipAccountIds, forceRequest) {
2411
2565
  return __async(this, null, function* () {
2412
- var _a;
2566
+ var _a, _b;
2413
2567
  const { ui } = this.options;
2414
2568
  const platformType = getPlatformType();
2415
2569
  const isWeb = platformType === "in-app-browser" /* MetaMaskMobileWebview */ || platformType === "web-desktop" /* DesktopWeb */;
2416
2570
  const { preferExtension = true, showInstallModal = false } = ui;
2417
2571
  const secure = isSecure();
2418
2572
  const hasExtensionInstalled = yield hasExtension();
2419
- if (((_a = this.__transport) == null ? void 0 : _a.isConnected()) && !secure) {
2573
+ let transportType;
2574
+ if (platformType === "in-app-browser" /* MetaMaskMobileWebview */ || isWeb && hasExtensionInstalled && preferExtension) {
2575
+ transportType = "browser" /* Browser */;
2576
+ } else {
2577
+ transportType = "mwp" /* MWP */;
2578
+ }
2579
+ if ((_a = this.options.analytics) == null ? void 0 : _a.enabled) {
2580
+ try {
2581
+ const baseProps = yield getBaseAnalyticsProperties(
2582
+ this.options,
2583
+ this.storage
2584
+ );
2585
+ const dappConfiguredChains = Object.keys(
2586
+ this.options.api.supportedNetworks
2587
+ );
2588
+ analytics2.track("mmconnect_connection_initiated", __spreadProps(__spreadValues({}, baseProps), {
2589
+ transport_type: transportType,
2590
+ dapp_configured_chains: dappConfiguredChains,
2591
+ dapp_requested_chains: scopes
2592
+ }));
2593
+ } catch (error) {
2594
+ logger2("Error tracking connection_initiated event", error);
2595
+ }
2596
+ }
2597
+ if (((_b = this.__transport) == null ? void 0 : _b.isConnected()) && !secure) {
2420
2598
  return this.handleConnection(
2421
2599
  this.__transport.connect({ scopes, caipAccountIds, forceRequest }).then(() => {
2422
2600
  if (this.__transport instanceof MWPTransport) {
@@ -2424,30 +2602,40 @@ var MultichainSDK = class _MultichainSDK extends MultichainCore {
2424
2602
  } else {
2425
2603
  return this.storage.setTransport("browser" /* Browser */);
2426
2604
  }
2427
- })
2605
+ }),
2606
+ scopes,
2607
+ transportType
2428
2608
  );
2429
2609
  }
2430
2610
  if (platformType === "in-app-browser" /* MetaMaskMobileWebview */) {
2431
2611
  const defaultTransport = yield this.setupDefaultTransport();
2432
2612
  return this.handleConnection(
2433
- defaultTransport.connect({ scopes, caipAccountIds, forceRequest })
2613
+ defaultTransport.connect({ scopes, caipAccountIds, forceRequest }),
2614
+ scopes,
2615
+ transportType
2434
2616
  );
2435
2617
  }
2436
2618
  if (isWeb && hasExtensionInstalled && preferExtension) {
2437
2619
  const defaultTransport = yield this.setupDefaultTransport();
2438
2620
  return this.handleConnection(
2439
- defaultTransport.connect({ scopes, caipAccountIds, forceRequest })
2621
+ defaultTransport.connect({ scopes, caipAccountIds, forceRequest }),
2622
+ scopes,
2623
+ transportType
2440
2624
  );
2441
2625
  }
2442
2626
  yield this.setupMWP();
2443
2627
  const shouldShowInstallModal = hasExtensionInstalled ? showInstallModal : !preferExtension || showInstallModal;
2444
2628
  if (secure && !shouldShowInstallModal) {
2445
2629
  return this.handleConnection(
2446
- this.deeplinkConnect(scopes, caipAccountIds)
2630
+ this.deeplinkConnect(scopes, caipAccountIds),
2631
+ scopes,
2632
+ transportType
2447
2633
  );
2448
2634
  }
2449
2635
  return this.handleConnection(
2450
- this.showInstallModal(shouldShowInstallModal, scopes, caipAccountIds)
2636
+ this.showInstallModal(shouldShowInstallModal, scopes, caipAccountIds),
2637
+ scopes,
2638
+ transportType
2451
2639
  );
2452
2640
  });
2453
2641
  }
@@ -2700,6 +2888,7 @@ function preloadQR() {
2700
2888
  }
2701
2889
 
2702
2890
  // src/ui/index.ts
2891
+ init_utils();
2703
2892
  var __instance;
2704
2893
  function preload() {
2705
2894
  return __async(this, null, function* () {
@@ -2792,7 +2981,7 @@ var ModalFactory = class {
2792
2981
  }
2793
2982
  createDeeplink(connectionRequest) {
2794
2983
  if (!connectionRequest) {
2795
- return `${METAMASK_DEEPLINK_BASE}`;
2984
+ throw new Error("createDeeplink can only be called with a connection request");
2796
2985
  }
2797
2986
  const json = JSON.stringify(connectionRequest);
2798
2987
  const compressed = compressString(json);
@@ -2908,10 +3097,12 @@ export {
2908
3097
  getPlatformType,
2909
3098
  getTransportType,
2910
3099
  getVersion,
3100
+ getWalletActionAnalyticsProperties,
2911
3101
  hasExtension,
2912
3102
  infuraRpcUrls,
2913
3103
  isEnabled,
2914
3104
  isMetamaskExtensionInstalled,
3105
+ isRejectionError,
2915
3106
  isSecure
2916
3107
  };
2917
3108
  //# sourceMappingURL=connect-multichain.mjs.map