{"version":3,"file":"kiosk.mjs","names":["KioskOwnerCapParser"],"sources":["../../src/query/kiosk.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { ClientWithCoreApi, SuiClientTypes } from '@mysten/sui/client';\nimport { isValidSuiAddress } from '@mysten/sui/utils';\n\nimport { Extension, ExtensionKey } from '../contracts/0x2/kiosk_extension.js';\nimport type {\n\tFetchKioskOptions,\n\tKioskCompatibleClient,\n\tKioskExtension,\n\tKioskListing,\n\tKioskPaginationArguments,\n\tOwnedKiosks,\n\tPagedKioskData,\n} from '../types/index.js';\nimport { KIOSK_OWNER_CAP } from '../types/index.js';\nimport {\n\tattachListingsAndPrices,\n\tattachLockedItems,\n\tattachObjects,\n\textractKioskData,\n\tgetAllDynamicFields,\n\tgetKioskObject,\n} from '../utils.js';\nimport { getAllObjects } from './client-utils.js';\nimport { PersonalKioskCap } from '../contracts/kiosk/personal_kiosk.js';\n\nexport async function fetchKiosk(\n\tclient: KioskCompatibleClient,\n\tkioskId: string,\n\tpagination: KioskPaginationArguments,\n\toptions: FetchKioskOptions,\n): Promise<PagedKioskData> {\n\t// TODO: Replace the `getAllDynamicFields` with a paginated\n\t// response, once we have better RPC support for\n\t// type filtering & batch fetching.\n\t// This can't work with pagination currently.\n\tconst data = await getAllDynamicFields(client, kioskId, pagination);\n\n\tconst listings: KioskListing[] = [];\n\tconst lockedItemIds: string[] = [];\n\n\t// extracted kiosk data.\n\tconst kioskData = extractKioskData(data, listings, lockedItemIds, kioskId);\n\n\t// split the fetching in two queries as we are most likely passing different options for each kind.\n\t// For items, we usually seek the Display.\n\t// For listings we usually seek the DF value (price) / exclusivity.\n\tconst [kiosk, listingObjects, items] = await Promise.all([\n\t\toptions.withKioskFields ? getKioskObject(client, kioskId) : Promise.resolve(undefined),\n\t\toptions.withListingPrices ? getAllObjects(client, kioskData.listingIds) : Promise.resolve([]),\n\t\toptions.withObjects ? getAllObjects(client, kioskData.itemIds) : Promise.resolve([]),\n\t]);\n\n\tif (options.withKioskFields) kioskData.kiosk = kiosk;\n\t// attach items listings. IF we have `options.withListingPrices === true`, it will also attach the prices.\n\tattachListingsAndPrices(kioskData, listings, listingObjects);\n\t// add `locked` status to items that are locked.\n\tattachLockedItems(kioskData, lockedItemIds);\n\n\t// Attach the objects for the queried items.\n\tattachObjects(kioskData, items);\n\n\treturn {\n\t\tdata: kioskData,\n\t\tnextCursor: null,\n\t\thasNextPage: false,\n\t};\n}\n\n/**\n * A function to fetch all the user's kiosk Caps\n * And a list of the kiosk address ids.\n * Returns a list of `kioskOwnerCapIds` and `kioskIds`.\n * Extra options allow pagination.\n */\n\nconst DEFAULT_PAGE_SIZE = 50;\nconst PERSON_KIOSK_CURSOR = 'personal';\nconst OWNED_KIOSKS_CURSOR = 'owned';\nexport async function getOwnedKiosks(\n\tclient: ClientWithCoreApi,\n\taddress: string,\n\toptions?: {\n\t\tpagination?: KioskPaginationArguments;\n\t\tpersonalKioskType: string;\n\t},\n): Promise<OwnedKiosks> {\n\t// TODO: this should throw an error, but I am not going to change it right now incase it breaks existing code.\n\tif (!isValidSuiAddress(address)) {\n\t\treturn {\n\t\t\tnextCursor: null,\n\t\t\thasNextPage: false,\n\t\t\tkioskOwnerCaps: [],\n\t\t\tkioskIds: [],\n\t\t};\n\t}\n\n\tconst limit = options?.pagination?.limit ?? DEFAULT_PAGE_SIZE;\n\tconst [cursorType, cursor] = options?.pagination?.cursor?.split(':') ?? [\n\t\tPERSON_KIOSK_CURSOR,\n\t\tnull,\n\t];\n\n\tif (options?.personalKioskType && cursorType === PERSON_KIOSK_CURSOR) {\n\t\tconst personalResult = await client.core.listOwnedObjects({\n\t\t\towner: address,\n\t\t\ttype: options.personalKioskType,\n\t\t\tcursor,\n\t\t\tlimit,\n\t\t\tinclude: {\n\t\t\t\tcontent: true,\n\t\t\t},\n\t\t});\n\n\t\tconst personalKioskData = personalResult.objects\n\t\t\t.filter((obj) => !(obj instanceof Error))\n\t\t\t.map((obj) => {\n\t\t\t\treturn { obj, kioskId: PersonalKioskCap.parse(obj.content).cap?.for };\n\t\t\t})\n\t\t\t.filter(\n\t\t\t\t(\n\t\t\t\t\titem,\n\t\t\t\t): item is {\n\t\t\t\t\tobj: SuiClientTypes.Object<{ content: true }>;\n\t\t\t\t\tkioskId: string;\n\t\t\t\t} => item.kioskId !== undefined,\n\t\t\t);\n\n\t\tconst personalKioskResponse = formatOwnedKioskResponse(\n\t\t\t{\n\t\t\t\tdata: personalKioskData,\n\t\t\t\thasNextPage: personalResult.hasNextPage,\n\t\t\t\tnextCursor: personalResult.cursor,\n\t\t\t},\n\t\t\tPERSON_KIOSK_CURSOR,\n\t\t);\n\n\t\tif (personalKioskResponse.hasNextPage) {\n\t\t\treturn personalKioskResponse;\n\t\t}\n\n\t\tconst remainingLimit = limit - personalKioskResponse.kioskOwnerCaps.length;\n\n\t\t// If we have all personal kiosks, but don't have space for the owned kiosks\n\t\t// we need to start loading owned kiosks for the next page, but don't have a real cursor\n\t\tif (remainingLimit < 1) {\n\t\t\treturn {\n\t\t\t\tnextCursor: `${OWNED_KIOSKS_CURSOR}:`,\n\t\t\t\thasNextPage: true,\n\t\t\t\tkioskOwnerCaps: personalKioskResponse.kioskOwnerCaps,\n\t\t\t\tkioskIds: personalKioskResponse.kioskIds,\n\t\t\t};\n\t\t}\n\n\t\tconst ownedResult = await client.core.listOwnedObjects({\n\t\t\towner: address,\n\t\t\ttype: KIOSK_OWNER_CAP,\n\t\t\tcursor: null,\n\t\t\tlimit: remainingLimit,\n\t\t\tinclude: {\n\t\t\t\tcontent: true,\n\t\t\t},\n\t\t});\n\n\t\tconst { KioskOwnerCap: KioskOwnerCapParser } = await import('../contracts/0x2/kiosk.js');\n\n\t\tconst ownedKioskData = ownedResult.objects\n\t\t\t.filter((obj) => !(obj instanceof Error))\n\t\t\t.map((obj) => {\n\t\t\t\treturn { obj, kioskId: KioskOwnerCapParser.parse(obj.content).for };\n\t\t\t})\n\t\t\t.filter(\n\t\t\t\t(\n\t\t\t\t\titem,\n\t\t\t\t): item is {\n\t\t\t\t\tobj: SuiClientTypes.Object<{ content: true }>;\n\t\t\t\t\tkioskId: string;\n\t\t\t\t} => item.kioskId !== undefined,\n\t\t\t);\n\n\t\tconst ownedKiosksResponse = formatOwnedKioskResponse(\n\t\t\t{\n\t\t\t\tdata: ownedKioskData,\n\t\t\t\thasNextPage: ownedResult.hasNextPage,\n\t\t\t\tnextCursor: ownedResult.cursor,\n\t\t\t},\n\t\t\tOWNED_KIOSKS_CURSOR,\n\t\t);\n\n\t\treturn {\n\t\t\tnextCursor: ownedKiosksResponse.nextCursor,\n\t\t\thasNextPage: ownedKiosksResponse.hasNextPage,\n\t\t\tkioskOwnerCaps: [\n\t\t\t\t...personalKioskResponse.kioskOwnerCaps,\n\t\t\t\t...ownedKiosksResponse.kioskOwnerCaps,\n\t\t\t],\n\t\t\tkioskIds: [...personalKioskResponse.kioskIds, ...ownedKiosksResponse.kioskIds],\n\t\t};\n\t}\n\n\tconst result = await client.core.listOwnedObjects({\n\t\towner: address,\n\t\ttype: KIOSK_OWNER_CAP,\n\t\tcursor: cursor || null,\n\t\tlimit,\n\t\tinclude: {\n\t\t\tcontent: true,\n\t\t},\n\t});\n\n\tconst { KioskOwnerCap: KioskOwnerCapParser } = await import('../contracts/0x2/kiosk.js');\n\n\tconst ownedKioskData = result.objects\n\t\t.filter((obj) => !(obj instanceof Error))\n\t\t.map((obj) => {\n\t\t\treturn { obj, kioskId: KioskOwnerCapParser.parse(obj.content).for };\n\t\t})\n\t\t.filter(\n\t\t\t(\n\t\t\t\titem,\n\t\t\t): item is {\n\t\t\t\tobj: SuiClientTypes.Object<{ content: true }>;\n\t\t\t\tkioskId: string;\n\t\t\t} => item.kioskId !== undefined,\n\t\t);\n\n\treturn formatOwnedKioskResponse(\n\t\t{\n\t\t\tdata: ownedKioskData,\n\t\t\thasNextPage: result.hasNextPage,\n\t\t\tnextCursor: result.cursor,\n\t\t},\n\t\tOWNED_KIOSKS_CURSOR,\n\t);\n}\n\nfunction formatOwnedKioskResponse(\n\tresponse: {\n\t\tdata: {\n\t\t\tobj: SuiClientTypes.Object<{ content: true }>;\n\t\t\tkioskId: string;\n\t\t}[];\n\t\thasNextPage: boolean;\n\t\tnextCursor: string | null;\n\t},\n\tcursorType: string,\n): OwnedKiosks {\n\tconst { data, hasNextPage, nextCursor } = response;\n\n\treturn {\n\t\tnextCursor: nextCursor ? `${cursorType}:${nextCursor}` : nextCursor,\n\t\thasNextPage,\n\t\tkioskOwnerCaps: data.map((item) => {\n\t\t\tconst isPersonal = item.obj.type?.includes('PersonalKioskCap') || false;\n\t\t\treturn {\n\t\t\t\tisPersonal,\n\t\t\t\tdigest: item.obj.digest,\n\t\t\t\tversion: item.obj.version,\n\t\t\t\tobjectId: item.obj.objectId,\n\t\t\t\tkioskId: item.kioskId,\n\t\t\t};\n\t\t}),\n\t\tkioskIds: data.map((item) => item.kioskId),\n\t};\n}\n\n// Get a kiosk extension data for a given kioskId and extensionType.\nexport async function fetchKioskExtension(\n\tclient: ClientWithCoreApi,\n\tkioskId: string,\n\textensionType: string,\n): Promise<KioskExtension | null> {\n\tconst { dynamicField } = await client.core.getDynamicField({\n\t\tparentId: kioskId,\n\t\tname: {\n\t\t\ttype: `0x2::kiosk_extension::ExtensionKey<${extensionType}>`,\n\t\t\tbcs: ExtensionKey.serialize({ dummy_field: false }).toBytes(),\n\t\t},\n\t});\n\n\tconst extension = Extension.parse(dynamicField.value.bcs);\n\n\treturn {\n\t\tobjectId: dynamicField.fieldId,\n\t\ttype: extensionType,\n\t\tisEnabled: extension.is_enabled,\n\t\tpermissions: extension.permissions.toString(),\n\t\tstorageId: extension.storage.id,\n\t\tstorageSize: Number(extension.storage.size),\n\t};\n}\n"],"mappings":"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"}