Simple Extensions

Some extensions may be implemented without the "more advanced" Kiosk Extensions API. To understand the approaches to building extensions of this kind, let's look at the tools that are available to the extension developer.

Available tools

UID access via the uid_mut

Kiosk, like any object on Sui, has an id: UID field, which allows this object to not just be uniquely identified but also carry custom dynamic fields and dynamic object fields. The Kiosk itself is built around dynamic fields and features like place and list are built around dynamic object fields.

The uid_mut_as_owner function

Kiosk can carry additional dynamic fields and dynamic object fields. The uid_mut_as_owner function allows the Kiosk Owner to mutably access the UID of the Kiosk object and use it to add or remove custom fields.

Function signature:

kiosk::uid_mut_as_owner(self: &mut Kiosk, cap: &KioskOwnerCap): &mut UID

The public uid getter

Anyone can read the uid of the Kiosk. This allows third party modules read the fields of the Kiosk if they're allowed to do so (TODO: Custom Dynamic Field Keys). Therefore enabling the "Object Capability" and other patterns.

Extension ideas

Given that the Kiosk Owner can attach custom dynamic fields to Kiosk, and anyone can then read them (but not modify), we can use this to implement simple extensions. For example, a "Kiosk Name" extension: the Kiosk Owner can set a name for the Kiosk, attach it as a dynamic field, and make it readable by anyone.

We used a similar approach in the Personal Kiosk Extension.

module examples::kiosk_name_ext {
    use std::string::String;
    use std::option::{Self, Option};
    use sui::dynamic_field as df;
    use sui::kiosk::{Self, Kiosk, KioskOwnerCap};

    /// The dynamic field key for the Kiosk Name Extension
    struct KioskName has store, drop {}

    /// Add a name to the Kiosk (in this implementation can be called only once)
    public fun add(self: &mut Kiosk, cap: &KioskOwnerCap, name: String) {
        let uid_mut = kiosk::uid_mut_as_owner(self, cap);
        df::add(uid_mut, KioskName {}, name)
    }

    /// Try read the name of the Kiosk - if set - return Some(String), if not - None
    public fun name(self: &Kiosk): Option<String> {
        if (df::exists_(kiosk::uid(self), KioskName {}) {
            option::some(*df::borrow(kiosk::uid(self), KioskName {}))
        } else {
            option::none()
        }
    }
}