Skip to content

Commit

Permalink
feat: add kiosk policy
Browse files Browse the repository at this point in the history
  • Loading branch information
daniellam258 committed Mar 5, 2024
1 parent 3ba6f12 commit 81b3f53
Show file tree
Hide file tree
Showing 5 changed files with 438 additions and 18 deletions.
27 changes: 27 additions & 0 deletions unit-five/example_projects/kiosk/Move.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# @generated by Move, please check-in and do not edit manually.

[move]
version = 0
manifest_digest = "1FF626947D27118D75E5892ECC965B6EA5D58EF40C92513A237A9F1A2B5F5DDB"
deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082"

dependencies = [
{ name = "Sui" },
]

[[move.package]]
name = "MoveStdlib"
source = { git = "https://github.com/MystenLabs/sui.git", rev = "framework/testnet", subdir = "crates/sui-framework/packages/move-stdlib" }

[[move.package]]
name = "Sui"
source = { git = "https://github.com/MystenLabs/sui.git", rev = "framework/testnet", subdir = "crates/sui-framework/packages/sui-framework" }

dependencies = [
{ name = "MoveStdlib" },
]

[move.toolchain-version]
compiler-version = "1.20.0"
edition = "legacy"
flavor = "sui"
50 changes: 50 additions & 0 deletions unit-five/example_projects/kiosk/sources/dummy_policy.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) Sui Foundation, Inc.
// SPDX-License-Identifier: Apache-2.0

// The code is taken here https://github.com/MystenLabs/apps/blob/main/kiosk/docs/creating_a_rule_guide.md#rule-structure-dummy

module kiosk::dummy_rule {
use sui::coin::Coin;
use sui::sui::SUI;
use sui::transfer_policy::{
Self as policy,
TransferPolicy,
TransferPolicyCap,
TransferRequest
};

/// The Rule Witness; has no fields and is used as a
/// static authorization method for the rule.
struct Rule has drop {}

/// Configuration struct with any fields (as long as it
/// has `drop`). Managed by the Rule module.
struct Config has store, drop {}

/// Function that adds a Rule to the `TransferPolicy`.
/// Requires `TransferPolicyCap` to make sure the rules are
/// added only by the publisher of T.
public fun set<T>(
policy: &mut TransferPolicy<T>,
cap: &TransferPolicyCap<T>
) {
policy::add_rule(Rule {}, policy, cap, Config {})
}

/// Action function - perform a certain action (any, really)
/// and pass in the `TransferRequest` so it gets the Receipt.
/// Receipt is a Rule Witness, so there's no way to create
/// it anywhere else but in this module.
///
/// This example also illustrates that Rules can add Coin<SUI>
/// to the balance of the TransferPolicy allowing creators to
/// collect fees.
public fun pay<T>(
policy: &mut TransferPolicy<T>,
request: &mut TransferRequest<T>,
payment: Coin<SUI>
) {
policy::add_to_balance(Rule {}, policy, payment);
policy::add_receipt(Rule {}, request);
}
}
77 changes: 77 additions & 0 deletions unit-five/example_projects/kiosk/sources/fixed_royalty_rule.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright (c) Sui Foundation, Inc.
// SPDX-License-Identifier: Apache-2.0

// The code is modified from here https://github.com/MystenLabs/apps/blob/main/kiosk/sources/rules/royalty_rule.move

module kiosk::fixed_royalty_rule {
use sui::sui::SUI;
use sui::coin::{Self, Coin};
use sui::transfer_policy::{
Self as policy,
TransferPolicy,
TransferPolicyCap,
TransferRequest
};

/// The `amount_bp` passed is more than 100%.
const EIncorrectArgument: u64 = 0;
/// The `Coin` used for payment is not enough to cover the fee.
const EInsufficientAmount: u64 = 1;

/// Max value for the `amount_bp`.
const MAX_BPS: u16 = 10_000;

/// The Rule Witness to authorize the policy
struct Rule has drop {}

/// Configuration for the Rule
struct Config has store, drop {
/// Percentage of the transfer amount to be paid as royalty fee
amount_bp: u16,
/// This is used as royalty fee if the calculated fee is smaller than `min_amount`
min_amount: u64,
}

/// Function that adds a Rule to the `TransferPolicy`.
/// Requires `TransferPolicyCap` to make sure the rules are
/// added only by the publisher of T.
public fun add<T>(
policy: &mut TransferPolicy<T>,
cap: &TransferPolicyCap<T>,
amount_bp: u16,
min_amount: u64

) {
assert!(amount_bp <= MAX_BPS, EIncorrectArgument);
policy::add_rule(Rule {}, policy, cap, Config { amount_bp, min_amount })
}

/// Buyer action: Pay the royalty fee for the transfer.
public fun pay<T: key + store>(
policy: &mut TransferPolicy<T>,
request: &mut TransferRequest<T>,
payment: Coin<SUI>
) {
let paid = policy::paid(request);
let amount = fee_amount(policy, paid);

assert!(coin::value(&payment) == amount, EInsufficientAmount);

policy::add_to_balance(Rule {}, policy, payment);
policy::add_receipt(Rule {}, request)
}

/// Helper function to calculate the amount to be paid for the transfer.
/// Can be used dry-runned to estimate the fee amount based on the Kiosk listing price.
public fun fee_amount<T: key + store>(policy: &TransferPolicy<T>, paid: u64): u64 {
let config: &Config = policy::get_rule(Rule {}, policy);
let amount = (((paid as u128) * (config.amount_bp as u128) / 10_000) as u64);

// If the amount is less than the minimum, use the minimum
if (amount < config.min_amount) {
amount = config.min_amount
};

amount
}
}
61 changes: 60 additions & 1 deletion unit-five/example_projects/kiosk/sources/kiosk.move
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,64 @@
// SPDX-License-Identifier: Apache-2.0

module kiosk::kiosk {

use sui::kiosk::{Self, Kiosk, KioskOwnerCap};
use sui::tx_context::{TxContext, sender};
use sui::object::{Self, UID};
use sui::coin::{Self, Coin};
use sui::sui::{SUI};
use sui::transfer_policy::{Self, TransferRequest, TransferPolicy, TransferPolicyCap};
use sui::package::{Self, Publisher};
use sui::transfer::{Self};

struct TShirt has key, store {
id: UID,
}

struct KIOSK has drop {}

fun init(otw: KIOSK, ctx: &mut TxContext) {
let publisher = package::claim(otw, ctx);
transfer::public_transfer(publisher, sender(ctx));
}

public fun new_tshirt(ctx: &mut TxContext): TShirt {
TShirt {
id: object::new(ctx),
}
}

/// Create new kiosk
public fun new_kiosk(ctx: &mut TxContext): (Kiosk, KioskOwnerCap) {
kiosk::new(ctx)
}

/// Place item inside Kiosk
public fun place(kiosk: &mut Kiosk, cap: &KioskOwnerCap, item: TShirt) {
kiosk::place(kiosk, cap, item)
}

/// Withdraw item from Kiosk
public fun withdraw(kiosk: &mut Kiosk, cap: &KioskOwnerCap, item_id: object::ID): TShirt {
kiosk::take(kiosk, cap, item_id)
}

/// List item for sale
public fun list(kiosk: &mut Kiosk, cap: &KioskOwnerCap, item_id: object::ID, price: u64) {
kiosk::list<TShirt>(kiosk, cap, item_id, price)
}

/// Buy listed item
public fun buy(kiosk: &mut Kiosk, item_id: object::ID, payment: Coin<SUI>): (TShirt, TransferRequest<TShirt>){
kiosk::purchase(kiosk, item_id, payment)
}

/// Confirm the TransferRequest
public fun confirm_request(policy: &TransferPolicy<TShirt>, req: TransferRequest<TShirt>) {
transfer_policy::confirm_request(policy, req);
}

/// Create new policy for type `T`
public fun new_policy(publisher: &Publisher, ctx: &mut TxContext): (TransferPolicy<TShirt>, TransferPolicyCap<TShirt>) {
transfer_policy::new(publisher, ctx)
}
}
Loading

0 comments on commit 81b3f53

Please sign in to comment.