# .derupt-interfaces

1. Set your `devPrincipal` in the `src\lib\constants.js`  to a preferred payout address.
2. (re)Build your Derupt,  with your `devPrincipal` set as needed.
3. Navigate to the `/settings`  page in your Derupt instance&#x20;
4. Click the "Activate Origin" button to get ready to `mint` your Derupt Interface NFT
5. Set your preferred payout details, then click the "Mint" button.

{% hint style="info" %}
Updates to payout details can be performed via clicking on "Update Interface"
{% endhint %}

{% hint style="info" %}
Interface NFT Metadata can be altered via `public\metadata.json`
{% endhint %}

{% hint style="warning" %}
**Interface NFT's are origin specific**, thus you will likely want to Mint two of them. \
One from your Preproduction Origin and the other via your Production Origin.
{% endhint %}

{% hint style="warning" %}
You must use the `transfer` function(smart contract call) if you wish to change `dev-principal`, which is currently not facilitated in app, but is technically doable if needed.
{% endhint %}

{% hint style="info" %}
Work in Progress
{% endhint %}

```
;; title: derupt-interfaces
;; version: 1.3.1
;; summary: Interfaces Contract
;; description: used by interface owners to manage their interface service fee(s)

;; derupt-interfaces Contract
(impl-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-009-trait-nft-standard.sip-009-trait)

(define-constant DAPP tx-sender)
(define-constant err-owner-only (err u100))
(define-constant err-not-token-owner (err u101))
(define-constant err-not-found (err u102))
(define-constant err-invalid-value (err u103))
(define-constant err-already-exists (err u104))
(define-constant err-limit-reached (err u105))
(define-constant err-limit-invalid (err u106))
(define-constant err-cant-send-to-self (err u107))

(define-non-fungible-token derupt-interface-token uint)
(define-data-var last-token-id uint u0)

(define-data-var current-supply uint u13)
(define-data-var max-supply uint u1337)
(define-read-only (get-current-supply) 
    (ok (var-get current-supply))
)
(define-read-only (get-max-supply) 
    (ok (var-get max-supply))
)
(define-public (update-current-supply (new-limit uint)) 
    (begin 
        ;; Ensure only the DAPP owner can update the limit
        (asserts! (is-eq tx-sender DAPP) err-owner-only)

        ;; Ensure the new limit is greater than the current-supply 
        (asserts! (> new-limit (var-get current-supply)) err-limit-invalid)

        ;; Ensure the new limit is less than the max-supply
        (asserts! (< new-limit (var-get max-supply)) err-limit-invalid)

        ;; Update the soft limit
        (ok (var-set current-supply new-limit))
    )
)

(define-map costs principal { mint-cost: uint, interface-update-cost: uint })
(define-public (update-interface-costs (mint-cost (optional uint)) (interface-update-cost (optional uint))) 
    (begin 
        (asserts! (is-eq tx-sender DAPP) err-owner-only)
        (asserts! (> (unwrap! mint-cost err-not-found) u0) err-invalid-value)
        (asserts! (> (unwrap! interface-update-cost err-not-found) u0) err-invalid-value)
        (match mint-cost value (map-set costs DAPP 
            { 
                mint-cost: (unwrap! mint-cost err-invalid-value),
                interface-update-cost: (unwrap! (get interface-update-cost (map-get? costs DAPP)) err-not-found)                
            }) false)
        (match interface-update-cost value (map-set costs DAPP 
            { 
                mint-cost: (unwrap! (get mint-cost (map-get? costs DAPP)) err-not-found),
                interface-update-cost: (unwrap! interface-update-cost err-invalid-value)  
            }) false)
        (ok true)
    )
)

;; Interface-badges is a map by nft uint as index
(define-map interface-badges uint {metadata-uri: (string-ascii 256), alt-origin: (string-utf8 256)})
(define-public (update-interface-badge (token-id uint) (new-token-uri (string-ascii 256))) 
    (let 
        (
            (token-id-value-check (asserts! (>= token-id u0) err-invalid-value))
            (new-token-uri-value-check (asserts! (>= (len new-token-uri) u0) err-invalid-value))
            (token-owner (unwrap! (unwrap! (get-owner token-id) err-not-found) err-not-found))
        )
        (asserts! (is-eq tx-sender token-owner) err-not-token-owner)
        (map-set interface-badges token-id 
            {
                metadata-uri: new-token-uri, 
                alt-origin: (unwrap! (get alt-origin (map-get? interface-badges token-id)) err-not-found)
            }
        )
        (ok true)
    )
)
;; Interface is a map by alt-origin as index
(define-map interface (string-utf8 256) 
    { 
        pay-dev: bool, pay-gaia: bool,
        dev-stx-amount: uint, gaia-stx-amount: uint,
        dev-ft-amount: uint, gaia-ft-amount: uint,
        dev-principal: principal, gaia-principal: principal
    }
)
(define-public (update-interface 
    (alt-origin (string-utf8 256))
    (pay-dev bool) 
    (pay-gaia bool) 
    (dev-stx-amount uint) 
    (gaia-stx-amount uint) 
    (dev-ft-amount uint) 
    (gaia-ft-amount uint)
    (dev-principal principal)
    (gaia-principal principal)
) 
    (let 
        (    
            (dev-stx-amount-value-checker (asserts! (>= dev-stx-amount u0) err-invalid-value))
            (dev-ft-amount-value-checker (asserts! (>= dev-ft-amount u0) err-invalid-value))
            (gaia-stx-amount-value-checker (asserts! (>= gaia-stx-amount u0) err-invalid-value))
            (gaia-ft-amount-value-checker (asserts! (>= gaia-ft-amount u0) err-invalid-value))
            (dev-principal-value-checker (asserts! (is-eq dev-principal tx-sender) err-invalid-value))
            (gaia-principal-value-checker (asserts! (not (is-eq gaia-principal tx-sender)) err-invalid-value))

            (alt-origin-dev (unwrap! (get dev-principal (map-get? interface alt-origin)) err-not-found))
        )
        (begin 
            (asserts! (is-eq alt-origin-dev tx-sender) err-owner-only)
            (try! (stx-transfer? (unwrap! (get interface-update-cost (map-get? costs DAPP)) err-not-found) tx-sender DAPP))
            (map-set interface alt-origin 
                { 
                    pay-dev: pay-dev, pay-gaia: pay-gaia,
                    dev-stx-amount: dev-stx-amount, 
                    gaia-stx-amount: gaia-stx-amount,
                    dev-ft-amount: dev-ft-amount, 
                    gaia-ft-amount: gaia-ft-amount,
                    dev-principal: dev-principal, 
                    gaia-principal: gaia-principal                   
                }
            )
            (ok true)   
        )
    )
)

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

(define-read-only (get-token-uri (token-id uint))
    (ok (get metadata-uri (map-get? interface-badges token-id)))
)

(define-read-only (get-token-interface (alt-origin (string-utf8 256))) 
    (ok (map-get? interface alt-origin))
)

(define-read-only (get-owner (token-id uint))
    (ok (nft-get-owner? derupt-interface-token token-id))
)

(define-read-only (get-costs) 
    (ok (unwrap! (map-get? costs DAPP) err-not-found))
)

(define-public (transfer (token-id uint) (sender principal) (recipient principal))
    (let 
        (
            (sender-is-not-receiver (asserts! (not (is-eq recipient tx-sender)) err-cant-send-to-self))
            (alt-origin (unwrap! (get alt-origin (map-get? interface-badges token-id)) err-not-found))
        ) 
        (asserts! (is-eq tx-sender sender) err-not-token-owner)        
        (asserts! (map-set interface alt-origin {
            pay-dev: (unwrap! (get pay-dev (map-get? interface alt-origin)) err-not-found), 
            pay-gaia: (unwrap! (get pay-gaia (map-get? interface alt-origin)) err-not-found),
            dev-stx-amount: (unwrap! (get dev-stx-amount (map-get? interface alt-origin)) err-not-found), 
            gaia-stx-amount: (unwrap! (get gaia-stx-amount (map-get? interface alt-origin)) err-not-found),
            dev-ft-amount: (unwrap! (get dev-ft-amount (map-get? interface alt-origin)) err-not-found), 
            gaia-ft-amount: (unwrap! (get gaia-ft-amount (map-get? interface alt-origin)) err-not-found),
            dev-principal: recipient, 
            gaia-principal: (unwrap! (get gaia-principal (map-get? interface alt-origin)) err-not-found)
        }) err-not-found)    
        (nft-transfer? derupt-interface-token token-id sender recipient)
    )
)

(define-public (mint 
    (alt-origin (string-utf8 256)) (metadata-uri (string-ascii 256))
    (pay-dev bool) (pay-gaia bool) 
    (dev-stx-amount uint) (gaia-stx-amount uint) 
    (dev-ft-amount uint) (gaia-ft-amount uint)
    (dev-principal principal) (gaia-principal principal)
)
    (let
        (
            (dev-stx-amount-value-checker (asserts! (>= dev-stx-amount u0) err-invalid-value))
            (dev-ft-amount-value-checker (asserts! (>= dev-ft-amount u0) err-invalid-value))
            (gaia-stx-amount-value-checker (asserts! (>= gaia-stx-amount u0) err-invalid-value))
            (gaia-ft-amount-value-checker (asserts! (>= gaia-ft-amount u0) err-invalid-value))
            (dev-principal-value-checker (asserts! (is-eq dev-principal tx-sender) err-invalid-value))
            (gaia-principal-value-checker (asserts! (not (is-eq gaia-principal tx-sender)) err-invalid-value))
            
            (token-id (+ (var-get last-token-id) u1))
            (limit (var-get current-supply))
        )       
        (asserts! (>= limit token-id) err-limit-reached)
        (asserts! (> (len alt-origin) u0) err-invalid-value)
        (asserts! (> (len metadata-uri) u0) err-invalid-value)
        (asserts! (is-eq dev-principal tx-sender) err-invalid-value)
        (try! (nft-mint? derupt-interface-token token-id dev-principal))
        (try! (stx-transfer? (unwrap! (get mint-cost (map-get? costs DAPP)) err-not-found) tx-sender DAPP))
        (asserts! (map-insert interface alt-origin 
            { 
                pay-dev: pay-dev, pay-gaia: pay-gaia,
                dev-stx-amount: dev-stx-amount, gaia-stx-amount: gaia-stx-amount,
                dev-ft-amount: dev-ft-amount, gaia-ft-amount: gaia-ft-amount,
                dev-principal: dev-principal, gaia-principal: gaia-principal
            }
        ) err-already-exists)
        (map-insert interface-badges token-id {metadata-uri: metadata-uri, alt-origin: alt-origin})
        (var-set last-token-id token-id)
        (ok token-id)
    )
)

(map-insert costs DAPP {mint-cost: u10000000, interface-update-cost: u1000000})
```
