diff --git a/clients/js/sui/utils.ts b/clients/js/sui/utils.ts index 91ebbd139..ca7f2865e 100644 --- a/clients/js/sui/utils.ts +++ b/clients/js/sui/utils.ts @@ -150,27 +150,37 @@ export const getOwnedObjectId = async ( // TODO(kp): remove this once it's in the sdk export async function getPackageId( provider: JsonRpcProvider, - stateObjectId: string + objectId: string ): Promise { - const fields = await provider - .getObject({ - id: stateObjectId, - options: { - showContent: true, - }, - }) - .then((result) => { - if (result.data?.content?.dataType === "moveObject") { - return result.data.content.fields; - } - - throw new Error("Not a moveObject"); + let currentPackage; + let nextCursor; + do { + const dynamicFields = await provider.getDynamicFields({ + parentId: objectId, + cursor: nextCursor, }); - if ("upgrade_cap" in fields) { - return fields.upgrade_cap.fields.package; + currentPackage = dynamicFields.data.find((field) => + field.name.type.endsWith("CurrentPackage") + ); + nextCursor = dynamicFields.hasNextPage ? dynamicFields.nextCursor : null; + } while (nextCursor && !currentPackage); + if (!currentPackage) { + throw new Error("CurrentPackage not found"); } - - throw new Error("upgrade_cap not found"); + const obj = await provider.getObject({ + id: currentPackage.objectId, + options: { + showContent: true, + }, + }); + const packageId = + obj.data?.content && "fields" in obj.data.content + ? obj.data.content.fields.value?.fields?.package + : null; + if (!packageId) { + throw new Error("Unable to get current package"); + } + return packageId; } export const getProvider = ( diff --git a/sdk/js/src/sui/utils.ts b/sdk/js/src/sui/utils.ts index 8848d5734..62682c5f9 100644 --- a/sdk/js/src/sui/utils.ts +++ b/sdk/js/src/sui/utils.ts @@ -12,6 +12,7 @@ import { import { ensureHexPrefix } from "../utils"; import { SuiRpcValidationError } from "./error"; import { SuiError } from "./types"; +import { DynamicFieldPage } from "@mysten/sui.js/dist/types/dynamic_fields"; const UPGRADE_CAP_TYPE = "0x2::package::UpgradeCap"; @@ -178,17 +179,37 @@ export const getOwnedObjectIdPaginated = async ( } }; -export const getPackageId = async ( +/** + * @param provider + * @param objectId Core or token bridge state object ID + * @returns The latest package ID for the provided state object + */ +export async function getPackageId( provider: JsonRpcProvider, objectId: string -): Promise => { - const fields = await getObjectFields(provider, objectId); - if (fields && "upgrade_cap" in fields) { - return fields.upgrade_cap.fields.package; +): Promise { + let currentPackage; + let nextCursor; + do { + const dynamicFields: DynamicFieldPage = await provider.getDynamicFields({ + parentId: objectId, + cursor: nextCursor, + }); + currentPackage = dynamicFields.data.find((field) => + field.name.type.endsWith("CurrentPackage") + ); + nextCursor = dynamicFields.hasNextPage ? dynamicFields.nextCursor : null; + } while (nextCursor && !currentPackage); + if (!currentPackage) { + throw new Error("CurrentPackage not found"); } - - throw new Error("upgrade_cap not found"); -}; + const fields = await getObjectFields(provider, currentPackage.objectId); + const packageId = fields?.value?.fields?.package; + if (!packageId) { + throw new Error("Unable to get current package"); + } + return packageId; +} export const getPackageIdFromType = (type: string): string | null => { if (!isValidSuiType(type)) return null;