@openzeppelin/ui-builder-adapter-evm 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -470,7 +470,7 @@ var import_react_query = require("@tanstack/react-query");
470
470
  var import_core3 = require("@wagmi/core");
471
471
  var import_chains3 = require("viem/chains");
472
472
  var import_wagmi = require("wagmi");
473
- var import_react7 = require("react");
473
+ var import_react9 = require("react");
474
474
  var import_ui_builder_utils14 = require("@openzeppelin/ui-builder-utils");
475
475
 
476
476
  // src/wallet/context/wagmi-context.tsx
@@ -490,6 +490,7 @@ var import_viem = require("viem");
490
490
  var import_ui_builder_utils10 = require("@openzeppelin/ui-builder-utils");
491
491
 
492
492
  // src/networks/mainnet.ts
493
+ var import_react2 = require("@web3icons/react");
493
494
  var import_chains = require("viem/chains");
494
495
  var ethereumMainnet = {
495
496
  id: "ethereum-mainnet",
@@ -505,7 +506,7 @@ var ethereumMainnet = {
505
506
  apiUrl: "https://api.etherscan.io/v2/api",
506
507
  primaryExplorerApiIdentifier: "etherscan-v2",
507
508
  supportsEtherscanV2: true,
508
- icon: "ethereum",
509
+ iconComponent: import_react2.NetworkEthereum,
509
510
  nativeCurrency: {
510
511
  name: "Ether",
511
512
  symbol: "ETH",
@@ -527,7 +528,7 @@ var arbitrumMainnet = {
527
528
  apiUrl: "https://api.etherscan.io/v2/api",
528
529
  primaryExplorerApiIdentifier: "etherscan-v2",
529
530
  supportsEtherscanV2: true,
530
- icon: "arbitrum",
531
+ iconComponent: import_react2.NetworkArbitrumOne,
531
532
  nativeCurrency: {
532
533
  name: "Ether",
533
534
  symbol: "ETH",
@@ -549,7 +550,7 @@ var polygonMainnet = {
549
550
  apiUrl: "https://api.etherscan.io/v2/api",
550
551
  primaryExplorerApiIdentifier: "etherscan-v2",
551
552
  supportsEtherscanV2: true,
552
- icon: "polygon",
553
+ iconComponent: import_react2.NetworkPolygon,
553
554
  nativeCurrency: {
554
555
  name: "MATIC",
555
556
  symbol: "MATIC",
@@ -571,7 +572,7 @@ var polygonZkEvmMainnet = {
571
572
  apiUrl: "https://api.etherscan.io/v2/api",
572
573
  primaryExplorerApiIdentifier: "etherscan-v2",
573
574
  supportsEtherscanV2: true,
574
- icon: "polygon",
575
+ iconComponent: import_react2.NetworkPolygon,
575
576
  nativeCurrency: {
576
577
  name: "Ether",
577
578
  symbol: "ETH",
@@ -593,7 +594,7 @@ var baseMainnet = {
593
594
  apiUrl: "https://api.etherscan.io/v2/api",
594
595
  primaryExplorerApiIdentifier: "etherscan-v2",
595
596
  supportsEtherscanV2: true,
596
- icon: "base",
597
+ iconComponent: import_react2.NetworkBase,
597
598
  nativeCurrency: {
598
599
  name: "Ether",
599
600
  symbol: "ETH",
@@ -615,7 +616,7 @@ var bscMainnet = {
615
616
  apiUrl: "https://api.etherscan.io/v2/api",
616
617
  primaryExplorerApiIdentifier: "etherscan-v2",
617
618
  supportsEtherscanV2: true,
618
- icon: "bsc",
619
+ iconComponent: import_react2.NetworkBinanceSmartChain,
619
620
  nativeCurrency: {
620
621
  name: "BNB",
621
622
  symbol: "BNB",
@@ -637,7 +638,7 @@ var optimismMainnet = {
637
638
  apiUrl: "https://api.etherscan.io/v2/api",
638
639
  primaryExplorerApiIdentifier: "etherscan-v2",
639
640
  supportsEtherscanV2: true,
640
- icon: "optimism",
641
+ iconComponent: import_react2.NetworkOptimism,
641
642
  nativeCurrency: {
642
643
  name: "Ether",
643
644
  symbol: "ETH",
@@ -659,7 +660,7 @@ var avalancheMainnet = {
659
660
  apiUrl: "https://api.etherscan.io/v2/api",
660
661
  primaryExplorerApiIdentifier: "etherscan-v2",
661
662
  supportsEtherscanV2: true,
662
- icon: "avalanche",
663
+ iconComponent: import_react2.NetworkAvalanche,
663
664
  nativeCurrency: {
664
665
  name: "Avalanche",
665
666
  symbol: "AVAX",
@@ -681,7 +682,7 @@ var zkSyncEraMainnet = {
681
682
  apiUrl: "https://block-explorer-api.mainnet.zksync.io/api",
682
683
  primaryExplorerApiIdentifier: "zksync-era-mainnet",
683
684
  supportsEtherscanV2: false,
684
- icon: "zksync",
685
+ iconComponent: import_react2.NetworkZksync,
685
686
  nativeCurrency: {
686
687
  name: "Ether",
687
688
  symbol: "ETH",
@@ -703,7 +704,7 @@ var scrollMainnet = {
703
704
  apiUrl: "https://api.etherscan.io/v2/api",
704
705
  primaryExplorerApiIdentifier: "etherscan-v2",
705
706
  supportsEtherscanV2: true,
706
- icon: "scroll",
707
+ iconComponent: import_react2.NetworkScroll,
707
708
  nativeCurrency: {
708
709
  name: "Ether",
709
710
  symbol: "ETH",
@@ -725,7 +726,7 @@ var lineaMainnet = {
725
726
  apiUrl: "https://api.etherscan.io/v2/api",
726
727
  primaryExplorerApiIdentifier: "etherscan-v2",
727
728
  supportsEtherscanV2: true,
728
- icon: "linea",
729
+ iconComponent: import_react2.NetworkLinea,
729
730
  nativeCurrency: {
730
731
  name: "Ether",
731
732
  symbol: "ETH",
@@ -735,6 +736,7 @@ var lineaMainnet = {
735
736
  };
736
737
 
737
738
  // src/networks/testnet.ts
739
+ var import_react3 = require("@web3icons/react");
738
740
  var import_chains2 = require("viem/chains");
739
741
  var ethereumSepolia = {
740
742
  id: "ethereum-sepolia",
@@ -750,7 +752,7 @@ var ethereumSepolia = {
750
752
  apiUrl: "https://api.etherscan.io/v2/api",
751
753
  primaryExplorerApiIdentifier: "etherscan-v2",
752
754
  supportsEtherscanV2: true,
753
- icon: "ethereum",
755
+ iconComponent: import_react3.NetworkEthereum,
754
756
  nativeCurrency: {
755
757
  name: "Sepolia Ether",
756
758
  symbol: "ETH",
@@ -772,7 +774,7 @@ var arbitrumSepolia = {
772
774
  apiUrl: "https://api.etherscan.io/v2/api",
773
775
  primaryExplorerApiIdentifier: "etherscan-v2",
774
776
  supportsEtherscanV2: true,
775
- icon: "arbitrum",
777
+ iconComponent: import_react3.NetworkArbitrumOne,
776
778
  nativeCurrency: {
777
779
  name: "Arbitrum Sepolia Ether",
778
780
  symbol: "ETH",
@@ -794,7 +796,7 @@ var polygonAmoy = {
794
796
  apiUrl: "https://api.etherscan.io/v2/api",
795
797
  primaryExplorerApiIdentifier: "etherscan-v2",
796
798
  supportsEtherscanV2: true,
797
- icon: "polygon",
799
+ iconComponent: import_react3.NetworkPolygon,
798
800
  nativeCurrency: {
799
801
  name: "MATIC",
800
802
  symbol: "MATIC",
@@ -816,7 +818,7 @@ var polygonZkEvmCardona = {
816
818
  apiUrl: "https://api.etherscan.io/v2/api",
817
819
  primaryExplorerApiIdentifier: "etherscan-v2",
818
820
  supportsEtherscanV2: true,
819
- icon: "polygon",
821
+ iconComponent: import_react3.NetworkPolygon,
820
822
  nativeCurrency: {
821
823
  name: "Ether",
822
824
  symbol: "ETH",
@@ -838,7 +840,7 @@ var baseSepolia = {
838
840
  apiUrl: "https://api.etherscan.io/v2/api",
839
841
  primaryExplorerApiIdentifier: "etherscan-v2",
840
842
  supportsEtherscanV2: true,
841
- icon: "base",
843
+ iconComponent: import_react3.NetworkBase,
842
844
  nativeCurrency: {
843
845
  name: "Sepolia Ether",
844
846
  symbol: "ETH",
@@ -860,7 +862,7 @@ var bscTestnet = {
860
862
  apiUrl: "https://api.etherscan.io/v2/api",
861
863
  primaryExplorerApiIdentifier: "etherscan-v2",
862
864
  supportsEtherscanV2: true,
863
- icon: "bsc",
865
+ iconComponent: import_react3.NetworkBinanceSmartChain,
864
866
  nativeCurrency: {
865
867
  name: "BNB",
866
868
  symbol: "BNB",
@@ -882,7 +884,7 @@ var optimismSepolia = {
882
884
  apiUrl: "https://api.etherscan.io/v2/api",
883
885
  primaryExplorerApiIdentifier: "etherscan-v2",
884
886
  supportsEtherscanV2: true,
885
- icon: "optimism",
887
+ iconComponent: import_react3.NetworkOptimism,
886
888
  nativeCurrency: {
887
889
  name: "Sepolia Ether",
888
890
  symbol: "ETH",
@@ -907,7 +909,7 @@ var avalancheFuji = {
907
909
  // Unified identifier for V2 API
908
910
  supportsEtherscanV2: true,
909
911
  requiresExplorerApiKey: true,
910
- icon: "avalanche",
912
+ iconComponent: import_react3.NetworkAvalanche,
911
913
  nativeCurrency: {
912
914
  name: "Avalanche",
913
915
  symbol: "AVAX",
@@ -929,7 +931,7 @@ var zksyncSepoliaTestnet = {
929
931
  apiUrl: "https://block-explorer-api.sepolia.zksync.dev/api",
930
932
  primaryExplorerApiIdentifier: "zksync-era-sepolia",
931
933
  supportsEtherscanV2: false,
932
- icon: "zksync",
934
+ iconComponent: import_react3.NetworkZksync,
933
935
  nativeCurrency: {
934
936
  name: "Ether",
935
937
  symbol: "ETH",
@@ -951,7 +953,7 @@ var scrollSepolia = {
951
953
  apiUrl: "https://api.etherscan.io/v2/api",
952
954
  primaryExplorerApiIdentifier: "etherscan-v2",
953
955
  supportsEtherscanV2: true,
954
- icon: "scroll",
956
+ iconComponent: import_react3.NetworkScroll,
955
957
  nativeCurrency: {
956
958
  name: "Ether",
957
959
  symbol: "ETH",
@@ -973,7 +975,7 @@ var lineaSepolia = {
973
975
  apiUrl: "https://api.etherscan.io/v2/api",
974
976
  primaryExplorerApiIdentifier: "etherscan-v2",
975
977
  supportsEtherscanV2: true,
976
- icon: "linea",
978
+ iconComponent: import_react3.NetworkLinea,
977
979
  nativeCurrency: {
978
980
  name: "Linea Ether",
979
981
  symbol: "ETH",
@@ -995,7 +997,7 @@ var monadTestnet = {
995
997
  apiUrl: "https://api.etherscan.io/v2/api",
996
998
  primaryExplorerApiIdentifier: "etherscan-v2",
997
999
  supportsEtherscanV2: true,
998
- icon: "monad",
1000
+ iconComponent: import_react3.NetworkMonad,
999
1001
  nativeCurrency: {
1000
1002
  name: "Monad",
1001
1003
  symbol: "MON",
@@ -1038,25 +1040,25 @@ var evmNetworks = [...evmMainnetNetworks, ...evmTestnetNetworks];
1038
1040
 
1039
1041
  // src/wallet/rainbowkit/components.tsx
1040
1042
  var import_lucide_react4 = require("lucide-react");
1041
- var import_react6 = require("react");
1043
+ var import_react8 = require("react");
1042
1044
  var import_ui_builder_ui5 = require("@openzeppelin/ui-builder-ui");
1043
1045
  var import_ui_builder_utils7 = require("@openzeppelin/ui-builder-utils");
1044
1046
 
1045
1047
  // src/wallet/components/connect/ConnectButton.tsx
1046
1048
  var import_lucide_react = require("lucide-react");
1047
- var import_react5 = require("react");
1049
+ var import_react7 = require("react");
1048
1050
  var import_ui_builder_react_core2 = require("@openzeppelin/ui-builder-react-core");
1049
1051
  var import_ui_builder_ui2 = require("@openzeppelin/ui-builder-ui");
1050
1052
  var import_ui_builder_utils4 = require("@openzeppelin/ui-builder-utils");
1051
1053
 
1052
1054
  // src/wallet/utils/SafeWagmiComponent.tsx
1053
- var import_react3 = require("react");
1055
+ var import_react5 = require("react");
1054
1056
  var import_ui_builder_utils2 = require("@openzeppelin/ui-builder-utils");
1055
1057
 
1056
1058
  // src/wallet/hooks/useIsWagmiProviderInitialized.ts
1057
- var import_react2 = require("react");
1059
+ var import_react4 = require("react");
1058
1060
  var useIsWagmiProviderInitialized = () => {
1059
- return (0, import_react2.useContext)(WagmiProviderInitializedContext);
1061
+ return (0, import_react4.useContext)(WagmiProviderInitializedContext);
1060
1062
  };
1061
1063
 
1062
1064
  // src/wallet/utils/SafeWagmiComponent.tsx
@@ -1066,13 +1068,13 @@ var SafeWagmiComponent = ({
1066
1068
  fallback = null
1067
1069
  }) => {
1068
1070
  const isProviderInitialized = useIsWagmiProviderInitialized();
1069
- const [hasError, setHasError] = (0, import_react3.useState)(false);
1070
- (0, import_react3.useEffect)(() => {
1071
+ const [hasError, setHasError] = (0, import_react5.useState)(false);
1072
+ (0, import_react5.useEffect)(() => {
1071
1073
  if (isProviderInitialized) {
1072
1074
  setHasError(false);
1073
1075
  }
1074
1076
  }, [isProviderInitialized]);
1075
- (0, import_react3.useEffect)(() => {
1077
+ (0, import_react5.useEffect)(() => {
1076
1078
  const handleError = (event) => {
1077
1079
  if (event.error?.message?.includes("useConfig") || event.error?.message?.includes("WagmiProvider")) {
1078
1080
  import_ui_builder_utils2.logger.debug(
@@ -1105,7 +1107,7 @@ var SafeWagmiComponent = ({
1105
1107
  };
1106
1108
 
1107
1109
  // src/wallet/components/connect/ConnectorDialog.tsx
1108
- var import_react4 = require("react");
1110
+ var import_react6 = require("react");
1109
1111
  var import_ui_builder_react_core = require("@openzeppelin/ui-builder-react-core");
1110
1112
  var import_ui_builder_ui = require("@openzeppelin/ui-builder-ui");
1111
1113
 
@@ -1165,12 +1167,12 @@ var ConnectorDialogContent = ({ open, onOpenChange }) => {
1165
1167
  pendingConnector
1166
1168
  } = (0, import_ui_builder_react_core.useDerivedConnectStatus)();
1167
1169
  const { isConnected } = (0, import_ui_builder_react_core.useDerivedAccountStatus)();
1168
- const [connectingId, setConnectingId] = (0, import_react4.useState)(null);
1170
+ const [connectingId, setConnectingId] = (0, import_react6.useState)(null);
1169
1171
  const fullConfig = useUiKitConfig();
1170
1172
  const showInjectedConnector = isConfigEnabled("showInjectedConnector");
1171
- (0, import_react4.useEffect)(() => {
1173
+ (0, import_react6.useEffect)(() => {
1172
1174
  }, [fullConfig, showInjectedConnector, isConnecting, pendingConnector]);
1173
- (0, import_react4.useEffect)(() => {
1175
+ (0, import_react6.useEffect)(() => {
1174
1176
  if (isConnected && connectingId) {
1175
1177
  onOpenChange(false);
1176
1178
  setConnectingId(null);
@@ -1219,7 +1221,7 @@ var CustomConnectButton = ({
1219
1221
  className,
1220
1222
  hideWhenConnected = true
1221
1223
  }) => {
1222
- const [dialogOpen, setDialogOpen] = (0, import_react5.useState)(false);
1224
+ const [dialogOpen, setDialogOpen] = (0, import_react7.useState)(false);
1223
1225
  const unavailableButton = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: (0, import_ui_builder_utils4.cn)("flex items-center", className), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_ui_builder_ui2.Button, { disabled: true, variant: "outline", size: "sm", className: "h-8 px-2 text-xs", children: [
1224
1226
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react.Wallet, { className: "size-3.5 mr-1" }),
1225
1227
  "Wallet Unavailable"
@@ -1237,19 +1239,19 @@ var CustomConnectButton = ({
1237
1239
  var ConnectButtonContent = ({ className, dialogOpen, setDialogOpen, hideWhenConnected }) => {
1238
1240
  const { isConnected } = (0, import_ui_builder_react_core2.useDerivedAccountStatus)();
1239
1241
  const { isConnecting: isHookConnecting, error: connectError } = (0, import_ui_builder_react_core2.useDerivedConnectStatus)();
1240
- const [isManuallyInitiated, setIsManuallyInitiated] = (0, import_react5.useState)(false);
1241
- (0, import_react5.useEffect)(() => {
1242
+ const [isManuallyInitiated, setIsManuallyInitiated] = (0, import_react7.useState)(false);
1243
+ (0, import_react7.useEffect)(() => {
1242
1244
  if (isConnected && hideWhenConnected) {
1243
1245
  setDialogOpen(false);
1244
1246
  setIsManuallyInitiated(false);
1245
1247
  }
1246
1248
  }, [isConnected, hideWhenConnected, setDialogOpen]);
1247
- (0, import_react5.useEffect)(() => {
1249
+ (0, import_react7.useEffect)(() => {
1248
1250
  if (!dialogOpen) {
1249
1251
  setIsManuallyInitiated(false);
1250
1252
  }
1251
1253
  }, [dialogOpen]);
1252
- (0, import_react5.useEffect)(() => {
1254
+ (0, import_react7.useEffect)(() => {
1253
1255
  if (isHookConnecting) {
1254
1256
  setIsManuallyInitiated(false);
1255
1257
  }
@@ -1396,20 +1398,20 @@ function extractRainbowKitCustomizations(kitConfig) {
1396
1398
  var import_jsx_runtime6 = require("react/jsx-runtime");
1397
1399
  var MIN_COMPONENT_LOADING_DISPLAY_MS = 1e3;
1398
1400
  var RainbowKitConnectButton = (props) => {
1399
- const [Component, setComponent] = (0, import_react6.useState)(null);
1400
- const [error, setError] = (0, import_react6.useState)(null);
1401
- const [isLoadingComponent, setIsLoadingComponent] = (0, import_react6.useState)(true);
1402
- const [showComponentLoadingOverride, setShowComponentLoadingOverride] = (0, import_react6.useState)(false);
1403
- const componentLoadingTimerRef = (0, import_react6.useRef)(null);
1404
- const [managerState, setManagerState] = (0, import_react6.useState)(evmUiKitManager.getState());
1405
- const isWagmiProviderReady = (0, import_react6.useContext)(WagmiProviderInitializedContext);
1406
- (0, import_react6.useEffect)(() => {
1401
+ const [Component, setComponent] = (0, import_react8.useState)(null);
1402
+ const [error, setError] = (0, import_react8.useState)(null);
1403
+ const [isLoadingComponent, setIsLoadingComponent] = (0, import_react8.useState)(true);
1404
+ const [showComponentLoadingOverride, setShowComponentLoadingOverride] = (0, import_react8.useState)(false);
1405
+ const componentLoadingTimerRef = (0, import_react8.useRef)(null);
1406
+ const [managerState, setManagerState] = (0, import_react8.useState)(evmUiKitManager.getState());
1407
+ const isWagmiProviderReady = (0, import_react8.useContext)(WagmiProviderInitializedContext);
1408
+ (0, import_react8.useEffect)(() => {
1407
1409
  const unsubscribe = evmUiKitManager.subscribe(() => {
1408
1410
  setManagerState(evmUiKitManager.getState());
1409
1411
  });
1410
1412
  return unsubscribe;
1411
1413
  }, []);
1412
- (0, import_react6.useEffect)(() => {
1414
+ (0, import_react8.useEffect)(() => {
1413
1415
  let isMounted = true;
1414
1416
  setIsLoadingComponent(true);
1415
1417
  setShowComponentLoadingOverride(true);
@@ -2288,10 +2290,10 @@ var minimalDefaultWagmiConfig = (0, import_core3.createConfig)({
2288
2290
  }
2289
2291
  });
2290
2292
  var EvmWalletUiRoot = ({ children }) => {
2291
- const [managerState, setManagerState] = (0, import_react7.useState)(
2293
+ const [managerState, setManagerState] = (0, import_react9.useState)(
2292
2294
  evmUiKitManager.getState()
2293
2295
  );
2294
- (0, import_react7.useEffect)(() => {
2296
+ (0, import_react9.useEffect)(() => {
2295
2297
  const handleStateChange = () => {
2296
2298
  setManagerState(evmUiKitManager.getState());
2297
2299
  };
@@ -2299,7 +2301,7 @@ var EvmWalletUiRoot = ({ children }) => {
2299
2301
  handleStateChange();
2300
2302
  return unsubscribe;
2301
2303
  }, []);
2302
- const queryClient = (0, import_react7.useMemo)(() => stableQueryClient, []);
2304
+ const queryClient = (0, import_react9.useMemo)(() => stableQueryClient, []);
2303
2305
  const {
2304
2306
  wagmiConfig,
2305
2307
  kitProviderComponent,
@@ -3685,54 +3687,38 @@ async function getContractBytecode(address, networkConfig) {
3685
3687
 
3686
3688
  // src/abi/sourcify.ts
3687
3689
  var import_ui_builder_utils27 = require("@openzeppelin/ui-builder-utils");
3688
- var SOURCIFY_BASE = "https://repo.sourcify.dev";
3689
- function buildSourcifyAbiUrlCandidates(chainId, address) {
3690
- const addrLower = address.toLowerCase();
3691
- const addrOriginal = address;
3692
- const categories = ["full_match", "partial_match"];
3693
- const addrs = [addrLower, addrOriginal];
3694
- const urls = [];
3695
- for (const category of categories) {
3696
- for (const addr of addrs) {
3697
- urls.push(`${SOURCIFY_BASE}/contracts/${category}/${chainId}/${addr}/metadata.json`);
3698
- }
3699
- }
3700
- return urls;
3690
+ var SOURCIFY_APP_BASE = "https://sourcify.dev";
3691
+ function getSourcifyContractAppUrl(chainId, address) {
3692
+ const normalizedAddress = address.toLowerCase();
3693
+ return `${SOURCIFY_APP_BASE}/status/${chainId}/${normalizedAddress}`;
3701
3694
  }
3702
- function getSourcifyRepoContractUrl(chainId, address) {
3703
- return `${SOURCIFY_BASE}/${chainId}/${address}`;
3695
+ var SOURCIFY_API_BASE = "https://sourcify.dev/server/v2";
3696
+ function buildSourcifyApiUrl(chainId, address) {
3697
+ const normalizedAddress = address.toLowerCase();
3698
+ const url = new URL(
3699
+ `${SOURCIFY_API_BASE}/contract/${chainId}/${normalizedAddress}?fields=abi,metadata`
3700
+ );
3701
+ return url.toString();
3704
3702
  }
3705
3703
  async function loadAbiFromSourcify(address, networkConfig, timeoutMs = 4e3) {
3706
- const candidates = buildSourcifyAbiUrlCandidates(networkConfig.chainId, address);
3707
3704
  const controller = new AbortController();
3708
3705
  const timeout = setTimeout(() => controller.abort(), timeoutMs);
3709
3706
  try {
3710
- let lastError = null;
3711
- for (const url of candidates) {
3712
- try {
3713
- import_ui_builder_utils27.logger.info("loadAbiFromSourcify", `Fetching metadata from ${url}`);
3714
- const response = await fetch(url, { signal: controller.signal });
3715
- if (!response.ok) {
3716
- lastError = new Error(
3717
- `Sourcify request failed: ${response.status} ${response.statusText} (${url})`
3718
- );
3719
- continue;
3720
- }
3721
- const metadata = await response.json();
3722
- const abi = metadata?.output?.abi;
3723
- if (!abi || !Array.isArray(abi)) {
3724
- lastError = new Error("Sourcify metadata did not include a valid ABI array");
3725
- continue;
3726
- }
3727
- const contractName = metadata.contractName || `Contract_${address.substring(0, 6)}`;
3728
- const schema = transformAbiToSchema(abi, contractName, address);
3729
- return { schema, originalAbi: JSON.stringify(abi) };
3730
- } catch (inner) {
3731
- lastError = inner;
3732
- continue;
3733
- }
3707
+ const url = buildSourcifyApiUrl(networkConfig.chainId, address);
3708
+ import_ui_builder_utils27.logger.info("loadAbiFromSourcify", `Fetching contract from ${url}`);
3709
+ const response = await fetch(url, { signal: controller.signal });
3710
+ if (!response.ok) {
3711
+ throw new Error(`Sourcify request failed: ${response.status} ${response.statusText}`);
3712
+ }
3713
+ const payload = await response.json();
3714
+ const abi = payload.abi ?? payload.metadata?.output?.abi;
3715
+ if (!abi || !Array.isArray(abi)) {
3716
+ throw new Error("Sourcify metadata did not include a valid ABI array");
3734
3717
  }
3735
- throw lastError ?? new Error("Sourcify metadata not found for any candidate URL");
3718
+ const normalizedAddress = address.toLowerCase();
3719
+ const contractName = payload.metadata?.contractName || `Contract_${normalizedAddress.substring(0, 6).toUpperCase()}`;
3720
+ const schema = transformAbiToSchema(abi, contractName, address);
3721
+ return { schema, originalAbi: JSON.stringify(abi) };
3736
3722
  } catch (error) {
3737
3723
  import_ui_builder_utils27.logger.warn("loadAbiFromSourcify", `Failed to fetch ABI from Sourcify: ${String(error)}`);
3738
3724
  throw error;
@@ -3814,7 +3800,7 @@ function buildContractResult(contractAddress, abiResult, networkConfig, sourcePr
3814
3800
  if (sourceProvider === EvmProviderKeys.Etherscan) {
3815
3801
  fetchedFrom = getEvmExplorerAddressUrl(contractAddress, networkConfig) || void 0;
3816
3802
  } else if (sourceProvider === EvmProviderKeys.Sourcify) {
3817
- fetchedFrom = getSourcifyRepoContractUrl(networkConfig.chainId, contractAddress);
3803
+ fetchedFrom = getSourcifyContractAppUrl(networkConfig.chainId, contractAddress);
3818
3804
  } else {
3819
3805
  fetchedFrom = getEvmExplorerAddressUrl(contractAddress, networkConfig) || void 0;
3820
3806
  }
@@ -4843,7 +4829,7 @@ var EoaExecutionStrategy = class {
4843
4829
  };
4844
4830
 
4845
4831
  // src/transaction/components/EvmRelayerOptions.tsx
4846
- var import_react9 = __toESM(require("react"), 1);
4832
+ var import_react11 = __toESM(require("react"), 1);
4847
4833
  var import_ui_builder_ui9 = require("@openzeppelin/ui-builder-ui");
4848
4834
 
4849
4835
  // src/transaction/components/AdvancedInfo.tsx
@@ -5096,11 +5082,11 @@ var SpeedSelection = ({ selectedSpeed, onSpeedChange }) => {
5096
5082
  };
5097
5083
 
5098
5084
  // src/transaction/components/useEvmRelayerOptions.ts
5099
- var import_react8 = require("react");
5085
+ var import_react10 = require("react");
5100
5086
  var import_react_hook_form = require("react-hook-form");
5101
5087
  var import_relayer_sdk3 = require("@openzeppelin/relayer-sdk");
5102
5088
  var useEvmRelayerOptions = ({ options, onChange }) => {
5103
- const onChangeRef = (0, import_react8.useRef)(onChange);
5089
+ const onChangeRef = (0, import_react10.useRef)(onChange);
5104
5090
  onChangeRef.current = onChange;
5105
5091
  const initialOptions = {
5106
5092
  speed: (() => {
@@ -5121,14 +5107,14 @@ var useEvmRelayerOptions = ({ options, onChange }) => {
5121
5107
  }
5122
5108
  });
5123
5109
  const formValues = watch("transactionOptions");
5124
- const isInitialMount = (0, import_react8.useRef)(true);
5110
+ const isInitialMount = (0, import_react10.useRef)(true);
5125
5111
  const hasCustomSettings = Boolean(
5126
5112
  formValues.gasPrice || formValues.maxFeePerGas || formValues.maxPriorityFeePerGas
5127
5113
  );
5128
5114
  const configMode = hasCustomSettings ? "custom" : "speed";
5129
5115
  const isEip1559 = Boolean(formValues.maxFeePerGas || formValues.maxPriorityFeePerGas);
5130
5116
  const gasType = isEip1559 ? "eip1559" : "legacy";
5131
- (0, import_react8.useEffect)(() => {
5117
+ (0, import_react10.useEffect)(() => {
5132
5118
  if (isInitialMount.current) {
5133
5119
  isInitialMount.current = false;
5134
5120
  if (initialOptions.speed && !options.speed) {
@@ -5140,7 +5126,7 @@ var useEvmRelayerOptions = ({ options, onChange }) => {
5140
5126
  return;
5141
5127
  }
5142
5128
  }, []);
5143
- (0, import_react8.useEffect)(() => {
5129
+ (0, import_react10.useEffect)(() => {
5144
5130
  if (isInitialMount.current) {
5145
5131
  return;
5146
5132
  }
@@ -5221,7 +5207,7 @@ var useEvmRelayerOptions = ({ options, onChange }) => {
5221
5207
  // src/transaction/components/EvmRelayerOptions.tsx
5222
5208
  var import_jsx_runtime11 = require("react/jsx-runtime");
5223
5209
  var EvmRelayerOptions = ({ options, onChange }) => {
5224
- const [showAdvancedInfo, setShowAdvancedInfo] = import_react9.default.useState(false);
5210
+ const [showAdvancedInfo, setShowAdvancedInfo] = import_react11.default.useState(false);
5225
5211
  const {
5226
5212
  control,
5227
5213
  formValues,