bitcoin-maximalists-twenty-two

SP19EXHS6HTJCKHF07JY9BHPEZ4Y4V5ZZMMN5F7GM

Source Code

(impl-trait 'SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-trait.nft-trait)

(define-non-fungible-token bitcoin-maximalists-twenty-two uint)

(define-constant CONTRACT_OWNER tx-sender)
(define-constant ERR_INVALID_PERCENTAGE (err u900))
(define-constant ERR_LICENSE_FROZEN (err u901))
(define-constant ERR_METADATA_FROZEN (err u902))
(define-constant ERR_MINT_LIMIT_REACHED (err u903))
(define-constant ERR_MINT_PAUSED (err u904))
(define-constant ERR_NO_LISTINGS (err u905))
(define-constant ERR_NO_OWNER (err u906))
(define-constant ERR_NOT_CONTRACT_OWNER (err u907))
(define-constant ERR_NOT_TOKEN_OWNER (err u908))
(define-constant ERR_TOKEN_ALREADY_MINTED (err u909))
(define-constant ERR_TOKEN_DOES_NOT_EXIST (err u910))
(define-constant ERR_TOKEN_LISTED (err u911))
(define-constant ERR_TOKEN_NOT_LISTED (err u912))
(define-constant ERR_TOKEN_NOT_MINTED (err u913))

(define-data-var last-token-id uint u1)
(define-data-var base-uri (string-ascii 100) "ipfs://bafybeidqp7bbe7ensdrpnz7h7eko4gio7hrrs5ff74qbkspqlrw4xhcof4/")
(define-data-var mint-price uint u420000000)
(define-data-var mint-list (list 365 uint) (list))
(define-data-var mint-limit uint u21)
(define-data-var mint-paused bool false)
(define-data-var market-enabled bool false)
(define-data-var listing-list (list 365 uint) (list))
(define-data-var license-frozen bool false)
(define-data-var metadata-frozen bool false)
(define-data-var artist-address principal 'SP28P0QPAKY7X7KMBKWXFHBP5X4ZET90T96QDHMNJ)
(define-data-var commission-address principal 'SP3DB5QDJAMRNRTQQ291X2HRQEHERH13QEE06HQC9)
(define-data-var market-address principal 'SP2BS7P19T6WP6734EBQ4B7PYYHTGYM0K7HDFEMJE)
(define-data-var artist-royalty uint u500)
(define-data-var commission-percent uint u800)
(define-data-var market-percent uint u200)
(define-map mints-per-user-map principal uint)
(define-map listing-map uint {price: uint})
(define-map owner-map uint principal)

(define-public (freeze-metadata)
  (begin
    (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_NOT_CONTRACT_OWNER)
    (var-set metadata-frozen true)
    (ok true)))
;; #[allow(unchecked_data)]
(define-public (set-base-uri (new-base-uri (string-ascii 80)))
  (begin
    (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_NOT_CONTRACT_OWNER)
    (asserts! (not (var-get metadata-frozen)) ERR_METADATA_FROZEN)
    (print { notification: "token-metadata-update", payload: { token-class: "nft", contract-id: (as-contract tx-sender) }})
    (var-set base-uri new-base-uri)
    (ok true)))
;; #[allow(unchecked_data)]
(define-public (set-mint-limit (limit uint))
  (begin
    (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_NOT_CONTRACT_OWNER)
    (ok (var-set mint-limit limit))))
;; #[allow(unchecked_data)]
(define-public (set-mint-price (price uint))
  (begin
    (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_NOT_CONTRACT_OWNER)
    (ok (var-set mint-price price))))

(define-public (toggle-mint-pause)
  (begin
    (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_NOT_CONTRACT_OWNER)
    (ok (var-set mint-paused (not (var-get mint-paused))))))

;; #[allow(unchecked_data)]
(define-public (mint (id uint))
    (let ((user-mints (get-mints-per-user tx-sender)))
    (begin
        (asserts! (is-eq false (var-get mint-paused)) ERR_MINT_PAUSED)
        (asserts! (< user-mints (var-get mint-limit)) ERR_MINT_LIMIT_REACHED)
        (asserts! (> id u0) ERR_TOKEN_DOES_NOT_EXIST)
        (asserts! (<= id u365) ERR_TOKEN_DOES_NOT_EXIST)
        (asserts! (is-none (index-of? (var-get mint-list) id)) ERR_TOKEN_ALREADY_MINTED)
        (map-set mints-per-user-map tx-sender (+ user-mints u1))
        (map-set owner-map id tx-sender)
        (try! (stx-transfer? (var-get mint-price) tx-sender CONTRACT_OWNER))
        (try! (nft-mint? bitcoin-maximalists-twenty-two id tx-sender))
        (var-set mint-list (unwrap-panic (as-max-len? (append (var-get mint-list) id) u365)))
        (ok id))))

(define-private (get-mints-per-user (caller principal))
  (default-to u0 (map-get? mints-per-user-map caller)))

(define-private (is-owner (id uint))
  (let ((owner (unwrap! (nft-get-owner? bitcoin-maximalists-twenty-two id) false)))
    (or (is-eq tx-sender owner) (is-eq contract-caller owner))))

(define-read-only (get-freeze-metadata)
  (ok (var-get metadata-frozen)))

(define-read-only (get-last-token-id)
  (ok (- (var-get last-token-id) u1)))

(define-read-only (get-mint-limit)
  (ok (var-get mint-limit)))

(define-read-only (get-mint-list)
  (ok (var-get mint-list)))

(define-read-only (get-mint-paused)
  (ok (var-get mint-paused)))

(define-read-only (get-mint-price)
  (ok (var-get mint-price)))

(define-read-only (get-owner (id uint))
  (ok (nft-get-owner? bitcoin-maximalists-twenty-two id)))

(define-read-only (get-token-owner (id uint))
  (ok (unwrap! (nft-get-owner? bitcoin-maximalists-twenty-two id) ERR_NO_OWNER)))

(define-read-only (get-token-uri (id uint))
  (ok (some (concat (concat (var-get base-uri) (int-to-ascii id)) ".json"))))

(define-read-only (get-uri (id uint))
  (ok (concat (concat (var-get base-uri) (int-to-ascii id)) ".json")))

(define-public (enlist (id uint) (price uint))
  (let ((listing  {price: price}))
    (asserts! (is-owner id) ERR_NOT_TOKEN_OWNER)
    (asserts! (not (is-some (index-of? (var-get listing-list) id))) ERR_TOKEN_LISTED)
    (var-set listing-list (unwrap-panic (as-max-len? (append (var-get listing-list) id) u365)))
    (map-set listing-map id listing)
    (print (merge listing {event: "new listing", id: id}))
    (ok true)))

(define-public (unlist (id uint))
  (begin
    (asserts! (is-owner id) ERR_NOT_TOKEN_OWNER)
    (try! (remove-listing id))
    (map-delete listing-map id)
    (print {event: "removed listing", id: id})
    (ok true)))
;; #[allow(unchecked_data)]
(define-public (buy (id uint))
  (let
       ((owner (unwrap! (nft-get-owner? bitcoin-maximalists-twenty-two id) ERR_NOT_TOKEN_OWNER))
        (listing (unwrap! (map-get? listing-map id) ERR_TOKEN_NOT_LISTED))
        (price (get price listing))
        (commission (var-get commission-percent))
        (comm-amount (/ (* price commission) u10000))
        (market (var-get market-percent))
        (market-amount (/ (* price market) u10000))
        (royalty (var-get artist-royalty))
        (royal-amount (/ (* price royalty) u10000)))
    (try! (stx-transfer? (- price (+ royal-amount (+ comm-amount market-amount))) tx-sender owner))
    (try! (pay price commission (as-contract (var-get commission-address))))
    (try! (pay price market (as-contract (var-get market-address))))
    (try! (pay price royalty (as-contract (var-get artist-address))))
    (try! (nft-transfer? bitcoin-maximalists-twenty-two id owner tx-sender))
    (try! (unlist id))
    (map-delete listing-map id)
    (print {event: "buy", id: id})
    (ok true)))
;; #[allow(unchecked_data)]
(define-public (transfer (id uint) (sender principal) (recipient principal))
  (begin
    (asserts! (is-eq tx-sender sender) ERR_NOT_TOKEN_OWNER)
    (asserts! (is-none (map-get? listing-map id)) ERR_TOKEN_LISTED)
    (try! (nft-transfer? bitcoin-maximalists-twenty-two id sender recipient))
    (ok true)))
;; #[allow(unchecked_data)]
(define-public (set-artist-address (address principal))
  (begin
    (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_NOT_CONTRACT_OWNER)
    (ok (var-set artist-address address))))

(define-public (set-artist-royalty (royalty uint))
  (begin
    (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_NOT_CONTRACT_OWNER)
    (asserts! (and (>= royalty u0) (<= royalty u1500)) ERR_INVALID_PERCENTAGE)
    (ok (var-set artist-royalty royalty))))
;; #[allow(unchecked_data)]
(define-public (set-commission-address (address principal))
  (begin
    (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_NOT_CONTRACT_OWNER)
    (ok (var-set commission-address address))))

(define-public (set-commission-percent (percent uint))
  (begin
    (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_NOT_CONTRACT_OWNER)
    (asserts! (and (>= percent u0) (<= percent u1500)) ERR_INVALID_PERCENTAGE)
    (ok (var-set commission-percent percent))))
;; #[allow(unchecked_data)]
(define-public (set-market-address (address principal))
  (begin
    (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_NOT_CONTRACT_OWNER)
    (ok (var-set market-address address))))

(define-public (set-market-percent (percent uint))
  (begin
    (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_NOT_CONTRACT_OWNER)
    (asserts! (and (>= percent u0) (<= percent u1500)) ERR_INVALID_PERCENTAGE)
    (ok (var-set market-percent percent))))

(define-private (pay (price uint) (amount uint) (recipient principal))
  (let ((pay-amount (/ (* price amount) u10000)))
  (if (and (> pay-amount u0) (not (is-eq tx-sender recipient)))
    (try! (stx-transfer? pay-amount tx-sender recipient))
    (print false))
  (ok true)))

(define-private (remove-listing (id uint))
  (let ((mylist (var-get listing-list))) 
    (match (index-of? mylist id) idx 
      (ok (var-set listing-list (unwrap-panic (as-max-len? (if (< idx (- (len mylist) u1))
        (concat (unwrap-panic (slice? mylist u0 idx)) (unwrap-panic (slice? mylist (+ idx u1) (len mylist))))
        (unwrap-panic (slice? mylist u0 idx))) u10))))
      ERR_TOKEN_NOT_LISTED)))

(define-read-only (get-artist-address)
  (ok (var-get artist-address)))

(define-read-only (get-artist-royalty)
  (ok (var-get artist-royalty)))

(define-read-only (get-commission-address)
  (ok (var-get commission-address)))

(define-read-only (get-commission-percent)
  (ok (var-get commission-percent)))

(define-read-only (get-market-address)
  (ok (var-get market-address)))

(define-read-only (get-market-percent)
  (ok (var-get market-percent)))

(define-read-only (get-listing-info (id uint))
  (ok (unwrap! (map-get? listing-map id) ERR_TOKEN_NOT_LISTED)))

(define-read-only (get-listing-list)
  (ok (var-get listing-list)))

(define-data-var license-uri (string-ascii 80) "https://arweave.net/zmc1WTspIhFyVY82bwfAIcIExLFH5lUcHHUN0wXg4W8/0")
(define-data-var license-name (string-ascii 40) "PUBLIC")

(define-public (freeze-license)
  (begin
    (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_NOT_CONTRACT_OWNER)
    (var-set license-frozen true)
    (ok true)))
;; #[allow(unchecked_data)]
(define-public (set-license-name (name (string-ascii 40)))
  (begin
    (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_NOT_CONTRACT_OWNER)
    (asserts! (not (var-get license-frozen)) ERR_LICENSE_FROZEN)
    (ok (var-set license-name name))))
;; #[allow(unchecked_data)]
(define-public (set-license-uri (uri (string-ascii 80)))
  (begin
    (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_NOT_CONTRACT_OWNER)
    (asserts! (not (var-get license-frozen)) ERR_LICENSE_FROZEN)
    (ok (var-set license-uri uri))))

(define-read-only (get-license-name)
  (ok (var-get license-name)))

(define-read-only (get-license-uri)
  (ok (var-get license-uri)))

(define-read-only (get-freeze-license)
  (ok (var-get license-frozen)))

Functions (44)

FunctionAccessArgs
freeze-metadatapublic
set-base-uripublicnew-base-uri: (string-ascii 80
set-mint-limitpubliclimit: uint
set-mint-pricepublicprice: uint
toggle-mint-pausepublic
mintpublicid: uint
get-mints-per-userprivatecaller: principal
is-ownerprivateid: uint
get-freeze-metadataread-only
get-last-token-idread-only
get-mint-limitread-only
get-mint-listread-only
get-mint-pausedread-only
get-mint-priceread-only
get-ownerread-onlyid: uint
get-token-ownerread-onlyid: uint
get-token-uriread-onlyid: uint
get-uriread-onlyid: uint
enlistpublicid: uint, price: uint
unlistpublicid: uint
buypublicid: uint
transferpublicid: uint, sender: principal, recipient: principal
set-artist-addresspublicaddress: principal
set-artist-royaltypublicroyalty: uint
set-commission-addresspublicaddress: principal
set-commission-percentpublicpercent: uint
set-market-addresspublicaddress: principal
set-market-percentpublicpercent: uint
payprivateprice: uint, amount: uint, recipient: principal
remove-listingprivateid: uint
get-artist-addressread-only
get-artist-royaltyread-only
get-commission-addressread-only
get-commission-percentread-only
get-market-addressread-only
get-market-percentread-only
get-listing-inforead-onlyid: uint
get-listing-listread-only
freeze-licensepublic
set-license-namepublicname: (string-ascii 40
set-license-uripublicuri: (string-ascii 80
get-license-nameread-only
get-license-uriread-only
get-freeze-licenseread-only