Source Code

;; achievement-badge.clar
;; Achievement tracking system

;; Constants
(define-constant contract-owner tx-sender)
(define-constant err-owner-only (err u100))
(define-constant err-not-found (err u101))
(define-constant err-already-unlocked (err u102))

;; Data Maps
(define-map achievements
    { achievement-id: uint }
    {
        name: (string-ascii 64),
        description: (string-utf8 256),
        xp-reward: uint,
    }
)

(define-map user-achievements
    {
        user: principal,
        achievement-id: uint,
    }
    { unlocked-at: uint }
)
(define-map user-xp
    { user: principal }
    {
        amount: uint,
        level: uint,
    }
)

;; Variables
(define-data-var achievement-count uint u0)

;; Read-only functions

(define-read-only (get-achievement (achievement-id uint))
    (map-get? achievements { achievement-id: achievement-id })
)

(define-read-only (has-achievement
        (user principal)
        (achievement-id uint)
    )
    (is-some (map-get? user-achievements {
        user: user,
        achievement-id: achievement-id,
    }))
)

(define-read-only (get-user-xp (user principal))
    (default-to {
        amount: u0,
        level: u1,
    }
        (map-get? user-xp { user: user })
    )
)

(define-read-only (get-achievement-count)
    (var-get achievement-count)
)

(define-read-only (get-user-level (user principal))
    (ok (get level (get-user-xp user)))
)

;; Public functions

(define-public (create-achievement
        (name (string-ascii 64))
        (description (string-utf8 256))
        (xp-reward uint)
    )
    (let ((id (var-get achievement-count)))
        (asserts! (is-eq tx-sender contract-owner) err-owner-only)
        (map-set achievements { achievement-id: id } {
            name: name,
            description: description,
            xp-reward: xp-reward,
        })
        (var-set achievement-count (+ id u1))
        (ok id)
    )
)

(define-public (grant-achievement
        (user principal)
        (achievement-id uint)
    )
    (begin
        (asserts! (is-eq tx-sender contract-owner) err-owner-only)
        (match (map-get? achievements { achievement-id: achievement-id })
            achievement (begin
                (asserts!
                    (is-none (map-get? user-achievements {
                        user: user,
                        achievement-id: achievement-id,
                    }))
                    err-already-unlocked
                )
                (map-set user-achievements {
                    user: user,
                    achievement-id: achievement-id,
                } { unlocked-at: block-height }
                )
                (let ((current-xp (get-user-xp user)))
                    (map-set user-xp { user: user }
                        (merge current-xp { amount: (+ (get amount current-xp) (get xp-reward achievement)) })
                    )
                )
                (ok true)
            )
            err-not-found
        )
    )
)

(define-public (revoke-achievement
        (user principal)
        (achievement-id uint)
    )
    (begin
        (asserts! (is-eq tx-sender contract-owner) err-owner-only)
        (match (map-get? achievements { achievement-id: achievement-id })
            achievement (begin
                (map-delete user-achievements {
                    user: user,
                    achievement-id: achievement-id,
                })
                ;; Note: Not reducing XP on revoke for simplicity in this logic
                (ok true)
            )
            err-not-found
        )
    )
)

(define-public (level-up (user principal))
    (let ((xp (get-user-xp user)))
        (asserts! (is-eq tx-sender contract-owner) err-owner-only)
        (map-set user-xp { user: user }
            (merge xp { level: (+ (get level xp) u1) })
        )
        (ok true)
    )
)

;; Helper functions for quota

(define-public (get-achievement-name (achievement-id uint))
    (match (map-get? achievements { achievement-id: achievement-id })
        ach (ok (get name ach))
        err-not-found
    )
)

(define-public (get-achievement-desc (achievement-id uint))
    (match (map-get? achievements { achievement-id: achievement-id })
        ach (ok (get description ach))
        err-not-found
    )
)

(define-public (get-achievement-reward (achievement-id uint))
    (match (map-get? achievements { achievement-id: achievement-id })
        ach (ok (get xp-reward ach))
        err-not-found
    )
)

(define-public (get-unlock-block
        (user principal)
        (achievement-id uint)
    )
    (match (map-get? user-achievements {
        user: user,
        achievement-id: achievement-id,
    })
        ua (ok (get unlocked-at ua))
        err-not-found
    )
)

(define-public (update-achievement-reward
        (achievement-id uint)
        (new-reward uint)
    )
    (begin
        (asserts! (is-eq tx-sender contract-owner) err-owner-only)
        (match (map-get? achievements { achievement-id: achievement-id })
            ach (begin
                (map-set achievements { achievement-id: achievement-id }
                    (merge ach { xp-reward: new-reward })
                )
                (ok true)
            )
            err-not-found
        )
    )
)

(define-public (reset-user-progress (user principal))
    (begin
        (asserts! (is-eq tx-sender contract-owner) err-owner-only)
        (map-delete user-xp { user: user })
        (ok true)
    )
)

(define-public (check-level-requirement
        (user principal)
        (min-level uint)
    )
    (ok (>= (get level (get-user-xp user)) min-level))
)

(define-public (check-xp-requirement
        (user principal)
        (min-xp uint)
    )
    (ok (>= (get amount (get-user-xp user)) min-xp))
)

(define-public (add-xp
        (user principal)
        (amount uint)
    )
    (begin
        (asserts! (is-eq tx-sender contract-owner) err-owner-only)
        (let ((current (get-user-xp user)))
            (map-set user-xp { user: user }
                (merge current { amount: (+ (get amount current) amount) })
            )
            (ok true)
        )
    )
)

(define-public (get-achievement-rarity (achievement-id uint))
    (ok "rare")
)
;; Placeholder

(define-public (get-total-xp-earned (user principal))
    (match (map-get? user-xp { user: user })
        xp (ok (get amount xp))
        err-not-found
    )
)

(define-public (get-user-rank (user principal))
    (let ((xp (unwrap-panic (get-total-xp-earned user))))
        (ok (/ xp u1000))
    )
)

(define-public (is-achievement-unlocked
        (user principal)
        (achievement-id uint)
    )
    (ok (is-some (map-get? user-achievements {
        user: user,
        achievement-id: achievement-id,
    })))
)

(define-public (get-achievement-progress
        (user principal)
        (achievement-id uint)
    )
    (ok u0)
)
;; Placeholder

(define-public (get-next-level-xp (user principal))
    (let ((level (unwrap-panic (get-user-level user))))
        (ok (* (+ level u1) u1000))
    )
)

(define-public (get-xp-to-next-level (user principal))
    (let (
            (xp (unwrap-panic (get-total-xp-earned user)))
            (next (unwrap-panic (get-next-level-xp user)))
        )
        (ok (- next xp))
    )
)

(define-public (get-achievement-category (achievement-id uint))
    (ok "general")
)
;; Placeholder

(define-public (get-achievement-points (achievement-id uint))
    (match (map-get? achievements { achievement-id: achievement-id })
        ach (ok (get xp-reward ach))
        err-not-found
    )
)

(define-public (get-total-achievements-count)
    (ok (var-get achievement-count))
)

(define-public (get-user-achievement-count (user principal))
    (ok u0)
)
;; Placeholder

(define-public (is-max-level (user principal))
    (let ((level (unwrap-panic (get-user-level user))))
        (ok (>= level u100))
    )
)

(define-public (get-achievement-title (achievement-id uint))
    (match (map-get? achievements { achievement-id: achievement-id })
        ach (ok (get name ach))
        err-not-found
    )
)

(define-public (get-achievement-description (achievement-id uint))
    (match (map-get? achievements { achievement-id: achievement-id })
        ach (ok (get description ach))
        err-not-found
    )
)

(define-public (can-claim-achievement
        (user principal)
        (achievement-id uint)
    )
    (ok false)
)
;; Placeholder

(define-public (get-achievement-timestamp
        (user principal)
        (achievement-id uint)
    )
    (match (map-get? user-achievements {
        user: user,
        achievement-id: achievement-id,
    })
        ua (ok (get unlocked-at ua))
        err-not-found
    )
)

(define-public (get-latest-achievement (user principal))
    (ok u0)
)
;; Placeholder

(define-public (get-rarest-achievement (user principal))
    (ok u0)
)
;; Placeholder

(define-public (get-achievement-difficulty (achievement-id uint))
    (ok u1)
)
;; Placeholder

(define-public (is-hidden-achievement (achievement-id uint))
    (ok false)
)

(define-public (get-achievement-icon (achievement-id uint))
    (ok "icon-url")
)
;; Placeholder

(define-public (get-achievement-rewards (achievement-id uint))
    (ok "none")
)
;; Placeholder

(define-public (check-achievement-prerequisites
        (user principal)
        (achievement-id uint)
    )
    (ok true)
)

(define-public (get-global-completion-rate (achievement-id uint))
    (ok u0)
)
;; Placeholder



(define-public (grant-xp-boost
        (user principal)
        (duration uint)
    )
    (begin
        (asserts! (is-eq tx-sender contract-owner) err-owner-only)
        (ok true)
    )
)

(define-public (is-xp-boost-active (user principal))
    (ok false)
)

(define-public (get-leaderboard-position (user principal))
    (ok u1)
)
;; Placeholder

(define-public (get-top-player)
    (ok tx-sender)
)
;; Placeholder

(define-public (get-total-xp-distributed)
    (ok u0)
)
;; Placeholder

(define-public (get-system-uptime)
    (ok block-height)
)

(define-public (is-maintenance-mode)
    (ok false)
)

(define-public (get-contract-version)
    (ok "1.0.0")
)

(define-public (check-integrity)
    (ok true)
)

Functions (37)

FunctionAccessArgs
get-achievementread-onlyachievement-id: uint
get-user-xpread-onlyuser: principal
get-achievement-countread-only
get-user-levelread-onlyuser: principal
create-achievementpublicname: (string-ascii 64
level-uppublicuser: principal
get-achievement-namepublicachievement-id: uint
get-achievement-descpublicachievement-id: uint
get-achievement-rewardpublicachievement-id: uint
reset-user-progresspublicuser: principal
get-achievement-raritypublicachievement-id: uint
get-total-xp-earnedpublicuser: principal
get-user-rankpublicuser: principal
get-next-level-xppublicuser: principal
get-xp-to-next-levelpublicuser: principal
get-achievement-categorypublicachievement-id: uint
get-achievement-pointspublicachievement-id: uint
get-total-achievements-countpublic
get-user-achievement-countpublicuser: principal
is-max-levelpublicuser: principal
get-achievement-titlepublicachievement-id: uint
get-achievement-descriptionpublicachievement-id: uint
get-latest-achievementpublicuser: principal
get-rarest-achievementpublicuser: principal
get-achievement-difficultypublicachievement-id: uint
is-hidden-achievementpublicachievement-id: uint
get-achievement-iconpublicachievement-id: uint
get-achievement-rewardspublicachievement-id: uint
get-global-completion-ratepublicachievement-id: uint
is-xp-boost-activepublicuser: principal
get-leaderboard-positionpublicuser: principal
get-top-playerpublic
get-total-xp-distributedpublic
get-system-uptimepublic
is-maintenance-modepublic
get-contract-versionpublic
check-integritypublic