Source Code

;; title: csw-registry
;; version: v1
;; summary: Registry for clarity smart wallets

(define-trait csw-trait (
  (get-owner
    ()
    (response principal uint)
  )
))

;; token definition
(define-non-fungible-token csw-ownership uint)

;; errors
(define-constant ERR-UNWRAP (err u101))
(define-constant ERR-NOT-AUTHORIZED (err u102))
(define-constant ERR-NOT-LISTED (err u103))
(define-constant ERR-WRONG-COMMISSION (err u104))
(define-constant ERR-LISTED (err u105))
(define-constant ERR-NO-CSW (err u106))
(define-constant ERR-HASH-MALFORMED (err u107))
(define-constant ERR-STX-BURNT-INSUFFICIENT (err u108))
(define-constant ERR-PREORDER-NOT-FOUND (err u109))
(define-constant ERR-CHARSET-INVALID (err u110))
(define-constant ERR-NAMESPACE-ALREADY-EXISTS (err u111))
(define-constant ERR-PREORDER-CLAIMABILITY-EXPIRED (err u112))
(define-constant ERR-NAMESPACE-NOT-FOUND (err u113))
(define-constant ERR-OPERATION-UNAUTHORIZED (err u114))
(define-constant ERR-NAMESPACE-ALREADY-LAUNCHED (err u115))
(define-constant ERR-NAMESPACE-PREORDER-LAUNCHABILITY-EXPIRED (err u116))
(define-constant ERR-NAMESPACE-NOT-LAUNCHED (err u117))
(define-constant ERR-CSW-NOT-AVAILABLE (err u118))
(define-constant ERR-NAMESPACE-BLANK (err u119))
(define-constant ERR-NAME-BLANK (err u120))
(define-constant ERR-NAME-PREORDERED-BEFORE-NAMESPACE-LAUNCH (err u121))
(define-constant ERR-NAMESPACE-HAS-MANAGER (err u122))
(define-constant ERR-OVERFLOW (err u123))
(define-constant ERR-NO-CSWSPACE-MANAGER (err u124))
(define-constant ERR-FAST-MINTED-BEFORE (err u125))
(define-constant ERR-PREORDERED-BEFORE (err u126))
(define-constant ERR-NAME-NOT-CLAIMABLE-YET (err u127))
(define-constant ERR-IMPORTED-BEFORE (err u128))
(define-constant ERR-LIFETIME-EQUAL-0 (err u129))
(define-constant ERR-MIGRATION-IN-PROGRESS (err u130))
(define-constant ERR-NO-PRIMARY-NAME (err u131))
(define-constant ERR-INVALID-CSW-CONTRACT (err u132))

;; Counter to keep track of the last minted NFT ID, ensuring unique identifiers
(define-data-var csw-index uint u0)

;; maps

;; Define a map to link NFT IDs to their respective smart wallet.
(define-map index-to-csw
  uint
  principal
)

;; Define a map to link smart wallet to their respective NFT IDs.
(define-map csw-to-index
  principal
  uint
)

;; It maps a user's principal to the ID of their primary name.
(define-map primary-csw
  principal
  uint
)

;; read-only
(define-read-only (get-last-token-id)
  (ok (var-get csw-index))
)

;; @desc SIP-09 compliant function to get token URI
(define-read-only (get-token-uri (id uint))
  (ok none)
)

(define-read-only (get-contract-uri)
  (ok none)
)

;; @desc SIP-09 compliant function to get the owner of a specific token by its ID
(define-read-only (get-owner (id uint))
  ;; Check and return the owner of the specified NFT
  (ok (nft-get-owner? csw-ownership id))
)

;; @desc get owner function
(define-read-only (get-owner-csw (clarity-smart-wallet <csw-trait>))
  ;; Check and return the owner of the specified NFT
  (ok (nft-get-owner? csw-ownership
    (unwrap! (get-id-from-csw (contract-of clarity-smart-wallet)) ERR-NO-CSW)
  ))
)

;; Defines a read-only function to fetch the unique ID of a BNS name given its name and the namespace it belongs to.
(define-read-only (get-id-from-csw (clarity-smart-wallet principal))
  ;; Attempts to retrieve the ID from the 'csw-to-index' map using the provided name and namespace as the key.
  (map-get? csw-to-index clarity-smart-wallet)
)

;; Defines a read-only function to fetch the BNS name and the namespace given a unique ID.
(define-read-only (get-csw-from-id (id uint))
  ;; Attempts to retrieve the name and namespace from the 'index-to-csw' map using the provided id as the key.
  (map-get? index-to-csw id)
)

;; Fetcher for primary csw
(define-read-only (get-primary-csw (owner principal))
  (map-get? primary-csw owner)
)

;; Fetcher for primary csw returns clarity smart wallet
(define-read-only (get-primary (owner principal))
  (ok (get-csw-from-id (unwrap! (map-get? primary-csw owner) ERR-NO-PRIMARY-NAME)))
)

;; public functions
;; @param id: ID of the NFT being transferred.
;; @param owner: Principal of the current owner of the NFT.
;; @param recipient: Principal of the recipient of the NFT.
(define-public (transfer
    (id uint)
    (owner principal)
    (recipient principal)
  )
  (let (
      ;; Get the csw of the NFT.
      (csw (unwrap! (get-csw-from-id id) ERR-NO-CSW))
      (nft-current-owner (unwrap! (nft-get-owner? csw-ownership id) ERR-NO-CSW))
    )
    ;; Check owner and recipient is not the same
    (asserts! (not (is-eq nft-current-owner recipient))
      ERR-OPERATION-UNAUTHORIZED
    )
    ;; Check contract-caller
    (asserts!
      (or (is-eq tx-sender nft-current-owner) (is-eq contract-caller nft-current-owner))
      ERR-NOT-AUTHORIZED
    )
    ;; Check if in fact the owner is-eq to nft-current-owner
    (asserts! (is-eq owner nft-current-owner) ERR-NOT-AUTHORIZED)
    ;; Update primary csw if needed for owner
    (update-primary-csw-owner id owner)
    ;; Update primary csw if needed for recipient
    (update-primary-csw-recipient id recipient)
    ;; Execute the NFT transfer.
    (try! (nft-transfer? csw-ownership id nft-current-owner recipient))
    (print {
      topic: "transfer-csw",
      owner: recipient,
      csw: csw,
      id: id,
    })
    (ok true)
  )
)

;; @desc Sets the primary csw for the caller to a specific csw they own.
;; @param primary-csw-id: ID of the csw to be set as primary.
(define-public (set-primary-csw (primary-csw-id uint))
  (begin
    ;; Verify the contract-caller is the owner of the csw.
    (asserts!
      (is-eq (unwrap! (nft-get-owner? csw-ownership primary-csw-id) ERR-NO-CSW)
        contract-caller
      )
      ERR-NOT-AUTHORIZED
    )
    ;; Update the contract-caller's primary csw.
    (map-set primary-csw contract-caller primary-csw-id)
    ;; Return true upon successful execution.
    (ok true)
  )
)

;; @desc registration function: (csw-register)
;; @param: clarity-smart-wallet (csw-trait): the clarity smart wallet to be registered.
(define-public (csw-register (clarity-smart-wallet <csw-trait>))
  (let (
      ;; Calculates the ID for the new csw to be minted.
      (id-to-be-minted (+ (var-get csw-index) u1))
      (csw (contract-of clarity-smart-wallet))
      (csw-id (map-get? csw-to-index csw))
      (owner (unwrap! (contract-call? clarity-smart-wallet get-owner) ERR-UNWRAP))
    )
    ;; Ensure the csw is not already registered.
    (asserts! (is-none csw-id) ERR-CSW-NOT-AVAILABLE)
    (asserts! (or (is-eq owner tx-sender) (is-eq owner contract-caller))
      ERR-NOT-AUTHORIZED
    )
    ;; Ensure the wallet contract is a valid smart-wallet-standard contract.
    (asserts!
      (is-eq (contract-hash? (contract-of clarity-smart-wallet))
        (contract-hash? .smart-wallet-standard)
      )
      ERR-INVALID-CSW-CONTRACT
    )
    ;; Update the index
    (var-set csw-index id-to-be-minted)
    (map-set csw-to-index csw id-to-be-minted)
    (map-set index-to-csw id-to-be-minted csw)
    ;; Update primary csw if needed for owner
    (update-primary-csw-recipient id-to-be-minted owner)
    ;; Mints the new csw NFT.
    (try! (nft-mint? csw-ownership id-to-be-minted owner))
    ;; Log the new csw registration
    (print {
      topic: "new-csw",
      owner: owner,
      csw: csw,
      id: id-to-be-minted,
    })
    ;; Signals successful completion.
    (ok id-to-be-minted)
  )
)

;; This function is similar to the 'transfer' function but does not check that the owner is the contract-caller.
;; @param id: the id of the nft being transferred.
;; @param owner: the principal of the current owner of the nft being transferred.
;; @param recipient: the principal of the recipient to whom the nft is being transferred.
(define-public (claim-transfer (clarity-smart-wallet <csw-trait>))
  (let (
      ;; Attempts to retrieve the name and namespace associated with the given NFT ID.
      (id (unwrap! (map-get? csw-to-index (contract-of clarity-smart-wallet))
        ERR-NO-CSW
      ))
      (owner (unwrap! (nft-get-owner? csw-ownership id) ERR-NO-CSW))
      (recipient (unwrap! (contract-call? clarity-smart-wallet get-owner) ERR-UNWRAP))
    )
    (asserts! (or (is-eq recipient tx-sender) (is-eq recipient contract-caller))
      ERR-NOT-AUTHORIZED
    )
    ;; Update primary name if needed for owner
    (update-primary-csw-owner id owner)
    ;; Update primary name if needed for recipient
    (update-primary-csw-recipient id recipient)
    ;; Executes the NFT transfer from the current owner to the recipient.
    (try! (nft-transfer? csw-ownership id owner recipient))
    (print {
      topic: "transfer-csw",
      owner: recipient,
      csw: clarity-smart-wallet,
      id: id,
    })
    (ok true)
  )
)

;; Private function to update the primary name of an address when transfering a name
;; If the id is = to the primary name then it means that a transfer is happening and we should delete it
(define-private (update-primary-csw-owner
    (id uint)
    (owner principal)
  )
  ;; Check if the owner is transferring the primary name
  (if (is-eq (map-get? primary-csw owner) (some id))
    ;; If it is, then delete the primary name map
    (map-delete primary-csw owner)
    ;; If it is not, do nothing, keep the current primary name
    false
  )
)

;; Private function to update the primary name of an address when recieving
(define-private (update-primary-csw-recipient
    (id uint)
    (recipient principal)
  )
  ;; Check if recipient has a primary name
  (match (map-get? primary-csw recipient)
    recipient-primary-csw
    ;; If recipient has a primary name do nothing
    true
    ;; If recipient doesn't have a primary name
    (map-set primary-csw recipient id)
  )
)

Functions (12)

FunctionAccessArgs
get-last-token-idread-only
get-token-uriread-onlyid: uint
get-contract-uriread-only
get-ownerread-onlyid: uint
get-owner-cswread-onlyclarity-smart-wallet: <csw-trait>
get-id-from-cswread-onlyclarity-smart-wallet: principal
get-csw-from-idread-onlyid: uint
get-primary-cswread-onlyowner: principal
get-primaryread-onlyowner: principal
set-primary-cswpublicprimary-csw-id: uint
csw-registerpublicclarity-smart-wallet: <csw-trait>
claim-transferpublicclarity-smart-wallet: <csw-trait>