@openzeppelin/ui-renderer 1.1.1 → 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/README.md +69 -28
- package/dist/index.cjs +179 -104
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +45 -25
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +45 -25
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +177 -105
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
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 {
|
|
210
|
-
const labels =
|
|
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,
|
|
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 (!
|
|
250
|
+
if (!execution) {
|
|
251
251
|
setValidationResult({
|
|
252
252
|
isValid: false,
|
|
253
|
-
error: "No
|
|
253
|
+
error: "No execution capability available for validation"
|
|
254
254
|
});
|
|
255
255
|
return;
|
|
256
256
|
}
|
|
257
257
|
try {
|
|
258
|
-
const result = await
|
|
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,
|
|
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
|
-
|
|
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 &&
|
|
304
|
+
if (isOpen && executionConfig.method === "relayer" && runtimeApiKey && relayer?.getRelayer) {
|
|
305
305
|
const relayerConfig = executionConfig;
|
|
306
306
|
setRelayerDetailsLoading(true);
|
|
307
|
-
|
|
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
|
-
|
|
320
|
-
|
|
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
|
|
441
|
+
* @param addressing The addressing capability to use for validation
|
|
442
442
|
* @returns Transform functions for address fields
|
|
443
443
|
*/
|
|
444
|
-
function createAddressTransform(
|
|
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 (
|
|
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
|
|
556
|
+
* @param addressing Optional addressing capability for address validation
|
|
557
557
|
* @returns Transform functions for the field type
|
|
558
558
|
*/
|
|
559
|
-
function createTransformForFieldType(fieldType,
|
|
559
|
+
function createTransformForFieldType(fieldType, addressing) {
|
|
560
560
|
switch (fieldType) {
|
|
561
561
|
case "blockchain-address":
|
|
562
|
-
if (!
|
|
563
|
-
return createAddressTransform(
|
|
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();
|
|
@@ -761,6 +761,44 @@ function extractRuntimeSecrets(data, fields) {
|
|
|
761
761
|
};
|
|
762
762
|
}
|
|
763
763
|
|
|
764
|
+
//#endregion
|
|
765
|
+
//#region src/utils/transactionSuccessCallback.ts
|
|
766
|
+
/**
|
|
767
|
+
* Normalizes adapter `txHash` for the success callback (non-empty trimmed string or omitted).
|
|
768
|
+
* Expects the `txHash` string from `signAndBroadcast`, not arbitrary values (avoids coercing objects).
|
|
769
|
+
*/
|
|
770
|
+
function normalizeTransactionSuccessHash(finalTxHash) {
|
|
771
|
+
if (finalTxHash == null) return;
|
|
772
|
+
const trimmed = finalTxHash.trim();
|
|
773
|
+
return trimmed !== "" ? trimmed : void 0;
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* Builds the {@link TransactionSuccessPayload} passed to `onTransactionSuccess`.
|
|
777
|
+
*/
|
|
778
|
+
function buildTransactionSuccessPayload(options) {
|
|
779
|
+
const hash = normalizeTransactionSuccessHash(options.finalTxHash);
|
|
780
|
+
return {
|
|
781
|
+
network_id: options.networkId,
|
|
782
|
+
ecosystem: options.ecosystem,
|
|
783
|
+
execution_method: options.executionMethod,
|
|
784
|
+
...hash !== void 0 ? { transaction_hash: hash } : {}
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
/**
|
|
788
|
+
* Invokes `onTransactionSuccess` with error containment: synchronous throws and async
|
|
789
|
+
* rejections are logged and never rethrown, so host callbacks cannot break transaction flow.
|
|
790
|
+
*/
|
|
791
|
+
function invokeOnTransactionSuccess(callback, payload, log) {
|
|
792
|
+
try {
|
|
793
|
+
const maybePromise = callback?.(payload);
|
|
794
|
+
Promise.resolve(maybePromise).catch((error) => {
|
|
795
|
+
log.error("TransactionForm", "onTransactionSuccess callback rejected with an error", error);
|
|
796
|
+
});
|
|
797
|
+
} catch (error) {
|
|
798
|
+
log.error("TransactionForm", "onTransactionSuccess callback threw an error", error);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
|
|
764
802
|
//#endregion
|
|
765
803
|
//#region src/components/fieldRegistry.ts
|
|
766
804
|
/**
|
|
@@ -833,11 +871,15 @@ function useShouldRenderField(field, control) {
|
|
|
833
871
|
*
|
|
834
872
|
* @returns The rendered form field component or null if the field should not be visible
|
|
835
873
|
*/
|
|
836
|
-
function DynamicFormField({ field, control,
|
|
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]);
|
|
837
879
|
const renderPayloadField = (0, react.useCallback)((payloadField, payloadIndex) => {
|
|
838
880
|
let enhancedPayloadField;
|
|
839
881
|
if (payloadField.originalParameterType) {
|
|
840
|
-
const generatedField =
|
|
882
|
+
const generatedField = requireTypeMapping(payloadField.name, payloadField.type).generateDefaultField({
|
|
841
883
|
name: payloadField.name || `payload_${payloadIndex}`,
|
|
842
884
|
type: payloadField.originalParameterType
|
|
843
885
|
}, contractSchema);
|
|
@@ -856,17 +898,20 @@ function DynamicFormField({ field, control, adapter, contractSchema }) {
|
|
|
856
898
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DynamicFormField, {
|
|
857
899
|
field: enhancedPayloadField,
|
|
858
900
|
control,
|
|
859
|
-
|
|
901
|
+
addressing,
|
|
902
|
+
typeMapping,
|
|
860
903
|
contractSchema
|
|
861
904
|
}, `${field.id}-payload-${payloadIndex}`);
|
|
862
905
|
}, [
|
|
863
906
|
field.id,
|
|
864
907
|
control,
|
|
865
|
-
|
|
866
|
-
|
|
908
|
+
contractSchema,
|
|
909
|
+
addressing,
|
|
910
|
+
requireTypeMapping,
|
|
911
|
+
typeMapping
|
|
867
912
|
]);
|
|
868
913
|
const renderKeyField = (0, react.useCallback)((keyField, entryIndex) => {
|
|
869
|
-
const mappedKeyType = keyField.originalParameterType ?
|
|
914
|
+
const mappedKeyType = keyField.originalParameterType ? requireTypeMapping(keyField.name, keyField.type).mapParameterTypeToFieldType(keyField.originalParameterType) : keyField.type;
|
|
870
915
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DynamicFormField, {
|
|
871
916
|
field: {
|
|
872
917
|
...keyField,
|
|
@@ -874,18 +919,21 @@ function DynamicFormField({ field, control, adapter, contractSchema }) {
|
|
|
874
919
|
readOnly: keyField.readOnly ?? field.readOnly
|
|
875
920
|
},
|
|
876
921
|
control,
|
|
877
|
-
|
|
922
|
+
addressing,
|
|
923
|
+
typeMapping,
|
|
878
924
|
contractSchema
|
|
879
925
|
}, `${field.id}-key-${entryIndex}`);
|
|
880
926
|
}, [
|
|
881
927
|
field.id,
|
|
882
928
|
field.readOnly,
|
|
883
929
|
control,
|
|
884
|
-
|
|
885
|
-
|
|
930
|
+
contractSchema,
|
|
931
|
+
addressing,
|
|
932
|
+
requireTypeMapping,
|
|
933
|
+
typeMapping
|
|
886
934
|
]);
|
|
887
935
|
const renderValueField = (0, react.useCallback)((valueField, entryIndex) => {
|
|
888
|
-
const mappedValueType = valueField.originalParameterType ?
|
|
936
|
+
const mappedValueType = valueField.originalParameterType ? requireTypeMapping(valueField.name, valueField.type).mapParameterTypeToFieldType(valueField.originalParameterType) : valueField.type;
|
|
889
937
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DynamicFormField, {
|
|
890
938
|
field: {
|
|
891
939
|
...valueField,
|
|
@@ -893,15 +941,18 @@ function DynamicFormField({ field, control, adapter, contractSchema }) {
|
|
|
893
941
|
readOnly: valueField.readOnly ?? field.readOnly
|
|
894
942
|
},
|
|
895
943
|
control,
|
|
896
|
-
|
|
944
|
+
addressing,
|
|
945
|
+
typeMapping,
|
|
897
946
|
contractSchema
|
|
898
947
|
}, `${field.id}-value-${entryIndex}`);
|
|
899
948
|
}, [
|
|
900
949
|
field.id,
|
|
901
950
|
field.readOnly,
|
|
902
951
|
control,
|
|
903
|
-
|
|
904
|
-
|
|
952
|
+
contractSchema,
|
|
953
|
+
addressing,
|
|
954
|
+
requireTypeMapping,
|
|
955
|
+
typeMapping
|
|
905
956
|
]);
|
|
906
957
|
if (!useShouldRenderField(field, control)) return null;
|
|
907
958
|
const FieldComponent = fieldComponents[field.type];
|
|
@@ -921,7 +972,8 @@ function DynamicFormField({ field, control, adapter, contractSchema }) {
|
|
|
921
972
|
readOnly: elementField.readOnly ?? field.readOnly
|
|
922
973
|
},
|
|
923
974
|
control,
|
|
924
|
-
|
|
975
|
+
addressing,
|
|
976
|
+
typeMapping,
|
|
925
977
|
contractSchema
|
|
926
978
|
}, `${field.id}-element-${index}`) },
|
|
927
979
|
...field.type === "object" && { renderProperty: (propertyField, propertyName) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DynamicFormField, {
|
|
@@ -930,7 +982,8 @@ function DynamicFormField({ field, control, adapter, contractSchema }) {
|
|
|
930
982
|
readOnly: propertyField.readOnly ?? field.readOnly
|
|
931
983
|
},
|
|
932
984
|
control,
|
|
933
|
-
|
|
985
|
+
addressing,
|
|
986
|
+
typeMapping,
|
|
934
987
|
contractSchema
|
|
935
988
|
}, `${field.id}-property-${propertyName}`) },
|
|
936
989
|
...field.type === "array-object" && { renderProperty: (propertyField, itemIndex, propertyName) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DynamicFormField, {
|
|
@@ -939,7 +992,8 @@ function DynamicFormField({ field, control, adapter, contractSchema }) {
|
|
|
939
992
|
readOnly: propertyField.readOnly ?? field.readOnly
|
|
940
993
|
},
|
|
941
994
|
control,
|
|
942
|
-
|
|
995
|
+
addressing,
|
|
996
|
+
typeMapping,
|
|
943
997
|
contractSchema
|
|
944
998
|
}, `${field.id}-item-${itemIndex}-property-${propertyName}`) }
|
|
945
999
|
};
|
|
@@ -952,7 +1006,8 @@ function DynamicFormField({ field, control, adapter, contractSchema }) {
|
|
|
952
1006
|
validation: field.validation,
|
|
953
1007
|
control,
|
|
954
1008
|
name: field.name,
|
|
955
|
-
|
|
1009
|
+
addressing,
|
|
1010
|
+
typeMapping,
|
|
956
1011
|
readOnly: field.readOnly,
|
|
957
1012
|
contractSchema,
|
|
958
1013
|
...enhancedProps
|
|
@@ -1085,7 +1140,7 @@ function formatErrorWithHash(errorMsg) {
|
|
|
1085
1140
|
});
|
|
1086
1141
|
}
|
|
1087
1142
|
/** Displays the current status of a transaction with appropriate icons and messages. */
|
|
1088
|
-
function TransactionStatusDisplay({ status, txHash, error, explorerUrl, className, customTitle, customMessage, result, functionDetails,
|
|
1143
|
+
function TransactionStatusDisplay({ status, txHash, error, explorerUrl, className, customTitle, customMessage, result, functionDetails, query, explorer }) {
|
|
1089
1144
|
if (status === "idle") return null;
|
|
1090
1145
|
let variant = "default";
|
|
1091
1146
|
let defaultTitle = "";
|
|
@@ -1118,12 +1173,14 @@ function TransactionStatusDisplay({ status, txHash, error, explorerUrl, classNam
|
|
|
1118
1173
|
}
|
|
1119
1174
|
const title = customTitle || defaultTitle;
|
|
1120
1175
|
let formattedResult = null;
|
|
1121
|
-
if (result !== void 0 && result !== null &&
|
|
1122
|
-
|
|
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);
|
|
1123
1179
|
} catch {
|
|
1124
1180
|
formattedResult = JSON.stringify(result, null, 2);
|
|
1125
1181
|
}
|
|
1126
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);
|
|
1127
1184
|
let content = null;
|
|
1128
1185
|
if (status === "error") content = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [error ? formatErrorWithHash(error) : customMessage ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1129
1186
|
className: "break-word",
|
|
@@ -1133,7 +1190,7 @@ function TransactionStatusDisplay({ status, txHash, error, explorerUrl, classNam
|
|
|
1133
1190
|
children: "An unknown error occurred."
|
|
1134
1191
|
}), txHash && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TransactionHashDisplay, {
|
|
1135
1192
|
txHash,
|
|
1136
|
-
explorerUrl:
|
|
1193
|
+
explorerUrl: resolvedExplorerUrl
|
|
1137
1194
|
})] });
|
|
1138
1195
|
else {
|
|
1139
1196
|
const messageText = customMessage || defaultMessage || "";
|
|
@@ -1143,7 +1200,7 @@ function TransactionStatusDisplay({ status, txHash, error, explorerUrl, classNam
|
|
|
1143
1200
|
messageText && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: messageText }),
|
|
1144
1201
|
txHash && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TransactionHashDisplay, {
|
|
1145
1202
|
txHash,
|
|
1146
|
-
explorerUrl:
|
|
1203
|
+
explorerUrl: resolvedExplorerUrl
|
|
1147
1204
|
}),
|
|
1148
1205
|
formattedResult && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1149
1206
|
className: "mt-3 pt-3 border-t border-border",
|
|
@@ -1208,7 +1265,7 @@ const PENDING_STATES = [
|
|
|
1208
1265
|
*
|
|
1209
1266
|
* @returns The rendered form component
|
|
1210
1267
|
*/
|
|
1211
|
-
function TransactionForm({ schema, contractSchema, adapter, isWalletConnected = false, executionConfig }) {
|
|
1268
|
+
function TransactionForm({ schema, contractSchema, adapter, isWalletConnected = false, executionConfig, onTransactionSuccess }) {
|
|
1212
1269
|
const [formError, setFormError] = (0, react.useState)(null);
|
|
1213
1270
|
const [executionConfigError, setExecutionConfigError] = (0, react.useState)(null);
|
|
1214
1271
|
const [runtimeApiKey, setRuntimeApiKey] = (0, react.useState)("");
|
|
@@ -1295,9 +1352,19 @@ function TransactionForm({ schema, contractSchema, adapter, isWalletConnected =
|
|
|
1295
1352
|
setTxResult(result);
|
|
1296
1353
|
_openzeppelin_ui_utils.logger.info("TransactionForm", "Execution result received:", result);
|
|
1297
1354
|
}
|
|
1355
|
+
const reportTransactionSuccess = () => {
|
|
1356
|
+
const executionMethod = executionConfig?.method ?? "eoa";
|
|
1357
|
+
invokeOnTransactionSuccess(onTransactionSuccess, buildTransactionSuccessPayload({
|
|
1358
|
+
networkId: adapter.networkConfig.id,
|
|
1359
|
+
ecosystem: adapter.networkConfig.ecosystem,
|
|
1360
|
+
executionMethod,
|
|
1361
|
+
finalTxHash
|
|
1362
|
+
}), _openzeppelin_ui_utils.logger);
|
|
1363
|
+
};
|
|
1298
1364
|
if (canExecuteLocally) {
|
|
1299
1365
|
setTxStatus("success");
|
|
1300
1366
|
setTxError(null);
|
|
1367
|
+
reportTransactionSuccess();
|
|
1301
1368
|
return;
|
|
1302
1369
|
}
|
|
1303
1370
|
if (adapter.waitForTransactionConfirmation) {
|
|
@@ -1308,6 +1375,7 @@ function TransactionForm({ schema, contractSchema, adapter, isWalletConnected =
|
|
|
1308
1375
|
_openzeppelin_ui_utils.logger.info("TransactionForm", `Transaction confirmed: ${finalTxHash}`, confirmationResult.receipt);
|
|
1309
1376
|
setTxStatus("success");
|
|
1310
1377
|
setTxError(null);
|
|
1378
|
+
reportTransactionSuccess();
|
|
1311
1379
|
} else {
|
|
1312
1380
|
_openzeppelin_ui_utils.logger.error("TransactionForm", `Transaction failed confirmation: ${finalTxHash}`, confirmationResult.error);
|
|
1313
1381
|
setTxError(confirmationResult.error?.message ?? "Transaction failed during confirmation.");
|
|
@@ -1317,6 +1385,7 @@ function TransactionForm({ schema, contractSchema, adapter, isWalletConnected =
|
|
|
1317
1385
|
_openzeppelin_ui_utils.logger.warn("TransactionForm", "Adapter does not support waitForTransactionConfirmation. Marking as success after submission.");
|
|
1318
1386
|
setTxStatus("success");
|
|
1319
1387
|
setTxError(null);
|
|
1388
|
+
reportTransactionSuccess();
|
|
1320
1389
|
}
|
|
1321
1390
|
} catch (error) {
|
|
1322
1391
|
_openzeppelin_ui_utils.logger.error("TransactionForm", "Transaction error during submission process:", error);
|
|
@@ -1336,7 +1405,8 @@ function TransactionForm({ schema, contractSchema, adapter, isWalletConnected =
|
|
|
1336
1405
|
field,
|
|
1337
1406
|
control: methods.control,
|
|
1338
1407
|
error: errors[field.name]?.message,
|
|
1339
|
-
adapter,
|
|
1408
|
+
addressing: adapter,
|
|
1409
|
+
typeMapping: adapter,
|
|
1340
1410
|
contractSchema
|
|
1341
1411
|
}, field.id))
|
|
1342
1412
|
});
|
|
@@ -1395,7 +1465,8 @@ function TransactionForm({ schema, contractSchema, adapter, isWalletConnected =
|
|
|
1395
1465
|
customMessage: txStatusDetails?.message,
|
|
1396
1466
|
result: txResult,
|
|
1397
1467
|
functionDetails: currentFunction,
|
|
1398
|
-
adapter
|
|
1468
|
+
query: adapter,
|
|
1469
|
+
explorer: adapter
|
|
1399
1470
|
})
|
|
1400
1471
|
}),
|
|
1401
1472
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
|
|
@@ -1415,7 +1486,8 @@ function TransactionForm({ schema, contractSchema, adapter, isWalletConnected =
|
|
|
1415
1486
|
className: "w-full",
|
|
1416
1487
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExecutionConfigDisplay, {
|
|
1417
1488
|
executionConfig,
|
|
1418
|
-
adapter,
|
|
1489
|
+
execution: adapter,
|
|
1490
|
+
relayer: adapter,
|
|
1419
1491
|
error: executionConfigError,
|
|
1420
1492
|
onRuntimeApiKeyChange: setRuntimeApiKey
|
|
1421
1493
|
})
|
|
@@ -1445,22 +1517,22 @@ function TransactionForm({ schema, contractSchema, adapter, isWalletConnected =
|
|
|
1445
1517
|
//#endregion
|
|
1446
1518
|
//#region src/components/AddressBookWidget/AddAliasDialog.tsx
|
|
1447
1519
|
/** Dialog for creating a new address alias entry. */
|
|
1448
|
-
function AddAliasDialog({ open, onOpenChange, onSave, currentNetworkId,
|
|
1520
|
+
function AddAliasDialog({ open, onOpenChange, onSave, currentNetworkId, addressing: defaultAddressing, resolveAddressing, addressPlaceholder: defaultPlaceholder, resolveAddressPlaceholder, resolveNetwork, networks }) {
|
|
1449
1521
|
const [saving, setSaving] = (0, react.useState)(false);
|
|
1450
1522
|
const initialNetwork = (0, react.useMemo)(() => currentNetworkId && resolveNetwork ? resolveNetwork(currentNetworkId) : void 0, [currentNetworkId, resolveNetwork]);
|
|
1451
1523
|
const [selectedNetwork, setSelectedNetwork] = (0, react.useState)(initialNetwork ?? null);
|
|
1452
|
-
const [
|
|
1524
|
+
const [activeAddressing, setActiveAddressing] = (0, react.useState)(defaultAddressing);
|
|
1453
1525
|
const [activePlaceholder, setActivePlaceholder] = (0, react.useState)(defaultPlaceholder);
|
|
1454
1526
|
(0, react.useEffect)(() => {
|
|
1455
1527
|
if (open) {
|
|
1456
1528
|
setSelectedNetwork(initialNetwork ?? null);
|
|
1457
|
-
|
|
1529
|
+
setActiveAddressing(defaultAddressing);
|
|
1458
1530
|
setActivePlaceholder(defaultPlaceholder);
|
|
1459
1531
|
}
|
|
1460
1532
|
}, [
|
|
1461
1533
|
open,
|
|
1462
1534
|
initialNetwork,
|
|
1463
|
-
|
|
1535
|
+
defaultAddressing,
|
|
1464
1536
|
defaultPlaceholder
|
|
1465
1537
|
]);
|
|
1466
1538
|
const { control, handleSubmit, reset, trigger, formState } = (0, react_hook_form.useForm)({
|
|
@@ -1473,12 +1545,12 @@ function AddAliasDialog({ open, onOpenChange, onSave, currentNetworkId, adapter:
|
|
|
1473
1545
|
const handleNetworkChange = (0, react.useCallback)(async (network) => {
|
|
1474
1546
|
setSelectedNetwork(network);
|
|
1475
1547
|
if (resolveAddressPlaceholder) setActivePlaceholder(resolveAddressPlaceholder(network));
|
|
1476
|
-
if (
|
|
1477
|
-
|
|
1548
|
+
if (resolveAddressing) {
|
|
1549
|
+
setActiveAddressing(await resolveAddressing(network));
|
|
1478
1550
|
trigger("address");
|
|
1479
1551
|
}
|
|
1480
1552
|
}, [
|
|
1481
|
-
|
|
1553
|
+
resolveAddressing,
|
|
1482
1554
|
resolveAddressPlaceholder,
|
|
1483
1555
|
trigger
|
|
1484
1556
|
]);
|
|
@@ -1507,12 +1579,12 @@ function AddAliasDialog({ open, onOpenChange, onSave, currentNetworkId, adapter:
|
|
|
1507
1579
|
if (!nextOpen) {
|
|
1508
1580
|
reset();
|
|
1509
1581
|
setSelectedNetwork(initialNetwork ?? null);
|
|
1510
|
-
|
|
1582
|
+
setActiveAddressing(defaultAddressing);
|
|
1511
1583
|
setActivePlaceholder(defaultPlaceholder);
|
|
1512
1584
|
}
|
|
1513
1585
|
onOpenChange(nextOpen);
|
|
1514
1586
|
}, [
|
|
1515
|
-
|
|
1587
|
+
defaultAddressing,
|
|
1516
1588
|
defaultPlaceholder,
|
|
1517
1589
|
initialNetwork,
|
|
1518
1590
|
onOpenChange,
|
|
@@ -1556,7 +1628,7 @@ function AddAliasDialog({ open, onOpenChange, onSave, currentNetworkId, adapter:
|
|
|
1556
1628
|
placeholder: activePlaceholder,
|
|
1557
1629
|
control,
|
|
1558
1630
|
validation: { required: true },
|
|
1559
|
-
|
|
1631
|
+
addressing: activeAddressing
|
|
1560
1632
|
}),
|
|
1561
1633
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_openzeppelin_ui_components.TextField, {
|
|
1562
1634
|
id: "new-alias-name",
|
|
@@ -1761,7 +1833,7 @@ function ImportExportBar({ onExport, onImport, exportDisabled }) {
|
|
|
1761
1833
|
//#endregion
|
|
1762
1834
|
//#region src/components/AddressBookWidget/AddressBookWidget.tsx
|
|
1763
1835
|
/** Widget for managing a personal address book with aliases, search, and network filtering. */
|
|
1764
|
-
function AddressBookWidget({ aliases, isLoading, onSave, onRemove, onClear, onExport, onImport, currentNetworkId, resolveNetwork, resolveExplorerUrl,
|
|
1836
|
+
function AddressBookWidget({ aliases, isLoading, onSave, onRemove, onClear, onExport, onImport, currentNetworkId, resolveNetwork, resolveExplorerUrl, addressing, resolveAddressing, addressPlaceholder, resolveAddressPlaceholder, networks, filterNetworkIds, onFilterNetworkIdsChange, title = "Address Book", className }) {
|
|
1765
1837
|
const [search, setSearch] = (0, react.useState)("");
|
|
1766
1838
|
const [addDialogOpen, setAddDialogOpen] = (0, react.useState)(false);
|
|
1767
1839
|
const [confirmClear, setConfirmClear] = (0, react.useState)(false);
|
|
@@ -1834,8 +1906,8 @@ function AddressBookWidget({ aliases, isLoading, onSave, onRemove, onClear, onEx
|
|
|
1834
1906
|
onOpenChange: setAddDialogOpen,
|
|
1835
1907
|
onSave,
|
|
1836
1908
|
currentNetworkId,
|
|
1837
|
-
|
|
1838
|
-
|
|
1909
|
+
addressing,
|
|
1910
|
+
resolveAddressing,
|
|
1839
1911
|
addressPlaceholder,
|
|
1840
1912
|
resolveAddressPlaceholder,
|
|
1841
1913
|
resolveNetwork,
|
|
@@ -2203,8 +2275,8 @@ function FunctionResult({ functionDetails, result, loading }) {
|
|
|
2203
2275
|
/**
|
|
2204
2276
|
* Panel for displaying and querying simple view functions (functions without parameters)
|
|
2205
2277
|
*/
|
|
2206
|
-
function ViewFunctionsPanel({ functions, contractAddress,
|
|
2207
|
-
const safeFunctions =
|
|
2278
|
+
function ViewFunctionsPanel({ functions, contractAddress, query, schema, contractSchema, className }) {
|
|
2279
|
+
const safeFunctions = schema.filterAutoQueryableFunctions ? schema.filterAutoQueryableFunctions(functions) : functions;
|
|
2208
2280
|
const [results, setResults] = (0, react.useState)({});
|
|
2209
2281
|
const [loadingStates, setLoadingStates] = (0, react.useState)({});
|
|
2210
2282
|
const [hasQueried, setHasQueried] = (0, react.useState)(false);
|
|
@@ -2224,10 +2296,11 @@ function ViewFunctionsPanel({ functions, contractAddress, adapter, contractSchem
|
|
|
2224
2296
|
try {
|
|
2225
2297
|
await (0, _openzeppelin_ui_utils.rateLimitedBatch)(safeFunctions.map((func) => async () => {
|
|
2226
2298
|
try {
|
|
2227
|
-
const result = await
|
|
2299
|
+
const result = await query.queryViewFunction(contractAddress, func.id, [], contractSchema);
|
|
2228
2300
|
let formattedResult;
|
|
2229
2301
|
try {
|
|
2230
|
-
|
|
2302
|
+
const nextResult = query.formatFunctionResult(result, func);
|
|
2303
|
+
formattedResult = typeof nextResult === "string" ? nextResult : JSON.stringify(nextResult, null, 2);
|
|
2231
2304
|
} catch (formatError) {
|
|
2232
2305
|
_openzeppelin_ui_utils.logger.error("ViewFunctionsPanel", `Error formatting result for ${func.name}:`, formatError);
|
|
2233
2306
|
formattedResult = `Error formatting result: ${formatError instanceof Error ? formatError.message : "Unknown error"}`;
|
|
@@ -2269,11 +2342,11 @@ function ViewFunctionsPanel({ functions, contractAddress, adapter, contractSchem
|
|
|
2269
2342
|
setIsQueryInProgress(false);
|
|
2270
2343
|
}
|
|
2271
2344
|
}, [
|
|
2272
|
-
safeFunctions,
|
|
2273
2345
|
contractAddress,
|
|
2274
|
-
adapter,
|
|
2275
2346
|
contractSchema,
|
|
2276
|
-
isQueryInProgress
|
|
2347
|
+
isQueryInProgress,
|
|
2348
|
+
query,
|
|
2349
|
+
safeFunctions
|
|
2277
2350
|
]);
|
|
2278
2351
|
(0, react.useEffect)(() => {
|
|
2279
2352
|
let mounted = true;
|
|
@@ -2295,13 +2368,13 @@ function ViewFunctionsPanel({ functions, contractAddress, adapter, contractSchem
|
|
|
2295
2368
|
handleQueryAll
|
|
2296
2369
|
]);
|
|
2297
2370
|
(0, react.useEffect)(() => {
|
|
2298
|
-
const networkId =
|
|
2371
|
+
const networkId = query.networkConfig?.id;
|
|
2299
2372
|
if (!networkId) return;
|
|
2300
2373
|
return _openzeppelin_ui_utils.userRpcConfigService.subscribe(networkId, (event) => {
|
|
2301
2374
|
_openzeppelin_ui_utils.logger.info("ViewFunctionsPanel", "RPC configuration changed:", event);
|
|
2302
2375
|
handleQueryAll();
|
|
2303
2376
|
});
|
|
2304
|
-
}, [
|
|
2377
|
+
}, [handleQueryAll, query.networkConfig?.id]);
|
|
2305
2378
|
if (safeFunctions.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2306
2379
|
className: "text-xs text-muted-foreground",
|
|
2307
2380
|
children: "No simple view functions found in this contract."
|
|
@@ -2348,19 +2421,19 @@ function ViewFunctionsPanel({ functions, contractAddress, adapter, contractSchem
|
|
|
2348
2421
|
* ContractStateWidget - Compact widget for displaying contract state
|
|
2349
2422
|
* Shows contract state by allowing users to query simple view functions (no parameters)
|
|
2350
2423
|
*/
|
|
2351
|
-
function ContractStateWidget({ contractSchema, contractAddress,
|
|
2424
|
+
function ContractStateWidget({ contractSchema, contractAddress, query, schema, isVisible = true, onToggle, className, error }) {
|
|
2352
2425
|
const [viewFunctions, setViewFunctions] = (0, react.useState)([]);
|
|
2353
2426
|
const [animationState, setAnimationState] = (0, react.useState)(isVisible ? "entered" : "exited");
|
|
2354
|
-
const networkConfig =
|
|
2427
|
+
const networkConfig = query?.networkConfig;
|
|
2355
2428
|
const [lastSchema, setLastSchema] = (0, react.useState)(contractSchema ?? null);
|
|
2356
2429
|
(0, react.useEffect)(() => {
|
|
2357
2430
|
if (contractSchema) setLastSchema(contractSchema);
|
|
2358
2431
|
}, [contractSchema]);
|
|
2359
2432
|
const effectiveSchema = (0, react.useMemo)(() => contractSchema ?? lastSchema, [contractSchema, lastSchema]);
|
|
2360
2433
|
(0, react.useEffect)(() => {
|
|
2361
|
-
if (!effectiveSchema
|
|
2362
|
-
setViewFunctions(effectiveSchema.functions.filter((fn) =>
|
|
2363
|
-
}, [effectiveSchema,
|
|
2434
|
+
if (!effectiveSchema) return;
|
|
2435
|
+
setViewFunctions(effectiveSchema.functions.filter((fn) => schema.isViewFunction(fn)).filter((fn) => fn.inputs.length === 0));
|
|
2436
|
+
}, [effectiveSchema, schema]);
|
|
2364
2437
|
(0, react.useEffect)(() => {
|
|
2365
2438
|
if (isVisible) {
|
|
2366
2439
|
setAnimationState("entering");
|
|
@@ -2379,7 +2452,7 @@ function ContractStateWidget({ contractSchema, contractAddress, adapter, isVisib
|
|
|
2379
2452
|
const handleToggle = () => {
|
|
2380
2453
|
if (onToggle) onToggle();
|
|
2381
2454
|
};
|
|
2382
|
-
if (!contractAddress || !
|
|
2455
|
+
if (!contractAddress || !networkConfig) return null;
|
|
2383
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", {
|
|
2384
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"),
|
|
2385
2458
|
"aria-hidden": "true",
|
|
@@ -2414,7 +2487,7 @@ function ContractStateWidget({ contractSchema, contractAddress, adapter, isVisib
|
|
|
2414
2487
|
className: "mt-1 text-xs text-center",
|
|
2415
2488
|
children: error.message
|
|
2416
2489
|
})]
|
|
2417
|
-
}) : !effectiveSchema && !lastSchema
|
|
2490
|
+
}) : !effectiveSchema && !lastSchema ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2418
2491
|
className: "flex flex-col items-center justify-center h-full space-y-3 py-6",
|
|
2419
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", {
|
|
2420
2493
|
className: "text-center space-y-1",
|
|
@@ -2429,7 +2502,8 @@ function ContractStateWidget({ contractSchema, contractAddress, adapter, isVisib
|
|
|
2429
2502
|
}) : viewFunctions.length > 0 && effectiveSchema ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ViewFunctionsPanel, {
|
|
2430
2503
|
functions: viewFunctions,
|
|
2431
2504
|
contractAddress,
|
|
2432
|
-
|
|
2505
|
+
query,
|
|
2506
|
+
schema,
|
|
2433
2507
|
contractSchema: effectiveSchema,
|
|
2434
2508
|
className: "flex-grow flex flex-col min-h-0"
|
|
2435
2509
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -2480,7 +2554,7 @@ function ContractActionBar({ networkConfig, contractAddress = null, onToggleCont
|
|
|
2480
2554
|
//#endregion
|
|
2481
2555
|
//#region src/components/network/NetworkServiceSettingsPanel.tsx
|
|
2482
2556
|
/** Panel for configuring network service settings like RPC endpoints. */
|
|
2483
|
-
function NetworkServiceSettingsPanel({
|
|
2557
|
+
function NetworkServiceSettingsPanel({ relayer, networkId, service, onSettingsChanged }) {
|
|
2484
2558
|
const [isTesting, setIsTesting] = (0, react.useState)(false);
|
|
2485
2559
|
const [result, setResult] = (0, react.useState)(null);
|
|
2486
2560
|
const { control, handleSubmit, setValue, getValues, watch, formState: { isDirty } } = (0, react_hook_form.useForm)({ defaultValues: {} });
|
|
@@ -2525,12 +2599,12 @@ function NetworkServiceSettingsPanel({ adapter, networkId, service, onSettingsCh
|
|
|
2525
2599
|
getValues
|
|
2526
2600
|
]);
|
|
2527
2601
|
const testConnection = (0, react.useCallback)(async () => {
|
|
2528
|
-
if (!
|
|
2602
|
+
if (!relayer.testNetworkServiceConnection) return;
|
|
2529
2603
|
setIsTesting(true);
|
|
2530
2604
|
setResult(null);
|
|
2531
2605
|
try {
|
|
2532
2606
|
const data = getValues();
|
|
2533
|
-
const r = await
|
|
2607
|
+
const r = await relayer.testNetworkServiceConnection(service.id, data);
|
|
2534
2608
|
setResult({
|
|
2535
2609
|
success: r.success,
|
|
2536
2610
|
message: r.error || (r.success ? "Connection successful" : "Connection failed"),
|
|
@@ -2545,15 +2619,15 @@ function NetworkServiceSettingsPanel({ adapter, networkId, service, onSettingsCh
|
|
|
2545
2619
|
setIsTesting(false);
|
|
2546
2620
|
}
|
|
2547
2621
|
}, [
|
|
2548
|
-
|
|
2622
|
+
relayer,
|
|
2549
2623
|
service.id,
|
|
2550
2624
|
getValues
|
|
2551
2625
|
]);
|
|
2552
2626
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
|
|
2553
2627
|
onSubmit: handleSubmit((0, react.useCallback)(async (formData) => {
|
|
2554
2628
|
const data = formData;
|
|
2555
|
-
if (
|
|
2556
|
-
if (!await
|
|
2629
|
+
if (relayer.validateNetworkServiceConfig) {
|
|
2630
|
+
if (!await relayer.validateNetworkServiceConfig(service.id, data)) {
|
|
2557
2631
|
setResult({
|
|
2558
2632
|
success: false,
|
|
2559
2633
|
message: "Invalid configuration"
|
|
@@ -2569,7 +2643,7 @@ function NetworkServiceSettingsPanel({ adapter, networkId, service, onSettingsCh
|
|
|
2569
2643
|
message: "Settings saved successfully"
|
|
2570
2644
|
});
|
|
2571
2645
|
}, [
|
|
2572
|
-
|
|
2646
|
+
relayer,
|
|
2573
2647
|
networkId,
|
|
2574
2648
|
service.id,
|
|
2575
2649
|
onSettingsChanged
|
|
@@ -2611,8 +2685,7 @@ function NetworkServiceSettingsPanel({ adapter, networkId, service, onSettingsCh
|
|
|
2611
2685
|
className: "space-y-4",
|
|
2612
2686
|
children: primaryFields.map((field) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DynamicFormField, {
|
|
2613
2687
|
field,
|
|
2614
|
-
control
|
|
2615
|
-
adapter
|
|
2688
|
+
control
|
|
2616
2689
|
}, field.id))
|
|
2617
2690
|
}),
|
|
2618
2691
|
Object.keys(sectionGroups).length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_openzeppelin_ui_components.Accordion, {
|
|
@@ -2658,8 +2731,7 @@ function NetworkServiceSettingsPanel({ adapter, networkId, service, onSettingsCh
|
|
|
2658
2731
|
className: indentUnder ? "ml-6" : "",
|
|
2659
2732
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DynamicFormField, {
|
|
2660
2733
|
field: wrappedField,
|
|
2661
|
-
control
|
|
2662
|
-
adapter
|
|
2734
|
+
control
|
|
2663
2735
|
})
|
|
2664
2736
|
}, field.id);
|
|
2665
2737
|
})
|
|
@@ -2702,7 +2774,7 @@ function NetworkServiceSettingsPanel({ adapter, networkId, service, onSettingsCh
|
|
|
2702
2774
|
const hideTest = fields.some((f) => {
|
|
2703
2775
|
return f.metadata?.hideTestConnection === true;
|
|
2704
2776
|
});
|
|
2705
|
-
return Boolean(
|
|
2777
|
+
return Boolean(relayer.testNetworkServiceConnection) && !hideTest;
|
|
2706
2778
|
})() ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_openzeppelin_ui_components.Button, {
|
|
2707
2779
|
type: "button",
|
|
2708
2780
|
variant: "outline",
|
|
@@ -2723,14 +2795,14 @@ function NetworkServiceSettingsPanel({ adapter, networkId, service, onSettingsCh
|
|
|
2723
2795
|
|
|
2724
2796
|
//#endregion
|
|
2725
2797
|
//#region src/components/network/NetworkSettingsDialog.tsx
|
|
2726
|
-
const NetworkSettingsDialog = ({ isOpen, onOpenChange, networkConfig,
|
|
2727
|
-
const services = (0, _openzeppelin_ui_utils.filterEnabledServiceForms)(
|
|
2798
|
+
const NetworkSettingsDialog = ({ isOpen, onOpenChange, networkConfig, relayer, onSettingsChanged }) => {
|
|
2799
|
+
const services = (0, _openzeppelin_ui_utils.filterEnabledServiceForms)(relayer?.getNetworkServiceForms() ?? []);
|
|
2728
2800
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_openzeppelin_ui_components.Dialog, {
|
|
2729
2801
|
open: isOpen,
|
|
2730
2802
|
onOpenChange,
|
|
2731
2803
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_openzeppelin_ui_components.DialogContent, {
|
|
2732
2804
|
className: "max-w-2xl sm:max-w-3xl",
|
|
2733
|
-
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 &&
|
|
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, {
|
|
2734
2806
|
defaultValue: services[0]?.id,
|
|
2735
2807
|
className: "w-full",
|
|
2736
2808
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_openzeppelin_ui_components.TabsList, {
|
|
@@ -2743,16 +2815,10 @@ const NetworkSettingsDialog = ({ isOpen, onOpenChange, networkConfig, adapter })
|
|
|
2743
2815
|
value: svc.id,
|
|
2744
2816
|
className: "px-2",
|
|
2745
2817
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NetworkServiceSettingsPanel, {
|
|
2746
|
-
|
|
2818
|
+
relayer,
|
|
2747
2819
|
networkId: networkConfig.id,
|
|
2748
2820
|
service: svc,
|
|
2749
|
-
onSettingsChanged
|
|
2750
|
-
const cfg = _openzeppelin_ui_utils.appConfigService.getTypedNestedConfig("walletui", "config");
|
|
2751
|
-
adapter.configureUiKit?.(cfg ?? {
|
|
2752
|
-
kitName: "custom",
|
|
2753
|
-
kitConfig: {}
|
|
2754
|
-
});
|
|
2755
|
-
}
|
|
2821
|
+
onSettingsChanged
|
|
2756
2822
|
})
|
|
2757
2823
|
}, svc.id))]
|
|
2758
2824
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -2779,7 +2845,7 @@ const NetworkSettingsDialog = ({ isOpen, onOpenChange, networkConfig, adapter })
|
|
|
2779
2845
|
* Used in exported apps to provide access to RPC and Explorer configuration.
|
|
2780
2846
|
*/
|
|
2781
2847
|
const WalletConnectionWithSettings = () => {
|
|
2782
|
-
const {
|
|
2848
|
+
const { isRuntimeLoading, activeRuntime, activeNetworkConfig, reconfigureActiveUiKit } = (0, _openzeppelin_ui_react.useWalletState)();
|
|
2783
2849
|
const { setOpenNetworkSettingsHandler } = (0, _openzeppelin_ui_components.useNetworkErrors)();
|
|
2784
2850
|
const [showNetworkSettings, setShowNetworkSettings] = (0, react.useState)(false);
|
|
2785
2851
|
const openNetworkSettings = (0, react.useCallback)((networkId) => {
|
|
@@ -2788,10 +2854,10 @@ const WalletConnectionWithSettings = () => {
|
|
|
2788
2854
|
(0, react.useEffect)(() => {
|
|
2789
2855
|
setOpenNetworkSettingsHandler(openNetworkSettings);
|
|
2790
2856
|
}, [openNetworkSettings, setOpenNetworkSettingsHandler]);
|
|
2791
|
-
if (
|
|
2857
|
+
if (isRuntimeLoading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "h-9 w-28 animate-pulse rounded bg-muted" });
|
|
2792
2858
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2793
2859
|
className: "flex items-center gap-2",
|
|
2794
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_openzeppelin_ui_react.WalletConnectionUI, {}),
|
|
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, {
|
|
2795
2861
|
variant: "ghost",
|
|
2796
2862
|
size: "icon",
|
|
2797
2863
|
className: "h-9 w-9",
|
|
@@ -2803,7 +2869,13 @@ const WalletConnectionWithSettings = () => {
|
|
|
2803
2869
|
isOpen: showNetworkSettings,
|
|
2804
2870
|
onOpenChange: setShowNetworkSettings,
|
|
2805
2871
|
networkConfig: activeNetworkConfig,
|
|
2806
|
-
|
|
2872
|
+
relayer: activeRuntime?.relayer ?? null,
|
|
2873
|
+
onSettingsChanged: () => {
|
|
2874
|
+
reconfigureActiveUiKit(_openzeppelin_ui_utils.appConfigService.getTypedNestedConfig("walletui", "config") ?? {
|
|
2875
|
+
kitName: "custom",
|
|
2876
|
+
kitConfig: {}
|
|
2877
|
+
});
|
|
2878
|
+
}
|
|
2807
2879
|
})] });
|
|
2808
2880
|
};
|
|
2809
2881
|
|
|
@@ -2818,6 +2890,7 @@ exports.NetworkSettingsDialog = NetworkSettingsDialog;
|
|
|
2818
2890
|
exports.TransactionExecuteButton = TransactionExecuteButton;
|
|
2819
2891
|
exports.TransactionForm = TransactionForm;
|
|
2820
2892
|
exports.WalletConnectionWithSettings = WalletConnectionWithSettings;
|
|
2893
|
+
exports.buildTransactionSuccessPayload = buildTransactionSuccessPayload;
|
|
2821
2894
|
exports.createAddressTransform = createAddressTransform;
|
|
2822
2895
|
exports.createArrayObjectTransform = createArrayObjectTransform;
|
|
2823
2896
|
exports.createArrayTransform = createArrayTransform;
|
|
@@ -2831,6 +2904,8 @@ exports.createTextTransform = createTextTransform;
|
|
|
2831
2904
|
exports.createTransformForFieldType = createTransformForFieldType;
|
|
2832
2905
|
exports.generateDefaultValue = generateDefaultValue;
|
|
2833
2906
|
exports.getDefaultValueByFieldType = getDefaultValueByFieldType;
|
|
2907
|
+
exports.invokeOnTransactionSuccess = invokeOnTransactionSuccess;
|
|
2908
|
+
exports.normalizeTransactionSuccessHash = normalizeTransactionSuccessHash;
|
|
2834
2909
|
exports.rendererConfig = rendererConfig;
|
|
2835
2910
|
exports.useAliasEditState = useAliasEditState;
|
|
2836
2911
|
exports.validateField = validateField;
|