Source Code

;; 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)))

Functions (10)

FunctionAccessArgs
get-last-token-idread-only
get-token-uriread-onlyid: uint
get-ownerread-onlyid: uint
get-listingread-onlyid: uint
get-total-feesread-only
mintpublicuri: (string-ascii 256
list-nftpublicid: uint, price: uint
unlist-nftpublicid: uint
buy-nftpublicid: uint
transferpublicid: uint, recipient: principal