;; eg. case
;; (contract-call? .backgrounds mint-name 'STNHKEPYEPJ8ET55ZZ0M5A34J0R3N5FM2CMMMAZ6 "DarkPurple")
;; (contract-call? .cars mint-name 'STNHKEPYEPJ8ET55ZZ0M5A34J0R3N5FM2CMMMAZ6 "BentleyBlack")
;; (contract-call? .rims mint-name 'STNHKEPYEPJ8ET55ZZ0M5A34J0R3N5FM2CMMMAZ6 "ClassyCream")
;; (contract-call? .heads mint-name 'STNHKEPYEPJ8ET55ZZ0M5A34J0R3N5FM2CMMMAZ6 "NYC_Antenna_BigSmile")
;; ::set_tx_sender STNHKEPYEPJ8ET55ZZ0M5A34J0R3N5FM2CMMMAZ6
;; (contract-call? 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.upgrade-contract add-assemble-work-in-queue u1 u1 u1 u1)
;; ::set_tx_sender ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
;; (contract-call? .upgrade-contract assemble-finalize 'STNHKEPYEPJ8ET55ZZ0M5A34J0R3N5FM2CMMMAZ6 "uri-custom")
(define-data-var assemble-work-queue (list 100 {member: principal, background-id: uint, car-id: uint, rim-id: uint, head-id: uint}) (list))
(define-public (assemble-finalize (member principal) (metadata-uri (string-ascii 99)))
(begin
;; Check that admin is calling this contract
(asserts! (is-eq tx-sender (var-get contract-owner)) err-invalid)
(unwrap-panic (contract-call? .degens mint-uri member metadata-uri))
(pop-assemble-work-queue)))
(define-read-only (get-assemble-work-queue)
;; Get the actual work-queue so that we can process it
(ok (var-get assemble-work-queue)))
(define-read-only (get-assemble-head-work-queue)
;; Get the first element in the work queue so that we can process it
(ok (element-at (var-get assemble-work-queue) u0)))
(define-public (prepare-assemble (background-id uint) (car-id uint) (rim-id uint) (head-id uint))
(add-assemble-work-in-queue background-id car-id rim-id head-id))
(define-public (add-assemble-work-in-queue (background-id uint) (car-id uint) (rim-id uint) (head-id uint))
(ok
(begin
;; check user is owner of nft
(asserts!
(and
(is-eq (some tx-sender) (unwrap-panic (contract-call? .backgrounds get-owner background-id)))
(and
(is-eq (some tx-sender) (unwrap-panic (contract-call? .cars get-owner car-id)))
(and
(is-eq (some tx-sender) (unwrap-panic (contract-call? .rims get-owner rim-id)))
(is-eq (some tx-sender) (unwrap-panic (contract-call? .heads get-owner head-id))))))
err-not-owner)
(if (is-eq tx-sender (var-get contract-owner)) true (try! (fee-processing)))
(let ((work-queue-value (var-get assemble-work-queue))
(value-to-add {
member: tx-sender,
background-id: background-id,
car-id: car-id,
rim-id: rim-id,
head-id: head-id
}))
(var-set assemble-work-queue
(begin
;; check user has not already inserted this
;; if the id is already in the queue that means the NFT is burnt => throws err-not-owner when calling for get-owner
;; (asserts!
;; (is-none (index-of work-queue-value value-to-add))
;; err-invalid
;; )
;; check user is not abusing the queue
(asserts!
(< (len (filter is-assemble-value-for-principal work-queue-value)) u5)
err-too-many-pending-requests)
(unwrap-panic (contract-call? .backgrounds burn-token background-id))
(unwrap-panic (contract-call? .cars burn-token car-id))
(unwrap-panic (contract-call? .rims burn-token rim-id))
(unwrap-panic (contract-call? .heads burn-token head-id))
(append
(unwrap-panic (as-max-len? work-queue-value u99))
value-to-add)))))))
(define-private (pop-assemble-work-queue)
(ok
(let
((work-queue-value (var-get assemble-work-queue)))
(var-set assemble-work-queue
;; Remove first element in list
(filter is-assemble-first-element work-queue-value)))))
(define-private (is-assemble-first-element (value {background-id: uint, car-id: uint, rim-id: uint, head-id: uint, member: principal}))
(let
((first-element (element-at (var-get assemble-work-queue) u0)))
(not
(and
(is-some first-element)
(is-eq value (unwrap-panic first-element))))))
(define-private (is-assemble-value-for-principal (value {background-id: uint, car-id: uint, rim-id: uint, head-id: uint, member: principal}))
(is-eq (get member value) tx-sender))