;; SatGuard Rewards Vesting
(define-constant err-nf (err u430))
(define-constant err-early (err u431))
(define-constant err-owner (err u432))
(define-constant err-amt (err u433))
(define-data-var admin principal tx-sender)
(define-data-var vest-period uint u4320) ;; ~30 days in blocks
(define-data-var v-nonce uint u0)
(define-map vests {id: uint} {who: principal,total: uint,claimed: uint,start: uint,end: uint})
(define-read-only (get-vest (id uint)) (map-get? vests {id: id}))
(define-public (create-vest (who principal) (amt uint))
(let ((nid (+ (var-get v-nonce) u1)))
(asserts! (is-eq tx-sender (var-get admin)) err-owner)
(asserts! (> amt u0) err-amt)
(map-set vests {id: nid} {who: who,total: amt,claimed: u0,start: block-height,end: (+ block-height (var-get vest-period))})
(var-set v-nonce nid)
(print {e: "vest-created",id: nid,who: who,amt: amt})
(ok nid)))
(define-read-only (get-vested-amt (id uint))
(let ((v (unwrap! (map-get? vests {id: id}) (err u430))))
(if (>= block-height (get end v))
(ok (- (get total v) (get claimed v)))
(let ((elapsed (- block-height (get start v)))
(duration (- (get end v) (get start v)))
(vested (/ (* (get total v) elapsed) duration)))
(ok (- vested (get claimed v)))))))
(define-public (claim-vested (id uint))
(let ((v (unwrap! (map-get? vests {id: id}) err-nf))
(avail (unwrap! (get-vested-amt id) err-nf)))
(asserts! (is-eq tx-sender (get who v)) err-owner)
(asserts! (> avail u0) err-amt)
(try! (contract-call? .sg-token-core mint avail tx-sender))
(map-set vests {id: id} (merge v {claimed: (+ (get claimed v) avail)}))
(print {e: "vested-claimed",id: id,amt: avail})
(ok avail)))