INDIPOLI

INSTALL TUTORIAL — LARAGON / WINDOWS

A copy-pasteable walkthrough from a fresh Laragon install to a running IndiPoli at http://indipoli.test with the first opportunity flowing through the pipeline. Every command block is meant to be executed verbatim from a Laragon Terminal (Cmder) unless noted.

0. PREREQUISITES

1. CLONE THE REPO

cd C:\laragon\www
git clone https://github.com/YOUR_ORG/indipoli.git indipoli
cd indipoli

2. ENABLE REQUIRED PHP EXTENSIONS

Open your Laragon PHP ini file — the exact path depends on which PHP version Laragon is running. In the default bundle it is:

C:\laragon\bin\php\php-8.3.16-Win32-vs16-x64\php.ini

Open it in a text editor (Laragon tray → PHP → php.ini) and make sure the following extension lines are present and uncommented (remove any leading ;):

extension=sodium
extension=gmp
extension=pdo_mysql
extension=mbstring
extension=curl
extension=bcmath
extension=openssl
extension=fileinfo

Then restart Apache via the Laragon tray (right-click tray icon → Apache → Reload). Verify:

php -m | findstr /I "sodium gmp pdo_mysql mbstring curl bcmath openssl fileinfo"

3. INSTALL PHP DEPENDENCIES

composer install

4. INSTALL + BUILD THE FRONTEND BUNDLE

The Reown AppKit wallet bridge lives in frontend/src as a small TypeScript project. Build it once after cloning and then again whenever you touch those sources.

cd frontend
pnpm install
pnpm build
cd ..

If you don’t have pnpm installed, npm install && npm run build works too. The build emits public/assets/wallet.bundle.js (about 3.8 MB unminified).

5. CREATE THE MYSQL DATABASE

Open Laragon tray → MySQL → HeidiSQL (or any MySQL client) and run:

CREATE DATABASE indipoli
  DEFAULT CHARACTER SET utf8mb4
  COLLATE utf8mb4_0900_ai_ci;

CREATE USER 'indipoli'@'localhost' IDENTIFIED BY '';
GRANT ALL ON indipoli.* TO 'indipoli'@'localhost';
FLUSH PRIVILEGES;

The empty password is intentional for the Laragon dev default — every test fixture, migration and config file expects it. Change it only if you also update .env accordingly.

6. CREATE THE .env FILE

copy .env.example .env

Now open .env and fill in these fields:

APP_KEK_B64 (required)

The base64-encoded envelope-encryption master key. Generate one:

php scripts/generate-kek.php

Paste the output line into .env. Never lose this key. Losing it means every stored credential becomes unreadable.

REOWN_PROJECT_ID (required for wallet)

Get one from cloud.reown.com (see signup prerequisites).

VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEY (required for push)

Web Push needs a VAPID keypair. Generate one:

php scripts/generate-vapid.php

Paste both lines into .env. Keep the private key secret — it is what lets your server prove it is the origin allowed to push to the subscribed browsers.

TELEGRAM_BOT_TOKEN (optional)

Only needed if you want the bot integration. See the Telegram guide for how to obtain one from @BotFather. Can be set per-user in Settings instead of globally in .env.

RATE_*_PER_MIN, CIRCUIT_*

Defaults are fine for development. Raise them for production workloads.

7. RUN DATABASE MIGRATIONS

vendor\bin\phinx migrate -c db\phinx\phinx.php -e local

Expect ~25 migrations to run in order, covering Phases 1 through v1.1. If any one of them fails, check that the MySQL user has ALL privileges on the indipoli database.

8. CONFIGURE THE APACHE VIRTUAL HOST

Laragon auto-detects C:\laragon\www\indipoli and creates a vhost at http://indipoli.test. The repository ships a root .htaccess that rewrites everything into public/, so you do not need to change the document root. If Laragon’s auto-vhost points directly at public/ that also works.

Restart Apache via the tray to pick up the new vhost.

9. FIRST RUN — LANDING PAGE

Open http://indipoli.test/ in your browser. You should see the brutalist landing page with SIGNUP / LOGIN / TOS / DOCS in the header. If you get a 500, check the Apache error log in Laragon tray → Logs → Apache.

10. START THE BACKGROUND WORKERS

Open three separate Laragon terminals (one per worker) and run:

php bin\worker.php all
php bin\position-tracker.php
php bin\sweeper.php

worker.php processes the jobs queue (Moodix polling, LLM pairing, opportunity creation, trade notifications).
position-tracker.php refreshes open Polymarket positions.
sweeper.php cleans up expired jobs / orphaned locks / stale opportunities.

Leave all three running.

11. CREATE YOUR FIRST ACCOUNT

Visit /signup, fill in email / password / country / ToS, click Create Account. You will be redirected to login. Log in.

12. CONFIGURE CREDENTIALS IN SETTINGS

  1. Go to /settings/moodix and paste your Moodix API key.
  2. Go to /settings/polymarket and paste the three L2 fields (key / secret / passphrase).
  3. Go to /settings/llm and pick a provider, paste the key, optionally set a model name.
  4. Click Test Connection on each tab — green means the key works.
  5. Go to /settings/limits and set your risk limits (max per trade, max trades/day, max USDC/day, min auto-probability).

13. CONNECT YOUR WALLET

Go to /app/dashboard and click the Connect Wallet button in the wallet status widget. Approve the connection in your wallet extension, confirm the chain switch to Polygon if prompted, then sign the SIWE link message. Finally, click Approve USDC to grant a bounded allowance to the Polymarket CTF Exchange. Your browser signs each step; the server only records the receipts.

14. VERIFY THE PIPELINE

php bin\jobs.php status

You should see job counts cycling as Moodix polling fires. Within a minute or two, the dashboard’s Opportunities panel should start filling via SSE (no refresh needed). When you see a high-edge row with a Trade button, the pipeline is fully operational.

TROUBLESHOOTING

ext-gmp missing / ext-sodium missing

Composer will install fine but runtime crashes with “Call to undefined function gmp_...” or sodium errors. Re-check step 2 — the extension lines must be active in the exact php.ini that php -v reports, and you must restart Apache afterwards.

HTTP 419 on POST requests

Already handled. FlightPHP v3.18 maintains a response-code whitelist; the Bootstrap shim patches 419 and 451 at container wire-up. You do not need to change anything — just make sure you are running the current app/Bootstrap.php.

Empty .mmdb file / GeoIP lookup failing

The GeoLite2 database is not shipped in the repo. For development IndiPoli honours GEOIP_BYPASS_LOCAL=true, which lets private-range IPs (127.0.0.1, ::1, 192.168.*) through without a lookup. For a real MMDB file, register a free MaxMind account, download GeoLite2-Country.mmdb, and put it in var/geoip/.

Password reset email not arriving

Laragon ships a built-in mail catcher at http://localhost:8025. IndiPoli’s default MAILER_DSN=smtp://localhost:1025 points at it. Open that URL and you will see every outgoing email.

Port 80 already in use

Common on Windows if IIS is running. Either stop IIS (net stop w3svc) or change Laragon’s Apache port (Laragon menu → Preferences → Services & Ports).

Worker dies after a minute

Normal. WORKER_MAX_RUNTIME_SECONDS=600 limits a single worker process to 10 minutes for safety. Wrap it in a .bat loop or scripts/worker.bat if you want supervisord-like behaviour on Windows.

Tests fail on a fresh install

The integration tests hit the live http://indipoli.test vhost and the indipoli MySQL database. Make sure both are running and the migrations have been applied before composer test.

Installed successfully? Great. Now configure the v1.1 integrations: push, multi-wallet, telegram.