;; use the SIP009 interface
;; (impl-trait .nft-trait.nft-trait)
(impl-trait 'SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-trait.nft-trait)
(define-constant token-name "sf-v2.5")
(define-constant token-symbol "SFAN")
(define-non-fungible-token superfandom-nft uint)
;;
(define-data-var last-token-id uint u0)
(define-data-var administrator principal tx-sender)
(define-map nft-data uint {metadata-url: (string-ascii 256),
creator-fandom-id: (string-ascii 40), owner-fandom-id: (string-ascii 40), mint-block-height: uint,
redemption-count: uint,
beneficiaries: (list 10 (string-ascii 40)),
shares: (list 10 uint)})
;; constants
(define-constant not-allowed (err u10))
(define-constant not-found (err u11))
(define-constant transfer-not-supported (err u406)) ;; if operation is not supported yet
;; the contract administrator can change the contract administrator
(define-public (transfer-administrator (new-administrator principal))
(begin
(asserts! (is-eq (var-get administrator) tx-sender) not-allowed)
(var-set administrator new-administrator)
(ok true)
)
)
(define-public (mint-token (metadataUrl (string-ascii 256)) (creatorSuperFandomId (string-ascii 40)) (ownerSuperFandomId (string-ascii 40)) (redemptionCount uint)
(beneficiaries (list 10 (string-ascii 40))) (shares (list 10 uint)))
(let
(
(next-id (+ u1 (var-get last-token-id)))
)
(asserts! (is-administrator) not-allowed)
(try! (as-contract (nft-mint? superfandom-nft next-id tx-sender)))
(map-insert nft-data next-id {metadata-url: metadataUrl, creator-fandom-id: creatorSuperFandomId,
owner-fandom-id: ownerSuperFandomId, mint-block-height: block-height, redemption-count: redemptionCount,
beneficiaries: beneficiaries,
shares: shares})
(var-set last-token-id next-id)
(print {action: "mint-token", token-id: next-id, tx-sender: tx-sender})
(ok next-id)
)
)
(define-public (transfer (tokenId uint) (owner principal) (recipient principal))
transfer-not-supported
)
(define-public (burn-token (tokenId uint))
(begin
(asserts! (is-administrator) not-allowed)
(unwrap! (as-contract (nft-burn? superfandom-nft tokenId tx-sender)) not-found)
(map-delete nft-data tokenId)
(print {action: "burn-token", token-id: tokenId, tx-sender: tx-sender})
(ok true)
)
)
(define-public (change-fandom-owner (tokenId uint) (newOwnerSuperFandomId (string-ascii 40)))
(begin
(asserts! (is-administrator) not-allowed)
(let
(
(token-data (unwrap! (map-get? nft-data tokenId) not-found))
)
(map-set nft-data tokenId (merge token-data {owner-fandom-id: newOwnerSuperFandomId}))
(print {action: "change-fandom-owner", token-id: tokenId, tx-sender: tx-sender, new-owner-fandom-id: newOwnerSuperFandomId})
(ok true)
)
)
)
(define-public (redeem (tokenId uint) (ownerSuperFandomId (string-ascii 40)))
(begin
(asserts! (is-administrator) not-allowed)
(let
(
(token-data (unwrap! (map-get? nft-data tokenId) not-found))
(token-owner-fandom-id (get owner-fandom-id token-data))
(creator-fandom-id (get creator-fandom-id token-data))
(redemption-count (get redemption-count token-data))
)
(asserts! (> redemption-count u0) not-allowed)
(asserts! (is-eq ownerSuperFandomId token-owner-fandom-id) not-allowed)
(asserts! (not (is-eq creator-fandom-id ownerSuperFandomId)) not-allowed)
(map-set nft-data tokenId (merge token-data {redemption-count: (- redemption-count u1)}))
(print {action: "redeem", token-id: tokenId, tx-sender: tx-sender, redemption-count: (- redemption-count u1)})
(ok (- redemption-count u1))
)
)
)
(define-public (update-beneficiaries (tokenId uint)
(beneficiaries (list 10 (string-ascii 40))) (shares (list 10 uint)))
(begin
(asserts! (is-administrator) not-allowed)
(let
(
(token-data (unwrap! (map-get? nft-data tokenId) not-found))
)
(map-set nft-data tokenId (merge token-data {beneficiaries: beneficiaries, shares: shares}))
(print {action: "update-beneficiaries", token-id: tokenId, tx-sender: tx-sender, beneficiaries: beneficiaries})
(ok true)
)
)
)
(define-public (update-token-uri (tokenId uint) (newMetadataURL (string-ascii 256)))
(begin
(asserts! (is-administrator) not-allowed)
(let
(
(token-data (unwrap! (map-get? nft-data tokenId) not-found))
)
(map-set nft-data tokenId (merge token-data {metadata-url: newMetadataURL}))
(print {action: "update-token-uri", token-id: tokenId, tx-sender: tx-sender, metadata-url: newMetadataURL})
(ok true)
)
)
)
(define-read-only (get-owner (token-id uint))
(ok (nft-get-owner? superfandom-nft token-id))
)
(define-read-only (get-last-token-id)
(ok (var-get last-token-id)))
(define-read-only (get-token-uri (token-id uint))
(ok (get metadata-url (map-get? nft-data token-id)))
)
(define-read-only (get-owner-fandom-id (token-id uint))
(get owner-fandom-id (map-get? nft-data token-id))
)
(define-read-only (get-administrator)
(var-get administrator)
)
(define-read-only (is-administrator)
(is-eq (var-get administrator) tx-sender)
)
(define-read-only (get-redemption-count (token-id uint))
(get redemption-count (map-get? nft-data token-id))
)
(define-read-only (get-beneficiaries (token-id uint))
(get beneficiaries (map-get? nft-data token-id))
)
(define-read-only (get-shares (token-id uint))
(get shares (map-get? nft-data token-id))
)
(define-read-only (get-token-data (token-id uint))
(map-get? nft-data token-id)
)