# Introduction

What is Derupt?

[Derupt](https://derupt.io) is a suite of open source [Smart Contracts](/legacy/contracts-legacy) deployed on the [Stacks](https://stacks.co) blockchain, designed to empower content creators and content consumers and reward users with [CryptoCash](https://stackers.cc) & STX.\
\
Derupt provides creators with a decentralized alternative to present and monetize their content. Creators can now leverage various decentralized and censorship-resistant methods of monetization that align perfectly with the sentiment of their content.

**Derupt Key Features:**

* **Sending Messages:** You Mine CryptoCash as you Chime your Content.
* **Liking Messages:** You Transfer CryptoCash to Authors as you Like their Content.
* **Disliking Messages:** You Stack CryptoCash as you Dislike another Authors Content.
* **Favorable Reply Messages:** You Send a(Reply) Message as you Like their Content.
* **Unfavorable Reply Messages:** You Send a(Reply) Message as you Dislike their Content.

## Be the change:

New Users can use the [Get Started](/user/get-started) guide:

{% content-ref url="/pages/hO31tg3rUWo9tb5P6nxc" %}
[Get Started](/user/get-started)
{% endcontent-ref %}

## Build the change:

Developers looking to integrate can use the Sentiment [API Docs](/latest/api) and or the [Smart Contracts ](/legacy/contracts-legacy)docs:

{% content-ref url="/pages/wtKkbghEp2sNli4ccnDA" %}
[API](/latest/api)
{% endcontent-ref %}

{% content-ref url="/pages/IZYXLTY7QT6iAiH6T4A3" %}
[Contracts](/latest/contracts)
{% endcontent-ref %}


# Get Started

To get started with Derupt, you will need a few things.

**What you Need:**&#x20;

* Stacks Wallet&#x20;
* Tokens (*STX & CryptoCash*)
* BNS Name (.btc)
* Profile Pictures  (Deruptar NFTs & more)&#x20;

<mark style="color:orange;">**Note:**</mark> Users Deploy and Activate their `.derupt-profile` contract as well.  (done in app)

**What do you need them for?**

{% hint style="info" %}
**Stacks Wallet:** \
Used for authentication. \
We recommend that you use [Leather](https://chrome.google.com/webstore/detail/leather/ldinpeekobnhjjdofggfgjlcehhmanlj) for desktop or [Xverse](https://chrome.google.com/webstore/detail/xverse-wallet/idnnbdplmphpflfnlkomgpfbpcgelopg) for mobile. \
*(BACK IT UP AND NEVER SHARE YOUR KEY SEED PHRASE)*
{% endhint %}

{% hint style="info" %}
**STX & CryptoCash Tokens:** \
Used for sending Messages and or Actions.&#x20;
{% endhint %}

{% hint style="info" %}
**BNS Name:** \
Used to discover profile pages via human readable names.\
We recommend that you get a Name from [BTC.US](https://btc.us/)&#x20;
{% endhint %}

{% hint style="info" %}
**Profile Picture options:** \
Owning and Using a Deruptar NFT as your Profile Picture gives you a Diamond badge.\
Owning and Using a Supported NFT as your Profile Picture gives you a Check badge.\
Using a Uploaded PNG as your Profile Picture does not render a badge.\
Using a inherit default Deruptar SVG as your Profile Picture does not render a badge.
{% endhint %}


# Guides

The Derupt user experience guide.

Before you start using [Derupt](https://derupt.io), be sure to review the [Get Started](/user/get-started) documentation.&#x20;

{% hint style="warning" %}
Users are prompted in App to Deploy & Activate their unique .derupt-profile contract before being able to create content or engage with others content. \
\
Note: Deployment and Activation is only required once per user.
{% endhint %}

<details>

<summary><mark style="color:orange;">How to update your profile</mark></summary>

how to coming soon...

#### <mark style="color:orange;">Updating your profile picture</mark>

how to coming soon...

#### <mark style="color:orange;">Updating your profile banner</mark>

how to coming soon...

</details>

<details>

<summary><mark style="color:orange;">How to post your content (How to Chime)</mark></summary>

how to coming soon...

</details>

<details>

<summary><mark style="color:orange;">How to engage with others content</mark> </summary>

Each message should have the following available actions for engagement.

<img src="/files/zlYI4yGFSsvLVPS6blTT" alt="" data-size="original">

#### <mark style="color:orange;">Replying</mark>

how to coming soon...

#### <mark style="color:orange;">Liking</mark>

how to coming soon...

#### <mark style="color:orange;">Disliking</mark>

how to coming soon...

#### <mark style="color:orange;">Gifting</mark>

how to coming soon...

#### <mark style="color:orange;">Sharing</mark>

how to coming soon...

</details>


# Building on Derupt

Derupt developer support documentation.

Derupt is just a set of smart contracts with functions; an agreed upon procedure for messages and message interactions.  To interface with those smart contract functions, you need a client. \
\
As a developer, you can receive payments from the content created and interacted with via your client. See [.derupt-interfaces](/legacy/contracts-legacy/.derupt-interfaces) for details on how to setup and configure your pay out parameters.\
\
As a developer you don't have to think about private keys since its designed to work with Stacks.\
\
Your user's simply sign transactions with their [Leather ](https://chromewebstore.google.com/detail/leather/ldinpeekobnhjjdofggfgjlcehhmanlj?hl=en)(formerly Hiro) or [Xverse](https://chromewebstore.google.com/detail/xverse-wallet/idnnbdplmphpflfnlkomgpfbpcgelopg?hl=en) wallet when interacting with your custom Derupt client.


# Contracts

Explore the documentation for the Derupt Smart Contracts.

{% content-ref url="/pages/LL0tyCjND0jAEHGBdUnE" %}
[Testnet Addresses](/legacy/contracts-legacy/testnet)
{% endcontent-ref %}

{% content-ref url="/pages/fp3uovU0BS3DmYs5V4nd" %}
[Mainnet Addresses (older)](/legacy/contracts-legacy/mainnet-1)
{% endcontent-ref %}

{% content-ref url="/pages/QNi0aEZqnRbyu9bpGDKA" %}
[.derupt-interfaces](/legacy/contracts-legacy/.derupt-interfaces)
{% endcontent-ref %}

{% content-ref url="/pages/EWWHrFNwPHgS1F00Bx3Z" %}
[.derupt-core-trait](/legacy/contracts-legacy/.derupt-core-trait)
{% endcontent-ref %}

{% content-ref url="/pages/xvQAElX5bPz3DEwEvonk" %}
[.derupt-feed](/legacy/contracts-legacy/.derupt-feed)
{% endcontent-ref %}

{% content-ref url="/pages/YFAUQVBc8npXwk0u2E4n" %}
[.derupt-gifts](/legacy/contracts-legacy/.derupt-gifts)
{% endcontent-ref %}

{% content-ref url="/pages/wCRAZNd6LO1iePc3s5NW" %}
[.derupt-miners](/legacy/contracts-legacy/.derupt-miners)
{% endcontent-ref %}

{% content-ref url="/pages/MOYsrzPg5RLqwozqNkQv" %}
[.derupt-stackers](/legacy/contracts-legacy/.derupt-stackers)
{% endcontent-ref %}

{% content-ref url="/pages/lPto0ATKrW9xoQUHooag" %}
[.derupt-sentiment](/legacy/contracts-legacy/.derupt-sentiment)
{% endcontent-ref %}

{% content-ref url="/pages/5vTkr42yP6lMAtl9u8Ku" %}
[.derupt-core-yyyymmdd](/legacy/contracts-legacy/.derupt-core-yyyymmdd)
{% endcontent-ref %}

{% content-ref url="/pages/QAJOJbCb1lbWciIkevN9" %}
[.derupt-profile-trait](/legacy/contracts-legacy/.derupt-profile-trait)
{% endcontent-ref %}

{% content-ref url="/pages/CoEh2otLAJINORJMaK8w" %}
[.derupt-profiles](/legacy/contracts-legacy/.derupt-profiles)
{% endcontent-ref %}

{% content-ref url="/pages/OKIlwBiIKdXqDxaFE8NE" %}
[.derupt-profile](/legacy/contracts-legacy/.derupt-profile)
{% endcontent-ref %}

{% hint style="info" %}
Looking for the Deruptars NFT Contract?\
[Testnet Contract](https://explorer.hiro.so/txid/STVG43BSMRD85XJSRPFJKR2BPMMZNP3XBSCMZC6T.deruptars?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)\
[Mainnet Contract](https://explorer.hiro.so/txid/SP2KAF9RF86PVX3NEE27DFV1CQX0T4WGR41X3S45C.deruptars?chain=mainnet)
{% endhint %}


# Testnet Addresses

Deployed by: ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X

**View Derupt Testnet Contracts on Explorer:**

* .derupt-ext-trait
* .derupt-interfaces
* .derupt-core-trait
* .derupt-feed
* .derupt-gifts
* .derupt-miners
* .derupt-stackers
* .derupt-sentiment
* .derupt-core-20241204
* .derupt-profile-trait
* .derupt-profiles
* .derupt-profile (deployed by user's)
  * example user A
  * example user B
* .derupt-ext-reg
* .derupt-ext (deployed by dev's)
  * example ext A (sample: "Transfer CC Too")&#x20;
  * example ext B

Other sips deployed

* .sip-009-trait-nft-standard
* .sip-010-trait-ft-standard
* .sip-013-trait-sft-standard

[CryptoCash Contracts (testnet)](https://docs.stackers.cc/latest/contracts/testnet)

{% hint style="info" %}
Users Deploy and Activate their .derupt-profile contract in app.
{% endhint %}

{% hint style="info" %}
Developers Deploy .derupt-ext contract(s) and they are Enabled for use by Users in app.
{% endhint %}

{% hint style="info" %}
Additionally you may want to review the Deruptars NFT Contract
{% endhint %}


# Mainnet Addresses

Deployed by: YTBD

**View Derupt Mainnet Contracts on Explorer:**

* .derupt-ext-trait
* .derupt-interfaces
* .derupt-core-trait
* .derupt-feed
* .derupt-gifts
* .derupt-miners
* .derupt-stackers
* .derupt-sentiment
* .derupt-core-yyyymmdd
* .derupt-profile-trait
* .derupt-profiles
* .derupt-profile (deployed by user's)
  * example user A
  * example user B
* .derupt-ext-reg
* .derupt-ext (deployed by dev's)
  * example ext A
  * example ext B

Other sips deployed

* .sip-009-trait-nft-standard
* .sip-010-trait-ft-standard
* .sip-013-trait-sft-standard

{% hint style="info" %}
Users Deploy and Activate their .derupt-profile contract in app.
{% endhint %}

{% hint style="info" %}
Developers Deploy .derupt-ext contract(s) and they are Enabled for use by Users in app.
{% endhint %}

{% hint style="info" %}
Additionally you may want to review the [Deruptars NFT Contract](https://explorer.hiro.so/txid/SP2KAF9RF86PVX3NEE27DFV1CQX0T4WGR41X3S45C.deruptars?chain=mainnet)
{% endhint %}


# .derupt-ext-trait

Developers can extend the functionality of Derupt by creating Extensions for user to use.

### More Details Coming Soon

*(sample extensions coming soon)*

```
;; title: derupt-ext-trait
;; version: 1.3.1
;; summary: Derupt Extension Trait Contract

(use-trait cryptocash-token-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.cryptocash-token-trait.cryptocash-token)
(use-trait cryptocash-core-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.cryptocash-core-trait.cryptocash-core)
(use-trait sip-009-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-009-trait-nft-standard.sip-009-trait)
(use-trait sip-010-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-010-trait-ft-standard.sip-010-trait)
(use-trait sip-013-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-013-trait-sft-standard.sip-013-trait)

(define-trait derupt-ext
    (
        (update-ext-owner
            (principal)
            (response bool uint)
        )

        (update-ext-metadata
            (
                (optional (string-ascii 24))
                (optional (string-ascii 256))
                (optional (string-ascii 256))
            )
            (response bool uint)
        )

        (exec-ext-func 
            (
                (optional (list 10 
                    {
                        stringutf8: (optional (string-utf8 256)), 
                        stringascii: (optional (string-ascii 256)), 
                        uint: (optional uint), 
                        int: (optional int), 
                        principal: (optional principal), 
                        bool: (optional bool),
                        buff: (optional (buff 34)),
                        proxy: (optional (buff 2048)),
                        cryptocash-token-contract: (optional <cryptocash-token-trait>),
                        cryptocash-core-contract: (optional <cryptocash-core-trait>),
                        sip-009-contract: (optional <sip-009-trait>),
                        sip-010-contract: (optional <sip-010-trait>),
                        sip-013-contract: (optional <sip-013-trait>)
                    }
                ))
            )            
            (response bool uint)
        )
    )
)
```

{% hint style="warning" %}
Extension argument `ext` must follow the`.derupt-ext-trait` function schema
{% endhint %}

{% hint style="warning" %}
Extension execution is done per the `exec-ext-func` function, which takes `extras` as an argument.  Extension(s) contract calls are made in the `.derupt-core-yyyymmdd`.&#x20;
{% endhint %}

{% hint style="warning" %}
Users can have only 1 extension enabled, per key function call.  eg..

* can have 1 `ext` allowed in `gift-message`&#x20;
* can have 1 `ext` allowed in `send-message`
* can have 1 `ext` allowed in `like-message`&#x20;
* can have 1 `ext` allowed in `dislike-message`
* can have 1 `ext` allowed in `favorable-reply-message`
* can have 1 `ext` allowed in `unfavorable-reply-message`

(note: users can change the enabled extension over time)
{% endhint %}


# .derupt-interfaces

Derupt Developers use Derupt Interface NFT's to configure their pay out details.

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})
```


# .derupt-core-trait

Each core trait plays a vital role in facilitating interactions between users.

{% hint style="info" %}
**Core Traits**

* `gift-message`: to send Gifts providing the necessary token inputs.
* `send-message`: to send a Message that supports optional arguments.
* `like-message`: to express appreciation for a Message by Liking it.
* `dislike-message`: to express disapproval for a Message by Disliking it.
* `favorable-reply-message`: to send a favorable Reply, supports optional arguments.
* `unfavorable-reply-message`: to send a unfavorable Reply, supports optional arguments.
  {% endhint %}

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

```
;; title: derupt-core-trait
;; version: 1.3.1
;; summary: Derupt Core Trait Contract

(use-trait sip-009-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-009-trait-nft-standard.sip-009-trait)
(use-trait sip-010-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-010-trait-ft-standard.sip-010-trait)
(use-trait sip-013-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-013-trait-sft-standard.sip-013-trait)

(use-trait derupt-ext-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-ext-trait.derupt-ext)

(use-trait cryptocash-token-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.cryptocash-token-trait.cryptocash-token)
(use-trait cryptocash-core-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.cryptocash-core-trait.cryptocash-core)

(define-trait derupt-core-trait 
    (
        (gift-message
            (
                principal 
                principal bool
                <sip-010-trait>
                uint
                (optional (buff 34))
                (optional <derupt-ext-trait>)
                (optional (list 10 
                    {
                        stringutf8: (optional (string-utf8 256)), 
                        stringascii: (optional (string-ascii 256)), 
                        uint: (optional uint), 
                        int: (optional int), 
                        principal: (optional principal), 
                        bool: (optional bool),
                        buff: (optional (buff 34)),
                        proxy: (optional (buff 2048)),
                        cryptocash-token-contract: (optional <cryptocash-token-trait>),
                        cryptocash-core-contract: (optional <cryptocash-core-trait>),
                        sip-009-contract: (optional <sip-009-trait>),
                        sip-010-contract: (optional <sip-010-trait>),
                        sip-013-contract: (optional <sip-013-trait>)
                    }
                ))
            ) (response bool uint)
        )
        (send-message 
            (
                (string-utf8 256) 
                (optional (string-utf8 256))
                (optional (string-utf8 256)) 
                (optional (string-utf8 256))
                (list 200 uint) 
                (string-utf8 256)
                (optional <derupt-ext-trait>)
                (optional (list 10 
                    {
                        stringutf8: (optional (string-utf8 256)), 
                        stringascii: (optional (string-ascii 256)), 
                        uint: (optional uint), 
                        int: (optional int), 
                        principal: (optional principal), 
                        bool: (optional bool),
                        buff: (optional (buff 34)),
                        proxy: (optional (buff 2048)),
                        cryptocash-token-contract: (optional <cryptocash-token-trait>),
                        cryptocash-core-contract: (optional <cryptocash-core-trait>),
                        sip-009-contract: (optional <sip-009-trait>),
                        sip-010-contract: (optional <sip-010-trait>),
                        sip-013-contract: (optional <sip-013-trait>)
                    }
                ))
                bool
                bool
                uint
                uint
                (optional principal)
                (optional principal)
                <cryptocash-core-trait>
            ) (response bool uint)
        )
        (like-message
            (
                principal 
                (string-utf8 256) 
                <cryptocash-token-trait>
                uint
                bool
                bool
                uint
                uint
                (optional principal)
                (optional principal)
                (optional <derupt-ext-trait>)
                (optional (list 10 
                    {
                        stringutf8: (optional (string-utf8 256)), 
                        stringascii: (optional (string-ascii 256)), 
                        uint: (optional uint), 
                        int: (optional int), 
                        principal: (optional principal), 
                        bool: (optional bool),
                        buff: (optional (buff 34)),
                        proxy: (optional (buff 2048)),
                        cryptocash-token-contract: (optional <cryptocash-token-trait>),
                        cryptocash-core-contract: (optional <cryptocash-core-trait>),
                        sip-009-contract: (optional <sip-009-trait>),
                        sip-010-contract: (optional <sip-010-trait>),
                        sip-013-contract: (optional <sip-013-trait>)
                    }
                ))
            ) (response bool uint)
        )
        (dislike-message
            (
                principal 
                (string-utf8 256) 
                <cryptocash-token-trait>
                <cryptocash-core-trait>
                uint
                uint
                bool
                bool
                uint
                uint
                (optional principal)
                (optional principal)
                (optional <derupt-ext-trait>)
                (optional (list 10 
                    {
                        stringutf8: (optional (string-utf8 256)), 
                        stringascii: (optional (string-ascii 256)), 
                        uint: (optional uint), 
                        int: (optional int), 
                        principal: (optional principal), 
                        bool: (optional bool),
                        buff: (optional (buff 34)),
                        proxy: (optional (buff 2048)),
                        cryptocash-token-contract: (optional <cryptocash-token-trait>),
                        cryptocash-core-contract: (optional <cryptocash-core-trait>),
                        sip-009-contract: (optional <sip-009-trait>),
                        sip-010-contract: (optional <sip-010-trait>),
                        sip-013-contract: (optional <sip-013-trait>)
                    }
                ))
            ) (response bool uint)
        )
        (favorable-reply-message
            (
                (string-utf8 256) 
                principal 
                (optional (string-utf8 256))
                (optional (string-utf8 256)) 
                (string-utf8 256)
                (string-utf8 256) 
                (list 200 uint)
                (string-utf8 256)
                (optional <derupt-ext-trait>)
                (optional (list 10 
                    {
                        stringutf8: (optional (string-utf8 256)), 
                        stringascii: (optional (string-ascii 256)), 
                        uint: (optional uint), 
                        int: (optional int), 
                        principal: (optional principal), 
                        bool: (optional bool),
                        buff: (optional (buff 34)),
                        proxy: (optional (buff 2048)),
                        cryptocash-token-contract: (optional <cryptocash-token-trait>),
                        cryptocash-core-contract: (optional <cryptocash-core-trait>),
                        sip-009-contract: (optional <sip-009-trait>),
                        sip-010-contract: (optional <sip-010-trait>),
                        sip-013-contract: (optional <sip-013-trait>)
                    }
                ))
                <cryptocash-token-trait>
                <cryptocash-core-trait>
                uint
                bool
                bool
                uint
                uint
                uint
                uint
                (optional principal)
                (optional principal)
            ) (response bool uint)
        )
        (unfavorable-reply-message 
            (
                (string-utf8 256) 
                principal 
                (optional (string-utf8 256))
                (optional (string-utf8 256)) 
                (string-utf8 256)
                (string-utf8 256) 
                (list 200 uint)
                (string-utf8 256)
                (optional <derupt-ext-trait>)
                (optional (list 10 
                    {
                        stringutf8: (optional (string-utf8 256)), 
                        stringascii: (optional (string-ascii 256)), 
                        uint: (optional uint), 
                        int: (optional int), 
                        principal: (optional principal), 
                        bool: (optional bool),
                        buff: (optional (buff 34)),
                        proxy: (optional (buff 2048)),
                        cryptocash-token-contract: (optional <cryptocash-token-trait>),
                        cryptocash-core-contract: (optional <cryptocash-core-trait>),
                        sip-009-contract: (optional <sip-009-trait>),
                        sip-010-contract: (optional <sip-010-trait>),
                        sip-013-contract: (optional <sip-013-trait>)
                    }
                ))
                <cryptocash-token-trait>
                <cryptocash-core-trait>
                uint
                uint
                bool
                bool
                uint
                uint
                uint
                uint
                (optional principal)
                (optional principal)
            ) (response bool uint)
        )
    )
)
```


# .derupt-feed

All .derupt-profile contract message calls are logged in .derupt-feed

**The following function is only callable by .derupt-core-yyyymmdd:**

* log-send-message

{% hint style="info" %}
**About Messages**: log-send-message is only callable by the current .derupt-core-yyyymmdd contract.  \
*(To prove messages in a transparent order of operations, so that developers have consistent data for presentation across all potential user interfaces)*
{% endhint %}

{% hint style="info" %}
**About Replies:** log-send-message include Reply Messages as inferred by the inclusion of a `reply-to` transaction id argument.\
(The log-send-message function logs send-message calls received from core) \
(The core wraps replies functions as send-message function calls)
{% endhint %}

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

```
;; title: derupt-feed
;; version: 1.3.1
;; summary: Feed Contract
;; description: used to log Feed

(use-trait sip-010-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-010-trait-ft-standard.sip-010-trait)
;; (use-trait sip-010-trait 'MAINNETADDRESS.sip-010-trait-ft-standard.sip-010-trait)

(use-trait derupt-ext-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-ext-trait.derupt-ext)
;; (use-trait derupt-ext-trait 'MAINNETADDRESS.derupt-ext-trait.derupt-ext)

(use-trait cryptocash-token-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.cryptocash-token-trait.cryptocash-token)

(use-trait cryptocash-core-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.cryptocash-core-trait.cryptocash-core)

(define-constant DAPP tx-sender)

;; Error constants
(define-constant ERR-UNAUTHORIZED (err u100))
(define-constant ERR-NOTFOUND (err u101))
(define-constant ERR-MISSINGARG (err u103))
(define-constant ERR-INSUFFICIENT-BALANCE (err u104))
(define-constant ERR-INSUFFICIENT-ARG (err u106))
(define-constant ERR-NEW-BRO-REQUIRED (err u107))
(define-constant ERR-NEW-PARTNER-REQUIRED (err u108))
(define-constant ERR-WRONG-CC-TOKEN-VERSION (err u109))
(define-constant ERR-WRONG-CC-CORE-VERSION (err u110))

;; Contract references
(define-data-var derupt-core-contract principal (as-contract tx-sender))
(define-data-var cc-token-contract principal (as-contract tx-sender))
(define-data-var cc-core-contract principal (as-contract tx-sender))

;; Cost map
(define-map cost principal { chime-stx-cost: (optional uint), chime-ft-cost: (optional uint), like-ft-cost: (optional uint), dislike-ft-cost: (optional uint) })
(define-map crypto-bros (string-ascii 11) principal)
(define-map crypto-partners (string-ascii 11) principal)

;; Setter for costs
(define-public (set-cost (chime-stx-cost (optional uint)) (chime-ft-cost (optional uint)) (like-ft-cost (optional uint)) (dislike-ft-cost (optional uint))) 
  (begin 
    (asserts! (is-eq tx-sender (unwrap! (map-get? crypto-bros "cryptodude") ERR-UNAUTHORIZED)) ERR-UNAUTHORIZED)
      (match chime-stx-cost value (map-set cost DAPP 
        { 
            chime-stx-cost:   (some value), 
            chime-ft-cost:   (unwrap! (get chime-ft-cost (map-get? cost DAPP)) ERR-NOTFOUND),
            like-ft-cost:   (unwrap! (get like-ft-cost (map-get? cost DAPP)) ERR-NOTFOUND),
            dislike-ft-cost:  (unwrap! (get dislike-ft-cost (map-get? cost DAPP)) ERR-NOTFOUND) 
        }) false)
      (match chime-ft-cost value (map-set cost DAPP 
        { 
            chime-stx-cost:   (unwrap! (get chime-stx-cost (map-get? cost DAPP)) ERR-NOTFOUND),
            chime-ft-cost:  (some value), 
            like-ft-cost:   (unwrap! (get like-ft-cost (map-get? cost DAPP)) ERR-NOTFOUND),
            dislike-ft-cost:   (unwrap! (get dislike-ft-cost (map-get? cost DAPP)) ERR-NOTFOUND),
        }) false)
      (match like-ft-cost value (map-set cost DAPP
        { 
            chime-stx-cost:   (unwrap! (get chime-stx-cost (map-get? cost DAPP)) ERR-NOTFOUND),
            chime-ft-cost:   (unwrap! (get chime-ft-cost (map-get? cost DAPP)) ERR-NOTFOUND),  
            like-ft-cost:   (some value), 
            dislike-ft-cost:   (unwrap! (get dislike-ft-cost (map-get? cost DAPP)) ERR-NOTFOUND) 
        }) false)
      (match dislike-ft-cost value (map-set cost DAPP
        {
            chime-stx-cost:   (unwrap! (get chime-stx-cost (map-get? cost DAPP)) ERR-NOTFOUND), 
            chime-ft-cost:   (unwrap! (get chime-ft-cost (map-get? cost DAPP)) ERR-NOTFOUND), 
            like-ft-cost:   (unwrap! (get like-ft-cost (map-get? cost DAPP)) ERR-NOTFOUND), 
            dislike-ft-cost:   (some value) 
        }) false)
      (ok true)
  )
)

;; Get All Costs
(define-read-only (view-cost)
  (ok (map-get? cost DAPP))
)

;; Get Costs Individually
(define-read-only (get-chime-stx-amount)
  (ok (unwrap! (unwrap! (get chime-stx-cost (map-get? cost DAPP)) ERR-NOTFOUND) ERR-NOTFOUND))
)

(define-read-only (get-chime-ft-amount)
  (ok (unwrap! (unwrap! (get chime-ft-cost (map-get? cost DAPP)) ERR-NOTFOUND) ERR-NOTFOUND))
)

(define-read-only (get-like-ft-amount)
  (ok (unwrap! (unwrap! (get like-ft-cost (map-get? cost DAPP)) ERR-NOTFOUND) ERR-NOTFOUND))
)

(define-read-only (get-dislike-ft-amount)
  (ok (unwrap! (unwrap! (get dislike-ft-cost (map-get? cost DAPP)) ERR-NOTFOUND) ERR-NOTFOUND))
)

;; Validates core-contract (Derupt Core)
(define-read-only (validate-core-contract (input-core-contract principal)) 
  (if (is-eq input-core-contract (var-get derupt-core-contract)) 
    (ok true)
    (ok false)
  )
)

;; Setter for Derupt Core contract address (callable by DAPP, eg when a new .derupt-core-yyyymmdd is deployed by DAPP)
(define-public (set-derupt-core-contract (new-core-contract principal))
  (begin
    (asserts! (is-eq tx-sender DAPP) ERR-UNAUTHORIZED) 
    (asserts! (is-eq new-core-contract tx-sender) ERR-UNAUTHORIZED)
    (ok (var-set derupt-core-contract new-core-contract))
  )
)

;; Get .derupt-core-yyyymmdd contract address
(define-read-only (get-derupt-core-contract) 
    (ok (var-get derupt-core-contract))
)

;; Validates cc-token-contract (CryptoCash Token Contract)
(define-read-only (validate-cc-token-contract (input-contract <cryptocash-token-trait>)) 
  (if (is-eq (contract-of input-contract) (var-get cc-token-contract)) 
    (ok true)
    (ok false)
  )
)

;; Setter for CC Token contract address (callable by DAPP, eg if a new .cryptocash-token is ever required to be deployed by DAPP) 
;; To be used only in the event that CryptoCash requires a hard fork
(define-public (set-cc-token-contract (new-cc-token-contract principal))
  (begin
    (asserts! (is-eq tx-sender DAPP) ERR-UNAUTHORIZED) 
    (asserts! (is-eq new-cc-token-contract tx-sender) ERR-UNAUTHORIZED)
    (ok (var-set cc-token-contract new-cc-token-contract))
  )
)

;; Get .cryptocash-token contract address
(define-read-only (get-cc-token-contract) 
    (ok (var-get cc-token-contract))
)

;; Validates cc-core-contract (CryptoCash Core Contract)
(define-read-only (validate-cc-core-contract (input-contract <cryptocash-core-trait>)) 
  (if (is-eq (contract-of input-contract) (var-get cc-core-contract)) 
    (ok true)
    (ok false)
  )
)

;; Setter for CC Core contract address (callable by DAPP, eg if a new .cryptocash-core is ever required to be deployed by DAPP) 
;; To be used only in the event that CryptoCash requires a hard fork
(define-public (set-cc-core-contract (new-cc-core-contract principal))
  (begin
    (asserts! (is-eq tx-sender DAPP) ERR-UNAUTHORIZED) 
    (asserts! (is-eq new-cc-core-contract tx-sender) ERR-UNAUTHORIZED)
    (ok (var-set cc-core-contract new-cc-core-contract))
  )
)

;; Get .cryptocash-core contract address
(define-read-only (get-cc-core-contract) 
    (ok (var-get cc-core-contract))
)

;; Setter for updating crypto-bros
(define-public (update-crypto-bros (bro (string-ascii 11)) (new-bro principal))        
    (begin 
      (asserts! (is-eq (unwrap! (map-get? crypto-bros bro) ERR-UNAUTHORIZED) tx-sender) ERR-UNAUTHORIZED)
      (asserts! (not (is-eq new-bro tx-sender)) ERR-NEW-BRO-REQUIRED)
      (ok (map-set crypto-bros bro new-bro))
    )
)

(define-read-only (view-crypto-bros (bro (string-ascii 11))) 
  (ok (unwrap! (map-get? crypto-bros bro) ERR-NOTFOUND))
)

;; Setter for updating crypto-partners
(define-public (update-crypto-partners (new-partner principal))        
    (begin 
      (asserts! (is-eq tx-sender (unwrap! (map-get? crypto-bros "cryptodude") ERR-UNAUTHORIZED)) ERR-UNAUTHORIZED)
      
      (asserts! (not (is-eq new-partner tx-sender)) ERR-NEW-PARTNER-REQUIRED)
      (ok (map-set crypto-partners "charity" new-partner))
    )
)

(define-read-only (view-crypto-partners (partner (string-ascii 9))) 
  (ok (unwrap! (map-get? crypto-partners partner) ERR-NOTFOUND))
)

;; Log Send Messages
(define-public (log-send-message 
    (content (string-utf8 256)) (attachment-uri (optional (string-utf8 256))) 
    (thumbnail-uri (optional (string-utf8 256))) (reply-to (optional (string-utf8 256))) 
    (mine-amounts (list 200 uint)) (alt-origin (string-utf8 256))
    (ext (optional <derupt-ext-trait>))
    (pay-dev bool) 
    (pay-gaia bool) 
    (dev-stx-total uint) 
    (gaia-stx-total uint)
    (dev-address (optional principal)) 
    (gaia-address (optional principal)) 
  )
    (let 
      (        
        (chime-stx-total (unwrap! (unwrap! (get chime-stx-cost (map-get? cost DAPP)) ERR-MISSINGARG) ERR-MISSINGARG)) 
        (mine-total (fold + mine-amounts u0))
      ) 
      (asserts! (is-eq contract-caller (var-get derupt-core-contract)) ERR-UNAUTHORIZED)
      (print 
        { 
          event: "send-message", content: content, publisher: tx-sender, attachment-uri: attachment-uri, 
          thumbnail-uri: thumbnail-uri, reply-to: reply-to, alt-origin: alt-origin, ext: ext,
          pay-dev: pay-dev, pay-gaia: pay-gaia, dev-address: dev-address, gaia-address: gaia-address,
          dev-stx-total: dev-stx-total, gaia-stx-total: gaia-stx-total, chime-stx-total: chime-stx-total, mine-total: mine-total, mine-amounts: mine-amounts
        }
      )
      (ok true)
    )
)

(define-public (pay-stx 
  (mine-amounts (list 200 uint)) 
  (pay-dev bool) 
  (pay-gaia bool) 
  (dev-stx-amount uint) 
  (gaia-stx-amount uint)
  (dev-address (optional principal)) 
  (gaia-address (optional principal)) 
  (cryptocash-core-contract <cryptocash-core-trait>)
  )
  (let 
    (
      (dev-stx-total dev-stx-amount) 
      (gaia-stx-total gaia-stx-amount) 
      (chime-stx-total (unwrap! (unwrap! (get chime-stx-cost (map-get? cost DAPP)) ERR-MISSINGARG) ERR-MISSINGARG)) 
      (mine-stx-total (fold + mine-amounts u0)) 
      (user-stx-balance (stx-get-balance tx-sender))
    )     
    ;; CryptoCash core version check
    (asserts! (unwrap! (validate-cc-core-contract cryptocash-core-contract) ERR-NOTFOUND) ERR-WRONG-CC-CORE-VERSION)
    
    (if (and pay-dev pay-gaia) 
    ;; Case 1: pay-dev and pay-gaia are both true hence pay all
      (begin 
        (asserts! (> user-stx-balance (+ chime-stx-total dev-stx-total gaia-stx-total mine-stx-total)) ERR-INSUFFICIENT-BALANCE)
        (try! (contract-call? cryptocash-core-contract mine mine-amounts))
        (try! (stx-transfer? (/ chime-stx-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptodude") ERR-UNAUTHORIZED)))
        (try! (stx-transfer? (/ chime-stx-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptosmith") ERR-UNAUTHORIZED)))
        (try! (stx-transfer? (/ chime-stx-total u3) tx-sender (unwrap! (map-get? crypto-partners "charity") ERR-UNAUTHORIZED)))
        (try! (stx-transfer? dev-stx-total tx-sender (unwrap! dev-address ERR-MISSINGARG)))
        (try! (stx-transfer? gaia-stx-total tx-sender (unwrap! gaia-address ERR-MISSINGARG)))
        (ok true)
      )
      (if (or pay-dev pay-gaia)
      ;; Here we use 'or' to switch either if pay-dev or pay-gaia is true
        (if pay-dev 
        ;; Case 2: pay-dev is true while pay-gaia is false hence pay dev + normal
          (begin 
            (asserts! (> user-stx-balance (+ chime-stx-total dev-stx-total mine-stx-total)) ERR-INSUFFICIENT-BALANCE)
            (try! (contract-call? cryptocash-core-contract mine mine-amounts))
            (try! (stx-transfer? (/ chime-stx-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptodude") ERR-UNAUTHORIZED)))
            (try! (stx-transfer? (/ chime-stx-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptosmith") ERR-UNAUTHORIZED)))
            (try! (stx-transfer? (/ chime-stx-total u3) tx-sender (unwrap! (map-get? crypto-partners "charity") ERR-UNAUTHORIZED)))
            (try! (stx-transfer? dev-stx-total tx-sender (unwrap! dev-address ERR-MISSINGARG)))
            (ok true)
          )
          ;; Case 3: pay-gaia is true while pay-dev is false hence pay-gaia + normal
          (begin 
            (asserts! (> user-stx-balance (+ chime-stx-total gaia-stx-total mine-stx-total)) ERR-INSUFFICIENT-BALANCE)
            (try! (contract-call? cryptocash-core-contract mine mine-amounts))
            (try! (stx-transfer? (/ chime-stx-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptodude") ERR-UNAUTHORIZED)))
            (try! (stx-transfer? (/ chime-stx-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptosmith") ERR-UNAUTHORIZED)))
            (try! (stx-transfer? (/ chime-stx-total u3) tx-sender (unwrap! (map-get? crypto-partners "charity") ERR-UNAUTHORIZED)))
            (try! (stx-transfer? gaia-stx-total tx-sender (unwrap! gaia-address ERR-MISSINGARG)))
            (ok true)
          )
        )
        ;; Case 4: pay-dev and pay-gaia are both false hence pay only normal
        (begin 
          (asserts! (> user-stx-balance (+ chime-stx-total mine-stx-total)) ERR-INSUFFICIENT-BALANCE)
          (try! (contract-call? cryptocash-core-contract mine mine-amounts))
          (try! (stx-transfer? (/ chime-stx-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptodude") ERR-UNAUTHORIZED)))
          (try! (stx-transfer? (/ chime-stx-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptosmith") ERR-UNAUTHORIZED)))
          (try! (stx-transfer? (/ chime-stx-total u3) tx-sender (unwrap! (map-get? crypto-partners "charity") ERR-UNAUTHORIZED)))
          (ok true)
        )
      )     
    )
  )
)

(define-public (pay-ft-like
  (author-principal principal)
  (like-ft-amount uint)
  (pay-dev bool) 
  (pay-gaia bool) 
  (dev-ft-amount uint) 
  (gaia-ft-amount uint)
  (dev-address (optional principal)) 
  (gaia-address (optional principal)) 
  (cryptocash-token-contract <cryptocash-token-trait>)
  )
  (let 
    (
      (dev-ft-total dev-ft-amount) 
      (gaia-ft-total gaia-ft-amount) 
      (chime-ft-total (unwrap! (unwrap! (get chime-ft-cost (map-get? cost DAPP)) ERR-MISSINGARG) ERR-MISSINGARG)) 
      (like-ft-total like-ft-amount) 
      (like-ft-minimum (unwrap! (unwrap! (get like-ft-cost (map-get? cost DAPP)) ERR-MISSINGARG) ERR-MISSINGARG)) 
      (user-ft-balance (unwrap! (contract-call? cryptocash-token-contract get-balance tx-sender) ERR-MISSINGARG))
    ) 
    (begin
      ;; CryptoCash token version check
      (asserts! (unwrap! (validate-cc-token-contract cryptocash-token-contract) ERR-NOTFOUND) ERR-WRONG-CC-TOKEN-VERSION)
      (asserts! (>= like-ft-total like-ft-minimum) ERR-INSUFFICIENT-BALANCE)

      (if (and pay-dev pay-gaia) 
      ;; Case 1: pay-dev and pay-gaia are both true hence pay all
        (begin 
          (asserts! (> user-ft-balance (+ chime-ft-total dev-ft-total gaia-ft-total like-ft-total)) ERR-INSUFFICIENT-BALANCE)
          (try! (contract-call? cryptocash-token-contract transfer like-ft-total tx-sender author-principal none ))
          (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptodude") ERR-UNAUTHORIZED) none))
          (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptosmith") ERR-UNAUTHORIZED) none))
          (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-partners "charity") ERR-UNAUTHORIZED) none))
          (try! (contract-call? cryptocash-token-contract transfer dev-ft-total tx-sender (unwrap! dev-address ERR-MISSINGARG) none))
          (try! (contract-call? cryptocash-token-contract transfer gaia-ft-total tx-sender (unwrap! gaia-address ERR-MISSINGARG) none))
          (ok true)
        )
        (if (or pay-dev pay-gaia)
        ;; Here we use 'or' to switch either if pay-dev or pay-gaia is true
          (if pay-dev 
          ;; Case 2: pay-dev is true while pay-gaia is false hence pay dev + normal
            (begin
              (asserts! (> user-ft-balance (+ chime-ft-total dev-ft-total like-ft-total)) ERR-INSUFFICIENT-BALANCE)
              (try! (contract-call? cryptocash-token-contract transfer like-ft-total tx-sender author-principal none))
              (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptodude") ERR-UNAUTHORIZED) none))
              (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptosmith") ERR-UNAUTHORIZED) none))
              (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-partners "charity") ERR-UNAUTHORIZED) none))
              (try! (contract-call? cryptocash-token-contract transfer dev-ft-total tx-sender (unwrap! dev-address ERR-MISSINGARG) none))
              (ok true)
            )
            ;; Case 3: pay-gaia is true while pay-dev is false hence pay-gaia + normal
            (begin 
              (asserts! (> user-ft-balance (+ chime-ft-total gaia-ft-total like-ft-total)) ERR-INSUFFICIENT-BALANCE)
              (try! (contract-call? cryptocash-token-contract transfer like-ft-total tx-sender author-principal none))
              (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptodude") ERR-UNAUTHORIZED) none))
              (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptosmith") ERR-UNAUTHORIZED) none))
              (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-partners "charity") ERR-UNAUTHORIZED) none))
              (try! (contract-call? cryptocash-token-contract transfer gaia-ft-total tx-sender (unwrap! gaia-address ERR-MISSINGARG) none))
              (ok true)
            )
          )
          ;; Case 4: pay-dev and pay-gaia are both false hence pay only normal
          (begin 
            (asserts! (> user-ft-balance (+ chime-ft-total like-ft-total)) ERR-INSUFFICIENT-BALANCE)
            (try! (contract-call? cryptocash-token-contract transfer like-ft-total tx-sender author-principal none))
            (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptodude") ERR-UNAUTHORIZED) none))
            (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptosmith") ERR-UNAUTHORIZED) none))
            (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-partners "charity") ERR-UNAUTHORIZED) none))
            (ok true)
          )
        )     
      )    
    )    
  )
)

(define-public (pay-ft-dislike
  (dislike-ft-amount uint)
  (lockPeriod uint)
  (pay-dev bool) 
  (pay-gaia bool) 
  (dev-ft-amount uint) 
  (gaia-ft-amount uint)
  (dev-address (optional principal)) 
  (gaia-address (optional principal)) 
  (cryptocash-token-contract <cryptocash-token-trait>)
  (cryptocash-core-contract <cryptocash-core-trait>)
  )
  (let 
    (
      (dev-ft-total dev-ft-amount) 
      (gaia-ft-total gaia-ft-amount) 
      (chime-ft-total (unwrap! (unwrap! (get chime-ft-cost (map-get? cost DAPP)) ERR-MISSINGARG) ERR-MISSINGARG)) 
      (dislike-ft-total dislike-ft-amount) 
      (dislike-ft-minimum (unwrap! (unwrap! (get dislike-ft-cost (map-get? cost DAPP)) ERR-MISSINGARG) ERR-MISSINGARG)) 
      (user-ft-balance (unwrap! (contract-call? cryptocash-token-contract get-balance tx-sender) ERR-MISSINGARG))
    ) 
    (begin
      ;; CryptoCash Token and Core version checks
      (asserts! (unwrap! (validate-cc-token-contract cryptocash-token-contract) ERR-NOTFOUND) ERR-WRONG-CC-TOKEN-VERSION)
      (asserts! (unwrap! (validate-cc-core-contract cryptocash-core-contract) ERR-NOTFOUND) ERR-WRONG-CC-CORE-VERSION)

      (asserts! (> lockPeriod u0) ERR-INSUFFICIENT-ARG)
      (asserts! (>= dislike-ft-total dislike-ft-minimum) ERR-INSUFFICIENT-ARG) 
      (if (and pay-dev pay-gaia) 
      ;; Case 1: pay-dev and pay-gaia are both true hence pay all
        (begin          
          (asserts! (> user-ft-balance (+ chime-ft-total dev-ft-total gaia-ft-total dislike-ft-total)) ERR-INSUFFICIENT-BALANCE)
          (try! (contract-call? cryptocash-core-contract stack dislike-ft-total lockPeriod))
          (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptodude") ERR-UNAUTHORIZED) none))
          (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptosmith") ERR-UNAUTHORIZED) none))
          (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-partners "charity") ERR-UNAUTHORIZED) none))
          (try! (contract-call? cryptocash-token-contract transfer dev-ft-total tx-sender (unwrap! dev-address ERR-MISSINGARG) none))
          (try! (contract-call? cryptocash-token-contract transfer gaia-ft-total tx-sender (unwrap! gaia-address ERR-MISSINGARG) none))
          (ok true)
        )
        (if (or pay-dev pay-gaia)
        ;; Here we use 'or' to switch either if pay-dev or pay-gaia is true
          (if pay-dev 
          ;; Case 2: pay-dev is true while pay-gaia is false hence pay dev + normal
            (begin 
              (asserts! (> user-ft-balance (+ chime-ft-total dev-ft-total dislike-ft-total)) ERR-INSUFFICIENT-BALANCE)
              (try! (contract-call? cryptocash-core-contract stack dislike-ft-total lockPeriod))
              (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptodude") ERR-UNAUTHORIZED) none))
              (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptosmith") ERR-UNAUTHORIZED) none))
              (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-partners "charity") ERR-UNAUTHORIZED) none))
              (try! (contract-call? cryptocash-token-contract transfer dev-ft-total tx-sender (unwrap! dev-address ERR-MISSINGARG) none))
              (ok true)
            )
            ;; Case 3: pay-gaia is true while pay-dev is false hence pay-gaia + normal
            (begin
              (asserts! (> user-ft-balance (+ chime-ft-total gaia-ft-total dislike-ft-total)) ERR-INSUFFICIENT-BALANCE)
              (try! (contract-call? cryptocash-core-contract stack dislike-ft-total lockPeriod))
              (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptodude") ERR-UNAUTHORIZED) none))
              (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptosmith") ERR-UNAUTHORIZED) none))
              (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-partners "charity") ERR-UNAUTHORIZED) none))
              (try! (contract-call? cryptocash-token-contract transfer gaia-ft-total tx-sender (unwrap! gaia-address ERR-MISSINGARG) none))
              (ok true)
            )
          )
          ;; Case 4: pay-dev and pay-gaia are both false hence pay only normal
          (begin
            (asserts! (> user-ft-balance (+ chime-ft-total dislike-ft-total)) ERR-INSUFFICIENT-BALANCE)
            (try! (contract-call? cryptocash-core-contract stack dislike-ft-total lockPeriod))
            (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptodude") ERR-UNAUTHORIZED) none))
            (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-bros "cryptosmith") ERR-UNAUTHORIZED) none))
            (try! (contract-call? cryptocash-token-contract transfer (/ chime-ft-total u3) tx-sender (unwrap! (map-get? crypto-partners "charity") ERR-UNAUTHORIZED) none))
            (ok true)
          )
        )     
      )
    )
    
  )
)

;; Default cost map insertion
(map-insert cost DAPP { chime-stx-cost:  (some u100000), chime-ft-cost:  (some u10), like-ft-cost:  (some u100), dislike-ft-cost:  (some u100) })

;; Mapp insertion for crypto-bros principals
;; (map-insert crypto-bros "cryptodude" 'SP3ABD2FW64Y75W22R4G9TVKF6EA79RZHRC5BG4HD)
;; (map-insert crypto-bros "cryptosmith" 'SP2E9NTWSFGEN393GHT0CC4K7QCEX2CGYK0G2TY2F)
(map-insert crypto-bros "cryptodude" 'ST3WAR3N1XRR139DXCGPR1ATPK2VN63PGRYJTFK5N)
(map-insert crypto-bros "cryptosmith" 'ST30RNTQNY63F6XR66J2Q3WP1THZT3VHZGYEXA9XX)


;; Map insertion for crypto partners
;; replace periodically with a variable charity principal that we partner with for a temparory period of time. Rotating in new charities
;; (map-insert crypto-partners "charity" 'SP16DCVM40B7DDPZQ6R9XZ8FXSH52246GP1C4FJPP)
(map-insert crypto-partners "charity" 'STSM74KAMAH949MDDYAAZZ8V2W9YAS07F8WCD7K6)
```


# .derupt-gifts

All .derupt-profile contract gifting are logged in .derupt-gifts

**The following function calls are only callable by .derupt-core-yyyymmdd:**

* log-gift

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

```
;; title: derupt-gifts
;; version: 1.3.1
;; summary: Gifts Contract
;; description: used to log Gifts

(use-trait sip-010-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-010-trait-ft-standard.sip-010-trait)
;; (use-trait sip-010-trait 'MAINNETADDRESS.sip-010-trait-ft-standard.sip-010-trait)

(use-trait derupt-ext-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-ext-trait.derupt-ext)
;; (use-trait derupt-ext-trait 'MAINNETADDRESS.derupt-ext-trait.derupt-ext)

;; Error Constants
(define-constant ERR-UNAUTHORIZED (err u100))
(define-constant ERR-NOTFOUND (err u101))

;; Get Derupt core contract
(define-read-only (get-derupt-core-contract)
  (contract-call? .derupt-feed get-derupt-core-contract)
)

;; Log Gift
(define-public (log-gift (sender principal) 
  (recipient principal) (is-stx bool) 
  (contractId <sip-010-trait>) (amount uint) (memo (optional (buff 34))) (ext (optional <derupt-ext-trait>))
)
  (let 
    ((derupt-core-contract (unwrap! (get-derupt-core-contract) ERR-NOTFOUND))) 
    (asserts! (is-eq contract-caller derupt-core-contract) ERR-UNAUTHORIZED)
    (print { event: "gift", sender: sender, recipient: recipient, is-stx: is-stx, contractId: contractId, amount: amount, memo: memo, ext: ext})
    (ok true)
  )
)
```


# .derupt-miners

All .derupt-profile contract mining actions are logged in .derupt-miners

**The following function calls are only callable by .derupt-core-yyyymmdd:**

* log-mine
* log-mining-claim-reward

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

```
;; title: derupt-miners
;; version: 1.3.1
;; summary: Miners Contract
;; description: used to log mining and mining reward claims

(define-constant ERR-UNAUTHORIZED (err u100))
(define-constant ERR-NOTFOUND (err u101))

;; Get Derupt core contract
(define-read-only (get-derupt-core-contract)
  (contract-call? .derupt-feed get-derupt-core-contract)
)

;; Log Mine
(define-public (log-mine (miner principal) (mine-amounts (list 200 uint)))
  (let 
    ((derupt-core-contract (unwrap! (get-derupt-core-contract) ERR-NOTFOUND))) 
    (asserts! (is-eq contract-caller derupt-core-contract) ERR-UNAUTHORIZED)
    (print { event: "mine", miner: miner, mine-total: (fold + mine-amounts u0), mine-amounts: mine-amounts })
    (ok true)
  )
)

;; Log Mining Reward Claim
(define-public (log-mining-reward-claim (claimHeights (list 200 uint)))
  (let 
    ((derupt-core-contract (unwrap! (get-derupt-core-contract) ERR-NOTFOUND))) 
    (asserts! (is-eq contract-caller derupt-core-contract) ERR-UNAUTHORIZED)
    (print { event: "mining-reward-claim", miner: tx-sender, claimHeights: claimHeights })
    (ok true)
  )
)
```


# .derupt-stackers

All .derupt-profile contract stacking actions are logged in .derupt-stackers

**The following function calls are only callable by .derupt-core-yyyymmdd:**

* log-stack
* log-stacking-claim-reward

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

```
;; title: derupt-stackers
;; version: 1.3.1
;; summary: Stackers Contract
;; description: used to log stacking and stacking reward claims

(define-constant ERR-UNAUTHORIZED (err u100))
(define-constant ERR-NOTFOUND (err u101))

;; Get Derupt core contract
(define-read-only (get-derupt-core-contract)
  (contract-call? .derupt-feed get-derupt-core-contract)
)

;; Log Stack
(define-public (log-stack (stacker principal) (dislike-ft-total uint) (lockPeriod uint))
  (let
    ((derupt-core-contract (unwrap! (get-derupt-core-contract) ERR-NOTFOUND))) 
    (asserts! (is-eq contract-caller derupt-core-contract) ERR-UNAUTHORIZED)
    (print { event: "stack", stacker: stacker, dislike-ft-total: dislike-ft-total, lockPeriod: lockPeriod })
    (ok true)
  )
)

;; Log Stacking Reward Claim
(define-public (log-stacking-reward-claim (targetCycles (list 32 uint)))
  (let 
    ((derupt-core-contract (unwrap! (get-derupt-core-contract) ERR-NOTFOUND))) 
    (asserts! (is-eq contract-caller derupt-core-contract) ERR-UNAUTHORIZED)
    (print { event: "stacking-reward-claim", stacker: tx-sender, targetCycles: targetCycles })
    (ok true)
  )
)
```


# .derupt-sentiment

All .derupt-profile contract sentiments are logged in .derupt-sentiments

**The following function calls are only callable by .derupt-core-yyyymmdd:**

* log-like-message
* log-dislike-message

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

```
;; title: derupt-sentiment
;; version: 1.3.1
;; summary: Sentiment Contract
;; description: used to log sentiment

(use-trait sip-010-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-010-trait-ft-standard.sip-010-trait)
;; (use-trait sip-010-trait 'MAINNETADDRESS.sip-010-trait-ft-standard.sip-010-trait)

(use-trait derupt-ext-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-ext-trait.derupt-ext)
;; (use-trait derupt-ext-trait 'MAINNETADDRESS.derupt-ext-trait.derupt-ext)

(define-constant ERR-UNAUTHORIZED (err u100))
(define-constant ERR-NOTFOUND (err u101))

;; Get Derupt core contract
(define-read-only (get-derupt-core-contract)  
  (contract-call? .derupt-feed get-derupt-core-contract)
)

;; Log Like Message
(define-public (log-like-message 
  (liker principal)
  (author-principal principal) (like-ft-total uint) (liked-txid (string-utf8 256)) 
  (contractId <sip-010-trait>)
  (pay-dev bool) 
  (pay-gaia bool) 
  (dev-ft-total uint) 
  (gaia-ft-total uint)
  (dev-principal (optional principal)) 
  (gaia-principal (optional principal))
  (ext (optional <derupt-ext-trait>))
)
  (let 
    (
      (derupt-core-contract (unwrap! (get-derupt-core-contract) ERR-NOTFOUND))
    ) 
    (asserts! (is-eq contract-caller derupt-core-contract) ERR-UNAUTHORIZED)
    (print 
      {
        event: "like-message", liker: liker, author-principal: author-principal,  like-ft-total: like-ft-total, liked-txid: liked-txid,
        contractId: contractId,
        pay-dev: pay-dev, pay-gaia: pay-gaia, dev-principal: dev-principal, gaia-principal: gaia-principal, dev-ft-total: dev-ft-total, gaia-ft-total: gaia-ft-total,
        ext: ext
      }
    )
    (ok true)
  )
)

;; Log Dislike Message
(define-public (log-dislike-message 
  (disliker principal)
  (author-principal principal) 
  (dislike-ft-total uint) 
  (lockPeriod uint)
  (disliked-txid (string-utf8 256)) 
  (contractId <sip-010-trait>)
  (pay-dev bool) 
  (pay-gaia bool) 
  (dev-ft-total uint) 
  (gaia-ft-total uint)
  (dev-principal (optional principal)) 
  (gaia-principal (optional principal))
  (ext (optional <derupt-ext-trait>))
)
  (let 
    (
      (derupt-core-contract (unwrap! (get-derupt-core-contract) ERR-NOTFOUND))
    ) 
    (asserts! (is-eq contract-caller derupt-core-contract) ERR-UNAUTHORIZED)
    (print 
      {
        event: "dislike-message", disliker: disliker, author-principal: author-principal, dislike-ft-total: dislike-ft-total, disliked-txid: disliked-txid,
        contractId: contractId,
        pay-dev: pay-dev, pay-gaia: pay-gaia, dev-principal: dev-principal, gaia-principal: gaia-principal, dev-ft-total: dev-ft-total, gaia-ft-total: gaia-ft-total,
        ext: ext
      }
    )
    (ok true)
  )
)
```


# .derupt-core-yyyymmdd

Users call their own .derupt-profile which then calls .derupt-core-yyyymmdd

{% hint style="info" %}
The core maybe require or receive upgrades/updates from time to time, for that we follow a simple date based naming convention to track versions. &#x20;
{% endhint %}

{% hint style="info" %}
**General:**

* **.derupt-core-yyyymmdd** contract is for handling public message & action logic.&#x20;
* **.derupt-core-yyyymmdd** contract receives calls from **.derupt-profile** contracts and proceeds to process them accordingly.
  {% endhint %}

{% hint style="warning" %}
**Warning:**

* **users should deploy a** `.derupt-profile`contract in app before using core features.
* **users should call**`.derupt-profile`
* **users should not call**`.derupt-core-yyyymmdd` *(nor logging contracts)*
* **users should only** enable 1 extension per 1 key function at a time (eg up to 6 active extensions at a time)&#x20;
  {% endhint %}

{% hint style="info" %}
**Key Functions Process Transactions Overview:**

What happens in a process depends on the function the user is calling.&#x20;

* **gift-message:** `transfer` of a variable sip-010 token is called during this process.
* **send-message**: `mine` cryptocash is called during this process.&#x20;
* **like-message**: `transfer` cryptocash is called during this process.
* **dislike-message**: `stack` cryptocash is called during this process.
* **favorable-reply-message**: `mine` & `transfer` cryptocash is called during this process.
* **unfavorable-reply-message**: `mine` & `stack` cryptocash is called during this process.&#x20;
  {% endhint %}

The 6 key functions and arguments in the `.derupt-core-yyyymmdd` contract:

<details>

<summary><mark style="color:orange;">gift-message</mark></summary>

<mark style="color:orange;">Broadcast Send Message to the Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\)`.derupt-profile`\
2\)`.derupt-core-yyyymmdd (&.derupt-ext if defined)` \
3\)`.derupt-gifts`

**Arguments:**

* ...

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>

<details>

<summary><mark style="color:orange;">send-message</mark> </summary>

<mark style="color:orange;">Broadcast Send Message to the Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\)`.derupt-profile`\
2\)`.derupt-core-yyyymmdd (&.derupt-ext if defined)` \
3\)`.derupt-feed (&.derupt-miners)`

**Arguments:**

* ...

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>

<details>

<summary><mark style="color:orange;">like-message</mark></summary>

<mark style="color:orange;">Broadcast Like Message to Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\) `.derupt-profile`\
2\) `.derupt-core-yyyymmdd (&.derupt-ext if defined)` \
3\) `.derupt-sentiment`

**Arguments:**

* ...

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>

<details>

<summary><mark style="color:orange;">dislike-message</mark></summary>

<mark style="color:orange;">Broadcast Dislike Message to Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\) `.derupt-profile`\
2\) `.derupt-core-yyyymmdd (&.derupt-ext if defined)` \
3\) `.derupt-sentiment (&.derupt-stackers)`

**Arguments:**

* ...

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>

<details>

<summary><mark style="color:orange;">favorable-reply-message</mark></summary>

<mark style="color:orange;">Broadcast Favorable Reply Message to Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\) `.derupt-profile`\
2\) `.derupt-core-yyyymmdd (&.derupt-ext if defined)` \
3\) `.derupt-feed (&.derupt-sentiment &.derupt-miners)`

**Arguments:**

* ...

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>

<details>

<summary><mark style="color:orange;">unfavorable-reply-message</mark></summary>

<mark style="color:orange;">Broadcast Unfavorable Reply Message to Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\) `.derupt-profile`\
2\) `.derupt-core-yyyymmdd (&.derupt-ext if defined)` \
3\) `.derupt-feed (&.derupt-sentiment &.derupt-miners &.derupt-stackers)`

**Arguments:**

* ...

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>

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

```
;; title: derupt-core-20241204
;; version: 1.3.1
;; summary: Gifts Contract
;; description: used to handle core Derupt logic

(impl-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-core-trait.derupt-core-trait)

(use-trait derupt-ext-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-ext-trait.derupt-ext)

(use-trait sip-009-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-009-trait-nft-standard.sip-009-trait)
(use-trait sip-010-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-010-trait-ft-standard.sip-010-trait)
(use-trait sip-013-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-013-trait-sft-standard.sip-013-trait)

(use-trait cryptocash-token-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.cryptocash-token-trait.cryptocash-token)
(use-trait cryptocash-core-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.cryptocash-core-trait.cryptocash-core)

;; Error
(define-constant ERR-UNAUTHORIZED (err u100))
(define-constant ERR-NOTFOUND (err u101))
(define-constant ERR-SELF-GIFT (err u102))
(define-constant ERR-INSUFFICIENT-BALANCE (err u103))
(define-constant ERR-SENDER-MISMATCH (err u104))
(define-constant ERR-INVALID-MEMO (err u105))
(define-constant ERR-CONTENT-REQUIRED (err u106))
(define-constant ERR-WITH-ATTACHMENT (err u107))
(define-constant ERR-WITH-THUMBNAIL (err u108))
(define-constant ERR-WITH-REPLYTO (err u109))
(define-constant ERR-ALT-ORIGIN-REQUIRED (err u110))
(define-constant ERR-WITH-MINE-AMOUNT (err u111))
(define-constant ERR-INVALID-VALUE (err u112))
(define-constant ERR-INVALID-DEV-ADDRESS (err u113))
(define-constant ERR-INVALID-GAIA-ADDRESS (err u114))
(define-constant ERR-LIKED-TXID-REQUIRED (err u115))
(define-constant ERR-INVALID-CC-TOKEN (err u116))
(define-constant ERR-SELF-LIKE (err u117))
(define-constant ERR-INVALID-LIKE-AMOUNT (err u118))
(define-constant ERR-DISLIKED-TXID-REQUIRED (err u119))
(define-constant ERR-SELF-DISLIKE (err u120))
(define-constant ERR-INVALID-CC-CORE (err u121))
(define-constant ERR-INVALID-DISLIKE-AMOUNT (err u122))
(define-constant ERR-INVALID-LOCK-PERIOD (err u123))
(define-constant ERR-INVALID-EXTRA (err u124))

;; Constant Equals Versioning via Contract Naming Convention
(define-constant derupt-core-yyyymmdd (as-contract tx-sender))

;; Get Costs
(define-read-only (get-chime-stx-amount)  
  (contract-call? .derupt-feed get-chime-stx-amount)
)

(define-read-only (get-chime-ft-amount)  
  (contract-call? .derupt-feed get-chime-ft-amount)
)

(define-read-only (get-cc-token-contract)
  (contract-call? .derupt-feed get-cc-token-contract)
)

(define-read-only (get-cc-core-contract)
  (contract-call? .derupt-feed get-cc-core-contract)
)

;; Log Stacking
(define-private (log-stack (stacker principal) (dislike-ft-total uint) (lockPeriod uint)) 
  (contract-call? .derupt-stackers log-stack tx-sender dislike-ft-total lockPeriod)
)

;; Log Mining
(define-private (log-mine (miner principal) (mine-amounts (list 200 uint))) 
  (contract-call? .derupt-miners log-mine tx-sender mine-amounts)
)

;; Log Gifting
(define-private (log-gift 
  (sender principal) 
  (recipient principal) 
  (is-stx bool) 
  (contractId <sip-010-trait>) 
  (amount uint) 
  (memo (optional (buff 34)))
  (ext (optional <derupt-ext-trait>))
) 
  (contract-call? .derupt-gifts log-gift sender recipient is-stx contractId amount memo ext)
)

;; Log Send Message
(define-private (log-send-message 
  (content (string-utf8 256)) 
  (attachment-uri (optional (string-utf8 256))) 
  (thumbnail-uri (optional (string-utf8 256))) 
  (reply-to (optional (string-utf8 256))) 
  (mine-amounts (list 200 uint)) 
  (alt-origin (string-utf8 256))
  (ext (optional <derupt-ext-trait>))
  (pay-dev bool) 
  (pay-gaia bool) 
  (dev-stx-amount uint) 
  (gaia-stx-amount uint)
  (dev-principal (optional principal)) 
  (gaia-principal (optional principal))
) 
  (contract-call? .derupt-feed log-send-message content attachment-uri thumbnail-uri reply-to mine-amounts alt-origin ext pay-dev pay-gaia dev-stx-amount gaia-stx-amount dev-principal gaia-principal)
)

;; Log Like Message
(define-private (log-like-message 
  (author-principal principal) 
  (like-ft-total uint) 
  (liked-txid (string-utf8 256)) 
  (contractId <sip-010-trait>)
  (pay-dev bool)
  (pay-gaia bool) 
  (dev-ft-total uint) 
  (gaia-ft-total uint)
  (dev-principal (optional principal)) 
  (gaia-principal (optional principal))
  (ext (optional <derupt-ext-trait>))
) 
  (contract-call? .derupt-sentiment log-like-message tx-sender author-principal like-ft-total liked-txid contractId pay-dev pay-gaia dev-ft-total gaia-ft-total dev-principal gaia-principal ext)
)

;; Log Dislike Message
(define-private (log-dislike-message 
  (author-principal principal) 
  (dislike-ft-total uint) 
  (lock-period uint) 
  (disliked-txid (string-utf8 256)) 
  (contractId <sip-010-trait>)
  (pay-dev bool) 
  (pay-gaia bool) 
  (dev-ft-total uint) 
  (gaia-ft-total uint)
  (dev-principal (optional principal)) 
  (gaia-principal (optional principal))
  (ext (optional <derupt-ext-trait>))
) 
  (contract-call? .derupt-sentiment log-dislike-message tx-sender author-principal dislike-ft-total lock-period disliked-txid contractId pay-dev pay-gaia dev-ft-total gaia-ft-total dev-principal gaia-principal ext)
)

;; Mine Reward Claim
(define-private (claim-mining-reward (minerBlockHeight uint)) 
  (contract-call? .cryptocash-core claim-mining-reward minerBlockHeight)
)
(define-public (claim-mining-reward-list (claimHeights (list 200 uint))) 
  (begin 
    (map claim-mining-reward claimHeights)
    (try! (contract-call? .derupt-miners log-mining-reward-claim claimHeights))
    (ok true)
  )
)

;; Stack Reward Claim
(define-private (claim-stacking-reward (targetCycle uint)) 
  (contract-call? .cryptocash-core claim-stacking-reward targetCycle)
)
(define-public (claim-stacking-reward-list (targetCycles (list 32 uint))) 
  (begin 
    (map claim-stacking-reward targetCycles)
    (try! (contract-call? .derupt-stackers log-stacking-reward-claim targetCycles))
    (ok true)
  )
)

;; Extras validate function
(define-private (validate-extra (extra {
    stringutf8: (optional (string-utf8 256)), 
    stringascii: (optional (string-ascii 256)), 
    uint: (optional uint), 
    int: (optional int), 
    principal: (optional principal), 
    bool: (optional bool),
    buff: (optional (buff 34)),
    proxy: (optional (buff 2048)),
    cryptocash-token-contract: (optional <cryptocash-token-trait>),
    cryptocash-core-contract: (optional <cryptocash-core-trait>),
    sip-009-contract: (optional <sip-009-trait>),
    sip-010-contract: (optional <sip-010-trait>),
    sip-013-contract: (optional <sip-013-trait>)
  })
  (res (response bool uint))
  )
  (begin   
    ;; Validate `cryptocash-token-contract` if present
     (if (is-some (get cryptocash-token-contract extra))
      (let ((provided-token-contract (unwrap! (get cryptocash-token-contract extra) ERR-NOTFOUND)))
        (asserts! 
          (is-eq (contract-of provided-token-contract) (unwrap! (get-cc-token-contract) ERR-NOTFOUND)) 
          ERR-INVALID-CC-TOKEN
        )
      )
      false ;; Skip validation if none
    )


    ;; Validate `cryptocash-core-contract` if present
    (if (is-some (get cryptocash-core-contract extra))
      (let ((provided-core-contract (unwrap! (get cryptocash-core-contract extra) ERR-NOTFOUND)))
        (asserts! 
          (is-eq (contract-of provided-core-contract) (unwrap! (get-cc-core-contract) ERR-NOTFOUND)) 
          ERR-INVALID-CC-CORE
        )
      )
      false ;; Skip validation if none
    )
    res
  )
)

;; Core Operation Gift Message - updated
(define-public (gift-message (sender principal) 
    (recipient principal) (is-stx bool) 
    (contractId <sip-010-trait>) (amount uint)
    (memo (optional (buff 34)))
    (ext (optional <derupt-ext-trait>))
    (extras (optional (list 10 
      {
        stringutf8: (optional (string-utf8 256)), 
        stringascii: (optional (string-ascii 256)), 
        uint: (optional uint), 
        int: (optional int), 
        principal: (optional principal), 
        bool: (optional bool),
        buff: (optional (buff 34)),
        proxy: (optional (buff 2048)),
        cryptocash-token-contract: (optional <cryptocash-token-trait>),
        cryptocash-core-contract: (optional <cryptocash-core-trait>),
        sip-009-contract: (optional <sip-009-trait>),
        sip-010-contract: (optional <sip-010-trait>),
        sip-013-contract: (optional <sip-013-trait>)
      }))
    )    
  ) 
  (begin    

    ;; Validate EXTRAs Optional CryptoCash Core & Token - for Ext use
    (if (is-some extras) 
      (asserts! (is-ok (fold validate-extra (unwrap! extras ERR-NOTFOUND) (ok true))) ERR-INVALID-EXTRA)
      false
    )   
    
    ;; Validate recipient is not sender
    (asserts! (not (is-eq sender recipient)) ERR-SELF-GIFT)
    
    ;; Sender is tx-sender
    (asserts! (is-eq sender tx-sender) ERR-SENDER-MISMATCH)

    ;; Ensure sender balance is greater than amount being sent
    (asserts! (> (unwrap! (contract-call? contractId get-balance sender) ERR-NOTFOUND) amount) ERR-INSUFFICIENT-BALANCE)
    
    ;; Ensure memo buff is present, if so len must less than or equal to 34
    (if (is-some memo)
      (asserts! (<= (len (unwrap! memo ERR-INVALID-MEMO)) u34) ERR-INVALID-MEMO)
      false
    )

    ;; Executes extention contract function if defined
    (if (not (is-none ext))
      (let 
        ((targetContract (unwrap! ext ERR-NOTFOUND))) 
        (try! (contract-call? targetContract exec-ext-func extras ))
        true
      )
      false
    )

    (is-ok (log-gift sender recipient is-stx contractId amount memo ext))
    (ok true)
  )
)

;; Core Operation Send Message - updated
(define-public (send-message 
  (content (string-utf8 256)) 
  (attachment-uri (optional (string-utf8 256))) 
  (thumbnail-uri (optional (string-utf8 256))) 
  (reply-to (optional (string-utf8 256))) 
  (mine-amounts (list 200 uint)) 
  (alt-origin (string-utf8 256))
  (ext (optional <derupt-ext-trait>))
  (extras (optional (list 10 
    {
      stringutf8: (optional (string-utf8 256)), 
      stringascii: (optional (string-ascii 256)), 
      uint: (optional uint), 
      int: (optional int), 
      principal: (optional principal), 
      bool: (optional bool),
      buff: (optional (buff 34)),
      proxy: (optional (buff 2048)),
      cryptocash-token-contract: (optional <cryptocash-token-trait>),
      cryptocash-core-contract: (optional <cryptocash-core-trait>),
      sip-009-contract: (optional <sip-009-trait>),
      sip-010-contract: (optional <sip-010-trait>),
      sip-013-contract: (optional <sip-013-trait>)
    }))
  )
  (pay-dev bool) 
  (pay-gaia bool) 
  (dev-stx-amount uint) 
  (gaia-stx-amount uint)
  (dev-principal (optional principal)) 
  (gaia-principal (optional principal))
  (cryptocash-core-contract <cryptocash-core-trait>)
  )
  (let 
    (
      (dev-stx-total dev-stx-amount) 
      (gaia-stx-total gaia-stx-amount) 
    ) 
      ;; Validate CryptoCash Core - for Derupt use 
      (asserts! (is-eq (contract-of cryptocash-core-contract) (unwrap! (get-cc-core-contract) ERR-INVALID-CC-CORE)) ERR-INVALID-CC-CORE) ;; needed for dislike-message, but we also need it at send-message validation but accidently skipped it.

      ;; Validate EXTRAs Optional CryptoCash Core & Token - for Ext use
      (if (is-some extras) 
        (asserts! (is-ok (fold validate-extra (unwrap! extras ERR-NOTFOUND) (ok true))) ERR-INVALID-EXTRA)
        false
      ) 

      ;; Content Required
      (asserts! (> (len content) u0) ERR-CONTENT-REQUIRED)

      ;; len check attachment-uri and make sure its less than or equal to 256
      (asserts! (<= (len (unwrap! attachment-uri ERR-WITH-ATTACHMENT)) u256) ERR-WITH-ATTACHMENT)

      ;; len check thumbnail-uri and make sure its less than or equal to 256
      (asserts! (<= (len (unwrap! thumbnail-uri ERR-WITH-THUMBNAIL)) u256) ERR-WITH-THUMBNAIL)

      ;; len check reply-to and make sure its less than or equal to 256
      (asserts! (<= (len (unwrap! reply-to ERR-WITH-REPLYTO)) u256) ERR-WITH-REPLYTO)

      ;; sum check of list and make sure its greater than 0
      (asserts! (> (fold + mine-amounts u0) u0) ERR-WITH-MINE-AMOUNT)

      ;; Alt-Origin Required
      (asserts! (> (len alt-origin) u0) ERR-ALT-ORIGIN-REQUIRED)

      ;; Interface Amounts greater than or equal to 0
      (asserts! (>= dev-stx-total u0) ERR-INVALID-VALUE)
      (asserts! (>= gaia-stx-amount u0) ERR-INVALID-VALUE)

      ;; Interface Payment Address checks
      (asserts! (is-standard (unwrap! dev-principal ERR-INVALID-DEV-ADDRESS)) ERR-INVALID-DEV-ADDRESS)
      (asserts! (is-standard (unwrap! gaia-principal ERR-INVALID-GAIA-ADDRESS)) ERR-INVALID-GAIA-ADDRESS)
      
      ;; Proceed with calling Feed contract
      (try! (contract-call? .derupt-feed pay-stx mine-amounts pay-dev pay-gaia dev-stx-amount gaia-stx-amount dev-principal gaia-principal cryptocash-core-contract))

      ;; Executes extention contract function if defined
      (if (not (is-none ext))
        (let 
          ((targetContract (unwrap! ext ERR-NOTFOUND))) 
          (try! (contract-call? targetContract exec-ext-func extras))
          true
        )
        false
      )

      (is-ok (log-send-message content attachment-uri thumbnail-uri reply-to mine-amounts alt-origin ext pay-dev pay-gaia dev-stx-total gaia-stx-total dev-principal gaia-principal))
      (is-ok (log-mine tx-sender mine-amounts))
      (ok true)
  )
)

;; Core Operation Like Message
(define-public (like-message 
  (author-principal principal) 
  (liked-txid (string-utf8 256)) 
  (cryptocash-token-contract <cryptocash-token-trait>)
  (like-ft-amount uint) 
  (pay-dev bool) 
  (pay-gaia bool) 
  (dev-ft-amount uint) 
  (gaia-ft-amount uint)
  (dev-principal (optional principal)) 
  (gaia-principal (optional principal))
  (ext (optional <derupt-ext-trait>))
  (extras (optional (list 10 
    {
      stringutf8: (optional (string-utf8 256)), 
      stringascii: (optional (string-ascii 256)), 
      uint: (optional uint), 
      int: (optional int), 
      principal: (optional principal), 
      bool: (optional bool),
      buff: (optional (buff 34)),
      proxy: (optional (buff 2048)),
      cryptocash-token-contract: (optional <cryptocash-token-trait>),
      cryptocash-core-contract: (optional <cryptocash-core-trait>),
      sip-009-contract: (optional <sip-009-trait>),
      sip-010-contract: (optional <sip-010-trait>),
      sip-013-contract: (optional <sip-013-trait>)
    }))
  )
  )
  (let
    (
      (like-ft-total like-ft-amount)
      (dev-ft-total dev-ft-amount)
      (gaia-ft-total gaia-ft-amount)
    )    
      ;; Validate CryptoCash Token - for Derupt use 
      (asserts! (is-eq (contract-of cryptocash-token-contract) (unwrap! (get-cc-token-contract) ERR-INVALID-CC-TOKEN)) ERR-INVALID-CC-TOKEN)
      
      ;; Validate EXTRAs Optional CryptoCash Core & Token - for Ext use
      (if (is-some extras) 
        (asserts! (is-ok (fold validate-extra (unwrap! extras ERR-NOTFOUND) (ok true))) ERR-INVALID-EXTRA)
        false
      ) 

      ;; Can't Like Self
      (asserts! (not (is-eq tx-sender author-principal)) ERR-SELF-LIKE)
      
      ;; Liked Transaction ID Required
      (asserts! (> (len liked-txid) u0) ERR-LIKED-TXID-REQUIRED)

      ;; Like Amount to Author must be greater than 0
      (asserts! (> like-ft-amount u0) ERR-INVALID-LIKE-AMOUNT)

      ;; Interface Amounts greater than or equal to 0
      (asserts! (>= dev-ft-total u0) ERR-INVALID-VALUE)
      (asserts! (>= gaia-ft-total u0) ERR-INVALID-VALUE)

      ;; Interface Payment Address checks
      (asserts! (is-standard (unwrap! dev-principal ERR-INVALID-DEV-ADDRESS)) ERR-INVALID-DEV-ADDRESS)
      (asserts! (is-standard (unwrap! gaia-principal ERR-INVALID-GAIA-ADDRESS)) ERR-INVALID-GAIA-ADDRESS)

      ;; Proceed with calling Feed contract
      (try! (contract-call? .derupt-feed pay-ft-like author-principal like-ft-total pay-dev pay-gaia dev-ft-total gaia-ft-total dev-principal gaia-principal cryptocash-token-contract))

      ;; Executes extention contract function if defined
      (if (not (is-none ext))
        (let 
          ((targetContract (unwrap! ext ERR-NOTFOUND))) 
          (try! (contract-call? targetContract exec-ext-func extras))
          true
        )
        false
      )

      (is-ok (log-like-message author-principal like-ft-total liked-txid cryptocash-token-contract pay-dev pay-gaia dev-ft-total gaia-ft-total dev-principal gaia-principal ext))
      (ok true)
  )
)

;; Core Operation Dislike Message
(define-public (dislike-message 
  (author-principal principal) 
  (disliked-txid (string-utf8 256)) 
  (cryptocash-token-contract <cryptocash-token-trait>)
  (cryptocash-core-contract <cryptocash-core-trait>)
  (dislike-ft-amount uint)
  (lockPeriod uint) 
  (pay-dev bool) 
  (pay-gaia bool) 
  (dev-ft-amount uint) 
  (gaia-ft-amount uint)
  (dev-principal (optional principal)) 
  (gaia-principal (optional principal))
  (ext (optional <derupt-ext-trait>))
  (extras (optional (list 10 
    {
      stringutf8: (optional (string-utf8 256)), 
      stringascii: (optional (string-ascii 256)), 
      uint: (optional uint), 
      int: (optional int), 
      principal: (optional principal), 
      bool: (optional bool),
      buff: (optional (buff 34)),
      proxy: (optional (buff 2048)),
      cryptocash-token-contract: (optional <cryptocash-token-trait>),
      cryptocash-core-contract: (optional <cryptocash-core-trait>),
      sip-009-contract: (optional <sip-009-trait>),
      sip-010-contract: (optional <sip-010-trait>),
      sip-013-contract: (optional <sip-013-trait>)
    }))
  )
)
  (let
    (
      (dislike-ft-total dislike-ft-amount)
      (dev-ft-total dev-ft-amount)
      (gaia-ft-total gaia-ft-amount)
    )
      ;; Validate CryptoCash Token - for Derupt use 
      (asserts! (is-eq (contract-of cryptocash-token-contract) (unwrap! (get-cc-token-contract) ERR-INVALID-CC-TOKEN)) ERR-INVALID-CC-TOKEN) 

      ;; Validate CryptoCash Core - for Derupt use 
      (asserts! (is-eq (contract-of cryptocash-core-contract) (unwrap! (get-cc-core-contract) ERR-INVALID-CC-CORE)) ERR-INVALID-CC-CORE) 

      ;; Validate EXTRAs Optional CryptoCash Core & Token - for Ext use
      (if (is-some extras) 
        (asserts! (is-ok (fold validate-extra (unwrap! extras ERR-NOTFOUND) (ok true))) ERR-INVALID-EXTRA)
        false
      ) 

      ;; Can't Dislike Self
      (asserts! (not (is-eq tx-sender author-principal)) ERR-SELF-DISLIKE)

      ;; Liked Transaction ID Required
      (asserts! (> (len disliked-txid) u0) ERR-DISLIKED-TXID-REQUIRED)

      ;; Dislike Amount to Stack must be greater than 0
      (asserts! (> dislike-ft-total u0) ERR-INVALID-DISLIKE-AMOUNT)

      ;; Lock Period must be greater than 0
      (asserts! (> lockPeriod u0) ERR-INVALID-LOCK-PERIOD)

      ;; Interface Amounts greater than or equal to 0
      (asserts! (>= dev-ft-total u0) ERR-INVALID-VALUE)
      (asserts! (>= gaia-ft-total u0) ERR-INVALID-VALUE)

      ;; Interface Payment Address checks
      (asserts! (is-standard (unwrap! dev-principal ERR-INVALID-DEV-ADDRESS)) ERR-INVALID-DEV-ADDRESS)
      (asserts! (is-standard (unwrap! gaia-principal ERR-INVALID-GAIA-ADDRESS)) ERR-INVALID-GAIA-ADDRESS)

      ;; Proceed with calling Feed contract
      (try! (contract-call? .derupt-feed pay-ft-dislike dislike-ft-total lockPeriod pay-dev pay-gaia dev-ft-total gaia-ft-total dev-principal gaia-principal cryptocash-token-contract cryptocash-core-contract))
      
      ;; Executes extention contract function if defined
      (if (not (is-none ext))
        (let 
          ((targetContract (unwrap! ext ERR-NOTFOUND))) 
          (try! (contract-call? targetContract exec-ext-func extras))
          true
        )
        false
      )

      (is-ok (log-dislike-message author-principal dislike-ft-total lockPeriod disliked-txid cryptocash-token-contract pay-dev pay-gaia dev-ft-total gaia-ft-total dev-principal gaia-principal ext))      
      (is-ok (log-stack tx-sender dislike-ft-total lockPeriod))
      (ok true)
  )
)

;; Core Operation Favorable Reply Message
(define-public (favorable-reply-message 
  (content (string-utf8 256)) 
  (author-principal principal) 
  (attachment-uri (optional (string-utf8 256))) 
  (thumbnail-uri (optional (string-utf8 256))) 
  (reply-to (string-utf8 256)) 
  (liked-txid (string-utf8 256)) 
  (mine-amounts (list 200 uint)) 
  (alt-origin (string-utf8 256))
  (ext (optional <derupt-ext-trait>)) 
  (extras (optional (list 10 
    {
      stringutf8: (optional (string-utf8 256)), 
      stringascii: (optional (string-ascii 256)), 
      uint: (optional uint), 
      int: (optional int), 
      principal: (optional principal), 
      bool: (optional bool),
      buff: (optional (buff 34)),
      proxy: (optional (buff 2048)),
      cryptocash-token-contract: (optional <cryptocash-token-trait>),
      cryptocash-core-contract: (optional <cryptocash-core-trait>),
      sip-009-contract: (optional <sip-009-trait>),
      sip-010-contract: (optional <sip-010-trait>),
      sip-013-contract: (optional <sip-013-trait>)
    }))
  )
  (cryptocash-token-contract <cryptocash-token-trait>)
  (cryptocash-core-contract <cryptocash-core-trait>)
  (like-ft-amount uint)
  (pay-dev bool) 
  (pay-gaia bool) 
  (dev-stx-amount uint) 
  (gaia-stx-amount uint)
  (dev-ft-amount uint) 
  (gaia-ft-amount uint)
  (dev-principal (optional principal)) 
  (gaia-principal (optional principal))
)
    (begin

      ;; Validate EXTRAs Optional CryptoCash Core & Token - for Ext use
      (if (is-some extras) 
        (asserts! (is-ok (fold validate-extra (unwrap! extras ERR-NOTFOUND) (ok true))) ERR-INVALID-EXTRA)
        false
      ) 

      (asserts! (not (is-eq tx-sender author-principal)) ERR-UNAUTHORIZED)
      (try! (send-message content attachment-uri thumbnail-uri (some reply-to) mine-amounts alt-origin none none pay-dev pay-gaia dev-stx-amount gaia-stx-amount dev-principal gaia-principal cryptocash-core-contract))
      (try! (like-message author-principal liked-txid cryptocash-token-contract like-ft-amount pay-dev pay-gaia dev-ft-amount gaia-ft-amount dev-principal gaia-principal none none))

      ;; Executes extention contract function if defined
      (if (not (is-none ext))
        (let 
          ((targetContract (unwrap! ext ERR-NOTFOUND))) 
          (try! (contract-call? targetContract exec-ext-func extras))
          true
        )
        false
      )

      (ok true)
    )
)

;; Core Operation Unfavorable Reply Message
(define-public (unfavorable-reply-message 
  (content (string-utf8 256)) 
  (author-principal principal) 
  (attachment-uri (optional (string-utf8 256))) 
  (thumbnail-uri (optional (string-utf8 256))) 
  (reply-to (string-utf8 256))   
  (disliked-txid (string-utf8 256)) 
  (mine-amounts (list 200 uint))  
  (alt-origin (string-utf8 256))
  (ext (optional <derupt-ext-trait>))  
  (extras (optional (list 10 
    {
      stringutf8: (optional (string-utf8 256)), 
      stringascii: (optional (string-ascii 256)), 
      uint: (optional uint), 
      int: (optional int), 
      principal: (optional principal), 
      bool: (optional bool),
      buff: (optional (buff 34)),
      proxy: (optional (buff 2048)),
      cryptocash-token-contract: (optional <cryptocash-token-trait>),
      cryptocash-core-contract: (optional <cryptocash-core-trait>),
      sip-009-contract: (optional <sip-009-trait>),
      sip-010-contract: (optional <sip-010-trait>),
      sip-013-contract: (optional <sip-013-trait>)
    }))
  )
  (cryptocash-token-contract <cryptocash-token-trait>)
  (cryptocash-core-contract <cryptocash-core-trait>)
  (dislike-ft-amount uint)
  (lockPeriod uint)
  (pay-dev bool) 
  (pay-gaia bool) 
  (dev-stx-amount uint) 
  (gaia-stx-amount uint)
  (dev-ft-amount uint) 
  (gaia-ft-amount uint)
  (dev-principal (optional principal)) 
  (gaia-principal (optional principal))
)
    (begin

      ;; Validate EXTRAs Optional CryptoCash Core & Token - for Ext use
      (if (is-some extras) 
        (asserts! (is-ok (fold validate-extra (unwrap! extras ERR-NOTFOUND) (ok true))) ERR-INVALID-EXTRA)
        false
      ) 

      (asserts! (not (is-eq tx-sender author-principal)) ERR-UNAUTHORIZED)
      (try! (send-message content attachment-uri thumbnail-uri (some reply-to) mine-amounts alt-origin none none pay-dev pay-gaia dev-stx-amount gaia-stx-amount dev-principal gaia-principal cryptocash-core-contract))
      (try! (dislike-message author-principal disliked-txid cryptocash-token-contract cryptocash-core-contract dislike-ft-amount lockPeriod pay-dev pay-gaia dev-ft-amount gaia-ft-amount dev-principal gaia-principal none none))

      ;; Executes extention contract function if defined
      (if (not (is-none ext))
        (let 
          ((targetContract (unwrap! ext ERR-NOTFOUND))) 
          (try! (contract-call? targetContract exec-ext-func extras))
          true
        )
        false
      )
      
      (ok true)
    )
)

;; Set the derupt-core-yyyymmdd version in derupt-feed contract as a data variable
(contract-call? .derupt-feed set-derupt-core-contract derupt-core-yyyymmdd)
```


# .derupt-profile-trait

Profile traits plays a vital role in facilitating interactions between Derupt users.

{% hint style="info" %}
**Profile Traits**

* `registration-activation`: to register user contracts as members.
* `get-activation-status`: to get a user contract member status.
* `send-message`: to send a Message that supports optional arguments.
* `like-message`: to express appreciation for a Message by Liking it.
* `dislike-message`: to express disapproval for a Message by Disliking it.
* `favorable-reply-message`: to send a favorable Reply, supports optional arguments.
* `unfavorable-reply-message`: to send a unfavorable Reply, supports optional arguments.
  {% endhint %}

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

```
;; title: derupt-profile-trait
;; version: 1.3.1
;; summary: Derupt Profile Trait Contract

(use-trait derupt-core-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-core-trait.derupt-core-trait)
(use-trait derupt-ext-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-ext-trait.derupt-ext)

(use-trait sip-009-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-009-trait-nft-standard.sip-009-trait)
(use-trait sip-010-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-010-trait-ft-standard.sip-010-trait) 
(use-trait sip-013-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-013-trait-sft-standard.sip-013-trait)

(use-trait cryptocash-token-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.cryptocash-token-trait.cryptocash-token)
(use-trait cryptocash-core-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.cryptocash-core-trait.cryptocash-core)

(define-trait derupt-profile-trait 
    (
        (registration-activation (principal) (response bool uint))
        (get-activation-status (principal) (response bool uint))    
        (gift-message 
            (
                principal 
                uint 
                (string-utf8 256) 
                bool 
                <sip-010-trait>
                <derupt-core-trait> 
                (optional (buff 34))
                (optional <derupt-ext-trait>)
                (optional (list 10 
                    {
                        stringutf8: (optional (string-utf8 256)), 
                        stringascii: (optional (string-ascii 256)), 
                        uint: (optional uint), 
                        int: (optional int), 
                        principal: (optional principal), 
                        bool: (optional bool),
                        buff: (optional (buff 34)),
                        proxy: (optional (buff 2048)),
                        cryptocash-token-contract: (optional <cryptocash-token-trait>),
                        cryptocash-core-contract: (optional <cryptocash-core-trait>),
                        sip-009-contract: (optional <sip-009-trait>),
                        sip-010-contract: (optional <sip-010-trait>),
                        sip-013-contract: (optional <sip-013-trait>)
                    }
                ))
            ) (response bool uint)            
        )     
        (send-message 
            (
                (string-utf8 256) 
                (optional (string-utf8 256))
                (optional (string-utf8 256)) 
                (optional (string-utf8 256)) 
                (list 200 uint)
                (string-utf8 256)
                (optional <derupt-ext-trait>)
                (optional (list 10 
                    {
                        stringutf8: (optional (string-utf8 256)), 
                        stringascii: (optional (string-ascii 256)), 
                        uint: (optional uint), 
                        int: (optional int), 
                        principal: (optional principal), 
                        bool: (optional bool),
                        buff: (optional (buff 34)),
                        proxy: (optional (buff 2048)),
                        cryptocash-token-contract: (optional <cryptocash-token-trait>),
                        cryptocash-core-contract: (optional <cryptocash-core-trait>),
                        sip-009-contract: (optional <sip-009-trait>),
                        sip-010-contract: (optional <sip-010-trait>),
                        sip-013-contract: (optional <sip-013-trait>)
                    }
                ))
                <derupt-core-trait>
                <cryptocash-core-trait>
            ) (response bool uint)
        ) 
        (like-message 
            (
                principal 
                (string-utf8 256)
                <cryptocash-token-trait>
                <derupt-core-trait>
                uint  
                (string-utf8 256)
                (optional <derupt-ext-trait>)
                (optional (list 10 
                    {
                        stringutf8: (optional (string-utf8 256)), 
                        stringascii: (optional (string-ascii 256)), 
                        uint: (optional uint), 
                        int: (optional int), 
                        principal: (optional principal), 
                        bool: (optional bool),
                        buff: (optional (buff 34)),
                        proxy: (optional (buff 2048)),
                        cryptocash-token-contract: (optional <cryptocash-token-trait>),
                        cryptocash-core-contract: (optional <cryptocash-core-trait>),
                        sip-009-contract: (optional <sip-009-trait>),
                        sip-010-contract: (optional <sip-010-trait>),
                        sip-013-contract: (optional <sip-013-trait>)
                    }
                ))              
            ) (response bool uint)
        )
        (dislike-message 
            (
                principal 
                (string-utf8 256) 
                <cryptocash-token-trait>
                <cryptocash-core-trait>
                <derupt-core-trait>
                uint   
                uint
                (string-utf8 256)
                (optional <derupt-ext-trait>)
                (optional (list 10 
                    {
                        stringutf8: (optional (string-utf8 256)), 
                        stringascii: (optional (string-ascii 256)), 
                        uint: (optional uint), 
                        int: (optional int), 
                        principal: (optional principal), 
                        bool: (optional bool),
                        buff: (optional (buff 34)),
                        proxy: (optional (buff 2048)),
                        cryptocash-token-contract: (optional <cryptocash-token-trait>),
                        cryptocash-core-contract: (optional <cryptocash-core-trait>),
                        sip-009-contract: (optional <sip-009-trait>),
                        sip-010-contract: (optional <sip-010-trait>),
                        sip-013-contract: (optional <sip-013-trait>)
                    }
                ))             
            ) (response bool uint)
        ) 
        (favorable-reply-message 
            (
                (string-utf8 256) 
                (optional (string-utf8 256))
                (optional (string-utf8 256)) 
                (string-utf8 256)
                principal 
                (string-utf8 256) 
                (list 200 uint)
                (string-utf8 256)
                (optional <derupt-ext-trait>)
                (optional (list 10 
                    {
                        stringutf8: (optional (string-utf8 256)), 
                        stringascii: (optional (string-ascii 256)), 
                        uint: (optional uint), 
                        int: (optional int), 
                        principal: (optional principal), 
                        bool: (optional bool),
                        buff: (optional (buff 34)),
                        proxy: (optional (buff 2048)),
                        cryptocash-token-contract: (optional <cryptocash-token-trait>),
                        cryptocash-core-contract: (optional <cryptocash-core-trait>),
                        sip-009-contract: (optional <sip-009-trait>),
                        sip-010-contract: (optional <sip-010-trait>),
                        sip-013-contract: (optional <sip-013-trait>)
                    }
                ))
                <cryptocash-token-trait>
                <cryptocash-core-trait> 
                <derupt-core-trait>
                uint
            ) (response bool uint)
        )
        (unfavorable-reply-message 
            (
                (string-utf8 256) 
                (optional (string-utf8 256)) 
                (optional (string-utf8 256)) 
                (string-utf8 256)
                principal 
                (string-utf8 256) 
                (list 200 uint)
                (string-utf8 256)
                (optional <derupt-ext-trait>)
                (optional (list 10 
                    {
                        stringutf8: (optional (string-utf8 256)), 
                        stringascii: (optional (string-ascii 256)), 
                        uint: (optional uint), 
                        int: (optional int), 
                        principal: (optional principal), 
                        bool: (optional bool),
                        buff: (optional (buff 34)),
                        proxy: (optional (buff 2048)),
                        cryptocash-token-contract: (optional <cryptocash-token-trait>),
                        cryptocash-core-contract: (optional <cryptocash-core-trait>),
                        sip-009-contract: (optional <sip-009-trait>),
                        sip-010-contract: (optional <sip-010-trait>),
                        sip-013-contract: (optional <sip-013-trait>)
                    }
                ))
                <cryptocash-token-trait>
                <cryptocash-core-trait>
                <derupt-core-trait>
                uint
                uint
            ) (response bool uint)
        )
    )
)
```


# .derupt-profiles

All .derupt-profile contract activations are logged in .derupt-profiles contract

**The following function call is only only callable by .derupt-profile:**

* activate-member

{% hint style="info" %}
**General:**

* The **.derupt-profiles** contract is for logging user contract activations.
  {% endhint %}

{% hint style="warning" %}
**Warning:**

* **users should deploy a** `.derupt-profile` contract in app to interact with core features.
* **users should call**`.derupt-profile`&#x20;
* **users should not call**`.derupt-core-yyyymmdd` *(nor logging contracts)*
* **users should only** enable 1 extension per 1 key function at a time (eg up to 6 active extensions at a time)&#x20;
  {% endhint %}

In should be noted, users deploy their `.derupt-profile` contracts to Stacks Mainnet, then their Activation is what is logged in `.derupt-profiles`  events

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

```
;; title: derupt-profiles
;; version: 1.3.1
;; summary: Profiles Contract
;; description: used to log all user .derupt-profile contract activations

(use-trait derupt-profile-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-profile-trait.derupt-profile-trait)
;; (use-trait derupt-profile-trait 'MAINNETADDRESS.derupt-profile-trait.derupt-profile-trait)

;; Errors
(define-constant ERR-UNAUTHORIZED (err u100))
(define-constant ERR-NOTFOUND (err u101))
(define-constant ERR-ALREADY-ACTIVATED (err u106))

(define-public (activate-member (contract-address <derupt-profile-trait>)) 
    (let 
        (
            (member-caller (unwrap! (get name (unwrap! (principal-destruct? contract-caller) ERR-NOTFOUND)) ERR-NOTFOUND))
            (member-status (unwrap! (contract-call? contract-address get-activation-status tx-sender) ERR-NOTFOUND))
        )
        (asserts! (is-eq member-caller "derupt-profile") ERR-UNAUTHORIZED)
        (asserts! (is-eq (contract-of contract-address) contract-caller) ERR-UNAUTHORIZED)
        (asserts! (is-eq member-status false) ERR-ALREADY-ACTIVATED)                                 
        (is-ok (contract-call? contract-address registration-activation tx-sender))
        (print {publisher: tx-sender, contract: contract-caller})
        (ok true)
    )
)
```


# .derupt-ext-reg

Derupt developers can deploy extension, the .derupt-ext-reg is used to announce new extensions.

{% hint style="info" %}
**General:**

* A distinct **.derupt-ext** contract should be deployed by developer(s).&#x20;
* **.derupt-ext** contract(s) are used integrate 3rd party Stacks Smart contracts into the Derupt user experience during Derupt Core Operations.&#x20;
* `register-ext` function **must** be called by the extension contract deployer.&#x20;
  {% endhint %}

{% hint style="warning" %}
**Dev Warning:**

* **deploy a single** `.derupt-ext` contract to integrate w/ a single 3rd party contract function. &#x20;
* **users use your** `.derupt-ext`  contract as an `ext` argument in Derupt core operation calls.&#x20;
* **all extension arguments** are passed as `extras` during core operation function calls.\
  *(\* extension can use internal variables that do not require being passed if so desired)*&#x20;
* **to pass user input** as **`extras`** during **`ExtensionModal`** presentation, simply define the applicable `argsFromUser` via your [extension metadata.json description](https://docs.derupt.io/latest/contracts/.derupt-ext#extension-description-metadata)
  {% endhint %}

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

```
;; title: derupt-ext-reg
;; version: 1.3.1
;; summary: Extension Registry Contract
;; description: used to log extension registration

(use-trait derupt-ext-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-ext-trait.derupt-ext)
;; (use-trait derupt-ext-trait 'MAINNETADDRESS.derupt-ext-trait.derupt-ext)

;; Error Constants
(define-constant ERR-UNAUTHORIZED (err u100))
(define-constant ERR-INVALID-PRINCIPAL (err u101))

(define-public (register-ext (ext-contract <derupt-ext-trait>))
    (let (
        (principal-data (unwrap! (principal-destruct? (contract-of ext-contract)) ERR-INVALID-PRINCIPAL))
        (version (get version principal-data))
        (hash-bytes (get hash-bytes principal-data))
        (ext-deployer (unwrap! (principal-construct? version hash-bytes) ERR-INVALID-PRINCIPAL))
    )
        (asserts! (is-eq tx-sender ext-deployer) ERR-UNAUTHORIZED)
        (print {ext-contract: (contract-of ext-contract)})
        (ok true)
    )
)
```


# .derupt-profile

Derupt users need their own .derupt-profile contract on Stacks Mainnet. (deployed & activated in app)

{% hint style="info" %}
**General:**

* A distinct **.derupt-profile** contract should be deployed and activated per user.&#x20;
* **.derupt-profile** contract calls the **.derupt-core-yyyymmdd** contract for application logic purposes
  {% endhint %}

{% hint style="warning" %}
**Warning:**

* **users should deploy a** `.derupt-profile`contract in app to interact with core features.
* **users should call**`.derupt-profile`
* **users should not call**`.derupt-core-yyyymmdd` *(nor logging contracts)*
  {% endhint %}

{% hint style="info" %}
**Key Functions Process Transactions Overview:**

What happens in a process depends on the function the user is calling.&#x20;

* **gift-message:** `transfer` of a variable sip-010 token is called during this process.
* **send-message**: `mine` cryptocash is called during this process.&#x20;
* **like-message**: `transfer` cryptocash is called during this process.
* **dislike-message**: `stack` cryptocash is called during this process.
* **favorable-reply-message**: `mine` & `transfer` cryptocash is called during this process.
* **unfavorable-reply-message**: `mine` & `stack` cryptocash is called during this process. &#x20;
  {% endhint %}

The 6 key functions and arguments in a users  `.derupt-profile` contract:

<details>

<summary><mark style="color:orange;">gift-message</mark></summary>

<mark style="color:orange;">Broadcast Send Message to the Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\)`.derupt-profile`\
2\)`.derupt-core-yyyymmdd (&.derupt-ext if defined)` \
3\)`.derupt-gifts`

**Arguments:**

* ...

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>

<details>

<summary><mark style="color:orange;">send-message</mark> </summary>

<mark style="color:orange;">Broadcast Send Message to the Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\)`.derupt-profile`\
2\)`.derupt-core-yyyymmdd (&.derupt-ext if defined)` \
3\)`.derupt-feed (&.derupt-miners)`

**Arguments:**

* ...

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>

<details>

<summary><mark style="color:orange;">like-message</mark></summary>

<mark style="color:orange;">Broadcast Like Message to Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\) `.derupt-profile`\
2\) `.derupt-core-yyyymmdd (&.derupt-ext if defined)` \
3\) `.derupt-sentiments`

**Arguments:**

* ...

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>

<details>

<summary><mark style="color:orange;">dislike-message</mark></summary>

<mark style="color:orange;">Broadcast Dislike Message to Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\) `.derupt-profile`\
2\) `.derupt-core-yyyymmdd (&.derupt-ext if defined)` \
3\) `.derupt-sentiments (&.derupt-stackers)`

**Arguments:**

* ...

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>

<details>

<summary><mark style="color:orange;">favorable-reply-message</mark></summary>

<mark style="color:orange;">Broadcast Favorable Reply Message to Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\) `.derupt-profile`\
2\) `.derupt-core-yyyymmdd (&.derupt-ext if defined)` \
3\) `.derupt-feed (&.derupt-sentiments &.derupt-miners)`

**Arguments:**

* ...

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>

<details>

<summary><mark style="color:orange;">unfavorable-reply-message</mark></summary>

<mark style="color:orange;">Broadcast Unfavorable Reply Message to Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\) `.derupt-profile`\
2\) `.derupt-core-yyyymmdd (&.derupt-ext if defined)` \
3\) `.derupt-feed (&.derupt-sentiments &.derupt-miners &.derupt-stackers)`

**Arguments:**

* ...

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>

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

```
;; title: derupt-profile
;; version: 1.3.1
;; summary: Profile Contract
;; description: Each user should deploy one of these contracts, and call these functions to interface with the Derupt protocol.

(impl-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-profile-trait.derupt-profile-trait)

(use-trait sip-009-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-009-trait-nft-standard.sip-009-trait)
(use-trait sip-010-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-010-trait-ft-standard.sip-010-trait)
(use-trait sip-013-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-013-trait-sft-standard.sip-013-trait)

(use-trait derupt-core-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-core-trait.derupt-core-trait)
(use-trait derupt-profile-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-profile-trait.derupt-profile-trait)
(use-trait derupt-ext-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-ext-trait.derupt-ext)

(use-trait cryptocash-token-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.cryptocash-token-trait.cryptocash-token)
(use-trait cryptocash-core-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.cryptocash-core-trait.cryptocash-core)

;; User Principal
(define-constant APP_USER tx-sender)

;; Error constants
(define-constant ERR-UNAUTHORIZED (err u100))
(define-constant ERR-NOTFOUND (err u101))
(define-constant ERR-VALIDATION-FAILED (err u102))
(define-constant ERR-INSUFFICIENT-BALANCE (err u104))
(define-constant ERR-UNAUTHORIZED-CONTRACT (err u105))
(define-constant ERR-INVALID-VALUE (err u106))

;; Member activation map
(define-map member-status principal bool)

(define-data-var loadoutUri (optional (string-utf8 256)) (some u"default"))

;; Get Derupt-core contract
(define-private (get-derupt-core-contract)
  (contract-call? 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-feed get-derupt-core-contract) 
  ;; (contract-call? 'MAINNETADDRESS.derupt-feed get-derupt-core-contract) 
)

(define-private (get-chime-stx-amount)
  (contract-call? 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-feed get-chime-stx-amount)  
  ;; (contract-call? 'MAINNETADDRESS.derupt-feed get-chime-stx-amount)  
)

(define-private (get-chime-ft-amount)
  (contract-call? 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-feed get-chime-ft-amount)  
  ;; (contract-call? 'MAINNETADDRESS.derupt-feed get-chime-ft-amount)  
)

(define-read-only (get-loadout-uri)
  (ok (var-get loadoutUri))
)

;; User Operation Loadout - set URI to new value
(define-public (set-loadout-uri (newUri (optional (string-utf8 256))))
  (begin
    (asserts! (is-eq tx-sender APP_USER) ERR-UNAUTHORIZED)
    (asserts! (is-some newUri) ERR-INVALID-VALUE)
    (ok (var-set loadoutUri newUri))
  )
)

;; validatation of core contract (Derupt Core)
(define-private (validate-core-contract (contract principal))
  (contract-call? 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-feed validate-core-contract contract)
  ;; (contract-call? 'MAINNETADDRESS.derupt-feed validate-core-contract contract)
)

;; Member activation
(define-public (registration-activation (member principal))
  (let 
    (
      (caller (unwrap! (get name (unwrap! (principal-destruct? contract-caller) ERR-NOTFOUND)) ERR-NOTFOUND))
    ) 
      (asserts! (is-eq tx-sender member) ERR-UNAUTHORIZED)
      (asserts! (is-eq caller "derupt-profiles") ERR-UNAUTHORIZED)
      (map-set member-status APP_USER true)
      (ok true)
  )
)

;; Get status via chain change
(define-public (get-activation-status (member principal))
  (begin
    (asserts! (is-eq tx-sender member) ERR-UNAUTHORIZED)
    (ok (unwrap! (map-get? member-status APP_USER) ERR-NOTFOUND))
  )
)

;; Get status via api
(define-read-only (activation-status)
  (ok (unwrap! (map-get? member-status APP_USER) ERR-NOTFOUND))
)

;; this contract-address should be this users specific .derupt-profile contract address
(define-public (activate-member (contract-address <derupt-profile-trait>)) 
  (contract-call? 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-profiles activate-member contract-address)
  ;; (contract-call? 'MAINNETADDRESS.derupt-profiles activate-member contract-address)
)

;; User Operation Gifting
(define-public (gift-message (chime-author principal) (amount uint) 
  (via-id (string-utf8 256)) (is-stx bool) (contractId <sip-010-trait>)
  (core-contract <derupt-core-trait>) (memo (optional (buff 34)))
  (ext (optional <derupt-ext-trait>))
  (extras (optional (list 10 
    {
      stringutf8: (optional (string-utf8 256)), 
      stringascii: (optional (string-ascii 256)), 
      uint: (optional uint), 
      int: (optional int), 
      principal: (optional principal), 
      bool: (optional bool),
      buff: (optional (buff 34)),
      proxy: (optional (buff 2048)),
      cryptocash-token-contract: (optional <cryptocash-token-trait>),
      cryptocash-core-contract: (optional <cryptocash-core-trait>),
      sip-009-contract: (optional <sip-009-trait>),
      sip-010-contract: (optional <sip-010-trait>),
      sip-013-contract: (optional <sip-013-trait>)
    }))
  )
)
  (let 
    (
      (profile-balance-ft (unwrap! (contract-call? contractId get-balance tx-sender) ERR-INSUFFICIENT-BALANCE))
      (profile-balance-stx (stx-get-balance tx-sender))
      (inputed-core-contract (contract-of core-contract)) 
    ) 
      (if is-stx
        (begin 
          (asserts! (>= profile-balance-stx amount) ERR-INSUFFICIENT-BALANCE)
          (asserts! (unwrap! (validate-core-contract inputed-core-contract) ERR-VALIDATION-FAILED) ERR-UNAUTHORIZED-CONTRACT)
          (if (is-some memo) 
            (try! (stx-transfer-memo? amount tx-sender chime-author (unwrap! memo ERR-NOTFOUND)))
            (try! (stx-transfer? amount tx-sender chime-author))
          )          
          (try! (contract-call? core-contract gift-message tx-sender chime-author is-stx contractId amount memo ext extras))
          (print {event: "gift-message", chime-author: chime-author, amount: amount, via-id: via-id, is-stx: true, memo: memo, ext: ext})
          (ok true)
        )
        (begin 
          (asserts! (>= profile-balance-ft amount) ERR-INSUFFICIENT-BALANCE)
          (asserts! (unwrap! (validate-core-contract inputed-core-contract) ERR-VALIDATION-FAILED) ERR-UNAUTHORIZED-CONTRACT)
          (try! (contract-call? contractId transfer amount tx-sender chime-author memo))
          (try! (contract-call? core-contract gift-message tx-sender chime-author is-stx contractId amount memo ext extras))
          (print {event: "gift-message", chime-author: chime-author, amount: amount, via-id: via-id, is-stx: false, contractId: contractId, memo: memo, ext: ext})
          (ok true)
        )
      )
    )
)

;; User Operation Send Message
(define-public (send-message 
  (content (string-utf8 256)) 
  (attachment-uri (optional (string-utf8 256))) 
  (thumbnail-uri (optional (string-utf8 256))) 
  (reply-to (optional (string-utf8 256))) 
  (mine-amounts (list 200 uint))
  (alt-origin (string-utf8 256))
  (ext (optional <derupt-ext-trait>))
  (extras (optional (list 10 
    {
      stringutf8: (optional (string-utf8 256)), 
      stringascii: (optional (string-ascii 256)), 
      uint: (optional uint), 
      int: (optional int), 
      principal: (optional principal), 
      bool: (optional bool),
      buff: (optional (buff 34)),
      proxy: (optional (buff 2048)),
      cryptocash-token-contract: (optional <cryptocash-token-trait>),
      cryptocash-core-contract: (optional <cryptocash-core-trait>),
      sip-009-contract: (optional <sip-009-trait>),
      sip-010-contract: (optional <sip-010-trait>),
      sip-013-contract: (optional <sip-013-trait>)
    }))
  )
  (core-contract <derupt-core-trait>)
  (cryptocash-core-contract <cryptocash-core-trait>)
)           
  (let 
    (
      (tpi-values (unwrap! (contract-call? 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-interfaces get-token-interface alt-origin) ERR-NOTFOUND))
      ;;(tpi-values (unwrap! (contract-call? 'MAINNETADDRESS.derupt-interfaces get-token-interface alt-origin) ERR-NOTFOUND))
      (pay-dev (unwrap! (get pay-dev tpi-values) ERR-NOTFOUND)) 
      (pay-gaia (unwrap! (get pay-gaia tpi-values) ERR-NOTFOUND)) 
      (dev-stx-amount (unwrap! (get dev-stx-amount tpi-values) ERR-NOTFOUND)) 
      (gaia-stx-amount (unwrap! (get gaia-stx-amount tpi-values) ERR-NOTFOUND))      
      (dev-principal  (get dev-principal tpi-values)) 
      (gaia-principal  (unwrap! (get gaia-principal tpi-values) ERR-NOTFOUND))
      (derupt-core-contract (unwrap! (get-derupt-core-contract) ERR-NOTFOUND))
      (chime-stx-total (unwrap! (get-chime-stx-amount) ERR-NOTFOUND))
      (dev-stx-total dev-stx-amount) 
      (gaia-stx-total gaia-stx-amount) 
      (inputed-core-contract (contract-of core-contract))      
    )            
    (asserts! (is-eq tx-sender APP_USER) ERR-UNAUTHORIZED)
    (asserts! (unwrap! (validate-core-contract inputed-core-contract) ERR-VALIDATION-FAILED) ERR-UNAUTHORIZED-CONTRACT)
    (try! (contract-call? core-contract send-message content attachment-uri thumbnail-uri reply-to mine-amounts alt-origin ext extras pay-dev pay-gaia dev-stx-amount gaia-stx-amount dev-principal (some gaia-principal) cryptocash-core-contract))   
    (print 
      { 
        event: "send-message", content: content, attachment-uri: attachment-uri, thumbnail-uri: thumbnail-uri, reply-to: reply-to, 
        alt-origin: alt-origin, ext: ext, 
        mine-total: (fold + mine-amounts u0), mine-amounts: mine-amounts,
        chime-stx-total: chime-stx-total,
        dev-stx-total: dev-stx-total, gaia-stx-total: gaia-stx-total,
        dev-principal: dev-principal, gaia-principal: gaia-principal
      }
    )
    (ok true)
  )
)

;; User Operation Like Message
(define-public (like-message 
    (author-principal principal) 
    (liked-txid (string-utf8 256)) 
    (cryptocash-token-contract <cryptocash-token-trait>)
    (core-contract <derupt-core-trait>)
    (like-ft-amount uint)
    (alt-origin (string-utf8 256))
    (ext (optional <derupt-ext-trait>))
    (extras (optional (list 10 
      {
        stringutf8: (optional (string-utf8 256)), 
        stringascii: (optional (string-ascii 256)), 
        uint: (optional uint), 
        int: (optional int), 
        principal: (optional principal), 
        bool: (optional bool),
        buff: (optional (buff 34)),
        proxy: (optional (buff 2048)),
        cryptocash-token-contract: (optional <cryptocash-token-trait>),
        cryptocash-core-contract: (optional <cryptocash-core-trait>),
        sip-009-contract: (optional <sip-009-trait>),
        sip-010-contract: (optional <sip-010-trait>),
        sip-013-contract: (optional <sip-013-trait>)
      }))
    )
  )    
  (let 
    (
      (tpi-values (unwrap! (contract-call? 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-interfaces get-token-interface alt-origin) ERR-NOTFOUND))
      ;; (tpi-values (unwrap! (contract-call? 'MAINNETADDRESS.derupt-interfaces get-token-interface alt-origin) ERR-NOTFOUND))
      (pay-dev (unwrap! (get pay-dev tpi-values) ERR-NOTFOUND)) 
      (pay-gaia (unwrap! (get pay-gaia tpi-values) ERR-NOTFOUND))       
      (dev-ft-amount (unwrap! (get dev-ft-amount tpi-values) ERR-NOTFOUND)) 
      (gaia-ft-amount (unwrap! (get gaia-ft-amount tpi-values) ERR-NOTFOUND))
      (dev-principal  (get dev-principal tpi-values)) 
      (gaia-principal  (unwrap! (get gaia-principal tpi-values) ERR-NOTFOUND))
      (derupt-core-contract (unwrap! (get-derupt-core-contract) ERR-NOTFOUND))
      (like-ft-total like-ft-amount)
      (chime-ft-total (unwrap! (get-chime-ft-amount) ERR-NOTFOUND))
      (dev-ft-total dev-ft-amount)
      (gaia-ft-total gaia-ft-amount)
      (inputed-core-contract (contract-of core-contract))
    )
    (asserts! (is-eq tx-sender APP_USER) ERR-UNAUTHORIZED)      
    (asserts! (unwrap! (validate-core-contract inputed-core-contract) ERR-VALIDATION-FAILED) ERR-UNAUTHORIZED-CONTRACT)
    (try! (contract-call? core-contract like-message author-principal liked-txid cryptocash-token-contract like-ft-amount pay-dev pay-gaia dev-ft-amount gaia-ft-amount dev-principal (some gaia-principal) ext extras))
    (print 
      { 
        event: "like-message", author-principal: author-principal, liked-txid: liked-txid, 
        cryptocash-token-contract: cryptocash-token-contract,
        like-ft-total: like-ft-total,
        chime-ft-total: chime-ft-total,
        alt-origin: alt-origin,
        ext: ext,
        pay-dev: pay-dev,
        pay-gaia: pay-gaia,
        dev-ft-total: dev-ft-total, 
        gaia-ft-total: gaia-ft-total,
        dev-principal: dev-principal, 
        gaia-principal: gaia-principal
      }
    )
    (ok true)
  )
)

;; User Operation Dislike Message
(define-public (dislike-message 
    (author-principal principal) 
    (disliked-txid (string-utf8 256)) 
    (cryptocash-token-contract <cryptocash-token-trait>)
    (cryptocash-core-contract <cryptocash-core-trait>)
    (core-contract <derupt-core-trait>)
    (dislike-ft-amount uint)
    (lockPeriod uint)
    (alt-origin (string-utf8 256))
    (ext (optional <derupt-ext-trait>))
    (extras (optional (list 10 
      {
        stringutf8: (optional (string-utf8 256)), 
        stringascii: (optional (string-ascii 256)), 
        uint: (optional uint), 
        int: (optional int), 
        principal: (optional principal), 
        bool: (optional bool),
        buff: (optional (buff 34)),
        proxy: (optional (buff 2048)),
        cryptocash-token-contract: (optional <cryptocash-token-trait>),
        cryptocash-core-contract: (optional <cryptocash-core-trait>),
        sip-009-contract: (optional <sip-009-trait>),
        sip-010-contract: (optional <sip-010-trait>),
        sip-013-contract: (optional <sip-013-trait>)
      }))
    )
  ) 
  (let 
    (
      (tpi-values (unwrap! (contract-call? 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-interfaces get-token-interface alt-origin) ERR-NOTFOUND))
      ;; (tpi-values (unwrap! (contract-call? 'MAINNETADDRESS.derupt-interfaces get-token-interface alt-origin) ERR-NOTFOUND))
      (pay-dev (unwrap! (get pay-dev tpi-values) ERR-NOTFOUND)) 
      (pay-gaia (unwrap! (get pay-gaia tpi-values) ERR-NOTFOUND))
      (dev-ft-amount (unwrap! (get dev-ft-amount tpi-values) ERR-NOTFOUND)) 
      (gaia-ft-amount (unwrap! (get gaia-ft-amount tpi-values) ERR-NOTFOUND))
      (dev-principal  (get dev-principal tpi-values)) 
      (gaia-principal  (unwrap! (get gaia-principal tpi-values) ERR-NOTFOUND))
      (derupt-core-contract (unwrap! (get-derupt-core-contract) ERR-NOTFOUND))
      (dislike-ft-total dislike-ft-amount)
      (chime-ft-total (unwrap! (get-chime-ft-amount) ERR-NOTFOUND))
      (dev-ft-total dev-ft-amount)
      (gaia-ft-total gaia-ft-amount) 
      (inputed-core-contract (contract-of core-contract))      
    )
    (asserts! (is-eq tx-sender APP_USER) ERR-UNAUTHORIZED)
    (asserts! (unwrap! (validate-core-contract inputed-core-contract) ERR-VALIDATION-FAILED) ERR-UNAUTHORIZED-CONTRACT)
    (try! (contract-call? core-contract dislike-message author-principal disliked-txid cryptocash-token-contract cryptocash-core-contract dislike-ft-amount lockPeriod pay-dev pay-gaia dev-ft-amount gaia-ft-amount dev-principal (some gaia-principal) ext extras))
    (print 
      { 
        event: "dislike-message", author-principal: author-principal, disliked-txid: disliked-txid,
        cryptocash-token-contract: cryptocash-token-contract,
        dislike-ft-total: dislike-ft-total,
        lockPeriod: lockPeriod,
        chime-ft-total: chime-ft-total,
        alt-origin: alt-origin,
        ext: ext,
        pay-dev: pay-dev,
        pay-gaia: pay-gaia,
        dev-ft-total: dev-ft-total, 
        gaia-ft-total: gaia-ft-total,
        dev-principal: dev-principal, 
        gaia-principal: gaia-principal
      }
    )
    (ok true)  
  )           
)

;; User Operation Favorable Reply Message
(define-public (favorable-reply-message 
    (content (string-utf8 256)) 
    (attachment-uri (optional (string-utf8 256))) 
    (thumbnail-uri (optional (string-utf8 256))) 
    (reply-to (string-utf8 256)) 
    (author-principal principal) 
    (liked-txid (string-utf8 256)) 
    (mine-amounts (list 200 uint)) 
    (alt-origin (string-utf8 256))
    (ext (optional <derupt-ext-trait>)) 
    (extras (optional (list 10 
      {
        stringutf8: (optional (string-utf8 256)), 
        stringascii: (optional (string-ascii 256)), 
        uint: (optional uint), 
        int: (optional int), 
        principal: (optional principal), 
        bool: (optional bool),
        buff: (optional (buff 34)),
        proxy: (optional (buff 2048)),
        cryptocash-token-contract: (optional <cryptocash-token-trait>),
        cryptocash-core-contract: (optional <cryptocash-core-trait>),
        sip-009-contract: (optional <sip-009-trait>),
        sip-010-contract: (optional <sip-010-trait>),
        sip-013-contract: (optional <sip-013-trait>)
      }))
    )
    (cryptocash-token-contract <cryptocash-token-trait>)
    (cryptocash-core-contract <cryptocash-core-trait>)
    (core-contract <derupt-core-trait>)
    (like-ft-amount uint)
  )
  (let 
    (
      (tpi-values (unwrap! (contract-call? 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-interfaces get-token-interface alt-origin) ERR-NOTFOUND))
      ;; (tpi-values (unwrap! (contract-call? 'MAINNETADDRESS.derupt-interfaces get-token-interface alt-origin) ERR-NOTFOUND))
      (pay-dev (unwrap! (get pay-dev tpi-values) ERR-NOTFOUND)) 
      (pay-gaia (unwrap! (get pay-gaia tpi-values) ERR-NOTFOUND)) 
      (dev-stx-amount (unwrap! (get dev-stx-amount tpi-values) ERR-NOTFOUND)) 
      (gaia-stx-amount (unwrap! (get gaia-stx-amount tpi-values) ERR-NOTFOUND))
      (dev-ft-amount (unwrap! (get dev-ft-amount tpi-values) ERR-NOTFOUND)) 
      (gaia-ft-amount (unwrap! (get gaia-ft-amount tpi-values) ERR-NOTFOUND))
      (dev-principal  (get dev-principal tpi-values)) 
      (gaia-principal  (unwrap! (get gaia-principal tpi-values) ERR-NOTFOUND))
      (derupt-core-contract (unwrap! (get-derupt-core-contract) ERR-NOTFOUND))
      (like-ft-total like-ft-amount)
      (chime-stx-total (unwrap! (get-chime-stx-amount) ERR-NOTFOUND))
      (chime-ft-total (unwrap! (get-chime-ft-amount) ERR-NOTFOUND))
      (dev-stx-total dev-stx-amount)
      (gaia-stx-total gaia-stx-amount)
      (dev-ft-total dev-ft-amount)
      (gaia-ft-total gaia-ft-amount)
      (inputed-core-contract (contract-of core-contract))
    )
      (asserts! (is-eq tx-sender APP_USER) ERR-UNAUTHORIZED)      
      (asserts! (unwrap! (validate-core-contract inputed-core-contract) ERR-VALIDATION-FAILED) ERR-UNAUTHORIZED-CONTRACT)
      (try! (contract-call? core-contract favorable-reply-message content author-principal attachment-uri thumbnail-uri reply-to liked-txid mine-amounts alt-origin ext extras cryptocash-token-contract cryptocash-core-contract like-ft-amount pay-dev pay-gaia dev-stx-amount gaia-stx-amount dev-ft-amount gaia-ft-amount dev-principal (some gaia-principal)))
      (print 
        { 
          event: "favorable-reply-message", content: content, publisher: author-principal, attachment-uri: attachment-uri, thumbnail-uri: thumbnail-uri, reply-to: reply-to, 
          cryptocash-token-contract: cryptocash-token-contract,
          alt-origin: alt-origin, ext: ext,
          mine-total: (fold + mine-amounts u0),
          mine-amounts: mine-amounts,
          like-ft-total: like-ft-total,
          chime-stx-total: chime-stx-total,
          chime-ft-total: chime-ft-total,
          pay-dev: pay-dev,
          pay-gaia: pay-gaia,
          dev-stx-total: dev-stx-total, 
          gaia-stx-total: gaia-stx-total,
          dev-ft-total: dev-ft-total, 
          gaia-ft-total: gaia-ft-total,
          dev-principal: dev-principal, 
          gaia-principal: gaia-principal
        }
      )
      (ok true)
  )
)

;; User Operation Favorable Reply Message
(define-public (unfavorable-reply-message 
    (content (string-utf8 256)) 
    (attachment-uri (optional (string-utf8 256))) 
    (thumbnail-uri (optional (string-utf8 256))) 
    (reply-to (string-utf8 256)) 
    (author-principal principal) 
    (disliked-txid (string-utf8 256)) 
    (mine-amounts (list 200 uint))
    (alt-origin (string-utf8 256)) 
    (ext (optional <derupt-ext-trait>))
    (extras (optional (list 10 
      {
        stringutf8: (optional (string-utf8 256)), 
        stringascii: (optional (string-ascii 256)), 
        uint: (optional uint), 
        int: (optional int), 
        principal: (optional principal), 
        bool: (optional bool),
        buff: (optional (buff 34)),
        proxy: (optional (buff 2048)),
        cryptocash-token-contract: (optional <cryptocash-token-trait>),
        cryptocash-core-contract: (optional <cryptocash-core-trait>),
        sip-009-contract: (optional <sip-009-trait>),
        sip-010-contract: (optional <sip-010-trait>),
        sip-013-contract: (optional <sip-013-trait>)
      }))
    )
    (cryptocash-token-contract <cryptocash-token-trait>)
    (cryptocash-core-contract <cryptocash-core-trait>) 
    (core-contract <derupt-core-trait>)
    (dislike-ft-amount uint)
    (lockPeriod uint)
  )
  (let 
    (
      (tpi-values (unwrap! (contract-call? 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-interfaces get-token-interface alt-origin) ERR-NOTFOUND))
      ;; (tpi-values (unwrap! (contract-call? 'MAINNETADDRESS.derupt-interfaces get-token-interface alt-origin) ERR-NOTFOUND))
      (pay-dev (unwrap! (get pay-dev tpi-values) ERR-NOTFOUND)) 
      (pay-gaia (unwrap! (get pay-gaia tpi-values) ERR-NOTFOUND)) 
      (dev-stx-amount (unwrap! (get dev-stx-amount tpi-values) ERR-NOTFOUND)) 
      (gaia-stx-amount (unwrap! (get gaia-stx-amount tpi-values) ERR-NOTFOUND))
      (dev-ft-amount (unwrap! (get dev-ft-amount tpi-values) ERR-NOTFOUND)) 
      (gaia-ft-amount (unwrap! (get gaia-ft-amount tpi-values) ERR-NOTFOUND))
      (dev-principal  (get dev-principal tpi-values)) 
      (gaia-principal  (unwrap! (get gaia-principal tpi-values) ERR-NOTFOUND))
      (derupt-core-contract (unwrap! (get-derupt-core-contract) ERR-NOTFOUND))
      (dislike-ft-total dislike-ft-amount)
      (chime-stx-total (unwrap! (get-chime-stx-amount) ERR-NOTFOUND))
      (chime-ft-total (unwrap! (get-chime-ft-amount) ERR-NOTFOUND))
      (dev-stx-total dev-stx-amount)
      (gaia-stx-total gaia-stx-amount)
      (dev-ft-total dev-ft-amount)
      (gaia-ft-total gaia-ft-amount)
      (inputed-core-contract (contract-of core-contract))
    )
    (asserts! (is-eq tx-sender APP_USER) ERR-UNAUTHORIZED)
    (asserts! (unwrap! (validate-core-contract inputed-core-contract) ERR-VALIDATION-FAILED) ERR-UNAUTHORIZED-CONTRACT)     
    (try! (contract-call? core-contract unfavorable-reply-message content author-principal attachment-uri thumbnail-uri reply-to disliked-txid mine-amounts alt-origin ext extras cryptocash-token-contract cryptocash-core-contract dislike-ft-amount lockPeriod pay-dev pay-gaia dev-stx-amount gaia-stx-amount dev-ft-amount gaia-ft-amount dev-principal (some gaia-principal)))
    (print 
      { 
        event: "unfavorable-reply-message", content: content, publisher: author-principal, attachment-uri: attachment-uri, thumbnail-uri: thumbnail-uri, reply-to: reply-to, 
        cryptocash-token-contract: cryptocash-token-contract, 
        alt-origin: alt-origin, ext: ext,
        mine-total: (fold + mine-amounts u0),
        mine-amounts: mine-amounts,
        dislike-ft-total: dislike-ft-total,
        lockPeriod: lockPeriod,
        chime-stx-total: chime-stx-total,
        chime-ft-total: chime-ft-total,
        pay-dev: pay-dev,
        pay-gaia: pay-gaia,
        dev-stx-total: dev-stx-total, 
        gaia-stx-total: gaia-stx-total,
        dev-ft-total: dev-ft-total, 
        gaia-ft-total: gaia-ft-total,
        dev-principal: dev-principal, 
        gaia-principal: gaia-principal
      }
    )
    (ok true)
  )
)

(map-insert member-status APP_USER false)
```


# .derupt-ext

Developers can extend the functionality of Derupt by creating Extensions for user to use.

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

```
;; title: derupt-ext
;; version: 1.3.1
;; summary: Derupt Extension Contract (sample extension for reference)

;; Derupt Extension Example - Send passed amount of CC to passed principal
(impl-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-ext-trait.derupt-ext)

(use-trait cryptocash-token-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.cryptocash-token-trait.cryptocash-token)
(use-trait cryptocash-core-trait 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.cryptocash-core-trait.cryptocash-core)

(use-trait sip-009-trait-ft-standard 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-009-trait-nft-standard.sip-009-trait)
(use-trait sip-010-trait-ft-standard 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-010-trait-ft-standard.sip-010-trait)
(use-trait sip-013-trait-ft-standard 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.sip-013-trait-sft-standard.sip-013-trait)

;; Errors
(define-constant ERR-UNAUTHORIZED (err u100))
(define-constant ERR-NOTFOUND (err u101))
(define-constant ERR-WRONG-CC-TOKEN-VERSION (err u102))

(define-data-var ext-owner principal tx-sender)

(define-map ext-meta principal 
  { 
    name: (string-ascii 24),
    description: (string-ascii 256),
    image: (string-ascii 256)
  }
)

(define-read-only (get-ext-metadata) 
  (ok (unwrap! (map-get? ext-meta (var-get ext-owner)) ERR-NOTFOUND))
)

(define-public (update-ext-owner (new-ext-owner principal)) 
  (begin 
    (asserts! (is-eq tx-sender (var-get ext-owner)) ERR-UNAUTHORIZED)
    (asserts! (is-standard new-ext-owner) ERR-UNAUTHORIZED)
    (var-set ext-owner new-ext-owner)
    (print {prev-owner: tx-sender, new-owner: new-ext-owner})
    (ok true)
  )
)

(define-read-only (get-ext-owner) 
  (ok (var-get ext-owner))
)

(define-public (update-ext-metadata (name (optional (string-ascii 24))) (description (optional (string-ascii 256))) (image (optional (string-ascii 256)))) 
  (let 
    (
      (meta (map-get? ext-meta (var-get ext-owner)))
      (prev-name (unwrap! (get name meta) ERR-NOTFOUND))
      (prev-description (unwrap! description ERR-NOTFOUND))
      (prev-image (unwrap! image ERR-NOTFOUND))
    ) 
    (asserts! (is-eq tx-sender (var-get ext-owner)) ERR-UNAUTHORIZED)
    (match name value (map-set ext-meta (var-get ext-owner) {name: value, description: prev-description, image: prev-image}) false)
    (match description value (map-set ext-meta (var-get ext-owner) {name: prev-name, description: value, image: prev-image}) false)
    (match image value (map-set ext-meta (var-get ext-owner) {name: prev-name, description: prev-description, image: value}) false)
    (print { prev-name: prev-name, new-name: (unwrap! name ERR-NOTFOUND), prev-description: prev-description, description: (unwrap! description ERR-NOTFOUND), prev-image: prev-image, image: (unwrap! image ERR-NOTFOUND)})
    (ok true)
  )
)


;; Get derupt-core-contract - used to verify call origin
(define-private (get-derupt-core-contract)
  (contract-call? 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-feed get-derupt-core-contract) 
)

;; Get cc-token-contract - used to get active cc token contract
(define-private (get-cc-token-contract)
  (contract-call? 'ST1ZK4MRVTQQJMVAAJQWBV2WPQ87QV2851YCTHD7X.derupt-feed get-cc-token-contract) 
)

;; Transfer CryptoCash
(define-public (cryptocash-transfer (cc-token-contract <cryptocash-token-trait>) (amount uint) (recipient principal))
  (contract-call? cc-token-contract transfer amount tx-sender recipient none)
)

;; Execute Extension Function
(define-public (exec-ext-func 
    (extras (optional (list 10 
      {
        stringutf8: (optional (string-utf8 256)), 
        stringascii: (optional (string-ascii 256)), 
        uint: (optional uint), 
        int: (optional int), 
        principal: (optional principal), 
        bool: (optional bool),
        buff: (optional (buff 34)),
        proxy: (optional (buff 2048)),
        cryptocash-token-contract: (optional <cryptocash-token-trait>),
        cryptocash-core-contract: (optional <cryptocash-core-trait>),
        sip-009-contract: (optional <sip-009-trait>),
        sip-010-contract: (optional <sip-010-trait>),
        sip-013-contract: (optional <sip-013-trait>)
      }))
    )
  )
    (let
      ;;get and verify call is coming from current core.
      (
        (derupt-core-contract (unwrap! (get-derupt-core-contract) ERR-NOTFOUND))  
        (cc-token-address (unwrap! (get-cc-token-contract) ERR-WRONG-CC-TOKEN-VERSION)) 
        (cc-token-contract (unwrap! (get cryptocash-token-contract (element-at? (unwrap! extras ERR-NOTFOUND) u0)) ERR-NOTFOUND))  
        ;; Amount extraction from position x of expected tuple arguments
        (amount (unwrap! (unwrap! (get uint (element-at? (unwrap! extras ERR-NOTFOUND) u0)) ERR-NOTFOUND) ERR-NOTFOUND))  
        (recipient (unwrap! (unwrap! (get principal (element-at? (unwrap! extras ERR-NOTFOUND) u0)) ERR-NOTFOUND) ERR-NOTFOUND))  
      )
      (asserts! (is-eq contract-caller derupt-core-contract) ERR-UNAUTHORIZED)    
      (asserts! (is-eq (contract-of cc-token-contract) cc-token-address) ERR-NOTFOUND) 

      ;; perform cc transfer?
      (try! (cryptocash-transfer cc-token-contract amount recipient))

      ;; Print logging
      (print 
        { 
          event: "derupt-ext-message: Transfer CC Too", 
          tx-sender: tx-sender, 
          recipient: recipient,
          extras: extras,
          amount:amount
        }
      )
      (ok true)
    )
)

(map-insert ext-meta (var-get ext-owner) {name: "Transfer CC too", description: "Extension to Transfer an AMOUNT of CC to defined PRINCIPAL", image: "https://stackers.cc/cryptocash.png"})
```

## Extension Contract Metadata

The extension *contract metadata* represents the top level summary of the extension.

```json
{
  "name": "Transfer CC too",
  "description": "https://stackers.cc/derupt-ext-metadata.json",
  "image": "https://stackers.cc/more-cc.gif"
}
```

## Extension Description Metadata

The extension *description metadata* enables greater control over the integration and functionality of the Extension within the Derupt UX/UI, facilitating for you:

* Extension Information Summary (`info`):
  * A general Summary / Explanation of the Extension
* Availability for specific Core Operation (`ops`):
  * To enable use of the Extension by Derupt Core Operations
* Applicable Transaction Post Conditions (`postconditions`):
  * Set the appropriate type: `ft`, `nft`, and or `stx`
* Function Arguments from the User (`argsFromUser`)
  * To enable the applicable argument input fields to be rendered and supplied by the user. \
    (`render` set visibility of the argument input field to the user in the Extension options modal)\
    (`label` set the label you want to apply to the visible field)\
    (`order` set the rendered order of argument input fields)\
    (`optional` representative if input field is an optional input \[`false` means the argument input field is required, `true` means the argument input field is optional]) \
    \
    *Note: `argsFromUser` are passed as `extra` function arguments in core operation calls.*

```json
{
    "info": "Extension to Transfer a AMOUNT of CC to a PRINCIPAL (TESTNET)",
    "ops": {
        "send-message": false,
        "like-message": true,
        "dislike-message": true,
        "favorable-reply-message": true,
        "unfavorable-reply-message": true,
        "gift-message": true
    },
    "postconditions": [
        {
            "type": "ft",
            "contractAddress": "ST1ZK0A249B4SWAHVXD70R13P6B5HNKZAA0WNTJTR.cryptocash-token:cryptocash"
        }
    ],
    "argsFromUser": {
        "0": {
            "uint": {
                "render": true,
                "label": "Amount",
                "order": 0,
                "optional": false
            },
            "principal": {
                "render": true,
                "label": "Recipient Principal",
                "order": 1,
                "optional": false
            }
        }
    }
}
```

{% hint style="warning" %}
Extension Contract Metadata pointers is updated via `update-metadata`&#x20;
{% endhint %}

{% hint style="warning" %}
Extension Description Metadata is updated via `derupt-ext-metadata.json` \
(or equivalent)&#x20;
{% endhint %}

{% hint style="warning" %}
Extensions must follow[`.derupt-ext-trait`](/latest/contracts/.derupt-ext-trait) standard
{% endhint %}

{% hint style="warning" %}
Extension execution `exec-ext-func` function, taking `extras` as an argument. \
\
Developers should define`argsFromUser` to ensure specific fields are presented to the user during the presentation of `ExtensionModal` in order to collect users input if needed.
{% endhint %}

{% hint style="warning" %}
Users can have only 1 extension called, per core function call: eg

* can have 1 `ext` called during `send-message`
* can have 1 `ext` called during `like-message`&#x20;
* can have 1 `ext` called during `dislike-message`
* can have 1 `ext` called during `favorable-reply-message`
* can have 1 `ext` called during `unfavorable-reply-message`
* can have 1 `ext` called during `gift-message`

(note: users can change the enabled extension over time)
{% endhint %}


# API

Explore the documentation for Derupt Sentiment APIs


# Sentiment API Setup Guide

Setup a Derupt Sentiment API to calculate Message Like and Dislike counts.

This page is currently under development... check back soon.


# Sentiment API Endpoint

A singular end point that takes a 'txid' and 'who' as arguments.

## Get Sentiment of Message by Transaction ID.

## Get the Sentiment of a Derupt Message

<mark style="color:blue;">`GET`</mark> `https://sentiment.derupt.io/sentiment?txid={txid}&who={principal}`

Returns Sentiment of Derupt message, referenced by its Stacks Transaction `txid`

#### Path Parameters

| Name                                   | Type   | Description                                   |
| -------------------------------------- | ------ | --------------------------------------------- |
| txid<mark style="color:red;">\*</mark> | string | Stacks Transaction `txid` of message          |
| who<mark style="color:red;">\*</mark>  | string | Derupt Authenticated User `principal` address |

{% tabs %}
{% tab title="200 Returns Sentiment" %}

```javascript
{
    "txid": "0xef066bc2c49526f400e6269e7b547700e0b2ecd8f859ae3715623baa71f2f151",
    "likes": 1,
    "dislikes": 1,
    "replies": 0,
    "who": "SP261NT1ZC1JFX0JGFGKZM8AC8Q703MK1SP0X3S0W",
    "liked": true,
    "disliked": true,
    "replied": false
}
```

{% endtab %}

{% tab title="400: Bad Request Error in Request" %}

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Count Sums:** \
Likes and Dislikes are on chain, however the running sum total is calculated overtime off chain and served via APIs.&#x20;
{% endhint %}

{% hint style="warning" %}
**Count Validation Considerations:**&#x20;

* Verification of token transferred from Liker to Author is CryptoCash when Liking.
* Verification of token transferred from Liker to Author are different Addresses.
* Verification of token stacked from Disliker is CryptoCash when Disliking.&#x20;
* Verification of unique action per Message.(eg 1 Like & Dislike from 1 account address)
  {% endhint %}

{% hint style="info" %}
Want to learn how to setup your own Derupt Sentiment API Node? \
Check out the [**Sentiment API Setup Guide**](/latest/api/setup-guide)
{% endhint %}


# Clients

Derupt is permissionless, anyone can setup and run a client.

Derupt Client Repo (link to repo of `derupt-client` when launched)\
&#x20;\
Derupt can be ran locally, or on a server for your community to access.


# Features FAQ

Frequently Asked Questions about Derupt features.

#### **How does Derupt work with CryptoCash?**

<figure><img src="/files/ZchMXh2zcVt2wsbfRfRf" alt=""><figcaption><p>Mine as you Create, Transfer as you Like, Stack as you Dislike (Replies are combinations, depending on sentiment)</p></figcaption></figure>

#### **Where is the Content stored?**

Derupt Content is stored in a mix of on chain and off chain storage. (All requiring Stacks auth)<br>

#### **What Content is stored on chain?**&#x20;

Message Bodies are stored directly on chain (+all off chain URI's for attachments/thumbnails)<br>

#### **What Content is stored off chain?**

Attachments & Thumbnails are is stored in User specific Stacks GAIA Storages.<br>

#### **Where is the Sentiment stored?**

Derupt User Content Sentiment is stored directly onchain.<br>

#### **How is Sentiment calculated?**

Sentiment is stored onchain, however the running totals are calculated over time off chain and served in app via [Sentiment API Endpoints](/latest/api/sentiment-endpoint)


# Comparisons FAQ

How does Derupt Compare to X (Twitter), TikTok, or NOSTR?

#### **How does Derupt Content Monetization differ from other Platforms?**

<figure><img src="/files/QB2Dyfu5fVPTnGTq6hH8" alt=""><figcaption></figcaption></figure>

#### How does Derupt Content Moderation differ from other Platforms?

<figure><img src="/files/m5gKx5WYPOsAvSR3LeVJ" alt=""><figcaption></figcaption></figure>


# Contracts (legacy)

Explore the documentation for the Derupt Smart Contracts.

{% hint style="danger" %}
This is legacy documentation relative to Derupt contracts when using CityCoins prior to CCIP-020 shutting down CityCoins protocol. \
\
Refer to latest docs for newest implementation.
{% endhint %}

{% content-ref url="/pages/LL0tyCjND0jAEHGBdUnE" %}
[Testnet Addresses](/legacy/contracts-legacy/testnet)
{% endcontent-ref %}

{% content-ref url="/pages/fp3uovU0BS3DmYs5V4nd" %}
[Mainnet Addresses (older)](/legacy/contracts-legacy/mainnet-1)
{% endcontent-ref %}

{% content-ref url="/pages/QNi0aEZqnRbyu9bpGDKA" %}
[.derupt-interfaces](/legacy/contracts-legacy/.derupt-interfaces)
{% endcontent-ref %}

{% content-ref url="/pages/EWWHrFNwPHgS1F00Bx3Z" %}
[.derupt-core-trait](/legacy/contracts-legacy/.derupt-core-trait)
{% endcontent-ref %}

{% content-ref url="/pages/xvQAElX5bPz3DEwEvonk" %}
[.derupt-feed](/legacy/contracts-legacy/.derupt-feed)
{% endcontent-ref %}

{% content-ref url="/pages/YFAUQVBc8npXwk0u2E4n" %}
[.derupt-gifts](/legacy/contracts-legacy/.derupt-gifts)
{% endcontent-ref %}

{% content-ref url="/pages/wCRAZNd6LO1iePc3s5NW" %}
[.derupt-miners](/legacy/contracts-legacy/.derupt-miners)
{% endcontent-ref %}

{% content-ref url="/pages/MOYsrzPg5RLqwozqNkQv" %}
[.derupt-stackers](/legacy/contracts-legacy/.derupt-stackers)
{% endcontent-ref %}

{% content-ref url="/pages/lPto0ATKrW9xoQUHooag" %}
[.derupt-sentiment](/legacy/contracts-legacy/.derupt-sentiment)
{% endcontent-ref %}

{% content-ref url="/pages/5vTkr42yP6lMAtl9u8Ku" %}
[.derupt-core-yyyymmdd](/legacy/contracts-legacy/.derupt-core-yyyymmdd)
{% endcontent-ref %}

{% content-ref url="/pages/QAJOJbCb1lbWciIkevN9" %}
[.derupt-profile-trait](/legacy/contracts-legacy/.derupt-profile-trait)
{% endcontent-ref %}

{% content-ref url="/pages/CoEh2otLAJINORJMaK8w" %}
[.derupt-profiles](/legacy/contracts-legacy/.derupt-profiles)
{% endcontent-ref %}

{% content-ref url="/pages/OKIlwBiIKdXqDxaFE8NE" %}
[.derupt-profile](/legacy/contracts-legacy/.derupt-profile)
{% endcontent-ref %}


# Testnet Addresses

Deployed by ST4YQYP4NGYAWFA6Z2FDPHBJ2DEM4FEEJPDVFT45

**View Derupt (legacy) Testnet Contracts on Explorer:**

* [.derupt-interfaces](https://explorer.hiro.so/txid/0x9162f79083b190d52463ac15976c0bd5015784e040dd53258051755bf64ef4c1?chain=testnet)
* [.derupt-core-trait](https://explorer.hiro.so/txid/0x66b9cc60fc6e6bd8e70c808e701cbd042e9a440e0c1d7ded96ac86a025c014b4?chain=testnet)
* [.derupt-feed](https://explorer.hiro.so/txid/0x31a575f4eb6a8bcbfa06bcaae3dcb4ac92b4f05c509d8f0e860cca56b7d1b6ae?chain=testnet)
* [.derupt-gifts](https://explorer.hiro.so/txid/0x6dd05f110987b7dcbfab8fd9f77bbd05bfec66740ef9c7fc2fcb019b67ebbe5e?chain=testnet)
* [.derupt-miners](https://explorer.hiro.so/txid/0x9a4892953f55adabd093164c9c3ce08b8667df0723d639a5f60220000d3be366?chain=testnet)
* [.derupt-stackers](https://explorer.hiro.so/txid/0xb0b5ae12cbecb723d60b143f6106911296c3c24d6cf0f0123924f221ec67b9bd?chain=testnet)
* [.derupt-sentiment](https://explorer.hiro.so/txid/0x6d2361b61b095b83fe414e59e471a391f1bbbe3b738379e586722b4249c372bf?chain=testnet)
* [.derupt-core-20240222](https://explorer.hiro.so/txid/0xef488fe8aa4a1359cc8d80330e88f430c1897ca1733029b0876f74e5f3146fcb?chain=testnet)
* [.derupt-profile-trait](https://explorer.hiro.so/txid/0xf9d7f9d0371634691a068d68097983a0424e89ba88e8a11f2da0c5692553c884?chain=testnet)
* [.derupt-profiles](https://explorer.hiro.so/txid/0x3d30a405d939aa9dda96de6d31559b5d8bf8ef74d8bb4f7c9e54c8cc9c8d80da?chain=testnet)
* .derupt-profile (deployed by user's)
  * [sample user A](https://explorer.hiro.so/txid/0xc5d618dd64dccd43609ed49fd06f3037666de668a43d2ad8a03037bebbe15671?chain=testnet)
  * [sample user B](https://explorer.hiro.so/txid/0x06d210fde73846ce5f3eddb6ed31572a516e709a422c35dc7e2e6fc064efcc43?chain=testnet)

{% hint style="info" %}
Users **Deploy** and **Activate** their .derupt-profile contract **in app**.
{% endhint %}


# Testnet Addresses (broken)

Deployed by ST3HNWNVVCP31S8CVQCD8WDVFXZJGKFP8VVGKVENW

**View Derupt (broken) Nakamoto Testnet Contracts on Explorer:**

* [.derupt-ext-trait](https://explorer.hiro.so/txid/0xa16a4844fc4db90d537c364797c18ed346f3bc076ab0a5d2949439b6140d7c28?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-interfaces](https://explorer.hiro.so/txid/0x0d765145c9d7ace274858497a17448a34031da7315c14b56858bc93425668543?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-core-trait](https://explorer.hiro.so/txid/0xb4d0a4977ce309084b74a527c0d2cb7df1ad1e55af20b6294b60cd11dbdd1a1f?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-feed](https://explorer.hiro.so/txid/0xd2b2393154692409989570a76f6b4dc3c6825aaa133b5773ee776ca63e6ae836?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-gifts](https://explorer.hiro.so/txid/0x092157d0d832691a38577bc7d8a80dd91117c075cd9dbd242cc9a13ac8f130eb?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-miners](https://explorer.hiro.so/txid/0x83b420d42eda2feaaa114cf6d2f76b004122e208d7f3d8680f7ee2c3ac41347d?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-stackers](https://explorer.hiro.so/txid/0x16df06492b0b5515988f1d2117ffcff713132b864aa5892817324b9732c837e5?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-sentiment](https://explorer.hiro.so/txid/0xefb0178f25611ec87f7901ed79f91acf6d015f75528afcb2d5976c275bfa8370?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-core-20241003](https://explorer.hiro.so/txid/0x1920bcfdcb1cc0e8e02b48a7f73d1a47a672af27e44d8125956e8e39dbb87f84?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-profile-trait](https://explorer.hiro.so/txid/0xc5c1c1d540e4d4bd58d6518632f279839ac202b2691956abfdfc663986710d37?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-profiles](https://explorer.hiro.so/txid/0xf785a9900023f190077b9163f4442f413fada9cde0cf2f57b09c3b7eed05dd54?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* .derupt-profile (deployed by user's)
  * [example user A](https://explorer.hiro.so/txid/STWPZJFBEWSV74NZ62R1SGFBQ6DYQ0VMFW43JRRQ.derupt-profile?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
  * example user B
* [.derupt-ext-reg](https://explorer.hiro.so/txid/0xac7399aeca5a6fa74ed54be22c452bd0c696227e605bd0ee5e08daa09808ef04?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* .derupt-ext (deployed by dev's)
  * [example ext A ](https://explorer.hiro.so/txid/0x36f108c956d7c5297f4d87f41e532118329d9db3f47e67da115032c9c015b1cd?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)(sample: "Transfer CC Too")&#x20;
  * example ext B

{% hint style="info" %}
Users Deploy and Activate their .derupt-profile contract in app.
{% endhint %}

{% hint style="info" %}
Developers Deploy .derupt-ext contract(s) and they are Enabled for use by Users in app.
{% endhint %}

{% hint style="info" %}
Additionally you may want to review the [Deruptars NFT Contract](https://explorer.hiro.so/txid/STVG43BSMRD85XJSRPFJKR2BPMMZNP3XBSCMZC6T.deruptars?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
{% endhint %}


# Testnet Addresses (nakamoto)

Deployed by ST1ZK0A249B4SWAHVXD70R13P6B5HNKZAA0WNTJTR

**View Derupt (deprecated) Nakamoto Testnet Contracts on Explorer:**

* [.derupt-ext-trait](https://explorer.hiro.so/txid/0x41301726180c49eb8d9c9756a0471b4d8dc60a47bd7493822a705116da8a2889?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-interfaces](https://explorer.hiro.so/txid/0xef36d812a6422922996941f88345ba68c230299aa92af9167d6894b338eedf3e?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-core-trait](https://explorer.hiro.so/txid/0x2df775201c81c032e23d9321b5f701b432f21fe28a023bddb9215499728738e2?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-feed](https://explorer.hiro.so/txid/0x1f6c861cef18f2b532328cf7edddb05f237119b580ac8bcc4c50349dad077637?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-gifts](https://explorer.hiro.so/txid/0x04c9178134afc4f3a8c51fd1d766dc7272c0f0fed8b11ea66462ac0940f9cfcf?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-miners](https://explorer.hiro.so/txid/0x857326a562b8293ad67af89ebf0d2819780711670177c447b32a53f23eb422a3?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-stackers](https://explorer.hiro.so/txid/0x3e6c1fd99ae7878b02a281371ac112b84ac27d3c337b319efe59bc9a6ccb24c9?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-sentiment](https://explorer.hiro.so/txid/0x05fd7bf499b7315356bce16c2bd3eda4b9c0e471fe7c344af6fc9ec1cff42436?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-core-20240610](https://explorer.hiro.so/txid/0xba9fc349a9a4640734c016b9fe0fc824d546ea2b4df59ecd3e06af104046bc09?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-profile-trait](https://explorer.hiro.so/txid/0x3cdce3f5138444dcdfd50d810e21fe6ce0512556138fb1d823076e0eda21742d?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-profiles](https://explorer.hiro.so/txid/0xf040ba184f2a136c26105e565dedd7c064cbd93a8c012d2314f7847d09577071?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* .derupt-profile (deployed by user's)
  * [example user A](https://explorer.hiro.so/txid/0xfba955d7666c68fb857034f37a65d4afd40a457dc3276c82380b457a3bf26402?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
  * [example user B](https://explorer.hiro.so/txid/0xa076597272eb8ada0b2e0407bec99298ca37371827dabcc77f90567062abe4ad?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* [.derupt-ext-reg](https://explorer.hiro.so/txid/0x968175ccef754791727ea7432f957bcfe54d2473269eb2875593b3c3303fccf4?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
* .derupt-ext (deployed by dev's)
  * [example ext A](https://explorer.hiro.so/txid/0x925449a15e8529421ae52494c97ab90df4c7850cdea8844a35abedad664e43f4?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so) (sample: "Transfer CC Too")&#x20;
  * example ext B

{% hint style="info" %}
Users Deploy and Activate their .derupt-profile contract in app.
{% endhint %}

{% hint style="info" %}
Developers Deploy .derupt-ext contract(s) and they are Enabled for use by Users in app.
{% endhint %}

{% hint style="info" %}
Additionally you may want to review the [Deruptars NFT Contract](https://explorer.hiro.so/txid/STVG43BSMRD85XJSRPFJKR2BPMMZNP3XBSCMZC6T.deruptars?chain=testnet\&api=https://api.nakamoto.testnet.hiro.so)
{% endhint %}


# Mainnet Addresses (old)

Deployed by SP7MKPEA5DVQQ1PQNYPC1P5YRF14CY3CWZF70R01

**View Derupt Mainnet Contracts on Explorer:**

* [.derupt-ext-trait](https://explorer.hiro.so/txid/0x4b99355f19559cc9d88cb644d0fd73f257532d095d0da06bc9cb8cffec7bb4e5?chain=mainnet)
* [.derupt-interfaces](https://explorer.hiro.so/txid/0xb7d76fa22c36418211671517c8dea31751f12b74aad150ae17933a1e0dd5df3d?chain=mainnet)
* [.derupt-core-trait](https://explorer.hiro.so/txid/0x8649cc07d5873a0f0117f78db100a7010a4840c256c35ac941b143460fa14849?chain=mainnet)
* [.derupt-feed](https://explorer.hiro.so/txid/0x574e6a1cfdf376ac4d1c7a5653f273cb5f30b8a2000208b6d2b85db952b66b31?chain=mainnet)
* [.derupt-gifts](https://explorer.hiro.so/txid/0xcf37f07f4e2d963ca3ccee7f4b343041da5e110f3ede7e4af9467255523230d3?chain=mainnet)
* [.derupt-miners](https://explorer.hiro.so/txid/0x58febd212dec2a94d0fc6f58368bca1692757b02b06b539bea5c6567f245b53b?chain=mainnet)
* [.derupt-stackers](https://explorer.hiro.so/txid/0x57f53adfc5089288fb529e549b46a4aa10d6e154ebfeb85ea13cde59c51c40ce?chain=mainnet)
* [.derupt-sentiment](https://explorer.hiro.so/txid/0x27771d1586354a5db8c0c35cd757cacc0a01bae11b87b7a96442dacfab5246dd?chain=mainnet)
* [.derupt-core-20240826](https://explorer.hiro.so/txid/0x4d2a80b86ba568238b5581fbacb072fa6c2d909f1b58280a856c2733013935a7?chain=mainnet)
* [.derupt-profile-trait](https://explorer.hiro.so/txid/0x0489411a2e5a2b364ab3c313a9b471fdc4bdb8e18501475d5841eafde8b4e2d8?chain=mainnet)
* [.derupt-profiles](https://explorer.hiro.so/txid/0x48c775c638ca0c49d3dca243c76114a64ad7ae526d445b7beb4345ab3dda3416?chain=mainnet)
* .derupt-profile (deployed by user's)
  * example user A
  * example user B
* .derupt-ext-reg
* .derupt-ext (deployed by dev's)
  * example ext A
  * example ext B

{% hint style="info" %}
Users Deploy and Activate their .derupt-profile contract in app.
{% endhint %}

{% hint style="info" %}
Developers Deploy .derupt-ext contract(s) and they are Enabled for use by Users in app.
{% endhint %}

{% hint style="info" %}
Additionally you may want to review the [Deruptars NFT Contract](https://explorer.hiro.so/txid/SP2KAF9RF86PVX3NEE27DFV1CQX0T4WGR41X3S45C.deruptars?chain=mainnet)
{% endhint %}


# Mainnet Addresses (older)

Deployed by SP3VTSYAD7E789BJA2BAX93PYFFZFVK1H39X5D8YS

**View Derupt (legacy) Mainnet Contracts on Explorer:**

* [.derupt-interfaces](https://explorer.hiro.so/txid/0xbf11009ee7535c83869b3be797aa495f39d8a60c946104c663e62497fff56c74?chain=mainnet)
* [.derupt-core-trait](https://explorer.hiro.so/txid/0x43d451404dd65f2259ad0096c4b43864bf9f340a20d5d3ee0599cd3e2da5daa9?chain=mainnet)
* [.derupt-feed](https://explorer.hiro.so/txid/0xd1f6891fb17eedc43680ace1e8249b4e6185201ed6b7d6add07823ef9bd11ca2?chain=mainnet)
* [.derupt-gifts](https://explorer.hiro.so/txid/0xbb270575442f999cef63d2d52a4e7a05d3bc4adb3cc7c00b238c4d2c982a1a3d?chain=mainnet)
* [.derupt-miners](https://explorer.hiro.so/txid/0x03e1cf5a0ad61a5d2ab3bc1f32533b87f2a1269cb425c7250a38e1e9ba6d58d9?chain=mainnet)
* [.derupt-stackers](https://explorer.hiro.so/txid/0xe943bd3d19002bd42fe593c11f4e537b5a2b519f0d85e2e8709f29bcb60af907?chain=mainnet)
* [.derupt-sentiment](https://explorer.hiro.so/txid/0xf2b064f4670153e9f2daa73df292d61c5ce4d7369911f1df9a29247a17e445f5?chain=mainnet)
* [.derupt-core-20240227](https://explorer.hiro.so/txid/0x657ae04ac962768f710696dbbf3ed9543264ae4e6de584dc4d0deab9b03e6c1e?chain=mainnet)
* [.derupt-profile-trait](https://explorer.hiro.so/txid/0xddcaa9cfbe60f6fac5adcf2441f4f66bdaf0b1efa0bb212d65b17f3bd84132a9?chain=mainnet)
* [.derupt-profiles](https://explorer.hiro.so/txid/0xcabaa3fdcef227743a79cd92c93b2fada4be5750b0cb1b4b40b0f0d68a4adb27?chain=mainnet)
* .derupt-profile (deployed by user's)
  * [sample user A](https://explorer.hiro.so/txid/SP1NNJSHTNQ551JNJB79YVNY16EW9AW50YF60AREW.derupt-profile?chain=mainnet)
  * [sample user B](https://explorer.hiro.so/txid/0x4053c14af40e2b5d64c6d13845f0b21f8fa6fdc04a98cc9d290fdf11863721fe?chain=mainnet)

{% hint style="info" %}
Users **Deploy** and **Activate** their .derupt-profile contract **in app**.
{% endhint %}


# .derupt-interfaces

Derupt Developers use Derupt Interface NFT's to configure their pay out details.

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 %}


# .derupt-core-trait

Each core trait plays a vital role in facilitating interactions between users.

{% hint style="info" %}
**Core Traits**

* `gift-message`: to send Gifts providing the necessary token inputs.
* `send-message`: to send a Message that supports optional arguments.
* `like-message`: to express appreciation for a Message by Liking it.
* `dislike-message`: to express disapproval for a Message by Disliking it.
* `favorable-reply-message`: to send a favorable Reply, supports optional arguments.
* `unfavorable-reply-message`: to send a unfavorable Reply, supports optional arguments.
  {% endhint %}


# .derupt-feed

All .derupt-profile contract message calls are logged in .derupt-feed

**The following function is only callable by .derupt-core-yyyymmdd:**

* log-send-message

{% hint style="info" %}
**About Messages**: log-send-message is only callable by the current .derupt-core-yyyymmdd contract.  \
*(To prove messages in a transparent order of operations, so that developers have consistent data for presentation across all potential user interfaces)*
{% endhint %}

{% hint style="info" %}
**About Replies:** log-send-message include Reply Messages as inferred by the inclusion of a `reply-to` transaction id argument.\
(The log-send-message function logs send-message calls received from core) \
(The core wraps replies functions as send-message function calls)
{% endhint %}


# .derupt-gifts

All .derupt-profile contract gifting are logged in .derupt-gifts

**The following function calls are only callable by .derupt-core-yyyymmdd:**

* log-gift


# .derupt-miners

All .derupt-profile contract mining actions are logged in .derupt-miners

**The following function calls are only callable by .derupt-core-yyyymmdd:**

* log-mine
* log-mining-claim-reward


# .derupt-stackers

All .derupt-profile contract stacking actions are logged in .derupt-stackers

**The following function calls are only callable by .derupt-core-yyyymmdd:**

* log-stack
* log-stacking-claim-reward


# .derupt-sentiment

All .derupt-profile contract sentiments are logged in .derupt-sentiments

**The following function calls are only callable by .derupt-core-yyyymmdd:**

* log-like-message
* log-dislike-message


# .derupt-core-yyyymmdd

Users call their own .derupt-profile which then calls .derupt-core-yyyymmdd

{% hint style="info" %}
The core maybe require or receive upgrades/updates from time to time, for that we follow a simple date based naming convention to track versions. &#x20;
{% endhint %}

{% hint style="info" %}
**General:**

* **.derupt-core-yyyymmdd** contract is for handling public message & action logic.&#x20;
* **.derupt-core-yyyymmdd** contract receives calls from **.derupt-profile** contracts and proceeds to process them accordingly.
  {% endhint %}

{% hint style="warning" %}
**Warning:**

* **users should deploy a** `.derupt-profile`contract in app before using core features.
* **users should call**`.derupt-profile`
* **users should not call**`.derupt-core-yyyymmdd (nor logging contracts)`
  {% endhint %}

{% hint style="info" %}
**Functions Process Transactions Overview:**

What happens in a process depends on the function the user is calling.&#x20;

* **send-message**: mine-citycoin is called during this process.&#x20;
* **like-message**: transfer-citycoin is called during this process.
* **dislike-message**: stack-citycoin is called during this process.
* **favorable-reply-message**: mine-citycoin & transfer-citycoin is called during this process.
* **unfavorable-reply-message**: mine-citycoin & stack-citycoin is called during this process.&#x20;
  {% endhint %}

The five core functions and arguments in the `.derupt-core-yyyymmdd` contract:

<details>

<summary><mark style="color:orange;">send-message</mark> </summary>

<mark style="color:orange;">Broadcast Send Message to the Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\)`.derupt-profile`\
2\)`.derupt-core-yyyymmdd` \
3\)`.derupt-feed (&.derupt-miners)`

**Arguments:**

* content
  * required || string-utf8 || Max: 256 || *Message Body*
* attachment-uri
  * optional || string-utf8 || Max: 256 || *Message Attachment* \
    *(example: 'bns\://1679121920338.mp3')*
* thumbnail-uri
  * optional || string-utf8 || Max: 256 || *Attachment Preview* \
    *(example: 'bns\://1679121920589.png')*
* reply-to
  * optional || string-utf8 || Max: 256 || *Stacks Transaction ID*
* cityName
  * required || string-ascii || Max: 10 || *Example: 'mia' or 'nyc'*
* alt-origin
  * required || string-utf8 || Max: 256 || *Alternative Origin*
* extras
  * optional || tuple || Max: 256 (per) || *10 Additional Arguments*&#x20;

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>

<details>

<summary><mark style="color:orange;">like-message</mark></summary>

<mark style="color:orange;">Broadcast Like Message to Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\) `.derupt-profile`\
2\) `.derupt-core-yyyymmdd` \
3\) `.derupt-sentiment`

**Arguments:**

* author-principal
  * required || principal || principal || *The Liked Message Author Principal*
* liked-txid
  * required || string-utf8 || Max: 256 || *Stacks Transaction ID (of Liked Message)*
* contractId
  * required || trait\_reference || trait\_reference || *CityCoin Contract Reference*&#x20;

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>

<details>

<summary><mark style="color:orange;">dislike-message</mark></summary>

<mark style="color:orange;">Broadcast Dislike Message to Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\) `.derupt-profile`\
2\) `.derupt-core-yyyymmdd` \
3\) `.derupt-sentiment (&.derupt-stackers)`

**Arguments:**

* author-principal
  * required || principal || principal || *The Liked Message Author Principal*
* disliked-txid
  * required || string-utf8 || Max: 256 || *Stacks Transaction ID (of Disliked Message)*
* cityName
  * required || string-ascii || Max: 10 || *Example: 'mia' or 'nyc'*
* contractId
  * required || trait\_reference || trait\_reference || *CityCoin Contract Reference*

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>

<details>

<summary><mark style="color:orange;">favorable-reply-message</mark></summary>

<mark style="color:orange;">Broadcast Favorable Reply Message to Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\) `.derupt-profile`\
2\) `.derupt-core-yyyymmdd` \
3\) `.derupt-feed (&.derupt-sentiment &.derupt-miners)`

**Arguments:**

* content
  * required || string-utf8 || Max: 256 || *Message Body*
* author-principal
  * required || principal || principal || *The Liked Message Author Principal*
* attachment-uri
  * optional || string-utf8 || Max: 256 || *Message Attachment* \
    *(example: 'bns\://1679121920338.mp3')*
* thumbnail-uri
  * optional || string-utf8 || Max: 256 || *Attachment Preview* \
    *(example: 'bns\://1679121920589.png')*
* reply-to
  * optional || string-utf8 || Max: 256 || *Stacks Transaction ID*
* liked-txid
  * required || string-utf8 || Max: 256 || *Stacks Transaction ID (of Liked Message)*
* cityName
  * required || string-ascii || Max: 10 || *Example: 'mia' or 'nyc'*
* alt-origin
  * required || string-utf8 || Max: 256 || *Alternative Origin*
* contractId
  * required || trait\_reference || trait\_reference || *CityCoin Contract Reference*
* extras
  * optional || tuple || Max: 256 (per) || *10 Additional Arguments*

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>

<details>

<summary><mark style="color:orange;">unfavorable-reply-message</mark></summary>

<mark style="color:orange;">Broadcast Unfavorable Reply Message to Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\) `.derupt-profile`\
2\) `.derupt-core-yyyymmdd` \
3\) `.derupt-feed (&.derupt-sentiment &.derupt-miners &.derupt-stackers)`

**Arguments:**

* content
  * required || string-utf8 || Max: 256 || *Message Body*
* author-principal
  * required || principal || principal || *The Liked Message Author Principal*
* attachment-uri
  * optional || string-utf8 || Max: 256 || *Message Attachment*
* thumbnail-uri
  * optional || string-utf8 || Max: 256 || *Attachment Preview*
* reply-to
  * optional || string-utf8 || Max: 256 || *Stacks Transaction ID*
* disliked-txid
  * required || string-utf8 || Max: 256 || *Stacks Transaction ID (of Disliked Message)*
* cityName
  * required || string-ascii || Max: 10 || *Example: 'mia' or 'nyc'*
* contractId
  * required || trait\_reference || trait\_reference || *CityCoin Contract Reference*
* alt-origin
  * required || string-utf8 || Max: 256 || *Alternative Origin*
* extras
  * optional || tuple || Max: 256 (per) || *10 Additional Arguments*

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>


# .derupt-profile-trait

Profile traits plays a vital role in facilitating interactions between Derupt users.

{% hint style="info" %}
**User Traits**

* `registration-activation`: to register user contracts as members.
* `get-activation-status`: to get a user contract member status.
* `send-message`: to send a Message that supports optional arguments.
* `like-message`: to express appreciation for a Message by Liking it.
* `dislike-message`: to express disapproval for a Message by Disliking it.
* `favorable-reply-message`: to send a favorable Reply, supports optional arguments.
* `unfavorable-reply-message`: to send a unfavorable Reply, supports optional arguments.
  {% endhint %}


# .derupt-profiles

All .derupt-profile contract activations are logged in .derupt-profiles contract

**The following function call is only only callable by .derupt-profile:**

* activate-member

{% hint style="info" %}
**General:**

* The **.derupt-profiles** contract is for logging user contract activations.
  {% endhint %}

{% hint style="warning" %}
**Warning:**

* **users should deploy a** `.derupt-profile` contract in app to interact with core features.
* **users should call**`.derupt-profile`&#x20;
* **users should not call**`.derupt-core-yyyymmdd (nor logging contracts)`
  {% endhint %}

In should be noted, users deploy their `.derupt-profile` contracts to Stacks Mainnet, then their Activation is what is logged in `.derupt-profiles`  events


# .derupt-profile

Derupt users need their own .derupt-profile contract on Stacks Mainnet. (deployed & activated in app)

{% hint style="info" %}
**General:**

* A distinct **.derupt-profile** contract should be deployed and activated per user.&#x20;
* **.derupt-profile** contract calls the **.derupt-core-yyyymmdd** contract for application logic purposes
  {% endhint %}

{% hint style="warning" %}
**Warning:**

* **users should deploy a** `.derupt-profile`contract in app to interact with core features.
* **users should call**`.derupt-profile`
* **users should not call**`.derupt-core-yyyymmdd (nor logging contracts)`
  {% endhint %}

{% hint style="info" %}
**Functions Process Transactions Overview:**

What happens in a process depends on the function the user is calling.&#x20;

* **send-message**: mine-citycoin is called during this process.
* **like-message**: transfer-citycoin is called during this process.
* **dislike-message**: stack-citycoin is called during this process.
* **favorable-reply-message**: mine-citycoin & transfer-citycoin is called during this process.
* **unfavorable-reply-message**: mine-citycoin & stack-citycoin is called during this process.&#x20;
  {% endhint %}

The five main functions and arguments in a `.derupt-profile`contract:

<details>

<summary><mark style="color:orange;">send-message</mark> </summary>

<mark style="color:orange;">Broadcast Send Message to the Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\)`.derupt-profile`\
2\)`.derupt-core-yyyymmdd` \
3\)`.derupt-feed (&.derupt-miners)`

**Arguments:**

* content
  * required || string-utf8 || Max: 256 || *Message Body*
* attachment-uri
  * optional || string-utf8 || Max: 256 || *Message Attachment* \
    *(example: 'bns\://1679121920338.mp3')*
* thumbnail-uri
  * optional || string-utf8 || Max: 256 || *Attachment Preview* \
    *(example: 'bns\://1679121920589.png')*
* reply-to
  * optional || string-utf8 || Max: 256 || *Stacks Transaction ID*
* cityName
  * required || string-ascii || Max: 10 || *Example: 'mia' or 'nyc'*
* alt-origin
  * required || string-utf8 || Max: 256 || *Alternative Origin*
* extras
  * optional || tuple || Max: 256 (per) || *10 Additional Arguments*&#x20;
* core-contract
  * required || trait\_reference || trait\_reference || *Derupt Core Contract Reference*&#x20;

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>

<details>

<summary><mark style="color:orange;">like-message</mark></summary>

<mark style="color:orange;">Broadcast Like Message to Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\) `.derupt-profile`\
2\) `.derupt-core-yyyymmdd` \
3\) `.derupt-sentiments`

**Arguments:**

* author-principal
  * required || principal || principal || *The Liked Message Author Principal*
* liked-txid
  * required || string-utf8 || Max: 256 || *Stacks Transaction ID (of Liked Message)*
* contractId
  * required || trait\_reference || trait\_reference || *CityCoin Contract Reference*
* core-contract
  * required || trait\_reference || trait\_reference || *Derupt Core Contract Reference*&#x20;

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>

<details>

<summary><mark style="color:orange;">dislike-message</mark></summary>

<mark style="color:orange;">Broadcast Dislike Message to Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\) `.derupt-profile`\
2\) `.derupt-core-yyyymmdd` \
3\) `.derupt-sentiments (&.derupt-stackers)`

**Arguments:**

* author-principal
  * required || principal || principal || *The Liked Message Author Principal*
* disliked-txid
  * required || string-utf8 || Max: 256 || *Stacks Transaction ID (of Disliked Message)*
* cityName
  * required || string-ascii || Max: 10 || *Example: 'mia' or 'nyc'*
* contractId
  * required || trait\_reference || trait\_reference || *CityCoin Contract Reference*
* core-contract
  * required || trait\_reference || trait\_reference || *Derupt Core Contract Reference*&#x20;

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>

<details>

<summary><mark style="color:orange;">favorable-reply-message</mark></summary>

<mark style="color:orange;">Broadcast Favorable Reply Message to Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\) `.derupt-profile`\
2\) `.derupt-core-yyyymmdd` \
3\) `.derupt-feed (&.derupt-sentiments &.derupt-miners)`

**Arguments:**

* content
  * required || string-utf8 || Max: 256 || *Message Body*
* attachment-uri
  * optional || string-utf8 || Max: 256 || *Message Attachment* \
    *(example: 'bns\://1679121920338.mp3')*
* thumbnail-uri
  * optional || string-utf8 || Max: 256 || *Attachment Preview* \
    *(example: 'bns\://1679121920589.png')*
* reply-to
  * optional || string-utf8 || Max: 256 || *Stacks Transaction ID*
* author-principal
  * required || principal || principal || *The Liked Message Author Principal*
* liked-txid
  * required || string-utf8 || Max: 256 || *Stacks Transaction ID (of Liked Message)*
* cityName
  * required || string-ascii || Max: 10 || *Example: 'mia' or 'nyc'*
* alt-origin
  * required || string-utf8 || Max: 256 || *Alternative Origin*
* extras
  * optional || tuple || Max: 256 (per) || *10 Additional Arguments*
* contractId
  * required || trait\_reference || trait\_reference || *CityCoin Contract Reference*
* core-contract
  * required || trait\_reference || trait\_reference || Derupt Core Contract Reference

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>

<details>

<summary><mark style="color:orange;">unfavorable-reply-message</mark></summary>

<mark style="color:orange;">Broadcast Unfavorable Reply Message to Stacks Blockchain</mark>

**Data Flow of the Function:**\
1\) `.derupt-profile`\
2\) `.derupt-core-yyyymmdd` \
3\) `.derupt-feed (&.derupt-sentiments &.derupt-miners &.derupt-stackers)`

**Arguments:**

* content
  * required || string-utf8 || Max: 256 || *Message Body*
* attachment-uri
  * optional || string-utf8 || Max: 256 || *Message Attachment* \
    *(example: 'bns\://1679121920338.mp3')*
* thumbnail-uri
  * optional || string-utf8 || Max: 256 || *Attachment Preview* \
    *(example: 'bns\://1679121920589.png')*
* reply-to
  * optional || string-utf8 || Max: 256 || *Stacks Transaction ID*
* author-principal
  * required || principal || principal || *The Liked Message Author Principal*
* disliked-txid
  * required || string-utf8 || Max: 256 || *Stacks Transaction ID (of Disliked Message)*
* cityName
  * required || string-ascii || Max: 10 || *Example: 'mia' or 'nyc'*
* alt-origin
  * required || string-utf8 || Max: 256 || *Alternative Origin*
* extras
  * optional || tuple || Max: 256 (per) || *10 Additional Arguments*
* contractId
  * required || trait\_reference || trait\_reference || *CityCoin Contract Reference*
* core-contract
  * required || trait\_reference || trait\_reference || Derupt Core Contract Reference

**Responses:**

* Successful Stacks Transaction
* Unsuccessful Stacks Transaction

</details>


# API (legacy)

Explore the documentation for Derupt Sentiment APIs


# Sentiment API Setup Guide

Setup a Derupt Sentiment API to calculate Message Like and Dislike counts.

This page is currently under development... check back soon.


# Sentiment API Endpoint

A singular end point that takes a 'txid' and 'who' as arguments.

## Get Sentiment of Message by Transaction ID.

## Get the Sentiment of a Derupt Message

<mark style="color:blue;">`GET`</mark> `https://sentiment.derupt.io/sentiment?txid={txid}&who={principal}`

Returns Sentiment of Derupt message, referenced by its Stacks Transaction `txid`

#### Path Parameters

| Name                                   | Type   | Description                                   |
| -------------------------------------- | ------ | --------------------------------------------- |
| txid<mark style="color:red;">\*</mark> | string | Stacks Transaction `txid` of message          |
| who<mark style="color:red;">\*</mark>  | string | Derupt Authenticated User `principal` address |

{% tabs %}
{% tab title="200 Returns Sentiment" %}

```javascript
{
    "txid": "0xef066bc2c49526f400e6269e7b547700e0b2ecd8f859ae3715623baa71f2f151",
    "likes": 1,
    "dislikes": 1,
    "replies": 0,
    "who": "SP261NT1ZC1JFX0JGFGKZM8AC8Q703MK1SP0X3S0W",
    "liked": true,
    "disliked": true,
    "replied": false
}
```

{% endtab %}

{% tab title="400: Bad Request Error in Request" %}

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Count Sums:** \
Likes and Dislikes are on chain, however the running sum total is calculated overtime off chain and served via APIs.&#x20;
{% endhint %}

{% hint style="warning" %}
**Count Validation Considerations:**&#x20;

* Verification of token transferred from Liker to Author is CityCoin when Liking.
* Verification of token transferred from Liker to Author are different Addresses.
* Verification of token stacked from Disliker is CityCoin when Disliking.&#x20;
* Verification of unique action per Message.(eg 1 Like & Dislike from 1 account address)
  {% endhint %}

{% hint style="info" %}
Want to learn how to setup your own Derupt Sentiment API Node? \
Check out the [**Sentiment API Setup Guide**](/latest/api/setup-guide)
{% endhint %}


# Clients (legacy)

Derupt is permissionless, anyone can setup and run a client.

Derupt Client Repo (link to repo of `derupt-beta` (*legacy*) when live) \
&#x20;\
Derupt can be ran locally, or on a server for your community to access.


# NOSTR Comparison

How Derupt differs from NOSTR

## Summary of advantages of Derupt over NOSTR:

* **Monetization** allowing users to directly monetize content without permission.
* Users have more **flexibility** and control over where their data is stored.
* **Transparency** in how the platform operates and how content is handled.
* Better mechanisms for **spam prevention** due to financial barriers for interaction.
* **Greater user control** over content, data, and monetization.
* **High censorship resistance** through immutable, on-chain content.
* **Decentralization** ensures no single entity controls the platform.

<table><thead><tr><th width="221" align="center">ASPECT</th><th width="281" align="center">NOSTR</th><th align="center">DERUPT</th></tr></thead><tbody><tr><td align="center">Content Discovery </td><td align="center">Relays can drop content, or not relay, encouraging favoritism and censorship by omission (biased)</td><td align="center">On-chain transparent chronological algorithm, ensuring equal presentation. (unbiased)</td></tr><tr><td align="center">User Control</td><td align="center">Users rely on relays. No direct control over message persistence.</td><td align="center">Users control attachment storage, including their fallback loadout-URI</td></tr><tr><td align="center">Spam/Bot Prevention</td><td align="center">Easy for bots and users to spam due to lack of fees or identity barriers. Centralized Moderation.</td><td align="center">On-chain fees disincentivize spammers. Economic barrier in place. Client-side moderation.</td></tr><tr><td align="center">Interface Design</td><td align="center">Relay-dependent. Interface can't directly censor but can stop forwarding.</td><td align="center">Interface agnostic. Owners can mute client-side but cannot delete on-chain data.</td></tr><tr><td align="center">Content Storage</td><td align="center">Messages stored on voluntary relay nodes. No guarantees of permanence. No fallbacks.  </td><td align="center">Primary content stored on-chain; attachments in user-controlled Stacks storage, with fallback flexibility. </td></tr><tr><td align="center">Immutability</td><td align="center">Relays can drop messages at any time. No built-in immutability.</td><td align="center">On-chain messages are immutable and URI pointers are permanent. (fallback loadout-uri's ensure resilience in resolution)</td></tr><tr><td align="center">Censorship Resistance</td><td align="center">Subject to platform favoritism  and legal censorship.</td><td align="center">On-chain data cannot be removed. Interfaces may mute, but cannot delete content.</td></tr><tr><td align="center">Proof of Censorship</td><td align="center">No proofs capable, censorship done in secret. No user recourse. </td><td align="center">On-chain attestation proves existence of content.</td></tr></tbody></table>

Many of the "advantages" of NOSTR that people tend to advocate for, actually present disadvantages to the user when viewed through the lens of security, immutability, accountability, and censorship resistance.

## Why NOSTR's "advantages" are actually disadvantages:

* Free messaging leads to spam vulnerability with no economic deterrent.
* Ephemeral communication results in lack of accountability and traceability.
* Relay-based moderation introduces inconsistent content availability and censorship risks.
* Custom relay selection can create fragmented conversations and echo chambers.
* Lower-barrier of entry increases exposure to bots and spammers at scale.
* Offline relaying risks message tampering and delayed propagation.
* Faster innovation can lead to instability and security risks


# X (Twitter) Comparison

How Derupt differs from X (Twitter)

## Summary of advantages of Derupt over X:

* **Monetization** allowing users to directly monetize content without permission.
* Users have more **flexibility** and control over where their data is stored.
* **Transparency** in how the platform operates and how content is handled.
* Better mechanisms for **spam prevention** due to financial barriers for interaction.
* **Greater user control** over content, data, and monetization.
* **High censorship resistance** through immutable, on-chain content.
* **Decentralization** ensures no single entity controls the platform.

<table><thead><tr><th width="221" align="center">ASPECT</th><th width="281" align="center">X (Twitter)</th><th align="center">DERUPT</th></tr></thead><tbody><tr><td align="center">Content Monetization</td><td align="center">Permission Required</td><td align="center">Permission Not Required</td></tr><tr><td align="center">Monetization Method</td><td align="center">Achieved via ad-rev split based on attention</td><td align="center">Achieved via smart contracts, based on consumer sentiment</td></tr><tr><td align="center">Content Discovery </td><td align="center">Centralized opaque algorithm, encouraging favoritism and censorship by omission of presentation. (biased)</td><td align="center">Decentralized transparent chronological algorithm, encouraging equal opportunity of presentation. (unbiased)</td></tr><tr><td align="center">User Control</td><td align="center">Centralized, handled by the platform, very limited.</td><td align="center">Users control attachment storage, including their fallback loadout-URI</td></tr><tr><td align="center">Spam/Bot Prevention</td><td align="center">AI-driven moderation, no financial barriers.</td><td align="center">On-chain fees disincentivize spammers. Economic barrier in place.</td></tr><tr><td align="center">Interface Design</td><td align="center">Interface lock in, developers can not create full clients. eg No alternative interface available.</td><td align="center">Interface agnostic, developers can create full clients. eg Alternative interfaces availability.</td></tr><tr><td align="center">Content Storage</td><td align="center">Centralized storage, no fall back control</td><td align="center">Primary content stored on-chain; attachments in user-controlled Stacks storage, with fallback flexibility. </td></tr><tr><td align="center">Immutability</td><td align="center">Content can be removed or modified by the platform.</td><td align="center">On-chain messages are immutable and URI pointers are permanent. (fallback loadout-uri's ensure resilience in resolution)</td></tr><tr><td align="center">Censorship Resistance</td><td align="center">Subject to platform favoritism  and legal censorship.</td><td align="center">On-chain data cannot be removed. Interfaces may mute, but cannot delete content.</td></tr><tr><td align="center">Proof of Censorship</td><td align="center">No proofs capable, censorship done in secret. No user recourse. </td><td align="center">On-chain attestation proves existence of any muted content. </td></tr></tbody></table>

*


