# TypeScript Frontend Integration Guide This document explains how frontend developers should integrate with the backend through the reusable TypeScript client at `libs/geo-api-client`. Primary backend URL for integration: - `https://momswap.produktor.duckdns.org/` Deployment: API is proxied via reverse proxy from `https://momswap.produktor.duckdns.org` to backend at `172.17.0.1:8122`. Docker Compose maps port 8122 for the reverse proxy. ## Goals - Keep cryptographic signing logic in one place. - Avoid duplicating API request code in frontend apps. - Use a consistent local key storage format across projects. ## Client package location - Source: `libs/geo-api-client/src` - Entry point: `libs/geo-api-client/src/index.ts` - Build output (browser ESM): `libs/geo-api-client/dist/index.js` ## Build and test the client ```bash cd libs/geo-api-client bun install bun test bun run build ``` ## Public API (current) ### Class: `GeoApiClient` Constructor: - `new GeoApiClient(baseUrl, storage, storageKey?)` Key methods: - `ensureKeysInStorage()` - `getStoredKeys()` - `importKeys(keys)` - `exportKeys()` - `setAccessToken(token)` - `createChallenge(publicKey)` - `loginWithSignature(publicKey, privateKey)` - `createInvitation(payload, inviterPrivateKey)` - `registerWithInvitation(...)` - `listCollections()` - `createCollection(name)` - `listFeatures(collectionId)` - `createPointFeature(collectionId, lon, lat, properties)` ## Recommended integration flow 1. Create one `GeoApiClient` instance per backend base URL. 2. Call `ensureKeysInStorage()` when app initializes. 3. Use `loginWithSignature()` to obtain and set a bearer token. 4. Call collection/feature methods after authentication. 5. Use `importKeys`/`exportKeys` in profile settings UX. ## Example (TypeScript app) ```ts import { GeoApiClient } from "../libs/geo-api-client/dist/index.js"; const storage = window.localStorage; const storageLike = { getItem: (key: string) => storage.getItem(key), setItem: (key: string, value: string) => storage.setItem(key, value), removeItem: (key: string) => storage.removeItem(key), }; const client = new GeoApiClient("https://momswap.produktor.duckdns.org", storageLike); const keys = await client.ensureKeysInStorage(); await client.loginWithSignature(keys.publicKey, keys.privateKey); const created = await client.createCollection("My Places"); await client.createPointFeature(created.id, -16.6291, 28.4636, { name: "Santa Cruz" }); const features = await client.listFeatures(created.id); console.log(features); ``` ## Security notes - Private keys are currently stored in browser storage via the selected storage adapter. - If your frontend has stronger security requirements, wrap the storage adapter with your own encryption/decryption layer before calling `setItem`/`getItem`. - Never send private keys to the backend. ## No-build frontend compatibility For no-bundler apps, import the built ESM file: ```html ``` The backend itself serves static UI at `/web/`, but this library can be consumed by any frontend runtime that supports `fetch`, `TextEncoder`, and ES modules. For local development you can switch the client base URL to `http://localhost:8122`.