added web-app and landing

This commit is contained in:
johba 2025-09-23 14:18:04 +02:00
parent af031877a5
commit 769fa105b8
198 changed files with 22132 additions and 10 deletions

30
landing/.gitignore vendored Normal file
View file

@ -0,0 +1,30 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist
dist-ssr
coverage
*.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
*.tsbuildinfo

118
landing/AGENTS.md Normal file
View file

@ -0,0 +1,118 @@
# Landing Interface - CLAUDE.md
Vue 3 + Vite application serving as the main interface for KRAIKEN protocol.
## Technology Stack
- **Vue 3** (Composition API)
- **TypeScript** - Type-safe development
- **Vite** - Fast build tooling
- **Vue Router** - Client-side routing
- **Sass** - Advanced styling
## Architecture
### Views
**HomeView.vue** - Landing page
- Launch countdown timer
- Project introduction
- Feature highlights
- Call-to-action for staking
**DocsView.vue** - Documentation portal
- Comprehensive protocol documentation
- Auto-generated table of contents
- Mobile-responsive navigation
- Sections: Introduction, Liquidity, AI Agent, Tokenomics, Staking, FAQ
### Key Components
**Layout Components**:
- `KNavbar.vue` - Main navigation with scroll effects
- `KFooter.vue` - Site footer
- `LeftRightComponent.vue` - Content layout helper
**UI Components**:
- `KButton.vue` - Reusable button with hover states
- `Countdown.vue` - Launch countdown display
- `SocialButton.vue` - Social media links
- `NavItem.vue` - Navigation menu items
**Icons** (`components/icons/`):
- Custom SVG icons for UI elements
- Social media icons (Twitter, Discord, Telegram)
## Styling
### Design System
- **Primary Color**: #07111B (deep ocean)
- **Accent**: #9667BE (purple)
- **Background**: Dark theme throughout
- **Typography**: Custom fonts (Audiowide, DM Sans, Orbitron)
### Responsive Design
- Mobile-first approach
- Breakpoint: 768px
- Slide-out mobile navigation
- Optimized images for different screen sizes
## Development Commands
```bash
# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run build
# Preview production build
npm run preview
# Type checking
npm run type-check
```
## Deployment
Configured for GitHub Pages:
- Hash-based routing for compatibility
- Base URL configuration in vite.config.ts
- Assets optimized for CDN delivery
## Future Integrations
### Wallet Connection (Planned)
- Web3 wallet integration
- Network switching to Base
- Transaction signing
### Staking Interface (Planned)
- Position management
- Tax rate adjustment
- Real-time position monitoring
- Snatching interface
### Data Visualization (Planned)
- Protocol metrics dashboard
- Liquidity depth charts
- Staking statistics
## Code Quality Guidelines
- Use Composition API for all components
- Leverage TypeScript for type safety
- Keep components small and focused
- Use Sass variables for consistent theming
- Follow Vue 3 best practices
## Performance Optimization
- Lazy load route components
- Optimize images (WebP format)
- Minimize bundle size
- Use CSS animations over JavaScript
- Implement proper caching strategies

33
landing/README.md Normal file
View file

@ -0,0 +1,33 @@
# vue-kraiken
This template should help get you started developing with Vue 3 in Vite.
## Recommended IDE Setup
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
## Type Support for `.vue` Imports in TS
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types.
## Customize configuration
See [Vite Configuration Reference](https://vite.dev/config/).
## Project Setup
```sh
npm install
```
### Compile and Hot-Reload for Development
```sh
npm run dev
```
### Type-Check, Compile and Minify for Production
```sh
npm run build
```

1
landing/env.d.ts vendored Normal file
View file

@ -0,0 +1 @@
/// <reference types="vite/client" />

14
landing/index.html Normal file
View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>KrAIken</title>
<script defer src="https://cloud.umami.is/script.js" data-website-id="6e2869f2-02a5-4346-9b3e-3c27e24ea5d3"></script>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

3796
landing/package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

31
landing/package.json Normal file
View file

@ -0,0 +1,31 @@
{
"name": "vue-kraiken",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "run-p type-check \"build-only {@}\" --",
"preview": "vite preview",
"build-only": "vite build",
"type-check": "vue-tsc --build",
"subtree": "git subtree push --prefix dist origin gh-pages"
},
"dependencies": {
"sass": "^1.83.4",
"vue": "^3.5.13",
"vue-router": "^4.5.0"
},
"devDependencies": {
"@tsconfig/node22": "^22.0.0",
"@types/node": "^22.10.7",
"@vitejs/plugin-vue": "^5.2.1",
"@vue/tsconfig": "^0.7.0",
"npm-run-all2": "^7.0.2",
"typescript": "~5.7.3",
"vite": "^6.0.11",
"vite-plugin-vue-devtools": "^7.7.0",
"vue-tsc": "^2.2.0",
"gh-pages": "^6.1.1"
}
}

BIN
landing/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

13
landing/src/App.vue Normal file
View file

@ -0,0 +1,13 @@
<script setup lang="ts">
import { RouterLink, RouterView } from 'vue-router'
import KFooter from '@/components/KFooter.vue'
import KNavbar from '@/components/KNavbar.vue'
</script>
<template>
<k-navbar />
<main>
<RouterView />
</main>
<k-footer />
</template>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View file

@ -0,0 +1,64 @@
@font-face
font-family: "DM Sans Regular"
src: url("@/assets/fonts/DMSans_Regular.ttf") format('truetype')
font-weight: 200
font-style: normal
@font-face
font-family: "DM Sans Medium"
src: url("@/assets/fonts/DMSans_Medium.ttf") format('truetype')
font-weight: 200
font-style: normal
@font-face
font-family: "exo2"
src: url("@/assets/fonts/exo2.ttf") format('truetype')
font-style: normal
@font-face
font-family: "orbitron"
src: url("@/assets/fonts/Orbitron.ttf") format('truetype')
font-style: normal
@font-face
font-family: "Audiowide"
src: url("@/assets/fonts/Audiowide-Regular.ttf") format('truetype')
*
font-family: 'exo2', sans-serif
font-weight: 50
html
body
margin: 0
background: radial-gradient(96.91% 121.32% at 1.49% 17.97%, rgba(117, 80, 174, 0.00) 46.5%, rgba(37, 37, 71, 0.50) 100%), radial-gradient(91.35% 111.13% at 12.96% 16.43%, rgba(117, 80, 174, 0.00) 46.5%, rgba(30, 34, 63, 0.50) 100%), var(--Color, #07111B)
margin: 0
font-family: 'Roboto', sans-serif
text-align: center
// variables
color: #F0F0F0
letter-spacing: 0.15px
font-size: 14px
@media (min-width: 992px)
font-size: 18px
#app
display: flex
flex-direction: column
min-height: 100vh
main
overflow-x: hidden
display: flex
flex-direction: column
padding-bottom: 120px
@media (min-width: 992px)
margin-top: 0
footer
margin-top: auto
.k-container
width: auto
margin-left: auto
margin-right: auto
display: flex
flex-direction: column
gap: 80px
padding: 0 32px
@media (min-width: 992px)
gap: 120px
width: 850px

View file

@ -0,0 +1,135 @@
<template>
<div class="countdown">
<div class="countdown__title">
Time until launch
</div>
<div class="countdown__time">
<slot :days="differenceDays" :hours="differenceHours" :minutes="differenceMinutes">
<div>{{ differenceDays }}d {{ differenceHours }}h {{ differenceMinutes }}m {{ differenceSeconds }}s</div>
</slot>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted, computed } from "vue";
const seconds = ref(0);
let _timerId:ReturnType<typeof setTimeout>;
interface Props {
modelValue: number;
end: Date;
}
const emit = defineEmits(["update:modelValue"]);
const props = withDefaults(defineProps<Props>(), {
modelValue: 0,
});
const differenceDays = computed(() => {
if(seconds.value <= 0){
return 0
}
return Math.floor(seconds.value / (3600 * 24))
});
//tage abziehen
const differenceHours = computed(() => {
if(seconds.value <= 0){
return 0
}
return Math.floor((seconds.value - differenceDays.value * 3600 * 24) / 3600)
});
//tage + stunden abziehen
const differenceMinutes = computed(() =>
{
if(seconds.value <= 0){
return 0
}
return Math.floor((seconds.value - differenceDays.value * 3600 * 24 - differenceHours.value * 3600) / 60)
}
);
const differenceSeconds = computed(() =>
{
if (seconds.value <= 0) {
return 0;
}
return seconds.value - differenceDays.value * 86400 - differenceHours.value * 3600 - differenceMinutes.value * 60;
}
);
onMounted(() => {
seconds.value = Math.round((props.end.getTime() - new Date().getTime()) / 1000);
if (seconds.value > 0) {
_timerId = setInterval(() => {
seconds.value--;
emit("update:modelValue", seconds.value)
if (seconds.value <= 0) {
clearInterval(_timerId);
}
}, 1000);
}
emit("update:modelValue", seconds.value)
});
onUnmounted(() => clearInterval(_timerId));
</script>
<style lang="sass">
@keyframes borderAnimation
0%
background-position: 0% 50%
50%
background-position: 100% 50%
100%
background-position: 0% 50%
.countdown
z-index: 10
align-self: center
font-weight: bold
width: calc( 100vw - 48px)
@media (min-width: 768px)
width: 500px
.countdown__title
text-align: left
font-size: 18px
font-weight: 400
margin: 8px
@media (min-width: 768px)
font-size: 20px
.countdown__time
box-sizing: border-box
padding: 12px 24px
font-size: 32px
position: relative
border-radius: 12px
@media (min-width: 768px)
font-size: 40px
&>div
font-family: 'orbitron', sans-serif
font-weight: 400
&::before
content: ""
position: absolute
inset: 0
border-radius: inherit
/* Erbt die Abrundung */
padding: 2px
/* Dicke des Borders */
background: linear-gradient(10deg, #BF62B2, black)
-webkit-mask: linear-gradient(white, white) content-box, linear-gradient(white, white)
-webkit-mask-composite: destination-out
mask-composite: exclude
z-index: -1
</style>

View file

@ -0,0 +1,43 @@
<template>
<button class="kraken-button" :class="{'kraken-button--outlined': props.outlined}">
<slot></slot>
</button>
</template>
<script setup lang="ts">
const props = withDefaults(defineProps<{
outlined?: boolean
}>(), {
outlined: false
})
</script>
<style lang="sass">
.kraken-button
background-color: #000000
color: white
font-family: 'Exo 2 Bold', sans-serif
font-weight: 500
line-height: 26px
letter-spacing: 0.46px
font-size: 14px
padding: 16px 64px
border-radius: 12px
border: none
cursor: pointer
color: #BF62B2
display: inline-block
text-align: center
text-decoration: none
transition: all 0.3s ease-in-out
box-shadow: 0px 0px 7.6px 0px #000, 0px 0px 20.6px 0px #BF62B2
@media (min-width: 768px)
font-size: 20px
&:hover,&:active
background-color: #F9F9FA
color: #9667BE
box-shadow: 4px 4px 4px 0px rgba(0, 0, 0, 0.25) inset
</style>

View file

@ -0,0 +1,20 @@
<template>
<footer class="k-container">
<div class="k-footer">
KrAIken is a project by <u><a href="https://sovraigns.network/" target="_blank">SovrAIgns.network</a></u>.<br /> Resarch and Development in DeFAI (DeFi x AI) Agents. Use at your own risk.
</div>
</footer>
</template>
<style lang="sass">
.k-footer
font-size: 14px
line-height: 22px
letter-spacing: 0.15px
padding-bottom: 48px
a
color: #F0F0F0
@media (min-width: 992px)
font-size: 16px
</style>

View file

@ -0,0 +1,238 @@
<template>
<header>
<div class="kraken-navbar" :class="{ scrolled: isScrolled }">
<div class="navbar-left" @click="router.push('/')">
<div class="navbar-title">
<span>K</span>
<span class="big-spacing">r</span>
<span class="small-spacing">A</span>
<span class="big-spacing">I</span>
<span>ken</span>
</div>
</div>
<div class="desktop-nav">
<RouterLink to="/docs">Docs</RouterLink>
<div class="social-buttons">
<social-button type="telegram" href="https://t.me/kraikenportal"></social-button>
<social-button type="twitter" href="https://x.com/KrAIkenProtocol"></social-button>
</div>
</div>
<div class="menu-trigger" @click.stop="toggleMenu">
<svg width="24" height="24" viewBox="0 0 24 24">
<circle cx="12" cy="5" r="2" :fill="isScrolled ? '#D6D6D6' : '#07111B'" />
<circle cx="12" cy="12" r="2" :fill="isScrolled ? '#D6D6D6' : '#07111B'" />
<circle cx="12" cy="19" r="2" :fill="isScrolled ? '#D6D6D6' : '#07111B'" />
</svg>
</div>
</div>
<div class="menu-overlay" v-if="isMenuOpen" @click="closeMenu"></div>
<div class="slide-menu" :class="{ 'is-open': isMenuOpen }">
<div class="menu-items">
<RouterLink
to="/"
@click="closeMenu"
:class="{ active: $route.path === '/' }"
>Start</RouterLink>
<RouterLink
to="/docs"
@click="closeMenu"
:class="{ active: $route.path === '/docs' }"
>Docs</RouterLink>
</div>
<div class="menu-socials">
<social-button type="telegram" href="https://t.me/kraikenportal"></social-button>
<social-button type="twitter" href="https://x.com/KrAIkenProtocol"></social-button>
</div>
</div>
</header>
</template>
<script setup lang="ts">
import { RouterLink, useRouter } from "vue-router";
import SocialButton from "./SocialButton.vue";
import { onMounted, onUnmounted, ref,computed } from "vue";
const router = useRouter();
const scrollPosition = ref(0);
const isMenuOpen = ref(false);
const isScrolled = computed(() =>
router.currentRoute.value.fullPath.includes('/docs') ||
scrollPosition.value > 50
);
function updateScroll() {
scrollPosition.value = window.scrollY;
}
function toggleMenu() {
isMenuOpen.value = !isMenuOpen.value;
if (isMenuOpen.value) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = '';
}
}
function closeMenu() {
isMenuOpen.value = false;
document.body.style.overflow = '';
}
onMounted(() => window.addEventListener("scroll", updateScroll));
onUnmounted(() => window.removeEventListener("scroll", updateScroll));document.body.style.overflow = '';
</script>
<style lang="sass">
.desktop-nav
display: none
align-items: center
gap: 24px
@media (min-width: 768px)
display: flex
a
color: #07111B
text-decoration: none
font-size: 18px
line-height: 24px
font-weight: 500
&:hover, &:active, &:focus
color: #F9F9FA
.social-buttons
display: flex
gap: 16px
margin-left: 16px
.social-badge
border: 2px solid #07111B
transition: all 0.2s ease
svg
fill: #07111B
&:hover
border: 2px solid #07111B
svg
fill: #07111B
.menu-trigger
display: none
cursor: pointer
padding: 8px
z-index: 99
@media (max-width: 767px)
display: block
.menu-overlay
position: fixed
top: 0
left: 0
width: 100%
height: 100%
background: rgba(0, 0, 0, 0.6)
z-index: 96
display: none
@media (max-width: 767px)
display: block
.slide-menu
position: fixed
border-top-left-radius: 20px
border-bottom-left-radius: 20px
top: 0
right: -240px
width: 240px
height: 400px
background: #07111B
z-index: 99
transition: transform 0.3s ease
display: none
@media (max-width: 767px)
display: flex
flex-direction: column
&.is-open
transform: translateX(-240px)
.menu-items
padding: 80px 32px
display: flex
flex-direction: column
gap: 24px
flex: 1
a
color: #9A9898
text-decoration: none
font-size: 24px
font-weight: 500
&.router-link-active,
&.active
color: #D6D6D6
&:hover
opacity: 0.8
.menu-socials
padding: 32px
display: flex
gap: 16px
justify-content: center
.kraken-navbar
box-sizing: border-box
background-color: transparent
padding: 8px 24px
height: 60px
border-bottom: 2px solid transparent
display: flex
align-items: center
justify-content: space-between
position: fixed
top: 0
transition: 0.2s ease
color: #07111B
width: 100%
z-index: 99
&.scrolled
background-color: #07111B
color: #D6D6D6
border-bottom: 2px solid #9A9898
.desktop-nav
a
color: #D6D6D6
&:hover
color: #F9F9FA
.social-buttons
.social-badge
border-color: #D6D6D6
svg
fill: #D6D6D6
&:hover
border-color: #F9F9FA
svg
fill: #07111B
.navbar-left
display: flex
gap: 8px
letter-spacing: 3.6px
align-items: center
font-size: 32px
font-weight: 400
&:hover, &:active, &:focus
cursor: pointer
img
height: 40px
width: 40px
@media (min-width: 768px)
height: auto
width: auto
.navbar-title
font-size: 24px
font-family: 'Audiowide', sans-serif
>*
font-family: 'Audiowide', sans-serif
@media (min-width: 768px)
display: block
font-size: 36px
font-weight: bold
.big-spacing
letter-spacing: 5.76px
.small-spacing
letter-spacing: 1.8px
</style>

View file

@ -0,0 +1,71 @@
<template>
<div class="left-right-component" :class="{ 'left-right-component--reverse': props.reverse }">
<div class="left">
<slot name="left">
<img src="@/assets/img/chest.png" alt="kraken" class="image-card" />
</slot>
</div>
<div class="right">
<slot name="right">
<h2>Challenge the AI</h2>
<p>
KrAIken is a <u>DeFAI</u> Protocol in open beta.<br /><br />
Everyone is invited to train the AI by trading and challenge it's liquidity positions.
</p>
</slot>
</div>
</div>
</template>
<script setup lang="ts">
const props = withDefaults(
defineProps<{
reverse?: boolean;
}>(),
{
reverse: false,
}
);
</script>
<style lang="sass">
.left-right-component
display: flex
justify-content: space-between
align-items: center
gap: 24px
flex-direction: column
text-align: center
@media (min-width: 768px)
flex-direction: row
text-align: unset
&.left-right-component--reverse
flex-direction: column
@media (min-width: 768px)
flex-direction: row-reverse
.left
img
height: 255px
width: 255px
@media (min-width: 768px)
width: unset
height: unset
.right
max-width: 480px
text-align: center
@media (min-width: 768px)
text-align: unset
text-align: left
h2
font-size: 24px
font-weight: 400
@media (min-width: 768px)
font-size: 27px
p
margin-bottom: 32px
@media (min-width: 768px)
font-size: 18px
</style>

View file

@ -0,0 +1,69 @@
<template>
<li :class="{ active: isActive, parentActive: hasActiveChild }">
<router-link :to="'#' + props.item.id">{{ props.item.title }}</router-link>
<ul class="nav" v-if="props.item.children && props.item.children.length > 0">
<NavItem v-for="(child, index) in props.item.children" :key="index" :item="child" />
</ul>
</li>
</template>
<script setup lang="ts">
import { computed, inject, type Ref } from "vue";
interface MenuItem {
title: string;
id: string | null;
children: MenuItem[];
}
// Props für das aktuelle Element
const props = defineProps<{ item: MenuItem }>();
// `inject` für die aktive Referenz
const activeSection: any = inject("activeSection");
// Prüfen, ob das aktuelle Element aktiv ist
const isActive = computed(() => {
return activeSection.value === props.item.id;
});
// Rekursive Prüfung, ob ein untergeordnetes Element aktiv ist
const hasActiveChild = computed(() => {
return props.item.children.some((child) => checkChildActive(child));
});
function checkChildActive(child: MenuItem): boolean {
if (child.id === activeSection.value) {
return true;
}
return child.children.some((subChild) => checkChildActive(subChild));
}
</script>
<style scoped>
.nav {
list-style-type: none;
padding: 0;
margin: 0;
}
.nav li {
margin: 5px 0;
}
.nav a {
text-decoration: none;
color: #D6D6D6;
}
.nav li.active a {
font-weight: bold;
color: #9667BE;
}
.nav li.parentActive > a {
font-weight: bold;
color: #9667BE;
}
</style>

View file

@ -0,0 +1,67 @@
<template>
<a :href="props.href" target="_blank">
<div
class="social-badge"
>
<div class="social-badge-icon">
<component :is="img" />
</div>
</div>
</a>
</template>
<script setup lang="ts">
import { defineAsyncComponent, computed } from "vue";
interface Props {
type?: string;
href?: string;
}
const props = withDefaults(defineProps<Props>(), {});
const img = computed(() => {
let img;
switch (props.type) {
case "discord":
img = defineAsyncComponent(() => import(`../components/icons/IconDiscord.vue`));
break;
case "twitter":
img = defineAsyncComponent(() => import(`../components/icons/IconTwitter.vue`));
break;
case "telegram":
img = defineAsyncComponent(() => import(`../components/icons/IconTelegram.vue`));
break;
default:
break;
}
return img;
});
</script>
<style lang="sass">
.social-badge
border-radius: 14px
display: flex
border: 2px solid #D6D6D6
padding: 8px 24px
align-items: center
flex: 0 1 0
color: black
height: 100%
box-sizing: border-box
@media (min-width: 768px)
padding: 8px 48px
.social-badge-icon
display: flex
svg
fill: #D6D6D6
&:hover,&:active,&:focus
cursor: pointer
background-color: #F9F9FA
svg
fill: unset
</style>

View file

@ -0,0 +1,7 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor">
<path
d="M15 4a1 1 0 1 0 0 2V4zm0 11v-1a1 1 0 0 0-1 1h1zm0 4l-.707.707A1 1 0 0 0 16 19h-1zm-4-4l.707-.707A1 1 0 0 0 11 14v1zm-4.707-1.293a1 1 0 0 0-1.414 1.414l1.414-1.414zm-.707.707l-.707-.707.707.707zM9 11v-1a1 1 0 0 0-.707.293L9 11zm-4 0h1a1 1 0 0 0-1-1v1zm0 4H4a1 1 0 0 0 1.707.707L5 15zm10-9h2V4h-2v2zm2 0a1 1 0 0 1 1 1h2a3 3 0 0 0-3-3v2zm1 1v6h2V7h-2zm0 6a1 1 0 0 1-1 1v2a3 3 0 0 0 3-3h-2zm-1 1h-2v2h2v-2zm-3 1v4h2v-4h-2zm1.707 3.293l-4-4-1.414 1.414 4 4 1.414-1.414zM11 14H7v2h4v-2zm-4 0c-.276 0-.525-.111-.707-.293l-1.414 1.414C5.42 15.663 6.172 16 7 16v-2zm-.707 1.121l3.414-3.414-1.414-1.414-3.414 3.414 1.414 1.414zM9 12h4v-2H9v2zm4 0a3 3 0 0 0 3-3h-2a1 1 0 0 1-1 1v2zm3-3V3h-2v6h2zm0-6a3 3 0 0 0-3-3v2a1 1 0 0 1 1 1h2zm-3-3H3v2h10V0zM3 0a3 3 0 0 0-3 3h2a1 1 0 0 1 1-1V0zM0 3v6h2V3H0zm0 6a3 3 0 0 0 3 3v-2a1 1 0 0 1-1-1H0zm3 3h2v-2H3v2zm1-1v4h2v-4H4zm1.707 4.707l.586-.586-1.414-1.414-.586.586 1.414 1.414z"
/>
</svg>
</template>

View file

@ -0,0 +1,29 @@
<template>
<svg width="23" height="18" viewBox="0 0 23 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2590_494)">
<path
ref="svgPath"
d="M19.419 3.40166C16.7691 1.45664 14.2483 1.51053 14.2483 1.51053L13.9906 1.79865C17.1188 2.73512 18.5723 4.08593 18.5723 4.08593C16.6585 3.05941 14.7817 2.55501 13.0336 2.35694C11.7088 2.21276 10.4391 2.24892 9.3167 2.39287C9.20634 2.39287 9.11433 2.41083 9.00397 2.42879C8.35994 2.48292 6.79584 2.71692 4.82702 3.56357C4.14628 3.86966 3.74131 4.08593 3.74131 4.08593C3.74131 4.08593 5.2687 2.66303 8.58065 1.72656L8.39664 1.51053C8.39664 1.51053 5.87579 1.4564 3.22598 3.40166C3.22598 3.40166 0.576172 8.10242 0.576172 13.9018C0.576172 13.9018 2.12191 16.5134 6.18851 16.6393C6.18851 16.6393 6.86925 15.8289 7.42129 15.1446C5.08444 14.4601 4.20109 13.0195 4.20109 13.0195C4.20109 13.0195 4.3851 13.1454 4.71642 13.3256C4.73477 13.3435 4.75313 13.3615 4.79007 13.3797C4.84537 13.4156 4.90043 13.4338 4.95573 13.4697C5.41576 13.7219 5.87579 13.92 6.29911 14.0821C7.05351 14.3703 7.95521 14.6584 9.00397 14.8565C10.3841 15.1087 12.0032 15.1987 13.7697 14.8744C14.6344 14.7303 15.5178 14.4783 16.4378 14.0999C17.0819 13.8656 17.7996 13.5236 18.554 13.0372C18.554 13.0372 17.6339 14.514 15.2234 15.1805C15.7754 15.865 16.4378 16.6393 16.4378 16.6393C20.5047 16.5131 22.0688 13.9018 22.0688 13.9018C22.0688 8.10242 19.419 3.40166 19.419 3.40166ZM7.8818 12.2267C6.85138 12.2267 6.00498 11.3262 6.00498 10.2276C6.00498 9.12894 6.83303 8.22841 7.8818 8.22841C8.93056 8.22841 9.77697 9.12894 9.75861 10.2276C9.75861 11.3262 8.93056 12.2267 7.8818 12.2267ZM14.598 12.2267C13.5675 12.2267 12.7211 11.3262 12.7211 10.2276C12.7211 9.12894 13.5492 8.22841 14.598 8.22841C15.6467 8.22841 16.4748 9.12894 16.4748 10.2276C16.4748 11.3262 15.647 12.2267 14.598 12.2267Z"
:fill="props.color"
/>
</g>
<defs>
<clipPath id="clip0_2590_494">
<rect width="22" height="17" fill="white" transform="translate(0.333984 0.58667)" />
</clipPath>
</defs>
</svg>
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";
const svgPath = ref();
interface Props {
color?: string;
}
const props = withDefaults(defineProps<Props>(), {});
</script>

View file

@ -0,0 +1,7 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="17" fill="currentColor">
<path
d="M11 2.253a1 1 0 1 0-2 0h2zm-2 13a1 1 0 1 0 2 0H9zm.447-12.167a1 1 0 1 0 1.107-1.666L9.447 3.086zM1 2.253L.447 1.42A1 1 0 0 0 0 2.253h1zm0 13H0a1 1 0 0 0 1.553.833L1 15.253zm8.447.833a1 1 0 1 0 1.107-1.666l-1.107 1.666zm0-14.666a1 1 0 1 0 1.107 1.666L9.447 1.42zM19 2.253h1a1 1 0 0 0-.447-.833L19 2.253zm0 13l-.553.833A1 1 0 0 0 20 15.253h-1zm-9.553-.833a1 1 0 1 0 1.107 1.666L9.447 14.42zM9 2.253v13h2v-13H9zm1.553-.833C9.203.523 7.42 0 5.5 0v2c1.572 0 2.961.431 3.947 1.086l1.107-1.666zM5.5 0C3.58 0 1.797.523.447 1.42l1.107 1.666C2.539 2.431 3.928 2 5.5 2V0zM0 2.253v13h2v-13H0zm1.553 13.833C2.539 15.431 3.928 15 5.5 15v-2c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM5.5 15c1.572 0 2.961.431 3.947 1.086l1.107-1.666C9.203 13.523 7.42 13 5.5 13v2zm5.053-11.914C11.539 2.431 12.928 2 14.5 2V0c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM14.5 2c1.573 0 2.961.431 3.947 1.086l1.107-1.666C18.203.523 16.421 0 14.5 0v2zm3.5.253v13h2v-13h-2zm1.553 12.167C18.203 13.523 16.421 13 14.5 13v2c1.573 0 2.961.431 3.947 1.086l1.107-1.666zM14.5 13c-1.92 0-3.703.523-5.053 1.42l1.107 1.666C11.539 15.431 12.928 15 14.5 15v-2z"
/>
</svg>
</template>

View file

@ -0,0 +1,7 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="20" fill="currentColor">
<path
d="M11.447 8.894a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm0 1.789a1 1 0 1 0 .894-1.789l-.894 1.789zM7.447 7.106a1 1 0 1 0-.894 1.789l.894-1.789zM10 9a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0H8zm9.447-5.606a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm2 .789a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zM18 5a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0h-2zm-5.447-4.606a1 1 0 1 0 .894-1.789l-.894 1.789zM9 1l.447-.894a1 1 0 0 0-.894 0L9 1zm-2.447.106a1 1 0 1 0 .894 1.789l-.894-1.789zm-6 3a1 1 0 1 0 .894 1.789L.553 4.106zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zm-2-.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 2.789a1 1 0 1 0 .894-1.789l-.894 1.789zM2 5a1 1 0 1 0-2 0h2zM0 7.5a1 1 0 1 0 2 0H0zm8.553 12.394a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 1a1 1 0 1 0 .894 1.789l-.894-1.789zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zM8 19a1 1 0 1 0 2 0H8zm2-2.5a1 1 0 1 0-2 0h2zm-7.447.394a1 1 0 1 0 .894-1.789l-.894 1.789zM1 15H0a1 1 0 0 0 .553.894L1 15zm1-2.5a1 1 0 1 0-2 0h2zm12.553 2.606a1 1 0 1 0 .894 1.789l-.894-1.789zM17 15l.447.894A1 1 0 0 0 18 15h-1zm1-2.5a1 1 0 1 0-2 0h2zm-7.447-5.394l-2 1 .894 1.789 2-1-.894-1.789zm-1.106 1l-2-1-.894 1.789 2 1 .894-1.789zM8 9v2.5h2V9H8zm8.553-4.894l-2 1 .894 1.789 2-1-.894-1.789zm.894 0l-2-1-.894 1.789 2 1 .894-1.789zM16 5v2.5h2V5h-2zm-4.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zm-2.894-1l-2 1 .894 1.789 2-1L8.553.106zM1.447 5.894l2-1-.894-1.789-2 1 .894 1.789zm-.894 0l2 1 .894-1.789-2-1-.894 1.789zM0 5v2.5h2V5H0zm9.447 13.106l-2-1-.894 1.789 2 1 .894-1.789zm0 1.789l2-1-.894-1.789-2 1 .894 1.789zM10 19v-2.5H8V19h2zm-6.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zM2 15v-2.5H0V15h2zm13.447 1.894l2-1-.894-1.789-2 1 .894 1.789zM18 15v-2.5h-2V15h2z"
/>
</svg>
</template>

View file

@ -0,0 +1,5 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<!-- Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc. -->
<path d="M0 96C0 78.3 14.3 64 32 64l384 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 128C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32l384 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 288c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32L32 448c-17.7 0-32-14.3-32-32s14.3-32 32-32l384 0c17.7 0 32 14.3 32 32z"/></svg>
</template>

View file

@ -0,0 +1,7 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor">
<path
d="M10 3.22l-.61-.6a5.5 5.5 0 0 0-7.666.105 5.5 5.5 0 0 0-.114 7.665L10 18.78l8.39-8.4a5.5 5.5 0 0 0-.114-7.665 5.5 5.5 0 0 0-7.666-.105l-.61.61z"
/>
</svg>
</template>

View file

@ -0,0 +1,22 @@
<template>
<svg width="18" height="15" viewBox="0 0 18 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Group">
<path id="Vector" d="M16.558 0.345906L1.24462 6.2506C0.199293 6.66992 0.205631 7.2531 1.05407 7.5128L4.98317 8.73926L6.33449 13.1866C6.51217 13.677 6.42458 13.8716 6.93975 13.8716C7.33718 13.8716 7.51274 13.6899 7.7346 13.4742L9.64412 11.6175L13.6166 14.5525C14.3477 14.9559 14.8754 14.7469 15.0575 13.8739L17.6654 1.58466C17.9324 0.51398 17.2574 0.0283891 16.558 0.345906Z" />
<path id="Vector_2" d="M6.95616 12.6891L5.66016 8.424L15.6361 2.50586L8.26406 9.76418L6.95616 12.6891Z"/>
</g>
</svg>
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";
const svgPath = ref();
interface Props {
color?: string;
}
const props = withDefaults(defineProps<Props>(), {});
</script>

View file

@ -0,0 +1,19 @@
<!-- This icon is from <https://github.com/Templarian/MaterialDesign>, distributed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) license-->
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
aria-hidden="true"
role="img"
class="iconify iconify--mdi"
width="24"
height="24"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 24 24"
>
<path
d="M20 18v-4h-3v1h-2v-1H9v1H7v-1H4v4h16M6.33 8l-1.74 4H7v-1h2v1h6v-1h2v1h2.41l-1.74-4H6.33M9 5v1h6V5H9m12.84 7.61c.1.22.16.48.16.8V18c0 .53-.21 1-.6 1.41c-.4.4-.85.59-1.4.59H4c-.55 0-1-.19-1.4-.59C2.21 19 2 18.53 2 18v-4.59c0-.32.06-.58.16-.8L4.5 7.22C4.84 6.41 5.45 6 6.33 6H7V5c0-.55.18-1 .57-1.41C7.96 3.2 8.44 3 9 3h6c.56 0 1.04.2 1.43.59c.39.41.57.86.57 1.41v1h.67c.88 0 1.49.41 1.83 1.22l2.34 5.39z"
fill="currentColor"
></path>
</svg>
</template>

View file

@ -0,0 +1,18 @@
<template>
<svg width="19" height="19" viewBox="0 0 19 19" xmlns="http://www.w3.org/2000/svg">
<path id="Vector" d="M0.5 0.5L7.4306 10.625L0.646792 18.5H2.14979L8.0944 11.5946L12.8213 18.5H18.5L11.2592 7.92259L17.6488 0.5H16.1504L10.5945 6.95025L6.17872 0.5H0.5ZM2.29474 1.44737H5.6811L16.7053 17.5526H13.3189L2.29474 1.44737Z"/>
</svg>
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";
const svgPath = ref();
interface Props {
color?: string;
}
const props = withDefaults(defineProps<Props>(), {});
</script>

View file

@ -0,0 +1,30 @@
import { ref, onMounted, onUnmounted } from "vue";
// by convention, composable function names start with "use"
export function useMobile() {
const isMobile = ref<boolean>(false);
const handleWindowSizeChange = () => {
isMobile.value = isMobileFunc();
};
isMobile.value = isMobileFunc();
function isMobileFunc() {
if (screen.width <= 768) {
return true;
} else {
return false;
}
}
onMounted(async () => {
window.addEventListener("resize", handleWindowSizeChange);
handleWindowSizeChange();
});
onUnmounted(() => {
window.removeEventListener("resize", handleWindowSizeChange);
});
return isMobile;
}

10
landing/src/main.ts Normal file
View file

@ -0,0 +1,10 @@
import './assets/styles/main.sass'
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(router)
app.mount('#app')

View file

@ -0,0 +1,94 @@
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
const router = createRouter({
history: createWebHashHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'home',
component: HomeView,
},
{
path: "/docs",
name: "Docs",
meta: {
title: "Docs",
group: "navbar",
// group: "navbar",
},
redirect: "/docs/Introduction",
component: () => import("../views/DocsView.vue"),
children: [
{
path: "/docs/Introduction",
name: "Introduction",
meta: {
title: "Docs",
// group: "navbar",
},
component: () => import("../views/docs/Introduction.vue"),
},
{
path: "/docs/Liquidity-Management",
name: "Liquidity Management",
meta: {
title: "Docs",
// group: "navbar",
},
component: () => import("../views/docs/Liquidity-Management.vue"),
},
{
path: "/docs/AI-agent",
name: "AI-agent",
meta: {
title: "Docs",
// group: "navbar",
},
component: () => import("../views/docs/ai-agent.vue"),
},
{
path: "/docs/Tokenomics",
name: "Tokenomics",
meta: {
title: "Docs",
// group: "navbar",
},
component: () => import("../views/docs/Tokenomics.vue"),
},
{
path: "/docs/Staking",
name: "Staking",
meta: {
title: "Docs",
// group: "navbar",
},
component: () => import("../views/docs/Staking.vue"),
},
{
path: "/docs/FAQ",
name: "FAQ",
meta: {
title: "Docs",
// group: "navbar",
},
component: () => import("../views/docs/FAQ.vue"),
},
],
},
],
scrollBehavior(to, from, savedPosition) {
// Überprüfen, ob der Zielort ein Hash enthält
if (to.hash) {
// Warten, bis die Komponente geladen ist und dann zum Ziel scrollen
return {
el: to.hash,
behavior: "smooth", // Optional: für sanftes Scrollen
top: 80,
};
}
return savedPosition || { top: 0 }; // Scrollen zum Anfang der Seite, falls kein Hash vorhanden ist
},
})
export default router

View file

@ -0,0 +1,364 @@
<template>
<div class="docs-overlay" :class="{ open: sideMenuOpen }" @click="sideMenuOpen = false"></div>
<div class="docs-view" ref="docsView" style="
padding-top: 60px;
">
<div class="docs--header">
<div class="side-menu-toggle">
<div class="menu-circle"></div>
<icon-menu @click="openSideMenu"></icon-menu>
</div>
</div>
<transition name="slide">
<div class="side-menu" v-if="sideMenuOpen">
<h4>Navigation</h4>
<RouterLink
@click="sideMenuOpen = false"
v-for="route in docsRoute?.children"
:key="route.name"
:to="route.path"
>{{ route.name }}</RouterLink
>
</div>
</transition>
<div class="docs--body">
<div class="left">
<div class="left-navigation">
<h4>Navigation</h4>
<RouterLink v-for="route in docsRoute?.children" :key="route.name" :to="route.path">{{
route.name
}}</RouterLink>
</div>
</div>
<div class="center">
<RouterView @onmounted="routeOnMounted" />
</div>
<div class="right">
<div class="content" :key="rerender">
<div class="outline-marker" style="top: 71px; opacity: 1"></div>
<div><b>On this page</b></div>
<ul class="nav">
<NavItem v-for="(item, index) in subMenu" :key="index" :item="item" />
</ul>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { useRoute, useRouter, RouterLink } from "vue-router";
import { ref, onMounted, onBeforeUnmount, watch, provide } from "vue";
import IconMenu from "@/components/icons/IconMenu.vue";
import NavItem from "@/components/NavItem.vue";
const route = useRoute();
console.log("route", route);
const router = useRouter();
console.log("router", router.getRoutes());
const rerender = ref(0);
const docsView = ref();
const sideMenuOpen = ref(false);
const headings = ref();
const subMenu = ref<Array<any>>([]);
const docsRoute = router.getRoutes().find((obj) => obj.name === "Docs");
onMounted(() => {
window.addEventListener("scroll", handleScroll);
loadHeadlines();
});
function loadHeadlines() {
console.log("loadHeadlines");
headings.value = [];
subMenu.value = [];
const headings1 = docsView.value.querySelectorAll("h1, h2, h3, h4, h5, h6");
console.log("headings1", headings1);
generateIds(headings1);
subMenu.value = createMenuStructure(headings1);
console.log("subMenu.value", subMenu.value);
}
function generateIds(headings: any) {
for (let index = 0; index < headings.length; index++) {
const element = headings[index];
if (!element.id) {
element.id = element.tagName + index;
}
}
}
function createMenuStructure(headings: any) {
const menu: Array<any> = [];
const stack = [{ level: 0, children: menu }];
let i = 0;
headings.forEach((heading: any) => {
const level = parseInt(heading.tagName.slice(1), 10);
const title = heading.textContent.trim();
let id = heading.id || null;
console.log("heading.id", heading.id);
if (!id) {
id = heading.tagName + i;
}
const newItem = { title, id, children: [] };
// Passende Position im Stack finden
while (stack.length > 0 && stack[stack.length - 1].level >= level) {
stack.pop();
}
// Neues Element als Kind des aktuellen Stack-Eintrags hinzufügen
stack[stack.length - 1].children.push(newItem);
// Aktuelles Element auf den Stack legen
stack.push({ level, children: newItem.children });
i++;
});
return menu;
}
function openSideMenu() {
sideMenuOpen.value = true;
}
function routeOnMounted() {
console.log("routeOnMounted");
rerender.value++;
console.log("rerender", rerender);
loadHeadlines();
}
const activeSection = ref("");
// Überwache den Scrollvorgang
const handleScroll = () => {
const sections = document.querySelectorAll("h1, h2, h3, h4, h5, h6");
sections.forEach((section) => {
const rect = section.getBoundingClientRect();
if (rect.top <= window.innerHeight / 2 && rect.bottom >= window.innerHeight / 2) {
activeSection.value = section.id;
}
});
};
provide("activeSection", activeSection);
// Scroll-Events verwalten
onBeforeUnmount(() => {
window.removeEventListener("scroll", handleScroll);
});
</script>
<style lang="sass">
.docs-view
.docs--body
pre
overflow: auto
max-width: 100%
width: calc(100vw - 48px)
@media (min-width: 992px)
width: auto
overflow: unset
// docs styling e.g. warning-class
.warning
color: #e6a23c
font-weight: bold
.danger
color: #f56c6c
font-weight: bold
.docs-overlay
position: fixed
top: 0
left: 0
height: 100%
width: 100%
background-color: rgba(15, 15, 15, 0.7)
display: none
z-index: 100
&.open
display: block
.docs-view
position: relative
font-size: 16px
text-align: left
.docs--header
height: 40px
top: unset
bottom: 24px
left: 24px
position: fixed
height: 40px
padding: 4px
display: flex
align-items: center
background-color: var(--color-primary)
z-index: 96
@media (min-width: 992px)
display: none
.side-menu-toggle
height: 40px
padding: 12px
position: fixed
top: unset
bottom: 24px
left: 24px
display: flex
align-items: center
justify-content: center
z-index: 97
.menu-circle
position: absolute
width: 64px
height: 64px
background-color: rgba(0, 0, 0, 0.89)
border-radius: 50%
z-index: 96
svg
height: 36px
position: relative
z-index: 98
path
fill: white
.docs--body
display: flex
pre
line-height: 1
font-family: monospace
h1, h2, h3
text-align: left !important
h1
letter-spacing: -0.02em
line-height: 40px
font-size: 32px
h2
margin: 48px 0 16px
border-top: 1px solid lightgrey
padding-top: 24px
letter-spacing: -0.02em
line-height: 32px
font-size: 24px
h3
margin: 24px 0 16px
font-size: 20px
ul
padding-left: 1.25rem
margin: 16px 0
>div
flex: 0 0 auto
.right
width: 224px
padding: 0 32px 0 0
position: relative
display: none
@media (min-width: 992px)
display: block
.content
position: fixed
border-left: 1px solid lightgrey
padding-left: 16px
font-size: 13px
font-weight: 500
margin-top: 20px
ul
padding: 0 12px
margin: 0
li
list-style: none
&.active
color: #9667BE
font-weight: bold
.left
width: 272px
padding: 0 16px
position: relative
display: none
color: #D6D6D6
@media (min-width: 992px)
display: block
padding: 0 64px
.left-navigation
display: flex
flex-direction: column
gap: 8px
position: fixed
a
color: inherit
text-decoration: none
&.router-link-active
color: #9667BE
font-weight: bold
h4
font-size: 20px
margin-bottom: 16px
.center
padding: 0 24px
flex: 1 1 auto
a
text-decoration: underline
color: #3451b2
font-weight: bold
.side-menu
display: flex
flex-direction: column
position: fixed
top: 0
left: 0
z-index: 101
padding: 112px 32px 96px 32px
width: 50vw
max-width: 320px
background-color: var(--vp-sidebar-bg-color, #0F0F0F)
// opacity: 0
box-shadow: var(--vp-c-shadow-3)
overflow-x: hidden
overflow-y: auto
transition: opacity 0.5s, transform 0.25s ease
overscroll-behavior: contain
color: #9A9898
background-color: var(--midnight-black, #0F0F0F)
height: 100vh
gap: 4px
transform: translateX(0)
.router-link-active
color: white
font-weight: bold
a
color: white
text-decoration: none
font-size: 20px
padding: 4px 0
h4
colour: #9A9898
font-size: 24px // Made the Navigation title bigger too
margin-bottom: 20px
.slide-enter
transform: translateX(-100%)
.slide-enter-active
transition: all .1s ease-in
transform: translateX(-100%)
.slide-leave-active
transition: all .2s ease-in
.slide-leave-to
transform: translateX(-100%)
</style>

View file

@ -0,0 +1,188 @@
<template>
<div class="header-section">
<img v-if="isMobile" src="@/assets/img/header-image-mobile.png" width="800" height="600" alt="Kraiken Boss" />
<img v-else src="@/assets/img/header-image.png" width="1920" height="1080" alt="Kraiken Boss" />
<div class="header-text">
Deep Liquidity <br />
AI Agent
</div>
<div class="blur-effect"></div>
</div>
<countdown v-model="countdownExpired" :end="endDt">
<template #default>
Coming soon
</template>
</countdown>
<div class="k-container">
<section class="token-liquidity-section">
<h2>Unruggable Token Liquidity</h2>
<p>
$KRK is the first token with unruggable liquidity managed by AI.<br /><br />
The liquidity pool is protected by a sovereign AI Agent that optimizes liquidity positions based on real
time market data.
</p>
<br />
<!-- <k-button outlined @click="openUniswap" @mouseover="onMouseOver" @mouseout="onMouseOut"> {{ getKrkText }} </k-button> -->
<k-button outlined @mouseover="onMouseOver" @mouseout="onMouseOut"> {{ getKrkText }} </k-button>
</section>
<section class="challenge-section">
<left-right-component reverse>
<template #left>
<img src="@/assets/img/chest.png" alt="kraken" class="image-card" />
</template>
<template #right>
<h2>Going Deeper</h2>
<p>
KrAIken is built to deepen token liquidity, starting in the $KRK poolan ideal ground for
mastering market tides. <br /><br />
Once matured, it extends its reach across the crypto ocean, managing diverse pools, generating
profit, and expanding utility.
</p>
</template>
</left-right-component>
<left-right-component>
<template #left>
<img src="@/assets/img/arielle.png" alt="kraken" class="image-card" />
</template>
<template #right>
<h2>Meet Arielle (coming soon)</h2>
<p>
Ask questions, challenge the protocol, and find edge cases for KrAIken. <br /><br />
Arielle is here to assist.
</p>
<k-button @click="router.push('/docs')"> Read Docs</k-button>
</template>
</left-right-component>
</section>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
import KButton from "@/components/KButton.vue";
import LeftRightComponent from "@/components/LeftRightComponent.vue";
import Countdown from "@/components/Countdown.vue";
import { useMobile } from "@/composables/useMobile";
import { useRouter } from "vue-router";
const endDt = new Date(1742572800000);
const countdownExpired = ref(1);
const getKrkText = ref("Get $KRK");
const isMobile = useMobile();
const router = useRouter();
function openUniswap() {
window.open(
"https://app.uniswap.org/swap?chain=base&inputCurrency=NATIVE&outputCurrency=0x45caa5929f6ee038039984205bdecf968b954820",
"_blank"
);
}
function onMouseOver(event: any) {
getKrkText.value = "On launch";
}
function onMouseOut(event: any) {
getKrkText.value = "Get $KRK";
}
</script>
<style lang="sass">
.header-section
position: relative
.blur-effect
filter: blur(45px)
height: 300px
position: absolute
bottom: -150px
width: 100%
background-color: #07111B
left: -10%
width: 120%
img
max-width: 100%
min-width: 100%
height: auto
.header-text
color: #E6E6E6
mix-blend-mode: color-dodge
font-weight: 500
position: absolute
text-align: left
top: 50%
left: 35%
transform: translate(-50%, -50%)
font-size: 35px
font-weight: 500
@media (min-width: 768px)
width: unset
font-size: 78px
.image-card
box-shadow: 0px 0px 50px 0px #000
border-radius: 14.5px
.section-block
display: flex
flex-direction: column
gap: 32px
.kraken-button
align-self: center
h2
line-height: 133%
letter-spacing: 0px
.hero-section
display: flex
justify-content: space-between
align-items: center
text-align: center
flex-direction: column
@media (min-width: 768px)
text-align: left
flex-direction: row-reverse
img
height: 450px
width: 250px
@media (min-width: 768px)
width: unset
height: unset
.hero-text
display: flex
flex-direction: column
align-items: center
@media (min-width: 768px)
width: 365px
h1
font-size: 27px
@media (min-width: 768px)
font-size: 42px
p
font-size: 18px
.token-liquidity-section
text-align: center
align-self: center
margin-top: 88px
max-width: 840px
z-index: 10
p
text-align: center
font-weight: 50
@media (min-width: 768px)
text-align: unset
h2
font-weight: 400
letter-spacing: 0.25px
font-size: 24px
@media (min-width: 768px)
font-size: 27px
.challenge-section
display: flex
flex-direction: column
gap: 120px
</style>

View file

@ -0,0 +1,38 @@
<template>
<div>
<h1 id="first">FAQ</h1>
<h3>Where to buy $KRK?</h3>
<p>Once launched you can buy $KRK on Uniswap on Base Layer 2.</p>
<h3>What is the utility of $KRK?</h3>
<p>$KRK serves as training data for the AI agent and will eventually generate returns through cross-pool liquidity management.</p>
<h3>Why is the liquidity unruggable?</h3>
<p>Liquidity is permanently locked in Uniswap and managed by immutable contracts, with 75-95% ETH reserved in the Floor position to prevent full withdrawals even through a bank run event.</p>
<h3>How often does supply expand?</h3>
<p>The AI liquidity manager mints new $KRK based on market conditions - typically during sustained buying pressure or liquidity needs.</p>
<h3>What happens to the supply during price drops?</h3>
<p>The protocol automatically burns surplus $KRK from the liquidity pool to stabilize prices during sell pressure.</p>
<h3>Is the AI Agent owned by anyone?</h3>
<p>The AI Agent is fully sovereign. No owner or admin can intervene or change the behaviour of the agent. It operates in a closed environment on-chain.</p>
<h3>How does the AI agent respond to volatile markets?</h3>
<p>The agent adjusts the Anchor width, Discovery depth of the liquidity positions, and capital allocation based on volatility ratios and staking signals in real time.</p>
<h3>Is my $KRK at risk if the AI fails?</h3>
<p>Yes Per the disclaimer, failed AI decisions could negatively impact $KRK's value. The Floor position mitigates but doesn't eliminate this risk.</p>
<h3>Are there any fees when using the protocol?</h3>
<p>There are no fees and there is no fee switch. Kraiken is an immutable protocol that has been fair launched and will continue so.</p>
<h3>How can I stake my $KRK?</h3>
<p>You can get access to staking by contacting the team.</p>
<h3>Can the protocol code be changed later?</h3>
<p>No All contracts are permanently immutable after deployment. Liquidity Manager and AI agent operate autonomously with no upgrade path or admin controls.</p>
<h3>Are there team allocations or unlocks?</h3>
<p>No Kraiken is a fair-launch protocol with zero allocations for teams or investors. All tokens enter circulation via the liquidity pool.</p>
</div>
</template>
<script setup lang="ts">
import { onMounted } from 'vue';
const emit = defineEmits(["onmounted"])
onMounted(() => {
emit("onmounted")
})
</script>

View file

@ -0,0 +1,22 @@
<template>
<div>
<h1 id="first">Fair Market Mechanism</h1>
<p>The Harberger Tax, developed by economist Arnold Harberger and popularized in the book Radical Markets and the RadicalxChange movements Partial Common Ownership concept, is a system where property owners pay a tax based on their own assessed value of their property. However, they must be willing to sell the property at that value to anyone who wants to buy it. This approach encourages owners to be honest about the value of their assets and helps allocate resources to those who value them the most.</p>
<h2 id="second">Implementation in the Crypto Context</h2>
<p>In crypto, limited assets or positions are often held by a select few without options for redistributing ownershipexamples include early investors, protocol teams, fee distributions, multisig holders, NFT owners etc. The HARBERG protocol aims to challenge the current model of protocol ownership and test an alternative approach.</p>
<h2 id="third">Key Differences</h2>
<p>In the traditional model, the value of the asset is constantly changeable to reflect the current market value and dynamics. In the HARBERG protocol, the tax rate is constantly changeable, and owners must evaluate it regularly to retain their ownership positions.
</p>
<h3>Read More:</h3>
<p> See <a href="website.org">Harberger Tax Blog Post</a> or <a href="website.org">Owner Tax</a> </p>
</div>
</template>
<script setup lang="ts">
import { onMounted } from 'vue';
const emit = defineEmits(["onmounted"])
onMounted(() => {
emit("onmounted")
})
</script>

View file

@ -0,0 +1,24 @@
<template>
<div>
<h1 id="first">Generate Passive Income</h1>
<p>In traditional protocol designs, holders benefit from a protocols success only indirectly through an increase in token price. HARBERG changes this by allowing holders to earn directly through a passive income stream funded by protocol owners, who pay for the privilege of staying in their positions of power. </p>
<br>
<p>Token holders are essential for decentralisation, governance and decision-making in crypto. Their role is key to a projects long-term success. Its only fair that token holders should have the right to become owners of the very protocol they support.</p>
<h2 id="second">Buy $HARB</h2>
<p> $HARB tokens and the Harberg Protocol are deployed on Base an $ETHeum Layer 2. $HARB can be bought on <a href="uniswap.org">Uniswap</a> there. </p>
<h2 id="third">Passive Income</h2>
<p>By holding $HARB, holders can claim a passive income funded by the owners tax. The more owners are competing for limited owner slots the higher the tax for the token holders.</p>
<p>The longer the token is held, the more tax holders can claim. No protocol fee is taken. </p>
<h2 id="fourth">Sell $HARB</h2>
<p>$HARB can be sold anytime on <a href="uniswap.org">Uniswap</a> </p>
</div>
</template>
<script setup lang="ts">
import { onMounted } from 'vue';
const emit = defineEmits(["onmounted"])
onMounted(() => {
emit("onmounted")
})
</script>

View file

@ -0,0 +1,52 @@
<template>
<div>
<h1 id="first">Introduction</h1>
<p>Welcome to KrAIken, a decentralized finance (DeFi) protocol that integrates artificial intelligence (AI) to optimize liquidity management. KrAIken operates autonomously, ensuring on-chain execution of adaptive liquidity strategies.</p>
<p>At the core of KrAIken is the $KRK token and its liquidity pool, which acts as a testing ground and learning environment for the AI agent. The agent dynamically adjusts liquidity positions based on real-time market data, aiming to maintain stability and efficiency within the pool. Disclaimer: If the agent fails in its tasks, it may negatively impact the value of $KRK.</p>
<p>This initiative not only tests the resilience of the protocol but also offers the community an opportunity to interact with and evaluate its performance. Through continuous iteration, KrAIkens AI will eventually expand to other Uniswap liquidity pools, generating profits through liquidity fees and creating real utility for the protocol and the $KRK token.</p>
<p>KrAIken is not just another centralized, hosted large language model (LLM). It is fully sovereign. Developed by <a href="https://sovraigns.network">SovrAIgns.network</a>, KrAIken represents an evolution in DeFi, combining decentralized finance principles with adaptive AI to create a truly innovative financial platform.</p>
<p>In the chapters ahead, we will delve into KrAIkens liquidity management strategies, the architecture of its AI agent, the tokenomics of $KRK, and staking mechanisms available to our community members.</p>
<br>
<pre>
..-.
-+:.:==-=++=-
-=++++=++==+++++:
.=+++===:=++++==+++= :---:::
=-++=--. -+++**+: .-=======::
=-+*+:. :*****+ :--========-=:
+=**+. :+***+ .++===-==+++=+==: :::
=+**+-:--==-: *****: +**+===+=+++++++=: .--=--:: .::.
-=+*+=::- :--: *****- =***++*+ ++- : ======-:-=--: --
:--=++:.::+.:- -****=. :-++++**=**++++=: =+=++++==+=----: --
*:*+++= :*+==+=..=++-. -****++ -+**********+*+*++: =- =+++++++++++=+=--==: :=-
:*:+*******+*=-+=-:.+-++-: =++***++ -=**********+*****+=+ =+***++++== .==++===== -==
*:*:*:*:****+*++++-- :***= :++*****+=.=*******++*******+=+*- .++****++-+ +=-+=++==-: ===
***:: *+*+++++- :+**= *****************++*+*****+++*+**********+*+: =+++++++.- .===
*: ++*++++=. =+***+- *********::****+=+=****+-=+********::**+= +++++++= . --=
+===++++. :+******= +******:::****+=:=+****-:=+****:::::**** .:++==-= ::--
:-+*+++++= :-=*+****:: ::::**:*****=::::*****=:.+*****::***=..:----. ::-++++=== -:
+.:=+++++*+:.:=+*+*****:*:::******+-::::-****++:::-********+-+++++++++=- .:+++++=++--. -==-
+:** +***+-=++++++=::.==+******+********+:::::=******+=::::******++**+++++++++=-. ++++++++++:.: --:
**::*+****+++++==:+=++*= :--=******=******+=::::::*******++:::::+***=***+++:::=-----:: =+==++++==:----:
***=== =++++=-+=*++++::-::++**+=+***+==::::::********+++::::+***+=++++:: ----:.==+++++++=--::
+=*++=+++:--.+++++-++++=:::::=+**********++=:::::++==+++ ::::..=++++*++-----:
-+-+++*+++=.:--===:==+===-=+===+****++++*++++:::::-=.=== ..:-----=++++++::+:
++++**++++-:-..--=. :--- ---==========- . +=+-:::::.--=-+======-.=++++++++::
:+++++++++-::..:-::=: . .:-.: . . :-.:--.::--:=---:.:::- -++++:+:
:--:-+++==-:- -: .- :---=-=--=-: . =++++*+=
: .:.=-:.--:.... : : :.::---=-. .:-===+++=
:: .. .... :. . - ::: . . .. .====+++******:.:
:-..-==: . : : :====++++++++++*****++++=-++**************=+
***-:::::::= ++++- -+=- .--:::--=-= ++++++=++=++++==+ *++********** ******
</pre>
</div>
</template>
<script setup lang="ts">
import { onMounted } from 'vue';
const emit = defineEmits(["onmounted"])
onMounted(() => {
emit("onmounted")
})
</script>

View file

@ -0,0 +1,87 @@
<template>
<div>
<h1>Liquidity Management</h1>
<p>The liquidity of $KRK tokens is fully managed by an immutable Liquidity Manager (LM) contract. This contract governs the minting, burning, and allocation of liquidity to ensure market stability, efficient trading, and adaptive responses to market dynamics. The LM operates through three distinct liquidity positions: Floor, Anchor, and Discovery (inspired by <a href="https://docs.baseline.markets/btokenomics/dynamic_liquidity#protocol-owned-liquidity-positions">Baseline</a>). Each serves a specific role in maintaining a balanced and resilient ecosystem.</p>
<p>The Liquidity Manager operates exclusively on a Uniswap V3 pool on the Base network with a tick spacing of 200, equivalent to 1% fee tier. Other liquidity pools on different networks will only receive liquidity indirectly through arbitrage.</p>
<br>
<pre>
Floor % $ETH
%
% + $KRK
%
%
%
%
%
L %
i %
q % Discovery
u %
i %
d % ++++++++++++
i % ++++++++++++
t % ++++++++++++
y % Anchor ++++++++++++
% ++++++++++++
%++++++++++++
%%%%++++++++++++++++
%%%%++++++++++++++++
%%%%++++++++++++++++
%%%%%+++++++++++++++
%%%%%+++++++++++++++
%%%%%+++++++++++++++
Price
current Price
</pre>
<h2>Floor Position</h2>
<p>The Floor is a highly concentrated liquidity position within a narrow price range. Its primary function is to provide a guaranteed minimum buyback price for $KRK tokens. This reserve stabilizes the protocol by ensuring that token holders always have a predictable exit value. As the protocol grows, the LM allocates more $ETH to the Floor, increasing its depth and reliability. Between 75% and 95% of all $ETH managed by the protocol is typically held in the Floor position.</p>
<p>A critical aspect of the Floor position is its use of Volume Weighted Average Price (VWAP) to determine its pricing strategy. VWAP represents the average sale price of $KRK tokens weighted by trading volume, providing a kind of approximate and compressed memory over historic sales of tokens from its liquidity. The LM calculates the VWAP using cumulative trade data, ensuring that on average tokens are bought back for cheaper than they were sold for. By anchoring the protocols liquidity to a VWAP-adjusted price, the system retains a sober approach to Floor positioning while allowing for market-responsive adjustments of Anchor and Discovery.</p>
<h2>Anchor Position</h2>
<p>The Anchor position offers less liquidity depth than the Floor but spans a broader price range. It is always positioned at the current market price, ensuring its relevance to active trading. The size of the Anchor position dynamically adjusts based on the "sentiment" input, a value generated by an on-chain AI agent analyzing staking signals and trading data. Sentiment determines the allocation of 5% to 25% of the total $ETH supply to the Anchor, influencing its liquidity depth and responsiveness. This adaptive sizing strategy puts more capital at risk during market uptrends while adopting a defensive posture when sentiment turns negative. The exact adjustment strategy depends on the training embedded in the on-chain AI agent, which targets developing the token price and maximizing trading fees for the protocol. For more on staking signals, visit the "For Owners" chapter, and for details about the AI agent, see the "AI-Agent" chapter.</p>
<h2>Discovery Position</h2>
<p>The Discovery position provides the broadest price coverage and greater liquidity depth compared to the Anchor. It is designed for price exploration beyond the current range, supporting efficient trading during periods of high demand or significant market growth. Discovery covers a price range up to three times the current price, and holds liquidity at a depth twice as concentrated as the Anchor position. This ensures robust liquidity for price exploration while incentivizing trading activity in less active price ranges. $ETH accumulated in the Discovery position is periodically redistributed to the Floor and Anchor positions.</p>
<h2>Rebalancing Mechanism</h2>
<p>The Liquidity Manager rebalances the Floor, Anchor, and Discovery positions based on market price movements. This process is triggered through an open contract call that anyone can execute at any time. Before rebalancing occurs, the function ensures a key condition is met: the price must have moved significantly, surpassing a minimum amplitude threshold of twice the tick spacing (2%).</p>
<p>When the token price moves:</p>
<ul>
<li><strong>Upwards:</strong> The Liquidity Manager reallocates more $ETH to the Floor position to enhance its stability and increases the size of the Discovery position for further price exploration. New $KRK tokens are minted to support this growth.</li>
<li><strong>Downwards:</strong> The Liquidity Manager reduces the Anchor and Discovery positions proportionally and burns excess tokens, maintaining equilibrium and reducing supply pressure.</li>
</ul>
<p>This dynamic system ensures that the protocol responds effectively to market conditions while safeguarding token holders and traders. The contract is immutable, guaranteeing that neither the team nor any other entity can access or control the liquidity. Users are encouraged to review the code to understand the mechanics before participating.</p>
<h2>Risk Profile</h2>
<p>
While the Liquidity Manager offers a "guaranteed minimum buyback" through the Floor position, the price is dynamic because some $ETH is always allocated to the Anchor position for active trading. This ensures efficient price discovery and liquidity optimization but also introduces variability in the Floors backing. Compared to systems like Baseline, which use similar Floor, Anchor, and Discovery positions, Kraiken operates with a more dynamic and risk-tolerant approach. This allows for potentially higher rewards but comes with increased exposure to market fluctuations.
</p>
</div>
</template>
<script setup lang="ts">
import { onMounted } from 'vue';
const emit = defineEmits(["onmounted"])
onMounted(() => {
emit("onmounted")
})
</script>

View file

@ -0,0 +1,120 @@
<template>
<div>
<h1>Staking</h1>
<p>Staking has two important benefits:</p>
<p>1. It helps the AI Agent with market sentiment analysis.</p>
<p>2. It transparently rewards users that promote the $KRK token and the KrAIken protocol without the need of backdoor deals or insider allocation.</p>
<h2>1. Staking Slots</h2>
<p>As a token holder you can stake your $KRK tokens to claim staking slots and become a Staker of the KrAIken Protocol. Stakers earn a share of newly minted tokens when the token supply expands (see Tokenomics).</p>
<p>In exchange for that benefit stakers have to pay a self-assessed tax. At any time, another token holder who agrees to pay a higher tax can buyout lower-tax staking slots. This creates a fair and dynamic market for staking slots.</p>
<ul>
<li><strong>Owner Slots:</strong> How many slots you can claim depends on the percentage of tokens you own compared to the total supply. Staking 0.001% of $KRK total supply gives 1 owner slot.</li>
<li><strong>Dynamic Value:</strong> As new tokens are minted (see supply expansion in Tokenomics), your claim automatically applies to the new total supply</li>
<li><strong>Limited Capacity:</strong> There are only 20,000 staking slots that represent 20% of all $KRK at any time.</li>
</ul>
<p class="warning">Example: Alice stakes 10,000 $KRK. The current total supply sits at 1M. As she holds 1% of the current total supply she gets 1,000 owner slots. When the supply increases to 2M, the 1% (1,000 slots) are worth now 20,000 $KRK after expansion.</p>
</div>
<br>
<pre>
*** ### ### ***
*## ++ ##*
*## ++ ##*
*## ++ ##*
*# ++ ##*
*## ++ 20% ##*
*## ++ Staking +++ ##*
*## ++ +++ ##*
*## ++ ++ ##*
*## ++ ++++ ##*
*## ++ ++++ ##*
*## ++ ++++ ##*
*## +++++ ##*
*## ##*
*## ##*
*## 80% Open Market ##*
*## ##*
*## ##*
*## ##*
*## ##*
*## ##*
*# ##*
*## ##*
*## ##*
*** ### ### ***
</pre>
<div class="concept-block">
<h2>2. Harberger Tax Mechanism</h2>
<p>To keep things fair and transparent, stakers need to pay a sel-assessed tax on their position. Inspired by the <a href="https://en.wikipedia.org/wiki/Harberger_tax" target="_blank">Harberger tax concept</a> but adapted for crypto:</p>
<ul>
<li><strong>Traditional Model:</strong> Owners self-assess property value and pay tax accordingly</li>
<li><strong>KrAIken Adaptation:</strong> Stakers choose tax <em>rates</em> instead of values, creating a competitive market for positions</li>
</ul>
<p>This system achieves three key goals:</p>
<ol>
<li><strong>Market Efficiency:</strong> Positions flow to those willing to pay highest maintenance costs (tax)</li>
<li><strong>Anti-Squating:</strong> Staking positions can get replaced anytime someone is willing to pay a higher tax, preventing permanent control</li>
<li><strong>Protocol Funding:</strong> Collected taxes finance ongoing development</li>
</ol>
</div>
<div class="concept-block">
<h2>3. Earning Potential</h2>
<p>Staking provides leveraged exposure to $KRK's growth through two channels:</p>
<h3>A. Supply Expansion</h3>
<p>The protocol's AI liquidity manager regularly mints new tokens to:</p>
<ul>
<li>Maintain exchange liquidity</li>
<li>Respond to market demand</li>
</ul>
<p>Your staked percentage automatically applies to the new larger supply. Regular holders only benefit from price changes - stakers gain from both price <em>and</em> supply growth.</p>
<h3>B. Position Protection</h3>
<p>By choosing optimal tax rates, you can:</p>
<ul>
<li>Maintain your percentage through market cycles</li>
<li>Compound earnings through repeated staking</li>
<li>Outpace simple token holding returns</li>
</ul>
</div>
<div class="concept-block">
<h2>4. Position Security</h2>
<p>While others can buyout your position at any time, crucial protections exist:</p>
<ul>
<li><strong>Full Principal Return:</strong> If replaced, you receive all untaxed $KRK and potential profit immediately</li>
<li><strong>Three-Day Grace Period:</strong> New positions must pay minimum 3 days' tax upfront</li>
<li><strong>Rate Transparency:</strong> All positions display current tax rates for informed decisions</li>
</ul>
<p class="warning">Key Insight: Losing a postion due to a buyout means lossing the benefit of <em>future</em> earnings from that stake, not existing tokens or profit.</p>
</div>
<div class="concept-block">
<h2>5. Strategic Considerations</h2>
<p>Successful staking requires balancing:</p>
<ul>
<li><strong>Tax Rate Selection:</strong> Higher rates protect positions but reduce net returns</li>
<li><strong>Market Monitoring:</strong> Track competing stakers' tax rates</li>
<li><strong>Supply Forecasts:</strong> Anticipate minting events through protocol announcements</li>
</ul>
<p>Example Strategy: Use medium tax rates (5-15% daily) during high-growth periods to balance protection and returns</p>
</div>
</template>
<script setup lang="ts">
import { onMounted } from 'vue';
const emit = defineEmits(["onmounted"])
onMounted(() => {
emit("onmounted")
})
</script>

View file

@ -0,0 +1,145 @@
<template>
<div>
<h1>Tokenomics</h1>
<p>
This section describes the design and distribution of the protocol's native digital token, Kraiken ($KRK). The token is issued exclusively through its Uniswap V3 liquidity pool, and its supply adjusts dynamically with network growth and demand.</p>
<p>Kraiken is a fair-launch protocol, meaning there are no allocations or unlocks for teams or investors. This ensures equal opportunities for all participants from the very beginning.
</p>
<h2>Dynamic Supply</h2>
<p>There is no fixed supply for $KRK. The minting and burning of $KRK tokens are fully managed by an immutable Liquidity Manager (LM) contract, which oversees the token's supply and liquidity.</p>
<h3>Supply Expansion</h3>
<p>When buys exceed sells (rising demand), new $KRK tokens are minted to "refill" the liquidity pool (e.g., after tokens are purchased from Uniswap). This expands the total supply, which, assuming price stability, increases the protocols market capitalization.</p>
<pre>
=
[ ] ^-----^
A $ETH [ 00110 1 ] ^ ^
/ \ > [ 1100 11 ] ^-----^
\/'-'\/ > [ 0100 10 ] +$KRK +
\_;_/ $KRK + - > [ 0011110 ] > ETH KRK
/ \ < ETH KRK [ ]
Alice buys $KRK from Uniswap Pool LM Contract mints $KRK and fills up Uniswap Pool
</pre>
<br>
<br>
<h3>Token Burn</h3>
<p>When sells outpace buys, surplus $KRK tokens from the liquidity pool are automatically burned to maintain its balance (further stabilizing the price).</p>
<pre>
[ ] v-----v
A $KRK [ 00110 1 ] = v v
/ \ > [ 1100 11 ] v-----v
\/'-'\/ > [ 0100 10 ] -$KRK
\_;_/ $ETH - + > [ 0011110 ] < -
/ \ < ETH KRK [ ] ETH KRK
Alice sells $KRK to Uniswap Pool LM Contract burns $KRK and balances Uniswap Pool
</pre>
<br>
<p>These dynamic supply changes make tokenomics fair and transparent for everyone. Read further for more details.</p>
<h2>Primer to Liquidity Management</h2>
<p>
The LM maintains three key liquidity positions:
</p>
<h3>1. Floor</h3>
<p>
The Floor is a liquidity position of narrow price range with highly concentrated liquidity. The Floor position is a reserve designed to provide a guaranteed minimum buyback price for $KRK. As the protocol grows, the LM allocates more ETH to the Floor position, increasing its stability and appeal to holders. At any time between 75% and 95% of all ETH managed by the protocol are located in the Floor position.
</p>
<h3>2. Anchor</h3>
<p>
The Anchor position with lower liquidity depth compared to the Floor, but covers a broader price span. It is dynamically balanced to support trading around the current price. It ensures smooth trading experiences by reducing slippage and maintaining efficient liquidity deployment.
</p>
<h3>3. Discovery</h3>
<p>
The Discovery position has more dept and range than the Anchor. It allows for price exploration beyond the current range, enabling efficient trading during periods of high demand or market growth. This position grows with network activity and serves to attract more liquidity. $ETH that is accumulated in this position is regularly moved to Floor and Anchor.
</p>
<br>
<pre>
Floor % $ETH
%
% + $KRK
%
%
%
%
%
L %
i %
q % Discovery
u %
i %
d % ++++++++++++
i % ++++++++++++
t % ++++++++++++
y % Anchor ++++++++++++
% ++++++++++++
%++++++++++++
%%%%++++++++++++++++
%%%%++++++++++++++++
%%%%++++++++++++++++
%%%%%+++++++++++++++
%%%%%+++++++++++++++
%%%%%+++++++++++++++
Price
current Price
</pre>
<br>
<p>
When the price moves up, the LM rebalances by allocating more ETH to the Floor position and expanding Discovery. To support this growth, new $KRK tokens are minted. Conversely, when the price moves down, the LM shrinks the Floor and Discovery positions proportionally and burns excess tokens. For more details, see the <a href="#/docs/Liquidity-Management">Liquidity Management</a> section.
</p>
<h2>Protocol Initialization</h2>
<p>
The Kraiken Protocol is initialized with a single transaction. The team deposits 1 $ETH into the Liquidity Manager, which sets the initial pool price at 1 cent per token. The Liquidity Manager bootstraps the Uniswap V3 liquidity pool and begins adjusting positions dynamically.
</p>
<p>
From the start, the LM rebalances positions whenever the price moves more than 2% up or down, ensuring liquidity is always optimized for current market conditions.
</p>
<h2>Utility</h2>
<p>
The $KRK token and its liquidity pool generates sufficient training data to continuously improve the AI agents performance. It kickstarts AI-driven liquidity management systems across the crypto ecosystem.
The end goal: Enable the AI to autonomously manage liquidity positions across multiple token pools on Uniswap and other DEXs. This will result in fee revenue flowing back to $KRK holders.
</p>
<h2>Objective of Token Design</h2>
<p>
The Kraiken Protocol is designed to provide a fair and adaptive token ecosystem. By launching with minimal initial liquidity and no team or investor allocations, the protocol ensures equal opportunities for all participants. Minting and burning respond dynamically to market conditions, supporting growth during expansion and reducing supply (and sell pressure) during contraction.
</p>
<p>
The Liquidity Manager provides deep liquidity and stabilizes the price. This design allows casual holders to "hold and forget," benefiting from well-managed, stable token ecosystem without needing to actively participate in liquidity management or market decisions.
</p>
</div>
</template>
<script setup lang="ts">
import { onMounted } from 'vue';
const emit = defineEmits(["onmounted"])
onMounted(() => {
emit("onmounted")
})
</script>

View file

@ -0,0 +1,158 @@
<template>
<div>
<h1>AI Agent</h1>
<p>KrAIken is not just another LLM that suggests on-chain actions requiring admin or owner approval. Instead, KrAIken operates independently within its own on-chain execution environment, making decisions based on open data and a self-improving algorithm. No admin or owner can veto or interfere with its actions.</p>
<p>
In the chapter <strong>Liquidity Management</strong>, we described the static behavior of the contract, outlining how the liquidity manager maintains predefined parameters for market interactions. While effective in stable conditions, this static behavior lacks adaptability to dynamic market changes. Passive liquidity providers, acting as buyers of last resort, are inherently exposed to impermanent loss, as they bear the risk of price fluctuations during their provision of liquidity. By introducing an AI agent into the system, the previously static contract is now enabled to dynamically adjust to market conditions, optimizing its liquidity management strategy in real-time.
</p>
<p>
The AI agent not only relies on its training to optimize the pool but also incorporates real-time data directly sourced from stakers. Parameters such as the percentage staked and average tax rate provide valuable sentiment indicators that would otherwise only be available through off-chain analysis, enriching the agents decision-making capabilities with actionable insights from on-chain activity.
</p>
<h2>Inputs to the AI Agent</h2>
<p>
The AI agent interacts with its environment by consuming key input parameters that capture the state of the market, user behavior, and the system itself. These inputs are normalized and structured to enable efficient decision-making by the agent.
</p>
<ol>
<li>
<strong>Price Position Relative to Range:</strong>
<ul>
<li><em>Description:</em> The normalized position of the current token price within a predefined range (e.g., VWAP ± volatility bounds).</li>
<li><em>Range:</em> 0 (lower bound) to 1e18 (upper bound).</li>
</ul>
</li>
<li>
<strong>Volatility Ratio:</strong>
<ul>
<li><em>Description:</em> The ratio of current price volatility to a baseline, such as weekly historical volatility.</li>
<li><em>Range:</em> 0 (low volatility) to 1e18 (high volatility relative to baseline).</li>
</ul>
</li>
<li>
<strong>Volume-to-Liquidity Ratio:</strong>
<ul>
<li><em>Description:</em> The ratio of trading volume to liquidity in the relevant range, indicating potential profitability.</li>
<li><em>Range:</em> 0 (low volume relative to liquidity) to 1e18 (high volume relative to liquidity).</li>
</ul>
</li>
<li>
<strong>Time Since Last Call:</strong>
<ul>
<li><em>Description:</em> The elapsed time since the last AI agent update, expressed as a fraction of a predefined target interval.</li>
<li><em>Range:</em> 0 (just called) to 1e18 (maximum target interval elapsed).</li>
</ul>
</li>
<li>
<strong>Percentage Staked:</strong>
<ul>
<li><em>Description:</em> The proportion of available staking slots currently utilized by users.</li>
<li><em>Range:</em> 0 (no stake) to 1e18 (maximum stake capacity utilized).</li>
</ul>
</li>
<li>
<strong>Average Tax Rate:</strong>
<ul>
<li><em>Description:</em> The average tax rate applied to transactions, representing the systems cost structure.</li>
<li><em>Range:</em> 0 (0% tax) to 1e18 (4700% tax, maximum rate).</li>
</ul>
</li>
</ol>
<h2>Outputs from the AI Agent</h2>
<p>The AI agent optimizes specific liquidity management parameters based on its input data, dynamically adjusting them to improve market responsiveness and profitability. These outputs are sent to the liquidity manager contract for execution.</p>
<ol>
<li><strong>Capital Inefficiency:</strong>
<ul>
<li><strong>Description:</strong> Measures the deviation from optimal capital allocation, indicating potential areas for improvement in resource utilization.</li>
<li><strong>Type:</strong> <code>uint256</code></li>
</ul>
</li>
<li><strong>Anchor Share:</strong>
<ul>
<li><strong>Description:</strong> Represents the proportion of resources allocated to the anchor position, reflecting the agent's confidence in the current market stability.</li>
<li><strong>Type:</strong> <code>uint256</code></li>
</ul>
</li>
<li><strong>Anchor Width:</strong>
<ul>
<li><strong>Description:</strong> Defines the range or bandwidth of the anchor position, determining the scope of market conditions under consideration.</li>
<li><strong>Type:</strong> <code>uint24</code></li>
</ul>
</li>
<li><strong>Discovery Depth:</strong>
<ul>
<li><strong>Description:</strong> Indicates the extent to which the agent explores new strategies or market opportunities beyond the established anchor parameters.</li>
<li><strong>Type:</strong> <code>uint256</code></li>
</ul>
</li>
</ol>
<h2>Agent Contract</h2>
<p>
The Agent Contract serves as the execution layer for the AI agent, interfacing directly with the liquidity manager contract. It is invoked periodically by the liquidity manager to collect input data, run the genetic algorithm, and return actionable outputs for liquidity adjustments. The Agent Contract performs the following key functions:
</p>
<ol>
<li>
<strong>Input Collection and Preprocessing:</strong>
<ul>
<li>The contract gathers all necessary data points, such as price position, volatility ratio, volume-to-liquidity ratio, percentage staked, and average tax rate.</li>
<li>These inputs are normalized and placed onto the stack of the Push3 Virtual Machine (VM) for efficient computation.</li>
</ul>
</li>
<li>
<strong>Algorithm Loading:</strong>
<ul>
<li>The genetic algorithm, stored within the contracts state, is loaded and also placed onto the stack of the Push3 VM.</li>
<li>This setup initializes the VM for execution.</li>
</ul>
</li>
<li>
<strong>Execution and Output Retrieval:</strong>
<ul>
<li>The Push3 VM executes the genetic algorithm using the input parameters on the stack.</li>
<li>The execution results in a set of outputs, which may include adjustments to liquidity parameters or a non-action signal indicating no immediate changes are necessary.</li>
</ul>
</li>
<li>
<strong>Forwarding Outputs to Liquidity Manager:</strong>
<ul>
<li>The outputs are forwarded to the liquidity manager contract, which applies the recommended changes to reposition liquidity if necessary.</li>
</ul>
</li>
</ol>
<p>
By introducing the Agent Contract, the previously static liquidity manager becomes capable of real-time optimization, driven by on-chain evolutionary computation. If you want to know how genetic algorithms work, or why the system is considered an agent, read this <a href="https://github.com/Sovraigns/SoLUSH-3/blob/main/vision.md">vision document</a>.
</p>
<h2>Dynamic Adaptation Through AI</h2>
<p>
The AI agents ability to dynamically adapt parameters allows the liquidity manager to respond to market volatility, trading volume, and user behavior in real-time. For example:
</p>
<ul>
<li>
<strong>Volatile Markets:</strong> The agent can widen Anchor and Discovery spacing to reduce exposure and maintain stability.
</li>
<li>
<strong>High Volume:</strong> The agent can increase liquidity in Discovery to capture more trading fees.
</li>
<li>
<strong>User Engagement:</strong> High staking utilization might lead the agent to prioritize profitability over conservatism.
</li>
</ul>
<p>
By replacing static configurations with adaptive intelligence, the liquidity manager evolves into a dynamic system capable of optimizing for diverse and changing conditions. This integration enables a more resilient and efficient approach to decentralized liquidity management, where the AI agent collaborates with stakers to form a cybernetic system. Staking signals, such as the percentage staked and the average tax rate, provide critical real-time sentiment data that the agent uses to refine its decisions and adapt dynamically to market behaviors.
</p>
</div>
</template>
<script setup lang="ts">
import { onMounted } from 'vue';
const emit = defineEmits(["onmounted"])
onMounted(() => {
emit("onmounted")
})
</script>

12
landing/tsconfig.app.json Normal file
View file

@ -0,0 +1,12 @@
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
"exclude": ["src/**/__tests__/*"],
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"paths": {
"@/*": ["./src/*"]
}
}
}

11
landing/tsconfig.json Normal file
View file

@ -0,0 +1,11 @@
{
"files": [],
"references": [
{
"path": "./tsconfig.node.json"
},
{
"path": "./tsconfig.app.json"
}
]
}

View file

@ -0,0 +1,19 @@
{
"extends": "@tsconfig/node22/tsconfig.json",
"include": [
"vite.config.*",
"vitest.config.*",
"cypress.config.*",
"nightwatch.conf.*",
"playwright.config.*",
"eslint.config.*"
],
"compilerOptions": {
"noEmit": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"module": "ESNext",
"moduleResolution": "Bundler",
"types": ["node"]
}
}

19
landing/vite.config.ts Normal file
View file

@ -0,0 +1,19 @@
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
// https://vite.dev/config/
export default defineConfig({
// base: "/KraikenLanding/",
plugins: [
vue(),
vueDevTools(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
},
},
})