vsecoder 5728cfc85a fix(client): profile polish + proper back stack + dev feed seed
Profile screen
  - Missing safe-area top inset on the header — fixed by wrapping the
    outer View in paddingTop: insets.top (matches the rest of the tab
    screens).
  - "Чат" button icon + text sat on two lines because the button used
    column layout by default. Rewritten as a full-width CTA pill with
    flexDirection: row and alignItems: center → chat-bubble icon and
    label sit on one line.
  - Dedicated "Копировать адрес" button removed. The address row in
    the info card is now the tap target: pressing it copies to clipboard
    and flips the row to "Скопировано" with a green check for 1.8s.
  - Posts tab removed entirely. User's right — a "chat profile" has no
    posts concept, just participant count + date + encryption. The
    profile screen is now a single-view info card (address, encryption
    status, added date, participants). Posts are discoverable via the
    Feed tab; a dedicated /feed/author/{pub} screen is on the roadmap
    for browsing a specific user's timeline.

Back-stack navigation
  - app/(app)/profile/_layout.tsx + app/(app)/feed/_layout.tsx added,
    each with a native <Stack>. The outer AnimatedSlot is stack-less
    (intentional — it animates tab switches), so without these nested
    stacks `router.back()` from a profile screen had no history to pop
    and fell through to root. Now tapping an author in the feed → back
    returns to feed; opening a profile from chat header → back returns
    to the chat.

Dev feed seed
  - lib/devSeedFeed.ts: 12 synthetic posts (text-only, mix of hashtags,
    one with has_attachment, varying likes/views, timestamps from "1m
    ago" to "36h ago"). Exposed via getDevSeedFeed() — stripped from
    production via __DEV__ gate.
  - Feed screen falls back to the dev seed only when the real API
    returned zero posts. Gives something to scroll / tap / like-toggle
    before the backend has real content; real data takes over as soon
    as it arrives.

Note: tapping a mock post into detail will 404 against the real node
(the post_ids don't exist on-chain). Intentional — the seed is for
scroll + interaction feel, not deep linking.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 20:08:48 +03:00
2026-04-17 14:16:44 +03:00
2026-04-17 14:16:44 +03:00
2026-04-17 14:16:44 +03:00
2026-04-17 14:16:44 +03:00
2026-04-17 14:16:44 +03:00
2026-04-17 14:16:44 +03:00
2026-04-17 14:16:44 +03:00
2026-04-17 14:16:44 +03:00
2026-04-17 14:16:44 +03:00
2026-04-17 14:16:44 +03:00
2026-04-17 14:16:44 +03:00

DChain

Блокчейн-стек для децентрализованного мессенджера:

  • PBFT консенсус с multi-sig validator governance и equivocation slashing
  • Native Go контракты рядом с WASM (wazero) — нулевая задержка для системных сервисов типа username_registry
  • WebSocket push API — клиент не опрашивает, все события прилетают на соединение
  • E2E-шифрованный relay mailbox на libp2p gossipsub с TTL live-detection
  • Система обновлений: build-time версия → /api/well-known-version, peer-version gossip, /api/update-check против Gitea releases, update.sh с semver guard
  • Prometheus /metrics, Caddy auto-HTTPS, observer mode, load-test

Содержание


Быстрый старт

Одна нода в Docker, HTTP API на localhost:8080, Explorer UI и Swagger открыты:

# 1. Собираем prod-образ
docker build -t dchain-node-slim -f deploy/prod/Dockerfile.slim .

# 2. Ключ ноды (один раз)
mkdir -p keys
docker run --rm --entrypoint /usr/local/bin/client \
  -v "$PWD/keys:/out" dchain-node-slim \
  keygen --out /out/node.json

# 3. Запуск (genesis-валидатор)
docker run -d --name dchain --restart unless-stopped \
  -p 4001:4001 -p 8080:8080 \
  -v dchain_data:/data \
  -v "$PWD/keys:/keys:ro" \
  -e DCHAIN_GENESIS=true \
  -e DCHAIN_ANNOUNCE=/ip4/127.0.0.1/tcp/4001 \
  dchain-node-slim \
  --db=/data/chain --mailbox-db=/data/mailbox --key=/keys/node.json \
  --relay-key=/data/relay.json --listen=/ip4/0.0.0.0/tcp/4001 --stats-addr=:8080

# 4. Проверка
open http://localhost:8080/            # Explorer
open http://localhost:8080/swagger     # Swagger UI
curl -s http://localhost:8080/api/well-known-version | jq .

3-node dev-кластер (для тестов PBFT кворума, slashing, federation): docker compose up --build -d — см. docs/quickstart.md.

Продакшен деплой

Два варианта, по масштабу.

🔸 Single-node (deploy/single/)

Рекомендуется для личного/первого узла. Один узел + Caddy TLS + опциональный Prometheus. Полный runbook с 6 сценариями (публичная с UI, headless, полностью приватная, genesis, joiner, auto-update) — в deploy/single/README.md.

Модели доступа

Режим DCHAIN_API_TOKEN DCHAIN_API_PRIVATE Поведение
Public (default) не задан Все могут читать и писать
Token writes задан false Читать — любой; submit tx — только с токеном
Fully private задан true Всё требует Authorization: Bearer <token>

UI / Swagger — включать или нет?

Нужно DCHAIN_DISABLE_UI DCHAIN_DISABLE_SWAGGER Открыто
Публичная с эксплорером + docs не задано не задано / Explorer, /swagger, /api/*, /metrics
Headless API-нода с OpenAPI true не задано /swagger, /api/*, /metrics
Личная hardened true true /api/* + /metrics

Флаги читаются и из CLI (--disable-ui, --disable-swagger), и из env. /api/* JSON-поверхность регистрируется всегда — отключить её можно только на уровне Caddy / firewall.

Auto-update

# node.env — когда проект в Gitea
DCHAIN_UPDATE_SOURCE_URL=https://gitea.example.com/api/v1/repos/OWNER/REPO/releases/latest
UPDATE_ALLOW_MAJOR=false
# Hourly systemd timer с 15-мин jitter
sudo cp deploy/single/systemd/dchain-update.{service,timer} /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now dchain-update.timer

Подробно: docs/update-system.md + deploy/UPDATE_STRATEGY.md.

🔹 Multi-validator (deploy/prod/)

3 validator'а в PBFT-кворуме, Caddy с ip_hash для WS-стикинесса и least-conn для REST. Для федераций / консорциумов — см. deploy/prod/README.md и docs/node/multi-server.md.

Архитектура

┌────────────┐    libp2p     ┌────────────┐    libp2p     ┌────────────┐
│   node-A   │◄─────pubsub──►│   node-B   │◄─────pubsub──►│   node-C   │
│ validator  │               │ validator  │               │ validator  │
│  + relay   │               │  + relay   │               │  + relay   │
└─────┬──────┘               └─────┬──────┘               └─────┬──────┘
      │                            │                            │
      │ HTTPS / wss (via Caddy)    │                            │
      ▼                            ▼                            ▼
    mobile / web / CLI clients   (ip_hash для WS, least-conn для REST)

Четыре слоя: network → chain → transport → app. Детали — в docs/architecture.md.

Основные пакеты:

Путь Роль
blockchain/ Блочная машина, applyTx, native-контракты, schema-migrations
consensus/ PBFT (Pre-prepare → Prepare → Commit), мемпул, equivocation
p2p/ libp2p host, gossipsub, sync протокол, peer-version gossip
node/ HTTP + WS API, SSE, metrics, access control
node/version/ Build-time version metadata (ldflags-инжектимый)
vm/ wazero runtime для WASM-контрактов + gas model
relay/ E2E mailbox с NaCl-envelopes
identity/ Ed25519 + X25519 keypair, tx signing
economy/ Fee model, rewards
wallet/ Optional payout wallet (отдельный ключ)

REST / WebSocket API

Обзор (полный reference — docs/api/README.md):

Chain + stats

Endpoint Описание
GET /api/netstats height, total_txs, supply, validator_count
GET /api/network-info chain_id, genesis, peers, validators, contracts
GET /api/blocks?limit=N / /api/block/{index} Блоки
GET /api/tx/{id} / /api/txs/recent?limit=N Транзакции
GET /api/address/{pub_or_addr} Баланс + история
GET /api/validators Validator set
GET /api/peers Connected peers + их версии
POST /api/tx Submit signed tx (rate-limited, size-capped)

Discovery + update

Endpoint Описание
GET /api/well-known-version {node_version, build{}, protocol_version, features[], chain_id}
GET /api/well-known-contracts {name → contract_id} map
GET /api/update-check Diff с Gitea release (см. docs/update-system.md)

Real-time

  • GET /api/wsWebSocket (recommended). Ops: auth, subscribe, unsubscribe, submit_tx, typing, ping. Push: block, tx, inbox, typing, submit_ack.
  • GET /api/events — SSE legacy one-way.

Scoped WS-топики (addr:, inbox:, typing:) требуют auth через Ed25519-nonce; публичные (blocks, tx, contract_log) — без.

Docs / UI

  • GET /swaggerSwagger UI (рендерится через swagger-ui-dist).
  • GET /swagger/openapi.json — сырая OpenAPI 3.0 спека.
  • GET / — block-explorer HTML (выключается DCHAIN_DISABLE_UI=true).

CLI

client keygen               --out key.json
client --version            # → dchain-client vX.Y.Z (commit=... date=...)
client balance              --key key.json --node URL
client transfer             --key key.json --to <pub> --amount <µT> --node URL
client call-contract        --key key.json --contract native:username_registry \
                            --method register --arg alice --amount 10000 \
                            --node URL
client add-validator        --key key.json --target <pub> --cosigs pub:sig,pub:sig
client admit-sign           --key validator.json --target <candidate-pub>
client deploy-contract      --key key.json --wasm ./my.wasm --abi ./my_abi.json --node URL
# полный список — `client` без аргументов, или в docs/cli/README.md

Все флаги node — в docs/node/README.md, либо node --help.

Мониторинг

Prometheus endpoint /metrics на каждой ноде. Ключевые метрики:

dchain_blocks_total                  # committed blocks count
dchain_txs_total                     # tx count
dchain_tx_submit_accepted_total
dchain_tx_submit_rejected_total
dchain_ws_connections                # current WS sockets
dchain_peer_count_live               # live libp2p peer count
dchain_max_missed_blocks             # worst validator liveness gap
dchain_block_commit_seconds          # histogram of AddBlock time

Grafana + Prometheus поднимаются вместе с нодой через docker compose --profile monitor up -d (см. deploy/single/docker-compose.yml).

Тесты

# Unit + integration
go test ./...                       # blockchain + consensus + identity + relay + vm
go vet ./...                        # static checks

# End-to-end load (3-node dev cluster должен быть поднят):
docker compose up --build -d
go run ./cmd/loadtest \
  --node http://localhost:8081 \
  --funder testdata/node1.json \
  --clients 50 --duration 60s

Документация

Полный справочник в docs/ — см. docs/README.md как оглавление. Ключевые документы:

Документ О чём
docs/quickstart.md Три пути: локально, single-node prod, федерация
docs/architecture.md 4 слоя, consensus, storage, gas model
docs/update-system.md Versioning + update-check + semver guard
docs/api/README.md REST + WebSocket reference
docs/cli/README.md CLI команды и флаги
docs/node/README.md Запуск ноды (native + Docker)
docs/contracts/README.md Системные + WASM контракты
docs/development/README.md SDK для своих контрактов
deploy/single/README.md Single-node operator runbook
deploy/prod/README.md Multi-validator federation
deploy/UPDATE_STRATEGY.md Forward-compat design (4 слоя)
Description
No description provided
Readme 1.8 MiB
Languages
Go 57.7%
TypeScript 28.1%
JavaScript 5.8%
HTML 3.1%
CSS 2.7%
Other 2.6%