chore(release): clean up repo for v0.0.1 release

Excluded from release bundle:
- CONTEXT.md, CHANGELOG.md (agent/project working notes)
- client-app/ (React Native messenger — tracked separately)
- contracts/hello_go/ (unused standalone example)

Kept contracts/counter/ and contracts/name_registry/ as vm-test fixtures
(referenced by vm/vm_test.go; NOT production contracts).

Docs refactor:
- docs/README.md — new top-level index with cross-references
- docs/quickstart.md — rewrite around single-node as primary path
- docs/node/README.md — full rewrite, all CLI flags, schema table
- docs/api/README.md — add /api/well-known-version, /api/update-check
- docs/contracts/README.md — split native (Go) vs WASM (user-deployable)
- docs/update-system.md — new, full 5-layer update system design
- README.md — link into docs/, drop CHANGELOG/client-app references

Build-time version system (inherited from earlier commits this branch):
- node --version / client --version with ldflags-injected metadata
- /api/well-known-version with {build, protocol_version, features[]}
- Peer-version gossip on dchain/version/v1
- /api/update-check against Gitea release API
- deploy/single/update.sh with semver guard + 15-min systemd jitter
This commit is contained in:
vsecoder
2026-04-17 14:37:00 +03:00
parent 7e7393e4f8
commit 546d2c503f
55 changed files with 702 additions and 17381 deletions

View File

@@ -1,127 +0,0 @@
/**
* Main app tab layout.
* Redirects to welcome if no key found.
*/
import React, { useEffect } from 'react';
import { Tabs, router } from 'expo-router';
import { Ionicons } from '@expo/vector-icons';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useStore } from '@/lib/store';
import { useBalance } from '@/hooks/useBalance';
import { useContacts } from '@/hooks/useContacts';
import { useWellKnownContracts } from '@/hooks/useWellKnownContracts';
import { getWSClient } from '@/lib/ws';
const C_ACCENT = '#7db5ff';
const C_MUTED = '#98a7c2';
const C_BG = '#111a2b';
const C_BORDER = '#1c2840';
export default function AppLayout() {
const keyFile = useStore(s => s.keyFile);
const requests = useStore(s => s.requests);
const insets = useSafeAreaInsets();
useBalance();
useContacts();
useWellKnownContracts(); // auto-discover canonical system contracts from node
// Arm the WS client with this user's Ed25519 keypair. The client signs the
// server's auth nonce on every (re)connect so scoped subscriptions
// (addr:<my_pub>, inbox:<my_x25519>) are accepted. Without this the
// server would still accept global topic subs but reject scoped ones.
useEffect(() => {
const ws = getWSClient();
if (keyFile) {
ws.setAuthCreds({ pubKey: keyFile.pub_key, privKey: keyFile.priv_key });
} else {
ws.setAuthCreds(null);
}
}, [keyFile]);
useEffect(() => {
if (keyFile === null) {
const t = setTimeout(() => {
if (!useStore.getState().keyFile) router.replace('/');
}, 300);
return () => clearTimeout(t);
}
}, [keyFile]);
// Tab bar layout math:
// icon (22) + gap (4) + label (~13) = ~39px of content
// We add a 12px visual margin above, and pad the bottom by the larger of
// the platform safe-area inset or 10px so the bar never sits flush on the
// home indicator.
const BAR_CONTENT_HEIGHT = 52;
const bottomPad = Math.max(insets.bottom, 10);
return (
<Tabs
screenOptions={{
headerShown: false,
tabBarActiveTintColor: C_ACCENT,
tabBarInactiveTintColor: C_MUTED,
tabBarLabelStyle: {
fontSize: 10,
fontWeight: '500',
marginTop: 2,
},
tabBarStyle: {
backgroundColor: C_BG,
borderTopColor: C_BORDER,
borderTopWidth: 1,
height: BAR_CONTENT_HEIGHT + bottomPad,
paddingTop: 8,
paddingBottom: bottomPad,
},
}}
>
<Tabs.Screen
name="chats"
options={{
tabBarLabel: 'Чаты',
tabBarIcon: ({ color, focused }) => (
<Ionicons
name={focused ? 'chatbubbles' : 'chatbubbles-outline'}
size={22}
color={color}
/>
),
tabBarBadge: requests.length > 0 ? requests.length : undefined,
tabBarBadgeStyle: { backgroundColor: C_ACCENT, fontSize: 10 },
}}
/>
<Tabs.Screen
name="wallet"
options={{
tabBarLabel: 'Кошелёк',
tabBarIcon: ({ color, focused }) => (
<Ionicons
name={focused ? 'wallet' : 'wallet-outline'}
size={22}
color={color}
/>
),
}}
/>
<Tabs.Screen
name="settings"
options={{
tabBarLabel: 'Настройки',
tabBarIcon: ({ color, focused }) => (
<Ionicons
name={focused ? 'settings' : 'settings-outline'}
size={22}
color={color}
/>
),
}}
/>
{/* Non-tab screens — hidden from tab bar */}
<Tabs.Screen name="requests" options={{ href: null }} />
<Tabs.Screen name="new-contact" options={{ href: null }} />
</Tabs>
);
}