fix: clean URLs, contract addresses, gitmodule (#16, #58, #147) (#162)

This commit is contained in:
johba 2026-02-20 17:28:59 +01:00
parent 79c9c8571a
commit 1e0822eaa2
21 changed files with 126 additions and 47 deletions

1
.gitmodules vendored
View file

@ -7,6 +7,7 @@
[submodule "onchain/lib/uni-v3-lib"]
path = onchain/lib/uni-v3-lib
url = https://github.com/Aperture-Finance/uni-v3-lib
ignore = dirty
[submodule "onchain/lib/openzeppelin-contracts"]
path = onchain/lib/openzeppelin-contracts
url = https://github.com/openzeppelin/openzeppelin-contracts

View file

@ -1,13 +1,37 @@
<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 />
Autonomous liquidity protocol. Use at your own risk.
<div class="k-footer__contracts" v-if="krkAddress || stakeAddress">
<div class="k-footer__contracts-title">Verified Contracts</div>
<div class="k-footer__contracts-list">
<a v-if="krkAddress" :href="`https://basescan.org/address/${krkAddress}`" target="_blank" rel="noopener noreferrer">
KRK Token: {{ shortAddress(krkAddress) }}
</a>
<a v-if="stakeAddress" :href="`https://basescan.org/address/${stakeAddress}`" target="_blank" rel="noopener noreferrer">
Stake: {{ shortAddress(stakeAddress) }}
</a>
</div>
<div class="k-footer__audit-note"> Unaudited use at your own risk</div>
</div>
<div class="k-footer__about">
KrAIken is a project by <u><a href="https://sovraigns.network/" target="_blank">SovrAIgns.network</a></u
>.<br />
Autonomous liquidity protocol. Use at your own risk.
</div>
</div>
</footer>
</template>
<script setup lang="ts">
const krkAddress = import.meta.env.VITE_KRAIKEN_ADDRESS || '';
const stakeAddress = import.meta.env.VITE_STAKE_ADDRESS || '';
function shortAddress(addr: string): string {
if (!addr || addr.length < 10) return addr;
return `${addr.slice(0, 6)}${addr.slice(-4)}`;
}
</script>
<style lang="sass">
.k-footer
font-size: 14px
@ -18,4 +42,37 @@
color: #F0F0F0
@media (min-width: 992px)
font-size: 16px
.k-footer__contracts
margin-bottom: 24px
padding: 16px
background: rgba(255, 255, 255, 0.05)
border-radius: 8px
text-align: center
.k-footer__contracts-title
font-weight: 600
margin-bottom: 8px
font-size: 13px
text-transform: uppercase
letter-spacing: 1px
color: #9A9898
.k-footer__contracts-list
display: flex
gap: 24px
justify-content: center
flex-wrap: wrap
a
font-family: monospace
font-size: 13px
color: #7550AE
text-decoration: none
&:hover
text-decoration: underline
.k-footer__audit-note
margin-top: 8px
font-size: 12px
color: #9A9898
</style>

View file

@ -73,7 +73,7 @@ const pnlPercent = computed(() => {
const pnlClass = computed(() => (pnlPercent.value >= 0 ? 'positive' : 'negative'));
const appUrl = computed(() => `/app/#/wallet/${address.value}`);
const appUrl = computed(() => `/app/wallet/${address.value}`);
</script>
<template>

View file

@ -128,7 +128,7 @@
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.
<a href="/docs/Liquidity-Management">Liquidity Management</a> section.
</p>
<h2>Protocol Initialization</h2>

View file

@ -2,6 +2,7 @@ import { expect, test, type APIRequestContext } from '@playwright/test';
import { Wallet } from 'ethers';
import { createWalletContext } from '../setup/wallet-provider';
import { getStackConfig, validateStackHealthy } from '../setup/stack';
import { navigateSPA } from '../setup/navigate';
const ACCOUNT_PRIVATE_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80';
const ACCOUNT_ADDRESS = new Wallet(ACCOUNT_PRIVATE_KEY).address.toLowerCase();
@ -152,8 +153,8 @@ test.describe('Acquire & Stake', () => {
console.log('[TEST] Stack version footer verified.');
console.log('[TEST] Navigating to cheats page...');
await page.goto(`${STACK_WEBAPP_URL}/app/#/cheats`);
await expect(page.getByRole('heading', { name: 'Cheat Console' })).toBeVisible();
await navigateSPA(page, '/app/cheats');
await expect(page.getByRole('heading', { name: 'Cheat Console' })).toBeVisible({ timeout: 10_000 });
console.log('[TEST] Minting test ETH...');
await page.getByLabel('RPC URL').fill(STACK_RPC_URL);
@ -217,7 +218,7 @@ test.describe('Acquire & Stake', () => {
// Now test staking via UI
console.log('[TEST] Navigating to stake page...');
await page.goto(`${STACK_WEBAPP_URL}/app/#/stake`);
await navigateSPA(page, '/app/stake');
await page.waitForTimeout(2_000);
// Wait for the stake form to be initialized

View file

@ -2,6 +2,7 @@ import { expect, test, type APIRequestContext } from '@playwright/test';
import { Wallet } from 'ethers';
import { createWalletContext } from '../setup/wallet-provider';
import { getStackConfig, validateStackHealthy } from '../setup/stack';
import { navigateSPA } from '../setup/navigate';
import { TAX_RATE_OPTIONS } from '../../kraiken-lib/src/taxRates';
const ACCOUNT_PRIVATE_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80';
@ -163,8 +164,8 @@ test.describe('Max Stake All Tax Rates', () => {
// Step 1: Mint test ETH
console.log('[TEST] Navigating to cheats page...');
await page.goto(`${STACK_WEBAPP_URL}/app/#/cheats`);
await expect(page.getByRole('heading', { name: 'Cheat Console' })).toBeVisible();
await navigateSPA(page, '/app/cheats');
await expect(page.getByRole('heading', { name: 'Cheat Console' })).toBeVisible({ timeout: 10_000 });
console.log('[TEST] Minting test ETH (10 ETH)...');
await page.getByLabel('RPC URL').fill(STACK_RPC_URL);
@ -217,7 +218,7 @@ test.describe('Max Stake All Tax Rates', () => {
// Step 3: Navigate to stake page
console.log('[TEST] Navigating to stake page...');
await page.goto(`${STACK_WEBAPP_URL}/app/#/stake`);
await navigateSPA(page, '/app/stake');
await page.waitForTimeout(2_000);
const tokenAmountSlider = page.getByRole('slider', { name: 'Token Amount' });

View file

@ -55,7 +55,7 @@ test.describe('GraphQL URL Verification', () => {
try {
console.log('[TEST] Navigating to staking page...');
await page.goto(`${STACK_WEBAPP_URL}/app/#/stake`, { waitUntil: 'domcontentloaded' });
await page.goto(`${STACK_WEBAPP_URL}/app/stake`, { waitUntil: 'domcontentloaded' });
// Wait for page to fully load and settle
await page.waitForLoadState('networkidle');

View file

@ -80,7 +80,7 @@ test.describe('Dashboard Pages', () => {
});
try {
await page.goto(`${STACK_WEBAPP_URL}/app/#/wallet/${ACCOUNT_ADDRESS}`, {
await page.goto(`${STACK_WEBAPP_URL}/app/wallet/${ACCOUNT_ADDRESS}`, {
waitUntil: 'domcontentloaded',
});
await page.waitForLoadState('networkidle');
@ -143,7 +143,7 @@ test.describe('Dashboard Pages', () => {
const page = await context.newPage();
try {
await page.goto(`${STACK_WEBAPP_URL}/app/#/wallet/${ACCOUNT_ADDRESS}`, {
await page.goto(`${STACK_WEBAPP_URL}/app/wallet/${ACCOUNT_ADDRESS}`, {
waitUntil: 'domcontentloaded',
});
await page.waitForLoadState('networkidle');
@ -174,7 +174,7 @@ test.describe('Dashboard Pages', () => {
try {
// Navigate to a wallet with no balance
const unknownAddr = '0x0000000000000000000000000000000000000001';
await page.goto(`${STACK_WEBAPP_URL}/app/#/wallet/${unknownAddr}`, {
await page.goto(`${STACK_WEBAPP_URL}/app/wallet/${unknownAddr}`, {
waitUntil: 'domcontentloaded',
});
await page.waitForLoadState('networkidle');
@ -224,7 +224,7 @@ test.describe('Dashboard Pages', () => {
});
try {
await page.goto(`${STACK_WEBAPP_URL}/app/#/position/${positionId}`, {
await page.goto(`${STACK_WEBAPP_URL}/app/position/${positionId}`, {
waitUntil: 'domcontentloaded',
});
await page.waitForLoadState('networkidle');
@ -297,7 +297,7 @@ test.describe('Dashboard Pages', () => {
});
try {
await page.goto(`${STACK_WEBAPP_URL}/app/#/position/999999999`, {
await page.goto(`${STACK_WEBAPP_URL}/app/position/999999999`, {
waitUntil: 'domcontentloaded',
});
await page.waitForLoadState('networkidle');
@ -340,7 +340,7 @@ test.describe('Dashboard Pages', () => {
const page = await context.newPage();
try {
await page.goto(`${STACK_WEBAPP_URL}/app/#/position/${positionId}`, {
await page.goto(`${STACK_WEBAPP_URL}/app/position/${positionId}`, {
waitUntil: 'domcontentloaded',
});
await page.waitForLoadState('networkidle');

View file

@ -101,7 +101,7 @@ test.describe('Alex Rivera - Crypto-Curious Newcomer', () => {
// --- Navigate to Stake Page to Learn ---
pageStart = Date.now();
await page.goto(`${STACK_WEBAPP_URL}/app/#/stake`);
await page.goto(`${STACK_WEBAPP_URL}/app/stake`);
await page.waitForTimeout(3_000);
recordPageVisit('Stake (learning)', page.url(), pageStart, report);
@ -143,7 +143,7 @@ test.describe('Alex Rivera - Crypto-Curious Newcomer', () => {
logObservation(personaName, 'I need to get some tokens first... let me figure out how', report);
pageStart = Date.now();
await page.goto(`${STACK_WEBAPP_URL}/app/#/cheats`);
await page.goto(`${STACK_WEBAPP_URL}/app/cheats`);
await page.waitForTimeout(2_000);
recordPageVisit('Cheats (confused)', page.url(), pageStart, report);
@ -178,7 +178,7 @@ test.describe('Alex Rivera - Crypto-Curious Newcomer', () => {
// --- Navigate to Stake (Intimidated) ---
pageStart = Date.now();
await page.goto(`${STACK_WEBAPP_URL}/app/#/stake`);
await page.goto(`${STACK_WEBAPP_URL}/app/stake`);
await page.waitForTimeout(2_000);
recordPageVisit('Stake (attempting)', page.url(), pageStart, report);
@ -212,7 +212,7 @@ test.describe('Alex Rivera - Crypto-Curious Newcomer', () => {
await page.waitForTimeout(3_000);
// --- Check for Progress Indicators ---
await page.goto(`${STACK_WEBAPP_URL}/app/#/stake`);
await page.goto(`${STACK_WEBAPP_URL}/app/stake`);
await page.waitForTimeout(2_000);
await takeScreenshot(page, personaName, 'looking-for-my-position', report);

View file

@ -112,7 +112,7 @@ test.describe('All Personas - Fresh Pool State', () => {
console.log(`[${persona.shortName}] ✅ Wallet connected`);
// 3. Mint ETH
await page.goto(`${STACK_WEBAPP_URL}/app/#/cheats`);
await page.goto(`${STACK_WEBAPP_URL}/app/cheats`);
await page.waitForTimeout(1_000);
await mintEth(page, STACK_RPC_URL, address, persona.ethToMint);
await takeScreenshot(page, persona.shortName, '3-eth-minted', report);
@ -128,7 +128,7 @@ test.describe('All Personas - Fresh Pool State', () => {
await page.waitForTimeout(2_000);
// 5. Navigate to stake page
await page.goto(`${STACK_WEBAPP_URL}/app/#/stake`);
await page.goto(`${STACK_WEBAPP_URL}/app/stake`);
await page.waitForTimeout(3_000);
await takeScreenshot(page, persona.shortName, '5-stake-page', report);
@ -142,7 +142,7 @@ test.describe('All Personas - Fresh Pool State', () => {
await page.waitForTimeout(2_000);
// 7. Verify position exists
await page.goto(`${STACK_WEBAPP_URL}/app/#/stake`);
await page.goto(`${STACK_WEBAPP_URL}/app/stake`);
await page.waitForTimeout(2_000);
const myPositionsSection = page.locator('.my-positions-list, [class*="my-position"], [class*="MyPosition"]').first();

View file

@ -511,7 +511,7 @@ export async function attemptStake(
console.log(`[${personaName}] Attempting to stake ${amount} KRK at tax rate ${taxRateIndex}%...`);
const baseUrl = page.url().split('#')[0];
await page.goto(`${baseUrl}#/stake`);
await page.goto(`${baseUrl}stake`);
// Wait longer for page to load and stats to initialize
await page.waitForTimeout(3_000);

View file

@ -86,7 +86,7 @@ test.describe('Marcus "Flash" Chen - Degen/MEV Hunter', () => {
// --- Mint ETH (Cheats) ---
pageStart = Date.now();
await page.goto(`${STACK_WEBAPP_URL}/app/#/cheats`);
await page.goto(`${STACK_WEBAPP_URL}/app/cheats`);
await page.waitForTimeout(1_000);
recordPageVisit('Cheats', page.url(), pageStart, report);
@ -123,7 +123,7 @@ test.describe('Marcus "Flash" Chen - Degen/MEV Hunter', () => {
// --- Navigate to Stake Page ---
pageStart = Date.now();
await page.goto(`${STACK_WEBAPP_URL}/app/#/stake`);
await page.goto(`${STACK_WEBAPP_URL}/app/stake`);
await page.waitForTimeout(4_000);
recordPageVisit('Stake', page.url(), pageStart, report);
@ -149,7 +149,7 @@ test.describe('Marcus "Flash" Chen - Degen/MEV Hunter', () => {
// --- Try to Snatch Another Position (if visible) ---
logObservation(personaName, 'Scrolling through active positions looking for snatch targets...', report);
await page.goto(`${STACK_WEBAPP_URL}/app/#/stake`);
await page.goto(`${STACK_WEBAPP_URL}/app/stake`);
await page.waitForTimeout(2_000);
await takeScreenshot(page, personaName, 'looking-for-snatch-targets', report);
@ -166,7 +166,7 @@ test.describe('Marcus "Flash" Chen - Degen/MEV Hunter', () => {
// --- Check Statistics ---
pageStart = Date.now();
await page.goto(`${STACK_WEBAPP_URL}/app/#/stake`);
await page.goto(`${STACK_WEBAPP_URL}/app/stake`);
await page.waitForTimeout(1_000);
const statsVisible = await page.getByText('Statistics').isVisible().catch(() => false);

View file

@ -99,7 +99,7 @@ test.describe('Dr. Priya Malhotra - Institutional/Analytical Investor', () => {
// --- Examine Stake Page Statistics ---
pageStart = Date.now();
await page.goto(`${STACK_WEBAPP_URL}/app/#/stake`);
await page.goto(`${STACK_WEBAPP_URL}/app/stake`);
await page.waitForTimeout(3_000);
recordPageVisit('Stake (analysis)', page.url(), pageStart, report);
@ -109,7 +109,7 @@ test.describe('Dr. Priya Malhotra - Institutional/Analytical Investor', () => {
// --- Examine Three-Position Liquidity Claim ---
pageStart = Date.now();
await page.goto(`${STACK_WEBAPP_URL}/app/#/cheats`);
await page.goto(`${STACK_WEBAPP_URL}/app/cheats`);
await page.waitForTimeout(2_000);
recordPageVisit('Cheats (liquidity analysis)', page.url(), pageStart, report);
@ -157,7 +157,7 @@ test.describe('Dr. Priya Malhotra - Institutional/Analytical Investor', () => {
// --- Navigate to Stake for Optimal Tax Rate Analysis ---
pageStart = Date.now();
await page.goto(`${STACK_WEBAPP_URL}/app/#/stake`);
await page.goto(`${STACK_WEBAPP_URL}/app/stake`);
await page.waitForTimeout(2_000);
recordPageVisit('Stake (optimization)', page.url(), pageStart, report);
@ -192,7 +192,7 @@ test.describe('Dr. Priya Malhotra - Institutional/Analytical Investor', () => {
await page.waitForTimeout(3_000);
// --- Review Position Management Interface ---
await page.goto(`${STACK_WEBAPP_URL}/app/#/stake`);
await page.goto(`${STACK_WEBAPP_URL}/app/stake`);
await page.waitForTimeout(2_000);
await takeScreenshot(page, personaName, 'position-management', report);

View file

@ -91,7 +91,7 @@ test.describe('Sarah Park - Cautious Yield Farmer', () => {
// --- Navigate to Stake Page to Learn ---
pageStart = Date.now();
await page.goto(`${STACK_WEBAPP_URL}/app/#/stake`);
await page.goto(`${STACK_WEBAPP_URL}/app/stake`);
await page.waitForTimeout(3_000);
recordPageVisit('Stake (research)', page.url(), pageStart, report);
@ -115,7 +115,7 @@ test.describe('Sarah Park - Cautious Yield Farmer', () => {
// --- Mint ETH ---
pageStart = Date.now();
await page.goto(`${STACK_WEBAPP_URL}/app/#/cheats`);
await page.goto(`${STACK_WEBAPP_URL}/app/cheats`);
await page.waitForTimeout(1_000);
recordPageVisit('Cheats', page.url(), pageStart, report);
@ -142,7 +142,7 @@ test.describe('Sarah Park - Cautious Yield Farmer', () => {
// --- Navigate Back to Stake ---
pageStart = Date.now();
await page.goto(`${STACK_WEBAPP_URL}/app/#/stake`);
await page.goto(`${STACK_WEBAPP_URL}/app/stake`);
await page.waitForTimeout(2_000);
recordPageVisit('Stake (attempt)', page.url(), pageStart, report);
@ -169,7 +169,7 @@ test.describe('Sarah Park - Cautious Yield Farmer', () => {
await page.waitForTimeout(3_000);
// --- Check Active Positions ---
await page.goto(`${STACK_WEBAPP_URL}/app/#/stake`);
await page.goto(`${STACK_WEBAPP_URL}/app/stake`);
await page.waitForTimeout(2_000);
await takeScreenshot(page, personaName, 'checking-my-position', report);

View file

@ -27,7 +27,7 @@ import { execSync } from 'child_process';
const STACK_CONFIG = getStackConfig();
const STACK_RPC_URL = STACK_CONFIG.rpcUrl;
const STAKE_PAGE_URL = `${STACK_CONFIG.webAppUrl}/app/#/stake`;
const STAKE_PAGE_URL = `${STACK_CONFIG.webAppUrl}/app/stake`;
// Anvil test account keys
const MARCUS_KEY = '0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6'; // Anvil #3

View file

@ -18,7 +18,7 @@ import { join } from 'path';
const STACK_CONFIG = getStackConfig();
const STACK_RPC_URL = STACK_CONFIG.rpcUrl;
const STACK_WEBAPP_URL = STACK_CONFIG.webAppUrl;
const STAKE_PAGE_URL = 'http://localhost:5173/#/stake';
const STAKE_PAGE_URL = 'http://localhost:5173/stake';
// Different accounts for different personas
const MARCUS_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'; // Anvil #0

View file

@ -80,7 +80,7 @@ test.describe('Tyler "Bags" Morrison - Retail Degen', () => {
// --- Navigate to Cheats (Finds It Randomly) ---
pageStart = Date.now();
await page.goto(`${STACK_WEBAPP_URL}/app/#/cheats`);
await page.goto(`${STACK_WEBAPP_URL}/app/cheats`);
await page.waitForTimeout(1_000);
recordPageVisit('Cheats', page.url(), pageStart, report);
@ -118,7 +118,7 @@ test.describe('Tyler "Bags" Morrison - Retail Degen', () => {
// --- Navigate to Stake (No Idea What He's Doing) ---
pageStart = Date.now();
await page.goto(`${STACK_WEBAPP_URL}/app/#/stake`);
await page.goto(`${STACK_WEBAPP_URL}/app/stake`);
await page.waitForTimeout(3_000);
recordPageVisit('Stake', page.url(), pageStart, report);
@ -145,7 +145,7 @@ test.describe('Tyler "Bags" Morrison - Retail Degen', () => {
await page.waitForTimeout(3_000);
// --- Checks for Immediate Gains ---
await page.goto(`${STACK_WEBAPP_URL}/app/#/stake`);
await page.goto(`${STACK_WEBAPP_URL}/app/stake`);
await page.waitForTimeout(2_000);
await takeScreenshot(page, personaName, 'checking-gains', report);

17
tests/setup/navigate.ts Normal file
View file

@ -0,0 +1,17 @@
import type { Page } from '@playwright/test';
/**
* Navigate within the Vue SPA without a full page reload.
* Uses history.pushState + popstate to trigger Vue Router navigation,
* preserving wallet connection state and reactive stores.
*
* For initial page loads, use page.goto() instead.
*/
export async function navigateSPA(page: Page, path: string): Promise<void> {
await page.evaluate((p) => {
window.history.pushState({}, '', p);
window.dispatchEvent(new PopStateEvent('popstate'));
}, path);
// Give Vue Router time to resolve the route and render
await page.waitForTimeout(500);
}

View file

@ -17,7 +17,7 @@
<RouterLink v-for="navbarRoute in navbarRoutes" :key="navbarRoute.name" :to="navbarRoute.path">
{{ navbarRoute.title }}
</RouterLink>
<a href="/#/docs">Docs</a>
<a href="/app/docs">Docs</a>
</nav>
<template v-if="!isMobile">
<div class="vertical-line"></div>

View file

@ -46,7 +46,7 @@ provide('isMobile', isMobile);
provide('showPanel', showPanel);
function openDocs() {
window.open('https://emberspirit007.github.io/KraikenLanding/#/docs/Introduction');
window.open('/app/docs');
}
</script>

View file

@ -1,8 +1,10 @@
import { createRouter, createWebHashHistory } from 'vue-router';
import { createRouter, createWebHistory } from 'vue-router';
import { authGuard } from './authGuard';
const basePath = import.meta.env.VITE_BASE_PATH || '/app/';
const router = createRouter({
history: createWebHashHistory(),
history: createWebHistory(basePath),
routes: [
{
path: '/',