Production Ready v1.0.0

Integration & Setup Guide

Watchtower delivers real-time error logging, warning tracking, crash detection, and blockchain observability directly into your Telegram chat with one-click resolution buttons.

⚡ Zero-Config Setup (No API Key Required)

Because Watchtower is your team's internal tool, API keys are completely optional. You can point any client directly to Watchtower and start capturing events immediately.

Base Endpoint
https://watchtower.cogrowth.xyz
Authentication
Zero-Config (None Required)
Default Ingest Path
POST /v1/events
Heartbeat Ping
GET /v1/monitors/:slug/ping
🔒 Automatic Redaction: Watchtower's server automatically sanitizes private keys, crypto seeds, passwords, and authorization tokens from all incoming errors before saving or pinging Telegram.

📱 Mobile Frameworks (React Native, Flutter, iOS, Android)

Watchtower works natively with mobile applications. Choose your mobile stack below:

Install the browser client or send events directly in React Native:

npm install @folajindayo/watchtower-browser

App.tsx / App.js:

import { init, captureException, logger } from '@folajindayo/watchtower-browser';

// Initialize at top of app (Zero API key needed)
init({
  endpoint: 'https://watchtower.cogrowth.xyz',
  environment: __DEV__ ? 'development' : 'production',
  release: 'mobile-v1.0.0',
  captureUnhandled: true
});

// Capture caught errors
try {
  await authenticateMobileUser();
} catch (error) {
  captureException(error, {
    tags: { screen: 'LoginScreen', device: 'iOS' }
  });
}

In your Flutter application, send error and warning payloads via HTTP to the Watchtower native gateway:

import 'dart:convert';
import 'package:http/http.dart' as http;

class Watchtower {
  static const String endpoint = 'https://watchtower.cogrowth.xyz/v1/events';

  static Future<void> captureException(dynamic error, StackTrace stackTrace) async {
    try {
      await http.post(
        Uri.parse(endpoint),
        headers: {
          'Content-Type': 'application/json',
        },
        body: jsonEncode({
          'message': error.toString(),
          'level': 'error',
          'platform': 'flutter',
          'environment': 'production',
          'stacktrace': stackTrace.toString(),
        }),
      );
    } catch (_) {}
  }
}

// In main.dart:
void main() {
  FlutterError.onError = (details) {
    Watchtower.captureException(details.exception, details.stack ?? StackTrace.current);
  };
  runApp(MyApp());
}

Log errors and crashes from your native Swift / SwiftUI app:

import Foundation

class Watchtower {
    static let shared = Watchtower()
    private let url = URL(string: "https://watchtower.cogrowth.xyz/v1/events")!

    func captureError(message: String, level: String = "error", extra: [String: Any]? = nil) {
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")

        let payload: [String: Any] = [
            "message": message,
            "level": level,
            "platform": "ios",
            "environment": "production"
        ]

        request.httpBody = try? JSONSerialization.data(withJSONObject: payload)
        URLSession.shared.dataTask(with: request).resume()
    }
}

// Usage:
Watchtower.shared.captureError(message: "Failed to load wallet credentials")

Log uncaught exceptions and errors from your native Kotlin app:

import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject

object Watchtower {
    private val client = OkHttpClient()
    private const val ENDPOINT = "https://watchtower.cogrowth.xyz/v1/events"

    fun captureException(throwable: Throwable) {
        val json = JSONObject().apply {
            put("message", throwable.localizedMessage ?: "Unknown Android Exception")
            put("level", "error")
            put("platform", "android")
            put("stacktrace", throwable.stackTraceToString())
        }

        val request = Request.Builder()
            .url(ENDPOINT)
            .post(json.toString().toRequestBody("application/json".toMediaType()))
            .build()

        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: java.io.IOException) {}
            override fun onResponse(call: Call, response: Response) { response.close() }
        })
    }
}

⚙️ Backend Integration (Node.js, Express, Fastify)

Zero-overhead native Node.js SDK with automatic unhandled error interception.

npm install @folajindayo/watchtower-node
import { init, captureException, logger, setUser, expressErrorHandler } from '@folajindayo/watchtower-node';
import express from 'express';

const app = express();

// Initialize at startup (zero configuration / no API key needed)
init({
  endpoint: 'https://watchtower.cogrowth.xyz',
  environment: process.env.NODE_ENV || 'production',
  release: 'backend@1.0.0',
  autoCatch: true // Intercepts uncaughtException & unhandledRejection
});

// Structured logs deliver straight to Telegram & Status Board
logger.info('Order fulfillment worker started', { workerId: 3 });
logger.warn('Payment gateway slow response', { latencyMs: 2500 });

// Express error handling middleware
app.use(expressErrorHandler());

app.listen(8080);

💻 Frontend Integration (React, Next.js, Vite, Vue)

Client-side error boundary with automatic button click and navigation breadcrumbs.

npm install @folajindayo/watchtower-browser
import React from 'react';
import ReactDOM from 'react-dom/client';
import { init, ErrorBoundary } from '@folajindayo/watchtower-browser';
import App from './App';

init({
  endpoint: 'https://watchtower.cogrowth.xyz',
  environment: 'production',
  captureUnhandled: true, // Catches window.onerror
  autoBreadcrumbs: true   // Records click events and navigation
});

ReactDOM.createRoot(document.getElementById('root')!).render(
  <ErrorBoundary fallback={<div>Something went wrong. Our team has been alerted.</div>}>
    <App />
  </ErrorBoundary>
);

⛓️ Blockchain & Web3 Integration (EVM, Viem, Ethers)

Automatic revert reason decoding, relayer gas threshold alerts, and indexer lag reporting.

npm install @folajindayo/watchtower-evm viem
import { createPublicClient, http } from 'viem';
import { mainnet } from 'viem/chains';
import { withWatchtower } from '@folajindayo/watchtower-evm';

const baseClient = createPublicClient({ chain: mainnet, transport: http() });

// Wrap client with Watchtower middleware (Zero API key needed)
export const client = withWatchtower(baseClient, {
  watchtowerUrl: 'https://watchtower.cogrowth.xyz',
  chainId: 1
});

// Decodes custom Solidity revert errors & Panic codes:
// 🔴 EVM Revert: InsufficientAllowance(required: 1000, current: 0)

⏱️ Crons & Heartbeats (Dead Man's Switch)

Ensure your background workers and scheduled sync jobs run reliably. If a worker fails to ping, Telegram alerts you immediately.

Add this single curl line to any cron script or worker loop (no API key or auth token required):

curl -fsS -m 10 "https://watchtower.cogrowth.xyz/v1/monitors/nightly-sync/ping"

🤖 Telegram Control Plane

Telegram is your primary triage interface. Interactive buttons let you resolve, acknowledge, and ignore errors directly from your phone.

How to link your chat:

  1. Open @Tsion_Logger_Bot in Telegram (or add it to your team group).
  2. Send the command: /link JOIN01
  3. Your chat is now subscribed to real-time incident notifications!