@haneullabs/kiosk 0.1.0 → 1.1.3
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 +281 -137
- package/README.md +2 -2
- package/dist/client/kiosk-client.d.mts +126 -0
- package/dist/client/kiosk-client.d.mts.map +1 -0
- package/dist/client/kiosk-client.mjs +124 -0
- package/dist/client/kiosk-client.mjs.map +1 -0
- package/dist/client/kiosk-transaction.d.mts +235 -0
- package/dist/client/kiosk-transaction.d.mts.map +1 -0
- package/dist/client/kiosk-transaction.mjs +472 -0
- package/dist/client/kiosk-transaction.mjs.map +1 -0
- package/dist/client/tp-transaction.d.mts +138 -0
- package/dist/client/tp-transaction.d.mts.map +1 -0
- package/dist/client/tp-transaction.mjs +273 -0
- package/dist/client/tp-transaction.mjs.map +1 -0
- package/dist/constants.d.mts +42 -0
- package/dist/constants.d.mts.map +1 -0
- package/dist/constants.mjs +62 -0
- package/dist/constants.mjs.map +1 -0
- package/dist/contracts/0x2/bag.mjs +19 -0
- package/dist/contracts/0x2/bag.mjs.map +1 -0
- package/dist/contracts/0x2/balance.mjs +16 -0
- package/dist/contracts/0x2/balance.mjs.map +1 -0
- package/dist/contracts/0x2/deps/0x0000000000000000000000000000000000000000000000000000000000000001/type_name.mjs +16 -0
- package/dist/contracts/0x2/deps/0x0000000000000000000000000000000000000000000000000000000000000001/type_name.mjs.map +1 -0
- package/dist/contracts/0x2/kiosk.mjs +244 -0
- package/dist/contracts/0x2/kiosk.mjs.map +1 -0
- package/dist/contracts/0x2/kiosk_extension.mjs +25 -0
- package/dist/contracts/0x2/kiosk_extension.mjs.map +1 -0
- package/dist/contracts/0x2/transfer_policy.mjs +99 -0
- package/dist/contracts/0x2/transfer_policy.mjs.map +1 -0
- package/dist/contracts/0x2/vec_set.mjs +18 -0
- package/dist/contracts/0x2/vec_set.mjs.map +1 -0
- package/dist/contracts/kiosk/deps/haneul/kiosk.mjs +98 -0
- package/dist/contracts/kiosk/deps/haneul/kiosk.mjs.map +1 -0
- package/dist/contracts/kiosk/floor_price_rule.mjs +70 -0
- package/dist/contracts/kiosk/floor_price_rule.mjs.map +1 -0
- package/dist/contracts/kiosk/kiosk_lock_rule.mjs +72 -0
- package/dist/contracts/kiosk/kiosk_lock_rule.mjs.map +1 -0
- package/dist/contracts/kiosk/personal_kiosk.mjs +102 -0
- package/dist/contracts/kiosk/personal_kiosk.mjs.map +1 -0
- package/dist/contracts/kiosk/personal_kiosk_rule.mjs +66 -0
- package/dist/contracts/kiosk/personal_kiosk_rule.mjs.map +1 -0
- package/dist/contracts/kiosk/royalty_rule.mjs +115 -0
- package/dist/contracts/kiosk/royalty_rule.mjs.map +1 -0
- package/dist/contracts/utils/index.mjs +118 -0
- package/dist/contracts/utils/index.mjs.map +1 -0
- package/dist/index.d.mts +9 -0
- package/dist/index.mjs +9 -0
- package/dist/query/client-utils.mjs +215 -0
- package/dist/query/client-utils.mjs.map +1 -0
- package/dist/query/kiosk.mjs +155 -0
- package/dist/query/kiosk.mjs.map +1 -0
- package/dist/query/transfer-policy.mjs +110 -0
- package/dist/query/transfer-policy.mjs.map +1 -0
- package/dist/tx/kiosk.mjs +20 -0
- package/dist/tx/kiosk.mjs.map +1 -0
- package/dist/tx/rules/resolve.mjs +114 -0
- package/dist/tx/rules/resolve.mjs.map +1 -0
- package/dist/tx/transfer-policy.mjs +38 -0
- package/dist/tx/transfer-policy.mjs.map +1 -0
- package/dist/types/index.d.mts +25 -0
- package/dist/types/index.d.mts.map +1 -0
- package/dist/types/kiosk.d.mts +161 -0
- package/dist/types/kiosk.d.mts.map +1 -0
- package/dist/types/kiosk.mjs +21 -0
- package/dist/types/kiosk.mjs.map +1 -0
- package/dist/types/transfer-policy.d.mts +56 -0
- package/dist/types/transfer-policy.d.mts.map +1 -0
- package/dist/types/transfer-policy.mjs +19 -0
- package/dist/types/transfer-policy.mjs.map +1 -0
- package/dist/utils.d.mts +39 -0
- package/dist/utils.d.mts.map +1 -0
- package/dist/utils.mjs +137 -0
- package/dist/utils.mjs.map +1 -0
- package/docs/advanced-examples.md +100 -0
- package/docs/from-v1.md +314 -0
- package/docs/index.md +22 -0
- package/docs/kiosk-client/introduction.md +50 -0
- package/docs/kiosk-client/kiosk-transaction/examples.md +119 -0
- package/docs/kiosk-client/kiosk-transaction/kiosk-transaction.md +103 -0
- package/docs/kiosk-client/kiosk-transaction/managing.md +235 -0
- package/docs/kiosk-client/kiosk-transaction/purchasing.md +110 -0
- package/docs/kiosk-client/querying.md +237 -0
- package/docs/kiosk-client/transfer-policy-transaction/introduction.md +79 -0
- package/docs/kiosk-client/transfer-policy-transaction/using-the-manager.md +115 -0
- package/docs/llms-index.md +10 -0
- package/package.json +27 -20
- package/src/client/kiosk-client.ts +43 -5
- package/src/client/kiosk-transaction.ts +144 -65
- package/src/client/tp-transaction.ts +149 -95
- package/src/constants.ts +19 -24
- package/src/contracts/0x2/bag.ts +13 -0
- package/src/contracts/0x2/balance.ts +12 -0
- package/src/contracts/0x2/deps/0x0000000000000000000000000000000000000000000000000000000000000001/type_name.ts +12 -0
- package/src/contracts/0x2/kiosk.ts +797 -0
- package/src/contracts/0x2/kiosk_extension.ts +270 -0
- package/src/contracts/0x2/transfer_policy.ts +400 -0
- package/src/contracts/0x2/vec_set.ts +14 -0
- package/src/contracts/kiosk/deps/haneul/kiosk.ts +94 -0
- package/src/contracts/kiosk/floor_price_rule.ts +92 -0
- package/src/contracts/kiosk/kiosk_lock_rule.ts +97 -0
- package/src/contracts/kiosk/personal_kiosk.ts +295 -0
- package/src/contracts/kiosk/personal_kiosk_rule.ts +89 -0
- package/src/contracts/kiosk/royalty_rule.ts +144 -0
- package/src/contracts/kiosk/witness_rule.ts +92 -0
- package/src/contracts/utils/index.ts +234 -0
- package/src/query/client-utils.ts +302 -0
- package/src/query/kiosk.ts +130 -101
- package/src/query/transfer-policy.ts +112 -79
- package/src/tx/kiosk.ts +7 -231
- package/src/tx/rules/resolve.ts +97 -48
- package/src/tx/transfer-policy.ts +25 -86
- package/src/types/index.ts +7 -14
- package/src/types/kiosk.ts +25 -12
- package/src/types/transfer-policy.ts +4 -4
- package/src/utils.ts +79 -147
- package/dist/cjs/bcs.d.ts +0 -23
- package/dist/cjs/bcs.js +0 -50
- package/dist/cjs/bcs.js.map +0 -7
- package/dist/cjs/client/kiosk-client.d.ts +0 -76
- package/dist/cjs/client/kiosk-client.js +0 -123
- package/dist/cjs/client/kiosk-client.js.map +0 -7
- package/dist/cjs/client/kiosk-transaction.d.ts +0 -186
- package/dist/cjs/client/kiosk-transaction.js +0 -462
- package/dist/cjs/client/kiosk-transaction.js.map +0 -7
- package/dist/cjs/client/tp-transaction.d.ts +0 -114
- package/dist/cjs/client/tp-transaction.js +0 -307
- package/dist/cjs/client/tp-transaction.js.map +0 -7
- package/dist/cjs/constants.d.ts +0 -31
- package/dist/cjs/constants.js +0 -102
- package/dist/cjs/constants.js.map +0 -7
- package/dist/cjs/index.d.ts +0 -6
- package/dist/cjs/index.js +0 -24
- package/dist/cjs/index.js.map +0 -7
- package/dist/cjs/package.json +0 -5
- package/dist/cjs/query/kiosk.d.ts +0 -8
- package/dist/cjs/query/kiosk.js +0 -181
- package/dist/cjs/query/kiosk.js.map +0 -7
- package/dist/cjs/query/transfer-policy.d.ts +0 -29
- package/dist/cjs/query/transfer-policy.js +0 -92
- package/dist/cjs/query/transfer-policy.js.map +0 -7
- package/dist/cjs/tx/kiosk.d.ts +0 -71
- package/dist/cjs/tx/kiosk.js +0 -130
- package/dist/cjs/tx/kiosk.js.map +0 -7
- package/dist/cjs/tx/personal-kiosk.d.ts +0 -7
- package/dist/cjs/tx/personal-kiosk.js +0 -38
- package/dist/cjs/tx/personal-kiosk.js.map +0 -7
- package/dist/cjs/tx/rules/attach.d.ts +0 -7
- package/dist/cjs/tx/rules/attach.js +0 -62
- package/dist/cjs/tx/rules/attach.js.map +0 -7
- package/dist/cjs/tx/rules/resolve.d.ts +0 -15
- package/dist/cjs/tx/rules/resolve.js +0 -109
- package/dist/cjs/tx/rules/resolve.js.map +0 -7
- package/dist/cjs/tx/transfer-policy.d.ts +0 -29
- package/dist/cjs/tx/transfer-policy.js +0 -78
- package/dist/cjs/tx/transfer-policy.js.map +0 -7
- package/dist/cjs/types/index.d.ts +0 -27
- package/dist/cjs/types/index.js +0 -33
- package/dist/cjs/types/index.js.map +0 -7
- package/dist/cjs/types/kiosk.d.ts +0 -160
- package/dist/cjs/types/kiosk.js +0 -37
- package/dist/cjs/types/kiosk.js.map +0 -7
- package/dist/cjs/types/transfer-policy.d.ts +0 -53
- package/dist/cjs/types/transfer-policy.js +0 -35
- package/dist/cjs/types/transfer-policy.js.map +0 -7
- package/dist/cjs/utils.d.ts +0 -51
- package/dist/cjs/utils.js +0 -198
- package/dist/cjs/utils.js.map +0 -7
- package/dist/esm/bcs.d.ts +0 -23
- package/dist/esm/bcs.js +0 -35
- package/dist/esm/bcs.js.map +0 -7
- package/dist/esm/client/kiosk-client.d.ts +0 -76
- package/dist/esm/client/kiosk-client.js +0 -114
- package/dist/esm/client/kiosk-client.js.map +0 -7
- package/dist/esm/client/kiosk-transaction.d.ts +0 -186
- package/dist/esm/client/kiosk-transaction.js +0 -432
- package/dist/esm/client/kiosk-transaction.js.map +0 -7
- package/dist/esm/client/tp-transaction.d.ts +0 -114
- package/dist/esm/client/tp-transaction.js +0 -298
- package/dist/esm/client/tp-transaction.js.map +0 -7
- package/dist/esm/constants.d.ts +0 -31
- package/dist/esm/constants.js +0 -87
- package/dist/esm/constants.js.map +0 -7
- package/dist/esm/index.d.ts +0 -6
- package/dist/esm/index.js +0 -7
- package/dist/esm/index.js.map +0 -7
- package/dist/esm/package.json +0 -5
- package/dist/esm/query/kiosk.d.ts +0 -8
- package/dist/esm/query/kiosk.js +0 -169
- package/dist/esm/query/kiosk.js.map +0 -7
- package/dist/esm/query/transfer-policy.d.ts +0 -29
- package/dist/esm/query/transfer-policy.js +0 -76
- package/dist/esm/query/transfer-policy.js.map +0 -7
- package/dist/esm/tx/kiosk.d.ts +0 -71
- package/dist/esm/tx/kiosk.js +0 -110
- package/dist/esm/tx/kiosk.js.map +0 -7
- package/dist/esm/tx/personal-kiosk.d.ts +0 -7
- package/dist/esm/tx/personal-kiosk.js +0 -18
- package/dist/esm/tx/personal-kiosk.js.map +0 -7
- package/dist/esm/tx/rules/attach.d.ts +0 -7
- package/dist/esm/tx/rules/attach.js +0 -42
- package/dist/esm/tx/rules/attach.js.map +0 -7
- package/dist/esm/tx/rules/resolve.d.ts +0 -15
- package/dist/esm/tx/rules/resolve.js +0 -89
- package/dist/esm/tx/rules/resolve.js.map +0 -7
- package/dist/esm/tx/transfer-policy.d.ts +0 -29
- package/dist/esm/tx/transfer-policy.js +0 -58
- package/dist/esm/tx/transfer-policy.js.map +0 -7
- package/dist/esm/types/index.d.ts +0 -27
- package/dist/esm/types/index.js +0 -12
- package/dist/esm/types/index.js.map +0 -7
- package/dist/esm/types/kiosk.d.ts +0 -160
- package/dist/esm/types/kiosk.js +0 -17
- package/dist/esm/types/kiosk.js.map +0 -7
- package/dist/esm/types/transfer-policy.d.ts +0 -53
- package/dist/esm/types/transfer-policy.js +0 -15
- package/dist/esm/types/transfer-policy.js.map +0 -7
- package/dist/esm/utils.d.ts +0 -51
- package/dist/esm/utils.js +0 -183
- package/dist/esm/utils.js.map +0 -7
- package/dist/tsconfig.esm.tsbuildinfo +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/bcs.ts +0 -39
- package/src/tx/personal-kiosk.ts +0 -34
- package/src/tx/rules/attach.ts +0 -73
package/dist/utils.mjs
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { Item, Kiosk, Listing, Lock } from "./contracts/0x2/kiosk.mjs";
|
|
2
|
+
import { bcs } from "@haneullabs/haneul/bcs";
|
|
3
|
+
import { normalizeHaneulAddress, normalizeStructTag, parseStructTag } from "@haneullabs/haneul/utils";
|
|
4
|
+
|
|
5
|
+
//#region src/utils.ts
|
|
6
|
+
async function getKioskObject(client, id) {
|
|
7
|
+
const { object } = await client.core.getObject({
|
|
8
|
+
objectId: id,
|
|
9
|
+
include: { content: true }
|
|
10
|
+
});
|
|
11
|
+
if (!object.content) throw new Error(`Kiosk ${id} not found or has no content`);
|
|
12
|
+
const parsed = Kiosk.parse(object.content);
|
|
13
|
+
return {
|
|
14
|
+
id: parsed.id,
|
|
15
|
+
profits: parsed.profits.value.toString(),
|
|
16
|
+
owner: parsed.owner,
|
|
17
|
+
itemCount: parsed.item_count,
|
|
18
|
+
allowExtensions: parsed.allow_extensions
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function extractKioskData(data, listings, lockedItemIds, kioskId) {
|
|
22
|
+
return data.reduce((acc, val) => {
|
|
23
|
+
const type = val.name.type;
|
|
24
|
+
const parsedType = parseStructTag(type);
|
|
25
|
+
const baseType = `${normalizeHaneulAddress(parsedType.address)}::${parsedType.module}::${parsedType.name}`;
|
|
26
|
+
if (baseType === "0x0000000000000000000000000000000000000000000000000000000000000002::kiosk::Item") {
|
|
27
|
+
const parsed = Item.parse(val.name.bcs);
|
|
28
|
+
acc.itemIds.push(parsed.id);
|
|
29
|
+
acc.items.push({
|
|
30
|
+
objectId: parsed.id,
|
|
31
|
+
type: val.valueType,
|
|
32
|
+
isLocked: false,
|
|
33
|
+
kioskId
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
if (baseType === "0x0000000000000000000000000000000000000000000000000000000000000002::kiosk::Listing") {
|
|
37
|
+
const parsed = Listing.parse(val.name.bcs);
|
|
38
|
+
acc.listingIds.push(val.fieldId);
|
|
39
|
+
listings.push({
|
|
40
|
+
objectId: parsed.id,
|
|
41
|
+
listingId: val.fieldId,
|
|
42
|
+
isExclusive: parsed.is_exclusive
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
if (baseType === "0x0000000000000000000000000000000000000000000000000000000000000002::kiosk::Lock") lockedItemIds?.push(Lock.parse(val.name.bcs).id);
|
|
46
|
+
if (baseType === "0x0000000000000000000000000000000000000000000000000000000000000002::kiosk_extension::ExtensionKey") acc.extensions.push({
|
|
47
|
+
objectId: val.fieldId,
|
|
48
|
+
type: normalizeStructTag(parsedType.typeParams[0])
|
|
49
|
+
});
|
|
50
|
+
return acc;
|
|
51
|
+
}, {
|
|
52
|
+
items: [],
|
|
53
|
+
itemIds: [],
|
|
54
|
+
listingIds: [],
|
|
55
|
+
extensions: []
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A helper that attaches the listing prices to kiosk listings.
|
|
60
|
+
*/
|
|
61
|
+
function attachListingsAndPrices(kioskData, listings, listingObjects) {
|
|
62
|
+
const itemListings = listings.reduce((acc, item, idx) => {
|
|
63
|
+
acc[item.objectId] = { ...item };
|
|
64
|
+
if (listingObjects.length === 0) return acc;
|
|
65
|
+
const obj = listingObjects[idx];
|
|
66
|
+
if (obj.content) acc[item.objectId].price = bcs.u64().parse(obj.content).toString();
|
|
67
|
+
return acc;
|
|
68
|
+
}, {});
|
|
69
|
+
kioskData.items.forEach((item) => {
|
|
70
|
+
item.listing = itemListings[item.objectId] || void 0;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* A helper that attaches object data to kiosk items.
|
|
75
|
+
* Works with core API objects that contain BCS content.
|
|
76
|
+
*/
|
|
77
|
+
function attachObjects(kioskData, objects) {
|
|
78
|
+
const mapping = objects.reduce((acc, obj) => {
|
|
79
|
+
acc[obj.objectId] = obj;
|
|
80
|
+
return acc;
|
|
81
|
+
}, {});
|
|
82
|
+
kioskData.items.forEach((item) => {
|
|
83
|
+
item.data = mapping[item.objectId] || void 0;
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* A Helper to attach locked state to items in Kiosk Data.
|
|
88
|
+
*/
|
|
89
|
+
function attachLockedItems(kioskData, lockedItemIds) {
|
|
90
|
+
const lockedStatuses = lockedItemIds.reduce((acc, item) => {
|
|
91
|
+
acc[item] = true;
|
|
92
|
+
return acc;
|
|
93
|
+
}, {});
|
|
94
|
+
kioskData.items.forEach((item) => {
|
|
95
|
+
item.isLocked = lockedStatuses[item.objectId] || false;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* A helper to fetch all dynamic field pages.
|
|
100
|
+
* We need that to fetch the kiosk DFs consistently, until we have
|
|
101
|
+
* RPC calls that allow filtering of Type / batch fetching of spec
|
|
102
|
+
*/
|
|
103
|
+
async function getAllDynamicFields(client, parentId, pagination) {
|
|
104
|
+
let hasNextPage = true;
|
|
105
|
+
let cursor = null;
|
|
106
|
+
const data = [];
|
|
107
|
+
while (hasNextPage) {
|
|
108
|
+
const result = await client.core.listDynamicFields({
|
|
109
|
+
parentId,
|
|
110
|
+
limit: pagination.limit || void 0,
|
|
111
|
+
cursor
|
|
112
|
+
});
|
|
113
|
+
data.push(...result.dynamicFields);
|
|
114
|
+
hasNextPage = result.hasNextPage;
|
|
115
|
+
cursor = result.cursor;
|
|
116
|
+
}
|
|
117
|
+
return data;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Converts a number to basis points.
|
|
121
|
+
* Supports up to 2 decimal points.
|
|
122
|
+
* E.g 9.95 -> 995
|
|
123
|
+
* @param percentage A percentage amount in the range [0, 100] including decimals.
|
|
124
|
+
*/
|
|
125
|
+
function percentageToBasisPoints(percentage) {
|
|
126
|
+
if (percentage < 0 || percentage > 100) throw new Error("Percentage needs to be in the [0,100] range.");
|
|
127
|
+
return Math.ceil(percentage * 100);
|
|
128
|
+
}
|
|
129
|
+
function getNormalizedRuleType(rule) {
|
|
130
|
+
const normalizedRuleAddress = rule.split("::");
|
|
131
|
+
normalizedRuleAddress[0] = normalizeHaneulAddress(normalizedRuleAddress[0]);
|
|
132
|
+
return normalizedRuleAddress.join("::");
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
//#endregion
|
|
136
|
+
export { attachListingsAndPrices, attachLockedItems, attachObjects, extractKioskData, getAllDynamicFields, getKioskObject, getNormalizedRuleType, percentageToBasisPoints };
|
|
137
|
+
//# sourceMappingURL=utils.mjs.map
|
|
@@ -0,0 +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 '@haneullabs/haneul/bcs';\nimport { PaginationArguments } from '@haneullabs/haneul/jsonRpc';\nimport type { ClientWithCoreApi, HaneulClientTypes } from '@haneullabs/haneul/client';\nimport { normalizeStructTag, normalizeHaneulAddress, parseStructTag } from '@haneullabs/haneul/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 = HaneulClientTypes.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 = `${normalizeHaneulAddress(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: ObjectWithDisplay[],\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] = normalizeHaneulAddress(normalizedRuleAddress[0]);\n\treturn normalizedRuleAddress.join('::');\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Advanced Examples
|
|
2
|
+
|
|
3
|
+
> Advanced Kiosk SDK usage patterns and examples
|
|
4
|
+
|
|
5
|
+
# Some extended examples
|
|
6
|
+
|
|
7
|
+
For these examples, assume you have the following data and functions available:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// a constant for bullshark's type.
|
|
11
|
+
const bullsharkType = `${packageId}::haneulfrens::HaneulFren<${packageId}::bullshark::Bullshark>`;
|
|
12
|
+
// a constant for capy's type.
|
|
13
|
+
const capyType = `${packageId}::haneulfrens::HaneulFren<${packageId}::capy::Capy>`;
|
|
14
|
+
|
|
15
|
+
// initialize the client with the kiosk extension.
|
|
16
|
+
const client = new HaneulJsonRpcClient({
|
|
17
|
+
url: getJsonRpcFullnodeUrl('mainnet'),
|
|
18
|
+
network: 'mainnet',
|
|
19
|
+
}).$extend(kiosk());
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Minting a HaneulFren
|
|
23
|
+
|
|
24
|
+
This example demonstrates how to mint a HaneulFren.
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
async function mintFren(address: string) {
|
|
28
|
+
const { kioskOwnerCaps } = await client.kiosk.getOwnedKiosks({ address });
|
|
29
|
+
|
|
30
|
+
// Choose the first kiosk for simplicity. We could have extra logic here (e.g. let the user choose, pick a personal one, etc).
|
|
31
|
+
const cap = kioskOwnerCaps[0];
|
|
32
|
+
|
|
33
|
+
const tx = new Transaction();
|
|
34
|
+
const kioskTx = new KioskTransaction({ transaction: tx, kioskClient: client.kiosk, cap });
|
|
35
|
+
|
|
36
|
+
// We're mixing the logic here. If the cap is undefined, we create a new kiosk.
|
|
37
|
+
if (!cap) kioskTx.create();
|
|
38
|
+
|
|
39
|
+
// Let's mint a capy here into the kiosk (either a new or an existing one).
|
|
40
|
+
tx.moveCall({
|
|
41
|
+
target: `${packageId}::haneulfrens::mint_app::mint`,
|
|
42
|
+
arguments: [kioskTx.getKiosk(), kioskTx.getKioskCap()],
|
|
43
|
+
typeArguments: [capyType],
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// If we don't have a cap, that means we create a new kiosk for the user in this flow.
|
|
47
|
+
if (!cap) kioskTx.shareAndTransferCap(address);
|
|
48
|
+
|
|
49
|
+
kioskTx.finalize();
|
|
50
|
+
|
|
51
|
+
// sign and execute transaction.
|
|
52
|
+
await signAndExecuteTransaction({ tx: tx });
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Mixing two Haneulfrens
|
|
57
|
+
|
|
58
|
+
This example demonstrates how to use the Kiosk SDK to mix two `bullsharks`.
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
// We're mixing two frens.
|
|
62
|
+
async function mixFrens(firstFrenObjectId: string, secondFrenObjectId: string, cap: KioskOwnerCap) {
|
|
63
|
+
const tx = new Transaction();
|
|
64
|
+
const kioskTx = new KioskTransaction({ transaction: tx, kioskClient: client.kiosk, cap });
|
|
65
|
+
|
|
66
|
+
// borrow both frens.
|
|
67
|
+
const [fren1, promise1] = kioskTx.borrow({
|
|
68
|
+
itemType: bullsharkType,
|
|
69
|
+
itemId: firstFrenObjectId,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const [fren2, promise2] = kioskTx.borrow({
|
|
73
|
+
itemType: bullsharkType,
|
|
74
|
+
itemId: secondFrenObjectId,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// Let's call the mix function. We skip any payment related stuff here.
|
|
78
|
+
tx.moveCall({
|
|
79
|
+
target: `${packageId}::mix_app::mix`,
|
|
80
|
+
arguments: [fren1, fren2, kioskTx.getKiosk(), kioskTx.getKioskCap()],
|
|
81
|
+
typeArguments: [bullsharkType],
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
kioskTx
|
|
85
|
+
.return({
|
|
86
|
+
itemType: bullsharkType,
|
|
87
|
+
item: fren1,
|
|
88
|
+
promise: promise1,
|
|
89
|
+
})
|
|
90
|
+
.return({
|
|
91
|
+
itemType: bullsharkType,
|
|
92
|
+
item: fren2,
|
|
93
|
+
promise: promise2,
|
|
94
|
+
})
|
|
95
|
+
.finalize();
|
|
96
|
+
|
|
97
|
+
// sign and execute transaction.
|
|
98
|
+
await signAndExecuteTransaction({ tx: tx });
|
|
99
|
+
}
|
|
100
|
+
```
|
package/docs/from-v1.md
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
# Migrating from Kiosk SDK V1
|
|
2
|
+
|
|
3
|
+
> Migrate from Kiosk SDK v1 to the current version
|
|
4
|
+
|
|
5
|
+
The original version of Kiosk SDK provided basic experimentation with the Kiosk API. The new version
|
|
6
|
+
of the SDK (0.7+) provides a more robust experience for building kiosk/transfer policy transactions.
|
|
7
|
+
|
|
8
|
+
The new SDK offers a builder-pattern API, which provides better autocomplete capabilities, and also
|
|
9
|
+
makes code more readable.
|
|
10
|
+
|
|
11
|
+
While a one-to-one mapping between the old and new SDK is not possible, the following examples
|
|
12
|
+
should help you get started.
|
|
13
|
+
|
|
14
|
+
> An important benefit of the new SDK is that it works seamlessly with Personal Kiosk, which was not
|
|
15
|
+
> the case with the previous SDK (you would always have to wrap the transaction with `borrow_cap` /
|
|
16
|
+
> `return_cap` calls depending on whether the kiosk is personal or not).
|
|
17
|
+
|
|
18
|
+
## Placing an item to kiosk and listing it for sale
|
|
19
|
+
|
|
20
|
+
The following example is from the original Kiosk SDK V1 documentation.
|
|
21
|
+
|
|
22
|
+
### Before
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
const placeAndListToKiosk = async () => {
|
|
26
|
+
const kiosk = 'SomeKioskId';
|
|
27
|
+
const kioskCap = 'KioskCapObjectId';
|
|
28
|
+
const itemType = '0xItemAddr::some:ItemType';
|
|
29
|
+
const item = 'SomeItemId';
|
|
30
|
+
const price = '100000';
|
|
31
|
+
|
|
32
|
+
const tx = new Transaction();
|
|
33
|
+
|
|
34
|
+
placeAndList(tx, itemType, kiosk, kioskCap, item, price);
|
|
35
|
+
|
|
36
|
+
// ... continue to sign and execute the transaction
|
|
37
|
+
// ...
|
|
38
|
+
};
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### After
|
|
42
|
+
|
|
43
|
+
Using the new SDK, you can build the same transaction as follows:
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
// You need to do this only once and re-use it in the application.
|
|
47
|
+
const client = new HaneulJsonRpcClient({
|
|
48
|
+
url: getJsonRpcFullnodeUrl('mainnet'),
|
|
49
|
+
network: 'mainnet',
|
|
50
|
+
}).$extend(kiosk());
|
|
51
|
+
|
|
52
|
+
const placeAndListToKiosk = async () => {
|
|
53
|
+
// Assume you have saved the user's preferred kiosk Cap somewhere in your app's state.
|
|
54
|
+
const { kioskOwnerCaps } = await client.kiosk.getOwnedKiosks({ address: '0xSomeAddress' });
|
|
55
|
+
|
|
56
|
+
const tx = new Transaction();
|
|
57
|
+
|
|
58
|
+
// Assume you use the first owned kiosk.
|
|
59
|
+
new KioskTransaction({ transaction: tx, kioskClient: client.kiosk, cap: kioskOwnerCaps[0] })
|
|
60
|
+
.placeAndList({
|
|
61
|
+
itemType: '0xItemAddr::some:ItemType',
|
|
62
|
+
item: 'SomeItemId',
|
|
63
|
+
price: '100000',
|
|
64
|
+
})
|
|
65
|
+
.finalize();
|
|
66
|
+
|
|
67
|
+
// ... continue to sign and execute the transaction
|
|
68
|
+
};
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Create a new kiosk
|
|
72
|
+
|
|
73
|
+
The following example is from the original Kiosk SDK V1 documentation.
|
|
74
|
+
|
|
75
|
+
### Before
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
const createKiosk = async () => {
|
|
79
|
+
const accountAddress = '0xSomeHaneulAddress';
|
|
80
|
+
|
|
81
|
+
const tx = new Transaction();
|
|
82
|
+
const kiosk_cap = createKioskAndShare(tx);
|
|
83
|
+
|
|
84
|
+
tx.transferObjects([kiosk_cap], accountAddress);
|
|
85
|
+
|
|
86
|
+
// ... continue to sign and execute the transaction
|
|
87
|
+
// ...
|
|
88
|
+
};
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### After
|
|
92
|
+
|
|
93
|
+
Using the new SDK, you can build the same transaction as follows:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
// You need to do this only once and re-use it in the application.
|
|
97
|
+
const client = new HaneulJsonRpcClient({
|
|
98
|
+
url: getJsonRpcFullnodeUrl('mainnet'),
|
|
99
|
+
network: 'mainnet',
|
|
100
|
+
}).$extend(kiosk());
|
|
101
|
+
|
|
102
|
+
const createKiosk = async () => {
|
|
103
|
+
const tx = new Transaction();
|
|
104
|
+
|
|
105
|
+
const kioskTx = new KioskTransaction({ transaction: tx, kioskClient: client.kiosk });
|
|
106
|
+
|
|
107
|
+
kioskTx.create().shareAndTransferCap('0xSomeHaneulAddress').finalize();
|
|
108
|
+
|
|
109
|
+
// ... continue to sign and execute the transaction
|
|
110
|
+
};
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Purchasing an item and resolving rules
|
|
114
|
+
|
|
115
|
+
The following example is from the original Kiosk SDK V1 documentation.
|
|
116
|
+
|
|
117
|
+
### Before
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
|
|
121
|
+
queryTransferPolicy,
|
|
122
|
+
purchaseAndResolvePolicies,
|
|
123
|
+
place,
|
|
124
|
+
testnetEnvironment,
|
|
125
|
+
} from '@haneullabs/kiosk';
|
|
126
|
+
|
|
127
|
+
const client = new HaneulJsonRpcClient({
|
|
128
|
+
url: 'https://fullnode.testnet.haneul.io:443',
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// The kiosk we're purchasing from.
|
|
132
|
+
const kioskId = `0xSomeKioskAddress`;
|
|
133
|
+
// A sample item retrieved from `fetchKiosk` function (or hard-coded).
|
|
134
|
+
const item = {
|
|
135
|
+
isLocked: false,
|
|
136
|
+
objectId: '0xb892d61a9992a10c9453efcdbd14ca9720d7dc1000a2048224209c9e544ed223',
|
|
137
|
+
type: '0x52852c4ba80040395b259c641e70b702426a58990ff73cecf5afd31954429090::test::TestItem',
|
|
138
|
+
listing: {
|
|
139
|
+
isExclusive: false,
|
|
140
|
+
listingId: '0x368b512ff2514dbea814f26ec9a3d41198c00e8ed778099961e9ed22a9f0032b',
|
|
141
|
+
price: '20000000000', // in GEUNHWA
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
const ownedKiosk = `0xMyKioskAddress`;
|
|
145
|
+
const ownedKioskCap = `0xMyKioskOwnerCap`;
|
|
146
|
+
|
|
147
|
+
const purchaseItem = async (item, kioskId) => {
|
|
148
|
+
// Fetch the policy of the item (could be an array, if there's more than one transfer policy)
|
|
149
|
+
const policies = await queryTransferPolicy(client, item.type);
|
|
150
|
+
// Selecting the first one for simplicity.
|
|
151
|
+
const policyId = policy[0]?.id;
|
|
152
|
+
// Initialize transaction.
|
|
153
|
+
const tx = new Transaction();
|
|
154
|
+
|
|
155
|
+
// Both are required if there is a `kiosk_lock_rule`.
|
|
156
|
+
// Optional otherwise. Function throws an error if there's a kiosk_lock_rule and these are missing.
|
|
157
|
+
const extraParams = {
|
|
158
|
+
ownedKiosk,
|
|
159
|
+
ownedKioskCap,
|
|
160
|
+
};
|
|
161
|
+
// Define the environment.
|
|
162
|
+
// To use a custom package address for rules, you could call:
|
|
163
|
+
// const environment = customEnvironment('<PackageAddress>');
|
|
164
|
+
const environment = testnetEnvironment;
|
|
165
|
+
|
|
166
|
+
// Extra params. Optional, but required if the user tries to resolve a `kiosk_lock_rule`.
|
|
167
|
+
// Purchases the item. Supports `kiosk_lock_rule`, `royalty_rule` (accepts combination too).
|
|
168
|
+
const result = purchaseAndResolvePolicies(
|
|
169
|
+
tx,
|
|
170
|
+
item.type,
|
|
171
|
+
item.listing.price,
|
|
172
|
+
kioskId,
|
|
173
|
+
item.objectId,
|
|
174
|
+
policy[0],
|
|
175
|
+
environment,
|
|
176
|
+
extraParams,
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
// result = {item: <the_purchased_item>, canTransfer: true/false // depending on whether there was a kiosk lock rule }
|
|
180
|
+
// If the item didn't have a kiosk_lock_rule, you need to do something with it.
|
|
181
|
+
// For example, place it in your own kiosk. (demonstrated below)
|
|
182
|
+
if (result.canTransfer) place(tx, item.type, ownedKiosk, ownedKioskCap, result.item);
|
|
183
|
+
|
|
184
|
+
// ...finally, sign PTB & execute it.
|
|
185
|
+
};
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### After
|
|
189
|
+
|
|
190
|
+
Using the new SDK, you can build the same transaction as follows:
|
|
191
|
+
|
|
192
|
+
> This works with both personal and non-personal kiosks.
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
// You need to do this only once and re-use it in the application.
|
|
196
|
+
const client = new HaneulJsonRpcClient({
|
|
197
|
+
url: getJsonRpcFullnodeUrl('mainnet'),
|
|
198
|
+
network: 'mainnet',
|
|
199
|
+
}).$extend(kiosk());
|
|
200
|
+
|
|
201
|
+
// An Item as returned from `client.kiosk.getKiosk()` call.
|
|
202
|
+
const item = {
|
|
203
|
+
isLocked: false,
|
|
204
|
+
objectId: '0xb892d61a9992a10c9453efcdbd14ca9720d7dc1000a2048224209c9e544ed223',
|
|
205
|
+
type: '0x52852c4ba80040395b259c641e70b702426a58990ff73cecf5afd31954429090::test::TestItem',
|
|
206
|
+
kioskId: '0xSomeKioskAddress',
|
|
207
|
+
listing: {
|
|
208
|
+
isExclusive: false,
|
|
209
|
+
listingId: '0x368b512ff2514dbea814f26ec9a3d41198c00e8ed778099961e9ed22a9f0032b',
|
|
210
|
+
price: '20000000000', // in GEUNHWA
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
const purchase = async () => {
|
|
215
|
+
// Assume you have saved the user's preferred kiosk Cap somewhere in your app's state.
|
|
216
|
+
// You wouldn't need to query this for every purchase.
|
|
217
|
+
const { kioskOwnerCaps } = await client.kiosk.getOwnedKiosks({ address: '0xSomeAddress' });
|
|
218
|
+
|
|
219
|
+
const tx = new Transaction();
|
|
220
|
+
|
|
221
|
+
const kioskTx = new KioskTransaction({
|
|
222
|
+
transaction: tx,
|
|
223
|
+
kioskClient: client.kiosk,
|
|
224
|
+
cap: kioskOwnerCaps[0],
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// Purchase the item and resolve the rules.
|
|
228
|
+
await kioskTx.purchaseAndResolve({
|
|
229
|
+
itemType: item.type,
|
|
230
|
+
itemId: item.objectId,
|
|
231
|
+
price: item.listing.price,
|
|
232
|
+
sellerKiosk: item.kioskId,
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
kioskTx.finalize();
|
|
236
|
+
};
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Attach rules to transfer policy
|
|
240
|
+
|
|
241
|
+
The following example was taken from the original Kiosk SDK V1 documentation.
|
|
242
|
+
|
|
243
|
+
### Before
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
|
|
247
|
+
attachKioskLockRule,
|
|
248
|
+
attachRoyaltyRule,
|
|
249
|
+
createTransferPolicy,
|
|
250
|
+
percentageToBasisPoints,
|
|
251
|
+
testnetEnvironment,
|
|
252
|
+
} from '@haneullabs/kiosk';
|
|
253
|
+
|
|
254
|
+
// Attaches a royalty rule of 1% or 0.1 HANEUL (whichever is bigger)
|
|
255
|
+
// as well as a kiosk lock, making the objects tradeable only from/to a kiosk.
|
|
256
|
+
const attachStrongRoyalties = async () => {
|
|
257
|
+
const type = 'SomePackageId::type::MyType'; // the Type for which we're attaching rules.
|
|
258
|
+
const policyId = 'policyObjectId'; // the transfer Policy ID that was created for that Type.
|
|
259
|
+
const transferPolicyCap = 'transferPolicyCapId'; // the transferPolicyCap for that policy.
|
|
260
|
+
|
|
261
|
+
// Royalties configuration.
|
|
262
|
+
const percentage = 2.55; // 2.55%
|
|
263
|
+
const minAmount = 100_000_000; // 0.1 HANEUL.
|
|
264
|
+
|
|
265
|
+
// The environment on which we're referencing the rules package.
|
|
266
|
+
// Use `mainnetEnvironment` for mainnet.
|
|
267
|
+
const environment = testnetEnvironment;
|
|
268
|
+
|
|
269
|
+
const tx = new Transaction();
|
|
270
|
+
|
|
271
|
+
attachKioskLockRule(tx, type, policyId, policyCapId, environment);
|
|
272
|
+
attachRoyaltyRule(
|
|
273
|
+
tx,
|
|
274
|
+
type,
|
|
275
|
+
policyId,
|
|
276
|
+
policyCapId,
|
|
277
|
+
percentageToBasisPoints(percentage),
|
|
278
|
+
minAmount,
|
|
279
|
+
environment,
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
// ... continue to sign and execute the transaction
|
|
283
|
+
// ...
|
|
284
|
+
};
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### After
|
|
288
|
+
|
|
289
|
+
On the new SDK, the same transaction can be built as follows:
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
// You need to do this only once and re-use it in the application.
|
|
293
|
+
const client = new HaneulJsonRpcClient({
|
|
294
|
+
url: getJsonRpcFullnodeUrl('mainnet'),
|
|
295
|
+
network: 'mainnet',
|
|
296
|
+
}).$extend(kiosk());
|
|
297
|
+
|
|
298
|
+
const adjustPolicy = async () => {
|
|
299
|
+
const tx = new Transaction();
|
|
300
|
+
|
|
301
|
+
// You could have more than one cap, since you can create more than one transfer policy.
|
|
302
|
+
const policyCaps = await client.kiosk.getOwnedTransferPoliciesByType({
|
|
303
|
+
type: `SomePackageId::type::MyType`,
|
|
304
|
+
address: '0xOwnerAddress',
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
new TransferPolicyTransaction({ transaction: tx, kioskClient: client.kiosk, cap: policyCaps[0] })
|
|
308
|
+
.addRoyaltyRule(percentageToBasisPoints(2.55), 100_000_000)
|
|
309
|
+
.addLockRule();
|
|
310
|
+
|
|
311
|
+
// ... continue to sign and execute the transaction
|
|
312
|
+
// ...
|
|
313
|
+
};
|
|
314
|
+
```
|
package/docs/index.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Kiosk SDK
|
|
2
|
+
|
|
3
|
+
> TypeScript SDK for interacting with Haneul Kiosk on-chain commerce
|
|
4
|
+
|
|
5
|
+
Kiosk SDK is a tool to interact with Haneul/Haneullabs Kiosk. You can use it to query kiosk related
|
|
6
|
+
data, build transactions to interact, and extend Kiosk to support custom rules.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```sh npm2yarn
|
|
11
|
+
npm i @haneullabs/kiosk
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## About
|
|
15
|
+
|
|
16
|
+
The Kiosk SDK exports a client extension that integrates with Haneul clients. Add it to your client
|
|
17
|
+
using `$extend(kiosk())` to access kiosk functionality via `client.kiosk`.
|
|
18
|
+
|
|
19
|
+
> **Note:** The Kiosk SDK requires `HaneulJsonRpcClient` or `HaneulGraphQLClient`. It does not work
|
|
20
|
+
> with `HaneulGrpcClient` because it uses event queries that are not available in gRPC.
|
|
21
|
+
|
|
22
|
+
- [Read more about setting up the Kiosk client extension](/kiosk/kiosk-client/introduction)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Kiosk Client
|
|
2
|
+
|
|
3
|
+
> Introduction to the KioskClient for querying and managing kiosks
|
|
4
|
+
|
|
5
|
+
The Kiosk SDK exports a client extension that provides all Kiosk functionality.
|
|
6
|
+
|
|
7
|
+
> We recommend you keep only one client instance throughout your dApp or script. For example, in
|
|
8
|
+
> React, you'd use a context to provide the client.
|
|
9
|
+
|
|
10
|
+
> **Note:** The Kiosk SDK requires `HaneulJsonRpcClient` or `HaneulGraphQLClient`. It does not work
|
|
11
|
+
> with `HaneulGrpcClient` because it uses event queries that are not available in gRPC.
|
|
12
|
+
|
|
13
|
+
## Setting up the kiosk extension
|
|
14
|
+
|
|
15
|
+
Add the kiosk extension to your Haneul client using `$extend()`. The extension currently supports
|
|
16
|
+
`mainnet` and `testnet`. See the next section for usage on other networks.
|
|
17
|
+
|
|
18
|
+
_Haneullabs Kiosk rules and extensions are not supported in Devnet due to network wipes (that would
|
|
19
|
+
require constantly changing the package IDs)._
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
const client = new HaneulJsonRpcClient({
|
|
23
|
+
url: getJsonRpcFullnodeUrl('testnet'),
|
|
24
|
+
network: 'testnet',
|
|
25
|
+
}).$extend(kiosk());
|
|
26
|
+
|
|
27
|
+
// Now you can use client.kiosk for all kiosk operations
|
|
28
|
+
const { kioskOwnerCaps } = await client.kiosk.getOwnedKiosks({ address: '0x...' });
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Using the kiosk extension on devnet or localnet
|
|
32
|
+
|
|
33
|
+
To use all the functionality of Kiosk SDK outside of `mainnet` and `testnet`, pass the `packageIds`
|
|
34
|
+
for the rules and extensions you want to use.
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
const client = new HaneulJsonRpcClient({
|
|
38
|
+
url: getJsonRpcFullnodeUrl('devnet'),
|
|
39
|
+
network: 'devnet',
|
|
40
|
+
}).$extend(
|
|
41
|
+
kiosk({
|
|
42
|
+
packageIds: {
|
|
43
|
+
kioskLockRulePackageId: '0x...',
|
|
44
|
+
royaltyRulePackageId: '0x...',
|
|
45
|
+
personalKioskRulePackageId: '0x...',
|
|
46
|
+
floorPriceRulePackageId: '0x...',
|
|
47
|
+
},
|
|
48
|
+
}),
|
|
49
|
+
);
|
|
50
|
+
```
|