Source Code

;; DIAMOND HANDS PROTOCOL V3 - Lock. Earn. Prove Your Commitment.
;; Non-Custodial DeFi Vaults with Points System
;; Supports STX and sBTC
;; Built with Clarity 4

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

(define-constant CONTRACT_OWNER tx-sender)
(define-constant ERR_UNAUTHORIZED (err u100))
(define-constant ERR_NOT_FOUND (err u101))
(define-constant ERR_INACTIVE (err u102))
(define-constant ERR_AMOUNT (err u103))
(define-constant ERR_LOCK_PERIOD (err u104))
(define-constant ERR_NOT_UNLOCKED (err u105))
(define-constant ERR_ALREADY_WITHDRAWN (err u106))
(define-constant ERR_TRANSFER_FAILED (err u107))
(define-constant ERR_INVALID_NAME (err u108))
(define-constant ERR_INVALID_ASSET (err u109))

;; Vault parameters
(define-constant MIN_STX_DEPOSIT u1000000)        ;; 1 STX minimum
(define-constant MIN_SBTC_DEPOSIT u10000)         ;; 0.0001 sBTC minimum (8 decimals)
(define-constant MIN_LOCK u604800)                ;; 7 days in seconds
(define-constant MAX_LOCK u7776000)               ;; 90 days in seconds
(define-constant FEE_BPS u25)                     ;; 0.25% creation fee (reduced!)
(define-constant EARLY_PENALTY_BPS u1000)         ;; 10% early withdrawal penalty

;; Points multipliers (basis points, 10000 = 1x)
(define-constant POINTS_MULT_7_DAYS u10000)       ;; 1x for 7-29 days
(define-constant POINTS_MULT_30_DAYS u15000)      ;; 1.5x for 30-59 days
(define-constant POINTS_MULT_60_DAYS u20000)      ;; 2x for 60-89 days
(define-constant POINTS_MULT_90_DAYS u30000)      ;; 3x for 90 days

;; sBTC points bonus (10x because BTC is more valuable)
(define-constant SBTC_POINTS_MULTIPLIER u10)

;; Asset types
(define-constant ASSET_STX u1)
(define-constant ASSET_SBTC u2)

;; sBTC Contract Reference
;; For simnet/testnet: uses local mock contract
;; For mainnet: deploy with mainnet sBTC address (SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token)
(define-constant SBTC_CONTRACT .sbtc-token)

;; ============================================
;; DATA VARIABLES
;; ============================================

(define-data-var vault-nonce uint u0)
(define-data-var total-tvl-stx uint u0)
(define-data-var total-tvl-sbtc uint u0)
(define-data-var total-fees-stx uint u0)
(define-data-var total-fees-sbtc uint u0)
(define-data-var total-points uint u0)
(define-data-var fee-recipient principal tx-sender)

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

;; Main vault storage
(define-map vaults uint {
    owner: principal,
    name: (string-ascii 50),
    asset-type: uint,
    amount: uint,
    lock-time: uint,
    unlock-time: uint,
    points-earned: uint,
    active: bool
})

;; User stats
(define-map user-stats principal {
    total-vaults: uint,
    active-vaults: uint,
    total-points: uint,
    total-stx-locked: uint,
    total-sbtc-locked: uint
})

;; Leaderboard tracking (top point holders)
(define-map user-points principal uint)

;; Passkey storage for WebAuthn
(define-map passkeys principal (buff 33))

;; ============================================
;; POINTS CALCULATION
;; ============================================

;; Get points multiplier based on lock duration
(define-read-only (get-points-multiplier (lock-seconds uint))
    (if (>= lock-seconds u7776000)  ;; 90 days
        POINTS_MULT_90_DAYS
        (if (>= lock-seconds u5184000)  ;; 60 days
            POINTS_MULT_60_DAYS
            (if (>= lock-seconds u2592000)  ;; 30 days
                POINTS_MULT_30_DAYS
                POINTS_MULT_7_DAYS))))

;; Calculate points for a deposit
;; Formula: (amount / 1000000) * (lock_days) * multiplier / 10000
;; For sBTC: additional 10x multiplier
(define-read-only (calculate-points (amount uint) (lock-seconds uint) (asset-type uint))
    (let (
        (lock-days (/ lock-seconds u86400))
        (multiplier (get-points-multiplier lock-seconds))
        (base-points (/ (* (/ amount u1000000) (* lock-days multiplier)) u10000))
    )
        (if (is-eq asset-type ASSET_SBTC)
            (* base-points SBTC_POINTS_MULTIPLIER)
            base-points)))

;; ============================================
;; CLARITY 4: stacks-block-time
;; ============================================

(define-read-only (get-current-time)
    stacks-block-time)

(define-read-only (get-time-remaining (vault-id uint))
    (match (map-get? vaults vault-id)
        vault (if (>= stacks-block-time (get unlock-time vault))
            (ok u0)
            (ok (- (get unlock-time vault) stacks-block-time)))
        ERR_NOT_FOUND))

(define-read-only (is-vault-unlocked (vault-id uint))
    (match (map-get? vaults vault-id)
        vault (ok (>= stacks-block-time (get unlock-time vault)))
        ERR_NOT_FOUND))

;; ============================================
;; CLARITY 4: secp256r1-verify (Passkey)
;; ============================================

(define-public (register-passkey (public-key (buff 33)))
    (begin
        (map-set passkeys tx-sender public-key)
        (ok true)))

(define-read-only (get-passkey (user principal))
    (map-get? passkeys user))

(define-private (verify-passkey (user principal) (message-hash (buff 32)) (signature (buff 64)))
    (match (map-get? passkeys user)
        pk (secp256r1-verify message-hash signature pk)
        false))

;; ============================================
;; CLARITY 4: contract-hash?
;; ============================================

(define-read-only (get-contract-hash (contract principal))
    (contract-hash? contract))

(define-read-only (verify-contract (contract principal) (expected-hash (buff 32)))
    (match (contract-hash? contract)
        hash (is-eq hash expected-hash)
        err-val false))

;; ============================================
;; CLARITY 4: to-ascii? (Human-readable receipts)
;; ============================================

(define-read-only (get-vault-receipt (vault-id uint))
    (match (map-get? vaults vault-id)
        vault (ok (concat "DIAMOND-V3-" 
                    (concat (unwrap-panic (to-ascii? vault-id)) 
                        (concat "-" 
                            (concat (get name vault)
                                (concat "-"
                                    (concat (unwrap-panic (to-ascii? (get points-earned vault)))
                                        (concat "pts-"
                                            (if (get active vault) "ACTIVE" "WITHDRAWN")))))))))
        ERR_NOT_FOUND))

;; ============================================
;; CORE FUNCTIONS - STX VAULTS
;; ============================================

;; CREATE STX VAULT with custom name
(define-public (create-stx-vault (amount uint) (lock-seconds uint) (vault-name (string-ascii 50)))
    (let (
        (vault-id (+ (var-get vault-nonce) u1))
        (fee (/ (* amount FEE_BPS) u10000))
        (deposit-amount (- amount fee))
        (unlock-time (+ stacks-block-time lock-seconds))
        (points (calculate-points deposit-amount lock-seconds ASSET_STX))
        (current-stats (default-to 
            { total-vaults: u0, active-vaults: u0, total-points: u0, total-stx-locked: u0, total-sbtc-locked: u0 }
            (map-get? user-stats tx-sender)))
        (contract-addr (unwrap-panic (as-contract? () tx-sender)))
    )
        ;; Validations
        (asserts! (>= amount MIN_STX_DEPOSIT) ERR_AMOUNT)
        (asserts! (>= lock-seconds MIN_LOCK) ERR_LOCK_PERIOD)
        (asserts! (<= lock-seconds MAX_LOCK) ERR_LOCK_PERIOD)
        (asserts! (> (len vault-name) u0) ERR_INVALID_NAME)
        
        ;; Transfer STX to contract
        (try! (stx-transfer? deposit-amount tx-sender contract-addr))
        
        ;; Transfer fee to fee recipient
        (if (> fee u0)
            (try! (stx-transfer? fee tx-sender (var-get fee-recipient)))
            true)
        
        ;; Create vault record
        (map-set vaults vault-id {
            owner: tx-sender,
            name: vault-name,
            asset-type: ASSET_STX,
            amount: deposit-amount,
            lock-time: stacks-block-time,
            unlock-time: unlock-time,
            points-earned: points,
            active: true
        })
        
        ;; Update user stats
        (map-set user-stats tx-sender {
            total-vaults: (+ (get total-vaults current-stats) u1),
            active-vaults: (+ (get active-vaults current-stats) u1),
            total-points: (+ (get total-points current-stats) points),
            total-stx-locked: (+ (get total-stx-locked current-stats) deposit-amount),
            total-sbtc-locked: (get total-sbtc-locked current-stats)
        })
        
        ;; Update user points map
        (map-set user-points tx-sender 
            (+ (default-to u0 (map-get? user-points tx-sender)) points))
        
        ;; Update global counters
        (var-set vault-nonce vault-id)
        (var-set total-tvl-stx (+ (var-get total-tvl-stx) deposit-amount))
        (var-set total-fees-stx (+ (var-get total-fees-stx) fee))
        (var-set total-points (+ (var-get total-points) points))
        
        ;; Emit event
        (print {
            event: "vault-created",
            protocol: "diamond-hands-v3",
            vault-id: vault-id,
            owner: tx-sender,
            name: vault-name,
            asset: "STX",
            amount: deposit-amount,
            lock-time: stacks-block-time,
            unlock-time: unlock-time,
            points-earned: points
        })
        
        (ok vault-id)))

;; WITHDRAW STX - Direct to user wallet
(define-public (withdraw-stx (vault-id uint))
    (let (
        (vault (unwrap! (map-get? vaults vault-id) ERR_NOT_FOUND))
        (owner (get owner vault))
        (amount (get amount vault))
        (unlock-time (get unlock-time vault))
        (current-stats (unwrap! (map-get? user-stats owner) ERR_NOT_FOUND))
    )
        ;; Validations
        (asserts! (is-eq tx-sender owner) ERR_UNAUTHORIZED)
        (asserts! (get active vault) ERR_ALREADY_WITHDRAWN)
        (asserts! (is-eq (get asset-type vault) ASSET_STX) ERR_INVALID_ASSET)
        (asserts! (>= stacks-block-time unlock-time) ERR_NOT_UNLOCKED)
        
        ;; Transfer STX to user
        (try! (as-contract? ((with-stx amount))
            (try! (stx-transfer? amount tx-sender owner))))
        
        ;; Update vault status
        (map-set vaults vault-id (merge vault {
            active: false,
            amount: u0
        }))
        
        ;; Update user stats
        (map-set user-stats owner (merge current-stats {
            active-vaults: (- (get active-vaults current-stats) u1)
        }))
        
        ;; Update TVL
        (var-set total-tvl-stx (- (var-get total-tvl-stx) amount))
        
        ;; Emit event
        (print {
            event: "vault-withdrawn",
            protocol: "diamond-hands-v3",
            vault-id: vault-id,
            owner: owner,
            name: (get name vault),
            asset: "STX",
            amount: amount,
            points-retained: (get points-earned vault)
        })
        
        (ok amount)))

;; EARLY WITHDRAW STX - With 10% penalty
(define-public (early-withdraw-stx (vault-id uint))
    (let (
        (vault (unwrap! (map-get? vaults vault-id) ERR_NOT_FOUND))
        (owner (get owner vault))
        (amount (get amount vault))
        (penalty (/ (* amount EARLY_PENALTY_BPS) u10000))
        (payout (- amount penalty))
        (fee-addr (var-get fee-recipient))
        (current-stats (unwrap! (map-get? user-stats owner) ERR_NOT_FOUND))
        ;; Forfeit 50% of points on early withdrawal
        (points-forfeited (/ (get points-earned vault) u2))
    )
        ;; Validations
        (asserts! (is-eq tx-sender owner) ERR_UNAUTHORIZED)
        (asserts! (get active vault) ERR_ALREADY_WITHDRAWN)
        (asserts! (is-eq (get asset-type vault) ASSET_STX) ERR_INVALID_ASSET)
        
        ;; Transfer payout to user and penalty to fee recipient
        (try! (as-contract? ((with-stx amount))
            (begin
                (try! (stx-transfer? payout tx-sender owner))
                (try! (stx-transfer? penalty tx-sender fee-addr)))))
        
        ;; Update vault status
        (map-set vaults vault-id (merge vault {
            active: false,
            amount: u0,
            points-earned: (- (get points-earned vault) points-forfeited)
        }))
        
        ;; Update user stats (reduce points)
        (map-set user-stats owner (merge current-stats {
            active-vaults: (- (get active-vaults current-stats) u1),
            total-points: (- (get total-points current-stats) points-forfeited)
        }))
        
        ;; Update user points map
        (map-set user-points owner 
            (- (default-to u0 (map-get? user-points owner)) points-forfeited))
        
        ;; Update counters
        (var-set total-tvl-stx (- (var-get total-tvl-stx) amount))
        (var-set total-fees-stx (+ (var-get total-fees-stx) penalty))
        (var-set total-points (- (var-get total-points) points-forfeited))
        
        ;; Emit event
        (print {
            event: "vault-early-withdrawn",
            protocol: "diamond-hands-v3",
            vault-id: vault-id,
            owner: owner,
            name: (get name vault),
            asset: "STX",
            payout: payout,
            penalty: penalty,
            points-forfeited: points-forfeited
        })
        
        (ok payout)))

;; ============================================
;; CORE FUNCTIONS - sBTC VAULTS
;; ============================================

;; CREATE sBTC VAULT with custom name
;; Note: User must approve sBTC transfer first
(define-public (create-sbtc-vault (amount uint) (lock-seconds uint) (vault-name (string-ascii 50)))
    (let (
        (vault-id (+ (var-get vault-nonce) u1))
        (fee (/ (* amount FEE_BPS) u10000))
        (deposit-amount (- amount fee))
        (unlock-time (+ stacks-block-time lock-seconds))
        (points (calculate-points deposit-amount lock-seconds ASSET_SBTC))
        (current-stats (default-to 
            { total-vaults: u0, active-vaults: u0, total-points: u0, total-stx-locked: u0, total-sbtc-locked: u0 }
            (map-get? user-stats tx-sender)))
        (contract-addr (unwrap-panic (as-contract? () tx-sender)))
    )
        ;; Validations
        (asserts! (>= amount MIN_SBTC_DEPOSIT) ERR_AMOUNT)
        (asserts! (>= lock-seconds MIN_LOCK) ERR_LOCK_PERIOD)
        (asserts! (<= lock-seconds MAX_LOCK) ERR_LOCK_PERIOD)
        (asserts! (> (len vault-name) u0) ERR_INVALID_NAME)
        
        ;; Transfer sBTC to contract (SIP-010 ft-transfer)
        (try! (contract-call? SBTC_CONTRACT transfer deposit-amount tx-sender contract-addr none))
        
        ;; Transfer fee to fee recipient
        (if (> fee u0)
            (try! (contract-call? SBTC_CONTRACT transfer fee tx-sender (var-get fee-recipient) none))
            true)
        
        ;; Create vault record
        (map-set vaults vault-id {
            owner: tx-sender,
            name: vault-name,
            asset-type: ASSET_SBTC,
            amount: deposit-amount,
            lock-time: stacks-block-time,
            unlock-time: unlock-time,
            points-earned: points,
            active: true
        })
        
        ;; Update user stats
        (map-set user-stats tx-sender {
            total-vaults: (+ (get total-vaults current-stats) u1),
            active-vaults: (+ (get active-vaults current-stats) u1),
            total-points: (+ (get total-points current-stats) points),
            total-stx-locked: (get total-stx-locked current-stats),
            total-sbtc-locked: (+ (get total-sbtc-locked current-stats) deposit-amount)
        })
        
        ;; Update user points map
        (map-set user-points tx-sender 
            (+ (default-to u0 (map-get? user-points tx-sender)) points))
        
        ;; Update global counters
        (var-set vault-nonce vault-id)
        (var-set total-tvl-sbtc (+ (var-get total-tvl-sbtc) deposit-amount))
        (var-set total-fees-sbtc (+ (var-get total-fees-sbtc) fee))
        (var-set total-points (+ (var-get total-points) points))
        
        ;; Emit event
        (print {
            event: "vault-created",
            protocol: "diamond-hands-v3",
            vault-id: vault-id,
            owner: tx-sender,
            name: vault-name,
            asset: "sBTC",
            amount: deposit-amount,
            lock-time: stacks-block-time,
            unlock-time: unlock-time,
            points-earned: points
        })
        
        (ok vault-id)))

;; WITHDRAW sBTC - Direct to user wallet
(define-public (withdraw-sbtc (vault-id uint))
    (let (
        (vault (unwrap! (map-get? vaults vault-id) ERR_NOT_FOUND))
        (owner (get owner vault))
        (amount (get amount vault))
        (unlock-time (get unlock-time vault))
        (current-stats (unwrap! (map-get? user-stats owner) ERR_NOT_FOUND))
    )
        ;; Validations
        (asserts! (is-eq tx-sender owner) ERR_UNAUTHORIZED)
        (asserts! (get active vault) ERR_ALREADY_WITHDRAWN)
        (asserts! (is-eq (get asset-type vault) ASSET_SBTC) ERR_INVALID_ASSET)
        (asserts! (>= stacks-block-time unlock-time) ERR_NOT_UNLOCKED)
        
        ;; Transfer sBTC to user - the FT contract handles authorization
        (try! (as-contract? ()
            (try! (contract-call? SBTC_CONTRACT transfer amount tx-sender owner none))))
        
        ;; Update vault status
        (map-set vaults vault-id (merge vault {
            active: false,
            amount: u0
        }))
        
        ;; Update user stats
        (map-set user-stats owner (merge current-stats {
            active-vaults: (- (get active-vaults current-stats) u1)
        }))
        
        ;; Update TVL
        (var-set total-tvl-sbtc (- (var-get total-tvl-sbtc) amount))
        
        ;; Emit event
        (print {
            event: "vault-withdrawn",
            protocol: "diamond-hands-v3",
            vault-id: vault-id,
            owner: owner,
            name: (get name vault),
            asset: "sBTC",
            amount: amount,
            points-retained: (get points-earned vault)
        })
        
        (ok amount)))

;; EARLY WITHDRAW sBTC - With 10% penalty
(define-public (early-withdraw-sbtc (vault-id uint))
    (let (
        (vault (unwrap! (map-get? vaults vault-id) ERR_NOT_FOUND))
        (owner (get owner vault))
        (amount (get amount vault))
        (penalty (/ (* amount EARLY_PENALTY_BPS) u10000))
        (payout (- amount penalty))
        (fee-addr (var-get fee-recipient))
        (current-stats (unwrap! (map-get? user-stats owner) ERR_NOT_FOUND))
        (points-forfeited (/ (get points-earned vault) u2))
    )
        ;; Validations
        (asserts! (is-eq tx-sender owner) ERR_UNAUTHORIZED)
        (asserts! (get active vault) ERR_ALREADY_WITHDRAWN)
        (asserts! (is-eq (get asset-type vault) ASSET_SBTC) ERR_INVALID_ASSET)
        
        ;; Transfer sBTC - payout to user, penalty to fee recipient
        (try! (as-contract? ()
            (begin
                (unwrap-panic (contract-call? SBTC_CONTRACT transfer payout tx-sender owner none))
                (try! (contract-call? SBTC_CONTRACT transfer penalty tx-sender fee-addr none)))))
        
        ;; Update vault status
        (map-set vaults vault-id (merge vault {
            active: false,
            amount: u0,
            points-earned: (- (get points-earned vault) points-forfeited)
        }))
        
        ;; Update user stats
        (map-set user-stats owner (merge current-stats {
            active-vaults: (- (get active-vaults current-stats) u1),
            total-points: (- (get total-points current-stats) points-forfeited)
        }))
        
        ;; Update user points map
        (map-set user-points owner 
            (- (default-to u0 (map-get? user-points owner)) points-forfeited))
        
        ;; Update counters
        (var-set total-tvl-sbtc (- (var-get total-tvl-sbtc) amount))
        (var-set total-fees-sbtc (+ (var-get total-fees-sbtc) penalty))
        (var-set total-points (- (var-get total-points) points-forfeited))
        
        ;; Emit event
        (print {
            event: "vault-early-withdrawn",
            protocol: "diamond-hands-v3",
            vault-id: vault-id,
            owner: owner,
            name: (get name vault),
            asset: "sBTC",
            payout: payout,
            penalty: penalty,
            points-forfeited: points-forfeited
        })
        
        (ok payout)))

;; ============================================
;; READ-ONLY FUNCTIONS
;; ============================================

(define-read-only (get-vault (vault-id uint))
    (map-get? vaults vault-id))

(define-read-only (get-vault-info (vault-id uint))
    (match (map-get? vaults vault-id)
        vault (ok {
            id: vault-id,
            owner: (get owner vault),
            name: (get name vault),
            asset-type: (get asset-type vault),
            asset-name: (if (is-eq (get asset-type vault) ASSET_STX) "STX" "sBTC"),
            amount: (get amount vault),
            lock-time: (get lock-time vault),
            unlock-time: (get unlock-time vault),
            points-earned: (get points-earned vault),
            active: (get active vault),
            is-unlocked: (>= stacks-block-time (get unlock-time vault)),
            time-remaining: (if (>= stacks-block-time (get unlock-time vault))
                u0
                (- (get unlock-time vault) stacks-block-time))
        })
        ERR_NOT_FOUND))

(define-read-only (get-user-stats (user principal))
    (default-to 
        { total-vaults: u0, active-vaults: u0, total-points: u0, total-stx-locked: u0, total-sbtc-locked: u0 }
        (map-get? user-stats user)))

(define-read-only (get-user-points (user principal))
    (default-to u0 (map-get? user-points user)))

(define-read-only (get-protocol-stats)
    {
        total-vaults: (var-get vault-nonce),
        total-tvl-stx: (var-get total-tvl-stx),
        total-tvl-sbtc: (var-get total-tvl-sbtc),
        total-fees-stx: (var-get total-fees-stx),
        total-fees-sbtc: (var-get total-fees-sbtc),
        total-points: (var-get total-points),
        current-time: stacks-block-time,
        min-stx-deposit: MIN_STX_DEPOSIT,
        min-sbtc-deposit: MIN_SBTC_DEPOSIT,
        min-lock: MIN_LOCK,
        max-lock: MAX_LOCK,
        fee-bps: FEE_BPS,
        early-penalty-bps: EARLY_PENALTY_BPS
    })

;; Points estimation for UI
(define-read-only (estimate-points (amount uint) (lock-seconds uint) (asset-type uint))
    (let (
        (fee (/ (* amount FEE_BPS) u10000))
        (deposit-amount (- amount fee))
    )
        {
            deposit-after-fee: deposit-amount,
            fee: fee,
            points: (calculate-points deposit-amount lock-seconds asset-type),
            multiplier: (get-points-multiplier lock-seconds)
        }))

;; Get tier based on lock duration
(define-read-only (get-tier-name (lock-seconds uint))
    (if (>= lock-seconds u7776000)
        "DIAMOND"
        (if (>= lock-seconds u5184000)
            "GOLD"
            (if (>= lock-seconds u2592000)
                "SILVER"
                "BRONZE"))))

;; ============================================
;; ADMIN FUNCTIONS (Limited)
;; ============================================

(define-public (set-fee-recipient (new-recipient principal))
    (begin
        (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_UNAUTHORIZED)
        (var-set fee-recipient new-recipient)
        (ok true)))

;; ============================================
;; CONTRACT INFO
;; ============================================

(define-read-only (get-contract-info)
    {
        name: "Diamond Hands Protocol",
        version: "3.0.0",
        description: "Lock. Earn. Prove your commitment.",
        tagline: "Non-custodial time-locked vaults with points rewards",
        features: (list 
            "vault-naming"
            "points-system"
            "stx-vaults"
            "sbtc-vaults"
            "stacks-block-time"
            "secp256r1-verify" 
            "contract-hash?"
            "to-ascii?"
        ),
        points-tiers: (list
            "BRONZE: 7-29 days (1x)"
            "SILVER: 30-59 days (1.5x)"
            "GOLD: 60-89 days (2x)"
            "DIAMOND: 90 days (3x)"
        ),
        custodial: false,
        auto-withdraw: true
    })

Functions (26)

FunctionAccessArgs
get-points-multiplierread-onlylock-seconds: uint
calculate-pointsread-onlyamount: uint, lock-seconds: uint, asset-type: uint
get-current-timeread-only
get-time-remainingread-onlyvault-id: uint
is-vault-unlockedread-onlyvault-id: uint
register-passkeypublicpublic-key: (buff 33
get-passkeyread-onlyuser: principal
verify-passkeyprivateuser: principal, message-hash: (buff 32
get-contract-hashread-onlycontract: principal
verify-contractread-onlycontract: principal, expected-hash: (buff 32
get-vault-receiptread-onlyvault-id: uint
create-stx-vaultpublicamount: uint, lock-seconds: uint, vault-name: (string-ascii 50
withdraw-stxpublicvault-id: uint
early-withdraw-stxpublicvault-id: uint
create-sbtc-vaultpublicamount: uint, lock-seconds: uint, vault-name: (string-ascii 50
withdraw-sbtcpublicvault-id: uint
early-withdraw-sbtcpublicvault-id: uint
get-vaultread-onlyvault-id: uint
get-vault-inforead-onlyvault-id: uint
get-user-statsread-onlyuser: principal
get-user-pointsread-onlyuser: principal
get-protocol-statsread-only
estimate-pointsread-onlyamount: uint, lock-seconds: uint, asset-type: uint
get-tier-nameread-onlylock-seconds: uint
set-fee-recipientpublicnew-recipient: principal
get-contract-inforead-only