@haneullabs/kiosk 1.1.2 → 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 +10 -0
- package/README.md +1 -1
- package/dist/client/kiosk-client.d.mts.map +1 -1
- package/dist/client/kiosk-transaction.d.mts +1 -2
- package/dist/client/kiosk-transaction.d.mts.map +1 -1
- package/dist/client/tp-transaction.d.mts +1 -2
- package/dist/client/tp-transaction.d.mts.map +1 -1
- package/dist/constants.d.mts.map +1 -1
- package/dist/contracts/kiosk/deps/haneul/kiosk.mjs +1 -1
- package/dist/contracts/kiosk/deps/haneul/kiosk.mjs.map +1 -1
- package/dist/query/client-utils.mjs +6 -6
- package/dist/query/client-utils.mjs.map +1 -1
- package/dist/types/index.d.mts +0 -1
- package/dist/types/index.d.mts.map +1 -1
- package/dist/types/kiosk.d.mts +13 -27
- package/dist/types/kiosk.d.mts.map +1 -1
- package/dist/types/kiosk.mjs.map +1 -1
- package/dist/types/transfer-policy.d.mts.map +1 -1
- package/dist/utils.d.mts +1 -1
- package/dist/utils.d.mts.map +1 -1
- package/dist/utils.mjs.map +1 -1
- 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 +8 -6
- package/src/contracts/kiosk/deps/haneul/kiosk.ts +1 -1
- package/src/query/client-utils.ts +6 -6
- package/src/types/kiosk.ts +7 -4
- package/src/utils.ts +1 -1
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
|
+
```
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Examples
|
|
2
|
+
|
|
3
|
+
> Kiosk transaction code examples
|
|
4
|
+
|
|
5
|
+
The following dApp-focused examples demonstrate how to use the SDK to interact with Kiosk.
|
|
6
|
+
|
|
7
|
+
## Minting into Kiosk example
|
|
8
|
+
|
|
9
|
+
For every scenario using Kiosk in dApps, the user who has connected their wallet either has at least
|
|
10
|
+
one kiosk already or you must create it for them.
|
|
11
|
+
|
|
12
|
+
The SDK supports the scenario of `silently` creating the kiosk, as part of our Programmable
|
|
13
|
+
Transaction.
|
|
14
|
+
|
|
15
|
+
Assume that the mint function of the contract is:
|
|
16
|
+
|
|
17
|
+
`public fun mint(coin: Coin<HANEUL>, kiosk: &mut Kiosk, cap: &KioskOwnerCap){...}`
|
|
18
|
+
|
|
19
|
+
### When the user has a kiosk
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
const connectedAddress = '0xAnAddress';
|
|
23
|
+
|
|
24
|
+
// This function should run when the user connects the wallet.
|
|
25
|
+
// We should re-use the same client instance throughout our dApp.
|
|
26
|
+
const getCap = async () => {
|
|
27
|
+
let { kioskOwnerCaps } = await client.kiosk.getOwnedKiosks({ address: connectedAddress });
|
|
28
|
+
// Assume that the user has only 1 kiosk.
|
|
29
|
+
// Here, you need to do some more checks in a realistic scenario.
|
|
30
|
+
// And possibly give the user in our dApp a kiosk selector to choose which one they want to interact with (if they own more than one).
|
|
31
|
+
return kioskOwnerCaps[0];
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// The mint function could be like the following.
|
|
35
|
+
const mint = async () => {
|
|
36
|
+
const tx = new Transaction();
|
|
37
|
+
const kioskTx = new KioskTransaction({
|
|
38
|
+
kioskClient: client.kiosk,
|
|
39
|
+
transaction: tx,
|
|
40
|
+
cap: await getCap(),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Assume it costs one HANEUL
|
|
44
|
+
let coin = tx.splitCoins(tx.gas, [1_000_000_000]);
|
|
45
|
+
|
|
46
|
+
// A function that mints directly into the kiosk.
|
|
47
|
+
tx.moveCall({
|
|
48
|
+
target: '0xMyGame::hero::mint',
|
|
49
|
+
arguments: [
|
|
50
|
+
coin, // the payment
|
|
51
|
+
kioskTx.getKiosk(), // our kiosk that the hero will be placed in.
|
|
52
|
+
kioskTx.getKioskCap(), // our kiosk cap, so that the function can place or lock it.
|
|
53
|
+
],
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
kioskTx.finalize();
|
|
57
|
+
|
|
58
|
+
// Sign and execute transaction.
|
|
59
|
+
await signAndExecuteTransaction({ tx: tx });
|
|
60
|
+
};
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### When the user doesn't have a kiosk (silent creation)
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
// Our mint function.
|
|
67
|
+
const mint = async () => {
|
|
68
|
+
const tx = new Transaction();
|
|
69
|
+
const kioskTx = new KioskTransaction({ kioskClient: client.kiosk, transaction: tx });
|
|
70
|
+
|
|
71
|
+
// Creates a kiosk.
|
|
72
|
+
kioskTx.create();
|
|
73
|
+
|
|
74
|
+
// We'll assume it costs 1 HANEUL
|
|
75
|
+
let coin = tx.splitCoins(tx.gas, [1_000_000_000]);
|
|
76
|
+
|
|
77
|
+
// A function that mints directly into the kiosk.
|
|
78
|
+
tx.moveCall({
|
|
79
|
+
target: '0xMyGame::hero::mint',
|
|
80
|
+
arguments: [
|
|
81
|
+
coin, // the payment
|
|
82
|
+
kioskTx.getKiosk(), // our kiosk that the hero will be placed in.
|
|
83
|
+
kioskTx.getKioskCap(), // our kiosk cap, so that the function can place or lock it.
|
|
84
|
+
],
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
kioskTx.shareAndTransferCap('0xAddressToTransferCapTo');
|
|
88
|
+
kioskTx.finalize();
|
|
89
|
+
|
|
90
|
+
// Sign and execute transaction.
|
|
91
|
+
await signAndExecuteTransaction({ tx: tx });
|
|
92
|
+
};
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Borrowing an item from kiosk to do an action
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
// A sample function that borrows an item from kiosk and levels it up.
|
|
99
|
+
const levelUp = async (object) => {
|
|
100
|
+
const tx = new Transaction();
|
|
101
|
+
|
|
102
|
+
new KioskTransaction({ kioskClient: client.kiosk, transaction: tx, cap })
|
|
103
|
+
.borrowTx(object, (item) => {
|
|
104
|
+
tx.moveCall({
|
|
105
|
+
target: '0xMyGame::hero::level_up',
|
|
106
|
+
arguments: [item],
|
|
107
|
+
});
|
|
108
|
+
})
|
|
109
|
+
.finalize();
|
|
110
|
+
|
|
111
|
+
// Sign and execute transaction.
|
|
112
|
+
await signAndExecuteTransaction({ tx: tx });
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
levelUp({
|
|
116
|
+
itemType: '0x2MyGame::hero::Hero',
|
|
117
|
+
itemId: '0xMyHeroObjectId',
|
|
118
|
+
});
|
|
119
|
+
```
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# KioskTransaction
|
|
2
|
+
|
|
3
|
+
> Build kiosk transactions for listing, purchasing, and managing items
|
|
4
|
+
|
|
5
|
+
`KioskTransaction` is the client to build transactions that involve Kiosk. It's used similar to
|
|
6
|
+
`Transaction`, and helps in building a transaction.
|
|
7
|
+
|
|
8
|
+
You need to instantiate it once in every Programmable Transaction Block (PTB) that you're building.
|
|
9
|
+
|
|
10
|
+
There are two flows to follow, the first being managing an existing kiosk, and the second is
|
|
11
|
+
creating a new one. It hides all the complexity between a personal and a non-personal kiosk.
|
|
12
|
+
|
|
13
|
+
## Using an existing kiosk
|
|
14
|
+
|
|
15
|
+
If you have already retrieved a kiosk from `client.kiosk.getOwnedKiosks()`, you can pass a cap.
|
|
16
|
+
|
|
17
|
+
> You must always call `kioskTx.finalize()` before signing and executing the transaction, as your
|
|
18
|
+
> last command.
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
const { kioskOwnerCaps } = await client.kiosk.getOwnedKiosks({ address: '0xMyAddress' });
|
|
22
|
+
|
|
23
|
+
const tx = new Transaction();
|
|
24
|
+
const kioskTx = new KioskTransaction({
|
|
25
|
+
transaction: tx,
|
|
26
|
+
kioskClient: client.kiosk,
|
|
27
|
+
cap: kioskOwnerCaps[0],
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Now you can do whatever you want with kioskTx.
|
|
31
|
+
// For example, you could withdraw the profits from the kiosk.
|
|
32
|
+
kioskTx.withdraw('0xMyAddress', 100_000_000n);
|
|
33
|
+
|
|
34
|
+
// You could also chain some other functionality if you want to.
|
|
35
|
+
kioskTx
|
|
36
|
+
.place({
|
|
37
|
+
itemType: '0xMyItemType',
|
|
38
|
+
item: '0xMyItem',
|
|
39
|
+
})
|
|
40
|
+
.list({
|
|
41
|
+
itemType: '0xMyItemType',
|
|
42
|
+
itemId: '0xMyItem',
|
|
43
|
+
price: 10000n,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Always called as our last kioskTx interaction.
|
|
47
|
+
kioskTx.finalize();
|
|
48
|
+
|
|
49
|
+
// Sign and execute transaction.
|
|
50
|
+
await signAndExecuteTransaction({ tx: tx });
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Creating a new kiosk
|
|
54
|
+
|
|
55
|
+
If you don't have a kiosk yet, you can create one using `create()`. The `KioskTransaction` enables
|
|
56
|
+
use of the newly created kiosk to execute some functionality in the same PTB.
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
const tx = new Transaction();
|
|
60
|
+
const kioskTx = new KioskTransaction({ transaction: tx, kioskClient: client.kiosk });
|
|
61
|
+
|
|
62
|
+
// Calls the creation function.
|
|
63
|
+
kioskTx.create();
|
|
64
|
+
|
|
65
|
+
// We can use the kiosk for some action.
|
|
66
|
+
// For example, placing an item in the newly created kiosk.
|
|
67
|
+
kioskTx.place({
|
|
68
|
+
itemType: '0x...::hero::Hero',
|
|
69
|
+
item: '0xAHero',
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Shares the kiosk and transfers the `KioskOwnerCap` to the owner.
|
|
73
|
+
kioskTx.shareAndTransferCap('0xMyAddress');
|
|
74
|
+
|
|
75
|
+
// Always called as our last kioskTx interaction.
|
|
76
|
+
kioskTx.finalize();
|
|
77
|
+
|
|
78
|
+
// Sign and execute transaction.
|
|
79
|
+
await signAndExecuteTransaction({ tx: tx });
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Creating a new personal kiosk
|
|
83
|
+
|
|
84
|
+
`KioskTransaction` makes it easy to create a new personal kiosk, and use it in the same PTB.
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
const tx = new Transaction();
|
|
88
|
+
const kioskTx = new KioskTransaction({ transaction: tx, kioskClient: client.kiosk });
|
|
89
|
+
|
|
90
|
+
// An example that creates a personal kiosk, uses it to place an item, and shares it.
|
|
91
|
+
// The `PersonalKioskCap` is automatically transferred to the sender when calling `.finalize()`.
|
|
92
|
+
// The `Kiosk` is automatically shared when calling `.finalize()`.
|
|
93
|
+
kioskTx
|
|
94
|
+
.createPersonal(true) // `true` allows us to reuse the kiosk in the same PTB. If we pass false, we can only call `kioskTx.finalize()`.
|
|
95
|
+
.place({
|
|
96
|
+
itemType: '0x...::hero::Hero',
|
|
97
|
+
item: '0xAHero',
|
|
98
|
+
})
|
|
99
|
+
.finalize(); // finalize is always our last call.
|
|
100
|
+
|
|
101
|
+
// Sign and execute transaction.
|
|
102
|
+
await signAndExecuteTransaction({ tx: tx });
|
|
103
|
+
```
|