├── monitor ├── .npmrc ├── static │ ├── logo.png │ ├── favicon.png │ ├── kotlin_logo.png │ ├── ktor_logo.png │ ├── logo_meta.png │ └── svelte_logo.png ├── postcss.config.cjs ├── .gitignore ├── vite.config.ts ├── src │ ├── components │ │ ├── buttons │ │ │ ├── BlueButton.svelte │ │ │ ├── GreenButton.svelte │ │ │ └── GrayButton.svelte │ │ ├── PercentageBar.svelte │ │ ├── Head.svelte │ │ ├── containers │ │ │ ├── TitleAndTextContainerGreen.svelte │ │ │ └── TitleAndTextContainer.svelte │ │ ├── toggle-box │ │ │ └── ToggleBox.svelte │ │ ├── Footer.svelte │ │ ├── charts │ │ │ ├── PieChartWithLabels.svelte │ │ │ ├── LineChart.svelte │ │ │ ├── LineColumnChartWithLabels.svelte │ │ │ ├── AreaChartWithLabels.svelte │ │ │ ├── LineChartWithLabels.svelte │ │ │ ├── ColumnChart.svelte │ │ │ ├── ColumnChartWithLabels.svelte │ │ │ ├── CircleChart.svelte │ │ │ └── AreaChart.svelte │ │ ├── grids │ │ │ └── Grid.svelte │ │ └── nav │ │ │ └── TopNavButton.svelte │ ├── app.d.ts │ ├── routes │ │ ├── profile │ │ │ └── +page.svelte │ │ ├── nodes │ │ │ └── [name] │ │ │ │ ├── +layout.server.js │ │ │ │ └── +page.svelte │ │ ├── +layout.svelte │ │ ├── login │ │ │ └── +page.svelte │ │ └── +layout.server.js │ ├── helpers │ │ ├── colors.js │ │ └── helpers.js │ ├── stores │ │ ├── user.js │ │ └── data.js │ ├── app.scss │ ├── api │ │ ├── nodes.js │ │ ├── login.js │ │ └── hugin.js │ ├── app.html │ ├── theme │ │ └── chart.scss │ └── server │ │ └── github.server.js ├── Dockerfile ├── .run │ ├── build.run.xml │ └── dev.run.xml ├── tailwind.config.cjs ├── tsconfig.json ├── svelte.config.js ├── package.json └── yarn-error.log ├── settings.gradle.kts ├── scripts ├── stop_docker.sh ├── rebuild_all_docker.sh ├── setup_all_docker.sh ├── setup_monitor_docker.sh ├── rebuild_backend_docker.sh ├── setup_backend_docker.sh ├── rebuild_monitor_docker.sh ├── remove_docker.sh ├── postsencrypted_amount_1h.sql ├── postsencrypted_amount_24h.sql └── smoke-test.py ├── http ├── info.http ├── blocks.http ├── nodes.http ├── pools.http ├── outputs.http ├── supplies.http ├── hashrates.http ├── statistics.http ├── transactions.http ├── posts_encrypted.http └── posts_encrypted_group.http ├── resources ├── icon.png ├── logo.png ├── logo.psd ├── logo_github.png ├── logo_github.psd ├── logo_slate.png └── poweredby │ ├── docker.png │ ├── kotlin.png │ ├── ktor.png │ ├── svelte.png │ ├── ansible.png │ ├── keycloak.png │ ├── liquibase.png │ ├── postgresql.png │ ├── prometheus.png │ └── githubactions.png ├── ansible ├── roles │ ├── prometheus │ │ ├── vars │ │ │ ├── debian.yml │ │ │ ├── centos.yml │ │ │ ├── redhat.yml │ │ │ ├── centos-8.yml │ │ │ ├── fedora.yml │ │ │ ├── redhat-8.yml │ │ │ └── main.yml │ │ ├── molecule │ │ │ ├── default │ │ │ │ ├── prepare.yml │ │ │ │ ├── playbook.yml │ │ │ │ ├── tests │ │ │ │ │ └── test_default.py │ │ │ │ └── molecule.yml │ │ │ ├── latest │ │ │ │ ├── playbook.yml │ │ │ │ ├── tests │ │ │ │ │ └── test_alternative.py │ │ │ │ └── molecule.yml │ │ │ └── alternative │ │ │ │ ├── prepare.yml │ │ │ │ ├── tests │ │ │ │ └── test_alternative.py │ │ │ │ └── molecule.yml │ │ ├── templates │ │ │ ├── alert.rules.j2 │ │ │ ├── node_exporter.service.j2 │ │ │ ├── prometheus.yml.j2 │ │ │ └── prometheus.service.j2 │ │ ├── handlers │ │ │ └── main.yml │ │ ├── meta │ │ │ └── main.yml │ │ └── tasks │ │ │ ├── main.yml │ │ │ └── configure.yml │ ├── postgres │ │ ├── handlers │ │ │ └── main.yml │ │ ├── templates │ │ │ └── remove_data.sql.j2 │ │ └── tasks │ │ │ └── main.yml │ ├── nginx │ │ ├── handlers │ │ │ └── main.yml │ │ ├── templates │ │ │ ├── nginx-http.j2 │ │ │ └── nginx.conf.j2 │ │ └── tasks │ │ │ └── main.yml │ ├── docker │ │ ├── handlers │ │ │ └── main.yml │ │ └── tasks │ │ │ ├── docker-users.yml │ │ │ └── main.yml │ ├── liquibase │ │ ├── templates │ │ │ └── liquibase.properties.j2 │ │ └── tasks │ │ │ └── main.yml │ ├── node │ │ └── tasks │ │ │ └── main.yml │ ├── monitor │ │ └── tasks │ │ │ └── main.yml │ ├── backend │ │ └── tasks │ │ │ └── main.yml │ └── base │ │ └── tasks │ │ └── main.yml ├── ansible.cfg ├── prod.inventory ├── staging.inventory ├── ansible.sh ├── provision_vps.yml └── group_vars │ └── vps │ └── vps.yml ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── renovate.json ├── local.properties ├── liquibase.properties ├── MAINTAINERS.md ├── .jpb ├── jpb-settings.xml └── persistence-units.xml ├── Dockerfile ├── gradle.properties ├── src ├── test │ └── kotlin │ │ └── org │ │ └── kryptokrona │ │ └── api │ │ ├── ApplicationTest.kt │ │ └── routes │ │ └── BlockRoutesTest.kt └── main │ ├── resources │ ├── db │ │ └── changelog │ │ │ ├── 2023 │ │ │ └── 04 │ │ │ │ └── 0001.xml │ │ │ └── master.xml │ └── application.conf │ └── kotlin │ └── org │ └── kryptokrona │ └── api │ ├── models │ ├── response │ │ ├── NodeListResponse.kt │ │ ├── ExceptionResponse.kt │ │ └── ResultResponse.kt │ ├── request │ │ └── NodeRequest.kt │ ├── Hashrate.kt │ ├── Supply.kt │ ├── Block.kt │ ├── Output.kt │ ├── Node.kt │ ├── PostEncrypted.kt │ ├── PostEncryptedGroup.kt │ └── Pool.kt │ ├── utils │ ├── HttpClient.kt │ ├── Box.kt │ ├── SealedBox.kt │ ├── NewBox.kt │ ├── Metrics.kt │ ├── JsonUtil.kt │ └── HuginCrypto.kt │ ├── syncers │ └── BlockSyncer.kt │ ├── config │ ├── HuginConfig.kt │ ├── InitialSyncConfig.kt │ └── DiscordConfig.kt │ ├── services │ ├── pool │ │ └── PoolService.kt │ ├── block │ │ └── BlockService.kt │ ├── output │ │ └── OutputService.kt │ ├── supply │ │ └── SupplyService.kt │ ├── hashrate │ │ └── HashrateService.kt │ ├── transaction │ │ └── TransactionService.kt │ ├── node │ │ └── NodeService.kt │ ├── postencrypted │ │ ├── PostEncryptedService.kt │ │ └── PostEncryptedStatisticsService.kt │ └── postencryptedgroup │ │ ├── PostEncryptedGroupService.kt │ │ └── PostEncryptedGroupStatisticsService.kt │ └── plugins │ ├── Syncers.kt │ ├── Routing.kt │ └── DatabaseFactory.kt ├── prometheus.yml ├── SECURITY.md ├── .gitignore ├── .github ├── FUNDING.yml └── workflows │ ├── monitor-pr-ci.yml │ ├── monitor-ci.yml │ └── deploy-cd.yml ├── .run ├── migrate.run.xml ├── tests.run.xml └── server.run.xml ├── public-api-list.json ├── LICENSE └── docker-compose.yml /monitor/.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "kryptokrona-api" -------------------------------------------------------------------------------- /scripts/stop_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # stop docker compose 4 | (cd ../ && docker-compose down) -------------------------------------------------------------------------------- /http/info.http: -------------------------------------------------------------------------------- 1 | ### get all info 2 | GET http://localhost:8080/api/v1/info 3 | Accept: application/json -------------------------------------------------------------------------------- /resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/resources/icon.png -------------------------------------------------------------------------------- /resources/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/resources/logo.png -------------------------------------------------------------------------------- /resources/logo.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/resources/logo.psd -------------------------------------------------------------------------------- /http/blocks.http: -------------------------------------------------------------------------------- 1 | ### get all blocks 2 | GET http://localhost:8080/api/v1/blocks 3 | Accept: application/json -------------------------------------------------------------------------------- /http/nodes.http: -------------------------------------------------------------------------------- 1 | ### get all nodes 2 | GET http://localhost:8080/api/v1/nodes 3 | Accept: application/json -------------------------------------------------------------------------------- /http/pools.http: -------------------------------------------------------------------------------- 1 | ### get all pools 2 | GET http://localhost:8080/api/v1/pools 3 | Accept: application/json -------------------------------------------------------------------------------- /http/outputs.http: -------------------------------------------------------------------------------- 1 | ### get all outputs 2 | GET http://localhost:8080/api/v1/outputs 3 | Accept: application/json -------------------------------------------------------------------------------- /http/supplies.http: -------------------------------------------------------------------------------- 1 | ### get all supplies 2 | GET http://localhost:8080/api/v1/supplies 3 | Accept: application/json -------------------------------------------------------------------------------- /monitor/static/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/monitor/static/logo.png -------------------------------------------------------------------------------- /resources/logo_github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/resources/logo_github.png -------------------------------------------------------------------------------- /resources/logo_github.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/resources/logo_github.psd -------------------------------------------------------------------------------- /resources/logo_slate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/resources/logo_slate.png -------------------------------------------------------------------------------- /http/hashrates.http: -------------------------------------------------------------------------------- 1 | ### get all hashrates 2 | GET http://localhost:8080/api/v1/hashrates 3 | Accept: application/json -------------------------------------------------------------------------------- /monitor/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/monitor/static/favicon.png -------------------------------------------------------------------------------- /http/statistics.http: -------------------------------------------------------------------------------- 1 | ### get all statistics 2 | GET http://localhost:8080/api/v1/statistics 3 | Accept: application/json -------------------------------------------------------------------------------- /monitor/static/kotlin_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/monitor/static/kotlin_logo.png -------------------------------------------------------------------------------- /monitor/static/ktor_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/monitor/static/ktor_logo.png -------------------------------------------------------------------------------- /monitor/static/logo_meta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/monitor/static/logo_meta.png -------------------------------------------------------------------------------- /monitor/static/svelte_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/monitor/static/svelte_logo.png -------------------------------------------------------------------------------- /resources/poweredby/docker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/resources/poweredby/docker.png -------------------------------------------------------------------------------- /resources/poweredby/kotlin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/resources/poweredby/kotlin.png -------------------------------------------------------------------------------- /resources/poweredby/ktor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/resources/poweredby/ktor.png -------------------------------------------------------------------------------- /resources/poweredby/svelte.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/resources/poweredby/svelte.png -------------------------------------------------------------------------------- /ansible/roles/prometheus/vars/debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | prometheus_selinux_packages: 3 | - python-selinux 4 | - policycoreutils 5 | -------------------------------------------------------------------------------- /http/transactions.http: -------------------------------------------------------------------------------- 1 | ### get all transactions 2 | GET http://localhost:8080/api/v1/transactions 3 | Accept: application/json -------------------------------------------------------------------------------- /resources/poweredby/ansible.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/resources/poweredby/ansible.png -------------------------------------------------------------------------------- /resources/poweredby/keycloak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/resources/poweredby/keycloak.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /monitor/postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /resources/poweredby/liquibase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/resources/poweredby/liquibase.png -------------------------------------------------------------------------------- /resources/poweredby/postgresql.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/resources/poweredby/postgresql.png -------------------------------------------------------------------------------- /resources/poweredby/prometheus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/resources/poweredby/prometheus.png -------------------------------------------------------------------------------- /ansible/roles/postgres/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Restart Postgres 3 | service: 4 | name: postgresql 5 | state: restarted -------------------------------------------------------------------------------- /ansible/roles/prometheus/vars/centos.yml: -------------------------------------------------------------------------------- 1 | --- 2 | prometheus_selinux_packages: 3 | - libselinux-python 4 | - policycoreutils-python 5 | -------------------------------------------------------------------------------- /ansible/roles/prometheus/vars/redhat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | prometheus_selinux_packages: 3 | - libselinux-python 4 | - policycoreutils-python 5 | -------------------------------------------------------------------------------- /http/posts_encrypted.http: -------------------------------------------------------------------------------- 1 | ### get all encrypted posts 2 | GET http://localhost:8080/api/v1/posts-encrypted 3 | Accept: application/json -------------------------------------------------------------------------------- /resources/poweredby/githubactions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kryptokrona/kryptokrona-api/HEAD/resources/poweredby/githubactions.png -------------------------------------------------------------------------------- /ansible/roles/prometheus/molecule/default/prepare.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Prepare 3 | hosts: all 4 | gather_facts: false 5 | tasks: [] 6 | -------------------------------------------------------------------------------- /ansible/roles/prometheus/vars/centos-8.yml: -------------------------------------------------------------------------------- 1 | --- 2 | prometheus_selinux_packages: 3 | - python3-libselinux 4 | - python3-policycoreutils 5 | -------------------------------------------------------------------------------- /ansible/roles/prometheus/vars/fedora.yml: -------------------------------------------------------------------------------- 1 | --- 2 | prometheus_selinux_packages: 3 | - python3-libselinux 4 | - python3-policycoreutils 5 | -------------------------------------------------------------------------------- /ansible/roles/prometheus/vars/redhat-8.yml: -------------------------------------------------------------------------------- 1 | --- 2 | prometheus_selinux_packages: 3 | - python3-libselinux 4 | - python3-policycoreutils 5 | -------------------------------------------------------------------------------- /ansible/roles/nginx/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Reload Nginx 3 | become: yes 4 | service: 5 | name: nginx 6 | state: reloaded 7 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:base" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /http/posts_encrypted_group.http: -------------------------------------------------------------------------------- 1 | ### get all encrypted group posts 2 | GET http://localhost:8080/api/v1/posts-encrypted-group 3 | Accept: application/json -------------------------------------------------------------------------------- /local.properties: -------------------------------------------------------------------------------- 1 | liquibase.dev.url=jdbc:postgresql://localhost:5432/kryptokrona_api_dev 2 | liquibase.dev.user=postgres 3 | liquibase.dev.password=test1234 -------------------------------------------------------------------------------- /ansible/roles/docker/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Restart Docker 3 | service: 4 | name: docker 5 | state: restarted 6 | ignore_errors: "{{ ansible_check_mode }}" -------------------------------------------------------------------------------- /ansible/roles/prometheus/molecule/default/playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Run role 3 | hosts: all 4 | any_errors_fatal: true 5 | roles: 6 | - cloudalchemy.prometheus 7 | -------------------------------------------------------------------------------- /ansible/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | host_key_checking = False 3 | inventory=./inventory 4 | deprecation_warnings=False 5 | ansible_python_interpreter=/usr/bin/python3 6 | timeout = 120 -------------------------------------------------------------------------------- /monitor/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | vite.config.js.timestamp-* 10 | vite.config.ts.timestamp-* 11 | -------------------------------------------------------------------------------- /ansible/roles/prometheus/molecule/latest/playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Run role 3 | hosts: all 4 | any_errors_fatal: true 5 | roles: 6 | - cloudalchemy.prometheus 7 | vars: 8 | prometheus_version: latest 9 | -------------------------------------------------------------------------------- /liquibase.properties: -------------------------------------------------------------------------------- 1 | # only used for docker compose 2 | url=jdbc:postgresql://db:5432/kryptokrona_api_dev 3 | username=postgres 4 | password=test1234 5 | changeLogFile=/db/changelog/master.xml 6 | driver=org.postgresql.Driver -------------------------------------------------------------------------------- /ansible/roles/docker/tasks/docker-users.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure Docker users are added to the docker group 3 | user: 4 | name: "{{ item }}" 5 | groups: docker 6 | append: true 7 | with_items: "{{ docker_users }}" -------------------------------------------------------------------------------- /scripts/rebuild_all_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # remove old images 4 | docker-compose down --rmi all 5 | 6 | # start docker compose with all services 7 | docker-compose -f ../docker-compose.yml up -V -d --build --force-recreate -------------------------------------------------------------------------------- /MAINTAINERS.md: -------------------------------------------------------------------------------- 1 | # List of maintainers and how to submit Kryptokrona API changes 2 | 3 | ## Maintainers List 4 | 5 | - [mjovanc](https://github.com/mjovanc) 6 | - [appelskrutt34](https://github.com/appelskrutt34) 7 | -------------------------------------------------------------------------------- /scripts/setup_all_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # inject keycloak hostname 4 | sudo -- sh -c -e "echo '127.0.0.1 keycloak' >> /etc/hosts" 5 | 6 | # start docker compose with all services 7 | docker-compose -f ../docker-compose.yml up -d -------------------------------------------------------------------------------- /monitor/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { sveltekit } from '@sveltejs/kit/vite'; 2 | import { defineConfig } from 'vite'; 3 | 4 | export default defineConfig({ 5 | plugins: [sveltekit()], 6 | build: { 7 | outDir: "./build" 8 | } 9 | }); 10 | -------------------------------------------------------------------------------- /ansible/roles/prometheus/templates/alert.rules.j2: -------------------------------------------------------------------------------- 1 | {{ ansible_managed | comment }} 2 | 3 | groups: 4 | - name: ansible managed alert rules 5 | rules: 6 | {{ prometheus_alert_rules | to_nice_yaml(indent=2,sort_keys=False) | indent(2,False) }} 7 | -------------------------------------------------------------------------------- /ansible/prod.inventory: -------------------------------------------------------------------------------- 1 | # hosts.inventory 2 | # add hostname or IP under vps 3 | 4 | [vps] 5 | xkr.mjovanc.com letsencrypt_email=mjovanc@icloud.com domain_name=xkr.mjovanc.com exporter_version=1.3.1 6 | 7 | [server] 8 | localhost ansible_connection=local 9 | -------------------------------------------------------------------------------- /ansible/staging.inventory: -------------------------------------------------------------------------------- 1 | # hosts.inventory 2 | # add hostname or IP under vps 3 | 4 | [vps] 5 | stage.xkr.mjovanc.com letsencrypt_email=mjovanc@icloud.com domain_name=stage.xkr.mjovanc.com exporter_version=1.3.1 6 | 7 | [server] 8 | localhost ansible_connection=local 9 | -------------------------------------------------------------------------------- /monitor/src/components/buttons/BlueButton.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 | 10 | -------------------------------------------------------------------------------- /monitor/src/components/buttons/GreenButton.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 | 10 | -------------------------------------------------------------------------------- /ansible/roles/liquibase/templates/liquibase.properties.j2: -------------------------------------------------------------------------------- 1 | url=jdbc:postgresql://127.0.0.1:5432/{{ vault_postgres_db_name }} 2 | username={{ vault_postgres_db_user }} 3 | password={{ vault_postgres_db_password }} 4 | changeLogFile=/db/changelog/master.xml 5 | driver=org.postgresql.Driver -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /scripts/setup_monitor_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # inject keycloak hostname 4 | sudo -- sh -c -e "echo '127.0.0.1 keycloak' >> /etc/hosts" 5 | 6 | # start docker compose with monitor (used for developing the monitor) 7 | docker-compose -f ../docker-compose.yml up -d db liquibase monitor keycloak -------------------------------------------------------------------------------- /scripts/rebuild_backend_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # removing old images 4 | docker-compose down --rmi all 5 | 6 | # start docker compose with backend (used for developing the monitor) 7 | docker-compose -f ../docker-compose.yml up -V -d --build --force-recreate db liquibase backend prometheus keycloak -------------------------------------------------------------------------------- /scripts/setup_backend_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # inject keycloak hostname 4 | sudo -- sh -c -e "echo '127.0.0.1 keycloak' >> /etc/hosts" 5 | 6 | # start docker compose with backend (used for developing the monitor) 7 | docker-compose -f ../docker-compose.yml up -d db liquibase backend prometheus keycloak -------------------------------------------------------------------------------- /ansible/roles/prometheus/templates/node_exporter.service.j2: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Node Exporter 3 | After=network.target 4 | 5 | [Service] 6 | User=node_exporter 7 | Group=node_exporter 8 | Type=simple 9 | ExecStart=/usr/local/bin/node_exporter 10 | 11 | [Install] 12 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /monitor/src/app.d.ts: -------------------------------------------------------------------------------- 1 | // See https://kit.svelte.dev/docs/types#app 2 | // for information about these interfaces 3 | declare global { 4 | namespace App { 5 | // interface Error {} 6 | // interface Locals {} 7 | // interface PageData {} 8 | // interface Platform {} 9 | } 10 | } 11 | 12 | export {}; 13 | -------------------------------------------------------------------------------- /ansible/roles/prometheus/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart prometheus 3 | become: true 4 | systemd: 5 | daemon_reload: true 6 | name: prometheus 7 | state: restarted 8 | 9 | - name: reload prometheus 10 | become: true 11 | systemd: 12 | name: prometheus 13 | state: reloaded 14 | -------------------------------------------------------------------------------- /ansible/roles/prometheus/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | go_arch_map: 3 | i386: '386' 4 | x86_64: 'amd64' 5 | aarch64: 'arm64' 6 | armv7l: 'armv7' 7 | armv6l: 'armv6' 8 | 9 | go_arch: "{{ go_arch_map[ansible_architecture] | default(ansible_architecture) }}" 10 | _prometheus_binary_install_dir: '/usr/local/bin' 11 | -------------------------------------------------------------------------------- /monitor/src/routes/profile/+page.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 |
7 |

{$user.username}

8 | 9 |
10 | -------------------------------------------------------------------------------- /monitor/src/routes/nodes/[name]/+layout.server.js: -------------------------------------------------------------------------------- 1 | export const ssr = true; 2 | import {getNode} from "../../../api/nodes"; 3 | 4 | export const load = async ({ url }) => { 5 | const searchparams = new URLSearchParams(url.searchParams); 6 | let node = await getNode(searchparams.get("name"), searchparams.get("port")); 7 | return { node }; 8 | }; 9 | -------------------------------------------------------------------------------- /scripts/rebuild_monitor_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # remove old images 4 | docker rm kryptokrona_api_db 5 | docker rm kryptokrona_api_monitor 6 | docker rm kryptokrona_api_liquibase 7 | 8 | # start docker compose to setup monitor (used for developing the backend) 9 | docker-compose -f ../docker-compose.yml up -V -d --build --force-recreate db liquibase monitor -------------------------------------------------------------------------------- /.jpb/jpb-settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM gradle:8-jdk17 AS build 2 | COPY --chown=gradle:gradle . /home/gradle/src 3 | WORKDIR /home/gradle/src 4 | RUN gradle shadowJar --no-daemon 5 | 6 | FROM openjdk:17.0.2 7 | EXPOSE 8080:8080 8 | RUN mkdir /app 9 | COPY --from=build /home/gradle/src/build/libs/kryptokrona-api-shadow.jar /app/ktor.jar 10 | ENTRYPOINT ["sh", "-c", "sleep 15 && java -jar /app/ktor.jar"] -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | ktor_version=2.3.1 2 | kotlin_version=1.8.21 3 | logback_version=1.4.6 4 | kotlin.code.style=official 5 | postgres_version=42.6.0 6 | h2_version=2.1.214 7 | ktorm_version=3.6.0 8 | liquibase_core=4.22.0 9 | hikaricp_version=5.0.1 10 | ehcache_version=3.10.8 11 | ktorm_jackson_version=3.6.0 12 | slf4j_version=2.0.7 13 | kryptokrona_version=0.1.1 14 | prometheus_version=1.11.0 15 | dbEnv= -------------------------------------------------------------------------------- /ansible/roles/nginx/templates/nginx-http.j2: -------------------------------------------------------------------------------- 1 | server_tokens off; 2 | 3 | server { 4 | listen 80 default_server; 5 | server_name {{ domain_name }}; 6 | 7 | location /.well-known/acme-challenge { 8 | root /var/www/letsencrypt; 9 | try_files $uri $uri/ =404; 10 | } 11 | 12 | location / { 13 | rewrite ^ https://{{ domain_name }}$request_uri? permanent; 14 | } 15 | } -------------------------------------------------------------------------------- /monitor/src/components/PercentageBar.svelte: -------------------------------------------------------------------------------- 1 | 7 | 8 |
11 |
15 |
16 | -------------------------------------------------------------------------------- /monitor/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18-alpine AS builder 2 | WORKDIR /app 3 | COPY package*.json ./ 4 | RUN npm install --frozen-lockfile 5 | COPY . . 6 | RUN npm run build 7 | 8 | FROM node:18-alpine 9 | WORKDIR /app 10 | COPY --from=builder /app/build build/ 11 | COPY --from=builder /app/node_modules node_modules/ 12 | COPY --from=builder /app/package.json package.json 13 | EXPOSE 3000 14 | ENV NODE_ENV=production 15 | CMD [ "node", "./build/index.js" ] 16 | -------------------------------------------------------------------------------- /monitor/.run/build.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 5 | 6 | 22 | -------------------------------------------------------------------------------- /src/main/resources/db/changelog/master.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/test/kotlin/org/kryptokrona/api/routes/BlockRoutesTest.kt: -------------------------------------------------------------------------------- 1 | package org.kryptokrona.api.routes; 2 | 3 | import io.ktor.client.request.* 4 | import io.ktor.http.* 5 | import io.ktor.server.testing.* 6 | import kotlin.test.Test 7 | import kotlin.test.assertEquals 8 | 9 | class BlockRoutesTest { 10 | 11 | @Test 12 | fun blockRouteTest() = testApplication { 13 | client.get("/api/v1/blocks").apply { 14 | assertEquals(HttpStatusCode.OK, status) 15 | } 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /monitor/src/helpers/colors.js: -------------------------------------------------------------------------------- 1 | export const COLOR = { 2 | BLUE: "#1d4ed8", 3 | VIOLET: "#6d28d9", 4 | FUSCHIA: "#a21caf", 5 | ROSE: "#be123c", 6 | GREEN: "#15803d", 7 | INDIGO: "#4338ca", 8 | PURPLE: "#7e22ce", 9 | PINK: "#be185d", 10 | SKY: "#0369a1", 11 | RED: "#b91c1c", 12 | ORANGE: "#c2410c", 13 | }; 14 | 15 | export const COLORS = [ 16 | "#1d4ed8", 17 | "#6d28d9", 18 | "#a21caf", 19 | "#be123c", 20 | "#4338ca", 21 | "#7e22ce", 22 | "#be185d", 23 | "#0369a1", 24 | ]; 25 | -------------------------------------------------------------------------------- /prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 15s 3 | evaluation_interval: 15s 4 | 5 | scrape_configs: 6 | - job_name: 'prometheus' 7 | static_configs: 8 | - targets: ['localhost:9090'] 9 | - targets: ['localhost:9323'] 10 | 11 | - job_name: 'docker' 12 | static_configs: 13 | - targets: ['host.docker.internal:9323'] 14 | 15 | - job_name: 'backend' 16 | metrics_path: '/api/v1/info/requests/metrics' 17 | static_configs: 18 | - targets: [ 'backend:8080' ] 19 | -------------------------------------------------------------------------------- /ansible/roles/node/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create blockchain directory 3 | file: 4 | path: /root/.kryptokrona 5 | state: directory 6 | 7 | - name: Start Kryptokrona Node Container 8 | docker_container: 9 | name: "{{ docker_container_name_node }}" 10 | image: "{{ docker_image_node }}:latest" 11 | state: started 12 | pull: true 13 | force_kill: yes 14 | recreate: yes 15 | volumes: 16 | - "/root/.kryptokrona:/root/.kryptokrona" 17 | networks: 18 | - name: "host" -------------------------------------------------------------------------------- /ansible/ansible.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # this file is intended for manually deploy from your local computer and not in the GitHub Actions workflow 3 | 4 | # checks if keypair doesn't exist 5 | if [ ! -f ~/.ssh/id_mjovanc ]; then 6 | ssh-keygen -t rsa -N "" -f ~/.ssh/id_mjovanc 7 | eval "$(ssh-agent -s)" &>/dev/null 8 | ssh-add ~/.ssh/id_mjovanc &>/dev/null 9 | ssh-copy-id -i ~/.ssh/id_mjovanc.pub root@xkr.mjovanc.com 10 | fi 11 | 12 | ansible-playbook provision_vps.yml -i staging.inventory --ask-vault-pass 13 | -------------------------------------------------------------------------------- /monitor/tailwind.config.cjs: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: ["./src/**/*.{html,js,svelte,ts}"], 4 | theme: { 5 | extend: {}, 6 | }, 7 | plugins: [], 8 | theme: { 9 | fontFamily: { 10 | roboto: ["Roboto Mono", "monospace", "sans-serif"], 11 | }, 12 | extend: { 13 | colors: { 14 | "beige-100": "#FFF8E7", 15 | "beige-200": "#F5E8CE", 16 | "beige-300": "#E8D4BA", 17 | "beige-400":"#CFB298" 18 | } 19 | } 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Versions currently supported. Will update this file once the project matures. 6 | 7 | | Version | Supported | 8 | | ------- | ------------------ | 9 | | 0.1.0 | :white_check_mark: | 10 | 11 | ## Reporting a Vulnerability 12 | 13 | If you find any vulnerability, please report them as an issue here on GitHub or Hugin Messenger in the group "Hugin". Join the group by using this group key: `4820de8e26d21981afe6de2ff7b62fa6aa01126482ca0faeff151886c73619e5`. 14 | -------------------------------------------------------------------------------- /src/main/resources/application.conf: -------------------------------------------------------------------------------- 1 | ktor { 2 | deployment { 3 | port = 8080 4 | } 5 | application { 6 | modules = [ org.kryptokrona.api.ApplicationKt.module ] 7 | } 8 | applicationEngine = "netty" 9 | } 10 | 11 | db { 12 | url = "jdbc:postgresql://127.0.0.1:5432/kryptokrona_api_dev" 13 | url = ${?DB_URL} 14 | user = postgres 15 | user = ${?DB_USER} 16 | password = test1234 17 | password = ${?DB_PASSWORD} 18 | driver = "org.postgresql.Driver" 19 | driver = ${?DB_DRIVER} 20 | } -------------------------------------------------------------------------------- /monitor/src/stores/user.js: -------------------------------------------------------------------------------- 1 | import {writable} from "svelte/store"; 2 | import {browser} from '$app/environment'; 3 | 4 | export const user = writable({}); 5 | 6 | if(browser){ 7 | const content = localStorage.getItem('user'); 8 | if(content){ 9 | user.set(JSON.parse(content)); 10 | } 11 | } 12 | 13 | export function setUser(username, email) { 14 | user.set({username, email}); 15 | localStorage.setItem('user', JSON.stringify(user)); 16 | } 17 | 18 | export function clearUser() { 19 | user.set({}); 20 | } 21 | -------------------------------------------------------------------------------- /monitor/.run/dev.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | 17 | 18 | -------------------------------------------------------------------------------- /monitor/src/stores/data.js: -------------------------------------------------------------------------------- 1 | import { writable } from "svelte/store"; 2 | 3 | export const nodes = writable([]); 4 | export const cpuUsage = writable(0); 5 | export const ramUsage = writable(0); 6 | export const diskUsage = writable(0); 7 | export const cpuUsageOverTime = writable({}); 8 | export const ramUsageOverTime = writable({}); 9 | export const diskUsageOverTime = writable({}); 10 | export const threads = writable(0); 11 | export const posts = writable([]); 12 | export const groupPosts = writable([]); 13 | export const totalPosts = writable(0); 14 | export const totalGroupPosts = writable(0); 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | build/ 3 | !gradle/wrapper/gradle-wrapper.jar 4 | !**/src/main/**/build/ 5 | !**/src/test/**/build/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | bin/ 16 | !**/src/main/**/bin/ 17 | !**/src/test/**/bin/ 18 | 19 | ### IntelliJ IDEA ### 20 | .idea 21 | *.iws 22 | *.iml 23 | *.ipr 24 | out/ 25 | !**/src/main/**/out/ 26 | !**/src/test/**/out/ 27 | 28 | ### NetBeans ### 29 | /nbproject/private/ 30 | /nbbuild/ 31 | /dist/ 32 | /nbdist/ 33 | /.nb-gradle/ 34 | 35 | ### VS Code ### 36 | .vscode/ 37 | 38 | .DS_Store -------------------------------------------------------------------------------- /monitor/src/components/containers/TitleAndTextContainerGreen.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 |
11 |
12 |

{title}

13 |
14 |
15 |

{text}

16 |
17 |
18 | 19 |
20 |
21 | -------------------------------------------------------------------------------- /monitor/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.svelte-kit/tsconfig.json", 3 | "compilerOptions": { 4 | "allowJs": true, 5 | "checkJs": false, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "resolveJsonModule": true, 9 | "skipLibCheck": true, 10 | "sourceMap": true, 11 | "strict": true 12 | }, 13 | // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias 14 | // 15 | // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes 16 | // from the referenced tsconfig.json - TypeScript does not merge them in 17 | } 18 | -------------------------------------------------------------------------------- /ansible/roles/postgres/templates/remove_data.sql.j2: -------------------------------------------------------------------------------- 1 | -- This file is used in the cron job to delete data periodically 2 | -- if we want to change for how long timespan we want to keep data 3 | -- you could add whole line inside the string below to 4 | -- 6 years 5 months 4 days 3 hours 2 minutes 1 second 5 | WITH posts_to_delete AS ( 6 | SELECT id 7 | FROM post 8 | WHERE created_at < CURRENT_DATE - '{{ removal_interval }}'::INTERVAL 9 | ), 10 | deleted_refs AS ( 11 | DELETE FROM post_hashtag ph 12 | WHERE ph.post_id IN (SELECT * FROM posts_to_delete) 13 | ) 14 | DELETE FROM post p 15 | WHERE p.id IN (SELECT * FROM posts_to_delete); -------------------------------------------------------------------------------- /monitor/src/helpers/helpers.js: -------------------------------------------------------------------------------- 1 | export function getShortdate(d) { 2 | var month = d.getMonth(); 3 | var day = d.getDate().toString().padStart(2, "0"); 4 | var year = d.getFullYear(); 5 | year = year.toString().substr(-2); 6 | month = (month + 1).toString().padStart(2, "0"); 7 | return month + "/" + day + "/" + year; 8 | } 9 | 10 | export const getLocaleString = (d) => { 11 | if (!d) return d; 12 | return new Date(d).toLocaleString(); 13 | }; 14 | 15 | export const getTwoDecimalsPercentage = (n) => { 16 | return n.toFixed(2) + "%"; 17 | }; 18 | 19 | export const getZeroDecimalsPercentage = (n) => { 20 | return n.toFixed(0) + "%"; 21 | }; 22 | -------------------------------------------------------------------------------- /monitor/src/components/containers/TitleAndTextContainer.svelte: -------------------------------------------------------------------------------- 1 | 8 | 9 |
10 |
11 |

{title}

12 |
13 |
14 |

{text}

15 |
16 |
17 | 18 |
19 |
20 | -------------------------------------------------------------------------------- /monitor/svelte.config.js: -------------------------------------------------------------------------------- 1 | import adapter from "@sveltejs/adapter-node"; 2 | import preprocess from "svelte-preprocess"; 3 | 4 | const config = { 5 | preprocess: preprocess({ 6 | postcss: true, 7 | scss: { 8 | prependData: `@import 'src/app.scss';`, 9 | }, 10 | }), 11 | onwarn: (warning, handler) => { 12 | const { code } = warning; 13 | if ( 14 | code === "css-semicolonexpected" || 15 | code === "css-ruleorselectorexpected" || 16 | code === "css-unused-selector" 17 | ) 18 | return; 19 | handler(warning); 20 | }, 21 | kit: { 22 | paths: { 23 | base: '/monitor', 24 | }, 25 | adapter: adapter(), 26 | }, 27 | }; 28 | 29 | export default config; 30 | -------------------------------------------------------------------------------- /src/main/kotlin/org/kryptokrona/api/utils/HttpClient.kt: -------------------------------------------------------------------------------- 1 | package org.kryptokrona.api.utils 2 | 3 | import io.ktor.client.* 4 | import io.ktor.client.plugins.* 5 | import io.ktor.client.plugins.contentnegotiation.* 6 | import io.ktor.serialization.kotlinx.json.* 7 | import kotlinx.serialization.json.Json 8 | 9 | /** 10 | * HTTP client singleton object 11 | */ 12 | object HttpClient { 13 | val client = HttpClient { 14 | install(ContentNegotiation) { 15 | json(Json { ignoreUnknownKeys = true }) 16 | } 17 | install(HttpRequestRetry) { 18 | retryOnServerErrors(maxRetries = 5) 19 | exponentialDelay() 20 | } 21 | install(HttpSend) { 22 | maxSendCount = 50 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /ansible/roles/prometheus/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: cloudalchemy 4 | role_name: prometheus 5 | description: Prometheus monitoring system configuration and management 6 | license: MIT 7 | company: none 8 | min_ansible_version: 2.7 9 | platforms: 10 | - name: Ubuntu 11 | versions: 12 | - bionic 13 | - xenial 14 | - name: Debian 15 | versions: 16 | - stretch 17 | - buster 18 | - name: EL 19 | versions: 20 | - 7 21 | - 8 22 | - name: Fedora 23 | versions: 24 | - 30 25 | - 31 26 | galaxy_tags: 27 | - monitoring 28 | - prometheus 29 | - metrics 30 | - alerts 31 | - alerting 32 | - molecule 33 | - cloud 34 | 35 | dependencies: [] 36 | -------------------------------------------------------------------------------- /ansible/roles/nginx/templates/nginx.conf.j2: -------------------------------------------------------------------------------- 1 | user www-data; 2 | worker_processes 4; 3 | pid /run/nginx.pid; 4 | 5 | events { 6 | worker_connections 768; 7 | } 8 | 9 | http { 10 | # websocket configuration 11 | map $http_upgrade $connection_upgrade { 12 | default upgrade; 13 | '' close; 14 | } 15 | 16 | sendfile on; 17 | tcp_nopush on; 18 | tcp_nodelay on; 19 | keepalive_timeout 65; 20 | types_hash_max_size 2048; 21 | include /etc/nginx/mime.types; 22 | default_type application/octet-stream; 23 | 24 | access_log /var/log/nginx/access.log; 25 | error_log /var/log/nginx/error.log; 26 | 27 | gzip on; 28 | gzip_disable "msie6"; 29 | 30 | include /etc/nginx/conf.d/*.conf; 31 | include /etc/nginx/sites-enabled/*; 32 | } -------------------------------------------------------------------------------- /ansible/roles/prometheus/molecule/latest/tests/test_alternative.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import os 3 | import testinfra.utils.ansible_runner 4 | 5 | testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( 6 | os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all') 7 | 8 | 9 | @pytest.mark.parametrize("files", [ 10 | "/etc/systemd/system/prometheus.service", 11 | "/usr/local/bin/prometheus", 12 | "/usr/local/bin/promtool" 13 | ]) 14 | def test_files(host, files): 15 | f = host.file(files) 16 | assert f.exists 17 | assert f.is_file 18 | 19 | 20 | def test_service(host): 21 | s = host.service("prometheus") 22 | # assert s.is_enabled 23 | assert s.is_running 24 | 25 | 26 | def test_socket(host): 27 | s = host.socket("tcp://0.0.0.0:9090") 28 | assert s.is_listening 29 | -------------------------------------------------------------------------------- /monitor/src/components/toggle-box/ToggleBox.svelte: -------------------------------------------------------------------------------- 1 | 11 | 12 |