@openzeppelin/contracts-ui-builder-adapter-stellar
Version:
Stellar Adapter for Contracts UI Builder
97 lines (82 loc) • 2.71 kB
text/typescript
import { xdr } from '@stellar/stellar-sdk';
import type { FunctionParameter } from '@openzeppelin/contracts-ui-builder-types';
import { logger } from '@openzeppelin/contracts-ui-builder-utils';
// Import the type extraction utility from the shared utils module
import { extractSorobanTypeFromScSpec } from '../utils/type-detection';
/**
* Extracts struct field definitions from Stellar contract spec entries
*
* @param entries Array of ScSpecEntry from contract spec
* @param structName Name of the struct type to extract fields for
* @returns Array of FunctionParameter representing struct fields, or null if not found
*/
export function extractStructFields(
entries: xdr.ScSpecEntry[],
structName: string
): FunctionParameter[] | null {
try {
// Find the entry for the requested struct name
const entry = entries.find((e) => {
try {
return e.value().name().toString() === structName;
} catch {
return false;
}
});
if (!entry) {
return null;
}
const entryKind = entry.switch();
// Handle UDT Struct (like DemoStruct { id: u32, flag: bool, info: Symbol })
if (entryKind.value === xdr.ScSpecEntryKind.scSpecEntryUdtStructV0().value) {
const structUdt = entry.udtStructV0();
const fields = structUdt.fields();
const structFields: FunctionParameter[] = [];
for (const field of fields) {
const fieldName = field.name().toString();
const fieldType = extractSorobanTypeFromScSpec(field.type());
structFields.push({
name: fieldName,
type: fieldType,
});
}
return structFields;
}
return null;
} catch (error) {
logger.error(
'extractStructFields',
`Failed to extract struct fields for ${structName}:`,
error
);
return null;
}
}
/**
* Determines if a given type name is a struct type in the contract spec
*
* @param entries Array of ScSpecEntry from contract spec
* @param typeName Name of the type to check
* @returns true if the type is a struct, false otherwise
*/
export function isStructType(entries: xdr.ScSpecEntry[], typeName: string): boolean {
try {
const entry = entries.find((e) => {
try {
const entryName = e.value().name().toString();
return entryName === typeName;
} catch {
return false;
}
});
if (!entry) {
return false;
}
const entryKind = entry.switch();
const isStruct = entryKind.value === xdr.ScSpecEntryKind.scSpecEntryUdtStructV0().value;
return isStruct;
} catch (error) {
logger.error('isStructType', `Failed to check if ${typeName} is struct:`, error);
return false;
}
}