suix_getDynamicFields - Query Dynamic Ob...
Query dynamic object fields on Sui blockchain. Access dynamic field data and nested object structures with Dwellir's high-performance Sui RPC infrastructure.
Returns the list of dynamic field objects owned by an object on the Sui network.
Overview
The suix_getDynamicFields method allows you to query dynamic fields attached to any Sui object. Dynamic fields provide a way to add heterogeneous data to objects after creation, enabling flexible data structures and extensible object designs. This method is essential for exploring complex object hierarchies and understanding object relationships in Sui applications.
Code Examples
Practical Examples
Dynamic Field Manager
class DynamicFieldManager {
constructor(client) {
this.client = client;
this.fieldCache = new Map();
}
async getFieldsStructure(parentId, useCache = true) {
const cacheKey = `fields_${parentId}`;
if (useCache && this.fieldCache.has(cacheKey)) {
return this.fieldCache.get(cacheKey);
}
const fields = await this.getAllDynamicFields(parentId);
const structure = {
parentId: parentId,
totalFields: fields.length,
fieldsByType: this.groupFieldsByType(fields),
fieldsByName: this.groupFieldsByName(fields),
metadata: {
lastUpdated: Date.now(),
versions: fields.map(f => parseInt(f.version))
}
};
if (useCache) {
this.fieldCache.set(cacheKey, structure);
}
return structure;
}
groupFieldsByType(fields) {
return fields.reduce((acc, field) => {
const type = field.objectType;
if (!acc[type]) {
acc[type] = [];
}
acc[type].push(field);
return acc;
}, {});
}
groupFieldsByName(fields) {
return fields.reduce((acc, field) => {
const nameKey = this.getFieldNameKey(field.name);
acc[nameKey] = field;
return acc;
}, {});
}
getFieldNameKey(name) {
if (typeof name === 'string') return name;
if (name && name.value) return name.value.toString();
return JSON.stringify(name);
}
async getAllDynamicFields(parentId) {
let allFields = [];
let cursor = null;
let hasNextPage = true;
while (hasNextPage) {
const result = await this.client.getDynamicFields({
parentId: parentId,
cursor: cursor,
limit: 50
});
allFields = allFields.concat(result.data);
cursor = result.nextCursor;
hasNextPage = result.hasNextPage;
}
return allFields;
}
}Field Value Resolver
class FieldValueResolver {
constructor(client) {
this.client = client;
this.valueCache = new Map();
}
async resolveFieldValues(parentId, fieldNames = []) {
const fields = await this.client.getDynamicFields({ parentId });
const resolved = {};
for (const field of fields.data) {
const nameKey = this.getFieldNameKey(field.name);
// If specific fields requested, filter
if (fieldNames.length > 0 && !fieldNames.includes(nameKey)) {
continue;
}
try {
const value = await this.getFieldValue(field.objectId);
resolved[nameKey] = {
field: field,
value: value,
resolved: true
};
} catch (error) {
resolved[nameKey] = {
field: field,
error: error.message,
resolved: false
};
}
}
return resolved;
}
async getFieldValue(fieldObjectId, useCache = true) {
if (useCache && this.valueCache.has(fieldObjectId)) {
return this.valueCache.get(fieldObjectId);
}
const fieldObject = await this.client.getObject({
id: fieldObjectId,
options: {
showType: true,
showContent: true,
showBcs: true
}
});
if (fieldObject && fieldObject.data) {
if (useCache) {
this.valueCache.set(fieldObjectId, fieldObject.data);
}
return fieldObject.data;
}
return null;
}
getFieldNameKey(name) {
if (typeof name === 'string') return name;
if (name && name.value !== undefined) return name.value.toString();
return JSON.stringify(name);
}
}Dynamic Object Inspector
class DynamicObjectInspector {
constructor(client) {
this.client = client;
}
async inspectObject(objectId, options = {}) {
const {
includeFieldValues = false,
maxFieldsToInspect = 20,
includeTypeAnalysis = true
} = options;
try {
// Get object info
const objectInfo = await this.client.getObject({
id: objectId,
options: { showType: true, showContent: true }
});
// Get dynamic fields
const fieldsResult = await this.client.getDynamicFields({
parentId: objectId,
limit: maxFieldsToInspect
});
const inspection = {
objectId: objectId,
objectType: objectInfo.data?.type,
objectVersion: objectInfo.data?.version,
dynamicFieldsCount: fieldsResult.data.length,
hasMoreFields: fieldsResult.hasNextPage,
fields: fieldsResult.data
};
if (includeTypeAnalysis) {
inspection.typeAnalysis = this.analyzeFieldTypes(fieldsResult.data);
}
if (includeFieldValues) {
inspection.fieldValues = {};
for (const field of fieldsResult.data.slice(0, 10)) { // Limit to first 10
try {
const value = await this.client.getObject({
id: field.objectId,
options: { showContent: true }
});
const nameKey = this.getFieldNameKey(field.name);
inspection.fieldValues[nameKey] = value.data;
} catch (error) {
console.warn(`Failed to get value for field ${field.objectId}:`, error);
}
}
}
return inspection;
} catch (error) {
return {
objectId: objectId,
error: error.message,
timestamp: Date.now()
};
}
}
analyzeFieldTypes(fields) {
const typeCount = {};
const nameTypes = {};
fields.forEach(field => {
// Count object types
const objType = field.objectType;
typeCount[objType] = (typeCount[objType] || 0) + 1;
// Analyze name types
const nameType = typeof field.name === 'object' ?
field.name.type || 'object' : typeof field.name;
nameTypes[nameType] = (nameTypes[nameType] || 0) + 1;
});
return {
objectTypes: typeCount,
nameTypes: nameTypes,
totalFields: fields.length,
uniqueTypes: Object.keys(typeCount).length
};
}
getFieldNameKey(name) {
if (typeof name === 'string') return name;
if (name && name.value !== undefined) return name.value.toString();
return JSON.stringify(name);
}
async compareObjects(objectIds) {
const comparisons = [];
for (const objectId of objectIds) {
const inspection = await this.inspectObject(objectId, {
includeTypeAnalysis: true,
includeFieldValues: false
});
comparisons.push(inspection);
}
return {
objects: comparisons,
comparison: {
totalObjects: comparisons.length,
averageFieldsPerObject: comparisons.reduce(
(sum, obj) => sum + (obj.dynamicFieldsCount || 0), 0
) / comparisons.length,
commonTypes: this.findCommonTypes(comparisons),
uniquePatterns: this.findUniquePatterns(comparisons)
}
};
}
findCommonTypes(comparisons) {
const allTypes = new Set();
comparisons.forEach(comp => {
if (comp.typeAnalysis) {
Object.keys(comp.typeAnalysis.objectTypes).forEach(type =>
allTypes.add(type)
);
}
});
const commonTypes = {};
allTypes.forEach(type => {
const count = comparisons.filter(comp =>
comp.typeAnalysis?.objectTypes[type] > 0
).length;
if (count > 1) {
commonTypes[type] = count;
}
});
return commonTypes;
}
findUniquePatterns(comparisons) {
const patterns = [];
comparisons.forEach(comp => {
if (comp.typeAnalysis) {
const uniqueTypes = Object.keys(comp.typeAnalysis.objectTypes).filter(
type => {
const appearsInOthers = comparisons.some(other =>
other !== comp && other.typeAnalysis?.objectTypes[type] > 0
);
return !appearsInOthers;
}
);
if (uniqueTypes.length > 0) {
patterns.push({
objectId: comp.objectId,
uniqueTypes: uniqueTypes
});
}
}
});
return patterns;
}
}Best Practices
- Use Pagination: Always handle pagination for objects with many dynamic fields
- Cache Results: Cache field information when exploring object hierarchies
- Handle Large Objects: Be mindful of objects with hundreds of dynamic fields
- Validate Field Names: Handle different field name formats (strings, objects, numbers)
- Implement Retries: Network requests can fail, implement retry logic
- Limit Depth: When exploring recursively, set reasonable depth limits
Related Methods
- sui_getObject - Get detailed object information
- suix_getOwnedObjects - Get objects owned by address
- sui_multiGetObjects - Get multiple objects
Need help? Contact our support team or check the Sui documentation.
suix_getCommitteeInfo - Get Validator Co...
Get detailed validator committee information on Sui blockchain. Query committee composition, validator details, and governance data with Dwellir's high-performance Sui RPC infrastructure.
suix_getLatestSuiSystemState - Get Complete Sui Network State
Get the complete Sui system state including validators, staking pools, system parameters, and network governance data with Dwellir's high-performance Sui RPC infrastructure.