Source Code

(define-constant contract-owner tx-sender)
(define-constant err-owner-only (err u100))
(define-constant err-not-found (err u101))
(define-constant err-unauthorized (err u102))
(define-constant err-already-exists (err u103))
(define-constant err-invalid-amount (err u104))
(define-constant err-insufficient-balance (err u105))
(define-constant err-payment-failed (err u106))

(define-data-var payment-nonce uint u0)

(define-map robot-wallets
  principal
  {
    robot-id: uint,
    balance: uint,
    total-sent: uint,
    total-received: uint,
    escrow-locked: uint
  }
)

(define-map payments
  uint
  {
    sender: principal,
    receiver: principal,
    amount: uint,
    service-type: (string-ascii 40),
    payment-block: uint,
    status: (string-ascii 20),
    escrow-release-block: (optional uint)
  }
)

(define-map escrow-payments
  uint
  {
    payer: principal,
    payee: principal,
    amount: uint,
    release-condition-hash: (buff 32),
    released: bool,
    refunded: bool
  }
)

(define-map wallet-payments principal (list 200 uint))

(define-public (initialize-wallet (robot-id uint))
  (begin
    (asserts! (is-none (map-get? robot-wallets tx-sender)) err-already-exists)
    (map-set robot-wallets tx-sender
      {
        robot-id: robot-id,
        balance: u0,
        total-sent: u0,
        total-received: u0,
        escrow-locked: u0
      }
    )
    (ok true)
  )
)

(define-public (deposit-funds (amount uint))
  (let
    (
      (wallet (unwrap! (map-get? robot-wallets tx-sender) err-not-found))
    )
    (asserts! (> amount u0) err-invalid-amount)
    (try! (stx-transfer? amount tx-sender (as-contract tx-sender)))
    (map-set robot-wallets tx-sender (merge wallet {
      balance: (+ (get balance wallet) amount)
    }))
    (ok true)
  )
)

(define-public (send-payment (receiver principal) (amount uint) (service-type (string-ascii 40)))
  (let
    (
      (sender-wallet (unwrap! (map-get? robot-wallets tx-sender) err-not-found))
      (receiver-wallet (unwrap! (map-get? robot-wallets receiver) err-not-found))
      (payment-id (+ (var-get payment-nonce) u1))
    )
    (asserts! (> amount u0) err-invalid-amount)
    (asserts! (>= (get balance sender-wallet) amount) err-insufficient-balance)
    (map-set robot-wallets tx-sender (merge sender-wallet {
      balance: (- (get balance sender-wallet) amount),
      total-sent: (+ (get total-sent sender-wallet) amount)
    }))
    (map-set robot-wallets receiver (merge receiver-wallet {
      balance: (+ (get balance receiver-wallet) amount),
      total-received: (+ (get total-received receiver-wallet) amount)
    }))
    (map-set payments payment-id
      {
        sender: tx-sender,
        receiver: receiver,
        amount: amount,
        service-type: service-type,
        payment-block: stacks-block-height,
        status: "completed",
        escrow-release-block: none
      }
    )
    (map-set wallet-payments tx-sender
      (unwrap-panic (as-max-len? (append (default-to (list) (map-get? wallet-payments tx-sender)) payment-id) u200)))
    (var-set payment-nonce payment-id)
    (ok payment-id)
  )
)

(define-public (create-escrow-payment (payee principal) (amount uint) (release-condition-hash (buff 32)))
  (let
    (
      (wallet (unwrap! (map-get? robot-wallets tx-sender) err-not-found))
      (payment-id (+ (var-get payment-nonce) u1))
    )
    (asserts! (> amount u0) err-invalid-amount)
    (asserts! (>= (get balance wallet) amount) err-insufficient-balance)
    (map-set robot-wallets tx-sender (merge wallet {
      balance: (- (get balance wallet) amount),
      escrow-locked: (+ (get escrow-locked wallet) amount)
    }))
    (map-set escrow-payments payment-id
      {
        payer: tx-sender,
        payee: payee,
        amount: amount,
        release-condition-hash: release-condition-hash,
        released: false,
        refunded: false
      }
    )
    (var-set payment-nonce payment-id)
    (ok payment-id)
  )
)

(define-public (release-escrow (payment-id uint))
  (let
    (
      (escrow (unwrap! (map-get? escrow-payments payment-id) err-not-found))
      (payer-wallet (unwrap! (map-get? robot-wallets (get payer escrow)) err-not-found))
      (payee-wallet (unwrap! (map-get? robot-wallets (get payee escrow)) err-not-found))
    )
    (asserts! (is-eq tx-sender (get payer escrow)) err-unauthorized)
    (asserts! (not (get released escrow)) err-already-exists)
    (asserts! (not (get refunded escrow)) err-already-exists)
    (map-set robot-wallets (get payee escrow) (merge payee-wallet {
      balance: (+ (get balance payee-wallet) (get amount escrow)),
      total-received: (+ (get total-received payee-wallet) (get amount escrow))
    }))
    (map-set robot-wallets (get payer escrow) (merge payer-wallet {
      escrow-locked: (- (get escrow-locked payer-wallet) (get amount escrow)),
      total-sent: (+ (get total-sent payer-wallet) (get amount escrow))
    }))
    (map-set escrow-payments payment-id (merge escrow {released: true}))
    (ok true)
  )
)

(define-public (refund-escrow (payment-id uint))
  (let
    (
      (escrow (unwrap! (map-get? escrow-payments payment-id) err-not-found))
      (payer-wallet (unwrap! (map-get? robot-wallets (get payer escrow)) err-not-found))
    )
    (asserts! (is-eq tx-sender (get payee escrow)) err-unauthorized)
    (asserts! (not (get released escrow)) err-already-exists)
    (asserts! (not (get refunded escrow)) err-already-exists)
    (map-set robot-wallets (get payer escrow) (merge payer-wallet {
      balance: (+ (get balance payer-wallet) (get amount escrow)),
      escrow-locked: (- (get escrow-locked payer-wallet) (get amount escrow))
    }))
    (map-set escrow-payments payment-id (merge escrow {refunded: true}))
    (ok true)
  )
)

(define-public (withdraw-funds (amount uint))
  (let
    (
      (wallet (unwrap! (map-get? robot-wallets tx-sender) err-not-found))
    )
    (asserts! (> amount u0) err-invalid-amount)
    (asserts! (>= (get balance wallet) amount) err-insufficient-balance)
    (try! (as-contract (stx-transfer? amount tx-sender tx-sender)))
    (map-set robot-wallets tx-sender (merge wallet {
      balance: (- (get balance wallet) amount)
    }))
    (ok true)
  )
)

(define-read-only (get-wallet (owner principal))
  (ok (map-get? robot-wallets owner))
)

(define-read-only (get-payment (payment-id uint))
  (ok (map-get? payments payment-id))
)

(define-read-only (get-escrow-payment (payment-id uint))
  (ok (map-get? escrow-payments payment-id))
)

(define-read-only (get-wallet-payments (owner principal))
  (ok (map-get? wallet-payments owner))
)

Functions (11)

FunctionAccessArgs
initialize-walletpublicrobot-id: uint
deposit-fundspublicamount: uint
send-paymentpublicreceiver: principal, amount: uint, service-type: (string-ascii 40
create-escrow-paymentpublicpayee: principal, amount: uint, release-condition-hash: (buff 32
release-escrowpublicpayment-id: uint
refund-escrowpublicpayment-id: uint
withdraw-fundspublicamount: uint
get-walletread-onlyowner: principal
get-paymentread-onlypayment-id: uint
get-escrow-paymentread-onlypayment-id: uint
get-wallet-paymentsread-onlyowner: principal