Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
## Summary

<!-- Describe the change and why it is needed. -->

## Community mesh submissions

<!-- Delete this section when the pull request does not change the registry. -->

- [ ] I copied `data/communityMeshes/_template.json` and used a stable unique ID.
- [ ] The GeoJSON coverage uses `[longitude, latitude]` and has closed rings.
- [ ] The listed contacts and radio settings are maintained by this community.
- [ ] Any published PSKs or MQTT credentials are intentionally public.
- [ ] Licensed profiles have null PSKs and unlicensed profiles have valid PSKs.
- [ ] I ran `pnpm validate:community-meshes`, `pnpm test`, and `pnpm build`.
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,11 @@ jobs:
- name: Install Dependencies
run: pnpm install --ignore-scripts=false

- name: Validate Community Mesh Registry
run: pnpm validate:community-meshes

- name: Run Tests
run: pnpm test

- name: Build Package
run: pnpm build
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@

API backend used for meshtastic.org and associated tools.

## Community Mesh Registry

Clients can download the community mesh registry from `GET /v1/community-meshes`,
inspect one record at `GET /v1/community-meshes/:id`, and fetch its JSON Schema
from `GET /v1/community-meshes/schema`. Discovery is privacy-preserving: clients
download the same cacheable registry and compare its GeoJSON coverage locally;
they do not send a location to this API.

To list or update a community, follow the
[community mesh contribution guide](docs/community-mesh-registry.md).

## Stats

![Alt](https://repobeats.axiom.co/api/embed/42de1569e61bc8171266ba5e0cc1dab2e0a3986b.svg "Repobeats analytics image")
Expand Down
34 changes: 34 additions & 0 deletions data/communityMeshes/_template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"schemaVersion": 1,
"id": "replace-with-community-id",
"name": "Replace with community name",
"description": "Replace with a clear public description.",
"coverage": {
"type": "Polygon",
"coordinates": [[[0, 0], [0, 1], [1, 1], [0, 0]]]
},
"links": [{ "kind": "website", "url": "https://example.org" }],
"meshProfiles": [
{
"id": "public",
"name": "Public",
"description": "Replace with profile description.",
"radio": {
"region": "US",
"modem": { "kind": "preset", "preset": "LONG_FAST" },
"frequencySlot": 0,
"frequencyOffsetHz": 0,
"maxHops": 3,
"txPowerDbm": 0,
"ignoreMqtt": false,
"sx126xRxBoostedGain": false
},
"primaryChannel": {
"name": "Public",
"pskBase64": "AQ==",
"uplinkEnabled": false,
"downlinkEnabled": false
}
}
]
}
67 changes: 67 additions & 0 deletions docs/community-mesh-registry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Community Mesh Registry

The registry gives Meshtastic clients a reviewed, machine-readable list of
community radio configurations. Each community is one JSON file in
`data/communityMeshes/`, approved through the normal GitHub pull request review
process and published with this API.

## Privacy model

The API deliberately has no latitude/longitude lookup endpoint. Every client
downloads the same cacheable `GET /v1/community-meshes` response, uses each
record's GeoJSON bounding box as a fast first pass, and then performs the exact
point-in-polygon check on the device. A user's rough or precise location never
needs to leave the client.

## Submit a community

1. Copy `data/communityMeshes/_template.json` to a lowercase, hyphenated name
such as `data/communityMeshes/example-city.json`.
2. Give the record a stable, unique `id`, public name, description, and at least
one website or social link.
3. Draw the covered area as a GeoJSON `Polygon` or `MultiPolygon`. Coordinates
use `[longitude, latitude]`, and every polygon ring must end with the same
coordinate with which it starts.
4. Define one to three distinct `meshProfiles`. A profile is a separate radio
mesh, normally with its own primary channel and frequency settings. Put the
main choice first. Add secondary or tertiary profiles only when they exist.
5. Run `pnpm validate:community-meshes`, `pnpm test`, and `pnpm build`.
6. Open a pull request. A Meshtastic maintainer reviews the coverage, public
contact information, radio settings, and security implications before merge.

## Radio and channel settings

Use a standard modem preset whenever possible. For a custom modem, define all
required LoRa parameters in the schema, including bandwidth, spreading factor,
and coding rate. Radio fields can also describe frequency slot and offset, hop
limit, transmit power, MQTT behavior, and supported hardware-specific options.
An explicit frequency override is restricted to licensed profiles.

Every unlicensed channel must have a valid Base64 PSK. A PSK in this public
repository is a shared channel key, not a secret and not an access-control
mechanism. Channel names may be no more than 12 UTF-8 bytes. The primary channel
is required; optional channels can be offered by clients as opt-in choices.

For a licensed profile, include the `licensed` configuration and set every
channel's `pskBase64` to `null`. Clients are responsible for asking for the
operator's callsign and applying Meshtastic's licensed-mode setting before
switching to that profile. The registry does not store user callsigns.

Profiles may set a minimum firmware version and maximum position or telemetry
intervals. The registry does not define position precision.

## MQTT

Omit `mqtt` when the community has no custom broker. When present, it can define
the public broker address or URL, port, TLS, username, password, root topic,
proxy-to-client behavior, JSON output, MQTT encryption, and map reporting
interval. Channel `uplinkEnabled` and `downlinkEnabled` flags control which
channels use it.

All registry data is public. Never submit a private broker credential. Use a
dedicated, least-privilege account intended for public distribution, and rotate
it by updating the community record if necessary.

The authoritative field definitions and limits are in
`schemas/community-mesh.schema.json`; the served copy is available at
`GET /v1/community-meshes/schema`.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
"scripts": {
"dev": "tsx src/index.ts",
"start": "prisma migrate deploy && node dist/index.js",
"build": "prisma generate && tsc"
"build": "prisma generate && tsc",
"test": "tsx --test tests/*.test.ts",
"validate:community-meshes": "tsx src/scripts/validateCommunityMeshes.ts"
},
"dependencies": {
"@buf/meshtastic_api.bufbuild_es": "1.7.2-20240110092216-3a147af14302.1",
Expand All @@ -25,6 +27,7 @@
"@tinyhttp/favicon": "^3.0.0",
"@tinyhttp/logger": "^2.0.0",
"add": "^2.0.6",
"ajv": "^8.17.1",
"mqtt": "^5.3.5",
"octokit": "^3.1.2",
"pnpm": "^8.15.3",
Expand Down
34 changes: 34 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading