Purchasing from a kiosk
One of the base functionalities of the SDK is a seamless purchasing flow, allowing for ease of rules
resolving (hiding away the calls). The SDK supports all four rules by default, and works for
TESTNET
and MAINNET
. To support other networks,
follow the instructions in the Introduction.
How to purchase
By default, the SDK places the item in the caller's kiosk, unless there's a lock rule, in which case it locks it.
Them following is an example of a purchase call.
const item = {
itemType: '0x..::hero::Hero',
itemId: '0x..',
price: 100000n,
sellerKiosk: '0xSellerKiosk',
};
// Assume `kioskClient` and `cap` are supplied to the function as explained in the previous section.
const txb = new TransactionBlock();
const kioskTx = new KioskTransaction({ transactionBlock: txb, kioskClient, cap });
await kioskTx.purchaseAndResolve({
itemType: item.itemType,
itemId: item.itemId,
price: item.price,
sellerKiosk: item.sellerKiosk,
});
kioskTx.finalize();
// Sign and execute transaction block.
await signAndExecuteTransactionBlock({ tx: txb });
The function queries for a TransferPolicy for that item, and if a policy is found, it automatically resolves all the rules, one by one. You can add a custom rule resolver in the
KioskClient
instance, with instructions on how to resolve a custom rule. Read more in the next section.
Supporting a custom rule
You can use the purchaseAndResolve
function to support a custom rule.
const kioskClient = new KioskClient({...});
const myCustomRule = {
rule: `0xMyRuleAddress::game_rule::Rule`,
packageId: `0xMyRuleAddress`,
// The resolving function. This is called when calling the `purchaseAndResolve`.
resolveRuleFunction: (params: RuleResolvingParams) => {
// By knowing the params we have here, we can extract the variables we need to resolve this rule.
const { transactionBlock, itemType, packageId, extraArgs } = params;
const { gamePass } = extraArgs;
if(!gamePass) throw new Error("GamePass not supplied");
// Calls the game's rule prove function, which could, for example
// allow rules to resolve only if the holder has a gamePass object.
transactionBlock.moveCall({
target: `${packageId}::game_rule::prove_pass`,
typeArguments: [itemType],
arguments: [transferRequest, transactionBlock.object(gamePass)],
});
},
};
// This allows rules resolution from the `purchaseAndResolve` function.
kioskClient.addRuleResolver(myCustomRule);
// Assume `cap` is supplied to the function as explained in the introduction section.
const txb = new TransactionBlock();
const kioskTx = new KioskTransaction({ transactionBlock: txb, kioskClient, cap });
await kioskTx.purchaseAndResolve({
itemType: item.itemType,
itemId: item.itemId,
price: item.price,
sellerKiosk: item.sellerKiosk,
extraArgs: {
gamePass: '0xMyGamePassObjectId'
}
});
kioskTx.finalize();
// Sign and execute transaction block.
await signAndExecuteTransactionBlock({ tx: txb });
// For reference, here's the RuleResolvingParams contents.
type RuleResolvingParams = {
transactionBlock: TransactionBlock;
itemType: string;
itemId: string;
price: string;
policyId: ObjectArgument;
kiosk: ObjectArgument;
ownedKiosk: ObjectArgument;
ownedKioskCap: ObjectArgument;
transferRequest: TransactionArgument;
purchasedItem: TransactionArgument;
packageId: string;
extraArgs: Record<string, any>; // extraParams contains more possible {key, values} to pass for custom rules.
};