@openzeppelin/ui-renderer 1.2.0 → 2.0.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
@@ -206,8 +206,8 @@ const ExecutionConfigCard = ({ config }) => {
206
206
  //#region src/components/ExecutionConfigDisplay/components/RelayerConfigDetails.tsx
207
207
  const RelayerConfigDetails = ({ config, enhancedDetails, loading = false }) => {
208
208
  const { relayer } = config;
209
- const { activeAdapter } = (0, _openzeppelin_ui_react.useWalletState)();
210
- const labels = activeAdapter?.getUiLabels?.();
209
+ const { activeRuntime } = (0, _openzeppelin_ui_react.useWalletState)();
210
+ const labels = activeRuntime?.uiLabels.getUiLabels();
211
211
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
212
212
  className: "space-y-4",
213
213
  children: [
@@ -244,18 +244,18 @@ const RelayerConfigDetails = ({ config, enhancedDetails, loading = false }) => {
244
244
 
245
245
  //#endregion
246
246
  //#region src/components/ExecutionConfigDisplay/hooks/useExecutionValidation.ts
247
- const useExecutionValidation = ({ executionConfig, adapter, runtimeApiKey }) => {
247
+ const useExecutionValidation = ({ executionConfig, execution, runtimeApiKey }) => {
248
248
  const [validationResult, setValidationResult] = (0, react.useState)({ isValid: true });
249
249
  const validateConfig = (0, react.useCallback)(async () => {
250
- if (!adapter) {
250
+ if (!execution) {
251
251
  setValidationResult({
252
252
  isValid: false,
253
- error: "No adapter available for validation"
253
+ error: "No execution capability available for validation"
254
254
  });
255
255
  return;
256
256
  }
257
257
  try {
258
- const result = await adapter.validateExecutionConfig(executionConfig);
258
+ const result = await execution.validateExecutionConfig(executionConfig);
259
259
  if (result === true) {
260
260
  let runtimeError;
261
261
  if (executionConfig.method === "relayer" && (!runtimeApiKey || runtimeApiKey.trim() === "")) runtimeError = "Relayer API key is required for transaction execution";
@@ -274,8 +274,8 @@ const useExecutionValidation = ({ executionConfig, adapter, runtimeApiKey }) =>
274
274
  });
275
275
  }
276
276
  }, [
277
+ execution,
277
278
  executionConfig,
278
- adapter,
279
279
  runtimeApiKey
280
280
  ]);
281
281
  (0, react.useEffect)(() => {
@@ -286,7 +286,7 @@ const useExecutionValidation = ({ executionConfig, adapter, runtimeApiKey }) =>
286
286
 
287
287
  //#endregion
288
288
  //#region src/components/ExecutionConfigDisplay/ExecutionConfigDisplay.tsx
289
- const ExecutionConfigDisplay = ({ executionConfig, adapter, error, onRuntimeApiKeyChange }) => {
289
+ const ExecutionConfigDisplay = ({ executionConfig, execution, relayer, error, onRuntimeApiKeyChange }) => {
290
290
  const { control, watch } = (0, react_hook_form.useForm)({ defaultValues: { runtimeApiKey: "" } });
291
291
  const runtimeApiKey = watch("runtimeApiKey");
292
292
  const [isOpen, setIsOpen] = (0, react.useState)(false);
@@ -294,17 +294,17 @@ const ExecutionConfigDisplay = ({ executionConfig, adapter, error, onRuntimeApiK
294
294
  const [relayerDetailsLoading, setRelayerDetailsLoading] = (0, react.useState)(false);
295
295
  const { isValid, error: validationError } = useExecutionValidation({
296
296
  executionConfig,
297
- adapter,
297
+ execution,
298
298
  runtimeApiKey
299
299
  });
300
300
  (0, react.useEffect)(() => {
301
301
  onRuntimeApiKeyChange?.(runtimeApiKey);
302
302
  }, [runtimeApiKey, onRuntimeApiKeyChange]);
303
303
  (0, react.useEffect)(() => {
304
- if (isOpen && executionConfig.method === "relayer" && runtimeApiKey && adapter?.getRelayer) {
304
+ if (isOpen && executionConfig.method === "relayer" && runtimeApiKey && relayer?.getRelayer) {
305
305
  const relayerConfig = executionConfig;
306
306
  setRelayerDetailsLoading(true);
307
- adapter.getRelayer(relayerConfig.serviceUrl, runtimeApiKey, relayerConfig.relayer.relayerId).then((details) => {
307
+ relayer.getRelayer(relayerConfig.serviceUrl, runtimeApiKey, relayerConfig.relayer.relayerId).then((details) => {
308
308
  setEnhancedRelayerDetails(details);
309
309
  }).catch((err) => {
310
310
  _openzeppelin_ui_utils.logger.error("ExecutionConfigDisplay", "Failed to fetch enhanced relayer details:", err);
@@ -314,10 +314,10 @@ const ExecutionConfigDisplay = ({ executionConfig, adapter, error, onRuntimeApiK
314
314
  });
315
315
  }
316
316
  }, [
317
- isOpen,
318
317
  executionConfig,
319
- runtimeApiKey,
320
- adapter
318
+ isOpen,
319
+ relayer,
320
+ runtimeApiKey
321
321
  ]);
322
322
  const getExecutionContent = () => {
323
323
  switch (executionConfig.method) {
@@ -438,10 +438,10 @@ function validateField(value, validation) {
438
438
  /**
439
439
  * Creates a transform for address fields
440
440
  *
441
- * @param adapter The blockchain adapter to use for validation
441
+ * @param addressing The addressing capability to use for validation
442
442
  * @returns Transform functions for address fields
443
443
  */
444
- function createAddressTransform(adapter) {
444
+ function createAddressTransform(addressing) {
445
445
  return {
446
446
  input: (value) => {
447
447
  if (value === null || value === void 0) return "";
@@ -449,7 +449,7 @@ function createAddressTransform(adapter) {
449
449
  },
450
450
  output: (value) => {
451
451
  const address = String(value || "");
452
- if (adapter.isValidAddress?.(address)) return address;
452
+ if (addressing.isValidAddress(address)) return address;
453
453
  return "";
454
454
  }
455
455
  };
@@ -553,14 +553,14 @@ function createTextTransform() {
553
553
  * Creates a transform function based on field type
554
554
  *
555
555
  * @param fieldType The type of field to create transforms for
556
- * @param adapter Optional adapter for address validation
556
+ * @param addressing Optional addressing capability for address validation
557
557
  * @returns Transform functions for the field type
558
558
  */
559
- function createTransformForFieldType(fieldType, adapter) {
559
+ function createTransformForFieldType(fieldType, addressing) {
560
560
  switch (fieldType) {
561
561
  case "blockchain-address":
562
- if (!adapter) throw new Error(`createTransformForFieldType: Adapter is required for 'blockchain-address' field type but was not provided.`);
563
- return createAddressTransform(adapter);
562
+ if (!addressing) throw new Error(`createTransformForFieldType: Addressing capability is required for 'blockchain-address' field type but was not provided.`);
563
+ return createAddressTransform(addressing);
564
564
  case "number":
565
565
  case "amount": return createNumberTransform();
566
566
  case "bigint": return createBigIntTransform();
@@ -871,11 +871,15 @@ function useShouldRenderField(field, control) {
871
871
  *
872
872
  * @returns The rendered form field component or null if the field should not be visible
873
873
  */
874
- function DynamicFormField({ field, control, adapter, contractSchema }) {
874
+ function DynamicFormField({ field, control, addressing, typeMapping, contractSchema }) {
875
+ const requireTypeMapping = (0, react.useCallback)((fieldName, fieldType) => {
876
+ if (!typeMapping) throw new Error(`DynamicFormField: Missing typeMapping capability for field "${fieldName}" (${fieldType}).`);
877
+ return typeMapping;
878
+ }, [typeMapping]);
875
879
  const renderPayloadField = (0, react.useCallback)((payloadField, payloadIndex) => {
876
880
  let enhancedPayloadField;
877
881
  if (payloadField.originalParameterType) {
878
- const generatedField = adapter.generateDefaultField({
882
+ const generatedField = requireTypeMapping(payloadField.name, payloadField.type).generateDefaultField({
879
883
  name: payloadField.name || `payload_${payloadIndex}`,
880
884
  type: payloadField.originalParameterType
881
885
  }, contractSchema);
@@ -894,17 +898,20 @@ function DynamicFormField({ field, control, adapter, contractSchema }) {
894
898
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DynamicFormField, {
895
899
  field: enhancedPayloadField,
896
900
  control,
897
- adapter,
901
+ addressing,
902
+ typeMapping,
898
903
  contractSchema
899
904
  }, `${field.id}-payload-${payloadIndex}`);
900
905
  }, [
901
906
  field.id,
902
907
  control,
903
- adapter,
904
- contractSchema
908
+ contractSchema,
909
+ addressing,
910
+ requireTypeMapping,
911
+ typeMapping
905
912
  ]);
906
913
  const renderKeyField = (0, react.useCallback)((keyField, entryIndex) => {
907
- const mappedKeyType = keyField.originalParameterType ? adapter.mapParameterTypeToFieldType(keyField.originalParameterType) : keyField.type;
914
+ const mappedKeyType = keyField.originalParameterType ? requireTypeMapping(keyField.name, keyField.type).mapParameterTypeToFieldType(keyField.originalParameterType) : keyField.type;
908
915
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DynamicFormField, {
909
916
  field: {
910
917
  ...keyField,
@@ -912,18 +919,21 @@ function DynamicFormField({ field, control, adapter, contractSchema }) {
912
919
  readOnly: keyField.readOnly ?? field.readOnly
913
920
  },
914
921
  control,
915
- adapter,
922
+ addressing,
923
+ typeMapping,
916
924
  contractSchema
917
925
  }, `${field.id}-key-${entryIndex}`);
918
926
  }, [
919
927
  field.id,
920
928
  field.readOnly,
921
929
  control,
922
- adapter,
923
- contractSchema
930
+ contractSchema,
931
+ addressing,
932
+ requireTypeMapping,
933
+ typeMapping
924
934
  ]);
925
935
  const renderValueField = (0, react.useCallback)((valueField, entryIndex) => {
926
- const mappedValueType = valueField.originalParameterType ? adapter.mapParameterTypeToFieldType(valueField.originalParameterType) : valueField.type;
936
+ const mappedValueType = valueField.originalParameterType ? requireTypeMapping(valueField.name, valueField.type).mapParameterTypeToFieldType(valueField.originalParameterType) : valueField.type;
927
937
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DynamicFormField, {
928
938
  field: {
929
939
  ...valueField,
@@ -931,15 +941,18 @@ function DynamicFormField({ field, control, adapter, contractSchema }) {
931
941
  readOnly: valueField.readOnly ?? field.readOnly
932
942
  },
933
943
  control,
934
- adapter,
944
+ addressing,
945
+ typeMapping,
935
946
  contractSchema
936
947
  }, `${field.id}-value-${entryIndex}`);
937
948
  }, [
938
949
  field.id,
939
950
  field.readOnly,
940
951
  control,
941
- adapter,
942
- contractSchema
952
+ contractSchema,
953
+ addressing,
954
+ requireTypeMapping,
955
+ typeMapping
943
956
  ]);
944
957
  if (!useShouldRenderField(field, control)) return null;
945
958
  const FieldComponent = fieldComponents[field.type];
@@ -959,7 +972,8 @@ function DynamicFormField({ field, control, adapter, contractSchema }) {
959
972
  readOnly: elementField.readOnly ?? field.readOnly
960
973
  },
961
974
  control,
962
- adapter,
975
+ addressing,
976
+ typeMapping,
963
977
  contractSchema
964
978
  }, `${field.id}-element-${index}`) },
965
979
  ...field.type === "object" && { renderProperty: (propertyField, propertyName) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DynamicFormField, {
@@ -968,7 +982,8 @@ function DynamicFormField({ field, control, adapter, contractSchema }) {
968
982
  readOnly: propertyField.readOnly ?? field.readOnly
969
983
  },
970
984
  control,
971
- adapter,
985
+ addressing,
986
+ typeMapping,
972
987
  contractSchema
973
988
  }, `${field.id}-property-${propertyName}`) },
974
989
  ...field.type === "array-object" && { renderProperty: (propertyField, itemIndex, propertyName) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DynamicFormField, {
@@ -977,7 +992,8 @@ function DynamicFormField({ field, control, adapter, contractSchema }) {
977
992
  readOnly: propertyField.readOnly ?? field.readOnly
978
993
  },
979
994
  control,
980
- adapter,
995
+ addressing,
996
+ typeMapping,
981
997
  contractSchema
982
998
  }, `${field.id}-item-${itemIndex}-property-${propertyName}`) }
983
999
  };
@@ -990,7 +1006,8 @@ function DynamicFormField({ field, control, adapter, contractSchema }) {
990
1006
  validation: field.validation,
991
1007
  control,
992
1008
  name: field.name,
993
- adapter,
1009
+ addressing,
1010
+ typeMapping,
994
1011
  readOnly: field.readOnly,
995
1012
  contractSchema,
996
1013
  ...enhancedProps
@@ -1123,7 +1140,7 @@ function formatErrorWithHash(errorMsg) {
1123
1140
  });
1124
1141
  }
1125
1142
  /** Displays the current status of a transaction with appropriate icons and messages. */
1126
- function TransactionStatusDisplay({ status, txHash, error, explorerUrl, className, customTitle, customMessage, result, functionDetails, adapter }) {
1143
+ function TransactionStatusDisplay({ status, txHash, error, explorerUrl, className, customTitle, customMessage, result, functionDetails, query, explorer }) {
1127
1144
  if (status === "idle") return null;
1128
1145
  let variant = "default";
1129
1146
  let defaultTitle = "";
@@ -1156,12 +1173,14 @@ function TransactionStatusDisplay({ status, txHash, error, explorerUrl, classNam
1156
1173
  }
1157
1174
  const title = customTitle || defaultTitle;
1158
1175
  let formattedResult = null;
1159
- if (result !== void 0 && result !== null && adapter && functionDetails) try {
1160
- formattedResult = adapter.formatFunctionResult(result, functionDetails);
1176
+ if (result !== void 0 && result !== null && query && functionDetails) try {
1177
+ const nextFormattedResult = query.formatFunctionResult(result, functionDetails);
1178
+ formattedResult = typeof nextFormattedResult === "string" ? nextFormattedResult : JSON.stringify(nextFormattedResult, null, 2);
1161
1179
  } catch {
1162
1180
  formattedResult = JSON.stringify(result, null, 2);
1163
1181
  }
1164
1182
  else if (result !== void 0 && result !== null) formattedResult = JSON.stringify(result, null, 2);
1183
+ const resolvedExplorerUrl = explorerUrl ?? (txHash ? explorer?.getExplorerTxUrl?.(txHash) ?? explorer?.getExplorerUrl(txHash) ?? null : null);
1165
1184
  let content = null;
1166
1185
  if (status === "error") content = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [error ? formatErrorWithHash(error) : customMessage ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1167
1186
  className: "break-word",
@@ -1171,7 +1190,7 @@ function TransactionStatusDisplay({ status, txHash, error, explorerUrl, classNam
1171
1190
  children: "An unknown error occurred."
1172
1191
  }), txHash && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TransactionHashDisplay, {
1173
1192
  txHash,
1174
- explorerUrl: explorerUrl || null
1193
+ explorerUrl: resolvedExplorerUrl
1175
1194
  })] });
1176
1195
  else {
1177
1196
  const messageText = customMessage || defaultMessage || "";
@@ -1181,7 +1200,7 @@ function TransactionStatusDisplay({ status, txHash, error, explorerUrl, classNam
1181
1200
  messageText && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: messageText }),
1182
1201
  txHash && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TransactionHashDisplay, {
1183
1202
  txHash,
1184
- explorerUrl: explorerUrl || null
1203
+ explorerUrl: resolvedExplorerUrl
1185
1204
  }),
1186
1205
  formattedResult && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1187
1206
  className: "mt-3 pt-3 border-t border-border",
@@ -1386,7 +1405,8 @@ function TransactionForm({ schema, contractSchema, adapter, isWalletConnected =
1386
1405
  field,
1387
1406
  control: methods.control,
1388
1407
  error: errors[field.name]?.message,
1389
- adapter,
1408
+ addressing: adapter,
1409
+ typeMapping: adapter,
1390
1410
  contractSchema
1391
1411
  }, field.id))
1392
1412
  });
@@ -1445,7 +1465,8 @@ function TransactionForm({ schema, contractSchema, adapter, isWalletConnected =
1445
1465
  customMessage: txStatusDetails?.message,
1446
1466
  result: txResult,
1447
1467
  functionDetails: currentFunction,
1448
- adapter
1468
+ query: adapter,
1469
+ explorer: adapter
1449
1470
  })
1450
1471
  }),
1451
1472
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
@@ -1465,7 +1486,8 @@ function TransactionForm({ schema, contractSchema, adapter, isWalletConnected =
1465
1486
  className: "w-full",
1466
1487
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExecutionConfigDisplay, {
1467
1488
  executionConfig,
1468
- adapter,
1489
+ execution: adapter,
1490
+ relayer: adapter,
1469
1491
  error: executionConfigError,
1470
1492
  onRuntimeApiKeyChange: setRuntimeApiKey
1471
1493
  })
@@ -1495,22 +1517,22 @@ function TransactionForm({ schema, contractSchema, adapter, isWalletConnected =
1495
1517
  //#endregion
1496
1518
  //#region src/components/AddressBookWidget/AddAliasDialog.tsx
1497
1519
  /** Dialog for creating a new address alias entry. */
1498
- function AddAliasDialog({ open, onOpenChange, onSave, currentNetworkId, adapter: defaultAdapter, resolveAdapter, addressPlaceholder: defaultPlaceholder, resolveAddressPlaceholder, resolveNetwork, networks }) {
1520
+ function AddAliasDialog({ open, onOpenChange, onSave, currentNetworkId, addressing: defaultAddressing, resolveAddressing, addressPlaceholder: defaultPlaceholder, resolveAddressPlaceholder, resolveNetwork, networks }) {
1499
1521
  const [saving, setSaving] = (0, react.useState)(false);
1500
1522
  const initialNetwork = (0, react.useMemo)(() => currentNetworkId && resolveNetwork ? resolveNetwork(currentNetworkId) : void 0, [currentNetworkId, resolveNetwork]);
1501
1523
  const [selectedNetwork, setSelectedNetwork] = (0, react.useState)(initialNetwork ?? null);
1502
- const [activeAdapter, setActiveAdapter] = (0, react.useState)(defaultAdapter);
1524
+ const [activeAddressing, setActiveAddressing] = (0, react.useState)(defaultAddressing);
1503
1525
  const [activePlaceholder, setActivePlaceholder] = (0, react.useState)(defaultPlaceholder);
1504
1526
  (0, react.useEffect)(() => {
1505
1527
  if (open) {
1506
1528
  setSelectedNetwork(initialNetwork ?? null);
1507
- setActiveAdapter(defaultAdapter);
1529
+ setActiveAddressing(defaultAddressing);
1508
1530
  setActivePlaceholder(defaultPlaceholder);
1509
1531
  }
1510
1532
  }, [
1511
1533
  open,
1512
1534
  initialNetwork,
1513
- defaultAdapter,
1535
+ defaultAddressing,
1514
1536
  defaultPlaceholder
1515
1537
  ]);
1516
1538
  const { control, handleSubmit, reset, trigger, formState } = (0, react_hook_form.useForm)({
@@ -1523,12 +1545,12 @@ function AddAliasDialog({ open, onOpenChange, onSave, currentNetworkId, adapter:
1523
1545
  const handleNetworkChange = (0, react.useCallback)(async (network) => {
1524
1546
  setSelectedNetwork(network);
1525
1547
  if (resolveAddressPlaceholder) setActivePlaceholder(resolveAddressPlaceholder(network));
1526
- if (resolveAdapter) {
1527
- setActiveAdapter(await resolveAdapter(network));
1548
+ if (resolveAddressing) {
1549
+ setActiveAddressing(await resolveAddressing(network));
1528
1550
  trigger("address");
1529
1551
  }
1530
1552
  }, [
1531
- resolveAdapter,
1553
+ resolveAddressing,
1532
1554
  resolveAddressPlaceholder,
1533
1555
  trigger
1534
1556
  ]);
@@ -1557,12 +1579,12 @@ function AddAliasDialog({ open, onOpenChange, onSave, currentNetworkId, adapter:
1557
1579
  if (!nextOpen) {
1558
1580
  reset();
1559
1581
  setSelectedNetwork(initialNetwork ?? null);
1560
- setActiveAdapter(defaultAdapter);
1582
+ setActiveAddressing(defaultAddressing);
1561
1583
  setActivePlaceholder(defaultPlaceholder);
1562
1584
  }
1563
1585
  onOpenChange(nextOpen);
1564
1586
  }, [
1565
- defaultAdapter,
1587
+ defaultAddressing,
1566
1588
  defaultPlaceholder,
1567
1589
  initialNetwork,
1568
1590
  onOpenChange,
@@ -1606,7 +1628,7 @@ function AddAliasDialog({ open, onOpenChange, onSave, currentNetworkId, adapter:
1606
1628
  placeholder: activePlaceholder,
1607
1629
  control,
1608
1630
  validation: { required: true },
1609
- adapter: activeAdapter
1631
+ addressing: activeAddressing
1610
1632
  }),
1611
1633
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_openzeppelin_ui_components.TextField, {
1612
1634
  id: "new-alias-name",
@@ -1811,7 +1833,7 @@ function ImportExportBar({ onExport, onImport, exportDisabled }) {
1811
1833
  //#endregion
1812
1834
  //#region src/components/AddressBookWidget/AddressBookWidget.tsx
1813
1835
  /** Widget for managing a personal address book with aliases, search, and network filtering. */
1814
- function AddressBookWidget({ aliases, isLoading, onSave, onRemove, onClear, onExport, onImport, currentNetworkId, resolveNetwork, resolveExplorerUrl, adapter, resolveAdapter, addressPlaceholder, resolveAddressPlaceholder, networks, filterNetworkIds, onFilterNetworkIdsChange, title = "Address Book", className }) {
1836
+ function AddressBookWidget({ aliases, isLoading, onSave, onRemove, onClear, onExport, onImport, currentNetworkId, resolveNetwork, resolveExplorerUrl, addressing, resolveAddressing, addressPlaceholder, resolveAddressPlaceholder, networks, filterNetworkIds, onFilterNetworkIdsChange, title = "Address Book", className }) {
1815
1837
  const [search, setSearch] = (0, react.useState)("");
1816
1838
  const [addDialogOpen, setAddDialogOpen] = (0, react.useState)(false);
1817
1839
  const [confirmClear, setConfirmClear] = (0, react.useState)(false);
@@ -1884,8 +1906,8 @@ function AddressBookWidget({ aliases, isLoading, onSave, onRemove, onClear, onEx
1884
1906
  onOpenChange: setAddDialogOpen,
1885
1907
  onSave,
1886
1908
  currentNetworkId,
1887
- adapter,
1888
- resolveAdapter,
1909
+ addressing,
1910
+ resolveAddressing,
1889
1911
  addressPlaceholder,
1890
1912
  resolveAddressPlaceholder,
1891
1913
  resolveNetwork,
@@ -2253,8 +2275,8 @@ function FunctionResult({ functionDetails, result, loading }) {
2253
2275
  /**
2254
2276
  * Panel for displaying and querying simple view functions (functions without parameters)
2255
2277
  */
2256
- function ViewFunctionsPanel({ functions, contractAddress, adapter, contractSchema, className }) {
2257
- const safeFunctions = adapter.filterAutoQueryableFunctions ? adapter.filterAutoQueryableFunctions(functions) : functions;
2278
+ function ViewFunctionsPanel({ functions, contractAddress, query, schema, contractSchema, className }) {
2279
+ const safeFunctions = schema.filterAutoQueryableFunctions ? schema.filterAutoQueryableFunctions(functions) : functions;
2258
2280
  const [results, setResults] = (0, react.useState)({});
2259
2281
  const [loadingStates, setLoadingStates] = (0, react.useState)({});
2260
2282
  const [hasQueried, setHasQueried] = (0, react.useState)(false);
@@ -2274,10 +2296,11 @@ function ViewFunctionsPanel({ functions, contractAddress, adapter, contractSchem
2274
2296
  try {
2275
2297
  await (0, _openzeppelin_ui_utils.rateLimitedBatch)(safeFunctions.map((func) => async () => {
2276
2298
  try {
2277
- const result = await adapter.queryViewFunction(contractAddress, func.id, [], contractSchema);
2299
+ const result = await query.queryViewFunction(contractAddress, func.id, [], contractSchema);
2278
2300
  let formattedResult;
2279
2301
  try {
2280
- formattedResult = adapter.formatFunctionResult(result, func);
2302
+ const nextResult = query.formatFunctionResult(result, func);
2303
+ formattedResult = typeof nextResult === "string" ? nextResult : JSON.stringify(nextResult, null, 2);
2281
2304
  } catch (formatError) {
2282
2305
  _openzeppelin_ui_utils.logger.error("ViewFunctionsPanel", `Error formatting result for ${func.name}:`, formatError);
2283
2306
  formattedResult = `Error formatting result: ${formatError instanceof Error ? formatError.message : "Unknown error"}`;
@@ -2319,11 +2342,11 @@ function ViewFunctionsPanel({ functions, contractAddress, adapter, contractSchem
2319
2342
  setIsQueryInProgress(false);
2320
2343
  }
2321
2344
  }, [
2322
- safeFunctions,
2323
2345
  contractAddress,
2324
- adapter,
2325
2346
  contractSchema,
2326
- isQueryInProgress
2347
+ isQueryInProgress,
2348
+ query,
2349
+ safeFunctions
2327
2350
  ]);
2328
2351
  (0, react.useEffect)(() => {
2329
2352
  let mounted = true;
@@ -2345,13 +2368,13 @@ function ViewFunctionsPanel({ functions, contractAddress, adapter, contractSchem
2345
2368
  handleQueryAll
2346
2369
  ]);
2347
2370
  (0, react.useEffect)(() => {
2348
- const networkId = adapter.networkConfig?.id;
2371
+ const networkId = query.networkConfig?.id;
2349
2372
  if (!networkId) return;
2350
2373
  return _openzeppelin_ui_utils.userRpcConfigService.subscribe(networkId, (event) => {
2351
2374
  _openzeppelin_ui_utils.logger.info("ViewFunctionsPanel", "RPC configuration changed:", event);
2352
2375
  handleQueryAll();
2353
2376
  });
2354
- }, [adapter.networkConfig?.id, handleQueryAll]);
2377
+ }, [handleQueryAll, query.networkConfig?.id]);
2355
2378
  if (safeFunctions.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2356
2379
  className: "text-xs text-muted-foreground",
2357
2380
  children: "No simple view functions found in this contract."
@@ -2398,19 +2421,19 @@ function ViewFunctionsPanel({ functions, contractAddress, adapter, contractSchem
2398
2421
  * ContractStateWidget - Compact widget for displaying contract state
2399
2422
  * Shows contract state by allowing users to query simple view functions (no parameters)
2400
2423
  */
2401
- function ContractStateWidget({ contractSchema, contractAddress, adapter, isVisible = true, onToggle, className, error }) {
2424
+ function ContractStateWidget({ contractSchema, contractAddress, query, schema, isVisible = true, onToggle, className, error }) {
2402
2425
  const [viewFunctions, setViewFunctions] = (0, react.useState)([]);
2403
2426
  const [animationState, setAnimationState] = (0, react.useState)(isVisible ? "entered" : "exited");
2404
- const networkConfig = adapter?.networkConfig;
2427
+ const networkConfig = query?.networkConfig;
2405
2428
  const [lastSchema, setLastSchema] = (0, react.useState)(contractSchema ?? null);
2406
2429
  (0, react.useEffect)(() => {
2407
2430
  if (contractSchema) setLastSchema(contractSchema);
2408
2431
  }, [contractSchema]);
2409
2432
  const effectiveSchema = (0, react.useMemo)(() => contractSchema ?? lastSchema, [contractSchema, lastSchema]);
2410
2433
  (0, react.useEffect)(() => {
2411
- if (!effectiveSchema || !adapter) return;
2412
- setViewFunctions(effectiveSchema.functions.filter((fn) => adapter.isViewFunction(fn)).filter((fn) => fn.inputs.length === 0));
2413
- }, [effectiveSchema, adapter]);
2434
+ if (!effectiveSchema) return;
2435
+ setViewFunctions(effectiveSchema.functions.filter((fn) => schema.isViewFunction(fn)).filter((fn) => fn.inputs.length === 0));
2436
+ }, [effectiveSchema, schema]);
2414
2437
  (0, react.useEffect)(() => {
2415
2438
  if (isVisible) {
2416
2439
  setAnimationState("entering");
@@ -2429,7 +2452,7 @@ function ContractStateWidget({ contractSchema, contractAddress, adapter, isVisib
2429
2452
  const handleToggle = () => {
2430
2453
  if (onToggle) onToggle();
2431
2454
  };
2432
- if (!contractAddress || !adapter || !networkConfig) return null;
2455
+ if (!contractAddress || !networkConfig) return null;
2433
2456
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(animationState === "entering" || animationState === "entered" || animationState === "exiting") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2434
2457
  className: (0, _openzeppelin_ui_utils.cn)("fixed inset-0 z-[9998] md:hidden bg-background/60 backdrop-blur-sm transition-opacity duration-500 ease-in-out", animationState === "entering" || animationState === "entered" ? "opacity-100" : "opacity-0"),
2435
2458
  "aria-hidden": "true",
@@ -2464,7 +2487,7 @@ function ContractStateWidget({ contractSchema, contractAddress, adapter, isVisib
2464
2487
  className: "mt-1 text-xs text-center",
2465
2488
  children: error.message
2466
2489
  })]
2467
- }) : !effectiveSchema && !lastSchema || !adapter ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2490
+ }) : !effectiveSchema && !lastSchema ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2468
2491
  className: "flex flex-col items-center justify-center h-full space-y-3 py-6",
2469
2492
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Loader2, { className: "h-8 w-8 text-primary animate-spin opacity-70" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2470
2493
  className: "text-center space-y-1",
@@ -2479,7 +2502,8 @@ function ContractStateWidget({ contractSchema, contractAddress, adapter, isVisib
2479
2502
  }) : viewFunctions.length > 0 && effectiveSchema ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ViewFunctionsPanel, {
2480
2503
  functions: viewFunctions,
2481
2504
  contractAddress,
2482
- adapter,
2505
+ query,
2506
+ schema,
2483
2507
  contractSchema: effectiveSchema,
2484
2508
  className: "flex-grow flex flex-col min-h-0"
2485
2509
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -2530,7 +2554,7 @@ function ContractActionBar({ networkConfig, contractAddress = null, onToggleCont
2530
2554
  //#endregion
2531
2555
  //#region src/components/network/NetworkServiceSettingsPanel.tsx
2532
2556
  /** Panel for configuring network service settings like RPC endpoints. */
2533
- function NetworkServiceSettingsPanel({ adapter, networkId, service, onSettingsChanged }) {
2557
+ function NetworkServiceSettingsPanel({ relayer, networkId, service, onSettingsChanged }) {
2534
2558
  const [isTesting, setIsTesting] = (0, react.useState)(false);
2535
2559
  const [result, setResult] = (0, react.useState)(null);
2536
2560
  const { control, handleSubmit, setValue, getValues, watch, formState: { isDirty } } = (0, react_hook_form.useForm)({ defaultValues: {} });
@@ -2575,12 +2599,12 @@ function NetworkServiceSettingsPanel({ adapter, networkId, service, onSettingsCh
2575
2599
  getValues
2576
2600
  ]);
2577
2601
  const testConnection = (0, react.useCallback)(async () => {
2578
- if (!adapter.testNetworkServiceConnection) return;
2602
+ if (!relayer.testNetworkServiceConnection) return;
2579
2603
  setIsTesting(true);
2580
2604
  setResult(null);
2581
2605
  try {
2582
2606
  const data = getValues();
2583
- const r = await adapter.testNetworkServiceConnection(service.id, data);
2607
+ const r = await relayer.testNetworkServiceConnection(service.id, data);
2584
2608
  setResult({
2585
2609
  success: r.success,
2586
2610
  message: r.error || (r.success ? "Connection successful" : "Connection failed"),
@@ -2595,15 +2619,15 @@ function NetworkServiceSettingsPanel({ adapter, networkId, service, onSettingsCh
2595
2619
  setIsTesting(false);
2596
2620
  }
2597
2621
  }, [
2598
- adapter,
2622
+ relayer,
2599
2623
  service.id,
2600
2624
  getValues
2601
2625
  ]);
2602
2626
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
2603
2627
  onSubmit: handleSubmit((0, react.useCallback)(async (formData) => {
2604
2628
  const data = formData;
2605
- if (adapter.validateNetworkServiceConfig) {
2606
- if (!await adapter.validateNetworkServiceConfig(service.id, data)) {
2629
+ if (relayer.validateNetworkServiceConfig) {
2630
+ if (!await relayer.validateNetworkServiceConfig(service.id, data)) {
2607
2631
  setResult({
2608
2632
  success: false,
2609
2633
  message: "Invalid configuration"
@@ -2619,7 +2643,7 @@ function NetworkServiceSettingsPanel({ adapter, networkId, service, onSettingsCh
2619
2643
  message: "Settings saved successfully"
2620
2644
  });
2621
2645
  }, [
2622
- adapter,
2646
+ relayer,
2623
2647
  networkId,
2624
2648
  service.id,
2625
2649
  onSettingsChanged
@@ -2661,8 +2685,7 @@ function NetworkServiceSettingsPanel({ adapter, networkId, service, onSettingsCh
2661
2685
  className: "space-y-4",
2662
2686
  children: primaryFields.map((field) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DynamicFormField, {
2663
2687
  field,
2664
- control,
2665
- adapter
2688
+ control
2666
2689
  }, field.id))
2667
2690
  }),
2668
2691
  Object.keys(sectionGroups).length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_openzeppelin_ui_components.Accordion, {
@@ -2708,8 +2731,7 @@ function NetworkServiceSettingsPanel({ adapter, networkId, service, onSettingsCh
2708
2731
  className: indentUnder ? "ml-6" : "",
2709
2732
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DynamicFormField, {
2710
2733
  field: wrappedField,
2711
- control,
2712
- adapter
2734
+ control
2713
2735
  })
2714
2736
  }, field.id);
2715
2737
  })
@@ -2752,7 +2774,7 @@ function NetworkServiceSettingsPanel({ adapter, networkId, service, onSettingsCh
2752
2774
  const hideTest = fields.some((f) => {
2753
2775
  return f.metadata?.hideTestConnection === true;
2754
2776
  });
2755
- return Boolean(adapter.testNetworkServiceConnection) && !hideTest;
2777
+ return Boolean(relayer.testNetworkServiceConnection) && !hideTest;
2756
2778
  })() ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_openzeppelin_ui_components.Button, {
2757
2779
  type: "button",
2758
2780
  variant: "outline",
@@ -2773,14 +2795,14 @@ function NetworkServiceSettingsPanel({ adapter, networkId, service, onSettingsCh
2773
2795
 
2774
2796
  //#endregion
2775
2797
  //#region src/components/network/NetworkSettingsDialog.tsx
2776
- const NetworkSettingsDialog = ({ isOpen, onOpenChange, networkConfig, adapter }) => {
2777
- const services = (0, _openzeppelin_ui_utils.filterEnabledServiceForms)(adapter?.getNetworkServiceForms?.() ?? []);
2798
+ const NetworkSettingsDialog = ({ isOpen, onOpenChange, networkConfig, relayer, onSettingsChanged }) => {
2799
+ const services = (0, _openzeppelin_ui_utils.filterEnabledServiceForms)(relayer?.getNetworkServiceForms() ?? []);
2778
2800
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_openzeppelin_ui_components.Dialog, {
2779
2801
  open: isOpen,
2780
2802
  onOpenChange,
2781
2803
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_openzeppelin_ui_components.DialogContent, {
2782
2804
  className: "max-w-2xl sm:max-w-3xl",
2783
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_openzeppelin_ui_components.DialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_openzeppelin_ui_components.DialogTitle, { children: "Network Settings" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_openzeppelin_ui_components.DialogDescription, { children: ["Configure settings for ", networkConfig?.name] })] }), networkConfig && adapter && services.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_openzeppelin_ui_components.Tabs, {
2805
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_openzeppelin_ui_components.DialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_openzeppelin_ui_components.DialogTitle, { children: "Network Settings" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_openzeppelin_ui_components.DialogDescription, { children: ["Configure settings for ", networkConfig?.name] })] }), networkConfig && relayer && services.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_openzeppelin_ui_components.Tabs, {
2784
2806
  defaultValue: services[0]?.id,
2785
2807
  className: "w-full",
2786
2808
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_openzeppelin_ui_components.TabsList, {
@@ -2793,16 +2815,10 @@ const NetworkSettingsDialog = ({ isOpen, onOpenChange, networkConfig, adapter })
2793
2815
  value: svc.id,
2794
2816
  className: "px-2",
2795
2817
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NetworkServiceSettingsPanel, {
2796
- adapter,
2818
+ relayer,
2797
2819
  networkId: networkConfig.id,
2798
2820
  service: svc,
2799
- onSettingsChanged: () => {
2800
- const cfg = _openzeppelin_ui_utils.appConfigService.getTypedNestedConfig("walletui", "config");
2801
- adapter.configureUiKit?.(cfg ?? {
2802
- kitName: "custom",
2803
- kitConfig: {}
2804
- });
2805
- }
2821
+ onSettingsChanged
2806
2822
  })
2807
2823
  }, svc.id))]
2808
2824
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -2829,7 +2845,7 @@ const NetworkSettingsDialog = ({ isOpen, onOpenChange, networkConfig, adapter })
2829
2845
  * Used in exported apps to provide access to RPC and Explorer configuration.
2830
2846
  */
2831
2847
  const WalletConnectionWithSettings = () => {
2832
- const { isAdapterLoading, activeAdapter, activeNetworkConfig } = (0, _openzeppelin_ui_react.useWalletState)();
2848
+ const { isRuntimeLoading, activeRuntime, activeNetworkConfig, reconfigureActiveUiKit } = (0, _openzeppelin_ui_react.useWalletState)();
2833
2849
  const { setOpenNetworkSettingsHandler } = (0, _openzeppelin_ui_components.useNetworkErrors)();
2834
2850
  const [showNetworkSettings, setShowNetworkSettings] = (0, react.useState)(false);
2835
2851
  const openNetworkSettings = (0, react.useCallback)((networkId) => {
@@ -2838,10 +2854,10 @@ const WalletConnectionWithSettings = () => {
2838
2854
  (0, react.useEffect)(() => {
2839
2855
  setOpenNetworkSettingsHandler(openNetworkSettings);
2840
2856
  }, [openNetworkSettings, setOpenNetworkSettingsHandler]);
2841
- if (isAdapterLoading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "h-9 w-28 animate-pulse rounded bg-muted" });
2857
+ if (isRuntimeLoading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "h-9 w-28 animate-pulse rounded bg-muted" });
2842
2858
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2843
2859
  className: "flex items-center gap-2",
2844
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_openzeppelin_ui_react.WalletConnectionUI, {}), activeAdapter && activeNetworkConfig && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_openzeppelin_ui_components.Button, {
2860
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_openzeppelin_ui_react.WalletConnectionUI, {}), activeRuntime?.relayer && activeNetworkConfig && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_openzeppelin_ui_components.Button, {
2845
2861
  variant: "ghost",
2846
2862
  size: "icon",
2847
2863
  className: "h-9 w-9",
@@ -2853,7 +2869,13 @@ const WalletConnectionWithSettings = () => {
2853
2869
  isOpen: showNetworkSettings,
2854
2870
  onOpenChange: setShowNetworkSettings,
2855
2871
  networkConfig: activeNetworkConfig,
2856
- adapter: activeAdapter
2872
+ relayer: activeRuntime?.relayer ?? null,
2873
+ onSettingsChanged: () => {
2874
+ reconfigureActiveUiKit(_openzeppelin_ui_utils.appConfigService.getTypedNestedConfig("walletui", "config") ?? {
2875
+ kitName: "custom",
2876
+ kitConfig: {}
2877
+ });
2878
+ }
2857
2879
  })] });
2858
2880
  };
2859
2881