@xtr-dev/rondevu-server 0.5.1 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/claude-code-review.yml +57 -0
- package/.github/workflows/claude.yml +50 -0
- package/.idea/modules.xml +8 -0
- package/.idea/rondevu-server.iml +8 -0
- package/.idea/workspace.xml +17 -0
- package/README.md +80 -199
- package/build.js +4 -1
- package/dist/index.js +2755 -1448
- package/dist/index.js.map +4 -4
- package/migrations/fresh_schema.sql +36 -41
- package/package.json +10 -4
- package/src/app.ts +38 -18
- package/src/config.ts +155 -9
- package/src/crypto.ts +361 -263
- package/src/index.ts +20 -25
- package/src/rpc.ts +658 -405
- package/src/storage/d1.ts +312 -263
- package/src/storage/factory.ts +69 -0
- package/src/storage/hash-id.ts +13 -9
- package/src/storage/memory.ts +559 -0
- package/src/storage/mysql.ts +588 -0
- package/src/storage/postgres.ts +595 -0
- package/src/storage/schemas/mysql.sql +59 -0
- package/src/storage/schemas/postgres.sql +64 -0
- package/src/storage/sqlite.ts +303 -269
- package/src/storage/types.ts +113 -113
- package/src/worker.ts +15 -34
- package/tests/integration/api.test.ts +395 -0
- package/tests/integration/setup.ts +170 -0
- package/wrangler.toml +25 -26
- package/ADVANCED.md +0 -502
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
name: Claude Code Review
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types: [opened, synchronize]
|
|
6
|
+
# Optional: Only run on specific file changes
|
|
7
|
+
# paths:
|
|
8
|
+
# - "src/**/*.ts"
|
|
9
|
+
# - "src/**/*.tsx"
|
|
10
|
+
# - "src/**/*.js"
|
|
11
|
+
# - "src/**/*.jsx"
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
claude-review:
|
|
15
|
+
# Optional: Filter by PR author
|
|
16
|
+
# if: |
|
|
17
|
+
# github.event.pull_request.user.login == 'external-contributor' ||
|
|
18
|
+
# github.event.pull_request.user.login == 'new-developer' ||
|
|
19
|
+
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
|
|
20
|
+
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
permissions:
|
|
23
|
+
contents: read
|
|
24
|
+
pull-requests: read
|
|
25
|
+
issues: read
|
|
26
|
+
id-token: write
|
|
27
|
+
|
|
28
|
+
steps:
|
|
29
|
+
- name: Checkout repository
|
|
30
|
+
uses: actions/checkout@v4
|
|
31
|
+
with:
|
|
32
|
+
fetch-depth: 1
|
|
33
|
+
|
|
34
|
+
- name: Run Claude Code Review
|
|
35
|
+
id: claude-review
|
|
36
|
+
uses: anthropics/claude-code-action@v1
|
|
37
|
+
with:
|
|
38
|
+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
39
|
+
prompt: |
|
|
40
|
+
REPO: ${{ github.repository }}
|
|
41
|
+
PR NUMBER: ${{ github.event.pull_request.number }}
|
|
42
|
+
|
|
43
|
+
Please review this pull request and provide feedback on:
|
|
44
|
+
- Code quality and best practices
|
|
45
|
+
- Potential bugs or issues
|
|
46
|
+
- Performance considerations
|
|
47
|
+
- Security concerns
|
|
48
|
+
- Test coverage
|
|
49
|
+
|
|
50
|
+
Use the repository's CLAUDE.md for guidance on style and conventions. Be constructive and helpful in your feedback.
|
|
51
|
+
|
|
52
|
+
Use `gh pr comment` with your Bash tool to leave your review as a comment on the PR.
|
|
53
|
+
|
|
54
|
+
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
|
|
55
|
+
# or https://code.claude.com/docs/en/cli-reference for available options
|
|
56
|
+
claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"'
|
|
57
|
+
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: Claude Code
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
issue_comment:
|
|
5
|
+
types: [created]
|
|
6
|
+
pull_request_review_comment:
|
|
7
|
+
types: [created]
|
|
8
|
+
issues:
|
|
9
|
+
types: [opened, assigned]
|
|
10
|
+
pull_request_review:
|
|
11
|
+
types: [submitted]
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
claude:
|
|
15
|
+
if: |
|
|
16
|
+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
|
|
17
|
+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
|
|
18
|
+
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
|
|
19
|
+
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
permissions:
|
|
22
|
+
contents: read
|
|
23
|
+
pull-requests: read
|
|
24
|
+
issues: read
|
|
25
|
+
id-token: write
|
|
26
|
+
actions: read # Required for Claude to read CI results on PRs
|
|
27
|
+
steps:
|
|
28
|
+
- name: Checkout repository
|
|
29
|
+
uses: actions/checkout@v4
|
|
30
|
+
with:
|
|
31
|
+
fetch-depth: 1
|
|
32
|
+
|
|
33
|
+
- name: Run Claude Code
|
|
34
|
+
id: claude
|
|
35
|
+
uses: anthropics/claude-code-action@v1
|
|
36
|
+
with:
|
|
37
|
+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
38
|
+
|
|
39
|
+
# This is an optional setting that allows Claude to read CI results on PRs
|
|
40
|
+
additional_permissions: |
|
|
41
|
+
actions: read
|
|
42
|
+
|
|
43
|
+
# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
|
|
44
|
+
# prompt: 'Update the pull request description to include a summary of changes.'
|
|
45
|
+
|
|
46
|
+
# Optional: Add claude_args to customize behavior and configuration
|
|
47
|
+
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
|
|
48
|
+
# or https://code.claude.com/docs/en/cli-reference for available options
|
|
49
|
+
# claude_args: '--allowed-tools Bash(gh pr:*)'
|
|
50
|
+
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="ProjectModuleManager">
|
|
4
|
+
<modules>
|
|
5
|
+
<module fileurl="file://$PROJECT_DIR$/.idea/rondevu-server.iml" filepath="$PROJECT_DIR$/.idea/rondevu-server.iml" />
|
|
6
|
+
</modules>
|
|
7
|
+
</component>
|
|
8
|
+
</project>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<module type="WEB_MODULE" version="4">
|
|
3
|
+
<component name="NewModuleRootManager">
|
|
4
|
+
<content url="file://$MODULE_DIR$" />
|
|
5
|
+
<orderEntry type="inheritedJdk" />
|
|
6
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
|
7
|
+
</component>
|
|
8
|
+
</module>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="PropertiesComponent">{
|
|
4
|
+
"keyToString": {
|
|
5
|
+
"settings.editor.selected.configurable": "org.jetbrains.plugins.github.ui.GithubSettingsConfigurable"
|
|
6
|
+
}
|
|
7
|
+
}</component>
|
|
8
|
+
<component name="TaskManager">
|
|
9
|
+
<task active="true" id="Default" summary="Default task">
|
|
10
|
+
<created>1767281720486</created>
|
|
11
|
+
<option name="number" value="Default" />
|
|
12
|
+
<option name="presentableId" value="Default" />
|
|
13
|
+
<updated>1767281720486</updated>
|
|
14
|
+
</task>
|
|
15
|
+
<servers />
|
|
16
|
+
</component>
|
|
17
|
+
</project>
|
package/README.md
CHANGED
|
@@ -2,55 +2,35 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@xtr-dev/rondevu-server)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**WebRTC signaling server with tags-based discovery**
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
HTTP signaling server with credential-based authentication, tag-based offer discovery, and JSON-RPC interface. Multiple storage backends supported.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
- [@xtr-dev/rondevu-client](https://github.com/xtr-dev/rondevu-client) - TypeScript client library ([npm](https://www.npmjs.com/package/@xtr-dev/rondevu-client))
|
|
11
|
-
- [@xtr-dev/rondevu-server](https://github.com/xtr-dev/rondevu-server) - HTTP signaling server ([npm](https://www.npmjs.com/package/@xtr-dev/rondevu-server), [live](https://api.ronde.vu))
|
|
12
|
-
- [@xtr-dev/rondevu-demo](https://github.com/xtr-dev/rondevu-demo) - Interactive demo ([live](https://ronde.vu))
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
## Features
|
|
17
|
-
|
|
18
|
-
- **RPC Interface**: Single endpoint for all operations with batching support
|
|
19
|
-
- **Username Claiming**: Cryptographic username ownership with Ed25519 signatures (365-day validity, auto-renewed on use)
|
|
20
|
-
- **Service Publishing**: Service:version@username naming (e.g., `chat:1.0.0@alice`)
|
|
21
|
-
- **Service Discovery**: Random and paginated discovery for finding services without knowing usernames
|
|
22
|
-
- **Semantic Versioning**: Compatible version matching (chat:1.0.0 matches any 1.x.x)
|
|
23
|
-
- **Signature-Based Authentication**: All authenticated requests use Ed25519 signatures
|
|
24
|
-
- **Complete WebRTC Signaling**: Offer/answer exchange and ICE candidate relay
|
|
25
|
-
- **Batch Operations**: Execute multiple operations in a single HTTP request
|
|
26
|
-
- **Dual Storage**: SQLite (Node.js/Docker) and Cloudflare D1 (Workers) backends
|
|
27
|
-
|
|
28
|
-
## Architecture
|
|
9
|
+
## Quick Start
|
|
29
10
|
|
|
11
|
+
**In-memory (default, zero dependencies):**
|
|
12
|
+
```bash
|
|
13
|
+
npm install && npm start
|
|
30
14
|
```
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
alice publishes chat:1.0.0@alice with offers
|
|
36
|
-
↓
|
|
37
|
-
bob queries chat:1.0.0@alice (direct) or chat:1.0.0 (discovery) → gets offer SDP
|
|
38
|
-
↓
|
|
39
|
-
bob posts answer SDP → WebRTC connection established
|
|
40
|
-
↓
|
|
41
|
-
ICE candidates exchanged via server relay
|
|
15
|
+
|
|
16
|
+
**SQLite (persistent):**
|
|
17
|
+
```bash
|
|
18
|
+
STORAGE_TYPE=sqlite STORAGE_PATH=./rondevu.db npm start
|
|
42
19
|
```
|
|
43
20
|
|
|
44
|
-
|
|
21
|
+
**MySQL:**
|
|
22
|
+
```bash
|
|
23
|
+
STORAGE_TYPE=mysql DATABASE_URL=mysql://user:pass@localhost:3306/rondevu npm start
|
|
24
|
+
```
|
|
45
25
|
|
|
46
|
-
**
|
|
26
|
+
**PostgreSQL:**
|
|
47
27
|
```bash
|
|
48
|
-
|
|
28
|
+
STORAGE_TYPE=postgres DATABASE_URL=postgres://user:pass@localhost:5432/rondevu npm start
|
|
49
29
|
```
|
|
50
30
|
|
|
51
31
|
**Docker:**
|
|
52
32
|
```bash
|
|
53
|
-
docker build -t rondevu . && docker run -p 3000:3000
|
|
33
|
+
docker build -t rondevu . && docker run -p 3000:3000 rondevu
|
|
54
34
|
```
|
|
55
35
|
|
|
56
36
|
**Cloudflare Workers:**
|
|
@@ -58,201 +38,102 @@ docker build -t rondevu . && docker run -p 3000:3000 -e STORAGE_PATH=:memory: ro
|
|
|
58
38
|
npx wrangler deploy
|
|
59
39
|
```
|
|
60
40
|
|
|
41
|
+
## Storage Backends
|
|
42
|
+
|
|
43
|
+
| Backend | Use Case | Persistence |
|
|
44
|
+
|---------|----------|-------------|
|
|
45
|
+
| `memory` | Zero-config, ephemeral workloads | No |
|
|
46
|
+
| `sqlite` | Single-instance VPS | Yes |
|
|
47
|
+
| `mysql` | Production, multi-instance | Yes |
|
|
48
|
+
| `postgres` | Production, multi-instance | Yes |
|
|
49
|
+
|
|
50
|
+
For MySQL/PostgreSQL, install optional dependencies:
|
|
51
|
+
```bash
|
|
52
|
+
npm install mysql2 # for MySQL
|
|
53
|
+
npm install pg # for PostgreSQL
|
|
54
|
+
```
|
|
55
|
+
|
|
61
56
|
## RPC Interface
|
|
62
57
|
|
|
63
|
-
All API calls
|
|
58
|
+
All API calls go to `POST /rpc` with JSON-RPC format. Requests must be arrays.
|
|
64
59
|
|
|
65
|
-
###
|
|
60
|
+
### Generate Credentials
|
|
66
61
|
|
|
67
|
-
**Single method call:**
|
|
68
62
|
```json
|
|
69
|
-
{
|
|
70
|
-
"method": "getUser",
|
|
71
|
-
"message": "getUser:alice:1733404800000",
|
|
72
|
-
"signature": "base64-encoded-signature",
|
|
73
|
-
"params": {
|
|
74
|
-
"username": "alice"
|
|
75
|
-
}
|
|
76
|
-
}
|
|
63
|
+
[{ "method": "generateCredentials", "params": { "name": "alice" } }]
|
|
77
64
|
```
|
|
78
65
|
|
|
79
|
-
|
|
66
|
+
Response:
|
|
80
67
|
```json
|
|
81
|
-
[
|
|
82
|
-
{
|
|
83
|
-
"method": "getUser",
|
|
84
|
-
"message": "getUser:alice:1733404800000",
|
|
85
|
-
"signature": "base64-encoded-signature",
|
|
86
|
-
"params": { "username": "alice" }
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
"method": "claimUsername",
|
|
90
|
-
"message": "claim:bob:1733404800000",
|
|
91
|
-
"signature": "base64-encoded-signature",
|
|
92
|
-
"params": {
|
|
93
|
-
"username": "bob",
|
|
94
|
-
"publicKey": "base64-encoded-public-key"
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
]
|
|
68
|
+
[{ "success": true, "result": { "name": "alice", "secret": "5a7f3e..." } }]
|
|
98
69
|
```
|
|
99
70
|
|
|
100
|
-
###
|
|
71
|
+
### Publish Offer (authenticated)
|
|
101
72
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
{
|
|
105
|
-
"success": true,
|
|
106
|
-
"result": { /* method-specific data */ }
|
|
107
|
-
}
|
|
73
|
+
```
|
|
74
|
+
Headers: X-Name, X-Timestamp, X-Nonce, X-Signature
|
|
108
75
|
```
|
|
109
76
|
|
|
110
|
-
**Error response:**
|
|
111
77
|
```json
|
|
112
|
-
{
|
|
113
|
-
"
|
|
114
|
-
"
|
|
115
|
-
}
|
|
78
|
+
[{
|
|
79
|
+
"method": "publishOffer",
|
|
80
|
+
"params": { "tags": ["chat"], "offers": [{ "sdp": "..." }], "ttl": 300000 }
|
|
81
|
+
}]
|
|
116
82
|
```
|
|
117
83
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
## Core Methods
|
|
121
|
-
|
|
122
|
-
### Username Management
|
|
123
|
-
|
|
124
|
-
```typescript
|
|
125
|
-
// Check username availability
|
|
126
|
-
POST /rpc
|
|
127
|
-
{
|
|
128
|
-
"method": "getUser",
|
|
129
|
-
"params": { "username": "alice" }
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Claim username (requires signature)
|
|
133
|
-
POST /rpc
|
|
134
|
-
{
|
|
135
|
-
"method": "claimUsername",
|
|
136
|
-
"message": "claim:alice:1733404800000",
|
|
137
|
-
"signature": "base64-signature",
|
|
138
|
-
"params": {
|
|
139
|
-
"username": "alice",
|
|
140
|
-
"publicKey": "base64-public-key"
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
```
|
|
84
|
+
### Discover Offers
|
|
144
85
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
```typescript
|
|
148
|
-
// Publish service (requires signature)
|
|
149
|
-
POST /rpc
|
|
150
|
-
{
|
|
151
|
-
"method": "publishService",
|
|
152
|
-
"message": "publishService:alice:chat:1.0.0@alice:1733404800000",
|
|
153
|
-
"signature": "base64-signature",
|
|
154
|
-
"params": {
|
|
155
|
-
"serviceFqn": "chat:1.0.0@alice",
|
|
156
|
-
"offers": [{ "sdp": "webrtc-offer-sdp" }],
|
|
157
|
-
"ttl": 300000
|
|
158
|
-
}
|
|
159
|
-
}
|
|
86
|
+
```json
|
|
87
|
+
[{ "method": "discover", "params": { "tags": ["chat"], "limit": 10 } }]
|
|
160
88
|
```
|
|
161
89
|
|
|
162
|
-
###
|
|
163
|
-
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
POST /rpc
|
|
167
|
-
{
|
|
168
|
-
"method": "getService",
|
|
169
|
-
"params": { "serviceFqn": "chat:1.0.0@alice" }
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// Random discovery
|
|
173
|
-
POST /rpc
|
|
174
|
-
{
|
|
175
|
-
"method": "getService",
|
|
176
|
-
"params": { "serviceFqn": "chat:1.0.0" }
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Paginated discovery
|
|
180
|
-
POST /rpc
|
|
181
|
-
{
|
|
182
|
-
"method": "getService",
|
|
183
|
-
"params": {
|
|
184
|
-
"serviceFqn": "chat:1.0.0",
|
|
185
|
-
"limit": 10,
|
|
186
|
-
"offset": 0
|
|
187
|
-
}
|
|
188
|
-
}
|
|
90
|
+
### Answer Offer (authenticated)
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
[{ "method": "answerOffer", "params": { "offerId": "abc...", "sdp": "..." } }]
|
|
189
94
|
```
|
|
190
95
|
|
|
191
|
-
###
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Add ICE candidates (requires signature)
|
|
208
|
-
POST /rpc
|
|
209
|
-
{
|
|
210
|
-
"method": "addIceCandidates",
|
|
211
|
-
"params": {
|
|
212
|
-
"serviceFqn": "chat:1.0.0@alice",
|
|
213
|
-
"offerId": "offer-id",
|
|
214
|
-
"candidates": [{ /* RTCIceCandidateInit */ }]
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// Poll for answers and ICE candidates (requires signature)
|
|
219
|
-
POST /rpc
|
|
220
|
-
{
|
|
221
|
-
"method": "poll",
|
|
222
|
-
"params": { "since": 1733404800000 }
|
|
223
|
-
}
|
|
96
|
+
### Other Methods (authenticated)
|
|
97
|
+
|
|
98
|
+
- `addIceCandidates` - Add ICE candidates
|
|
99
|
+
- `getIceCandidates` - Get ICE candidates
|
|
100
|
+
- `poll` - Poll for answers
|
|
101
|
+
- `deleteOffer` - Delete an offer
|
|
102
|
+
|
|
103
|
+
## Authentication
|
|
104
|
+
|
|
105
|
+
Authenticated methods require HMAC-SHA256 signatures:
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
Message: timestamp:nonce:method:JSON.stringify(params)
|
|
109
|
+
Headers: X-Name, X-Timestamp, X-Nonce, X-Signature (base64 HMAC)
|
|
224
110
|
```
|
|
225
111
|
|
|
226
112
|
## Configuration
|
|
227
113
|
|
|
228
|
-
Quick reference for common environment variables:
|
|
229
|
-
|
|
230
114
|
| Variable | Default | Description |
|
|
231
115
|
|----------|---------|-------------|
|
|
232
|
-
| `PORT` | `3000` | Server port
|
|
233
|
-
| `
|
|
234
|
-
| `STORAGE_PATH` |
|
|
116
|
+
| `PORT` | `3000` | Server port |
|
|
117
|
+
| `STORAGE_TYPE` | `memory` | Storage backend: `memory`, `sqlite`, `mysql`, `postgres` |
|
|
118
|
+
| `STORAGE_PATH` | `:memory:` | SQLite path (only for `sqlite` backend) |
|
|
119
|
+
| `DATABASE_URL` | - | Connection string (for `mysql`/`postgres`) |
|
|
120
|
+
| `DB_POOL_SIZE` | `10` | Connection pool size (for `mysql`/`postgres`) |
|
|
121
|
+
| `CORS_ORIGINS` | `*` | Allowed origins |
|
|
122
|
+
| `MASTER_ENCRYPTION_KEY` | - | 64-char hex for secret encryption |
|
|
123
|
+
| `OFFER_DEFAULT_TTL` | `60000` | Default offer TTL (ms) |
|
|
124
|
+
| `OFFER_MAX_TTL` | `86400000` | Max offer TTL (24h) |
|
|
235
125
|
|
|
236
|
-
|
|
126
|
+
Generate encryption key: `openssl rand -hex 32`
|
|
237
127
|
|
|
238
|
-
##
|
|
128
|
+
## Tag Validation
|
|
239
129
|
|
|
240
|
-
|
|
241
|
-
- Complete RPC method reference with examples
|
|
242
|
-
- Full configuration options
|
|
243
|
-
- Database schema documentation
|
|
244
|
-
- Security implementation details
|
|
245
|
-
- Migration guides
|
|
130
|
+
Tags: 1-64 chars, lowercase alphanumeric with dots/dashes.
|
|
246
131
|
|
|
247
|
-
|
|
132
|
+
Valid: `chat`, `video-call`, `com.example.service`
|
|
248
133
|
|
|
249
|
-
|
|
250
|
-
- **Message Format**: `{method}:{username}:{context}:{timestamp}`
|
|
251
|
-
- **Signature**: Base64-encoded Ed25519 signature of the message
|
|
252
|
-
- **Replay Protection**: Timestamps must be within 5 minutes
|
|
253
|
-
- **Username Ownership**: Verified via public key signature
|
|
134
|
+
## Links
|
|
254
135
|
|
|
255
|
-
|
|
136
|
+
- [Client Library](https://github.com/xtr-dev/rondevu-client) | [Demo](https://ronde.vu) | [API](https://api.ronde.vu)
|
|
256
137
|
|
|
257
138
|
## License
|
|
258
139
|
|