@openzeppelin/ui-builder-adapter-stellar 0.14.0 → 0.16.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
@@ -44,7 +44,7 @@ __export(index_exports, {
44
44
  module.exports = __toCommonJS(index_exports);
45
45
 
46
46
  // src/adapter.ts
47
- var import_ui_builder_types6 = require("@openzeppelin/ui-builder-types");
47
+ var import_ui_builder_types7 = require("@openzeppelin/ui-builder-types");
48
48
  var import_ui_builder_utils38 = require("@openzeppelin/ui-builder-utils");
49
49
 
50
50
  // src/configuration/rpc.ts
@@ -479,10 +479,17 @@ function extractStructFields(entries, structName) {
479
479
  for (const field of fields) {
480
480
  const fieldName = field.name().toString();
481
481
  const fieldType = extractSorobanTypeFromScSpec(field.type());
482
- structFields.push({
482
+ const fieldParam = {
483
483
  name: fieldName,
484
484
  type: fieldType
485
- });
485
+ };
486
+ if (isStructType(entries, fieldType)) {
487
+ const nestedFields = extractStructFields(entries, fieldType);
488
+ if (nestedFields && nestedFields.length > 0) {
489
+ fieldParam.components = nestedFields;
490
+ }
491
+ }
492
+ structFields.push(fieldParam);
486
493
  }
487
494
  return structFields;
488
495
  }
@@ -523,7 +530,7 @@ var import_stellar_sdk9 = require("@stellar/stellar-sdk");
523
530
  var import_ui_builder_utils12 = require("@openzeppelin/ui-builder-utils");
524
531
 
525
532
  // src/transform/parsers/index.ts
526
- var import_ui_builder_types3 = require("@openzeppelin/ui-builder-types");
533
+ var import_ui_builder_types4 = require("@openzeppelin/ui-builder-types");
527
534
  var import_ui_builder_utils10 = require("@openzeppelin/ui-builder-utils");
528
535
 
529
536
  // src/transform/parsers/generic-parser.ts
@@ -766,6 +773,20 @@ function extractOptionElementType(parameterType) {
766
773
  }
767
774
  return extractGenericInnerType(parameterType, "Option");
768
775
  }
776
+ function extractTupleTypes(parameterType) {
777
+ if (!isValidTypeString(parameterType) || !parameterType.startsWith("Tuple<")) {
778
+ return null;
779
+ }
780
+ const innerContent = extractGenericInnerType(parameterType, "Tuple");
781
+ if (!innerContent) {
782
+ return null;
783
+ }
784
+ const parts = splitTopLevelTypes(innerContent);
785
+ if (parts.length === 0) {
786
+ return null;
787
+ }
788
+ return parts;
789
+ }
769
790
  function extractGenericInnerType(parameterType, genericName) {
770
791
  const prefix = `${genericName}<`;
771
792
  if (!parameterType.startsWith(prefix) || !parameterType.endsWith(">")) {
@@ -839,6 +860,30 @@ function hasInvalidCharacters(str) {
839
860
  }
840
861
  return !/^[A-Za-z0-9<>,\s_]+$/.test(str);
841
862
  }
863
+ function splitTopLevelTypes(content) {
864
+ const types = [];
865
+ let start = 0;
866
+ let level = 0;
867
+ for (let i = 0; i < content.length; i += 1) {
868
+ const char = content[i];
869
+ if (char === "<") {
870
+ level += 1;
871
+ } else if (char === ">") {
872
+ level -= 1;
873
+ } else if (char === "," && level === 0) {
874
+ const segment = content.slice(start, i).trim();
875
+ if (segment) {
876
+ types.push(segment);
877
+ }
878
+ start = i + 1;
879
+ }
880
+ }
881
+ const lastSegment = content.slice(start).trim();
882
+ if (lastSegment) {
883
+ types.push(lastSegment);
884
+ }
885
+ return types;
886
+ }
842
887
 
843
888
  // src/utils/formatting.ts
844
889
  function stringifyWithBigInt(value, space) {
@@ -913,6 +958,34 @@ function convertStellarTypeToScValType(stellarType) {
913
958
  // src/utils/input-parsing.ts
914
959
  var import_stellar_sdk4 = require("@stellar/stellar-sdk");
915
960
  var import_ui_builder_utils7 = require("@openzeppelin/ui-builder-utils");
961
+
962
+ // src/utils/xdr-ordering.ts
963
+ function compareScValsByXdr(a, b) {
964
+ const aBytes = getBytes(a);
965
+ const bBytes = getBytes(b);
966
+ const minLength = Math.min(aBytes.length, bBytes.length);
967
+ for (let index = 0; index < minLength; index += 1) {
968
+ const diff = aBytes[index] - bBytes[index];
969
+ if (diff !== 0) {
970
+ return diff;
971
+ }
972
+ }
973
+ return aBytes.length - bBytes.length;
974
+ }
975
+ function getBytes(scVal) {
976
+ const xdrValue = scVal.toXDR();
977
+ if (xdrValue instanceof Uint8Array) {
978
+ return xdrValue;
979
+ }
980
+ const arrayLike = xdrValue;
981
+ const result = new Uint8Array(arrayLike.length);
982
+ for (let index = 0; index < arrayLike.length; index += 1) {
983
+ result[index] = arrayLike[index];
984
+ }
985
+ return result;
986
+ }
987
+
988
+ // src/utils/input-parsing.ts
916
989
  var SYSTEM_LOG_TAG4 = "StellarInputParsingUtils";
917
990
  function isMapArray(argValue) {
918
991
  try {
@@ -996,19 +1069,34 @@ function convertEnumToScVal(obj, scVals) {
996
1069
  }
997
1070
  function convertObjectToMap(mapArray) {
998
1071
  try {
999
- const mapVal = mapArray.reduce((acc, pair) => {
1000
- const key = pair["0"].value;
1072
+ const sortedEntries = [...mapArray].sort((a, b) => {
1073
+ const aKey = getScValFromPrimitive(a["0"]);
1074
+ const bKey = getScValFromPrimitive(b["0"]);
1075
+ return compareScValsByXdr(aKey, bKey);
1076
+ });
1077
+ const mapVal = sortedEntries.reduce((acc, pair) => {
1078
+ const key = String(pair["0"].value);
1001
1079
  if (Array.isArray(pair["1"])) {
1002
1080
  const valueScVal = getScValFromArg(pair["1"], []);
1003
1081
  acc[key] = valueScVal;
1004
1082
  } else {
1005
1083
  const value = pair["1"].value;
1006
- acc[key] = pair["1"].type === "bool" ? value === "true" : value;
1084
+ if (pair["1"].type === "bool") {
1085
+ if (typeof value === "boolean") {
1086
+ acc[key] = value;
1087
+ } else if (typeof value === "string") {
1088
+ acc[key] = value === "true";
1089
+ } else {
1090
+ acc[key] = Boolean(value);
1091
+ }
1092
+ } else {
1093
+ acc[key] = value;
1094
+ }
1007
1095
  }
1008
1096
  return acc;
1009
1097
  }, {});
1010
- const mapType = mapArray.reduce((acc, pair) => {
1011
- const key = pair["0"].value;
1098
+ const mapType = sortedEntries.reduce((acc, pair) => {
1099
+ const key = String(pair["0"].value);
1012
1100
  const keyTypeHint = convertStellarTypeToScValType(pair["0"].type);
1013
1101
  const valueTypeHint = convertStellarTypeToScValType(pair["1"].type);
1014
1102
  acc[key] = [
@@ -1026,12 +1114,43 @@ function convertObjectToMap(mapArray) {
1026
1114
 
1027
1115
  // src/transform/parsers/scval-converter.ts
1028
1116
  var import_stellar_sdk7 = require("@stellar/stellar-sdk");
1029
- var import_ui_builder_types2 = require("@openzeppelin/ui-builder-types");
1117
+ var import_ui_builder_types3 = require("@openzeppelin/ui-builder-types");
1118
+
1119
+ // src/utils/stellar-types.ts
1120
+ var PRIMITIVE_STELLAR_TYPES = /* @__PURE__ */ new Set([
1121
+ "Bool",
1122
+ "ScString",
1123
+ "ScSymbol",
1124
+ "Address",
1125
+ "Bytes",
1126
+ "U8",
1127
+ "U16",
1128
+ "U32",
1129
+ "U64",
1130
+ "U128",
1131
+ "U256",
1132
+ "I8",
1133
+ "I16",
1134
+ "I32",
1135
+ "I64",
1136
+ "I128",
1137
+ "I256"
1138
+ ]);
1139
+ function isPrimitiveParamType(type) {
1140
+ return PRIMITIVE_STELLAR_TYPES.has(type);
1141
+ }
1030
1142
 
1031
1143
  // src/transform/parsers/struct-parser.ts
1032
1144
  var import_stellar_sdk6 = require("@stellar/stellar-sdk");
1145
+ var import_ui_builder_types2 = require("@openzeppelin/ui-builder-types");
1033
1146
  var import_ui_builder_utils9 = require("@openzeppelin/ui-builder-utils");
1034
1147
  var SYSTEM_LOG_TAG5 = "StructParser";
1148
+ function isTupleStructSchema(schema) {
1149
+ if (!schema?.components || schema.components.length === 0) {
1150
+ return false;
1151
+ }
1152
+ return schema.components.every((component, index) => component.name === index.toString());
1153
+ }
1035
1154
  function needsParsing(value, fieldType) {
1036
1155
  if ((fieldType === "Bytes" || fieldType.startsWith("BytesN<")) && value instanceof Uint8Array) {
1037
1156
  return false;
@@ -1056,7 +1175,23 @@ function needsParsing(value, fieldType) {
1056
1175
  }
1057
1176
  return false;
1058
1177
  }
1059
- function convertStructToScVal(structObj, parameterType, paramSchema, parseInnerValue) {
1178
+ function convertStructToScVal(structObj, parameterType, paramSchema, parseInnerValue, convertToScVal) {
1179
+ if (isTupleStructSchema(paramSchema) && paramSchema && convertToScVal) {
1180
+ const tupleValues = paramSchema.components.map((component, index) => {
1181
+ const key = component.name ?? index.toString();
1182
+ let elementValue = structObj[key];
1183
+ if (typeof elementValue === "undefined") {
1184
+ throw new Error(
1185
+ `Missing tuple value for "${key}" in struct type "${parameterType}". Received: ${JSON.stringify(structObj)}`
1186
+ );
1187
+ }
1188
+ if (typeof elementValue === "string" && isLikelyEnumType(component.type)) {
1189
+ elementValue = { tag: elementValue };
1190
+ }
1191
+ return convertToScVal(elementValue, component.type, component, parseInnerValue);
1192
+ });
1193
+ return import_stellar_sdk6.xdr.ScVal.scvVec(tupleValues);
1194
+ }
1060
1195
  const convertedValue = {};
1061
1196
  const typeHints = {};
1062
1197
  for (const [fieldName, fieldValue] of Object.entries(structObj)) {
@@ -1074,6 +1209,9 @@ function convertStructToScVal(structObj, parameterType, paramSchema, parseInnerV
1074
1209
  } else {
1075
1210
  parsedValue = fieldValue;
1076
1211
  }
1212
+ if (typeof parsedValue === "string" && isLikelyEnumType(fieldType)) {
1213
+ parsedValue = { tag: parsedValue };
1214
+ }
1077
1215
  if (fieldType.startsWith("Map<") && Array.isArray(parsedValue)) {
1078
1216
  const mapTypeMatch = fieldType.match(/Map<(.+),\s*(.+)>$/);
1079
1217
  const mapKeyType = mapTypeMatch ? mapTypeMatch[1] : "ScSymbol";
@@ -1095,10 +1233,21 @@ function convertStructToScVal(structObj, parameterType, paramSchema, parseInnerV
1095
1233
  convertedValue[fieldName] = mapObject;
1096
1234
  typeHints[fieldName] = ["symbol", mapTypeHints];
1097
1235
  } else {
1098
- convertedValue[fieldName] = parsedValue;
1099
- const scValType = convertStellarTypeToScValType(fieldType);
1100
- if (scValType !== "map-special") {
1101
- typeHints[fieldName] = ["symbol", Array.isArray(scValType) ? scValType[0] : scValType];
1236
+ if (convertToScVal && (fieldType.startsWith("Vec<") || (0, import_ui_builder_types2.isEnumValue)(parsedValue))) {
1237
+ const fieldSchema = paramSchema?.components?.find((c) => c.name === fieldName);
1238
+ convertedValue[fieldName] = convertToScVal(
1239
+ parsedValue,
1240
+ fieldType,
1241
+ fieldSchema,
1242
+ parseInnerValue
1243
+ );
1244
+ typeHints[fieldName] = ["symbol", "scval"];
1245
+ } else {
1246
+ convertedValue[fieldName] = parsedValue;
1247
+ const scValType = convertStellarTypeToScValType(fieldType);
1248
+ if (scValType !== "map-special") {
1249
+ typeHints[fieldName] = ["symbol", Array.isArray(scValType) ? scValType[0] : scValType];
1250
+ }
1102
1251
  }
1103
1252
  }
1104
1253
  } else {
@@ -1112,7 +1261,40 @@ function convertStructToScVal(structObj, parameterType, paramSchema, parseInnerV
1112
1261
  convertedValue,
1113
1262
  typeHints
1114
1263
  });
1115
- const scVal = (0, import_stellar_sdk6.nativeToScVal)(convertedValue, { type: typeHints });
1264
+ const hasEnumFields = paramSchema?.components?.some((comp) => {
1265
+ const fieldValue = convertedValue[comp.name];
1266
+ return (0, import_ui_builder_types2.isEnumValue)(fieldValue);
1267
+ });
1268
+ let scVal;
1269
+ if (hasEnumFields && convertToScVal && paramSchema?.components) {
1270
+ const mapEntries = [];
1271
+ for (const fieldSchema of paramSchema.components) {
1272
+ const fieldName = fieldSchema.name;
1273
+ const fieldValue = convertedValue[fieldName];
1274
+ const keyScVal = (0, import_stellar_sdk6.nativeToScVal)(fieldName, { type: "symbol" });
1275
+ let valueScVal;
1276
+ if ((0, import_ui_builder_types2.isEnumValue)(fieldValue)) {
1277
+ valueScVal = convertToScVal(fieldValue, fieldSchema.type, fieldSchema, parseInnerValue);
1278
+ } else {
1279
+ const fieldTypeHint = typeHints[fieldName];
1280
+ if (fieldTypeHint && Array.isArray(fieldTypeHint) && fieldTypeHint.length > 1) {
1281
+ valueScVal = (0, import_stellar_sdk6.nativeToScVal)(fieldValue, { type: fieldTypeHint[1] });
1282
+ } else {
1283
+ valueScVal = (0, import_stellar_sdk6.nativeToScVal)(fieldValue);
1284
+ }
1285
+ }
1286
+ mapEntries.push(
1287
+ new import_stellar_sdk6.xdr.ScMapEntry({
1288
+ key: keyScVal,
1289
+ val: valueScVal
1290
+ })
1291
+ );
1292
+ }
1293
+ const sortedMapEntries = mapEntries.sort((a, b) => compareScValsByXdr(a.key(), b.key()));
1294
+ scVal = import_stellar_sdk6.xdr.ScVal.scvMap(sortedMapEntries);
1295
+ } else {
1296
+ scVal = (0, import_stellar_sdk6.nativeToScVal)(convertedValue, { type: typeHints });
1297
+ }
1116
1298
  import_ui_builder_utils9.logger.debug(SYSTEM_LOG_TAG5, "convertStructToScVal generated ScVal:", {
1117
1299
  parameterType,
1118
1300
  scValType: scVal.switch().name,
@@ -1139,16 +1321,95 @@ function isStructType2(value, parameterType) {
1139
1321
  function valueToScVal(value, parameterType, paramSchema, parseInnerValue) {
1140
1322
  const parseValue = parseInnerValue || ((val) => val);
1141
1323
  const genericInfo = parseGenericType(parameterType);
1324
+ const isTypedWrapper = (v) => !!v && typeof v === "object" && "type" in v && "value" in v;
1325
+ const enumMetadata = paramSchema?.enumMetadata;
1326
+ const possibleEnumValue = typeof value === "string" && (enumMetadata || isLikelyEnumType(parameterType)) ? { tag: value } : value;
1142
1327
  if (!genericInfo) {
1143
- if ((0, import_ui_builder_types2.isEnumValue)(value) || typeof value === "object" && value !== null && "enum" in value) {
1144
- return convertEnumToScVal(value);
1328
+ if (enumMetadata && enumMetadata.variants.every((v) => v.type === "integer")) {
1329
+ let numericValue;
1330
+ if (typeof value === "string") {
1331
+ const byName = enumMetadata.variants.find((v) => v.name === value);
1332
+ numericValue = byName?.value ?? Number(value);
1333
+ } else if (typeof value === "number") {
1334
+ numericValue = value;
1335
+ } else if ((0, import_ui_builder_types3.isEnumValue)(value)) {
1336
+ const byTag = enumMetadata.variants.find((v) => v.name === value.tag);
1337
+ numericValue = byTag?.value;
1338
+ }
1339
+ if (numericValue === void 0 || Number.isNaN(numericValue)) {
1340
+ const validNames = enumMetadata.variants.map((v) => v.name).join(", ");
1341
+ throw new Error(
1342
+ `Invalid integer enum value for ${parameterType}: ${String(value)}. Expected one of: ${validNames}`
1343
+ );
1344
+ }
1345
+ return (0, import_stellar_sdk7.nativeToScVal)(numericValue, { type: "u32" });
1346
+ }
1347
+ if (isTypedWrapper(possibleEnumValue)) {
1348
+ const wrapped = possibleEnumValue;
1349
+ const parsed = parsePrimitive(wrapped.value, wrapped.type);
1350
+ const finalVal = parsed !== null ? parsed : wrapped.value;
1351
+ const scValType2 = convertStellarTypeToScValType(wrapped.type);
1352
+ const typeHint2 = Array.isArray(scValType2) ? scValType2[0] : scValType2;
1353
+ return (0, import_stellar_sdk7.nativeToScVal)(finalVal, { type: typeHint2 });
1354
+ }
1355
+ if ((0, import_ui_builder_types3.isEnumValue)(possibleEnumValue) || typeof possibleEnumValue === "object" && possibleEnumValue !== null && "enum" in possibleEnumValue) {
1356
+ const enumValue = possibleEnumValue;
1357
+ if ("enum" in enumValue && typeof enumValue.enum === "number") {
1358
+ return (0, import_stellar_sdk7.nativeToScVal)(enumValue.enum, { type: "u32" });
1359
+ }
1360
+ const tagSymbol = (0, import_stellar_sdk7.nativeToScVal)(enumValue.tag, { type: "symbol" });
1361
+ if (!enumValue.values || enumValue.values.length === 0) {
1362
+ return import_stellar_sdk7.xdr.ScVal.scvVec([tagSymbol]);
1363
+ }
1364
+ const payloadValues = enumValue.values;
1365
+ let payloadScVals;
1366
+ let variant;
1367
+ if (enumMetadata) {
1368
+ variant = enumMetadata.variants.find((variantEntry) => variantEntry.name === enumValue.tag);
1369
+ if (!variant || !variant.payloadTypes) {
1370
+ return convertEnumToScVal(enumValue);
1371
+ }
1372
+ const payloadTypes = variant.payloadTypes;
1373
+ const payloadComponents = variant.payloadComponents;
1374
+ payloadScVals = payloadTypes.map((payloadType, index) => {
1375
+ const payloadSchema = payloadComponents?.[index] ? {
1376
+ name: `payload_${index}`,
1377
+ type: payloadType,
1378
+ components: payloadComponents[index]
1379
+ } : { name: `payload_${index}`, type: payloadType };
1380
+ const val = payloadValues[index];
1381
+ return valueToScVal(val, payloadType, payloadSchema, parseValue);
1382
+ });
1383
+ } else {
1384
+ return convertEnumToScVal(enumValue);
1385
+ }
1386
+ if (variant?.isSingleTuplePayload) {
1387
+ const tuplePayloadVec = import_stellar_sdk7.xdr.ScVal.scvVec(payloadScVals);
1388
+ return import_stellar_sdk7.xdr.ScVal.scvVec([tagSymbol, tuplePayloadVec]);
1389
+ }
1390
+ return import_stellar_sdk7.xdr.ScVal.scvVec([tagSymbol, ...payloadScVals]);
1391
+ }
1392
+ if (Array.isArray(possibleEnumValue) && paramSchema?.components && paramSchema.components.length) {
1393
+ if (possibleEnumValue.length !== paramSchema.components.length) {
1394
+ throw new Error(
1395
+ `Tuple-struct value length (${possibleEnumValue.length}) does not match schema components (${paramSchema.components.length}) for type ${parameterType}`
1396
+ );
1397
+ }
1398
+ return convertStructToScVal(
1399
+ possibleEnumValue,
1400
+ parameterType,
1401
+ paramSchema,
1402
+ parseValue,
1403
+ (innerValue, innerType, innerSchema) => valueToScVal(innerValue, innerType, innerSchema, parseInnerValue)
1404
+ );
1145
1405
  }
1146
- if (isStructType2(value, parameterType)) {
1406
+ if (!isPrimitiveParamType(parameterType) && isStructType2(value, parameterType)) {
1147
1407
  return convertStructToScVal(
1148
1408
  value,
1149
1409
  parameterType,
1150
1410
  paramSchema,
1151
- parseValue
1411
+ parseValue,
1412
+ (innerValue, innerType, innerSchema) => valueToScVal(innerValue, innerType, innerSchema, parseInnerValue)
1152
1413
  );
1153
1414
  }
1154
1415
  if (parameterType === "Bool" || parameterType === "Bytes") {
@@ -1178,15 +1439,30 @@ function valueToScVal(value, parameterType, paramSchema, parseInnerValue) {
1178
1439
  case "Vec": {
1179
1440
  const innerType = parameters[0];
1180
1441
  if (Array.isArray(value)) {
1181
- const convertedElements = value.map((element) => valueToScVal(element, innerType));
1442
+ let elementSchema;
1443
+ if (enumMetadata) {
1444
+ elementSchema = {
1445
+ name: "element",
1446
+ type: innerType,
1447
+ enumMetadata
1448
+ };
1449
+ } else if (paramSchema?.components) {
1450
+ elementSchema = {
1451
+ name: "element",
1452
+ type: innerType,
1453
+ components: paramSchema.components
1454
+ };
1455
+ }
1456
+ const convertedElements = value.map(
1457
+ (element) => valueToScVal(element, innerType, elementSchema, parseValue)
1458
+ );
1182
1459
  return (0, import_stellar_sdk7.nativeToScVal)(convertedElements);
1183
1460
  }
1184
1461
  return (0, import_stellar_sdk7.nativeToScVal)(value);
1185
1462
  }
1186
1463
  case "Map": {
1187
1464
  if (Array.isArray(value)) {
1188
- const convertedValue = {};
1189
- const typeHints = {};
1465
+ const mapEntries = [];
1190
1466
  value.forEach(
1191
1467
  (entry) => {
1192
1468
  if (typeof entry !== "object" || entry === null || !entry[0] || !entry[1] || typeof entry[0].value === "undefined" || typeof entry[1].value === "undefined") {
@@ -1202,26 +1478,74 @@ function valueToScVal(value, parameterType, paramSchema, parseInnerValue) {
1202
1478
  if (valuePrimitive !== null) {
1203
1479
  processedValue = valuePrimitive;
1204
1480
  }
1205
- const keyString = typeof processedKey === "string" ? processedKey : String(processedKey);
1206
- convertedValue[keyString] = processedValue;
1207
1481
  const keyScValType = convertStellarTypeToScValType(entry[0].type);
1482
+ const keyTypeHint = Array.isArray(keyScValType) ? keyScValType[0] : keyScValType;
1483
+ const keyScVal = (0, import_stellar_sdk7.nativeToScVal)(processedKey, { type: keyTypeHint });
1208
1484
  const valueScValType = convertStellarTypeToScValType(entry[1].type);
1209
- typeHints[keyString] = [
1210
- Array.isArray(keyScValType) ? keyScValType[0] : keyScValType,
1211
- Array.isArray(valueScValType) ? valueScValType[0] : valueScValType
1212
- ];
1485
+ const valueTypeHint = Array.isArray(valueScValType) ? valueScValType[0] : valueScValType;
1486
+ const valueScVal = (0, import_stellar_sdk7.nativeToScVal)(processedValue, { type: valueTypeHint });
1487
+ mapEntries.push(
1488
+ new import_stellar_sdk7.xdr.ScMapEntry({
1489
+ key: keyScVal,
1490
+ val: valueScVal
1491
+ })
1492
+ );
1213
1493
  }
1214
1494
  );
1215
- return (0, import_stellar_sdk7.nativeToScVal)(convertedValue, { type: typeHints });
1495
+ const sortedMapEntries = mapEntries.sort((a, b) => compareScValsByXdr(a.key(), b.key()));
1496
+ return import_stellar_sdk7.xdr.ScVal.scvMap(sortedMapEntries);
1216
1497
  }
1217
1498
  return (0, import_stellar_sdk7.nativeToScVal)(value);
1218
1499
  }
1500
+ case "Tuple": {
1501
+ if (!paramSchema?.components || paramSchema.components.length === 0) {
1502
+ throw new Error(
1503
+ `Tuple parameter "${paramSchema?.name ?? "unknown"}" is missing component metadata`
1504
+ );
1505
+ }
1506
+ const tupleComponents = paramSchema.components;
1507
+ const tupleValues = [];
1508
+ tupleComponents.forEach((component, index) => {
1509
+ const key = component.name ?? `item_${index}`;
1510
+ let elementValue;
1511
+ if (Array.isArray(value)) {
1512
+ elementValue = value[index];
1513
+ } else if (value && typeof value === "object") {
1514
+ elementValue = value[key];
1515
+ }
1516
+ if (typeof elementValue === "undefined") {
1517
+ const expectedTypes = tupleComponents.map((c) => c.type).join(", ");
1518
+ throw new Error(
1519
+ `Missing tuple value for "${key}" in parameter "${paramSchema.name ?? "unknown"}". Expected ${tupleComponents.length} values of types [${expectedTypes}] but received: ${JSON.stringify(value)}`
1520
+ );
1521
+ }
1522
+ if (typeof elementValue === "string" && isLikelyEnumType(component.type)) {
1523
+ elementValue = { tag: elementValue };
1524
+ }
1525
+ tupleValues.push(valueToScVal(elementValue, component.type, component, parseInnerValue));
1526
+ });
1527
+ return import_stellar_sdk7.xdr.ScVal.scvVec(tupleValues);
1528
+ }
1219
1529
  case "Option": {
1220
1530
  const innerType = parameters[0];
1221
1531
  if (value === null || value === void 0) {
1222
1532
  return (0, import_stellar_sdk7.nativeToScVal)(null);
1223
1533
  } else {
1224
- return valueToScVal(value, innerType);
1534
+ let innerSchema;
1535
+ if (enumMetadata) {
1536
+ innerSchema = {
1537
+ name: "inner",
1538
+ type: innerType,
1539
+ ...{ enumMetadata }
1540
+ };
1541
+ } else if (paramSchema?.components) {
1542
+ innerSchema = {
1543
+ name: "inner",
1544
+ type: innerType,
1545
+ components: paramSchema.components
1546
+ };
1547
+ }
1548
+ return valueToScVal(value, innerType, innerSchema, parseInnerValue);
1225
1549
  }
1226
1550
  }
1227
1551
  case "Result": {
@@ -1264,12 +1588,15 @@ function parseStellarInput(value, parameterType) {
1264
1588
  const result = parseGeneric(value, parameterType, parseStellarInput);
1265
1589
  return result;
1266
1590
  }
1267
- if ((0, import_ui_builder_types3.isEnumValue)(value) && isLikelyEnumType(parameterType)) {
1591
+ if ((0, import_ui_builder_types4.isEnumValue)(value) && isLikelyEnumType(parameterType)) {
1268
1592
  return value;
1269
1593
  }
1270
1594
  if ((0, import_ui_builder_utils10.isPlainObject)(value)) {
1271
1595
  return value;
1272
1596
  }
1597
+ if (Array.isArray(value)) {
1598
+ return value;
1599
+ }
1273
1600
  if (typeof value === "string" || typeof value === "number") {
1274
1601
  return value;
1275
1602
  }
@@ -3700,6 +4027,60 @@ var import_ui_builder_utils26 = require("@openzeppelin/ui-builder-utils");
3700
4027
  // src/mapping/enum-metadata.ts
3701
4028
  var import_stellar_sdk13 = require("@stellar/stellar-sdk");
3702
4029
  var import_ui_builder_utils25 = require("@openzeppelin/ui-builder-utils");
4030
+
4031
+ // src/mapping/tuple-components.ts
4032
+ function buildTupleComponents(parameterType, specEntries) {
4033
+ const tupleElements = extractTupleTypes(parameterType);
4034
+ if (!tupleElements || tupleElements.length === 0) {
4035
+ return null;
4036
+ }
4037
+ return tupleElements.map((elementType, index) => {
4038
+ let nestedComponents;
4039
+ if (specEntries && isStructType(specEntries, elementType)) {
4040
+ const structFields = extractStructFields(specEntries, elementType);
4041
+ if (structFields && structFields.length > 0) {
4042
+ nestedComponents = structFields;
4043
+ }
4044
+ } else if (elementType.startsWith("Tuple<")) {
4045
+ const tupleStruct = buildTupleComponents(elementType, specEntries);
4046
+ if (tupleStruct && tupleStruct.length > 0) {
4047
+ nestedComponents = tupleStruct;
4048
+ }
4049
+ }
4050
+ return {
4051
+ name: `item_${index}`,
4052
+ type: elementType,
4053
+ displayName: `Value ${index + 1} (${elementType})`,
4054
+ ...nestedComponents && { components: nestedComponents }
4055
+ };
4056
+ });
4057
+ }
4058
+
4059
+ // src/mapping/enum-metadata.ts
4060
+ function flattenPayloadType(payloadType, entries, flattenedTypes, flattenedComponents) {
4061
+ if (payloadType.startsWith("Tuple<")) {
4062
+ const tupleComponents = buildTupleComponents(payloadType, entries);
4063
+ if (tupleComponents && tupleComponents.length > 0) {
4064
+ tupleComponents.forEach((component) => {
4065
+ flattenedTypes.push(component.type);
4066
+ if (isStructType(entries, component.type)) {
4067
+ flattenedComponents.push(extractStructFields(entries, component.type) ?? void 0);
4068
+ } else {
4069
+ flattenedComponents.push(component.components);
4070
+ }
4071
+ });
4072
+ } else {
4073
+ flattenedTypes.push(payloadType);
4074
+ flattenedComponents.push(void 0);
4075
+ }
4076
+ } else if (isStructType(entries, payloadType)) {
4077
+ flattenedTypes.push(payloadType);
4078
+ flattenedComponents.push(extractStructFields(entries, payloadType) ?? void 0);
4079
+ } else {
4080
+ flattenedTypes.push(payloadType);
4081
+ flattenedComponents.push(void 0);
4082
+ }
4083
+ }
3703
4084
  function extractEnumVariants(entries, enumName) {
3704
4085
  try {
3705
4086
  const entry = entries.find((e) => {
@@ -3728,11 +4109,29 @@ function extractEnumVariants(entries, enumName) {
3728
4109
  });
3729
4110
  } else if (caseKind.value === import_stellar_sdk13.xdr.ScSpecUdtUnionCaseV0Kind.scSpecUdtUnionCaseTupleV0().value) {
3730
4111
  const tupleCase = caseEntry.tupleCase();
3731
- const payloadTypes = tupleCase.type().map((typeDef) => extractSorobanTypeFromScSpec(typeDef));
4112
+ const rawPayloadTypes = tupleCase.type().map((typeDef) => extractSorobanTypeFromScSpec(typeDef));
4113
+ const isSingleTuplePayload = rawPayloadTypes.length === 1 && rawPayloadTypes[0].startsWith("Tuple<");
4114
+ const flattenedPayloadTypes = [];
4115
+ const flattenedPayloadComponents = [];
4116
+ for (const payloadType of rawPayloadTypes) {
4117
+ flattenPayloadType(
4118
+ payloadType,
4119
+ entries,
4120
+ flattenedPayloadTypes,
4121
+ flattenedPayloadComponents
4122
+ );
4123
+ }
3732
4124
  variants.push({
3733
4125
  name: tupleCase.name().toString(),
3734
4126
  type: "tuple",
3735
- payloadTypes
4127
+ payloadTypes: flattenedPayloadTypes,
4128
+ ...flattenedPayloadComponents.some(
4129
+ (components) => components && components.length > 0
4130
+ ) && {
4131
+ payloadComponents: flattenedPayloadComponents
4132
+ },
4133
+ // Store metadata about whether this needs tuple wrapping during serialization
4134
+ ...isSingleTuplePayload && { isSingleTuplePayload: true }
3736
4135
  });
3737
4136
  isUnitOnly = false;
3738
4137
  }
@@ -3793,6 +4192,14 @@ function isEnumType(entries, typeName) {
3793
4192
  function getDefaultValidationForType() {
3794
4193
  return { required: true };
3795
4194
  }
4195
+ var STELLAR_NUMERIC_BOUNDS = {
4196
+ U8: { min: 0, max: 255 },
4197
+ U16: { min: 0, max: 65535 },
4198
+ U32: { min: 0, max: 4294967295 },
4199
+ I8: { min: -128, max: 127 },
4200
+ I16: { min: -32768, max: 32767 },
4201
+ I32: { min: -2147483648, max: 2147483647 }
4202
+ };
3796
4203
  function generateStellarDefaultField(parameter, contractSchema) {
3797
4204
  const specEntries = contractSchema?.metadata?.specEntries;
3798
4205
  const fieldType = mapStellarParameterTypeToFieldType(parameter.type);
@@ -3806,8 +4213,10 @@ function generateStellarDefaultField(parameter, contractSchema) {
3806
4213
  let structComponents = null;
3807
4214
  let finalFieldType = fieldType;
3808
4215
  let options;
3809
- if (isLikelyEnumType(parameter.type)) {
3810
- if (specEntries && isEnumType(specEntries, parameter.type)) {
4216
+ const enumDetectedBySpec = !!(specEntries && isEnumType(specEntries, parameter.type));
4217
+ const enumDetectedHeuristic = isLikelyEnumType(parameter.type);
4218
+ if (enumDetectedBySpec || enumDetectedHeuristic) {
4219
+ if (enumDetectedBySpec) {
3811
4220
  enumMetadata = extractEnumVariants(specEntries, parameter.type);
3812
4221
  if (enumMetadata) {
3813
4222
  if (enumMetadata.isUnitOnly) {
@@ -3836,6 +4245,12 @@ function generateStellarDefaultField(parameter, contractSchema) {
3836
4245
  structComponents = structFields;
3837
4246
  }
3838
4247
  }
4248
+ if (!structComponents) {
4249
+ const tupleComponents = buildTupleComponents(parameter.type, specEntries);
4250
+ if (tupleComponents && tupleComponents.length > 0) {
4251
+ structComponents = tupleComponents;
4252
+ }
4253
+ }
3839
4254
  const baseField = {
3840
4255
  id: `field-${Math.random().toString(36).substring(2, 9)}`,
3841
4256
  name: parameter.name || parameter.type,
@@ -3849,6 +4264,11 @@ function generateStellarDefaultField(parameter, contractSchema) {
3849
4264
  width: "full",
3850
4265
  options
3851
4266
  };
4267
+ baseField.validation = (0, import_ui_builder_utils26.enhanceNumericValidation)(
4268
+ baseField.validation,
4269
+ parameter.type,
4270
+ STELLAR_NUMERIC_BOUNDS
4271
+ );
3852
4272
  if (isBytesNType(parameter.type)) {
3853
4273
  const sizeMatch = parameter.type.match(/^BytesN<(\d+)>$/);
3854
4274
  const maxBytes = sizeMatch ? Number.parseInt(sizeMatch[1], 10) : void 0;
@@ -3859,17 +4279,50 @@ function generateStellarDefaultField(parameter, contractSchema) {
3859
4279
  };
3860
4280
  }
3861
4281
  }
3862
- if (fieldType === "array") {
4282
+ if (fieldType === "array" || fieldType === "array-object") {
3863
4283
  const elementType = extractVecElementType(parameter.type);
3864
4284
  if (elementType) {
3865
4285
  const elementFieldType = mapStellarParameterTypeToFieldType(elementType);
4286
+ let elementEnumMetadata;
4287
+ let elementComponents;
4288
+ let finalElementFieldType = elementFieldType;
4289
+ if (isLikelyEnumType(elementType)) {
4290
+ if (specEntries && isEnumType(specEntries, elementType)) {
4291
+ elementEnumMetadata = extractEnumVariants(specEntries, elementType) ?? void 0;
4292
+ if (elementEnumMetadata) {
4293
+ finalElementFieldType = elementEnumMetadata.isUnitOnly ? "select" : "enum";
4294
+ }
4295
+ }
4296
+ }
4297
+ if (specEntries && isStructType(specEntries, elementType)) {
4298
+ const structFields = extractStructFields(specEntries, elementType);
4299
+ if (structFields && structFields.length > 0) {
4300
+ elementComponents = structFields;
4301
+ finalElementFieldType = "object";
4302
+ }
4303
+ }
4304
+ if (fieldType === "array-object" && parameter.components) {
4305
+ elementComponents = parameter.components;
4306
+ finalElementFieldType = "object";
4307
+ }
4308
+ let elementValidation = { required: true };
4309
+ elementValidation = (0, import_ui_builder_utils26.enhanceNumericValidation)(
4310
+ elementValidation,
4311
+ elementType,
4312
+ STELLAR_NUMERIC_BOUNDS
4313
+ );
3866
4314
  const arrayField = {
3867
4315
  ...baseField,
3868
- elementType: elementFieldType,
4316
+ type: "array",
4317
+ // Always use 'array' as the field type
4318
+ elementType: finalElementFieldType,
3869
4319
  elementFieldConfig: {
3870
- type: elementFieldType,
3871
- validation: { required: true },
3872
- placeholder: `Enter ${elementType}`
4320
+ type: finalElementFieldType,
4321
+ validation: elementValidation,
4322
+ placeholder: `Enter ${elementType}`,
4323
+ originalParameterType: elementType,
4324
+ ...elementEnumMetadata && { enumMetadata: elementEnumMetadata },
4325
+ ...elementComponents && { components: elementComponents }
3873
4326
  }
3874
4327
  };
3875
4328
  return arrayField;
@@ -3887,13 +4340,21 @@ function generateStellarDefaultField(parameter, contractSchema) {
3887
4340
  valueType: valueFieldType,
3888
4341
  keyFieldConfig: {
3889
4342
  type: keyFieldType,
3890
- validation: { required: true },
4343
+ validation: (0, import_ui_builder_utils26.enhanceNumericValidation)(
4344
+ { required: true },
4345
+ mapTypes.keyType,
4346
+ STELLAR_NUMERIC_BOUNDS
4347
+ ),
3891
4348
  placeholder: `Enter ${mapTypes.keyType}`,
3892
4349
  originalParameterType: mapTypes.keyType
3893
4350
  },
3894
4351
  valueFieldConfig: {
3895
4352
  type: valueFieldType,
3896
- validation: { required: true },
4353
+ validation: (0, import_ui_builder_utils26.enhanceNumericValidation)(
4354
+ { required: true },
4355
+ mapTypes.valueType,
4356
+ STELLAR_NUMERIC_BOUNDS
4357
+ ),
3897
4358
  placeholder: `Enter ${mapTypes.valueType}`,
3898
4359
  originalParameterType: mapTypes.valueType
3899
4360
  }
@@ -3929,8 +4390,36 @@ function generateStellarDefaultField(parameter, contractSchema) {
3929
4390
 
3930
4391
  // src/transaction/formatter.ts
3931
4392
  var import_stellar_sdk14 = require("@stellar/stellar-sdk");
3932
- var import_ui_builder_types4 = require("@openzeppelin/ui-builder-types");
4393
+ var import_ui_builder_types5 = require("@openzeppelin/ui-builder-types");
3933
4394
  var import_ui_builder_utils27 = require("@openzeppelin/ui-builder-utils");
4395
+ function enrichParameterWithEnumMetadata(param, specEntries) {
4396
+ if (!specEntries) {
4397
+ return param;
4398
+ }
4399
+ const enriched = { ...param };
4400
+ if (isLikelyEnumType(param.type) && isEnumType(specEntries, param.type)) {
4401
+ const enumMetadata = extractEnumVariants(specEntries, param.type);
4402
+ if (enumMetadata) {
4403
+ enriched.enumMetadata = enumMetadata;
4404
+ }
4405
+ }
4406
+ const vecMatch = param.type.match(/^Vec<([^>]+)>$/);
4407
+ if (vecMatch) {
4408
+ const elementType = vecMatch[1];
4409
+ if (isLikelyEnumType(elementType) && isEnumType(specEntries, elementType)) {
4410
+ const enumMetadata = extractEnumVariants(specEntries, elementType);
4411
+ if (enumMetadata) {
4412
+ enriched.enumMetadata = enumMetadata;
4413
+ }
4414
+ }
4415
+ }
4416
+ if (enriched.components && enriched.components.length > 0) {
4417
+ enriched.components = enriched.components.map(
4418
+ (component) => enrichParameterWithEnumMetadata(component, specEntries)
4419
+ );
4420
+ }
4421
+ return enriched;
4422
+ }
3934
4423
  function formatStellarTransactionData(contractSchema, functionId, submittedInputs, fields) {
3935
4424
  import_ui_builder_utils27.logger.info(
3936
4425
  "formatStellarTransactionData",
@@ -3970,10 +4459,10 @@ function formatStellarTransactionData(contractSchema, functionId, submittedInput
3970
4459
  }
3971
4460
  const transformedArgs = expectedArgs.map((param, index) => {
3972
4461
  let valueToParse = orderedRawValues[index];
3973
- if ((0, import_ui_builder_types4.isEnumValue)(valueToParse)) {
3974
- const specEntries = contractSchema.metadata?.specEntries;
3975
- if (specEntries && isEnumType(specEntries, param.type)) {
3976
- const enumMetadata = extractEnumVariants(specEntries, param.type);
4462
+ if ((0, import_ui_builder_types5.isEnumValue)(valueToParse)) {
4463
+ const specEntries2 = contractSchema.metadata?.specEntries;
4464
+ if (specEntries2 && isEnumType(specEntries2, param.type)) {
4465
+ const enumMetadata = extractEnumVariants(specEntries2, param.type);
3977
4466
  const enumValue = valueToParse;
3978
4467
  if (enumMetadata && enumValue.values) {
3979
4468
  const selectedVariant = enumMetadata.variants.find((v) => v.name === enumValue.tag);
@@ -3981,14 +4470,15 @@ function formatStellarTransactionData(contractSchema, functionId, submittedInput
3981
4470
  const processedValues = enumValue.values.map(
3982
4471
  (rawValue, payloadIndex) => {
3983
4472
  const expectedType = selectedVariant.payloadTypes[payloadIndex];
3984
- if (expectedType) {
3985
- const processedValue = parseStellarInput(rawValue, expectedType);
3986
- return {
3987
- type: expectedType,
3988
- value: processedValue
3989
- };
4473
+ if (!expectedType) {
4474
+ return rawValue;
3990
4475
  }
3991
- return rawValue;
4476
+ const processedValue = parseStellarInput(rawValue, expectedType);
4477
+ const isPrimitivePayload = isPrimitiveParamType(expectedType) || isBytesNType(expectedType);
4478
+ if (isPrimitivePayload) {
4479
+ return { type: expectedType, value: processedValue };
4480
+ }
4481
+ return processedValue;
3992
4482
  }
3993
4483
  );
3994
4484
  valueToParse = { ...enumValue, values: processedValues };
@@ -4009,14 +4499,64 @@ function formatStellarTransactionData(contractSchema, functionId, submittedInput
4009
4499
  } catch {
4010
4500
  throw new Error("Contract address is missing or invalid in the provided schema.");
4011
4501
  }
4502
+ const fieldByName = /* @__PURE__ */ new Map();
4503
+ fields.forEach((field) => fieldByName.set(field.name, field));
4504
+ const specEntries = contractSchema.metadata?.specEntries;
4505
+ const argSchemaWithComponents = functionDetails.inputs.map((param) => {
4506
+ const field = fieldByName.get(param.name);
4507
+ const enhanced = { ...param };
4508
+ if (param.components && param.components.length > 0) {
4509
+ enhanced.components = param.components;
4510
+ } else if (field?.components && field.components.length > 0) {
4511
+ enhanced.components = field.components;
4512
+ }
4513
+ if (field?.enumMetadata) {
4514
+ enhanced.enumMetadata = field.enumMetadata;
4515
+ }
4516
+ if (param.type.startsWith("Vec<") && field?.elementFieldConfig) {
4517
+ if (field.elementFieldConfig.enumMetadata) {
4518
+ enhanced.enumMetadata = field.elementFieldConfig.enumMetadata;
4519
+ }
4520
+ if (field.elementFieldConfig.components) {
4521
+ enhanced.components = field.elementFieldConfig.components;
4522
+ }
4523
+ }
4524
+ if (enhanced.components && enhanced.components.length > 0) {
4525
+ enhanced.components = enhanced.components.map((component) => {
4526
+ const nestedFieldName = `${param.name}.${component.name}`;
4527
+ const nestedField = fieldByName.get(nestedFieldName);
4528
+ if (nestedField) {
4529
+ const enrichedComponent = { ...component };
4530
+ if (nestedField.enumMetadata) {
4531
+ enrichedComponent.enumMetadata = nestedField.enumMetadata;
4532
+ }
4533
+ if (nestedField.components) {
4534
+ enrichedComponent.components = nestedField.components;
4535
+ }
4536
+ if (component.type.startsWith("Vec<") && nestedField.elementFieldConfig) {
4537
+ if (nestedField.elementFieldConfig.enumMetadata) {
4538
+ enrichedComponent.enumMetadata = nestedField.elementFieldConfig.enumMetadata;
4539
+ }
4540
+ if (nestedField.elementFieldConfig.components) {
4541
+ enrichedComponent.components = nestedField.elementFieldConfig.components;
4542
+ }
4543
+ }
4544
+ return enrichedComponent;
4545
+ }
4546
+ return component;
4547
+ });
4548
+ }
4549
+ const finalEnhanced = enrichParameterWithEnumMetadata(enhanced, specEntries);
4550
+ return finalEnhanced;
4551
+ });
4012
4552
  const stellarTransactionData = {
4013
4553
  contractAddress: contractSchema.address,
4014
4554
  functionName: functionDetails.name,
4015
4555
  args: transformedArgs,
4016
4556
  argTypes: functionDetails.inputs.map((param) => param.type),
4017
4557
  // Include parameter types for ScVal conversion
4018
- argSchema: functionDetails.inputs,
4019
- // Include full parameter schema with struct field definitions
4558
+ argSchema: argSchemaWithComponents,
4559
+ // Include full parameter schema with struct/tuple field definitions
4020
4560
  transactionOptions: {
4021
4561
  // Add any Stellar-specific transaction options here
4022
4562
  // For example: fee, timeout, memo, etc.
@@ -4616,7 +5156,7 @@ var CustomAccountDisplay = ({ className }) => {
4616
5156
  };
4617
5157
 
4618
5158
  // src/wallet/utils/filterWalletComponents.ts
4619
- var import_ui_builder_types5 = require("@openzeppelin/ui-builder-types");
5159
+ var import_ui_builder_types6 = require("@openzeppelin/ui-builder-types");
4620
5160
  var import_ui_builder_utils35 = require("@openzeppelin/ui-builder-utils");
4621
5161
  function filterWalletComponents(allPossibleComponents, exclusions, kitName = "custom") {
4622
5162
  import_ui_builder_utils35.logger.debug(
@@ -4662,7 +5202,7 @@ function getComponentExclusionsFromConfig(kitConfig) {
4662
5202
  const componentsCfg = kitConfig.components;
4663
5203
  if (componentsCfg && typeof componentsCfg === "object" && "exclude" in componentsCfg && Array.isArray(componentsCfg.exclude)) {
4664
5204
  return componentsCfg.exclude.filter(
4665
- (key) => typeof key === "string" && import_ui_builder_types5.ECOSYSTEM_WALLET_COMPONENT_KEYS.includes(key)
5205
+ (key) => typeof key === "string" && import_ui_builder_types6.ECOSYSTEM_WALLET_COMPONENT_KEYS.includes(key)
4666
5206
  );
4667
5207
  }
4668
5208
  }
@@ -4758,7 +5298,7 @@ var StellarAdapter = class {
4758
5298
  constructor(networkConfig) {
4759
5299
  __publicField(this, "networkConfig");
4760
5300
  __publicField(this, "initialAppServiceKitName");
4761
- if (!(0, import_ui_builder_types6.isStellarNetworkConfig)(networkConfig)) {
5301
+ if (!(0, import_ui_builder_types7.isStellarNetworkConfig)(networkConfig)) {
4762
5302
  throw new Error("StellarAdapter requires a valid Stellar network configuration.");
4763
5303
  }
4764
5304
  this.networkConfig = networkConfig;