@mysten/sui
Version:
Sui TypeScript API(Work in Progress)
125 lines (124 loc) • 4.26 kB
JavaScript
import { isValidNamedPackage, isValidNamedType } from "../../utils/move-registry.js";
import { normalizeStructTag, parseStructTag } from "../../utils/sui-types.js";
const NAME_SEPARATOR = "/";
function findNamesInTransaction(builder) {
const packages = /* @__PURE__ */ new Set();
const types = /* @__PURE__ */ new Set();
for (const command of builder.commands) {
if (command.MakeMoveVec?.type) {
getNamesFromTypeList([command.MakeMoveVec.type]).forEach((type) => {
types.add(type);
});
continue;
}
if (!("MoveCall" in command)) continue;
const tx = command.MoveCall;
if (!tx) continue;
const pkg = tx.package.split("::")[0];
if (hasMvrName(pkg)) {
if (!isValidNamedPackage(pkg)) throw new Error(`Invalid package name: ${pkg}`);
packages.add(pkg);
}
getNamesFromTypeList(tx.typeArguments ?? []).forEach((type) => {
types.add(type);
});
}
return {
packages: [...packages],
types: [...types]
};
}
function getFirstLevelNamedTypes(types) {
const results = /* @__PURE__ */ new Set();
for (const type of types) {
findMvrNames(type).forEach((name) => results.add(name));
}
return results;
}
function findMvrNames(type) {
const types = /* @__PURE__ */ new Set();
if (typeof type === "string" && !hasMvrName(type)) return types;
const tag = isStructTag(type) ? type : parseStructTag(type);
if (hasMvrName(tag.address)) types.add(`${tag.address}::${tag.module}::${tag.name}`);
for (const param of tag.typeParams) {
findMvrNames(param).forEach((name) => types.add(name));
}
return types;
}
function populateNamedTypesFromCache(types, typeCache) {
const composedTypes = {};
types.forEach((type) => {
const normalized = normalizeStructTag(findAndReplaceCachedTypes(type, typeCache));
composedTypes[type] = normalized;
});
return composedTypes;
}
function findAndReplaceCachedTypes(tag, typeCache) {
const type = isStructTag(tag) ? tag : parseStructTag(tag);
const typeTag = `${type.address}::${type.module}::${type.name}`;
const cacheHit = typeCache[typeTag];
return {
...type,
address: cacheHit ? cacheHit.split("::")[0] : type.address,
typeParams: type.typeParams.map((param) => findAndReplaceCachedTypes(param, typeCache))
};
}
function replaceNames(builder, cache) {
for (const command of builder.commands) {
if (command.MakeMoveVec?.type) {
if (!hasMvrName(command.MakeMoveVec.type)) continue;
if (!cache.types[command.MakeMoveVec.type])
throw new Error(`No resolution found for type: ${command.MakeMoveVec.type}`);
command.MakeMoveVec.type = cache.types[command.MakeMoveVec.type];
}
const tx = command.MoveCall;
if (!tx) continue;
const nameParts = tx.package.split("::");
const name = nameParts[0];
if (hasMvrName(name) && !cache.packages[name])
throw new Error(`No address found for package: ${name}`);
if (hasMvrName(name)) {
nameParts[0] = cache.packages[name];
tx.package = nameParts.join("::");
}
const types = tx.typeArguments;
if (!types) continue;
for (let i = 0; i < types.length; i++) {
if (!hasMvrName(types[i])) continue;
if (!cache.types[types[i]]) throw new Error(`No resolution found for type: ${types[i]}`);
types[i] = cache.types[types[i]];
}
tx.typeArguments = types;
}
}
function batch(arr, size) {
const batches = [];
for (let i = 0; i < arr.length; i += size) {
batches.push(arr.slice(i, i + size));
}
return batches;
}
function getNamesFromTypeList(types) {
const names = /* @__PURE__ */ new Set();
for (const type of types) {
if (hasMvrName(type)) {
if (!isValidNamedType(type)) throw new Error(`Invalid type with names: ${type}`);
names.add(type);
}
}
return names;
}
function hasMvrName(nameOrType) {
return nameOrType.includes(NAME_SEPARATOR) || nameOrType.includes("@") || nameOrType.includes(".sui");
}
function isStructTag(type) {
return typeof type === "object" && "address" in type && "module" in type && "name" in type && "typeParams" in type;
}
export {
batch,
findNamesInTransaction,
getFirstLevelNamedTypes,
populateNamedTypesFromCache,
replaceNames
};
//# sourceMappingURL=utils.js.map