@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 +600 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +603 -59
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/mapping/enum-metadata.ts +75 -2
- package/src/mapping/field-generator.ts +103 -14
- package/src/mapping/struct-fields.ts +12 -2
- package/src/mapping/tuple-components.ts +43 -0
- package/src/transaction/formatter.ts +138 -10
- package/src/transform/parsers/index.ts +7 -0
- package/src/transform/parsers/scval-converter.ts +238 -21
- package/src/transform/parsers/struct-parser.ts +114 -8
- package/src/utils/input-parsing.ts +22 -5
- package/src/utils/safe-type-parser.ts +55 -0
- package/src/utils/stellar-types.ts +35 -0
- package/src/utils/xdr-ordering.ts +36 -0
package/dist/index.js
CHANGED
|
@@ -443,10 +443,17 @@ function extractStructFields(entries, structName) {
|
|
|
443
443
|
for (const field of fields) {
|
|
444
444
|
const fieldName = field.name().toString();
|
|
445
445
|
const fieldType = extractSorobanTypeFromScSpec(field.type());
|
|
446
|
-
|
|
446
|
+
const fieldParam = {
|
|
447
447
|
name: fieldName,
|
|
448
448
|
type: fieldType
|
|
449
|
-
}
|
|
449
|
+
};
|
|
450
|
+
if (isStructType(entries, fieldType)) {
|
|
451
|
+
const nestedFields = extractStructFields(entries, fieldType);
|
|
452
|
+
if (nestedFields && nestedFields.length > 0) {
|
|
453
|
+
fieldParam.components = nestedFields;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
structFields.push(fieldParam);
|
|
450
457
|
}
|
|
451
458
|
return structFields;
|
|
452
459
|
}
|
|
@@ -496,7 +503,7 @@ import {
|
|
|
496
503
|
import { logger as logger11, userRpcConfigService as userRpcConfigService2 } from "@openzeppelin/ui-builder-utils";
|
|
497
504
|
|
|
498
505
|
// src/transform/parsers/index.ts
|
|
499
|
-
import { isEnumValue as
|
|
506
|
+
import { isEnumValue as isEnumValue3 } from "@openzeppelin/ui-builder-types";
|
|
500
507
|
import { isPlainObject as isPlainObject2, logger as logger9 } from "@openzeppelin/ui-builder-utils";
|
|
501
508
|
|
|
502
509
|
// src/transform/parsers/generic-parser.ts
|
|
@@ -739,6 +746,20 @@ function extractOptionElementType(parameterType) {
|
|
|
739
746
|
}
|
|
740
747
|
return extractGenericInnerType(parameterType, "Option");
|
|
741
748
|
}
|
|
749
|
+
function extractTupleTypes(parameterType) {
|
|
750
|
+
if (!isValidTypeString(parameterType) || !parameterType.startsWith("Tuple<")) {
|
|
751
|
+
return null;
|
|
752
|
+
}
|
|
753
|
+
const innerContent = extractGenericInnerType(parameterType, "Tuple");
|
|
754
|
+
if (!innerContent) {
|
|
755
|
+
return null;
|
|
756
|
+
}
|
|
757
|
+
const parts = splitTopLevelTypes(innerContent);
|
|
758
|
+
if (parts.length === 0) {
|
|
759
|
+
return null;
|
|
760
|
+
}
|
|
761
|
+
return parts;
|
|
762
|
+
}
|
|
742
763
|
function extractGenericInnerType(parameterType, genericName) {
|
|
743
764
|
const prefix = `${genericName}<`;
|
|
744
765
|
if (!parameterType.startsWith(prefix) || !parameterType.endsWith(">")) {
|
|
@@ -812,6 +833,30 @@ function hasInvalidCharacters(str) {
|
|
|
812
833
|
}
|
|
813
834
|
return !/^[A-Za-z0-9<>,\s_]+$/.test(str);
|
|
814
835
|
}
|
|
836
|
+
function splitTopLevelTypes(content) {
|
|
837
|
+
const types = [];
|
|
838
|
+
let start = 0;
|
|
839
|
+
let level = 0;
|
|
840
|
+
for (let i = 0; i < content.length; i += 1) {
|
|
841
|
+
const char = content[i];
|
|
842
|
+
if (char === "<") {
|
|
843
|
+
level += 1;
|
|
844
|
+
} else if (char === ">") {
|
|
845
|
+
level -= 1;
|
|
846
|
+
} else if (char === "," && level === 0) {
|
|
847
|
+
const segment = content.slice(start, i).trim();
|
|
848
|
+
if (segment) {
|
|
849
|
+
types.push(segment);
|
|
850
|
+
}
|
|
851
|
+
start = i + 1;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
const lastSegment = content.slice(start).trim();
|
|
855
|
+
if (lastSegment) {
|
|
856
|
+
types.push(lastSegment);
|
|
857
|
+
}
|
|
858
|
+
return types;
|
|
859
|
+
}
|
|
815
860
|
|
|
816
861
|
// src/utils/formatting.ts
|
|
817
862
|
function stringifyWithBigInt(value, space) {
|
|
@@ -886,6 +931,34 @@ function convertStellarTypeToScValType(stellarType) {
|
|
|
886
931
|
// src/utils/input-parsing.ts
|
|
887
932
|
import { nativeToScVal, xdr as xdr3 } from "@stellar/stellar-sdk";
|
|
888
933
|
import { detectBytesEncoding as detectBytesEncoding2, logger as logger7, stringToBytes as stringToBytes2 } from "@openzeppelin/ui-builder-utils";
|
|
934
|
+
|
|
935
|
+
// src/utils/xdr-ordering.ts
|
|
936
|
+
function compareScValsByXdr(a, b) {
|
|
937
|
+
const aBytes = getBytes(a);
|
|
938
|
+
const bBytes = getBytes(b);
|
|
939
|
+
const minLength = Math.min(aBytes.length, bBytes.length);
|
|
940
|
+
for (let index = 0; index < minLength; index += 1) {
|
|
941
|
+
const diff = aBytes[index] - bBytes[index];
|
|
942
|
+
if (diff !== 0) {
|
|
943
|
+
return diff;
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
return aBytes.length - bBytes.length;
|
|
947
|
+
}
|
|
948
|
+
function getBytes(scVal) {
|
|
949
|
+
const xdrValue = scVal.toXDR();
|
|
950
|
+
if (xdrValue instanceof Uint8Array) {
|
|
951
|
+
return xdrValue;
|
|
952
|
+
}
|
|
953
|
+
const arrayLike = xdrValue;
|
|
954
|
+
const result = new Uint8Array(arrayLike.length);
|
|
955
|
+
for (let index = 0; index < arrayLike.length; index += 1) {
|
|
956
|
+
result[index] = arrayLike[index];
|
|
957
|
+
}
|
|
958
|
+
return result;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
// src/utils/input-parsing.ts
|
|
889
962
|
var SYSTEM_LOG_TAG4 = "StellarInputParsingUtils";
|
|
890
963
|
function isMapArray(argValue) {
|
|
891
964
|
try {
|
|
@@ -969,19 +1042,34 @@ function convertEnumToScVal(obj, scVals) {
|
|
|
969
1042
|
}
|
|
970
1043
|
function convertObjectToMap(mapArray) {
|
|
971
1044
|
try {
|
|
972
|
-
const
|
|
973
|
-
const
|
|
1045
|
+
const sortedEntries = [...mapArray].sort((a, b) => {
|
|
1046
|
+
const aKey = getScValFromPrimitive(a["0"]);
|
|
1047
|
+
const bKey = getScValFromPrimitive(b["0"]);
|
|
1048
|
+
return compareScValsByXdr(aKey, bKey);
|
|
1049
|
+
});
|
|
1050
|
+
const mapVal = sortedEntries.reduce((acc, pair) => {
|
|
1051
|
+
const key = String(pair["0"].value);
|
|
974
1052
|
if (Array.isArray(pair["1"])) {
|
|
975
1053
|
const valueScVal = getScValFromArg(pair["1"], []);
|
|
976
1054
|
acc[key] = valueScVal;
|
|
977
1055
|
} else {
|
|
978
1056
|
const value = pair["1"].value;
|
|
979
|
-
|
|
1057
|
+
if (pair["1"].type === "bool") {
|
|
1058
|
+
if (typeof value === "boolean") {
|
|
1059
|
+
acc[key] = value;
|
|
1060
|
+
} else if (typeof value === "string") {
|
|
1061
|
+
acc[key] = value === "true";
|
|
1062
|
+
} else {
|
|
1063
|
+
acc[key] = Boolean(value);
|
|
1064
|
+
}
|
|
1065
|
+
} else {
|
|
1066
|
+
acc[key] = value;
|
|
1067
|
+
}
|
|
980
1068
|
}
|
|
981
1069
|
return acc;
|
|
982
1070
|
}, {});
|
|
983
|
-
const mapType =
|
|
984
|
-
const key = pair["0"].value;
|
|
1071
|
+
const mapType = sortedEntries.reduce((acc, pair) => {
|
|
1072
|
+
const key = String(pair["0"].value);
|
|
985
1073
|
const keyTypeHint = convertStellarTypeToScValType(pair["0"].type);
|
|
986
1074
|
const valueTypeHint = convertStellarTypeToScValType(pair["1"].type);
|
|
987
1075
|
acc[key] = [
|
|
@@ -998,13 +1086,44 @@ function convertObjectToMap(mapArray) {
|
|
|
998
1086
|
}
|
|
999
1087
|
|
|
1000
1088
|
// src/transform/parsers/scval-converter.ts
|
|
1001
|
-
import { nativeToScVal as nativeToScVal4 } from "@stellar/stellar-sdk";
|
|
1002
|
-
import { isEnumValue } from "@openzeppelin/ui-builder-types";
|
|
1089
|
+
import { nativeToScVal as nativeToScVal4, xdr as xdr6 } from "@stellar/stellar-sdk";
|
|
1090
|
+
import { isEnumValue as isEnumValue2 } from "@openzeppelin/ui-builder-types";
|
|
1091
|
+
|
|
1092
|
+
// src/utils/stellar-types.ts
|
|
1093
|
+
var PRIMITIVE_STELLAR_TYPES = /* @__PURE__ */ new Set([
|
|
1094
|
+
"Bool",
|
|
1095
|
+
"ScString",
|
|
1096
|
+
"ScSymbol",
|
|
1097
|
+
"Address",
|
|
1098
|
+
"Bytes",
|
|
1099
|
+
"U8",
|
|
1100
|
+
"U16",
|
|
1101
|
+
"U32",
|
|
1102
|
+
"U64",
|
|
1103
|
+
"U128",
|
|
1104
|
+
"U256",
|
|
1105
|
+
"I8",
|
|
1106
|
+
"I16",
|
|
1107
|
+
"I32",
|
|
1108
|
+
"I64",
|
|
1109
|
+
"I128",
|
|
1110
|
+
"I256"
|
|
1111
|
+
]);
|
|
1112
|
+
function isPrimitiveParamType(type) {
|
|
1113
|
+
return PRIMITIVE_STELLAR_TYPES.has(type);
|
|
1114
|
+
}
|
|
1003
1115
|
|
|
1004
1116
|
// src/transform/parsers/struct-parser.ts
|
|
1005
|
-
import { nativeToScVal as nativeToScVal3 } from "@stellar/stellar-sdk";
|
|
1117
|
+
import { nativeToScVal as nativeToScVal3, xdr as xdr5 } from "@stellar/stellar-sdk";
|
|
1118
|
+
import { isEnumValue } from "@openzeppelin/ui-builder-types";
|
|
1006
1119
|
import { isPlainObject, logger as logger8 } from "@openzeppelin/ui-builder-utils";
|
|
1007
1120
|
var SYSTEM_LOG_TAG5 = "StructParser";
|
|
1121
|
+
function isTupleStructSchema(schema) {
|
|
1122
|
+
if (!schema?.components || schema.components.length === 0) {
|
|
1123
|
+
return false;
|
|
1124
|
+
}
|
|
1125
|
+
return schema.components.every((component, index) => component.name === index.toString());
|
|
1126
|
+
}
|
|
1008
1127
|
function needsParsing(value, fieldType) {
|
|
1009
1128
|
if ((fieldType === "Bytes" || fieldType.startsWith("BytesN<")) && value instanceof Uint8Array) {
|
|
1010
1129
|
return false;
|
|
@@ -1029,7 +1148,23 @@ function needsParsing(value, fieldType) {
|
|
|
1029
1148
|
}
|
|
1030
1149
|
return false;
|
|
1031
1150
|
}
|
|
1032
|
-
function convertStructToScVal(structObj, parameterType, paramSchema, parseInnerValue) {
|
|
1151
|
+
function convertStructToScVal(structObj, parameterType, paramSchema, parseInnerValue, convertToScVal) {
|
|
1152
|
+
if (isTupleStructSchema(paramSchema) && paramSchema && convertToScVal) {
|
|
1153
|
+
const tupleValues = paramSchema.components.map((component, index) => {
|
|
1154
|
+
const key = component.name ?? index.toString();
|
|
1155
|
+
let elementValue = structObj[key];
|
|
1156
|
+
if (typeof elementValue === "undefined") {
|
|
1157
|
+
throw new Error(
|
|
1158
|
+
`Missing tuple value for "${key}" in struct type "${parameterType}". Received: ${JSON.stringify(structObj)}`
|
|
1159
|
+
);
|
|
1160
|
+
}
|
|
1161
|
+
if (typeof elementValue === "string" && isLikelyEnumType(component.type)) {
|
|
1162
|
+
elementValue = { tag: elementValue };
|
|
1163
|
+
}
|
|
1164
|
+
return convertToScVal(elementValue, component.type, component, parseInnerValue);
|
|
1165
|
+
});
|
|
1166
|
+
return xdr5.ScVal.scvVec(tupleValues);
|
|
1167
|
+
}
|
|
1033
1168
|
const convertedValue = {};
|
|
1034
1169
|
const typeHints = {};
|
|
1035
1170
|
for (const [fieldName, fieldValue] of Object.entries(structObj)) {
|
|
@@ -1047,6 +1182,9 @@ function convertStructToScVal(structObj, parameterType, paramSchema, parseInnerV
|
|
|
1047
1182
|
} else {
|
|
1048
1183
|
parsedValue = fieldValue;
|
|
1049
1184
|
}
|
|
1185
|
+
if (typeof parsedValue === "string" && isLikelyEnumType(fieldType)) {
|
|
1186
|
+
parsedValue = { tag: parsedValue };
|
|
1187
|
+
}
|
|
1050
1188
|
if (fieldType.startsWith("Map<") && Array.isArray(parsedValue)) {
|
|
1051
1189
|
const mapTypeMatch = fieldType.match(/Map<(.+),\s*(.+)>$/);
|
|
1052
1190
|
const mapKeyType = mapTypeMatch ? mapTypeMatch[1] : "ScSymbol";
|
|
@@ -1068,10 +1206,21 @@ function convertStructToScVal(structObj, parameterType, paramSchema, parseInnerV
|
|
|
1068
1206
|
convertedValue[fieldName] = mapObject;
|
|
1069
1207
|
typeHints[fieldName] = ["symbol", mapTypeHints];
|
|
1070
1208
|
} else {
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1209
|
+
if (convertToScVal && (fieldType.startsWith("Vec<") || isEnumValue(parsedValue))) {
|
|
1210
|
+
const fieldSchema = paramSchema?.components?.find((c) => c.name === fieldName);
|
|
1211
|
+
convertedValue[fieldName] = convertToScVal(
|
|
1212
|
+
parsedValue,
|
|
1213
|
+
fieldType,
|
|
1214
|
+
fieldSchema,
|
|
1215
|
+
parseInnerValue
|
|
1216
|
+
);
|
|
1217
|
+
typeHints[fieldName] = ["symbol", "scval"];
|
|
1218
|
+
} else {
|
|
1219
|
+
convertedValue[fieldName] = parsedValue;
|
|
1220
|
+
const scValType = convertStellarTypeToScValType(fieldType);
|
|
1221
|
+
if (scValType !== "map-special") {
|
|
1222
|
+
typeHints[fieldName] = ["symbol", Array.isArray(scValType) ? scValType[0] : scValType];
|
|
1223
|
+
}
|
|
1075
1224
|
}
|
|
1076
1225
|
}
|
|
1077
1226
|
} else {
|
|
@@ -1085,7 +1234,40 @@ function convertStructToScVal(structObj, parameterType, paramSchema, parseInnerV
|
|
|
1085
1234
|
convertedValue,
|
|
1086
1235
|
typeHints
|
|
1087
1236
|
});
|
|
1088
|
-
const
|
|
1237
|
+
const hasEnumFields = paramSchema?.components?.some((comp) => {
|
|
1238
|
+
const fieldValue = convertedValue[comp.name];
|
|
1239
|
+
return isEnumValue(fieldValue);
|
|
1240
|
+
});
|
|
1241
|
+
let scVal;
|
|
1242
|
+
if (hasEnumFields && convertToScVal && paramSchema?.components) {
|
|
1243
|
+
const mapEntries = [];
|
|
1244
|
+
for (const fieldSchema of paramSchema.components) {
|
|
1245
|
+
const fieldName = fieldSchema.name;
|
|
1246
|
+
const fieldValue = convertedValue[fieldName];
|
|
1247
|
+
const keyScVal = nativeToScVal3(fieldName, { type: "symbol" });
|
|
1248
|
+
let valueScVal;
|
|
1249
|
+
if (isEnumValue(fieldValue)) {
|
|
1250
|
+
valueScVal = convertToScVal(fieldValue, fieldSchema.type, fieldSchema, parseInnerValue);
|
|
1251
|
+
} else {
|
|
1252
|
+
const fieldTypeHint = typeHints[fieldName];
|
|
1253
|
+
if (fieldTypeHint && Array.isArray(fieldTypeHint) && fieldTypeHint.length > 1) {
|
|
1254
|
+
valueScVal = nativeToScVal3(fieldValue, { type: fieldTypeHint[1] });
|
|
1255
|
+
} else {
|
|
1256
|
+
valueScVal = nativeToScVal3(fieldValue);
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
mapEntries.push(
|
|
1260
|
+
new xdr5.ScMapEntry({
|
|
1261
|
+
key: keyScVal,
|
|
1262
|
+
val: valueScVal
|
|
1263
|
+
})
|
|
1264
|
+
);
|
|
1265
|
+
}
|
|
1266
|
+
const sortedMapEntries = mapEntries.sort((a, b) => compareScValsByXdr(a.key(), b.key()));
|
|
1267
|
+
scVal = xdr5.ScVal.scvMap(sortedMapEntries);
|
|
1268
|
+
} else {
|
|
1269
|
+
scVal = nativeToScVal3(convertedValue, { type: typeHints });
|
|
1270
|
+
}
|
|
1089
1271
|
logger8.debug(SYSTEM_LOG_TAG5, "convertStructToScVal generated ScVal:", {
|
|
1090
1272
|
parameterType,
|
|
1091
1273
|
scValType: scVal.switch().name,
|
|
@@ -1112,16 +1294,95 @@ function isStructType2(value, parameterType) {
|
|
|
1112
1294
|
function valueToScVal(value, parameterType, paramSchema, parseInnerValue) {
|
|
1113
1295
|
const parseValue = parseInnerValue || ((val) => val);
|
|
1114
1296
|
const genericInfo = parseGenericType(parameterType);
|
|
1297
|
+
const isTypedWrapper = (v) => !!v && typeof v === "object" && "type" in v && "value" in v;
|
|
1298
|
+
const enumMetadata = paramSchema?.enumMetadata;
|
|
1299
|
+
const possibleEnumValue = typeof value === "string" && (enumMetadata || isLikelyEnumType(parameterType)) ? { tag: value } : value;
|
|
1115
1300
|
if (!genericInfo) {
|
|
1116
|
-
if (
|
|
1117
|
-
|
|
1301
|
+
if (enumMetadata && enumMetadata.variants.every((v) => v.type === "integer")) {
|
|
1302
|
+
let numericValue;
|
|
1303
|
+
if (typeof value === "string") {
|
|
1304
|
+
const byName = enumMetadata.variants.find((v) => v.name === value);
|
|
1305
|
+
numericValue = byName?.value ?? Number(value);
|
|
1306
|
+
} else if (typeof value === "number") {
|
|
1307
|
+
numericValue = value;
|
|
1308
|
+
} else if (isEnumValue2(value)) {
|
|
1309
|
+
const byTag = enumMetadata.variants.find((v) => v.name === value.tag);
|
|
1310
|
+
numericValue = byTag?.value;
|
|
1311
|
+
}
|
|
1312
|
+
if (numericValue === void 0 || Number.isNaN(numericValue)) {
|
|
1313
|
+
const validNames = enumMetadata.variants.map((v) => v.name).join(", ");
|
|
1314
|
+
throw new Error(
|
|
1315
|
+
`Invalid integer enum value for ${parameterType}: ${String(value)}. Expected one of: ${validNames}`
|
|
1316
|
+
);
|
|
1317
|
+
}
|
|
1318
|
+
return nativeToScVal4(numericValue, { type: "u32" });
|
|
1319
|
+
}
|
|
1320
|
+
if (isTypedWrapper(possibleEnumValue)) {
|
|
1321
|
+
const wrapped = possibleEnumValue;
|
|
1322
|
+
const parsed = parsePrimitive(wrapped.value, wrapped.type);
|
|
1323
|
+
const finalVal = parsed !== null ? parsed : wrapped.value;
|
|
1324
|
+
const scValType2 = convertStellarTypeToScValType(wrapped.type);
|
|
1325
|
+
const typeHint2 = Array.isArray(scValType2) ? scValType2[0] : scValType2;
|
|
1326
|
+
return nativeToScVal4(finalVal, { type: typeHint2 });
|
|
1327
|
+
}
|
|
1328
|
+
if (isEnumValue2(possibleEnumValue) || typeof possibleEnumValue === "object" && possibleEnumValue !== null && "enum" in possibleEnumValue) {
|
|
1329
|
+
const enumValue = possibleEnumValue;
|
|
1330
|
+
if ("enum" in enumValue && typeof enumValue.enum === "number") {
|
|
1331
|
+
return nativeToScVal4(enumValue.enum, { type: "u32" });
|
|
1332
|
+
}
|
|
1333
|
+
const tagSymbol = nativeToScVal4(enumValue.tag, { type: "symbol" });
|
|
1334
|
+
if (!enumValue.values || enumValue.values.length === 0) {
|
|
1335
|
+
return xdr6.ScVal.scvVec([tagSymbol]);
|
|
1336
|
+
}
|
|
1337
|
+
const payloadValues = enumValue.values;
|
|
1338
|
+
let payloadScVals;
|
|
1339
|
+
let variant;
|
|
1340
|
+
if (enumMetadata) {
|
|
1341
|
+
variant = enumMetadata.variants.find((variantEntry) => variantEntry.name === enumValue.tag);
|
|
1342
|
+
if (!variant || !variant.payloadTypes) {
|
|
1343
|
+
return convertEnumToScVal(enumValue);
|
|
1344
|
+
}
|
|
1345
|
+
const payloadTypes = variant.payloadTypes;
|
|
1346
|
+
const payloadComponents = variant.payloadComponents;
|
|
1347
|
+
payloadScVals = payloadTypes.map((payloadType, index) => {
|
|
1348
|
+
const payloadSchema = payloadComponents?.[index] ? {
|
|
1349
|
+
name: `payload_${index}`,
|
|
1350
|
+
type: payloadType,
|
|
1351
|
+
components: payloadComponents[index]
|
|
1352
|
+
} : { name: `payload_${index}`, type: payloadType };
|
|
1353
|
+
const val = payloadValues[index];
|
|
1354
|
+
return valueToScVal(val, payloadType, payloadSchema, parseValue);
|
|
1355
|
+
});
|
|
1356
|
+
} else {
|
|
1357
|
+
return convertEnumToScVal(enumValue);
|
|
1358
|
+
}
|
|
1359
|
+
if (variant?.isSingleTuplePayload) {
|
|
1360
|
+
const tuplePayloadVec = xdr6.ScVal.scvVec(payloadScVals);
|
|
1361
|
+
return xdr6.ScVal.scvVec([tagSymbol, tuplePayloadVec]);
|
|
1362
|
+
}
|
|
1363
|
+
return xdr6.ScVal.scvVec([tagSymbol, ...payloadScVals]);
|
|
1364
|
+
}
|
|
1365
|
+
if (Array.isArray(possibleEnumValue) && paramSchema?.components && paramSchema.components.length) {
|
|
1366
|
+
if (possibleEnumValue.length !== paramSchema.components.length) {
|
|
1367
|
+
throw new Error(
|
|
1368
|
+
`Tuple-struct value length (${possibleEnumValue.length}) does not match schema components (${paramSchema.components.length}) for type ${parameterType}`
|
|
1369
|
+
);
|
|
1370
|
+
}
|
|
1371
|
+
return convertStructToScVal(
|
|
1372
|
+
possibleEnumValue,
|
|
1373
|
+
parameterType,
|
|
1374
|
+
paramSchema,
|
|
1375
|
+
parseValue,
|
|
1376
|
+
(innerValue, innerType, innerSchema) => valueToScVal(innerValue, innerType, innerSchema, parseInnerValue)
|
|
1377
|
+
);
|
|
1118
1378
|
}
|
|
1119
|
-
if (isStructType2(value, parameterType)) {
|
|
1379
|
+
if (!isPrimitiveParamType(parameterType) && isStructType2(value, parameterType)) {
|
|
1120
1380
|
return convertStructToScVal(
|
|
1121
1381
|
value,
|
|
1122
1382
|
parameterType,
|
|
1123
1383
|
paramSchema,
|
|
1124
|
-
parseValue
|
|
1384
|
+
parseValue,
|
|
1385
|
+
(innerValue, innerType, innerSchema) => valueToScVal(innerValue, innerType, innerSchema, parseInnerValue)
|
|
1125
1386
|
);
|
|
1126
1387
|
}
|
|
1127
1388
|
if (parameterType === "Bool" || parameterType === "Bytes") {
|
|
@@ -1151,15 +1412,30 @@ function valueToScVal(value, parameterType, paramSchema, parseInnerValue) {
|
|
|
1151
1412
|
case "Vec": {
|
|
1152
1413
|
const innerType = parameters[0];
|
|
1153
1414
|
if (Array.isArray(value)) {
|
|
1154
|
-
|
|
1415
|
+
let elementSchema;
|
|
1416
|
+
if (enumMetadata) {
|
|
1417
|
+
elementSchema = {
|
|
1418
|
+
name: "element",
|
|
1419
|
+
type: innerType,
|
|
1420
|
+
enumMetadata
|
|
1421
|
+
};
|
|
1422
|
+
} else if (paramSchema?.components) {
|
|
1423
|
+
elementSchema = {
|
|
1424
|
+
name: "element",
|
|
1425
|
+
type: innerType,
|
|
1426
|
+
components: paramSchema.components
|
|
1427
|
+
};
|
|
1428
|
+
}
|
|
1429
|
+
const convertedElements = value.map(
|
|
1430
|
+
(element) => valueToScVal(element, innerType, elementSchema, parseValue)
|
|
1431
|
+
);
|
|
1155
1432
|
return nativeToScVal4(convertedElements);
|
|
1156
1433
|
}
|
|
1157
1434
|
return nativeToScVal4(value);
|
|
1158
1435
|
}
|
|
1159
1436
|
case "Map": {
|
|
1160
1437
|
if (Array.isArray(value)) {
|
|
1161
|
-
const
|
|
1162
|
-
const typeHints = {};
|
|
1438
|
+
const mapEntries = [];
|
|
1163
1439
|
value.forEach(
|
|
1164
1440
|
(entry) => {
|
|
1165
1441
|
if (typeof entry !== "object" || entry === null || !entry[0] || !entry[1] || typeof entry[0].value === "undefined" || typeof entry[1].value === "undefined") {
|
|
@@ -1175,26 +1451,74 @@ function valueToScVal(value, parameterType, paramSchema, parseInnerValue) {
|
|
|
1175
1451
|
if (valuePrimitive !== null) {
|
|
1176
1452
|
processedValue = valuePrimitive;
|
|
1177
1453
|
}
|
|
1178
|
-
const keyString = typeof processedKey === "string" ? processedKey : String(processedKey);
|
|
1179
|
-
convertedValue[keyString] = processedValue;
|
|
1180
1454
|
const keyScValType = convertStellarTypeToScValType(entry[0].type);
|
|
1455
|
+
const keyTypeHint = Array.isArray(keyScValType) ? keyScValType[0] : keyScValType;
|
|
1456
|
+
const keyScVal = nativeToScVal4(processedKey, { type: keyTypeHint });
|
|
1181
1457
|
const valueScValType = convertStellarTypeToScValType(entry[1].type);
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1458
|
+
const valueTypeHint = Array.isArray(valueScValType) ? valueScValType[0] : valueScValType;
|
|
1459
|
+
const valueScVal = nativeToScVal4(processedValue, { type: valueTypeHint });
|
|
1460
|
+
mapEntries.push(
|
|
1461
|
+
new xdr6.ScMapEntry({
|
|
1462
|
+
key: keyScVal,
|
|
1463
|
+
val: valueScVal
|
|
1464
|
+
})
|
|
1465
|
+
);
|
|
1186
1466
|
}
|
|
1187
1467
|
);
|
|
1188
|
-
|
|
1468
|
+
const sortedMapEntries = mapEntries.sort((a, b) => compareScValsByXdr(a.key(), b.key()));
|
|
1469
|
+
return xdr6.ScVal.scvMap(sortedMapEntries);
|
|
1189
1470
|
}
|
|
1190
1471
|
return nativeToScVal4(value);
|
|
1191
1472
|
}
|
|
1473
|
+
case "Tuple": {
|
|
1474
|
+
if (!paramSchema?.components || paramSchema.components.length === 0) {
|
|
1475
|
+
throw new Error(
|
|
1476
|
+
`Tuple parameter "${paramSchema?.name ?? "unknown"}" is missing component metadata`
|
|
1477
|
+
);
|
|
1478
|
+
}
|
|
1479
|
+
const tupleComponents = paramSchema.components;
|
|
1480
|
+
const tupleValues = [];
|
|
1481
|
+
tupleComponents.forEach((component, index) => {
|
|
1482
|
+
const key = component.name ?? `item_${index}`;
|
|
1483
|
+
let elementValue;
|
|
1484
|
+
if (Array.isArray(value)) {
|
|
1485
|
+
elementValue = value[index];
|
|
1486
|
+
} else if (value && typeof value === "object") {
|
|
1487
|
+
elementValue = value[key];
|
|
1488
|
+
}
|
|
1489
|
+
if (typeof elementValue === "undefined") {
|
|
1490
|
+
const expectedTypes = tupleComponents.map((c) => c.type).join(", ");
|
|
1491
|
+
throw new Error(
|
|
1492
|
+
`Missing tuple value for "${key}" in parameter "${paramSchema.name ?? "unknown"}". Expected ${tupleComponents.length} values of types [${expectedTypes}] but received: ${JSON.stringify(value)}`
|
|
1493
|
+
);
|
|
1494
|
+
}
|
|
1495
|
+
if (typeof elementValue === "string" && isLikelyEnumType(component.type)) {
|
|
1496
|
+
elementValue = { tag: elementValue };
|
|
1497
|
+
}
|
|
1498
|
+
tupleValues.push(valueToScVal(elementValue, component.type, component, parseInnerValue));
|
|
1499
|
+
});
|
|
1500
|
+
return xdr6.ScVal.scvVec(tupleValues);
|
|
1501
|
+
}
|
|
1192
1502
|
case "Option": {
|
|
1193
1503
|
const innerType = parameters[0];
|
|
1194
1504
|
if (value === null || value === void 0) {
|
|
1195
1505
|
return nativeToScVal4(null);
|
|
1196
1506
|
} else {
|
|
1197
|
-
|
|
1507
|
+
let innerSchema;
|
|
1508
|
+
if (enumMetadata) {
|
|
1509
|
+
innerSchema = {
|
|
1510
|
+
name: "inner",
|
|
1511
|
+
type: innerType,
|
|
1512
|
+
...{ enumMetadata }
|
|
1513
|
+
};
|
|
1514
|
+
} else if (paramSchema?.components) {
|
|
1515
|
+
innerSchema = {
|
|
1516
|
+
name: "inner",
|
|
1517
|
+
type: innerType,
|
|
1518
|
+
components: paramSchema.components
|
|
1519
|
+
};
|
|
1520
|
+
}
|
|
1521
|
+
return valueToScVal(value, innerType, innerSchema, parseInnerValue);
|
|
1198
1522
|
}
|
|
1199
1523
|
}
|
|
1200
1524
|
case "Result": {
|
|
@@ -1237,12 +1561,15 @@ function parseStellarInput(value, parameterType) {
|
|
|
1237
1561
|
const result = parseGeneric(value, parameterType, parseStellarInput);
|
|
1238
1562
|
return result;
|
|
1239
1563
|
}
|
|
1240
|
-
if (
|
|
1564
|
+
if (isEnumValue3(value) && isLikelyEnumType(parameterType)) {
|
|
1241
1565
|
return value;
|
|
1242
1566
|
}
|
|
1243
1567
|
if (isPlainObject2(value)) {
|
|
1244
1568
|
return value;
|
|
1245
1569
|
}
|
|
1570
|
+
if (Array.isArray(value)) {
|
|
1571
|
+
return value;
|
|
1572
|
+
}
|
|
1246
1573
|
if (typeof value === "string" || typeof value === "number") {
|
|
1247
1574
|
return value;
|
|
1248
1575
|
}
|
|
@@ -3681,11 +4008,69 @@ function getStellarCompatibleFieldTypes(parameterType) {
|
|
|
3681
4008
|
|
|
3682
4009
|
// src/mapping/field-generator.ts
|
|
3683
4010
|
import { startCase } from "lodash";
|
|
3684
|
-
import {
|
|
4011
|
+
import {
|
|
4012
|
+
enhanceNumericValidation,
|
|
4013
|
+
getDefaultValueForType,
|
|
4014
|
+
logger as logger25
|
|
4015
|
+
} from "@openzeppelin/ui-builder-utils";
|
|
3685
4016
|
|
|
3686
4017
|
// src/mapping/enum-metadata.ts
|
|
3687
4018
|
import { xdr as xdr11 } from "@stellar/stellar-sdk";
|
|
3688
4019
|
import { logger as logger24 } from "@openzeppelin/ui-builder-utils";
|
|
4020
|
+
|
|
4021
|
+
// src/mapping/tuple-components.ts
|
|
4022
|
+
function buildTupleComponents(parameterType, specEntries) {
|
|
4023
|
+
const tupleElements = extractTupleTypes(parameterType);
|
|
4024
|
+
if (!tupleElements || tupleElements.length === 0) {
|
|
4025
|
+
return null;
|
|
4026
|
+
}
|
|
4027
|
+
return tupleElements.map((elementType, index) => {
|
|
4028
|
+
let nestedComponents;
|
|
4029
|
+
if (specEntries && isStructType(specEntries, elementType)) {
|
|
4030
|
+
const structFields = extractStructFields(specEntries, elementType);
|
|
4031
|
+
if (structFields && structFields.length > 0) {
|
|
4032
|
+
nestedComponents = structFields;
|
|
4033
|
+
}
|
|
4034
|
+
} else if (elementType.startsWith("Tuple<")) {
|
|
4035
|
+
const tupleStruct = buildTupleComponents(elementType, specEntries);
|
|
4036
|
+
if (tupleStruct && tupleStruct.length > 0) {
|
|
4037
|
+
nestedComponents = tupleStruct;
|
|
4038
|
+
}
|
|
4039
|
+
}
|
|
4040
|
+
return {
|
|
4041
|
+
name: `item_${index}`,
|
|
4042
|
+
type: elementType,
|
|
4043
|
+
displayName: `Value ${index + 1} (${elementType})`,
|
|
4044
|
+
...nestedComponents && { components: nestedComponents }
|
|
4045
|
+
};
|
|
4046
|
+
});
|
|
4047
|
+
}
|
|
4048
|
+
|
|
4049
|
+
// src/mapping/enum-metadata.ts
|
|
4050
|
+
function flattenPayloadType(payloadType, entries, flattenedTypes, flattenedComponents) {
|
|
4051
|
+
if (payloadType.startsWith("Tuple<")) {
|
|
4052
|
+
const tupleComponents = buildTupleComponents(payloadType, entries);
|
|
4053
|
+
if (tupleComponents && tupleComponents.length > 0) {
|
|
4054
|
+
tupleComponents.forEach((component) => {
|
|
4055
|
+
flattenedTypes.push(component.type);
|
|
4056
|
+
if (isStructType(entries, component.type)) {
|
|
4057
|
+
flattenedComponents.push(extractStructFields(entries, component.type) ?? void 0);
|
|
4058
|
+
} else {
|
|
4059
|
+
flattenedComponents.push(component.components);
|
|
4060
|
+
}
|
|
4061
|
+
});
|
|
4062
|
+
} else {
|
|
4063
|
+
flattenedTypes.push(payloadType);
|
|
4064
|
+
flattenedComponents.push(void 0);
|
|
4065
|
+
}
|
|
4066
|
+
} else if (isStructType(entries, payloadType)) {
|
|
4067
|
+
flattenedTypes.push(payloadType);
|
|
4068
|
+
flattenedComponents.push(extractStructFields(entries, payloadType) ?? void 0);
|
|
4069
|
+
} else {
|
|
4070
|
+
flattenedTypes.push(payloadType);
|
|
4071
|
+
flattenedComponents.push(void 0);
|
|
4072
|
+
}
|
|
4073
|
+
}
|
|
3689
4074
|
function extractEnumVariants(entries, enumName) {
|
|
3690
4075
|
try {
|
|
3691
4076
|
const entry = entries.find((e) => {
|
|
@@ -3714,11 +4099,29 @@ function extractEnumVariants(entries, enumName) {
|
|
|
3714
4099
|
});
|
|
3715
4100
|
} else if (caseKind.value === xdr11.ScSpecUdtUnionCaseV0Kind.scSpecUdtUnionCaseTupleV0().value) {
|
|
3716
4101
|
const tupleCase = caseEntry.tupleCase();
|
|
3717
|
-
const
|
|
4102
|
+
const rawPayloadTypes = tupleCase.type().map((typeDef) => extractSorobanTypeFromScSpec(typeDef));
|
|
4103
|
+
const isSingleTuplePayload = rawPayloadTypes.length === 1 && rawPayloadTypes[0].startsWith("Tuple<");
|
|
4104
|
+
const flattenedPayloadTypes = [];
|
|
4105
|
+
const flattenedPayloadComponents = [];
|
|
4106
|
+
for (const payloadType of rawPayloadTypes) {
|
|
4107
|
+
flattenPayloadType(
|
|
4108
|
+
payloadType,
|
|
4109
|
+
entries,
|
|
4110
|
+
flattenedPayloadTypes,
|
|
4111
|
+
flattenedPayloadComponents
|
|
4112
|
+
);
|
|
4113
|
+
}
|
|
3718
4114
|
variants.push({
|
|
3719
4115
|
name: tupleCase.name().toString(),
|
|
3720
4116
|
type: "tuple",
|
|
3721
|
-
payloadTypes
|
|
4117
|
+
payloadTypes: flattenedPayloadTypes,
|
|
4118
|
+
...flattenedPayloadComponents.some(
|
|
4119
|
+
(components) => components && components.length > 0
|
|
4120
|
+
) && {
|
|
4121
|
+
payloadComponents: flattenedPayloadComponents
|
|
4122
|
+
},
|
|
4123
|
+
// Store metadata about whether this needs tuple wrapping during serialization
|
|
4124
|
+
...isSingleTuplePayload && { isSingleTuplePayload: true }
|
|
3722
4125
|
});
|
|
3723
4126
|
isUnitOnly = false;
|
|
3724
4127
|
}
|
|
@@ -3779,6 +4182,14 @@ function isEnumType(entries, typeName) {
|
|
|
3779
4182
|
function getDefaultValidationForType() {
|
|
3780
4183
|
return { required: true };
|
|
3781
4184
|
}
|
|
4185
|
+
var STELLAR_NUMERIC_BOUNDS = {
|
|
4186
|
+
U8: { min: 0, max: 255 },
|
|
4187
|
+
U16: { min: 0, max: 65535 },
|
|
4188
|
+
U32: { min: 0, max: 4294967295 },
|
|
4189
|
+
I8: { min: -128, max: 127 },
|
|
4190
|
+
I16: { min: -32768, max: 32767 },
|
|
4191
|
+
I32: { min: -2147483648, max: 2147483647 }
|
|
4192
|
+
};
|
|
3782
4193
|
function generateStellarDefaultField(parameter, contractSchema) {
|
|
3783
4194
|
const specEntries = contractSchema?.metadata?.specEntries;
|
|
3784
4195
|
const fieldType = mapStellarParameterTypeToFieldType(parameter.type);
|
|
@@ -3792,8 +4203,10 @@ function generateStellarDefaultField(parameter, contractSchema) {
|
|
|
3792
4203
|
let structComponents = null;
|
|
3793
4204
|
let finalFieldType = fieldType;
|
|
3794
4205
|
let options;
|
|
3795
|
-
|
|
3796
|
-
|
|
4206
|
+
const enumDetectedBySpec = !!(specEntries && isEnumType(specEntries, parameter.type));
|
|
4207
|
+
const enumDetectedHeuristic = isLikelyEnumType(parameter.type);
|
|
4208
|
+
if (enumDetectedBySpec || enumDetectedHeuristic) {
|
|
4209
|
+
if (enumDetectedBySpec) {
|
|
3797
4210
|
enumMetadata = extractEnumVariants(specEntries, parameter.type);
|
|
3798
4211
|
if (enumMetadata) {
|
|
3799
4212
|
if (enumMetadata.isUnitOnly) {
|
|
@@ -3822,6 +4235,12 @@ function generateStellarDefaultField(parameter, contractSchema) {
|
|
|
3822
4235
|
structComponents = structFields;
|
|
3823
4236
|
}
|
|
3824
4237
|
}
|
|
4238
|
+
if (!structComponents) {
|
|
4239
|
+
const tupleComponents = buildTupleComponents(parameter.type, specEntries);
|
|
4240
|
+
if (tupleComponents && tupleComponents.length > 0) {
|
|
4241
|
+
structComponents = tupleComponents;
|
|
4242
|
+
}
|
|
4243
|
+
}
|
|
3825
4244
|
const baseField = {
|
|
3826
4245
|
id: `field-${Math.random().toString(36).substring(2, 9)}`,
|
|
3827
4246
|
name: parameter.name || parameter.type,
|
|
@@ -3835,6 +4254,11 @@ function generateStellarDefaultField(parameter, contractSchema) {
|
|
|
3835
4254
|
width: "full",
|
|
3836
4255
|
options
|
|
3837
4256
|
};
|
|
4257
|
+
baseField.validation = enhanceNumericValidation(
|
|
4258
|
+
baseField.validation,
|
|
4259
|
+
parameter.type,
|
|
4260
|
+
STELLAR_NUMERIC_BOUNDS
|
|
4261
|
+
);
|
|
3838
4262
|
if (isBytesNType(parameter.type)) {
|
|
3839
4263
|
const sizeMatch = parameter.type.match(/^BytesN<(\d+)>$/);
|
|
3840
4264
|
const maxBytes = sizeMatch ? Number.parseInt(sizeMatch[1], 10) : void 0;
|
|
@@ -3845,17 +4269,50 @@ function generateStellarDefaultField(parameter, contractSchema) {
|
|
|
3845
4269
|
};
|
|
3846
4270
|
}
|
|
3847
4271
|
}
|
|
3848
|
-
if (fieldType === "array") {
|
|
4272
|
+
if (fieldType === "array" || fieldType === "array-object") {
|
|
3849
4273
|
const elementType = extractVecElementType(parameter.type);
|
|
3850
4274
|
if (elementType) {
|
|
3851
4275
|
const elementFieldType = mapStellarParameterTypeToFieldType(elementType);
|
|
4276
|
+
let elementEnumMetadata;
|
|
4277
|
+
let elementComponents;
|
|
4278
|
+
let finalElementFieldType = elementFieldType;
|
|
4279
|
+
if (isLikelyEnumType(elementType)) {
|
|
4280
|
+
if (specEntries && isEnumType(specEntries, elementType)) {
|
|
4281
|
+
elementEnumMetadata = extractEnumVariants(specEntries, elementType) ?? void 0;
|
|
4282
|
+
if (elementEnumMetadata) {
|
|
4283
|
+
finalElementFieldType = elementEnumMetadata.isUnitOnly ? "select" : "enum";
|
|
4284
|
+
}
|
|
4285
|
+
}
|
|
4286
|
+
}
|
|
4287
|
+
if (specEntries && isStructType(specEntries, elementType)) {
|
|
4288
|
+
const structFields = extractStructFields(specEntries, elementType);
|
|
4289
|
+
if (structFields && structFields.length > 0) {
|
|
4290
|
+
elementComponents = structFields;
|
|
4291
|
+
finalElementFieldType = "object";
|
|
4292
|
+
}
|
|
4293
|
+
}
|
|
4294
|
+
if (fieldType === "array-object" && parameter.components) {
|
|
4295
|
+
elementComponents = parameter.components;
|
|
4296
|
+
finalElementFieldType = "object";
|
|
4297
|
+
}
|
|
4298
|
+
let elementValidation = { required: true };
|
|
4299
|
+
elementValidation = enhanceNumericValidation(
|
|
4300
|
+
elementValidation,
|
|
4301
|
+
elementType,
|
|
4302
|
+
STELLAR_NUMERIC_BOUNDS
|
|
4303
|
+
);
|
|
3852
4304
|
const arrayField = {
|
|
3853
4305
|
...baseField,
|
|
3854
|
-
|
|
4306
|
+
type: "array",
|
|
4307
|
+
// Always use 'array' as the field type
|
|
4308
|
+
elementType: finalElementFieldType,
|
|
3855
4309
|
elementFieldConfig: {
|
|
3856
|
-
type:
|
|
3857
|
-
validation:
|
|
3858
|
-
placeholder: `Enter ${elementType}
|
|
4310
|
+
type: finalElementFieldType,
|
|
4311
|
+
validation: elementValidation,
|
|
4312
|
+
placeholder: `Enter ${elementType}`,
|
|
4313
|
+
originalParameterType: elementType,
|
|
4314
|
+
...elementEnumMetadata && { enumMetadata: elementEnumMetadata },
|
|
4315
|
+
...elementComponents && { components: elementComponents }
|
|
3859
4316
|
}
|
|
3860
4317
|
};
|
|
3861
4318
|
return arrayField;
|
|
@@ -3873,13 +4330,21 @@ function generateStellarDefaultField(parameter, contractSchema) {
|
|
|
3873
4330
|
valueType: valueFieldType,
|
|
3874
4331
|
keyFieldConfig: {
|
|
3875
4332
|
type: keyFieldType,
|
|
3876
|
-
validation:
|
|
4333
|
+
validation: enhanceNumericValidation(
|
|
4334
|
+
{ required: true },
|
|
4335
|
+
mapTypes.keyType,
|
|
4336
|
+
STELLAR_NUMERIC_BOUNDS
|
|
4337
|
+
),
|
|
3877
4338
|
placeholder: `Enter ${mapTypes.keyType}`,
|
|
3878
4339
|
originalParameterType: mapTypes.keyType
|
|
3879
4340
|
},
|
|
3880
4341
|
valueFieldConfig: {
|
|
3881
4342
|
type: valueFieldType,
|
|
3882
|
-
validation:
|
|
4343
|
+
validation: enhanceNumericValidation(
|
|
4344
|
+
{ required: true },
|
|
4345
|
+
mapTypes.valueType,
|
|
4346
|
+
STELLAR_NUMERIC_BOUNDS
|
|
4347
|
+
),
|
|
3883
4348
|
placeholder: `Enter ${mapTypes.valueType}`,
|
|
3884
4349
|
originalParameterType: mapTypes.valueType
|
|
3885
4350
|
}
|
|
@@ -3915,8 +4380,36 @@ function generateStellarDefaultField(parameter, contractSchema) {
|
|
|
3915
4380
|
|
|
3916
4381
|
// src/transaction/formatter.ts
|
|
3917
4382
|
import { Address as Address3 } from "@stellar/stellar-sdk";
|
|
3918
|
-
import { isEnumValue as
|
|
4383
|
+
import { isEnumValue as isEnumValue4 } from "@openzeppelin/ui-builder-types";
|
|
3919
4384
|
import { logger as logger26 } from "@openzeppelin/ui-builder-utils";
|
|
4385
|
+
function enrichParameterWithEnumMetadata(param, specEntries) {
|
|
4386
|
+
if (!specEntries) {
|
|
4387
|
+
return param;
|
|
4388
|
+
}
|
|
4389
|
+
const enriched = { ...param };
|
|
4390
|
+
if (isLikelyEnumType(param.type) && isEnumType(specEntries, param.type)) {
|
|
4391
|
+
const enumMetadata = extractEnumVariants(specEntries, param.type);
|
|
4392
|
+
if (enumMetadata) {
|
|
4393
|
+
enriched.enumMetadata = enumMetadata;
|
|
4394
|
+
}
|
|
4395
|
+
}
|
|
4396
|
+
const vecMatch = param.type.match(/^Vec<([^>]+)>$/);
|
|
4397
|
+
if (vecMatch) {
|
|
4398
|
+
const elementType = vecMatch[1];
|
|
4399
|
+
if (isLikelyEnumType(elementType) && isEnumType(specEntries, elementType)) {
|
|
4400
|
+
const enumMetadata = extractEnumVariants(specEntries, elementType);
|
|
4401
|
+
if (enumMetadata) {
|
|
4402
|
+
enriched.enumMetadata = enumMetadata;
|
|
4403
|
+
}
|
|
4404
|
+
}
|
|
4405
|
+
}
|
|
4406
|
+
if (enriched.components && enriched.components.length > 0) {
|
|
4407
|
+
enriched.components = enriched.components.map(
|
|
4408
|
+
(component) => enrichParameterWithEnumMetadata(component, specEntries)
|
|
4409
|
+
);
|
|
4410
|
+
}
|
|
4411
|
+
return enriched;
|
|
4412
|
+
}
|
|
3920
4413
|
function formatStellarTransactionData(contractSchema, functionId, submittedInputs, fields) {
|
|
3921
4414
|
logger26.info(
|
|
3922
4415
|
"formatStellarTransactionData",
|
|
@@ -3956,10 +4449,10 @@ function formatStellarTransactionData(contractSchema, functionId, submittedInput
|
|
|
3956
4449
|
}
|
|
3957
4450
|
const transformedArgs = expectedArgs.map((param, index) => {
|
|
3958
4451
|
let valueToParse = orderedRawValues[index];
|
|
3959
|
-
if (
|
|
3960
|
-
const
|
|
3961
|
-
if (
|
|
3962
|
-
const enumMetadata = extractEnumVariants(
|
|
4452
|
+
if (isEnumValue4(valueToParse)) {
|
|
4453
|
+
const specEntries2 = contractSchema.metadata?.specEntries;
|
|
4454
|
+
if (specEntries2 && isEnumType(specEntries2, param.type)) {
|
|
4455
|
+
const enumMetadata = extractEnumVariants(specEntries2, param.type);
|
|
3963
4456
|
const enumValue = valueToParse;
|
|
3964
4457
|
if (enumMetadata && enumValue.values) {
|
|
3965
4458
|
const selectedVariant = enumMetadata.variants.find((v) => v.name === enumValue.tag);
|
|
@@ -3967,14 +4460,15 @@ function formatStellarTransactionData(contractSchema, functionId, submittedInput
|
|
|
3967
4460
|
const processedValues = enumValue.values.map(
|
|
3968
4461
|
(rawValue, payloadIndex) => {
|
|
3969
4462
|
const expectedType = selectedVariant.payloadTypes[payloadIndex];
|
|
3970
|
-
if (expectedType) {
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
4463
|
+
if (!expectedType) {
|
|
4464
|
+
return rawValue;
|
|
4465
|
+
}
|
|
4466
|
+
const processedValue = parseStellarInput(rawValue, expectedType);
|
|
4467
|
+
const isPrimitivePayload = isPrimitiveParamType(expectedType) || isBytesNType(expectedType);
|
|
4468
|
+
if (isPrimitivePayload) {
|
|
4469
|
+
return { type: expectedType, value: processedValue };
|
|
3976
4470
|
}
|
|
3977
|
-
return
|
|
4471
|
+
return processedValue;
|
|
3978
4472
|
}
|
|
3979
4473
|
);
|
|
3980
4474
|
valueToParse = { ...enumValue, values: processedValues };
|
|
@@ -3995,14 +4489,64 @@ function formatStellarTransactionData(contractSchema, functionId, submittedInput
|
|
|
3995
4489
|
} catch {
|
|
3996
4490
|
throw new Error("Contract address is missing or invalid in the provided schema.");
|
|
3997
4491
|
}
|
|
4492
|
+
const fieldByName = /* @__PURE__ */ new Map();
|
|
4493
|
+
fields.forEach((field) => fieldByName.set(field.name, field));
|
|
4494
|
+
const specEntries = contractSchema.metadata?.specEntries;
|
|
4495
|
+
const argSchemaWithComponents = functionDetails.inputs.map((param) => {
|
|
4496
|
+
const field = fieldByName.get(param.name);
|
|
4497
|
+
const enhanced = { ...param };
|
|
4498
|
+
if (param.components && param.components.length > 0) {
|
|
4499
|
+
enhanced.components = param.components;
|
|
4500
|
+
} else if (field?.components && field.components.length > 0) {
|
|
4501
|
+
enhanced.components = field.components;
|
|
4502
|
+
}
|
|
4503
|
+
if (field?.enumMetadata) {
|
|
4504
|
+
enhanced.enumMetadata = field.enumMetadata;
|
|
4505
|
+
}
|
|
4506
|
+
if (param.type.startsWith("Vec<") && field?.elementFieldConfig) {
|
|
4507
|
+
if (field.elementFieldConfig.enumMetadata) {
|
|
4508
|
+
enhanced.enumMetadata = field.elementFieldConfig.enumMetadata;
|
|
4509
|
+
}
|
|
4510
|
+
if (field.elementFieldConfig.components) {
|
|
4511
|
+
enhanced.components = field.elementFieldConfig.components;
|
|
4512
|
+
}
|
|
4513
|
+
}
|
|
4514
|
+
if (enhanced.components && enhanced.components.length > 0) {
|
|
4515
|
+
enhanced.components = enhanced.components.map((component) => {
|
|
4516
|
+
const nestedFieldName = `${param.name}.${component.name}`;
|
|
4517
|
+
const nestedField = fieldByName.get(nestedFieldName);
|
|
4518
|
+
if (nestedField) {
|
|
4519
|
+
const enrichedComponent = { ...component };
|
|
4520
|
+
if (nestedField.enumMetadata) {
|
|
4521
|
+
enrichedComponent.enumMetadata = nestedField.enumMetadata;
|
|
4522
|
+
}
|
|
4523
|
+
if (nestedField.components) {
|
|
4524
|
+
enrichedComponent.components = nestedField.components;
|
|
4525
|
+
}
|
|
4526
|
+
if (component.type.startsWith("Vec<") && nestedField.elementFieldConfig) {
|
|
4527
|
+
if (nestedField.elementFieldConfig.enumMetadata) {
|
|
4528
|
+
enrichedComponent.enumMetadata = nestedField.elementFieldConfig.enumMetadata;
|
|
4529
|
+
}
|
|
4530
|
+
if (nestedField.elementFieldConfig.components) {
|
|
4531
|
+
enrichedComponent.components = nestedField.elementFieldConfig.components;
|
|
4532
|
+
}
|
|
4533
|
+
}
|
|
4534
|
+
return enrichedComponent;
|
|
4535
|
+
}
|
|
4536
|
+
return component;
|
|
4537
|
+
});
|
|
4538
|
+
}
|
|
4539
|
+
const finalEnhanced = enrichParameterWithEnumMetadata(enhanced, specEntries);
|
|
4540
|
+
return finalEnhanced;
|
|
4541
|
+
});
|
|
3998
4542
|
const stellarTransactionData = {
|
|
3999
4543
|
contractAddress: contractSchema.address,
|
|
4000
4544
|
functionName: functionDetails.name,
|
|
4001
4545
|
args: transformedArgs,
|
|
4002
4546
|
argTypes: functionDetails.inputs.map((param) => param.type),
|
|
4003
4547
|
// Include parameter types for ScVal conversion
|
|
4004
|
-
argSchema:
|
|
4005
|
-
// Include full parameter schema with struct field definitions
|
|
4548
|
+
argSchema: argSchemaWithComponents,
|
|
4549
|
+
// Include full parameter schema with struct/tuple field definitions
|
|
4006
4550
|
transactionOptions: {
|
|
4007
4551
|
// Add any Stellar-specific transaction options here
|
|
4008
4552
|
// For example: fee, timeout, memo, etc.
|