Skip to content

feat: loyalty unlock example#31

Merged
chariskms merged 4 commits intomainfrom
ck/loyalty-token-example
Mar 17, 2026
Merged

feat: loyalty unlock example#31
chariskms merged 4 commits intomainfrom
ck/loyalty-token-example

Conversation

@chariskms
Copy link
Collaborator

Adds a loyalty points example demonstrating PAS assets redemption (unlock) from the PAS closed loop framework for eligible addresses.

Copy link
Collaborator

@manolisliolios manolisliolios left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great

ctx: &mut TxContext,
) {
// Check eligibility and approve the redemption
loyalty_manager::approve_redeem(registry, &mut request);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to instead return a witness from the loyalty manager since we're acutally doing the unlock here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, if we go with the public(package) approach

policy: &Policy<Balance<LOYALTY_COIN>>,
mut request: Request<UnlockFunds<Balance<LOYALTY_COIN>>>,
ctx: &mut TxContext,
) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be better to return ): Balance<LOYALTY_COIN> to keep it composable?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could remove this function entirely, or use the balance to send the funds in a controlled way to another destination.

/// Issuers should carefully consider whether enabling `unlock_funds`
/// is appropriate for their token's compliance requirements.
#[allow(lint(self_transfer))]
public fun redeem(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since approve_redeem is public, why do we need this function at all? I'd expect thjis to be called from a PTB

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, for this exact case it is not necessary, but I prefer to show the unlock flow directly in Move rather than only through a PTB. There are cases where the redeemed balance should not be sent back to ctx.sender(), but instead transferred in a controlled way to a specific recipient address or even kept in the contracts. I think it’s useful to demonstrate this flow in Move. What do you think?

I can make approve_redeem public(package) so callers are required to go through treasury::redeem, which performs the resolve and send steps. We could also change the destination of the funds if needed.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am ok with either direction, but not having both public!

Copy link
Collaborator Author

@chariskms chariskms Mar 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered adding a whitelist of treasury recipient addresses, but for an example it adds complexity and contradicts the idea of an unlock (may confuse).

Instead, I made approve_redeem as public(package) so redemptions must go through treasury::redeem, and the resolved balance is still sent to ctx.sender(). I think this keeps the flow controlled while clearly showing that the balance is fully unlocked.

@chariskms chariskms merged commit 4e2898a into main Mar 17, 2026
2 checks passed
@chariskms chariskms deleted the ck/loyalty-token-example branch March 17, 2026 19:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants