Source Code

;; Collection Registry Contract
;; Clarity 4 - Stacks Mainnet
;;
;; Central registry that tracks all 50 deployed NFT collection contracts.

;; ======================= CONSTANTS =======================

(define-constant CONTRACT-OWNER tx-sender)
(define-constant ERR-NOT-AUTHORIZED (err u401))
(define-constant ERR-ALREADY-REGISTERED (err u410))
(define-constant ERR-NOT-FOUND (err u404))
(define-constant ERR-INVALID-ID (err u411))

;; ======================= ADMIN =======================

(define-data-var admin principal CONTRACT-OWNER)

(define-read-only (get-admin)
  (var-get admin)
)

(define-public (set-admin (new-admin principal))
  (begin
    (asserts! (is-eq tx-sender (var-get admin)) ERR-NOT-AUTHORIZED)
    (var-set admin new-admin)
    (ok true)
  )
)

;; ======================= DATA MAPS =======================

;; Collection info by sequential ID
(define-map collections uint {
  contract-address: principal,
  name: (string-ascii 64),
  symbol: (string-ascii 16),
  max-supply: uint,
  mint-price: uint,
  active: bool
})

;; Reverse lookup: principal -> ID
(define-map collection-by-address principal uint)

(define-data-var collection-count uint u0)

;; ======================= REGISTRATION =======================

(define-public (register-collection
    (contract-address principal)
    (name (string-ascii 64))
    (symbol (string-ascii 16))
    (max-supply uint)
    (mint-price uint))
  (let ((id (var-get collection-count)))
    (asserts! (is-eq tx-sender (var-get admin)) ERR-NOT-AUTHORIZED)
    (asserts! (is-none (map-get? collection-by-address contract-address)) ERR-ALREADY-REGISTERED)
    (map-set collections id {
      contract-address: contract-address,
      name: name,
      symbol: symbol,
      max-supply: max-supply,
      mint-price: mint-price,
      active: true
    })
    (map-set collection-by-address contract-address id)
    (var-set collection-count (+ id u1))
    (print {
      event: "collection-registered",
      id: id,
      contract-address: contract-address,
      name: name
    })
    (ok id)
  )
)

(define-public (set-collection-active (id uint) (active bool))
  (let ((info (unwrap! (map-get? collections id) ERR-NOT-FOUND)))
    (asserts! (is-eq tx-sender (var-get admin)) ERR-NOT-AUTHORIZED)
    (map-set collections id (merge info { active: active }))
    (ok true)
  )
)

;; ======================= READ-ONLY VIEWS =======================

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

(define-read-only (get-collection-id-by-address (collection principal))
  (map-get? collection-by-address collection)
)

(define-read-only (get-total-collections)
  (var-get collection-count)
)

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

Functions (8)

FunctionAccessArgs
get-adminread-only
set-adminpublicnew-admin: principal
register-collectionpubliccontract-address: principal, name: (string-ascii 64
set-collection-activepublicid: uint, active: bool
get-collection-by-idread-onlyid: uint
get-collection-id-by-addressread-onlycollection: principal
get-total-collectionsread-only
is-collection-activeread-onlyid: uint