# Overview

Komunitin is an app featuring a **local community currency wallet** and a **marketplace** allowing these local communities to easily trade between themselves and other communities. It effectively facilitates trade between a **decentralized set of local community currencies**.

**Community currencies**, also referred to as [local currencies](https://en.wikipedia.org/wiki/Local_currency) or local exchange trade systems ([LETS](https://en.wikipedia.org/wiki/Local_exchange_trading_system)), are a tool for financial inclusion that allows for a transition to a fairer and more ecologically sustainable economy. They are issued and governed by mutual credit communities, cooperatives, time banks, local councils, etc. These communities define the currency rules and deploy local monetary policies, yet they need more features than just a transfer system: providing a marketplace for buyers and sellers, publishing community news, facilitating communication between members, etc.

Different **state-of-the-art technologies** are used to accomplish the project mission, including the Stellar blockchain, the TypeScript and Go programming languages, PostgreSQL and Redis databases, Docker containers for a scalable microservice architecure and push messages for real-time notifications.

Komunitin is an [**open source**](https://github.com/komunitin/komunitin) project developed without profit and sustented by the user community.

Subscribe to the newsletter here to get accasionally updated:

{% embed url="<https://subscribe.komunitin.org>" %}

<figure><img src="https://2330518808-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgDH9z8NR6KlNrjXLy484%2Fuploads%2Fgit-blob-398b626b4a098a41fbe6cb08a32b10a2f2ea14e9%2Fthree-screens.png?alt=media" alt=""><figcaption><p>Login, transfers and offers screens of the Komunitin app on mobile</p></figcaption></figure>


# Demo

### Log in to the demo

Use the demo to experiment the app and discover all the features by yourself before starting a new community. Don't hesitate to make transfers and create offers and needs. Find the demo at:

{% embed url="<https://demo.komunitin.org>" %}

In this server there are two communities "NET1" (Time bank) and "NET2" (Mutual credit) with some users in each. You can use any of the following credentials to log in:

**NET1 - regular user**\
email: <euclides@komunitin.org>\
password: komunitin

**NET1 - admin user**\
email: <riemann@komunitin.org>\
password: komunitin

**NET2 - regular user**\
email: <noether@komunitin.org>\
password: komunitin

**NET2 - admin user**\
email: <fermat@komunitin.org>\
password: komunitin

The demo instance is automatically deployed with the lastest code in the main branch. It may occasionally be down or corrupted due to maintenance, testing or users changing passwords and/or config settings from the admin user. It is regularly reset with fresh data.


# Features

Komunitin is a complete solution for exchange communities and therefore provides both **accounting** and **social** features. By accounting we mean the features in the virtual wallet: everything related to sending and receiving transfers, balances, currencies, currency settings... By social we mean the features in the virtual marketplace: member profiles, offers, needs, means of contact, localization...


# Accounting

## Currencies

Komunitin allows for creating different currencies, one for each community. Each currency is effectively a different token in the Stellar blockchain. When defining a currency you need to set some basic properties:

* **Code**: A unique 4-uppercase-letter code such as HOUR or COIN
* **Name**: The name of the currency, such as "Euro" or "Hour" or "Twike"
* **Symbol**: Such as $, €, ℏ, ¤ or any valid string of unicode symbols up to 3 characters.
* **Decimals**: The number of decimals to use when formatting the currency. Usually 2.
* **Scale**: The real number of decimals when doing internal computations with the currency.
* **Value**: The value of the currency measured with the global unit `HOUR`, meaning an average hour of labor. This value sets the exchange rate with other currencies in Komunitin and can be set as a fraction. More on that in [External transfers](/features/accounting/external-transfers) section.

Currencies also have a set of settings defining some rules for the currency and what can or can not be done. See the Currency settings section.

## Accounts

Each account belongs to one and only one currency, and hence holds a balance in this currency. Each account is effectively an account in the Stellar blockchain. Accounts have

* **Code**: The currency code followed by 4 numbers. For example COIN0123.
* **Credit limit**: Each account can be as much negative as defined by its credit limit setting. If set to zero, then it can't be negative. If set to 100, then it can be as much negative as -100. Credit limits can be set in a per-account basis or also with a currency-wide strategy, and can change over time.
* **Maximum balance**: Optionally, accounts can be bounded by the upside too.

Accounts have a set of settings defining some behavior and what is allowed to do. See the Account settings section.

## Transfers

Users can send to other accounts of the same currency. There are several methods for making transfers and they can be enabled or disabled by configuration:

* **Simple Send**. A user can see the list of community members and choose the destination account. Then enter the amount and a description, and submit.
* **Simple Receive**. The initiating user is now the destination rather than the source. They go to the app, choose the source from the members list, set a description and amount and request the transfer. Generally, the source will receive a notification and an email asking for their approval. When the source approves the transfer, the destination will receive a notification as well.\
  Users can have a whitelist of accounts that will get their requests automatically accepted, and can even configure their account so that it automatically accepts all transfer requests.
* **Multiple Send / Multiple Receive**. The app provides an interface for entering a batch of transfers and executing them all at once. This is just a convenient productivity interface for use cases when tens of transfers need to be entered. This option is available either for sending or for receiving.
* **Upload file**. An alternative way to enter multiple transfers is importing a CSV (Comma Separated Values) file with the transfers. The user may use any spreadsheet program to comfortably create the file. The format is simple: exactly 4 columns with Source, Destination, Description and Amount. External transfers are not supported.
* **QR code**. This is a method that allows the requester to enter the Description and the Amount of a transfer and build a QR code. This QR code can be then scanned by the source to finish the transfer.
* **NFC tag**. This feature allows for transfers with a workflow similar to contactless cards (the technology is different though). Users can link one or several existing NFC tags to their account. Then the receiver can initiate the transfer by adding a description and an amount and showing their NFC reader to the source. The source brings their NFC tag close to the destination reader to complete the transfer. Currently NFC tag transfers only work in Android devices.

Note that all these transfer methods are configurable and can be enabled at currency or account level depending on your concrete requirements. It is not recommended to leave all them available by default since too many options may cause confusion to users. A good approach is to set a single default way to perform transfers and open additional methods on a per-account basis as required.

## Account settings

Beyond the code, and the credit and maximum limits accounts have some additional settings governing their behavior. All this settings can be set account by account and they have a default value for all accounts in a currency.

* **Send**. Allow this account to send to other accounts.
* **Receive**. Allow this account to request transfers from other accounts.
* **Simple Send**. Allow sending transfers by choosing the destination from a list.
* **Simple Receive**. Allow requesting transfers by choosing the source from a list.
* **Send by QR**. Allow sending transfers by scanning a QR code.
* **Receive by QR**. Allow receiving transfers by showing a QR code.
* **Send by NFC**. Allow this account to link NFC tags and authorize transfers through these linked tags.
* **Receive by NFC**. Allow this account to request transfers authorized with NFC tags. To perform NFC tag transfers, the source needs to have "Send by NFC" and the destination needs to have "Receive by NFC".
* **Multiple Send**. Allow sending a batch of transfers at once.
* **Multiple Receive**. Allow requesting a batch of transfers at once.
* **Accept transfers after 2 weeks**. Automatically accept all pending transfer requests after 2 weeks of inactivity.
* **Credit by transfers**. This setting enables a dynamic scheme for account credit limits. The account credit limit is updated automatically every time this account receives a transfer so the credit limit equals the total sum of transfers received by this account. The credit limit thus gradually grows with currency up to a configurable hard limit.
* **External Send**. Allow this account to send and receive transfers from accounts in other currencies.
* **External Receive**. Allow this account to request and receive transfer requests from accounts in other currencies.
* **Hide Balance**. Hide the account balance and limits from other users.

While this set of settings already provides a great level of flexibility, the project is set to provide more configurable features as they are requested by partner communities.

## Currency settings

Beyond the basic currency properties (name, code, symbol, scale, decimals), currencies have some additional settings.

* **Initial Credit**. The maximum negative balance that an account can have after signing up. Changing this value does not affect existing accounts.
* **Maximum Balance**. The maximum positive balance that an account can have after signing up. Leave to 0 for unlimited.
* **Enable External Send**. Enable the Komunitin protocol to send and receive transfers to accounts in other currencies.
* **Enable External Receive**. Enable the Komunitin protocol to request and receive requests of transfers from accounts in other currencies.
* **Enable Credit Commons (Experimental)**. Enable the Credit Commons protocol to send and receive transfers to accounts in other currencies. Not recommended for production use yet.
* **Maximum Trade Surplus**. The maximum amount all other communities combined can owe to your community.
* **Maximum Trade Deficit**. The maximum amount your community can owe to all other communities combined.
* **Default account settings**. Currencies have a set of account settings by default: Send, Receive, Simple Send, Simple Receive, Send by QR, Receive by QR, Send by NFC, Receive by NFC, Multiple Send, Multiple Receive, Accept transfers after 2 weeks, Credit by transfers, External Send, External Receive, and Hide Balance.\
  For example, if a community wants regular accounts to be just able to send and some special accounts to be able to both send and request transfers, they can set Send to true and Receive to false at currency level and then overwrite the Receive setting for the special accounts.


# External transfers

## External transfers

External transfers are transfers where the source and the destination accounts belong to different communities and hence use different currencies. Using external transfers, the system exchanges local currencies so end-users can seamlessly send with their own local currency. Komunitin uses a decentralized system based on the Stellar blockchain to enable reliable transfers between currencies without the need of any global coordination or intermediary global currency.

**The local currency rate**

The administration of each local currency in Komunitin needs to manually set the exchange rate of their own currency against a global value that we'll call HOUR. The name of this global HOUR unit is meant to be an hour of labour, but once the first local currency set their exchange rate, the next ones are effectively definig the rate of their currency against the previous ones.

This rate is fixed but can be adjustable anytime by the currency administration if required.

**Trustlines**

The currency administration may establish trustlines with any other currency that they know is indeed trustworthy. A trustline has a limit value L and it means, for the currency that defines it, "we are willing to accept a value up to L of your currency".

Once currency A trusts currency B, this means that users in B can send to users in A. Trustlines are directional, so if A trusts B, that does not immediately allow users in A to send to users in B (because B does not trust A). However, once some users in B sent to users in A, then A has a positive balance of trade with B, and that allows users in A to send to users in B until this balance gets to zero.

**Path transfers**

Trustlines form a network of trust among currencies allowing you to reach other users beyond the communities that directly trust your currency or have a negative balance against your currency. Indeed, if currency A trusts currency B and currency B trusts currency C, then a user in C can make a transfer to any user in A. The system will take the source amount in C and will exchange it for units of B. Then will take the amount in B and will exchange it for units in A that will be received by the destination. This process is completely automatic and transparent to the user.

These path transfers are currently restricted to have a maximum length of 4. Note that a balance of trade between two currencies may be affected by the behavior of users not belonging to any the two because of path transfers. Anyway, the trade balance between two currencies will never exceed the limit established by the trustline.

If the balance of trade between two currencies reach the limit established by the trustline, then the trade between these two currencies is stopped in that direction. Thus, each currency administrator is supposed to take action when such limit is getting close or reached. The action may be coordinating some trades with the neighbor currency or even adjusting their currency rate.

**Configuration options**

There are several configuration options related to external transfers apart from trustlines:

* **Enable external transfers**. This needs to be on to enable external transfers at all.
* **Allow external sending**. With this option, your currency users can send to users from other currencies and conversely, users from other currencies can send to your members.
* **Allow external receiving**. This is similar to the previous one, but allowing your users to request transfers from external users and also external users to request transfers from your users. Allowing external receiving requests opens the door to spam transfer requests from unknown users.
* **Accept external transfers automatically**. Whether to accept external transfer requests without manual approval.
* **External credit limit**. You may define a trade balance limit for the sum of all external transfers, in addition to the limits of the trustlines. When the sum of the balances of all trustlines is lower than this limit, external transfers are blocked.
* **External maximum balance**. Similar to the previous option, this limit sets the limit for the total imports, even if the limit of individual trustlines is not reached.
* **Public member list.** Communities may decide to publish or hide the member list (the name and account of all members in the community) from external users, so they can be searched from external users. Even without public member list, external users can use the QR code or enter the account number for creating transfers, but they will not see the destination account name.

**Example**

This mechanism is very flexible and allows for trading among very different types of community currencies. Imagine a city with two community currencies. Assume one is 100% backed by EUR and issued by the council. Another one is a mutual credit time-bank issued by a grass-roots association. The council sets the value of their currency to 1/10 (1 HOUR = 10 units). The time bank sets their value to 1 (1 HOUR = 1 time bank unit). The time bank agrees to trust the council currency up to an arbitrary limit of 1,000 time bank units (equal to 10,000 council units). Now all users having council units can request services and send to the time bank users. As soon as one council unit user sends to a time bank user, all time bank users can send to council unit users until the trade balance between the two currencies reaches zero again.

Suppose that this is working great but the trade is stopping from time to time due to the balance of trade reaching the limit of zero. The council may decide then to use 5,000 EUR of their budget to back a trustline to the time bank currency and thus allowing a more comfortable trading between the two currencies. Now the balance of trade can go up to 5,000 in one direction and up to 10,000 in the other. Suppose now that after some time the balance of trade is approaching the limit established by the council trustline. Then the time bank may decide to host a party open to the whole city where they will serve drinks and meals and will accept their own time currency. This way they rebalance and the trade can continue.

## The Credit Commons protocol

Additionally, Komunitin has experimental support for the Credit Commons protocol, which is a complementary mechanism to enable external transfers between currencies. Currently it is only available for testing using the transfer workflow with QR codes and the implementation is not yet complete. Check the [Credit Commons website](https://creditcommons.net/) for more information about this protocol.


# Currency model overview

Our goal is to provide a tool that facilitates the economic organization of a society in transition to a more sustainable production and consumption model and also a tool that promotes inclusion and fair trade. The model is based on real experience from local exchange communities across Spain, Italy and Greece for more than 10 years.

### Community currencies

Each community has their own currency. Local communities are able to get organized and make decisions following their own governance model, and they issue a local currency based on their interpersonal trust. The exact definition and rules of the currency are left to the local community. Hence we offer an administration account with rights to perform actions on their currency and the accounts in their community. The local exchange community will typically have some sort of board that will own the credentials for the admin account.

Typically, the community currency follows a mutual credit scheme, where the currency is created when an account gets negative. If your balance is positive, it means that you've given more to the community than received, and if your account is negative, you've got more than given. Community currencies are thought more as a unit of measure than as an asset. There are multiple ways to give credit to accounts. Some communities give all users the same amount of credit upon onboarding, others don't allow negative balances, but give the currency units based on community work, others allow increasing negative balances based on previous use of the currency. Some communities give extra credit to selected members for developing projects for the common good.

The app offers a wide range of different configuration options including different transfer methods and credit limit schemes so currency administrators can develop their own model.

### External transfers

Exchange between different community currencies is a feature that has been already rudimentarily implemented both by IntegralCES (Komunitin's predecessor) and CES (the most popular community currency platform). However existing applications don't model the risk of trusting currencies out of the control of the local community and that has been a source of problems. Thanks to the feature of *path payments* provided by Stellar (also referred to as credit mesh or Ripple in other ledgers), we define a model where communities can control the risk of trading with other currencies. In this model there is no need for any for-profit market maker or intermediary global currency, and the required liquidity for currency exchange is directly provided by communities through a special gateway account.

The community administration may establish a trustline with one or a few other neighboring communities. That means that this community is willing to accept a limited amount of currency from the other one. This trust can be granted unilaterally by one community to another, but will typically follow a trading agreement between two neighboring communities. External transfers are then possible via multiple hops of local currency exchanges via these bilateral trustlines, even if the endpoint communities don't directly trust each other.

Imagine Alice from community A wants to send to Carol from community C. However Carol uses currency C so she is not interested in currency A from Alice. Moreover, there is no trade agreement between currency A and currency C so Alice can't directly get currency C to send to Carol with her currency A. However both currency A and C have a trade agreement with an intermediate currency B. Thus, Alice can exchange her currency A by some currency B, and then exchange some currency B by some currency C to finally send to Carol.

In order to provide liquidity for external trade, the model does not rely on individual for-profit market makers. Instead, each community defines a fixed (but configurable) exchange rate of their currency against a global unit that we call HOUR. Then they define the trust (in HOURs) to each trustworthy neighbor community. This is the maximum amount of HOURs this community is willing to accept from the other community. If the limit is reached, the trade is blocked in one direction and then the two communities may need to cooperate to revert the situation (with coordinated trades, change of rates, etc).

This model is a mix between the classical centralized currency model, where a central authority issues the currency and everybody needs to trust this single institution and the path transfers model, where every individual is the issuer of their currency and they individually need to establish the trust lines with their peers. In this model, users need to fully trust the issuer and administrator of their local community currency, but they can trade with all other users from any reachable other community only through a limited trust with one or a few well-known neighbor communities.

\\


# Social

## Communities

Communities are the social counterparty of currencies as each community is related one-to-one with a currency. A community has a logo, a name, a description, a location, some means of contact, their membership terms, etc. Only the community administrator can update these details.

All other resources (members, offers and needs etc) belong to a single community.

## Members

A member is the subject in Komunitin and belongs to a single community. A member has a profile picture, a name, a description, a location, some means of contact and a community currency account. One member has only one account in one currency. If a person must have more than one account (for example a business account and a personal one), then they will manage two members too.

Anybody can sign up to be a community member, but the administration needs to manually accept each application. Before the sign up process, members must accept the community membership terms.

## Offers and needs

Every member can publish offers and needs. An offer is basically a post with several pictures, a title, a description, a value in community currency (that can be left to any text like "request quote" or "8¢/kg") and an expiry date.

A need is formally like similar to an offer, but while offers usually last months or years, needs are supposed to expire in few days. They don't have title and the piscure is not so important.

#### Categories

Offers and needs belong to a category. Example of categories are "Food", "Healthcare", "Professional services", "Construction", etc. Categories can be customized for each community depending on concrete needs.


# Notifications

The platform may deliver messages to users using three different channels: email, push notifications and in-app notifications. Users can configure their notification preferences and enable or disable different kinds of notifications.

## Email

Email messages are divided into two categories: *My account* and *Community news*.

### My account

These emails are tied to events that affect a user directly and that are important to keep a record of. Typical examples include:

* Transfers: sent, received, pending, rejected.
* Offers/needs: expired.
* Security-related messages: email validation, password reset.

Users can enable/disable *My account* emails from their notification settings. We highly recommend keeping them enabled, since they act as an audit trail for key account actions and security events.

### Community news

These emails are a periodic newsletter designed to help users keep up with the community without receiving a message for every single event. They include:

* A selection of recent offers/needs.
* A short account summary with balance and recent activity highlights.
* An alert box for your account (eg no active offers)
* Community-level statistics and news.

Users can configure the frequency of *Community news* emails (weekly or monthly) or disable them entirely.

## Push Notifications

Push notifications are short messages sent to users' devices to inform them about important events or updates. Users need to provide explicit consent to receive push notifications and they can manage their preferences in the app settings. We also divide push notifications into the same two categories *My account* and *Community news*. Users can choose to enable or disable each category independently.

Most push notifications respect the quiet hours and will only be sent from 8AM to 10PM in the local user timezone.

### My account

These notifications inform users about important events related to their account, and are intended to be timely and actionable. Including:

* Transfers: sent, received, pending, rejected.
* Offers/needs: about to expire, expired.
* Occasional account health nudges (e.g. no active offers/needs).
* Welcome message for new members.

Users can enable/disable *My account* push notifications from their notification settings. We highly recommend keeping them enabled to stay informed about critical account activities.

### Community news

These notifications inform users about community-related updates, such as:

* New members joining the community.
* New offers published.
* New needs published.

To avoid overwhelming users, new offers/needs are treated differently depending on urgency:

* **Urgent**: offers/needs expiring within 7 days. These generate push notifications immediately when published.
* **Normal**: everything else. These are batched and sent only occasionally as a digest.

New members are also batched and sent as a digest.

Users can enable/disable *Community news* push notifications independently from *My account* notifications.

### Devices

If a user has several devices, they will get the push notifications to all their devices. Note that users will stop receiving push notifications in a device after a few months of not opening the app from this device.

## In-app Notifications

In-app notifications are messages displayed within the app interface itself. They are equivalent to push notifications but are only visible from the app. Users can't disable in-app notifications since they are not intrusive and are only visible when the user is actively using the app.

Users can see their history of notifications in a dedicated page of the app, where they can review past messages and take any necessary actions.


# Newsletter

## Community Admin Guide: Automated Newsletter Service

The Komunitin newsletter is a strategic engagement tool designed to increase member retention and activity by delivering personalized and localized email updates.

### What is in the Newsletter?

The newsletter features a mobile-responsive layout divided into several key sections to provide value to your members:

#### 1. Header & Greeting

The header prominently displays your **Group Name and Logo** to build a closer connection with the user. Each email includes a **personalized greeting** addressing the member by name, highlighting that the content is tailored for them.

#### 2. Marketplace Highlights

This section aims to spark curiosity by showcasing a curated selection of marketplace items:

* **Offers**: Displays 3 selected offers from the local marketplace, including an image, title, truncated description, author details (name and avatar), and the distance from the author to the user.
* **Needs**: Displays 3 selected needs with a similar layout to the offers.
* **Primary Call to Action (CTA)**: A button directing users to the main Home feed to browse more content.
* **Secondary CTA**: A link encouraging users to "Publish a new offer" to drive community content creation.

#### 3. My Account Dashboard

Provides members with a clear view of their current status within the community:

* **Balance**: A prominent box displaying the local currency balance.
* **Balance Description**: A helpful explanation of the balance within the context of a mutual credit system (e.g., explaining that a negative balance is acceptable and represents receiving more than provided).
* **Monthly Stats**: Shows the number of transfers the user completed in the last month (hidden if no transfers occurred).

#### 4. Account Alert Box

A high-impact, personalized section that identifies specific tasks for the user to improve their participation. It prioritizes alerts such as:

* Missing profile details (image, bio, or location).
* Negative balance with no active offers.
* Positive balance with no active needs.
* Expired offers that need management.

#### 5. Community Statistics

Displays global community activity from the last month to show growth and vitality:

* Total number of transfers.
* Number of accounts with at least one transfer.
* Number of new accounts. (Note: Any figure that is zero is automatically hidden.)

#### 6. Footer

Includes the Komunitin logo and essential links for **one-click unsubscription** or managing **mailing preferences**.

***

### Configuration Options

Both administrators and individual users have control over how they interact with the newsletter service.

#### For Community Admins

Administrators can manage the following settings at the community level:

*

**Enable/Disable Newsletter**: Turn the entire newsletter service on or off for the community.

*

**Default Frequency**: Set the default delivery frequency for new users who join the community.

#### For Users

Individual members can personalize their own experience through their app settings:

*

**Frequency Selection**: Users can choose to receive the newsletter **weekly**, **monthly**, or opt-out entirely by selecting **never**.

## Newsletter Algorithms

### Offers and Needs Selection Algorithm

The offers and needs selection algorithm has been crafted to have these global properties:

* **Items are relevant to the user**: items selected should be appealing to the target user.
* **Items are varied**: items selected should be varied.
* **Equitable publishing of items**: all offers should be shown an equitable number of times across all newsletters.

Specifically, the algorithm selects a mix of 2 "Fresh & Close" items and 1 "Random" items to ensure relevance while maintaining variety.

#### 1. Fresh & Close Selection (2 Items)

This phase selects items from the 100 most recently updated candidates in the marketplace, excluding the recipient's own posts. Selection is done via **Weighted Random selection**, where each item is assigned a dynamic score:

*

**Distance Score**: Items within 1 km receive a perfect score. Beyond that, the score decays exponentially, reaching half its value every 10 km.

*

**Time Score**: Items created very recently (within one month or since the last newsletter) receive a perfect score. Older items decay exponentially with a three-month half-life.

*

**Quality Score**: Items with images receive a full score (1.0), while those without images are penalized (0.5) to promote more engaging content.

*

**Historic Penalty**: To avoid repetition, items from authors who were featured in any of the last three newsletters are penalized.

*

**Global Variety Penalty**: To ensure the same item isn't sent to the entire community at once, a penalty is applied if an item has already been selected for many other members in the current batch.

*

**Dynamic Re-scoring**: After the first item is chosen, the scores of remaining candidates from the same author or category are lowered to ensure the second item is different.

#### 2. Random Selection (1 Item)

The final item is chosen purely at random from the remaining pool of items (excluding the user's own and those already selected).

*

**Conflict Avoidance**: The system will retry the random selection up to three times if the chosen item happens to be from the same author or category as the items already selected in the first phase.

***

### Account Alert Conditions

The "Account Alert" box is designed to nudge users toward the most urgent action they can take to improve their standing or participation in the community. The system checks for issues in the following **priority order** and displays only the top-priority alert found:

| Priority | Condition                             | Recommended Action |
| -------- | ------------------------------------- | ------------------ |
| 1        | Negative balance AND no active offers | Create an Offer    |
| 2        | Positive balance AND no active needs  | Create a Need      |
| 3        | No active offers (any balance)        | Create an Offer    |
| 4        | No active needs (any balance)         | Create a Need      |
| 5        | Profile is missing an image           | Edit Profile       |
| 6        | Profile is missing a biography        | Edit Profile       |
| 7        | Profile is missing a location         | Edit Profile       |
| 8        | User has expired offers               | Manage Offers      |

#### Anti-Fatigue Logic (Repetition Check)

To prevent users from being "pestered" by the same message repeatedly, the system checks the logs of the previous two newsletters.

* If the same alert type was shown in the **last two consecutive newsletters**, that alert is skipped for the current email.
* The system then automatically moves to the next highest priority alert. This ensures that even if a user hasn't fixed a high-priority issue (like a missing profile picture), they might still be notified about other relevant tasks (like expiring offers).


# Enable push notifications

Push notifications require **explicit permission**.

The app will ask for permission when you enable push notifications. If you click **Deny/Block** (or your browser auto-blocks prompts), the browser **won’t show the permission prompt again**, and the app can’t override that. In that case you must re-enable notifications from your **browser settings**.

## Desktop (Windows / macOS / Linux)

### Chrome / Chromium / Edge (website in the browser)

1. Open the app website.
2. Click the **lock** (or site icon) next to the address bar.
3. Open **Site settings** (or **Permissions**).
4. Set **Notifications** to **Allow**.

Alternative path:

* Open browser **Settings** → **Privacy and security** → **Site settings** → **Notifications**, then move the site from *Blocked/Not allowed* to *Allowed*.

### Chrome (installed PWA)

Installed PWAs use the same site permission underneath.

1. Allow notifications for the site (steps above).
2. Check OS notifications:
   * **Windows:** Settings → System → Notifications → ensure the PWA/browser is allowed.
   * **macOS:** System Settings → Notifications → ensure the PWA/browser is allowed.
   * **Linux:** ensure desktop notifications are enabled for your session/DE.

### Firefox (website in the browser)

1. Open the app website.
2. Click the **padlock** in the address bar.
3. Open **More information** / page info → **Permissions**.
4. Under **Send Notifications**, choose **Allow** (or remove a previous Block so Firefox can ask again).

### Safari (macOS)

1. Safari → **Settings…** → **Websites** → **Notifications**.
2. Find the site and set it to **Allow**.

Also check macOS:

* System Settings → **Notifications** → find the website (or Safari) → **Allow Notifications**.

## Android

### Chrome (browser tab or installed PWA)

1. Open the app website.
2. Tap the **lock** (or site icon) → **Site settings**.
3. Set **Notifications** to **Allow**.

Also check Android system settings:

* Settings → **Apps** → (Chrome or the installed web app) → **Notifications** → enable.

### Firefox (Android)

1. Firefox → **Settings** → **Site permissions** → **Notifications**.
2. Move the site to **Allowed** (or remove it from Blocked so Firefox can ask again).

## iPhone / iPad (iOS / iPadOS)

iOS/iPadOS supports web push notifications for **Home Screen web apps (installed PWAs)** on iOS/iPadOS **16.4+**. You generally **won’t receive web push notifications from a normal browser tab**.

### Safari (installed PWA)

If you haven’t installed the app yet:

1. Open the app website in **Safari**.
2. Tap **Share** → **Add to Home Screen**.
3. Open the app from your **Home Screen**.

Grant/re-grant permission:

1. In the app, trigger the permission request and tap **Allow**.
2. If you previously tapped **Don’t Allow**, re-enable it in iOS:
   * Settings → **Notifications** → select the app’s Home Screen web app entry → enable **Allow Notifications**.

### Chrome / Firefox (iOS)

Chrome/Firefox on iOS don’t receive web push notifications from a normal browser tab.

To receive push notifications on iOS/iPadOS, use **Safari** and install the app as a **Home Screen web app** (Add to Home Screen), then grant permission there.

## Additional considerations

* Notifications don’t work in **private/incognito** windows.
* Your device/OS can block notifications globally (Focus/Do Not Disturb, battery optimizations, system-level notification toggles).
* Some browsers may **remove notification permission** for sites you haven’t visited in a while; if that happens, revisit the site and re-allow notifications.


# Technology

The Komunitin system is made of several microservices.

* **App**: The client application with user interface. See the [app](https://github.com/community-exchange-network/komunitin/blob/master/app/README.md) folder.
* **Notifications** service: The backend service for the messaging system including mails and push notifications. See the [notifications-ts](https://github.com/community-exchange-network/komunitin/blob/master/notifications-ts/README.md) folder.
* **Accounting** service: The decentralized backend for the accounting API based on the [Stellar](https://stellar.org/) blockchain. See the [accounting](https://github.com/community-exchange-network/komunitin/blob/master/accounting/README.md) folder.
* **Social** service: The new decentralized backend for the social API (Still to be developed!). Currently the service is being provided by **IntegralCES,** the current backend for the social APIs based on the legacy project built on Drupal. See the [ices project](https://drupal.org/project/ices).


# App

### App technology

There is a single codebase for the app to be run either as a native app in Android, iOS devices, Windows computers or as a web app from the browser. The app is written in TypeScript using the [Quasar](https://quasar.dev) framework and [Vue.js.](https://vuejs.org)

### PWA

The app is currently shipped as a [Progressive Web App](https://web.dev/explore/progressive-web-apps) (PWA) with the main instance at <https://komunitin.org>. Users need to visit the site and optionally install it to their device as an application. Nothing prevents this app to be bundled and shipped through the Google and Apple application stores, but currently the PWA model allows for quicker and easier development and release cycle.

### Material Design

The user experience and design of the app has been designed to follow the Google's [Material Design](https://material.io/) guidelines.


# Accounting

The next child pages briefly explain the architecture and technology used behind several main features related to transfers and accounting.


# API

The Komunitin Accounting API defines a protocol to make transfers and transfer requests between members of exchange communities. It is a HTTP REST JSON api following the [JSON:API](https://jsonapi.org) specification.

It can be used for simple transfers between members of the same exchange community but can also be used to make external transfers between members of different exchange communities automatically following a path of one or more currency exchange steps. The api has methods for creating and managing currencies, accounts, etc.

There is an OpenAPI spec file automatically generated from the test suite [here](https://github.com/community-exchange-network/komunitin/blob/master/accounting/openapi/openapi_v3.json). You can browse it using Swagger:

{% embed url="<https://petstore.swagger.io/?url=https://raw.githubusercontent.com/komunitin/komunitin/refs/heads/master/accounting/openapi/openapi_v3.json>" %}
Komunition accounting API auto-generated specs
{% endembed %}


# Stellar model

## The Stellar network

Komunitin uses the [Stellar network ](https://stellar.org)as their backend ledger. Stellar is a consolidated global blockchain providing a unique set of features that make it the best decentralized technology to implement the required model. Within the key features in Stellar there are the quick finalization time for transactions (\~5 sec), the cheap price of each transaction (fractions of cents), and the built-in implementation of custom assets, trustlines and path payments (required for external payments). Beyond that, Stellar support smart contracts allowing for future Decentralized Finance integrations.

This blockchain is ruled by the US-based non-proft The Stellar Foundation, aiming for financial inclusion.

## The model

See the [currency model](/features/accounting/currency-model-overview) page for an overview of the currency scheme we're modeling.

Every account and every transaction is recorded in the stellar network. And every community currency is a different Stellar asset. So Komunitin transactions are faithfully represented in the Stellar blockchain.

### Local transfers

* Each community has an issuer account and its own local asset in Stellar.
* The asset is freezable and trustlines authorizable.
* Each community has an administrator account in Stellar.
* Each user maps to an account in Stellar. The user account has two signers, the user's key and the administrator's key. The user key is enough for transfers, but the administrator is required for higher threshold operations.
* Each user account has a trustline with the local asset. The value of this trustline is the positive maximum defined for this currency or particular account, if any.
* The available credit for each user account (negative maximum) is modeled by "initial" transfer(s) from the issuer account. The service will subtract these initial transfers from the Stellar user balance to get the (eventually negative) user balance shown in the Komunitin app.

### External transfers

* Each community has an *external issuer* account and an *external trader* account in Stellar.
* The external issuer issues the HOUR asset, so each community issues their own HOUR asset.
* The external trader proxies all external transfers.
* External trader has a trustline and balance with the local currency asset as well as with the HOUR asset.
* External trader may have trustlines and balances with other external assets.
* External trader from other communities can define trustlines to this HOUR asset.
* External accounts define passive sell offers exchanging their issued HOURs by their local currency, in the two directions, following the conversion rate defined by the community.
* External accounts define 1:1 passive sell offers selling their issued HOURs by the trusted HOURs.
* External accounts define 1:1 (active) sell offers selling external HOURs in their balance by their own HOURs. These clear the balance of trade.
* Trustlines to external communities may be disabled. In this case the existing balance of external HOUR, if any, is moved to the external issuer account just in case we want to enable it again in the future.
* External trader has a credit limit and maximum balance on the local currency asset, defined by the community settings.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXfk6Q_RYUghJkMVusudYpv9Qg-cpDPYtrW6NQm77gtK-jeT9qQMMVJD3c-vyuupUhn-rO5E6fBL8XbpLiPz_L4q1t0r_QWcgPL-wfpCguoyNParVEX78VU4WWnZE_uYGjna71S766Jq9PWZZvGqsHbG4vND?key=bHIg-rgBbd-jpdUzkKPJrw" alt=""><figcaption></figcaption></figure>


# Data

The data required to run the accounting service is divided between the on-chain data and the server database data. The onchain are the accounts, assets, transactions and credit limits. The database saves further information such as transfer descriptions, account numbers, account settings, account tags, and importantly, the private keys. The service uses a PostgreSQL database.

### Custodial model

Every account needs a private key to sign their transactions. Furthermore, there are special accounts required for each community currency (the issuer, the admin, the external issuer and external trader), with their respective private keys. All these keys are stored in the Komunitin database. Thus, Komunitin implements a custodial scheme where users need to fully trust their servers, in contrast for non-custodial architectures where the user has their private keys and need not to trust any particular server.

The tradeoff for storing the keys in the server is that it is easier to have some features like password recovery, and automatic acceptance of payment requests.

### Encryption

In order to mitigate the risk of having all the private keys in the database, all private keys are symetrically encrypted in the database using a different key for each community. These community keys are also stored in the database and encrypted using a master key. This master key is provided to the service at deployment time, only through memory and not shared with other OS processes. Master and community are will be rotated periodically by policy as well as on demand.

This is a simple but effective security approach for the case of community currencies, where the strongest security layer is given via interpersonal trust within these small communities. The fact that all transactions are recorded in Stellar makes it possible for the local currency administrator to verify and restore the balance of a compromised account.

### Multitenant

While a single server hand handle different communities, each community data is completely isolated using the Row Level Security feature of PostgreSQL. From the security point of view, each currency data belongs to a different database and the app can't access data from currency A when processing a request in currency B.

### Open to non-custodial

Even if the current architecure is custodial, it has been designed in a way that it would be posisble to switch to a non-custodial scheme with some development effort and restricting some features.


# External transfers

External transfers are transfers where the two accounts belong to different currencies. We've already outlined the scheme in the [currency model ](https://github.com/community-exchange-network/komunitin/blob/master/docs/overview/currency-model.md#external-transfers)page and the set of elements [in the Stellar network](/technology/accounting/stellar-model#external-transfers).

Provided there is a trustline path between the source and destination currencies, the service needs to know the remote account public key in order to make the path transfer. Remember that the remote account can belong to a currency in the same or a different server.

## API

External transfers make use of a JSON:API extension for external resources. Concretely, an external `payee` relationship looks like:

```
"payee": { 
  "data" : { 
    "type": "accounts", 
    "id": "123"
    "meta": {
      "external": true
      "href": "https://komunitin.org/TEST/accounts/123"
    }
  }
}
```

The server can get the external resource following the href property. The public key is part of the resource body.

## Account discovery

Depending on the user interface method used to initiate the transfer, the account discovery model may vary.

* The most straightforward is the QR code method. Indeed, the QR already contains the full account URL, and this is directly used to get the public key.
* If using the account select field (either in the single or multiple page) the user will need to select first the remote community. Currently only the communities in the same server are available for selection.
  * If the remote community has enabled the possibility for anonymous users to list the community members, the source will see the full list of all remote members with names, avatar pictures and account numbers
  * Otherwise, the source can enter the account number AAAAXXXX and the remote account will be obtained from that. In this case the source doesn't see the name of the destination account.
* NFC tag transfers don't support external transfers currently.

## Information sharing

At this point we're capable of doing the Stellar transfer, but we want more than that: we want to share the transfer description and other offchain bits of information from the source server to the destination server.

In order to do so, the source server directly sends all these additional data to the destination server. The source identifies themselves using the source account private key so the external server can verify that the transfer information indeed comes from the transfer source.

This authentication method will be used for remote external transfer requests as well.

### Transfer requests

When it is the destination account who wants to initiate the external transfer, the destination server sends the transfer request to the source server. Then, if the source account allows receiving external transfer requests the transfer will be recorded in the source server and a notification will be sent to the source. After approval, the transfer will be submitted by the source server and will follow the same workflow as an external source.

Note that the requests between servers are authenticated using tokens signed with the respective account private keys.


# Multiple transfers

The user interface provides a page suitable to enter a batch of transfers (either sending or receiving requests) and send them all at once. While this may seem just a repetition of the single transfer case, it is a bit problematic in the case of a distributed ledger such as Stellar because it imposes a series of limits:

* The total transfer throughput of Stellar is in the orders of 1000 operations / ledger, and a new ledger closes every 5 sec.
* The Stellar transfer fee increases if the network gets flooded with transactions
* One account can only submit one transaction per ledger
* The Stellar service endpoints impose further rate limits (\~100 calls every 6 seconds).

In order to accommodate these limits, the server will use up to 10 [channel accounts](https://developers.stellar.org/docs/learn/encyclopedia/transactions-specialized/channel-accounts) so that a single account is doing up to 11 transfers / 5 sec. And the server further limits the rate of calls to Stellar so it does not break the 100 requests/ 6 sec limit.


# QR transfers

The concept behind QR transfers is fairly simple, as this method is just a convenient user experience for sources to have all the required information to create the transfer. Indeed, QR transfers don't use any different API call than regular simple transfers and all the logic is implemented in the frontend.

#### Transfer links

The QR codes encode transfer links. A transfer link is:

```
https://komunitin.org/pay?t=<account_url>&m=<description>&a=<amount>
```

With the amount being expressed in the account's currency. Since the full account url is used, this method works fine for external transfers and it is in fact the preferred method since account discovery is a challenge otherwise.

Note that you can scan the QR code with any other app and, provided it correctly redirects you to the Komunitin app, the transfer flow will continue.

Note also that transfer links may have further applications beyond QR codes.

#### Workflow

The destination is the initiator of the workflow by creating a transfer link encoded as a QR code with their own account, the description and the amount. Then the source scans the code as a quick way to have the transfer details, fills the source field with their own account and effectively submits the transfer.


# NFC transfers

NFC transfers are a transfer workflow using low-cost and read-only NFC tags. Each NFC tag contains an identifier that can be read using a NFC reader such as the ones found in current smartphones

The idea behind this method is to be able to link a NFC tag with a Komunitin account, so this account has this additional identifier. In fact several different tags can be linked to one account, but two accounts can't share a single tag.

#### Workflow

The NFC transfer workflow is, from the user point of view, not very different from the QR workflow. But it is the destination account that actually submits a transfer request to the server instead of the source (that of course can't submit anything from their tag). Indeed, the destination account sets the transfer description and amount and reads the NFC tag from the source. This NFC tag identifies the source account and the destination sends a transfer request to the source account, adding the NFC tag identifier. The server will immediately authorize the transfer.

#### Security

Note that this transfer method is not suitable for every use case since the NFC tags can be copied. The way to mitigate this risk is to disable the ability to make tag transfer requests for all but a whitelist of approved users. Also, if a NFC tag is compromised, it can be immediately unlinked from the account at the settings page.

Note that the tags are not stored in the server, but a secure digest of them.


# Social

The social service is the one responsible for managing member profiles, offers, needs, categories etc. This service is still to be developed. The social API is already specified and currently implemented by the legacy drupal-based system IntegralCES.


# API

REST API featuring marketplace services for Exchange Communities.

This API provides access to exchange community details, member profile and their offers and needs and informational messages. It doesn't feature transfers nor any accounting information, as this is available in a separate API.\\

Browse the specification using Swagger here:

{% embed url="<https://petstore.swagger.io/?url=https://raw.githubusercontent.com/komunitin/komunitin-api/refs/heads/master/social/openapi.yaml>" %}

### Format

This specification is based on the [JSON:API](https://jsonapi.org/) standard. Some additional format conventions are addopted.

#### URLs

* The URL structure starts with the community code, so it eases the service isolation among different exchange communities in a single server, as there is no way to ask for resources from different communities. The only exception is the global `/groups` endpoint.
* Clients should honor the links provided by API responses and not try to construct the URL's using the known structure defined in this document. This way it decouples client andserver from URL design, making the server fully responsible of URLs.

#### Ids

* All resources have a global UUID identifier as their `id` field, but the URLs are human-readable. The URLs are meant to be almost immutable to allow caching and others, but can occasinally change (for example, in case of server migration), while the UUIDs are really immutable.
* All resources have a `code` field. This field is automatically generated from other resource fields (typically the title). It is a human-readable URL-safe string that is unique within the scope of the exchange community. It is used to build human-readable URLs. Clients should not assume that the `code` fields will be forever immutable, and should use the `id` field for that. However they may use the `code` field if they must create an identifier that will be exposed to users.

#### Data types

* Geolocation fields follow the [GeoJSON](https://geojson.org/) specification. Note that the spec allows to specify either a concrete point or an area. An additional field `name` may appear in Geolocation fields, which is a text title for the location.
* Date or time fields follow the [RFC3339](https://tools.ietf.org/html/rfc3339) specification.
* Long text fields allow formatting through a restricted set of HTML tags.

#### Structure

This section extensively use the [JSON:API](https://jsonapi.org/) language.

* When fetching individual resources, no `links` member is provided in the top level document.
* Resources have a `links` member with the `self` attribute, containing the canonical URL for this resource.
* Relationships don't have a `self` attribute and are not directly operable. They must be edited through the resource endpoint. In one-to-many relationships, they must be edited using the "many" endpoint of the relation. For example, the relation between offers and categories must be edited using the `offers` endpoints.
* Relationships have either a `related` attribute when they are not included or the `data` attribute with the resource identifier objects when they are included in a compound document. In this latter case, the `links` member may be present with pagination when not all related resources are embedded.
* Exchnage relationship is always implicitely defined in the path.

#### Filtering

Filtering is available in all endpoints that return a collection following the custom [Simple filtering](https://github.com/komunitin/komunitin-api/blob/master/jsonapi-profiles/filter.md) JSON:API profile.

#### Pagination

Pagination is available in all endpoints that return a collection following the official [Cursor Pagination](https://jsonapi.org/profiles/ethanresnick/cursor-pagination/) JSON:API profile.

#### Versioning

Clients should allow additional fields along all JSON responses. Therefore adding new fields won't be considered breaking backwards compatibility. API versioning is done using HTTP headers (still to specify).

### Resource objects

The whole API is designed as a set of resources and CRUD operations on them.

#### Communities

Communities represent the different exchange communities. They have a logo, description, location, contact points, etc. Communities have a link to their corresponding currency in the Accounting API.

All other resources belong to a particular community. The endpoints in one community are separated from other communities, and the implementators are recommended to isolate the data in different databases too.

Special administrative rights must be held in order to change community details.

#### Members

Members are the subject of this API. They need not to be physical people, but can be businesses, non-profit organizations, etc. They have profile information, contact points and may create offers and needs. Members have a link to their corresponding account in the Accounting API.

#### Users

Users are objects representing the login credentials. A user is linked to one or more members, which carry the actual profile information. Users are the link between the authentication service and this API and allow to manage several members from a single log in and also sharing members accross diferent users without having to share the credentials.

#### Contacts

Represent a contact point of a member or an exchange community. It may be a telephone number, email address, WhatsApp or Telegram contacts. A contact is always attached to either a member or a community. Contact resources are included by default in they owner resources, and can't be directly listed, so they act effectively as sub-resources of community and member resources.

#### Categories

Offers and needs are organized in categories. An offer or need can only belong to a single category. Good and service categories can be customized for each community.

In order to make categories interoperable, they are mapped to the set of categories defined at [Statistical Classification of Products by Activity in the European Union, Version 2.1](https://ec.europa.eu/eurostat/ramon/nomenclatures/index.cfm?TargetUrl=LST_NOM_DTL\&StrNom=CPA_2_1\&StrLanguageCode=EN\&IntPcKey=\&StrLayoutCode=HIERARCHIC) (CPA). CPA has been chosen over other classifications because it is already translated to many languages and publicly accessible in machine-readable format. Note that CPA categories are not visible to end-users, just to community administrators.

#### Offers

Offers are publications created by members to advertize the goods and services they are willing to sell through the exchange system. They should include one or more images and have a title and a detailed description. Usually they are long-lived.

#### Needs

Needs are short publications created by members to request any good or service from the exchange community. They include a short description and are usually short-lived.

#### Posts

Posts are messages written by the exchange community administration to reach all members in the exchange community. Posts resource may be extended in a future for more flexible audiences, but at the moment we prefer to use external messaging systems for that purpose.

### Data privacy

Access to all resources may be restricted by assigning one of the predefined access labels to the `access` resource field.

* `private`: The resource is only accessible by its owner.
* `group`: The resource is only accessible by the members of the same exchange community.
* `public`: The resource is publicly accessible on the internet. Note that in order for members in other exchange communities to access a resource, it must be declared public. Public resources are also accessible by non-logged users when they browse the community network before registering.

In a future, other access labels may be added (friends, contacts, community:XXXX, etc) and the `access` field may accept multiple labels for a resource.

### Relation to other APIs

#### Authorization

Authorization endpoints are out of the scope of this API, which expects the user to be authorized with an OAuth2 access token. The access token is provided by a separate authorization API. The recommended OAuth2 flow for web apps and native apps is the Authorization Code Flow with Proof Key for Code Exchange (PKCE).

A general `komunitin_social` OAuth2 scope is required to access this API.

#### Accounting

This API depends on an Accounting service wich by default is the [Komunitin Accounting Protocol](https://github.com/komunitin/komunitin-api/blob/master/accounting/README.md). However the definition allows to replace it by another accounting API that has the concepts of currency and account.

Concretely, the `group` resource has the `currency` external relationship and the `member` resource has the `account` external relationship.

External relaitonships are defined in a custom extension profile of JSON:API: [External relationships](https://github.com/komunitin/komunitin-api/blob/master/jsonapi-profiles/external.md).

The similar structure helps implementators to reuse some of the code handling relationships, although the automatic inclusion is not generally available for external relationships.

#### Media

File server is out of the scope of this API, and should be handled using a separate specialized service. This way we ease the implementation of advanced upload techniques and efficient delivery of static binary files. File URLs should be randomized in order to minimize unauthorized access to files. Additional security measures such as short-lived Signed URLs can be implemented to further restrict access to binary files.\\

\\


# Notifications

The notifications service (`notifications-ts`) is a service written in TypeScript (Node.js) responsible for orchestrating and delivering messages to users across multiple channels (Web Push, Email, In-App) in response to system events.

It listens for events from other services (Accounting, Social), processes them, and dispatches notifications based on user preferences and system logic. It also generates "synthetic" events for reminders, expirations, and activity digests.

### Channels

#### Web Push

The service uses the **Standard Web Push** protocol to send notifications to browsers and PWAs, without relying on any third-party services. The flow is as follows:

* **Subscription**: The Client App subscribes using the browser's Push API and sends the subscription details (endpoint, keys) to the Notifications API.
* **Storage**: Subscriptions are stored in the PostgreSQL database.
* **Delivery**: When a push notification is triggered, it is queued to be processed asynchronously.
* **Telemetry**: The server listens for delivery receipts and user interactions (clicks, dismisses) to track engagement and delivery success, without relying on third-party analytics.

#### Email

Emails are sent for important events or digests and are sent through any configured SMTP service.

#### In-App

Notifications are also stored in the database for display within the application's notification center.

## Data Storage

* **PostgreSQL**: Stores persistent data such as User Subscriptions, In-App Notifications, and delivery logs. Access is managed via **Prisma ORM**.
* **Redis**:
  * **Streams**: For ingesting events from other microservices.
  * **BullMQ**: For managing job queues (synthetic event scheduling, push delivery queues).
  * **Cache**: For caching API responses from other services.


# Project

### Purpose

Komunitin aims to be the leading open source project for community currency exchanges by providing an engaging and decentralized, yet reliable application they can all use.

### Offer

As a community currency administrator you can use Komunitin in two ways:

* From the common instance at komunitin.org. Just fill a form to create your own currency, wait for it to be accepted and you can start configuring the details of your currency and onboarding new members. You need to accept the [terms of use](/project/terms-of-use) and make a small contribution to the system maintenance.
* Deploy your own instance. All the software in komunitin project is open source and ready to be deployed in your own server, provided you have the required infrastructure and technical skills.

## Roadmap

Komunitin and its predecessor IntegralCES has been developed and supported by the community for more than 10 years. We have a concrete roadmap but we don't have concrete deadlines, as the speed of development depends on available funding and voluntary work.

The team is doing an epic effort to convert our old centralized system to a modern, engaging, easy to use, secure and decentralized app.

The four main stages of the development roadmap match the four components of the whole Komunitin system:

1. Komunitin app
2. Notifications service
3. Accounting service
4. Social service

At this moment we have published and working versions for the Komunitin app and the Notifications service at [komunitin.org](http://komunitin.org) and we're actively developing the Accounting service using the [Stellar](https://stellar.org) blockchain.

After that, we'll upgrade the social service (offers, needs, profiles, locations, governance). The goal will be to create or integrate a federated/decentralized marketplace (and other social features) for community currencies.

### Technical Contribution

This project is open to contributions. Just fork the code and open a Pull Request in the project [Github](https://github.com/komunitin/komunitin). We are also welcome bug reports and are open to feature requests at the Github issue queue, but our time to answer all questions is limited.

### Paid services

Need some new feature, a custom design and/or domain but don't want to do it by yourself? We can customize a komunitin app for you. Need some further professional support? Contact us for a quote.

### Stellar award

This project has received the **Activation award** from the **Stellar Development Foundation** :tada:. This award allowed the development team to fund the development of the 3rd point: the Accounting Service and completely replace the old interface by the new app. Thanks Stellar!

\\


# Terms of Use

## Introduction

Komunitin is a software for managing community currencies. It is a major upgrade from the previous project [IntegralCES](https://es.wikipedia.org/wiki/IntegralCES) which in turn was conceived as an open source alternative to the popular [Community Exchange System](https://community-exchange.org). Komunitin is licensed under AGPL 3.0 and is distributed completely free of charge under the terms of this open source license from the source code repository.

The server [komunitin.org](https://komunitin.org) hosts an installation of Komunitin managed by the maintainers of the software.

## Objective

The purpose of the service [komunitin.org](https://komunitin.org) is to provide virtual support for community currencies aimed at facilitating mutual aid networks and collectives that use community currencies as a tool for cooperation, the common good, ecological and economic sustainability and solidarity.

## Who can use it

The service is available to all collectives that use community currencies for social purposes, for the common good, without profit motives in currency management, and with respectful behavior and a collaborative attitude towards other users and the Komunitin project. Any individual or collective deemed to be making inappropriate use of the service may be expelled.

For other uses of the service, please contact us.

## Legal nature of community currencies

Community currencies managed through this service are units of measure used to record contributions and exchanges between members within their respective communities. These currencies have no intrinsic monetary value and are not redeemable for fiat national currency, legal tender, or any other form of economic value. Users acknowledge that participation in these exchange systems is voluntary and that the currencies used have no financial value.

However, users must understand that while the community currencies themselves have no monetary value, the actual economic activities, goods, and services exchanged through this system may be subject to applicable local, national, and international laws and regulations. This includes, but is not limited to, tax obligations, licensing requirements, and other legal responsibilities that may apply to the provision of goods or services. Each user is solely responsible for understanding and complying with all applicable laws and regulations in their jurisdiction and we encourage communities to facilitate compliance. Komunitin provides only the technical infrastructure for recording exchanges and assume no responsibility for users' legal compliance.

## Shared maintenance

The maintenance costs of komunitin.org are divided into:

* Hosting (hardware, server administration, domains, certificates).
* Service administration (registrations, migrations, support, updates).
* Software maintenance (bug fixes, adaptation to new library versions).
* Software and service improvement (development of new features and enhancement of existing ones).

The maintenance of the service at komunitin.org is equitably covered by the various networks that use it. The contribution for maintaining the service will not be made individually, but rather each community will contribute collectively. Obviously, the different collectives will obtain these resources in the way they find most convenient.

The contribution may be made using your own community currency, provided you have external payments enabled.

### Amount of Contribution per Exchange Network

We calculate the contribution corresponding to each network based on the community's size. Many different parameters can be used to measure the size of the community. For simplicity and to avoid penalizing more active communities and users, we will simply use the number of accounts per community.

The contribution will specifically be 0.1 HOUR per account per year. A network with 100 accounts will need to contribute 10 HOUR annually to the project.

Note that the HOUR is the virtual unit that measures the value of every other currency in komunitin. For reference, this may be aproximately equivalent to 1€/account.

This figure is a minimum that we hope will help covering maintenance costs initially and ensure the long-term development of the project. The goal is not to generate financial profit from the development or management of the service, but only to ensure its proper maintenance and setup a healthy and sustainable financial scheme from the begining.

## Organization and Decision-Making

The organisational structure is currently very small and simple. There is a Telegram community with all currency administrators at komunitin.org where we can discuss any issue. For the technical discussions (including bug reports, improvement requests, etc) there is the issue queue at Github project.

Decisions are made currently by the development team, but the team is open to improve the structure as the project grows so all the community has voice and vote.


# New community

To open a new community with its own currency on komunitin.org, please read carefully and follow the instructions below.

## Do you really want to open a new community?

If you want to create an account in an existing community, go to [komunitn.org](https://komunitin.org) and find your local community.

If you are evaluating the system please use the [Demo Site](/readme/demo). Please do not create a new community just to test it, as this creates management work for us and uses up resources.

Please read the [Terms of Use](/project/terms-of-use) and be sure you're comfortable with them.

Creating a community currency exchange network that is truly useful is a task that requires a lot of dedication and effort. There are many cases of networks that start without a sufficiently motivated community to drive them and end up failing. So before taking the step and opening the community, it is important to carefully consider the objectives and characteristics of the currency, how you will spread the idea, how you will manage incidents, and to research how similar experiences to yours work... Once everything is ready, go ahead!

## Import data

If your network is already running on another system, maybe we can automatically import all the data without losing the history. In this case, do not fill out the form but instead [contact us](/project/contact) directly, and we will check the best way to do it.

## Apply

To register a new community in the system, you need to fill out a form. Note the Code field (four uppercase letters), which will be the identifier of your network and the four letters that all account numbers will start with. Choose carefully the name of the currency and the symbol as well.

After the community is approved you'll access the administrative interface and you'll be able to tune the settings.

Go to the following link to apply for a new currency:

{% embed url="<https://komunitin.org/signup-group>" %}


# Contact

### Newsletter

Want to be aware of the main news around Komunitin? Subscribe to the newsletter here.

{% embed url="<https://subscribe.komunitin.org>" %}

### Email

Send us a mail to <info@komunitin.org>.

###


