Source Code

;; StacksMint Collection Contract
;; Manages NFT collections with metadata
;; Creator Fee: 0.01 STX per collection creation

;; Constants
(define-constant CONTRACT-OWNER tx-sender)
(define-constant ERR-NOT-AUTHORIZED (err u100))
(define-constant ERR-NOT-FOUND (err u101))
(define-constant ERR-ALREADY-EXISTS (err u102))
(define-constant ERR-NOT-COLLECTION-OWNER (err u103))
(define-constant ERR-INVALID-COLLECTION (err u104))
(define-constant ERR-TRANSFER-FAILED (err u105))
(define-constant CREATOR-FEE u10000) ;; 0.01 STX in microSTX

;; Data Variables
(define-data-var last-collection-id uint u0)

;; Data Maps
(define-map collections uint {
  owner: principal,
  name: (string-ascii 64),
  description: (string-ascii 256),
  image: (string-ascii 256),
  max-supply: uint,
  minted: uint,
  is-active: bool,
  created-at: uint
})

(define-map collection-by-owner principal (list 50 uint))

;; Read-only functions

;; Get creator fee
(define-read-only (get-creator-fee)
  CREATOR-FEE
)

;; Get last collection ID
(define-read-only (get-last-collection-id)
  (var-get last-collection-id)
)

;; Get collection by ID
(define-read-only (get-collection (collection-id uint))
  (map-get? collections collection-id)
)

;; Get collection owner
(define-read-only (get-collection-owner (collection-id uint))
  (match (map-get? collections collection-id)
    collection (some (get owner collection))
    none
  )
)

;; Get collection name
(define-read-only (get-collection-name (collection-id uint))
  (match (map-get? collections collection-id)
    collection (some (get name collection))
    none
  )
)

;; Check if collection exists
(define-read-only (collection-exists (collection-id uint))
  (is-some (map-get? collections collection-id))
)

;; Check if collection is active
(define-read-only (is-collection-active (collection-id uint))
  (match (map-get? collections collection-id)
    collection (get is-active collection)
    false
  )
)

;; Get collection minted count
(define-read-only (get-collection-minted (collection-id uint))
  (match (map-get? collections collection-id)
    collection (get minted collection)
    u0
  )
)

;; Get collection max supply
(define-read-only (get-collection-max-supply (collection-id uint))
  (match (map-get? collections collection-id)
    collection (get max-supply collection)
    u0
  )
)

;; Check if collection can mint more
(define-read-only (can-mint (collection-id uint))
  (match (map-get? collections collection-id)
    collection (and 
      (get is-active collection)
      (< (get minted collection) (get max-supply collection))
    )
    false
  )
)

;; Public functions

;; Create new collection with creator fee
(define-public (create-collection 
  (name (string-ascii 64))
  (description (string-ascii 256))
  (image (string-ascii 256))
  (max-supply uint)
)
  (let
    (
      (collection-id (+ (var-get last-collection-id) u1))
    )
    ;; Pay creator fee
    (try! (stx-transfer? CREATOR-FEE tx-sender CONTRACT-OWNER))
    ;; Create collection
    (map-set collections collection-id {
      owner: tx-sender,
      name: name,
      description: description,
      image: image,
      max-supply: max-supply,
      minted: u0,
      is-active: true,
      created-at: block-height
    })
    ;; Update last collection ID
    (var-set last-collection-id collection-id)
    (ok collection-id)
  )
)

;; Increment collection minted count (called when NFT minted to collection)
(define-public (increment-minted (collection-id uint))
  (match (map-get? collections collection-id)
    collection (begin
      (asserts! (get is-active collection) ERR-INVALID-COLLECTION)
      (asserts! (< (get minted collection) (get max-supply collection)) ERR-INVALID-COLLECTION)
      (map-set collections collection-id 
        (merge collection { minted: (+ (get minted collection) u1) })
      )
      (ok true)
    )
    ERR-NOT-FOUND
  )
)

;; Update collection metadata (collection owner only)
(define-public (update-collection 
  (collection-id uint)
  (name (string-ascii 64))
  (description (string-ascii 256))
  (image (string-ascii 256))
)
  (match (map-get? collections collection-id)
    collection (begin
      (asserts! (is-eq tx-sender (get owner collection)) ERR-NOT-COLLECTION-OWNER)
      (map-set collections collection-id 
        (merge collection { 
          name: name, 
          description: description, 
          image: image 
        })
      )
      (ok true)
    )
    ERR-NOT-FOUND
  )
)

;; Pause collection (collection owner only)
(define-public (pause-collection (collection-id uint))
  (match (map-get? collections collection-id)
    collection (begin
      (asserts! (is-eq tx-sender (get owner collection)) ERR-NOT-COLLECTION-OWNER)
      (map-set collections collection-id 
        (merge collection { is-active: false })
      )
      (ok true)
    )
    ERR-NOT-FOUND
  )
)

;; Resume collection (collection owner only)
(define-public (resume-collection (collection-id uint))
  (match (map-get? collections collection-id)
    collection (begin
      (asserts! (is-eq tx-sender (get owner collection)) ERR-NOT-COLLECTION-OWNER)
      (map-set collections collection-id 
        (merge collection { is-active: true })
      )
      (ok true)
    )
    ERR-NOT-FOUND
  )
)

;; Transfer collection ownership (collection owner only)
(define-public (transfer-collection (collection-id uint) (new-owner principal))
  (match (map-get? collections collection-id)
    collection (begin
      (asserts! (is-eq tx-sender (get owner collection)) ERR-NOT-COLLECTION-OWNER)
      (map-set collections collection-id 
        (merge collection { owner: new-owner })
      )
      (ok true)
    )
    ERR-NOT-FOUND
  )
)

Functions (16)

FunctionAccessArgs
get-creator-feeread-only
get-last-collection-idread-only
get-collectionread-onlycollection-id: uint
get-collection-ownerread-onlycollection-id: uint
get-collection-nameread-onlycollection-id: uint
collection-existsread-onlycollection-id: uint
is-collection-activeread-onlycollection-id: uint
get-collection-mintedread-onlycollection-id: uint
get-collection-max-supplyread-onlycollection-id: uint
can-mintread-onlycollection-id: uint
create-collectionpublicname: (string-ascii 64
increment-mintedpubliccollection-id: uint
update-collectionpubliccollection-id: uint, name: (string-ascii 64
pause-collectionpubliccollection-id: uint
resume-collectionpubliccollection-id: uint
transfer-collectionpubliccollection-id: uint, new-owner: principal