@mysten/kiosk 0.3.0 → 0.3.2
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 +26 -0
- package/README.md +36 -42
- package/dist/index.js +67 -68
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +68 -68
- package/dist/index.mjs.map +1 -1
- package/dist/query/kiosk.d.ts +10 -52
- package/dist/types/kiosk.d.ts +62 -1
- package/dist/utils.d.ts +20 -4
- package/package.json +9 -13
- package/src/bcs.ts +17 -17
- package/src/constants.ts +2 -2
- package/src/query/kiosk.ts +106 -101
- package/src/query/transfer-policy.ts +31 -37
- package/src/tx/kiosk.ts +232 -289
- package/src/tx/transfer-policy.ts +90 -89
- package/src/types/env.ts +2 -2
- package/src/types/index.ts +2 -10
- package/src/types/kiosk.ts +87 -14
- package/src/types/transfer-policy.ts +6 -6
- package/src/utils.ts +148 -131
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@mysten/kiosk",
|
|
3
3
|
"author": "Mysten Labs <build@mystenlabs.com>",
|
|
4
4
|
"description": "Sui Kiosk library",
|
|
5
|
-
"version": "0.3.
|
|
5
|
+
"version": "0.3.2",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"main": "./dist/index.js",
|
|
8
8
|
"module": "./dist/index.mjs",
|
|
@@ -24,27 +24,23 @@
|
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@mysten/sui.js": "0.
|
|
27
|
+
"@mysten/sui.js": "0.37.0"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"eslint": "^8.38.0",
|
|
31
|
-
"prettier": "^2.8.7",
|
|
32
30
|
"tsup": "^6.7.0",
|
|
33
31
|
"typescript": "^5.0.4"
|
|
34
32
|
},
|
|
35
|
-
"prettier": {
|
|
36
|
-
"printWidth": 80,
|
|
37
|
-
"semi": true,
|
|
38
|
-
"singleQuote": true,
|
|
39
|
-
"trailingComma": "all"
|
|
40
|
-
},
|
|
41
33
|
"scripts": {
|
|
42
34
|
"build": "pnpm build:types && pnpm build:tsup",
|
|
43
35
|
"build:tsup": "tsup ./src/index.ts --format esm,cjs --sourcemap",
|
|
44
36
|
"build:types": "tsc --build",
|
|
45
37
|
"test": "echo \"Error: no test specified\"",
|
|
46
|
-
"
|
|
47
|
-
"prettier:
|
|
48
|
-
"
|
|
38
|
+
"pre-commit": "pnpm prettier:fix && pnpm lint && pnpm build",
|
|
39
|
+
"prettier:check": "prettier -c --ignore-unknown .",
|
|
40
|
+
"prettier:fix": "prettier -w --ignore-unknown .",
|
|
41
|
+
"eslint:check": "eslint --max-warnings=0 .",
|
|
42
|
+
"eslint:fix": "pnpm run eslint:check --fix",
|
|
43
|
+
"lint": "pnpm run eslint:check && pnpm run prettier:check",
|
|
44
|
+
"lint:fix": "pnpm run eslint:fix && pnpm run prettier:fix"
|
|
49
45
|
}
|
|
50
46
|
}
|
package/src/bcs.ts
CHANGED
|
@@ -3,38 +3,38 @@
|
|
|
3
3
|
|
|
4
4
|
import { bcs } from '@mysten/sui.js';
|
|
5
5
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
KIOSK_PURCHASE_CAP,
|
|
7
|
+
KIOSK_TYPE,
|
|
8
|
+
TRANSFER_POLICY_CREATED_EVENT,
|
|
9
|
+
TRANSFER_POLICY_TYPE,
|
|
10
10
|
} from './types';
|
|
11
11
|
|
|
12
12
|
// Register the `Kiosk` struct for faster queries.
|
|
13
13
|
bcs.registerStructType(KIOSK_TYPE, {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
id: 'address',
|
|
15
|
+
profits: 'u64',
|
|
16
|
+
owner: 'address',
|
|
17
|
+
itemCount: 'u32',
|
|
18
|
+
allowExtensions: 'bool',
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
// Register the `PurchaseCap` for faster queries.
|
|
22
22
|
bcs.registerStructType(KIOSK_PURCHASE_CAP, {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
id: 'address',
|
|
24
|
+
kioskId: 'address',
|
|
25
|
+
itemId: 'address',
|
|
26
|
+
minPrice: 'u64',
|
|
27
27
|
});
|
|
28
28
|
|
|
29
29
|
// Register the `TransferPolicyCreated` event data.
|
|
30
30
|
bcs.registerStructType(TRANSFER_POLICY_CREATED_EVENT, {
|
|
31
|
-
|
|
31
|
+
id: 'address',
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
bcs.registerStructType(TRANSFER_POLICY_TYPE, {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
id: 'address',
|
|
36
|
+
balance: 'u64',
|
|
37
|
+
rules: ['vector', 'string'],
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
export { bcs };
|
package/src/constants.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
/** The Transer Policy Rules package address on testnet */
|
|
5
5
|
export const TESTNET_RULES_PACKAGE_ADDRESS =
|
|
6
|
-
|
|
6
|
+
'bd8fc1947cf119350184107a3087e2dc27efefa0dd82e25a1f699069fe81a585';
|
|
7
7
|
|
|
8
8
|
/** The transfer policy rules package address on mainnet */
|
|
9
9
|
export const MAINNET_RULES_PACKAGE_ADDRESS =
|
|
10
|
-
|
|
10
|
+
'0x434b5bd8f6a7b05fede0ff46c6e511d71ea326ed38056e3bcd681d2d7c2a7879';
|
package/src/query/kiosk.ts
CHANGED
|
@@ -2,118 +2,123 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
JsonRpcProvider,
|
|
6
|
+
ObjectId,
|
|
7
|
+
PaginationArguments,
|
|
8
|
+
SuiAddress,
|
|
9
|
+
SuiObjectData,
|
|
10
|
+
SuiObjectResponse,
|
|
11
|
+
getObjectFields,
|
|
12
|
+
isValidSuiAddress,
|
|
10
13
|
} from '@mysten/sui.js';
|
|
11
14
|
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
attachListingsAndPrices,
|
|
16
|
+
attachLockedItems,
|
|
17
|
+
extractKioskData,
|
|
18
|
+
getAllDynamicFields,
|
|
19
|
+
getKioskObject,
|
|
16
20
|
} from '../utils';
|
|
17
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
FetchKioskOptions,
|
|
23
|
+
KIOSK_OWNER_CAP,
|
|
24
|
+
KioskListing,
|
|
25
|
+
OwnedKiosks,
|
|
26
|
+
PagedKioskData,
|
|
27
|
+
} from '../types';
|
|
18
28
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
* TODO: consider renaming the field for better indication.
|
|
31
|
-
*/
|
|
32
|
-
isExclusive: boolean;
|
|
33
|
-
/** The ID of the listing */
|
|
34
|
-
listingId: ObjectId;
|
|
35
|
-
price?: string;
|
|
36
|
-
};
|
|
29
|
+
export async function fetchKiosk(
|
|
30
|
+
provider: JsonRpcProvider,
|
|
31
|
+
kioskId: SuiAddress,
|
|
32
|
+
pagination: PaginationArguments<string>,
|
|
33
|
+
options: FetchKioskOptions,
|
|
34
|
+
): Promise<PagedKioskData> {
|
|
35
|
+
// TODO: Replace the `getAllDynamicFields` with a paginated
|
|
36
|
+
// response, once we have better RPC support for
|
|
37
|
+
// type filtering & batch fetching.
|
|
38
|
+
// This can't work with pagination currently.
|
|
39
|
+
const data = await getAllDynamicFields(provider, kioskId, pagination);
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
* Holds an Item `T`. The type of the item is known upfront.
|
|
41
|
-
*/
|
|
42
|
-
export type KioskItem = {
|
|
43
|
-
/** The ID of the Item */
|
|
44
|
-
objectId: ObjectId;
|
|
45
|
-
/** The type of the Item */
|
|
46
|
-
type: ObjectType;
|
|
47
|
-
/** Whether the item is Locked (there must be a `Lock` Dynamic Field) */
|
|
48
|
-
isLocked: boolean;
|
|
49
|
-
/** Optional listing */
|
|
50
|
-
listing?: KioskListing;
|
|
51
|
-
};
|
|
52
|
-
/**
|
|
53
|
-
* Aggregated data from the Kiosk.
|
|
54
|
-
*/
|
|
55
|
-
export type KioskData = {
|
|
56
|
-
items: KioskItem[];
|
|
57
|
-
itemIds: ObjectId[];
|
|
58
|
-
listingIds: ObjectId[];
|
|
59
|
-
kiosk?: Kiosk;
|
|
60
|
-
extensions: any[]; // type will be defined on later versions of the SDK.
|
|
61
|
-
};
|
|
41
|
+
const listings: KioskListing[] = [];
|
|
42
|
+
const lockedItemIds: ObjectId[] = [];
|
|
62
43
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
nextCursor: string | null;
|
|
66
|
-
hasNextPage: boolean;
|
|
67
|
-
};
|
|
44
|
+
// extracted kiosk data.
|
|
45
|
+
const kioskData = extractKioskData(data, listings, lockedItemIds);
|
|
68
46
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
47
|
+
// split the fetching in two queries as we are most likely passing different options for each kind.
|
|
48
|
+
// For items, we usually seek the Display.
|
|
49
|
+
// For listings we usually seek the DF value (price) / exclusivity.
|
|
50
|
+
const [kiosk, listingObjects] = await Promise.all([
|
|
51
|
+
options.withKioskFields ? getKioskObject(provider, kioskId) : Promise.resolve(undefined),
|
|
52
|
+
options.withListingPrices
|
|
53
|
+
? provider.multiGetObjects({
|
|
54
|
+
ids: kioskData.listingIds,
|
|
55
|
+
options: {
|
|
56
|
+
showContent: true,
|
|
57
|
+
},
|
|
58
|
+
})
|
|
59
|
+
: Promise.resolve([]),
|
|
60
|
+
]);
|
|
73
61
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
): Promise<PagedKioskData> {
|
|
80
|
-
const { data, nextCursor, hasNextPage } = await provider.getDynamicFields({
|
|
81
|
-
parentId: kioskId,
|
|
82
|
-
...pagination,
|
|
83
|
-
});
|
|
62
|
+
if (options.withKioskFields) kioskData.kiosk = kiosk;
|
|
63
|
+
// attach items listings. IF we have `options.withListingPrices === true`, it will also attach the prices.
|
|
64
|
+
attachListingsAndPrices(kioskData, listings, listingObjects);
|
|
65
|
+
// add `locked` status to items that are locked.
|
|
66
|
+
attachLockedItems(kioskData, lockedItemIds);
|
|
84
67
|
|
|
85
|
-
|
|
86
|
-
|
|
68
|
+
return {
|
|
69
|
+
data: kioskData,
|
|
70
|
+
nextCursor: null,
|
|
71
|
+
hasNextPage: false,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* A function to fetch all the user's kiosk Caps
|
|
77
|
+
* And a list of the kiosk address ids.
|
|
78
|
+
* Returns a list of `kioskOwnerCapIds` and `kioskIds`.
|
|
79
|
+
* Extra options allow pagination.
|
|
80
|
+
*/
|
|
81
|
+
export async function getOwnedKiosks(
|
|
82
|
+
provider: JsonRpcProvider,
|
|
83
|
+
address: SuiAddress,
|
|
84
|
+
options?: {
|
|
85
|
+
pagination?: PaginationArguments<string>;
|
|
86
|
+
},
|
|
87
|
+
): Promise<OwnedKiosks> {
|
|
88
|
+
if (!isValidSuiAddress(address))
|
|
89
|
+
return {
|
|
90
|
+
nextCursor: null,
|
|
91
|
+
hasNextPage: false,
|
|
92
|
+
kioskOwnerCaps: [],
|
|
93
|
+
kioskIds: [],
|
|
94
|
+
};
|
|
87
95
|
|
|
88
|
-
|
|
89
|
-
|
|
96
|
+
// fetch owned kiosk caps, paginated.
|
|
97
|
+
const { data, hasNextPage, nextCursor } = await provider.getOwnedObjects({
|
|
98
|
+
owner: address,
|
|
99
|
+
filter: { StructType: KIOSK_OWNER_CAP },
|
|
100
|
+
options: {
|
|
101
|
+
showContent: true,
|
|
102
|
+
},
|
|
103
|
+
...(options?.pagination || {}),
|
|
104
|
+
});
|
|
90
105
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
// For listings we usually seek the DF value (price) / exclusivity.
|
|
94
|
-
const [kiosk, listingObjects] = await Promise.all([
|
|
95
|
-
options.withKioskFields
|
|
96
|
-
? getKioskObject(provider, kioskId)
|
|
97
|
-
: Promise.resolve(undefined),
|
|
98
|
-
options.withListingPrices
|
|
99
|
-
? provider.multiGetObjects({
|
|
100
|
-
ids: kioskData.listingIds,
|
|
101
|
-
options: {
|
|
102
|
-
showContent: true,
|
|
103
|
-
},
|
|
104
|
-
})
|
|
105
|
-
: Promise.resolve([]),
|
|
106
|
-
]);
|
|
106
|
+
// get kioskIds from the OwnerCaps.
|
|
107
|
+
const kioskIdList = data?.map((x: SuiObjectResponse) => getObjectFields(x)?.for);
|
|
107
108
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
// add `locked` status to items that are locked.
|
|
112
|
-
attachLockedItems(kioskData, lockedItemIds);
|
|
109
|
+
// clean up data that might have an error in them.
|
|
110
|
+
// only return valid objects.
|
|
111
|
+
const filteredData = data.filter((x) => 'data' in x).map((x) => x.data) as SuiObjectData[];
|
|
113
112
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
113
|
+
return {
|
|
114
|
+
nextCursor,
|
|
115
|
+
hasNextPage,
|
|
116
|
+
kioskOwnerCaps: filteredData.map((x, idx) => ({
|
|
117
|
+
digest: x.digest,
|
|
118
|
+
version: x.version,
|
|
119
|
+
objectId: x.objectId,
|
|
120
|
+
kioskId: kioskIdList[idx],
|
|
121
|
+
})),
|
|
122
|
+
kioskIds: kioskIdList,
|
|
123
|
+
};
|
|
119
124
|
}
|
|
@@ -3,11 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import { JsonRpcProvider } from '@mysten/sui.js';
|
|
5
5
|
import { bcs } from '../bcs';
|
|
6
|
-
import {
|
|
7
|
-
TRANSFER_POLICY_CREATED_EVENT,
|
|
8
|
-
TRANSFER_POLICY_TYPE,
|
|
9
|
-
TransferPolicy,
|
|
10
|
-
} from '../types';
|
|
6
|
+
import { TRANSFER_POLICY_CREATED_EVENT, TRANSFER_POLICY_TYPE, TransferPolicy } from '../types';
|
|
11
7
|
|
|
12
8
|
/**
|
|
13
9
|
* Searches the `TransferPolicy`-s for the given type. The seach is performed via
|
|
@@ -19,41 +15,39 @@ import {
|
|
|
19
15
|
* @param type
|
|
20
16
|
*/
|
|
21
17
|
export async function queryTransferPolicy(
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
provider: JsonRpcProvider,
|
|
19
|
+
type: string,
|
|
24
20
|
): Promise<TransferPolicy[]> {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
21
|
+
// console.log('event type: %s', `${TRANSFER_POLICY_CREATED_EVENT}<${type}>`);
|
|
22
|
+
const { data } = await provider.queryEvents({
|
|
23
|
+
query: {
|
|
24
|
+
MoveEventType: `${TRANSFER_POLICY_CREATED_EVENT}<${type}>`,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
31
27
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
const search = data.map((event) => event.parsedJson as { id: string });
|
|
29
|
+
const policies = await provider.multiGetObjects({
|
|
30
|
+
ids: search.map((policy) => policy.id),
|
|
31
|
+
options: { showBcs: true, showOwner: true },
|
|
32
|
+
});
|
|
37
33
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
);
|
|
47
|
-
}
|
|
34
|
+
return policies
|
|
35
|
+
.filter((policy) => !!policy && 'data' in policy)
|
|
36
|
+
.map(({ data: policy }) => {
|
|
37
|
+
// should never happen; policies are objects and fetched via an event.
|
|
38
|
+
// policies are filtered for null and undefined above.
|
|
39
|
+
if (!policy || !policy.bcs || !('bcsBytes' in policy.bcs)) {
|
|
40
|
+
throw new Error(`Invalid policy: ${policy?.objectId}, expected object, got package`);
|
|
41
|
+
}
|
|
48
42
|
|
|
49
|
-
|
|
43
|
+
let parsed = bcs.de(TRANSFER_POLICY_TYPE, policy.bcs.bcsBytes, 'base64');
|
|
50
44
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
45
|
+
return {
|
|
46
|
+
id: policy?.objectId,
|
|
47
|
+
type: `${TRANSFER_POLICY_TYPE}<${type}>`,
|
|
48
|
+
owner: policy?.owner!,
|
|
49
|
+
rules: parsed.rules,
|
|
50
|
+
balance: parsed.balance,
|
|
51
|
+
} as TransferPolicy;
|
|
52
|
+
});
|
|
59
53
|
}
|