Skip to content

Commit e9dbb36

Browse files
committed
TLTV CLI v1.0.0
Command-line tool for the TLTV Federation Protocol. Generate channel identities, sign and verify documents, mine vanity IDs, resolve URIs, probe nodes, crawl the gossip network, and check streams. Single static binary, zero dependencies. Validated against all 7 protocol test vector suites with 55 unit tests and 7 integration tests.
0 parents  commit e9dbb36

18 files changed

Lines changed: 5668 additions & 0 deletions

.github/workflows/ci.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main, dev]
6+
pull_request:
7+
branches: [main, dev]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- uses: actions/setup-go@v5
16+
with:
17+
go-version: '1.22'
18+
19+
- name: Vet
20+
run: go vet ./...
21+
22+
- name: Test
23+
run: go test -v -count=1 ./...
24+
25+
- name: Build (static)
26+
run: CGO_ENABLED=0 go build -v -ldflags "-s -w" -o tltv .
27+
28+
- name: Verify static linkage
29+
run: |
30+
output=$(ldd ./tltv 2>&1 || true)
31+
case "$output" in
32+
*"not a dynamic executable"*) echo "OK: static binary" ;;
33+
*) echo "ERROR: binary is dynamically linked"; echo "$output"; exit 1 ;;
34+
esac
35+
36+
race:
37+
runs-on: ubuntu-latest
38+
steps:
39+
- uses: actions/checkout@v4
40+
41+
- uses: actions/setup-go@v5
42+
with:
43+
go-version: '1.22'
44+
45+
- name: Test (race detector)
46+
run: go test -race -count=1 ./...

.github/workflows/release.yml

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
release:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- uses: actions/setup-go@v5
18+
with:
19+
go-version: '1.22'
20+
21+
- name: Vet
22+
run: go vet ./...
23+
24+
- name: Test
25+
run: go test -v -count=1 ./...
26+
27+
- name: Build archives
28+
run: |
29+
VERSION=${GITHUB_REF_NAME}
30+
LDFLAGS="-s -w -X main.version=${VERSION}"
31+
mkdir -p dist
32+
33+
for pair in linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64 windows/arm64 freebsd/amd64; do
34+
GOOS=${pair%/*}
35+
GOARCH=${pair#*/}
36+
BIN=tltv
37+
if [ "$GOOS" = "windows" ]; then BIN=tltv.exe; fi
38+
39+
echo "Building ${GOOS}/${GOARCH}..."
40+
CGO_ENABLED=0 GOOS=$GOOS GOARCH=$GOARCH go build -ldflags "$LDFLAGS" -o "dist/${BIN}" .
41+
42+
ARCHIVE="tltv-cli_${VERSION}_${GOOS}-${GOARCH}"
43+
tar -czf "dist/${ARCHIVE}.tar.gz" -C dist "$BIN"
44+
rm "dist/${BIN}"
45+
done
46+
47+
- name: Verify Linux amd64 is static
48+
run: |
49+
CGO_ENABLED=0 go build -ldflags "-s -w" -o tltv-check .
50+
output=$(ldd ./tltv-check 2>&1 || true)
51+
case "$output" in
52+
*"not a dynamic executable"*) echo "OK: static binary" ;;
53+
*) echo "ERROR: binary is dynamically linked"; echo "$output"; exit 1 ;;
54+
esac
55+
rm ./tltv-check
56+
57+
- name: Create checksums
58+
working-directory: dist
59+
run: sha256sum * > checksums.txt
60+
61+
- name: Create release and upload assets
62+
env:
63+
TOKEN: ${{ secrets.GITHUB_TOKEN }}
64+
TAG: ${{ github.ref_name }}
65+
REPO: ${{ github.repository }}
66+
SERVER: ${{ github.server_url }}
67+
run: |
68+
# Detect API base (GitHub vs Forgejo/Gitea)
69+
if echo "$SERVER" | grep -q "github\.com"; then
70+
API_BASE="https://api.github.com/repos/${REPO}"
71+
UPLOAD_MODE=github
72+
else
73+
API_BASE="${SERVER}/api/v1/repos/${REPO}"
74+
UPLOAD_MODE=forgejo
75+
fi
76+
77+
# Detect pre-release from tag name
78+
PRERELEASE=false
79+
if echo "$TAG" | grep -qE '(rc|alpha|beta)'; then
80+
PRERELEASE=true
81+
fi
82+
83+
# Create release
84+
RESPONSE=$(curl -sS -X POST \
85+
-H "Authorization: token ${TOKEN}" \
86+
-H "Content-Type: application/json" \
87+
-d "{\"tag_name\":\"${TAG}\",\"name\":\"tltv-cli ${TAG}\",\"body\":\"Release ${TAG}\",\"draft\":false,\"prerelease\":${PRERELEASE}}" \
88+
"${API_BASE}/releases")
89+
90+
# Extract release ID (works for both APIs -- "id" is always the first integer id field)
91+
RELEASE_ID=$(echo "$RESPONSE" | grep -o '"id" *: *[0-9]*' | head -1 | grep -o '[0-9]*')
92+
93+
if [ -z "$RELEASE_ID" ]; then
94+
echo "ERROR: Failed to create release"
95+
echo "$RESPONSE"
96+
exit 1
97+
fi
98+
99+
echo "Created release ${TAG} (id: ${RELEASE_ID}, prerelease: ${PRERELEASE})"
100+
101+
# Upload assets
102+
for file in dist/*; do
103+
filename=$(basename "$file")
104+
echo "Uploading ${filename}..."
105+
106+
if [ "$UPLOAD_MODE" = "github" ]; then
107+
# GitHub: raw binary body to uploads.github.com
108+
curl -sS -X POST \
109+
-H "Authorization: token ${TOKEN}" \
110+
-H "Content-Type: application/octet-stream" \
111+
--data-binary "@${file}" \
112+
"https://uploads.github.com/repos/${REPO}/releases/${RELEASE_ID}/assets?name=${filename}" > /dev/null
113+
else
114+
# Forgejo/Gitea: multipart form upload
115+
curl -sS -X POST \
116+
-H "Authorization: token ${TOKEN}" \
117+
-F "attachment=@${file}" \
118+
"${API_BASE}/releases/${RELEASE_ID}/assets?name=${filename}" > /dev/null
119+
fi
120+
done
121+
122+
echo "Uploaded $(ls dist/* | wc -l) assets"

.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Binary
2+
tltv
3+
tltv.exe
4+
dist/
5+
6+
# Key files (never commit secrets)
7+
*.key
8+
9+
# Test artifacts
10+
*.test

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 TLTV
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Makefile

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
BINARY := tltv
2+
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
3+
LDFLAGS := -ldflags "-s -w -X main.version=$(VERSION)"
4+
5+
.PHONY: build install test clean release
6+
7+
build:
8+
CGO_ENABLED=0 go build $(LDFLAGS) -o $(BINARY) .
9+
10+
install:
11+
CGO_ENABLED=0 go install $(LDFLAGS) .
12+
13+
test:
14+
go test -v ./...
15+
16+
clean:
17+
rm -f $(BINARY)
18+
rm -rf dist/
19+
20+
# Cross-compile for all major platforms (static binaries, no cgo).
21+
# Produces tar.gz archives plus checksums.
22+
release: clean
23+
@mkdir -p dist
24+
@for pair in linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64 windows/arm64 freebsd/amd64; do \
25+
GOOS=$${pair%/*}; \
26+
GOARCH=$${pair#*/}; \
27+
BIN=$(BINARY); \
28+
if [ "$$GOOS" = "windows" ]; then BIN=$(BINARY).exe; fi; \
29+
echo "Building $$GOOS/$$GOARCH..."; \
30+
CGO_ENABLED=0 GOOS=$$GOOS GOARCH=$$GOARCH go build $(LDFLAGS) -o dist/$$BIN .; \
31+
ARCHIVE=$(BINARY)-cli_$(VERSION)_$$GOOS-$$GOARCH; \
32+
tar -czf dist/$$ARCHIVE.tar.gz -C dist $$BIN; \
33+
rm dist/$$BIN; \
34+
done
35+
@cd dist && sha256sum * > checksums.txt
36+
@echo "Release archives in dist/"
37+
@ls -lh dist/

0 commit comments

Comments
 (0)