@mysten/kiosk 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/client/kiosk-client.d.mts +4 -4
- package/dist/client/kiosk-client.d.mts.map +1 -1
- package/dist/client/kiosk-client.mjs.map +1 -1
- package/dist/contracts/0x2/kiosk.mjs +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +2 -2
- package/dist/query/client-utils.mjs +186 -1
- package/dist/query/client-utils.mjs.map +1 -1
- package/dist/query/kiosk.mjs +2 -1
- package/dist/query/kiosk.mjs.map +1 -1
- package/dist/query/transfer-policy.mjs +1 -1
- package/dist/query/transfer-policy.mjs.map +1 -1
- package/dist/types/index.d.mts +7 -4
- package/dist/types/index.d.mts.map +1 -1
- package/dist/types/kiosk.d.mts +13 -3
- package/dist/types/kiosk.d.mts.map +1 -1
- package/dist/types/kiosk.mjs.map +1 -1
- package/dist/utils.d.mts +3 -9
- package/dist/utils.d.mts.map +1 -1
- package/dist/utils.mjs +5 -24
- package/dist/utils.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client/kiosk-client.ts +4 -3
- package/src/query/client-utils.ts +253 -2
- package/src/query/kiosk.ts +3 -2
- package/src/query/transfer-policy.ts +4 -5
- package/src/types/index.ts +6 -2
- package/src/types/kiosk.ts +15 -3
- package/src/utils.ts +8 -38
package/dist/utils.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Kiosk, KioskData, KioskListing } from "./types/kiosk.mjs";
|
|
1
|
+
import { Kiosk, KioskData, KioskListing, ObjectWithDisplay } from "./types/kiosk.mjs";
|
|
2
2
|
import "./types/index.mjs";
|
|
3
3
|
import { PaginationArguments } from "@mysten/sui/jsonRpc";
|
|
4
4
|
import { ClientWithCoreApi, SuiClientTypes } from "@mysten/sui/client";
|
|
@@ -15,7 +15,7 @@ declare function attachListingsAndPrices(kioskData: KioskData, listings: KioskLi
|
|
|
15
15
|
* A helper that attaches object data to kiosk items.
|
|
16
16
|
* Works with core API objects that contain BCS content.
|
|
17
17
|
*/
|
|
18
|
-
declare function attachObjects(kioskData: KioskData, objects:
|
|
18
|
+
declare function attachObjects(kioskData: KioskData, objects: ObjectWithDisplay[]): void;
|
|
19
19
|
/**
|
|
20
20
|
* A Helper to attach locked state to items in Kiosk Data.
|
|
21
21
|
*/
|
|
@@ -26,12 +26,6 @@ declare function attachLockedItems(kioskData: KioskData, lockedItemIds: string[]
|
|
|
26
26
|
* RPC calls that allow filtering of Type / batch fetching of spec
|
|
27
27
|
*/
|
|
28
28
|
declare function getAllDynamicFields(client: ClientWithCoreApi, parentId: string, pagination: PaginationArguments<string>): Promise<DynamicFieldInfo[]>;
|
|
29
|
-
/**
|
|
30
|
-
* A helper to fetch all objects that works with pagination.
|
|
31
|
-
* It will fetch all objects in the array, and limit it to 50/request.
|
|
32
|
-
* Requests are sent using `Promise.all`.
|
|
33
|
-
*/
|
|
34
|
-
declare function getAllObjects(client: ClientWithCoreApi, ids: string[]): Promise<SuiClientTypes.Object[]>;
|
|
35
29
|
/**
|
|
36
30
|
* Converts a number to basis points.
|
|
37
31
|
* Supports up to 2 decimal points.
|
|
@@ -41,5 +35,5 @@ declare function getAllObjects(client: ClientWithCoreApi, ids: string[]): Promis
|
|
|
41
35
|
declare function percentageToBasisPoints(percentage: number): number;
|
|
42
36
|
declare function getNormalizedRuleType(rule: string): string;
|
|
43
37
|
//#endregion
|
|
44
|
-
export { DynamicFieldInfo, attachListingsAndPrices, attachLockedItems, attachObjects, extractKioskData, getAllDynamicFields,
|
|
38
|
+
export { DynamicFieldInfo, attachListingsAndPrices, attachLockedItems, attachObjects, extractKioskData, getAllDynamicFields, getKioskObject, getNormalizedRuleType, percentageToBasisPoints };
|
|
45
39
|
//# sourceMappingURL=utils.d.mts.map
|
package/dist/utils.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.mts","names":[],"sources":["../src/utils.ts"],"sourcesContent":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"utils.d.mts","names":[],"sources":["../src/utils.ts"],"sourcesContent":[],"mappings":";;;;;;KAWY,gBAAA,GAAmB,cAAA,CAAe;iBAExB,cAAA,SAAuB,gCAAgC,QAAQ;iBAsBrE,gBAAA,OACT,8BACI,2DAGR;AA7BH;AAEA;;AAAqF,iBA0FrE,uBAAA,CA1FqE,SAAA,EA2FzE,SA3FyE,EAAA,QAAA,EA4F1E,YA5F0E,EAAA,EAAA,cAAA,EA6FpE,cAAA,CAAe,MA7FqD,EAAA,CAAA,EAAA,IAAA;;;AAsBrF;;AAEW,iBAoGK,aAAA,CApGL,SAAA,EAoG8B,SApG9B,EAAA,OAAA,EAoGkD,iBApGlD,EAAA,CAAA,EAAA,IAAA;;;AAkEX;AACY,iBAkDI,iBAAA,CAlDJ,SAAA,EAkDiC,SAlDjC,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,EAAA,IAAA;;;;AAiCZ;AAiBA;AAqBsB,iBAAA,mBAAA,CAAmB,MAAA,EAChC,iBADgC,EAAA,QAAA,EAAA,MAAA,EAAA,UAAA,EAG5B,mBAH4B,CAAA,MAAA,CAAA,CAAA,EAItC,OAJsC,CAI9B,gBAJ8B,EAAA,CAAA;;;;;;AA+BzC;AAOgB,iBAPA,uBAAA,CAOqB,UAAA,EAAA,MAAA,CAAA,EAAA,MAAA;iBAArB,qBAAA"}
|
package/dist/utils.mjs
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { Kiosk, Listing, Lock } from "./contracts/0x2/kiosk.mjs";
|
|
1
|
+
import { Item, Kiosk, Listing, Lock } from "./contracts/0x2/kiosk.mjs";
|
|
2
2
|
import { bcs } from "@mysten/sui/bcs";
|
|
3
3
|
import { normalizeStructTag, normalizeSuiAddress, parseStructTag } from "@mysten/sui/utils";
|
|
4
|
-
import { chunk } from "@mysten/utils";
|
|
5
4
|
|
|
6
5
|
//#region src/utils.ts
|
|
7
|
-
const DEFAULT_QUERY_LIMIT = 50;
|
|
8
6
|
async function getKioskObject(client, id) {
|
|
9
7
|
const { object } = await client.core.getObject({
|
|
10
8
|
objectId: id,
|
|
@@ -26,9 +24,10 @@ function extractKioskData(data, listings, lockedItemIds, kioskId) {
|
|
|
26
24
|
const parsedType = parseStructTag(type);
|
|
27
25
|
const baseType = `${normalizeSuiAddress(parsedType.address)}::${parsedType.module}::${parsedType.name}`;
|
|
28
26
|
if (baseType === "0x0000000000000000000000000000000000000000000000000000000000000002::kiosk::Item") {
|
|
29
|
-
|
|
27
|
+
const parsed = Item.parse(val.name.bcs);
|
|
28
|
+
acc.itemIds.push(parsed.id);
|
|
30
29
|
acc.items.push({
|
|
31
|
-
objectId:
|
|
30
|
+
objectId: parsed.id,
|
|
32
31
|
type: val.valueType,
|
|
33
32
|
isLocked: false,
|
|
34
33
|
kioskId
|
|
@@ -118,24 +117,6 @@ async function getAllDynamicFields(client, parentId, pagination) {
|
|
|
118
117
|
return data;
|
|
119
118
|
}
|
|
120
119
|
/**
|
|
121
|
-
* A helper to fetch all objects that works with pagination.
|
|
122
|
-
* It will fetch all objects in the array, and limit it to 50/request.
|
|
123
|
-
* Requests are sent using `Promise.all`.
|
|
124
|
-
*/
|
|
125
|
-
async function getAllObjects(client, ids) {
|
|
126
|
-
const chunks = chunk(ids, DEFAULT_QUERY_LIMIT);
|
|
127
|
-
return (await Promise.all(chunks.map(async (objectIds) => {
|
|
128
|
-
const { objects } = await client.core.getObjects({
|
|
129
|
-
objectIds,
|
|
130
|
-
include: {
|
|
131
|
-
content: true,
|
|
132
|
-
previousTransaction: true
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
return objects.filter((obj) => !(obj instanceof Error));
|
|
136
|
-
}))).flat();
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
120
|
* Converts a number to basis points.
|
|
140
121
|
* Supports up to 2 decimal points.
|
|
141
122
|
* E.g 9.95 -> 995
|
|
@@ -152,5 +133,5 @@ function getNormalizedRuleType(rule) {
|
|
|
152
133
|
}
|
|
153
134
|
|
|
154
135
|
//#endregion
|
|
155
|
-
export { attachListingsAndPrices, attachLockedItems, attachObjects, extractKioskData, getAllDynamicFields,
|
|
136
|
+
export { attachListingsAndPrices, attachLockedItems, attachObjects, extractKioskData, getAllDynamicFields, getKioskObject, getNormalizedRuleType, percentageToBasisPoints };
|
|
156
137
|
//# sourceMappingURL=utils.mjs.map
|
package/dist/utils.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.mjs","names":["KioskStruct"],"sources":["../src/utils.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { bcs } from '@mysten/sui/bcs';\nimport { PaginationArguments } from '@mysten/sui/jsonRpc';\nimport type { ClientWithCoreApi, SuiClientTypes } from '@mysten/sui/client';\nimport { normalizeStructTag, normalizeSuiAddress, parseStructTag } from '@mysten/sui/utils';\nimport { chunk } from '@mysten/utils';\n\nimport { Listing, Lock, Kiosk as KioskStruct } from './contracts/0x2/kiosk.js';\nimport type { Kiosk, KioskData, KioskListing } from './types/index.js';\n\nconst DEFAULT_QUERY_LIMIT = 50;\n\nexport type DynamicFieldInfo = SuiClientTypes.ListDynamicFieldsResponse['dynamicFields'][number];\n\nexport async function getKioskObject(client: ClientWithCoreApi, id: string): Promise<Kiosk> {\n\tconst { object } = await client.core.getObject({\n\t\tobjectId: id,\n\t\tinclude: { content: true },\n\t});\n\n\tif (!object.content) {\n\t\tthrow new Error(`Kiosk ${id} not found or has no content`);\n\t}\n\n\tconst parsed = KioskStruct.parse(object.content);\n\n\treturn {\n\t\tid: parsed.id,\n\t\tprofits: parsed.profits.value.toString(),\n\t\towner: parsed.owner,\n\t\titemCount: parsed.item_count,\n\t\tallowExtensions: parsed.allow_extensions,\n\t};\n}\n\n// helper to extract kiosk data from dynamic fields.\nexport function extractKioskData(\n\tdata: DynamicFieldInfo[],\n\tlistings: KioskListing[],\n\tlockedItemIds: string[],\n\tkioskId: string,\n): KioskData {\n\treturn data.reduce<KioskData>(\n\t\t(acc: KioskData, val: DynamicFieldInfo) => {\n\t\t\tconst type = val.name.type;\n\n\t\t\tconst parsedType = parseStructTag(type);\n\t\t\tconst baseType = `${normalizeSuiAddress(parsedType.address)}::${parsedType.module}::${parsedType.name}`;\n\n\t\t\tif (\n\t\t\t\tbaseType ===\n\t\t\t\t'0x0000000000000000000000000000000000000000000000000000000000000002::kiosk::Item'\n\t\t\t) {\n\t\t\t\tacc.itemIds.push(val.fieldId);\n\t\t\t\tacc.items.push({\n\t\t\t\t\tobjectId: val.fieldId,\n\t\t\t\t\ttype: val.valueType,\n\t\t\t\t\tisLocked: false,\n\t\t\t\t\tkioskId,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tbaseType ===\n\t\t\t\t'0x0000000000000000000000000000000000000000000000000000000000000002::kiosk::Listing'\n\t\t\t) {\n\t\t\t\tconst parsed = Listing.parse(val.name.bcs);\n\n\t\t\t\tacc.listingIds.push(val.fieldId);\n\t\t\t\tlistings.push({\n\t\t\t\t\tobjectId: parsed.id,\n\t\t\t\t\tlistingId: val.fieldId,\n\t\t\t\t\tisExclusive: parsed.is_exclusive,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tbaseType ===\n\t\t\t\t'0x0000000000000000000000000000000000000000000000000000000000000002::kiosk::Lock'\n\t\t\t) {\n\t\t\t\tlockedItemIds?.push(Lock.parse(val.name.bcs).id);\n\t\t\t}\n\n\t\t\t// Check for ExtensionKey type\n\t\t\tif (\n\t\t\t\tbaseType ===\n\t\t\t\t'0x0000000000000000000000000000000000000000000000000000000000000002::kiosk_extension::ExtensionKey'\n\t\t\t) {\n\t\t\t\tacc.extensions.push({\n\t\t\t\t\tobjectId: val.fieldId,\n\t\t\t\t\ttype: normalizeStructTag(parsedType.typeParams[0]),\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn acc;\n\t\t},\n\t\t{ items: [], itemIds: [], listingIds: [], extensions: [] },\n\t);\n}\n\n/**\n * A helper that attaches the listing prices to kiosk listings.\n */\nexport function attachListingsAndPrices(\n\tkioskData: KioskData,\n\tlistings: KioskListing[],\n\tlistingObjects: SuiClientTypes.Object[],\n) {\n\tconst itemListings = listings.reduce<Record<string, KioskListing>>(\n\t\t(acc: Record<string, KioskListing>, item, idx) => {\n\t\t\tacc[item.objectId] = { ...item };\n\n\t\t\t// return in case we don't have any listing objects.\n\t\t\t// that's the case when we don't have the `listingPrices` included.\n\t\t\tif (listingObjects.length === 0) return acc;\n\n\t\t\tconst obj = listingObjects[idx];\n\n\t\t\t// Parse BCS content to extract the price (u64 value)\n\t\t\tif (obj.content) {\n\t\t\t\tacc[item.objectId].price = bcs.u64().parse(obj.content).toString();\n\t\t\t}\n\n\t\t\treturn acc;\n\t\t},\n\t\t{},\n\t);\n\n\tkioskData.items.forEach((item) => {\n\t\titem.listing = itemListings[item.objectId] || undefined;\n\t});\n}\n\n/**\n * A helper that attaches object data to kiosk items.\n * Works with core API objects that contain BCS content.\n */\nexport function attachObjects(kioskData: KioskData, objects: SuiClientTypes.Object[]) {\n\tconst mapping = objects.reduce<Record<string, SuiClientTypes.Object>>(\n\t\t(acc: Record<string, SuiClientTypes.Object>, obj) => {\n\t\t\tacc[obj.objectId] = obj;\n\t\t\treturn acc;\n\t\t},\n\t\t{},\n\t);\n\n\tkioskData.items.forEach((item) => {\n\t\titem.data = mapping[item.objectId] || undefined;\n\t});\n}\n\n/**\n * A Helper to attach locked state to items in Kiosk Data.\n */\nexport function attachLockedItems(kioskData: KioskData, lockedItemIds: string[]) {\n\t// map lock status in an array of type { item_id: true }\n\tconst lockedStatuses = lockedItemIds.reduce<Record<string, boolean>>(\n\t\t(acc: Record<string, boolean>, item: string) => {\n\t\t\tacc[item] = true;\n\t\t\treturn acc;\n\t\t},\n\t\t{},\n\t);\n\n\t// parse lockedItemIds and attach their locked status.\n\tkioskData.items.forEach((item) => {\n\t\titem.isLocked = lockedStatuses[item.objectId] || false;\n\t});\n}\n\n/**\n * A helper to fetch all dynamic field pages.\n * We need that to fetch the kiosk DFs consistently, until we have\n * RPC calls that allow filtering of Type / batch fetching of spec\n */\nexport async function getAllDynamicFields(\n\tclient: ClientWithCoreApi,\n\tparentId: string,\n\tpagination: PaginationArguments<string>,\n): Promise<DynamicFieldInfo[]> {\n\tlet hasNextPage = true;\n\tlet cursor: string | null = null;\n\tconst data: DynamicFieldInfo[] = [];\n\n\twhile (hasNextPage) {\n\t\tconst result = await client.core.listDynamicFields({\n\t\t\tparentId,\n\t\t\tlimit: pagination.limit || undefined,\n\t\t\tcursor,\n\t\t});\n\n\t\tdata.push(...result.dynamicFields);\n\n\t\thasNextPage = result.hasNextPage;\n\t\tcursor = result.cursor;\n\t}\n\n\treturn data;\n}\n\n/**\n * A helper to fetch all objects that works with pagination.\n * It will fetch all objects in the array, and limit it to 50/request.\n * Requests are sent using `Promise.all`.\n */\nexport async function getAllObjects(\n\tclient: ClientWithCoreApi,\n\tids: string[],\n): Promise<SuiClientTypes.Object[]> {\n\tconst chunks = chunk(ids, DEFAULT_QUERY_LIMIT);\n\n\tconst results = await Promise.all(\n\t\tchunks.map(async (objectIds) => {\n\t\t\tconst { objects } = await client.core.getObjects({\n\t\t\t\tobjectIds,\n\t\t\t\tinclude: {\n\t\t\t\t\tcontent: true,\n\t\t\t\t\tpreviousTransaction: true,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\treturn objects.filter((obj): obj is SuiClientTypes.Object => !(obj instanceof Error));\n\t\t}),\n\t);\n\n\treturn results.flat();\n}\n\n/**\n * Converts a number to basis points.\n * Supports up to 2 decimal points.\n * E.g 9.95 -> 995\n * @param percentage A percentage amount in the range [0, 100] including decimals.\n */\nexport function percentageToBasisPoints(percentage: number) {\n\tif (percentage < 0 || percentage > 100)\n\t\tthrow new Error('Percentage needs to be in the [0,100] range.');\n\treturn Math.ceil(percentage * 100);\n}\n\n// Normalizes the packageId part of a rule's type.\nexport function getNormalizedRuleType(rule: string) {\n\tconst normalizedRuleAddress = rule.split('::');\n\tnormalizedRuleAddress[0] = normalizeSuiAddress(normalizedRuleAddress[0]);\n\treturn normalizedRuleAddress.join('::');\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils.mjs","names":["KioskStruct"],"sources":["../src/utils.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { bcs } from '@mysten/sui/bcs';\nimport { PaginationArguments } from '@mysten/sui/jsonRpc';\nimport type { ClientWithCoreApi, SuiClientTypes } from '@mysten/sui/client';\nimport { normalizeStructTag, normalizeSuiAddress, parseStructTag } from '@mysten/sui/utils';\n\nimport { Item, Listing, Lock, Kiosk as KioskStruct } from './contracts/0x2/kiosk.js';\nimport type { Kiosk, KioskData, KioskListing, ObjectWithDisplay } from './types/index.js';\n\nexport type DynamicFieldInfo = SuiClientTypes.ListDynamicFieldsResponse['dynamicFields'][number];\n\nexport async function getKioskObject(client: ClientWithCoreApi, id: string): Promise<Kiosk> {\n\tconst { object } = await client.core.getObject({\n\t\tobjectId: id,\n\t\tinclude: { content: true },\n\t});\n\n\tif (!object.content) {\n\t\tthrow new Error(`Kiosk ${id} not found or has no content`);\n\t}\n\n\tconst parsed = KioskStruct.parse(object.content);\n\n\treturn {\n\t\tid: parsed.id,\n\t\tprofits: parsed.profits.value.toString(),\n\t\towner: parsed.owner,\n\t\titemCount: parsed.item_count,\n\t\tallowExtensions: parsed.allow_extensions,\n\t};\n}\n\n// helper to extract kiosk data from dynamic fields.\nexport function extractKioskData(\n\tdata: DynamicFieldInfo[],\n\tlistings: KioskListing[],\n\tlockedItemIds: string[],\n\tkioskId: string,\n): KioskData {\n\treturn data.reduce<KioskData>(\n\t\t(acc: KioskData, val: DynamicFieldInfo) => {\n\t\t\tconst type = val.name.type;\n\n\t\t\tconst parsedType = parseStructTag(type);\n\t\t\tconst baseType = `${normalizeSuiAddress(parsedType.address)}::${parsedType.module}::${parsedType.name}`;\n\n\t\t\tif (\n\t\t\t\tbaseType ===\n\t\t\t\t'0x0000000000000000000000000000000000000000000000000000000000000002::kiosk::Item'\n\t\t\t) {\n\t\t\t\tconst parsed = Item.parse(val.name.bcs);\n\t\t\t\tacc.itemIds.push(parsed.id);\n\t\t\t\tacc.items.push({\n\t\t\t\t\tobjectId: parsed.id,\n\t\t\t\t\ttype: val.valueType,\n\t\t\t\t\tisLocked: false,\n\t\t\t\t\tkioskId,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tbaseType ===\n\t\t\t\t'0x0000000000000000000000000000000000000000000000000000000000000002::kiosk::Listing'\n\t\t\t) {\n\t\t\t\tconst parsed = Listing.parse(val.name.bcs);\n\n\t\t\t\tacc.listingIds.push(val.fieldId);\n\t\t\t\tlistings.push({\n\t\t\t\t\tobjectId: parsed.id,\n\t\t\t\t\tlistingId: val.fieldId,\n\t\t\t\t\tisExclusive: parsed.is_exclusive,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tbaseType ===\n\t\t\t\t'0x0000000000000000000000000000000000000000000000000000000000000002::kiosk::Lock'\n\t\t\t) {\n\t\t\t\tlockedItemIds?.push(Lock.parse(val.name.bcs).id);\n\t\t\t}\n\n\t\t\t// Check for ExtensionKey type\n\t\t\tif (\n\t\t\t\tbaseType ===\n\t\t\t\t'0x0000000000000000000000000000000000000000000000000000000000000002::kiosk_extension::ExtensionKey'\n\t\t\t) {\n\t\t\t\tacc.extensions.push({\n\t\t\t\t\tobjectId: val.fieldId,\n\t\t\t\t\ttype: normalizeStructTag(parsedType.typeParams[0]),\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn acc;\n\t\t},\n\t\t{ items: [], itemIds: [], listingIds: [], extensions: [] },\n\t);\n}\n\n/**\n * A helper that attaches the listing prices to kiosk listings.\n */\nexport function attachListingsAndPrices(\n\tkioskData: KioskData,\n\tlistings: KioskListing[],\n\tlistingObjects: SuiClientTypes.Object[],\n) {\n\tconst itemListings = listings.reduce<Record<string, KioskListing>>(\n\t\t(acc: Record<string, KioskListing>, item, idx) => {\n\t\t\tacc[item.objectId] = { ...item };\n\n\t\t\t// return in case we don't have any listing objects.\n\t\t\t// that's the case when we don't have the `listingPrices` included.\n\t\t\tif (listingObjects.length === 0) return acc;\n\n\t\t\tconst obj = listingObjects[idx];\n\n\t\t\t// Parse BCS content to extract the price (u64 value)\n\t\t\tif (obj.content) {\n\t\t\t\tacc[item.objectId].price = bcs.u64().parse(obj.content).toString();\n\t\t\t}\n\n\t\t\treturn acc;\n\t\t},\n\t\t{},\n\t);\n\n\tkioskData.items.forEach((item) => {\n\t\titem.listing = itemListings[item.objectId] || undefined;\n\t});\n}\n\n/**\n * A helper that attaches object data to kiosk items.\n * Works with core API objects that contain BCS content.\n */\nexport function attachObjects(kioskData: KioskData, objects: ObjectWithDisplay[]) {\n\tconst mapping = objects.reduce<Record<string, ObjectWithDisplay>>(\n\t\t(acc: Record<string, ObjectWithDisplay>, obj) => {\n\t\t\tacc[obj.objectId] = obj;\n\t\t\treturn acc;\n\t\t},\n\t\t{},\n\t);\n\n\tkioskData.items.forEach((item) => {\n\t\titem.data = mapping[item.objectId] || undefined;\n\t});\n}\n\n/**\n * A Helper to attach locked state to items in Kiosk Data.\n */\nexport function attachLockedItems(kioskData: KioskData, lockedItemIds: string[]) {\n\t// map lock status in an array of type { item_id: true }\n\tconst lockedStatuses = lockedItemIds.reduce<Record<string, boolean>>(\n\t\t(acc: Record<string, boolean>, item: string) => {\n\t\t\tacc[item] = true;\n\t\t\treturn acc;\n\t\t},\n\t\t{},\n\t);\n\n\t// parse lockedItemIds and attach their locked status.\n\tkioskData.items.forEach((item) => {\n\t\titem.isLocked = lockedStatuses[item.objectId] || false;\n\t});\n}\n\n/**\n * A helper to fetch all dynamic field pages.\n * We need that to fetch the kiosk DFs consistently, until we have\n * RPC calls that allow filtering of Type / batch fetching of spec\n */\nexport async function getAllDynamicFields(\n\tclient: ClientWithCoreApi,\n\tparentId: string,\n\tpagination: PaginationArguments<string>,\n): Promise<DynamicFieldInfo[]> {\n\tlet hasNextPage = true;\n\tlet cursor: string | null = null;\n\tconst data: DynamicFieldInfo[] = [];\n\n\twhile (hasNextPage) {\n\t\tconst result = await client.core.listDynamicFields({\n\t\t\tparentId,\n\t\t\tlimit: pagination.limit || undefined,\n\t\t\tcursor,\n\t\t});\n\n\t\tdata.push(...result.dynamicFields);\n\n\t\thasNextPage = result.hasNextPage;\n\t\tcursor = result.cursor;\n\t}\n\n\treturn data;\n}\n\n/**\n * Converts a number to basis points.\n * Supports up to 2 decimal points.\n * E.g 9.95 -> 995\n * @param percentage A percentage amount in the range [0, 100] including decimals.\n */\nexport function percentageToBasisPoints(percentage: number) {\n\tif (percentage < 0 || percentage > 100)\n\t\tthrow new Error('Percentage needs to be in the [0,100] range.');\n\treturn Math.ceil(percentage * 100);\n}\n\n// Normalizes the packageId part of a rule's type.\nexport function getNormalizedRuleType(rule: string) {\n\tconst normalizedRuleAddress = rule.split('::');\n\tnormalizedRuleAddress[0] = normalizeSuiAddress(normalizedRuleAddress[0]);\n\treturn normalizedRuleAddress.join('::');\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import type { PaginationArguments } from '@mysten/sui/jsonRpc';
|
|
5
|
-
import type {
|
|
5
|
+
import type { SuiClientTypes } from '@mysten/sui/client';
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
8
|
FLOOR_PRICE_RULE_ADDRESS,
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
import type {
|
|
23
23
|
FetchKioskOptions,
|
|
24
24
|
KioskClientOptions,
|
|
25
|
+
KioskCompatibleClient,
|
|
25
26
|
KioskData,
|
|
26
27
|
OwnedKiosks,
|
|
27
28
|
} from '../types/index.js';
|
|
@@ -53,7 +54,7 @@ export function kiosk<const Name extends string = 'kiosk'>({
|
|
|
53
54
|
}: KioskExtensionOptions<Name> = {}) {
|
|
54
55
|
return {
|
|
55
56
|
name,
|
|
56
|
-
register: (client:
|
|
57
|
+
register: (client: KioskCompatibleClient) => {
|
|
57
58
|
return new KioskClient({
|
|
58
59
|
client,
|
|
59
60
|
network: client.network,
|
|
@@ -70,7 +71,7 @@ export function kiosk<const Name extends string = 'kiosk'>({
|
|
|
70
71
|
* If you pass packageIds, all functionality will be managed using these packages.
|
|
71
72
|
*/
|
|
72
73
|
export class KioskClient {
|
|
73
|
-
client:
|
|
74
|
+
client: KioskCompatibleClient;
|
|
74
75
|
network: SuiClientTypes.Network;
|
|
75
76
|
rules: TransferPolicyRule[];
|
|
76
77
|
packageIds?: BaseRulePackageIds;
|
|
@@ -1,13 +1,264 @@
|
|
|
1
1
|
// Copyright (c) Mysten Labs, Inc.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import type {
|
|
4
|
+
import type { SuiClientTypes } from '@mysten/sui/client';
|
|
5
5
|
import { graphql } from '@mysten/sui/graphql/schema';
|
|
6
6
|
import { isSuiGraphQLClient } from '@mysten/sui/graphql';
|
|
7
7
|
import { isSuiJsonRpcClient } from '@mysten/sui/jsonRpc';
|
|
8
|
+
import { normalizeStructTag } from '@mysten/sui/utils';
|
|
9
|
+
import { chunk, fromBase64 } from '@mysten/utils';
|
|
10
|
+
|
|
11
|
+
import type { KioskDisplay, ObjectWithDisplay } from '../types/kiosk.js';
|
|
12
|
+
import type { KioskCompatibleClient } from '../types/index.js';
|
|
13
|
+
|
|
14
|
+
const DEFAULT_QUERY_LIMIT = 50;
|
|
15
|
+
|
|
16
|
+
const FetchObjectsWithDisplayQuery = graphql(`
|
|
17
|
+
query FetchObjectsWithDisplay($objectKeys: [ObjectKey!]!) {
|
|
18
|
+
multiGetObjects(keys: $objectKeys) {
|
|
19
|
+
address
|
|
20
|
+
digest
|
|
21
|
+
version
|
|
22
|
+
asMoveObject {
|
|
23
|
+
contents {
|
|
24
|
+
bcs
|
|
25
|
+
type {
|
|
26
|
+
repr
|
|
27
|
+
}
|
|
28
|
+
display {
|
|
29
|
+
output
|
|
30
|
+
errors
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
asMovePackage {
|
|
35
|
+
__typename
|
|
36
|
+
}
|
|
37
|
+
owner {
|
|
38
|
+
__typename
|
|
39
|
+
... on AddressOwner {
|
|
40
|
+
address {
|
|
41
|
+
address
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
... on ObjectOwner {
|
|
45
|
+
address {
|
|
46
|
+
address
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
... on Shared {
|
|
50
|
+
initialSharedVersion
|
|
51
|
+
}
|
|
52
|
+
... on ConsensusAddressOwner {
|
|
53
|
+
startVersion
|
|
54
|
+
address {
|
|
55
|
+
address
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
previousTransaction {
|
|
60
|
+
digest
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
`);
|
|
65
|
+
|
|
66
|
+
export async function getAllObjects(
|
|
67
|
+
client: KioskCompatibleClient,
|
|
68
|
+
ids: string[],
|
|
69
|
+
): Promise<ObjectWithDisplay[]> {
|
|
70
|
+
if (ids.length === 0) return [];
|
|
71
|
+
|
|
72
|
+
const chunks = chunk(ids, DEFAULT_QUERY_LIMIT);
|
|
73
|
+
const results: ObjectWithDisplay[] = [];
|
|
74
|
+
|
|
75
|
+
if (isSuiGraphQLClient(client)) {
|
|
76
|
+
for (const batch of chunks) {
|
|
77
|
+
const { data } = await client.query({
|
|
78
|
+
query: FetchObjectsWithDisplayQuery,
|
|
79
|
+
variables: {
|
|
80
|
+
objectKeys: batch.map((address) => ({ address })),
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
if (data?.multiGetObjects) {
|
|
85
|
+
for (const obj of data.multiGetObjects) {
|
|
86
|
+
if (!obj) continue;
|
|
87
|
+
|
|
88
|
+
let type: string;
|
|
89
|
+
if (obj.asMovePackage) {
|
|
90
|
+
type = 'package';
|
|
91
|
+
} else if (obj.asMoveObject?.contents?.type?.repr) {
|
|
92
|
+
type = obj.asMoveObject.contents.type.repr;
|
|
93
|
+
} else {
|
|
94
|
+
type = '';
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const bcsContent = obj.asMoveObject?.contents?.bcs
|
|
98
|
+
? fromBase64(obj.asMoveObject.contents.bcs)
|
|
99
|
+
: undefined;
|
|
100
|
+
|
|
101
|
+
const displayData = obj.asMoveObject?.contents?.display;
|
|
102
|
+
const display: KioskDisplay | undefined = displayData
|
|
103
|
+
? {
|
|
104
|
+
data: (displayData.output as Record<string, string> | null) ?? null,
|
|
105
|
+
error: displayData.errors ? JSON.stringify(displayData.errors) : null,
|
|
106
|
+
}
|
|
107
|
+
: undefined;
|
|
108
|
+
|
|
109
|
+
results.push({
|
|
110
|
+
objectId: obj.address,
|
|
111
|
+
version: obj.version?.toString()!,
|
|
112
|
+
digest: obj.digest!,
|
|
113
|
+
type,
|
|
114
|
+
content: bcsContent!,
|
|
115
|
+
owner: mapGraphQLOwner(obj.owner!),
|
|
116
|
+
previousTransaction: (obj.previousTransaction?.digest ?? null)!,
|
|
117
|
+
objectBcs: undefined,
|
|
118
|
+
json: undefined,
|
|
119
|
+
display,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return results;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (isSuiJsonRpcClient(client)) {
|
|
129
|
+
for (const batch of chunks) {
|
|
130
|
+
const responses = await client.multiGetObjects({
|
|
131
|
+
ids: batch,
|
|
132
|
+
options: {
|
|
133
|
+
showDisplay: true,
|
|
134
|
+
showBcs: true,
|
|
135
|
+
showType: true,
|
|
136
|
+
showOwner: true,
|
|
137
|
+
showPreviousTransaction: true,
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
for (const resp of responses) {
|
|
142
|
+
if (!resp.data) continue;
|
|
143
|
+
const obj = resp.data;
|
|
144
|
+
|
|
145
|
+
const bcsContent =
|
|
146
|
+
obj.bcs?.dataType === 'moveObject' ? fromBase64(obj.bcs.bcsBytes) : undefined;
|
|
147
|
+
|
|
148
|
+
const type =
|
|
149
|
+
obj.type && obj.type.includes('::') ? normalizeStructTag(obj.type) : (obj.type ?? '');
|
|
150
|
+
|
|
151
|
+
const display: KioskDisplay | undefined = obj.display
|
|
152
|
+
? {
|
|
153
|
+
data: obj.display.data ?? null,
|
|
154
|
+
error: obj.display.error ? JSON.stringify(obj.display.error) : null,
|
|
155
|
+
}
|
|
156
|
+
: undefined;
|
|
157
|
+
|
|
158
|
+
results.push({
|
|
159
|
+
objectId: obj.objectId,
|
|
160
|
+
version: obj.version,
|
|
161
|
+
digest: obj.digest,
|
|
162
|
+
type,
|
|
163
|
+
content: bcsContent!,
|
|
164
|
+
owner: parseJsonRpcOwner(obj.owner!),
|
|
165
|
+
previousTransaction: (obj.previousTransaction ?? null)!,
|
|
166
|
+
objectBcs: undefined,
|
|
167
|
+
json: undefined,
|
|
168
|
+
display,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return results;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
throw new Error(
|
|
177
|
+
'Object fetching requires a JSON-RPC or GraphQL client. ' +
|
|
178
|
+
'gRPC clients are not supported by the kiosk SDK.',
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function parseJsonRpcOwner(owner: NonNullable<unknown>): SuiClientTypes.ObjectOwner {
|
|
183
|
+
if (owner === 'Immutable') {
|
|
184
|
+
return { $kind: 'Immutable', Immutable: true } as SuiClientTypes.ObjectOwner;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const ownerObj = owner as Record<string, any>;
|
|
188
|
+
|
|
189
|
+
if ('ConsensusAddressOwner' in ownerObj) {
|
|
190
|
+
return {
|
|
191
|
+
$kind: 'ConsensusAddressOwner',
|
|
192
|
+
ConsensusAddressOwner: {
|
|
193
|
+
owner: ownerObj.ConsensusAddressOwner.owner,
|
|
194
|
+
startVersion: ownerObj.ConsensusAddressOwner.start_version,
|
|
195
|
+
},
|
|
196
|
+
} as SuiClientTypes.ObjectOwner;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if ('AddressOwner' in ownerObj) {
|
|
200
|
+
return {
|
|
201
|
+
$kind: 'AddressOwner',
|
|
202
|
+
AddressOwner: ownerObj.AddressOwner,
|
|
203
|
+
} as SuiClientTypes.ObjectOwner;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if ('ObjectOwner' in ownerObj) {
|
|
207
|
+
return {
|
|
208
|
+
$kind: 'ObjectOwner',
|
|
209
|
+
ObjectOwner: ownerObj.ObjectOwner,
|
|
210
|
+
} as SuiClientTypes.ObjectOwner;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if ('Shared' in ownerObj) {
|
|
214
|
+
return {
|
|
215
|
+
$kind: 'Shared',
|
|
216
|
+
Shared: {
|
|
217
|
+
initialSharedVersion: ownerObj.Shared.initial_shared_version,
|
|
218
|
+
},
|
|
219
|
+
} as SuiClientTypes.ObjectOwner;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
throw new Error(`Unknown owner type: ${JSON.stringify(owner)}`);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function mapGraphQLOwner(
|
|
226
|
+
owner: NonNullable<unknown> & { __typename?: string },
|
|
227
|
+
): SuiClientTypes.ObjectOwner {
|
|
228
|
+
const o = owner as Record<string, any>;
|
|
229
|
+
switch (o.__typename) {
|
|
230
|
+
case 'AddressOwner':
|
|
231
|
+
return {
|
|
232
|
+
$kind: 'AddressOwner',
|
|
233
|
+
AddressOwner: o.address?.address!,
|
|
234
|
+
} as SuiClientTypes.ObjectOwner;
|
|
235
|
+
case 'ObjectOwner':
|
|
236
|
+
return {
|
|
237
|
+
$kind: 'ObjectOwner',
|
|
238
|
+
ObjectOwner: o.address?.address!,
|
|
239
|
+
} as SuiClientTypes.ObjectOwner;
|
|
240
|
+
case 'Immutable':
|
|
241
|
+
return { $kind: 'Immutable', Immutable: true } as SuiClientTypes.ObjectOwner;
|
|
242
|
+
case 'Shared':
|
|
243
|
+
return {
|
|
244
|
+
$kind: 'Shared',
|
|
245
|
+
Shared: { initialSharedVersion: String(o.initialSharedVersion) },
|
|
246
|
+
} as SuiClientTypes.ObjectOwner;
|
|
247
|
+
case 'ConsensusAddressOwner':
|
|
248
|
+
return {
|
|
249
|
+
$kind: 'ConsensusAddressOwner',
|
|
250
|
+
ConsensusAddressOwner: {
|
|
251
|
+
owner: o.address?.address!,
|
|
252
|
+
startVersion: String(o.startVersion),
|
|
253
|
+
},
|
|
254
|
+
} as SuiClientTypes.ObjectOwner;
|
|
255
|
+
default:
|
|
256
|
+
throw new Error(`Unknown GraphQL owner type: ${o.__typename}`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
8
259
|
|
|
9
260
|
export async function queryEvents(
|
|
10
|
-
client:
|
|
261
|
+
client: KioskCompatibleClient,
|
|
11
262
|
eventType: string,
|
|
12
263
|
): Promise<{ json: unknown }[]> {
|
|
13
264
|
if (isSuiGraphQLClient(client)) {
|
package/src/query/kiosk.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { isValidSuiAddress } from '@mysten/sui/utils';
|
|
|
8
8
|
import { Extension, ExtensionKey } from '../contracts/0x2/kiosk_extension.js';
|
|
9
9
|
import type {
|
|
10
10
|
FetchKioskOptions,
|
|
11
|
+
KioskCompatibleClient,
|
|
11
12
|
KioskExtension,
|
|
12
13
|
KioskListing,
|
|
13
14
|
OwnedKiosks,
|
|
@@ -20,13 +21,13 @@ import {
|
|
|
20
21
|
attachObjects,
|
|
21
22
|
extractKioskData,
|
|
22
23
|
getAllDynamicFields,
|
|
23
|
-
getAllObjects,
|
|
24
24
|
getKioskObject,
|
|
25
25
|
} from '../utils.js';
|
|
26
|
+
import { getAllObjects } from './client-utils.js';
|
|
26
27
|
import { PersonalKioskCap } from '../contracts/kiosk/personal_kiosk.js';
|
|
27
28
|
|
|
28
29
|
export async function fetchKiosk(
|
|
29
|
-
client:
|
|
30
|
+
client: KioskCompatibleClient,
|
|
30
31
|
kioskId: string,
|
|
31
32
|
pagination: PaginationArguments<string>,
|
|
32
33
|
options: FetchKioskOptions,
|
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import { isValidSuiAddress } from '@mysten/sui/utils';
|
|
5
|
-
import type { ClientWithCoreApi } from '@mysten/sui/client';
|
|
6
5
|
|
|
7
6
|
import {
|
|
8
7
|
TransferPolicyCap as TransferPolicyCapStruct,
|
|
9
8
|
TransferPolicy as TransferPolicyStruct,
|
|
10
9
|
} from '../contracts/0x2/transfer_policy.js';
|
|
11
|
-
import type { TransferPolicy, TransferPolicyCap } from '../types/index.js';
|
|
10
|
+
import type { KioskCompatibleClient, TransferPolicy, TransferPolicyCap } from '../types/index.js';
|
|
12
11
|
import {
|
|
13
12
|
TRANSFER_POLICY_CAP_TYPE,
|
|
14
13
|
TRANSFER_POLICY_CREATED_EVENT,
|
|
@@ -30,7 +29,7 @@ import { queryEvents } from './client-utils.js';
|
|
|
30
29
|
* @throws Error if the client doesn't support event querying
|
|
31
30
|
*/
|
|
32
31
|
export async function queryTransferPolicy(
|
|
33
|
-
client:
|
|
32
|
+
client: KioskCompatibleClient,
|
|
34
33
|
type: string,
|
|
35
34
|
): Promise<TransferPolicy[]> {
|
|
36
35
|
const data = await queryEvents(client, `${TRANSFER_POLICY_CREATED_EVENT}<${type}>`);
|
|
@@ -74,7 +73,7 @@ export async function queryTransferPolicy(
|
|
|
74
73
|
* @returns Array of TransferPolicyCap objects
|
|
75
74
|
*/
|
|
76
75
|
export async function queryTransferPolicyCapsByType(
|
|
77
|
-
client:
|
|
76
|
+
client: KioskCompatibleClient,
|
|
78
77
|
address: string,
|
|
79
78
|
type: string,
|
|
80
79
|
): Promise<TransferPolicyCap[]> {
|
|
@@ -125,7 +124,7 @@ export async function queryTransferPolicyCapsByType(
|
|
|
125
124
|
* @returns Array of TransferPolicyCap objects or undefined if address is invalid
|
|
126
125
|
*/
|
|
127
126
|
export async function queryOwnedTransferPolicies(
|
|
128
|
-
client:
|
|
127
|
+
client: KioskCompatibleClient,
|
|
129
128
|
address: string,
|
|
130
129
|
): Promise<TransferPolicyCap[] | undefined> {
|
|
131
130
|
if (!isValidSuiAddress(address)) return;
|
package/src/types/index.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
// Copyright (c) Mysten Labs, Inc.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import type {
|
|
4
|
+
import type { SuiClientTypes } from '@mysten/sui/client';
|
|
5
5
|
import type { TransactionObjectArgument } from '@mysten/sui/transactions';
|
|
6
6
|
|
|
7
7
|
import type { BaseRulePackageIds } from '../constants.js';
|
|
8
|
+
import { SuiJsonRpcClient } from '@mysten/sui/jsonRpc';
|
|
9
|
+
import { SuiGraphQLClient } from '@mysten/sui/graphql';
|
|
8
10
|
|
|
9
11
|
export * from './kiosk.js';
|
|
10
12
|
export * from './transfer-policy.js';
|
|
@@ -18,7 +20,9 @@ export type ObjectArgument = string | TransactionObjectArgument;
|
|
|
18
20
|
* The Client Options for Both KioskClient & TransferPolicyManager.
|
|
19
21
|
*/
|
|
20
22
|
export type KioskClientOptions = {
|
|
21
|
-
client:
|
|
23
|
+
client: KioskCompatibleClient;
|
|
22
24
|
network: SuiClientTypes.Network;
|
|
23
25
|
packageIds?: BaseRulePackageIds;
|
|
24
26
|
};
|
|
27
|
+
|
|
28
|
+
export type KioskCompatibleClient = SuiJsonRpcClient | SuiGraphQLClient;
|
package/src/types/kiosk.ts
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import type { TransactionArgument } from '@mysten/sui/transactions';
|
|
5
|
-
import { SuiClientTypes } from '@mysten/sui/client';
|
|
6
5
|
|
|
7
6
|
import type { ObjectArgument } from './index.js';
|
|
8
7
|
|
|
9
8
|
import { SUI_FRAMEWORK_ADDRESS } from '@mysten/sui/utils';
|
|
9
|
+
import { SuiClientTypes } from '@mysten/sui/client';
|
|
10
10
|
|
|
11
11
|
/** The Kiosk module. */
|
|
12
12
|
export const KIOSK_MODULE = `${SUI_FRAMEWORK_ADDRESS}::kiosk`;
|
|
@@ -88,6 +88,18 @@ export type KioskListing = {
|
|
|
88
88
|
price?: string;
|
|
89
89
|
};
|
|
90
90
|
|
|
91
|
+
export type KioskDisplay = {
|
|
92
|
+
data: Record<string, string> | null;
|
|
93
|
+
error: string | null;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export type ObjectWithDisplay = SuiClientTypes.Object<{
|
|
97
|
+
content: true;
|
|
98
|
+
previousTransaction: true;
|
|
99
|
+
}> & {
|
|
100
|
+
display?: KioskDisplay;
|
|
101
|
+
};
|
|
102
|
+
|
|
91
103
|
/**
|
|
92
104
|
* A dynamic field `Item { ID }` attached to the Kiosk.
|
|
93
105
|
* Holds an Item `T`. The type of the item is known upfront.
|
|
@@ -103,8 +115,8 @@ export type KioskItem = {
|
|
|
103
115
|
listing?: KioskListing;
|
|
104
116
|
/** The ID of the kiosk the item is placed in */
|
|
105
117
|
kioskId: string;
|
|
106
|
-
/** Optional
|
|
107
|
-
data?:
|
|
118
|
+
/** Optional object data with display metadata */
|
|
119
|
+
data?: ObjectWithDisplay;
|
|
108
120
|
};
|
|
109
121
|
|
|
110
122
|
/** The overview type returned from `getKiosk` */
|
package/src/utils.ts
CHANGED
|
@@ -5,12 +5,9 @@ import { bcs } from '@mysten/sui/bcs';
|
|
|
5
5
|
import { PaginationArguments } from '@mysten/sui/jsonRpc';
|
|
6
6
|
import type { ClientWithCoreApi, SuiClientTypes } from '@mysten/sui/client';
|
|
7
7
|
import { normalizeStructTag, normalizeSuiAddress, parseStructTag } from '@mysten/sui/utils';
|
|
8
|
-
import { chunk } from '@mysten/utils';
|
|
9
8
|
|
|
10
|
-
import { Listing, Lock, Kiosk as KioskStruct } from './contracts/0x2/kiosk.js';
|
|
11
|
-
import type { Kiosk, KioskData, KioskListing } from './types/index.js';
|
|
12
|
-
|
|
13
|
-
const DEFAULT_QUERY_LIMIT = 50;
|
|
9
|
+
import { Item, Listing, Lock, Kiosk as KioskStruct } from './contracts/0x2/kiosk.js';
|
|
10
|
+
import type { Kiosk, KioskData, KioskListing, ObjectWithDisplay } from './types/index.js';
|
|
14
11
|
|
|
15
12
|
export type DynamicFieldInfo = SuiClientTypes.ListDynamicFieldsResponse['dynamicFields'][number];
|
|
16
13
|
|
|
@@ -53,9 +50,10 @@ export function extractKioskData(
|
|
|
53
50
|
baseType ===
|
|
54
51
|
'0x0000000000000000000000000000000000000000000000000000000000000002::kiosk::Item'
|
|
55
52
|
) {
|
|
56
|
-
|
|
53
|
+
const parsed = Item.parse(val.name.bcs);
|
|
54
|
+
acc.itemIds.push(parsed.id);
|
|
57
55
|
acc.items.push({
|
|
58
|
-
objectId:
|
|
56
|
+
objectId: parsed.id,
|
|
59
57
|
type: val.valueType,
|
|
60
58
|
isLocked: false,
|
|
61
59
|
kioskId,
|
|
@@ -137,9 +135,9 @@ export function attachListingsAndPrices(
|
|
|
137
135
|
* A helper that attaches object data to kiosk items.
|
|
138
136
|
* Works with core API objects that contain BCS content.
|
|
139
137
|
*/
|
|
140
|
-
export function attachObjects(kioskData: KioskData, objects:
|
|
141
|
-
const mapping = objects.reduce<Record<string,
|
|
142
|
-
(acc: Record<string,
|
|
138
|
+
export function attachObjects(kioskData: KioskData, objects: ObjectWithDisplay[]) {
|
|
139
|
+
const mapping = objects.reduce<Record<string, ObjectWithDisplay>>(
|
|
140
|
+
(acc: Record<string, ObjectWithDisplay>, obj) => {
|
|
143
141
|
acc[obj.objectId] = obj;
|
|
144
142
|
return acc;
|
|
145
143
|
},
|
|
@@ -200,34 +198,6 @@ export async function getAllDynamicFields(
|
|
|
200
198
|
return data;
|
|
201
199
|
}
|
|
202
200
|
|
|
203
|
-
/**
|
|
204
|
-
* A helper to fetch all objects that works with pagination.
|
|
205
|
-
* It will fetch all objects in the array, and limit it to 50/request.
|
|
206
|
-
* Requests are sent using `Promise.all`.
|
|
207
|
-
*/
|
|
208
|
-
export async function getAllObjects(
|
|
209
|
-
client: ClientWithCoreApi,
|
|
210
|
-
ids: string[],
|
|
211
|
-
): Promise<SuiClientTypes.Object[]> {
|
|
212
|
-
const chunks = chunk(ids, DEFAULT_QUERY_LIMIT);
|
|
213
|
-
|
|
214
|
-
const results = await Promise.all(
|
|
215
|
-
chunks.map(async (objectIds) => {
|
|
216
|
-
const { objects } = await client.core.getObjects({
|
|
217
|
-
objectIds,
|
|
218
|
-
include: {
|
|
219
|
-
content: true,
|
|
220
|
-
previousTransaction: true,
|
|
221
|
-
},
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
return objects.filter((obj): obj is SuiClientTypes.Object => !(obj instanceof Error));
|
|
225
|
-
}),
|
|
226
|
-
);
|
|
227
|
-
|
|
228
|
-
return results.flat();
|
|
229
|
-
}
|
|
230
|
-
|
|
231
201
|
/**
|
|
232
202
|
* Converts a number to basis points.
|
|
233
203
|
* Supports up to 2 decimal points.
|