{"id":47681704,"url":"https://github.com/hyperlinksspace/hyperlinksspaceprogram","last_synced_at":"2026-05-14T22:05:30.975Z","repository":{"id":322735273,"uuid":"1088999177","full_name":"HyperlinksSpace/HyperlinksSpaceProgram","owner":"HyperlinksSpace","description":"AI \u0026 Blockchain multiplatform solution for managing, investing and earning assets. Features recommendations, chats, swaps, trades, wallets and deals. AI Transmitter accesses chains' data.","archived":false,"fork":false,"pushed_at":"2026-04-15T04:40:58.000Z","size":15898,"stargazers_count":2,"open_issues_count":10,"forks_count":4,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-15T06:03:26.876Z","etag":null,"topics":["ai","android","blockchain","eth","iphone","mac","telegram","ton","windows"],"latest_commit_sha":null,"homepage":"https://landing.program.hyperlinks.space/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/HyperlinksSpace.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-03T18:41:30.000Z","updated_at":"2026-04-15T04:32:30.000Z","dependencies_parsed_at":null,"dependency_job_id":"1c00f881-d934-4ef9-a753-1b4a127e59ad","html_url":"https://github.com/HyperlinksSpace/HyperlinksSpaceProgram","commit_stats":null,"previous_names":["bigbanghere/xp7k","xp7k/xp7k","bc1qa5pw/bc1qbot","techsymbol/q1cbbot","techsymbal/techsymbalbot","techsymbal/bot","hypeandlinks/app","andlinks/andlinks","hyperlinksspace/hyperlinksspaceprogram","hyperlinksspace/hyperlinksspacebot"],"tags_count":275,"template":false,"template_full_name":"Telegram-Mini-Apps/nextjs-template","purl":"pkg:github/HyperlinksSpace/HyperlinksSpaceProgram","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HyperlinksSpace%2FHyperlinksSpaceProgram","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HyperlinksSpace%2FHyperlinksSpaceProgram/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HyperlinksSpace%2FHyperlinksSpaceProgram/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HyperlinksSpace%2FHyperlinksSpaceProgram/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HyperlinksSpace","download_url":"https://codeload.github.com/HyperlinksSpace/HyperlinksSpaceProgram/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HyperlinksSpace%2FHyperlinksSpaceProgram/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31959886,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T00:39:45.007Z","status":"online","status_checked_at":"2026-04-18T02:00:07.018Z","response_time":103,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","android","blockchain","eth","iphone","mac","telegram","ton","windows"],"created_at":"2026-04-02T14:01:07.633Z","updated_at":"2026-05-14T22:05:30.969Z","avatar_url":"https://github.com/HyperlinksSpace.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Preview Image](https://raw.githubusercontent.com/HyperlinksSpace/HyperlinksSpaceProgram/refs/heads/main/assets/images/PreviewImage.png)\n\n# Hyperlinks Space Program\n\n\u003cu\u003e**In progress, contribute!**\u003c/u\u003e\n\nThis program is built upon [React Native](https://reactnative.dev/) by Meta and [Expo](https://expo.dev) multiplatform technologies, Windows build and executable creation achieved with [Electron Builder](https://www.electron.build/) and [Electron Forge](https://www.electronforge.io/), working in Telegram with help of [Telegram Mini Apps React SDK](http://telegram-mini-apps.com/), [Bot API](https://core.telegram.org/bots) and [Grammy](https://grammy.dev/). AI is backed by [OpenAI API](https://openai.com/ru-RU/api/), blockchain info is processed from [Swap.Coffee API](https://docs.swap.coffee/eng/user-guides/welcome). DB for the best user's experience we host on [Neon](https://neon.tech/). Keys are managed by [Google Cloud Key Management](https://cloud.google.com/security/products/security-key-management).\n\nCheck out our [Pitch Deck](./PitchDeck/PitchDeck.md).\n\n## Program design\n\nAccess [Figma](https://www.figma.com/design/53lDKAD6pRv3e0uef1DP18/TECHSYMBAL-Inc.?node-id=754-71\u0026t=v3tmAlywNgXkTWMd-1) in real time for contributing. Contact [Seva](https://t.me/anriltine) in Telegram to discuss and implement.\n\nAll core materials are available publicly for currently active https://www.hyperlinks.space/ team members' instant and easy access worldwide and our project's availability for newcomers' research only.\n\n## Structure\n\n- [`app`](./app) - Expo/React Telegram Mini App client (web/mobile screens, navigation, UI logic).\n- [`ui`](./ui) - shared UI layer (components, theme tokens, and font configuration used by the app).\n- [`bot`](./bot) - TypeScript Telegram bot service and runtime entrypoints.\n- [`database`](./database) - database startup/migration/service scripts.\n- [`ai`](./ai) - AI assistant service logic and model integration points.\n- [`api`](./api) - backend API handlers and server-side endpoints.\n- [`blockchain`](./blockchain) - TON/blockchain interaction logic and related helpers.\n- [`telegram`](./telegram) - Telegram-specific integration utilities and adapters.\n- [`windows`](./windows) - Electron desktop shell, NSIS installer config, and auto-update flow. Troubleshooting in-app updates: [texts/windows-in-app-updater-debug.md](./texts/windows-in-app-updater-debug.md).\n- [`scripts`](./scripts) - developer/ops scripts (local run, migration, release helpers).\n- [`docs`](./docs) - project and operational documentation (architecture, releases, security reference, tooling).\n- [`research`](./research) - exploratory notes, investigations, and proposals not yet promoted to `docs/`.\n- [`backlogs`](./backlogs) - short-term planning notes and prioritized work items.\n- [`assets`](./assets) - static assets used by app, installer, and branding.\n- [`dist`](./dist) - generated web build output (export artifacts).\n\n## How to fork and contribute?\n\n1. Install GitHub CLI and authorize to GitHub from CLI for instant work\n\n```\nwinget install --id GitHub.cli\ngh auth login\n```\n\n2. Fork the repo, clone it and create a new branch and switch to it\n\n```\ngh repo fork https://github.com/HyperlinksSpace/HyperlinksSpaceBot.git --clone\ngit checkout -b new-branch-for-an-update\ngit switch -c new-branch-for-an-update\n```\n\n3. Make a commit (address unassigned issue or think yourself)\n\n```\ngit add . # Stage changes on this branch\ngit commit -m \"Describe your change\" # Commit on this branch\n```\n\n3. After making a commit, make a pull request, gh tool will already know the upstream remote\n\n```\ngh pr create --title \"My new PR\" --body \"It is my best PR\"\n```\n\n4. For subsequent commits (sync `main`, create a fresh branch, and commit there)\n\n```\ngit checkout main # Return to main\ngit fetch upstream # Fully sync with upstream main\ngit reset --hard upstream/main # Reset local main to upstream/main\ngit push origin main # Keep your fork main in sync too\ngit switch -c new-branch-for-next-update # Create and switch to a new feature branch\n```\n\n**Move in loops starting from the step 3.**\n\n## Local deploy\n\n`npm` package note: `.env.example` is included in the published package so you can use it as a reference for establishing your testing environment with `.env` file.\n\nBefore local deploy / cloud deploy, prepare these env-backed services:\n\n1. **Neon PostgreSQL (`DATABASE_URL`)**\n   - Create an account/project at [Neon](https://neon.tech/).\n   - Create a database and copy the connection string.\n   - Put it into `.env` as `DATABASE_URL=...`.\n2. **OpenAI API (`OPENAI_API_KEY`)**\n   - Create an account at [OpenAI Platform](https://platform.openai.com/).\n   - Create an API key in the API Keys page.\n   - Put it into `.env` as `OPENAI_API_KEY=...`.\n3. **Telegram bot token (`BOT_TOKEN`)**\n   - In Telegram, open [@BotFather](https://t.me/BotFather), create a test bot with `/newbot`.\n   - Copy the bot token and put it into `.env` as `BOT_TOKEN=...`.\n4. **Vercel project envs (for comfortable deploy/testing)**\n   - Create a [Vercel](https://vercel.com/) account and import this repository as a project.\n   - In Project Settings -\u003e Environment Variables, set at least:\n     - `DATABASE_URL`\n     - `OPENAI_API_KEY`\n     - `BOT_TOKEN` (or `TELEGRAM_BOT_TOKEN`)\n     - Optional — **Google Cloud KMS** (wallet envelope API): **`GCP_SERVICE_ACCOUNT_JSON`** — see [below](#gcp_service_account_json-google-cloud-kms).\n   - Pull envs locally when needed with `vercel env pull .env.local`.\n5. **Vercel CLI login (required for `npm run start`)**  \n   The default dev command runs **`vercel dev`** (local API). That needs a **valid Vercel CLI session**, not only project env vars in the dashboard.\n   - Install the CLI if needed: `npm i -g vercel` (or use `npx vercel` as the scripts do).\n   - Run **`vercel login`** once and complete authentication in the browser.\n   - From the repo root, run **`vercel link`** if prompted so this directory is tied to your Vercel project (team/project scope).\n   - If you see **`The specified token is not valid`**, your stored token expired or was revoked: run **`vercel login`** again to refresh it. Do not set a broken **`VERCEL_TOKEN`** in `.env` unless it is a current deploy token from the Vercel dashboard.\n\n### GCP_SERVICE_ACCOUNT_JSON (Google Cloud KMS)\n\nServerless routes under [`api/`](./api) that call **Cloud KMS** (wallet envelope KEK) read credentials from the env var **`GCP_SERVICE_ACCOUNT_JSON`**. The value must be the **full JSON object** of a Google Cloud **service account key** whose identity is allowed to use the KMS crypto key (see [`infra/gcp/kms.env.example`](./infra/gcp/kms.env.example)). The app passes this JSON in-process to the Google client — **no** key file is required on Vercel.\n\n**How to get the JSON**\n\n1. Open [Google Cloud Console](https://console.cloud.google.com/), select project **`hyperlinksspacebot`**.\n2. Go to **IAM \u0026 Admin → Service Accounts** and open **`wallet-kms-unwrap@hyperlinksspacebot.iam.gserviceaccount.com`** (the account permitted for your key; adjust if you use a different project or SA).\n3. **Keys → Add key → Create new key → JSON**. A `.json` file downloads.\n\n   **CLI alternative** (with [`gcloud`](https://cloud.google.com/sdk/gcloud) installed and authorized):\n\n   ```bash\n   gcloud iam service-accounts keys create ./wallet-kms-unwrap-sa-key.json \\\n     --iam-account=wallet-kms-unwrap@hyperlinksspacebot.iam.gserviceaccount.com \\\n     --project=hyperlinksspacebot\n   ```\n\n**What to put in `GCP_SERVICE_ACCOUNT_JSON`**\n\n- The **entire file contents** of that key — the single JSON object with `\"type\": \"service_account\"`, `\"client_email\"`, `\"private_key\"`, etc. Paste into Vercel as one variable (minified or multi-line per the dashboard; the value must remain valid JSON).\n\n**Where to configure**\n\n- **Vercel (production):** Project → **Settings → Environment Variables** → add **`GCP_SERVICE_ACCOUNT_JSON`**, assign to **Production** (and **Preview** if needed), **Redeploy** so serverless functions see the new value.\n- **Local dev:** Prefer a file and `GOOGLE_APPLICATION_CREDENTIALS`, or put the same JSON string in `.env.local` — details in [`infra/gcp/backend-authentication.md`](./infra/gcp/backend-authentication.md).\n\nThe downloaded key is a **secret** (like a password): do **not** commit it to git; add `wallet-kms-unwrap-sa-key.json` to `.gitignore` if you keep a local copy.\n\nCopy env template locally:\n\n```bash\ncp .env.example .env\n```\n\nTo start the full local stack, run:\n\n```bash\nnpm run start\n```\n\nThis runs Expo dev server, the Telegram bot (polling mode), and local Vercel API (`vercel dev`). **Without a successful `vercel login`, the Vercel leg will exit** (e.g. invalid token). Use **`npm run start:expo`** if you only need the app and want to skip Vercel for now.\n\nAfter `npm run start`, you can test the app on real phones with Expo Go:\n\n- Install **Expo Go** from Google Play (Android) or App Store (iOS).\n- Make sure your phone and development machine are on the same network.\n- Open Expo Go and scan the QR code shown in the terminal/Expo UI.\n- The app will launch on the device and hot-reload on code changes.\n\nIsolated/local run options:\n\n- Expo only (no bot, no Vercel): `npm run start:expo`\n- Bot only (polling mode): `npm run bot:local`\n- Vercel API only: `npm run dev:vercel`\n\n## GitHub Actions\n\nCurrent Actions workflows include:\n\n- [`Vercel Deploy Test`](./.github/workflows/vercel-deploy-test-envs.yml) - manual web deploy to Vercel.\n- [`Electron Forge EXE Release`](./.github/workflows/electron-forge-exe-release.yml) - manual Windows release pipeline.\n- [`Electron EXE Release`](./.github/workflows/electron-exe-release.yml) - manual Windows release pipeline.\n- [`Lint errors check`](./.github/workflows/lint-errors-check.yml) - manual lint check.\n- [`EXPO Publish`](./.github/workflows/expo-publish.yml) - manual OTA publish with EAS CLI.\n- [`NPM Package Release`](./.github/workflows/npm-package-release.yml) - npm/GitHub Packages release workflow.\n\n## Deploy to Vercel\n\nFrom the repository root, deploy the static web build to Vercel production:\n\n```bash\nvercel --prod\n```\n\nDeploying from repository root makes this folder the project root, so `api/bot` is deployed and no Root Directory setting is needed. The project is configured so Vercel runs `npx expo export -p web` and serves the `dist/` output. Link the project first with `vercel` if needed.\n\n## Telegram bot\n\nThe bot is extended beyond a basic \"Hello\" and \"Start program\" responder and now supports AI streaming and threads.\n\n**Vercel (webhook)**  \n- **Runtime path:** Telegram sends updates to `POST /api/bot`. This route proxies to the shared bot webhook handler in `bot/webhook`.\n- **Webhook setup:** `scripts/set-webhook.ts` sets `https://\u003cbase\u003e/api/bot` using `VERCEL_PROJECT_PRODUCTION_URL` (preferred) or `VERCEL_URL`.\n- **Required env:** set `BOT_TOKEN` (or `TELEGRAM_BOT_TOKEN`) in Vercel project envs for production deploys.\n- **Deploy flow:** webhook mode is intended for Vercel deploys (CLI `vercel --prod` or the manual GitHub Action `Vercel Deploy (Test Envs)`).\n\n**Bot works locally but not on Vercel**  \n1. Confirm Vercel env has `BOT_TOKEN` and redeploy.\n2. Ensure the deployed URL is stable and matches the webhook target (`/api/bot`).\n3. Check deploy/runtime logs for `[set-webhook]` and `[webhook]` errors.\n4. Do not run local polling with the same token while validating webhook mode.\n\n**Local (getUpdates, no webhook)**  \n- Only `BOT_TOKEN` is required (env or `.env`).\n- Run bot only: `npm run bot:local`\n- Run full local stack (Expo + bot + Vercel): `npm run start`\n- Keep production and local bot tokens separate when possible to avoid webhook/polling conflicts.\n\n## Pull requests and commits requirements\n\n- Give pull requests and commits a proper name and description\n- Dedicate each pull request to an understandable area or field, each commit to a focused logical change\n- Check file changes in every commit pulled, no arbitrary files modifications should persist such as LF/CRLF line-ending conversion, broken/garbled text diffs, BOM added or removed, accidental \"invisible\" corruption from text filters\n- Add dependecies and packages step by step for security\n- An issue creation or following an existing before a pull request would be a good practice\n\n## Expo Workflows\n\n[EAS Workflows](https://docs.expo.dev/eas/workflows/get-started/) are here for Expo update/build/deploy flows (triggered via npm scripts from [`package.json`](./package.json)).\n\n## Previews\n\nRun `npm run draft` to [publish a preview update](https://docs.expo.dev/eas/workflows/examples/publish-preview-update/) of your project, which can be viewed in Expo Go or in a development build.\n\n## Development Builds\n\nRun `npm run development-builds` to [create a development build](https://docs.expo.dev/eas/workflows/examples/create-development-builds/). Note - you'll need to follow the [Prerequisites](https://docs.expo.dev/eas/workflows/examples/create-development-builds/#prerequisites) to ensure you have the correct emulator setup on your machine.\n\n## Expo envs setup\n\n**Expo app** – `npx expo start` reads env from the environment; for app-only env vars you can also put them in `.env` and use an Expo-compatible loader if you add one, or set them in the shell before running:\n   ```bash\n   export BOT_TOKEN=your_token\n   npx expo start\n   ```\n\n## GitLab access\n\nGitHub and GitLab repositories are identical. If you want to contribute through GitLab, get access from [@staindart](https://github.com/staindart).\n\nIf you can push to **both** [GitHub](https://github.com/HyperlinksSpace/HyperlinksSpaceProgram) and [GitLab](https://gitlab.com/hyperlinks.space/HyperlinksSpaceProgram) directly, we ask you to configure Git so pushes keep **both** hosts in sync: the repositories are the same; avoid updating only one side.\n\n1. **Keep `origin` on GitHub for fetch and the first push URL.** If you cloned from GitHub, this is already true: `origin` is where `git pull` / `git fetch origin` get updates. We standardize on GitHub for **incoming** history from `origin` so your local `main` tracks `origin/main` on GitHub.\n\n2. **Register GitLab as a second push URL on `origin`.** Git allows multiple **push** URLs per remote name, but only one **fetch** URL. Adding GitLab here means a single `git push origin \u003cbranch\u003e` (or the IDE **Sync** push step) sends the same commits to **both** GitHub and GitLab without a second command.\n\n   ```bash\n   git remote set-url --add --push origin https://gitlab.com/hyperlinks.space/HyperlinksSpaceProgram.git\n   ```\n\n   Run this once per clone; it does not change where you fetch from.\n\n3. **Add a separate remote named `gitlab`.** Because `origin`’s fetch URL stays on GitHub, `git fetch origin` never downloads refs from GitLab. The extra remote lets you run `git fetch gitlab` when you need to compare or merge with the GitLab copy (for example if CI or another contributor updated GitLab only).\n\n   ```bash\n   git remote add gitlab https://gitlab.com/hyperlinks.space/HyperlinksSpaceProgram.git\n   ```\n\n   Note, that GitHub and GitLab URL's are a little different :)\n\n   If `gitlab` already exists with a wrong URL, use `git remote set-url gitlab https://gitlab.com/hyperlinks.space/HyperlinksSpaceProgram.git` instead.\n\n4. **Verify** with `git remote -v`. You should see GitHub on fetch/push for `origin`, GitLab as the second `origin` push line, and `gitlab` for fetch/push to GitLab:\n\n   ```text\n   gitlab  https://gitlab.com/hyperlinks.space/HyperlinksSpaceProgram.git (fetch)\n   gitlab  https://gitlab.com/hyperlinks.space/HyperlinksSpaceProgram.git (push)\n   origin  https://github.com/HyperlinksSpace/HyperlinksSpaceProgram.git (fetch)\n   origin  https://github.com/HyperlinksSpace/HyperlinksSpaceProgram.git (push)\n   origin  https://gitlab.com/hyperlinks.space/HyperlinksSpaceProgram.git (push)\n   ```\n\n**GitLab HTTPS access:** GitLab.com does not use **fine-grained** personal access tokens for Git-over-HTTPS (`git push` / `git fetch`). Create a **legacy** personal access token under GitLab → **Edit profile** → **Access tokens** with scopes **`read_repository`** and **`write_repository`**, as described in the official guide: [Personal access tokens](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html). Use your GitLab username and the token as the password when Git prompts. GitHub authentication stays separate (for example `gh auth login` or your existing GitHub credential).\n\n## Program Kit\n\nTo make it easier for developers to create multiplatform programs with us, we decided to launch an npm package that provides a ready starter for creating such a program basis in one command.\n\n```bash\nnpx @www.hyperlinks.space/program-kit ./new-program\n```\n\nLink to the package: https://www.npmjs.com/package/@www.hyperlinks.space/program-kit\n\nThe **npm registry page** shows a separate package-oriented description: [`npmReadMe.md`](./npmReadMe.md) in the repo root. At publish time the [NPM Package Release](.github/workflows/npm-package-release.yml) workflow copies the main [`README.md`](./README.md) to `fullREADME.md`, then replaces `README.md` with the contents of `npmReadMe.md` so `npm pack` / `npm publish` ship the shorter readme as the package readme (npm always surfaces `README.md` from the tarball). Snapshot channels, tags, and local `npm pack` checks are in [`docs/npm-release.md`](./docs/npm-release.md).\n\n## Project discussions\n\nThis repository has [GitHub Discussions](https://github.com/HyperlinksSpace/HyperlinksSpaceProgram/discussions) opened, as well you can join our [Telegram Chat](https://t.me/HyperlinksSpaceChat) and [Channel](https://t.me/HyperlinksSpace).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyperlinksspace%2Fhyperlinksspaceprogram","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhyperlinksspace%2Fhyperlinksspaceprogram","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyperlinksspace%2Fhyperlinksspaceprogram/lists"}