;; StackHub NFT Marketplace - Gas Optimized
;; Platform fee: 1.25% on sales
(define-constant CONTRACT-OWNER tx-sender)
(define-constant ERR-NOT-OWNER (err u100))
(define-constant ERR-NOT-FOUND (err u101))
(define-constant ERR-UNAUTHORIZED (err u102))
(define-constant ERR-LISTED (err u103))
(define-constant ERR-NOT-LISTED (err u104))
(define-constant ERR-PRICE (err u105))
(define-constant PLATFORM-FEE u125) ;; 1.25% = 125/10000
(define-data-var last-token-id uint u0)
(define-data-var total-fees uint u0)
(define-non-fungible-token stackhub-nft uint)
(define-map nft-data uint {uri: (string-ascii 256), creator: principal})
(define-map listings uint {price: uint, seller: principal})
;; Read functions
(define-read-only (get-last-token-id)
(ok (var-get last-token-id)))
(define-read-only (get-token-uri (id uint))
(ok (get uri (map-get? nft-data id))))
(define-read-only (get-owner (id uint))
(ok (nft-get-owner? stackhub-nft id)))
(define-read-only (get-listing (id uint))
(map-get? listings id))
(define-read-only (get-total-fees)
(var-get total-fees))
;; Mint NFT
(define-public (mint (uri (string-ascii 256)))
(let ((id (+ (var-get last-token-id) u1)))
(try! (nft-mint? stackhub-nft id tx-sender))
(map-set nft-data id {uri: uri, creator: tx-sender})
(var-set last-token-id id)
(ok id)))
;; List NFT for sale
(define-public (list-nft (id uint) (price uint))
(begin
(asserts! (is-eq (some tx-sender) (nft-get-owner? stackhub-nft id)) ERR-UNAUTHORIZED)
(asserts! (> price u0) ERR-PRICE)
(asserts! (is-none (map-get? listings id)) ERR-LISTED)
(map-set listings id {price: price, seller: tx-sender})
(ok true)))
;; Unlist NFT
(define-public (unlist-nft (id uint))
(let ((listing (unwrap! (map-get? listings id) ERR-NOT-LISTED)))
(asserts! (is-eq tx-sender (get seller listing)) ERR-UNAUTHORIZED)
(map-delete listings id)
(ok true)))
;; Buy NFT - 1.25% fee to platform
(define-public (buy-nft (id uint))
(let (
(listing (unwrap! (map-get? listings id) ERR-NOT-LISTED))
(price (get price listing))
(seller (get seller listing))
(fee (/ (* price PLATFORM-FEE) u10000))
(seller-amount (- price fee))
)
(try! (stx-transfer? seller-amount tx-sender seller))
(try! (stx-transfer? fee tx-sender CONTRACT-OWNER))
(try! (nft-transfer? stackhub-nft id seller tx-sender))
(map-delete listings id)
(var-set total-fees (+ (var-get total-fees) fee))
(ok true)))
;; Transfer NFT
(define-public (transfer (id uint) (recipient principal))
(begin
(asserts! (is-eq (some tx-sender) (nft-get-owner? stackhub-nft id)) ERR-UNAUTHORIZED)
(asserts! (is-none (map-get? listings id)) ERR-LISTED)
(nft-transfer? stackhub-nft id tx-sender recipient)))