PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/moul/x/wesh/v0

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v0
Namespace
moul / x / wesh
Files
12 (README)(gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/moul/x/wesh/v0
gno
0.9

Files (12)

  • README.mdmarkdown
  • gnomod.tomltoml
  • hmac.gnogno
  • link.gnogno
  • rendezvous.gnogno
  • statement.gnogno
  • wesh.gnogno
  • hmac_test.gnogno
  • link_test.gnogno
  • rendezvous_test.gnogno
  • statement_test.gnogno
  • wesh_test.gnogno
README.mdPreviewRaw
# `gno.land/p/moul/x/wesh/v0`

**The publishable half of the Wesh protocol** (weshnet, the network behind
[Berty](https://berty.tech)) as a pure gno library: `Contact`, `WebLink`,
`ParseWebLink`, `RendezvousPoint`, `SeedCommitment`, `BindStatement`,
`DeviceStatement`, `VerifyBind`, `VerifyDevice`, `HMACSHA256`.

```go
import "gno.land/p/moul/x/wesh/v0"

c := wesh.Contact{AccountPK: pk, Seed: seed, DisplayName: "Alice"}
link, _ := c.WebLink()   // https://berty.tech/id#contact/<base58>/name=Alice
pt, _ := c.RendezvousPointAt(now, wesh.DefaultRotationInterval)
```

## Why a chain at all

Wesh is off-grid, peer-to-peer and end-to-end encrypted. A public chain is the
opposite in nearly every dimension, so this is deliberately **not** "weshnet on
chain". It carries only the parts that need an authenticated, ordered, publicly
auditable record, the one thing a peer-to-peer network cannot give itself, and
which Wesh is missing in three specific places:

- **Identities do not resolve.** A Berty ID travels out of band as a QR code or
  a `https://berty.tech/id#` link, and there is no lookup.
- **Seed resets are silent.** `ContactRequestResetReference` gives the account a
  new rendezvous seed, which kills every link ever shared, with no channel to
  announce it.
- **Devices can never be revoked.** The protocol documentation says so outright:
  the account metadata log is append-only and no authority can void an entry.

## What is in here

| piece | what it is |
|---|---|
| `Contact` | weshnet's `ShareableContact`: account key + public rendezvous seed + display name, with weshnet's own `CheckFormat` length rules |
| `Blob`, `WebLink`, `ParseWebLink` | the Berty link codec, hand-rolled protobuf + base58 |
| `RendezvousPoint`, `RoundPeriod`, `NextPeriod` | weshnet's rotating DHT topic derivation |
| `SeedCommitment`, `OpenCommitment` | publish `H(seed ‖ salt)` instead of the seed |
| `BindStatement`, `DeviceStatement`, `VerifyBind`, `VerifyDevice` | the canonical texts an account signs, and their ed25519 verification |
| `HMACSHA256` | RFC 2104, because gno has `sha256.Sum256` but no `crypto/hmac` |

**The link codec is conformance-tested**, not guessed: `TestBlobEncodingMatches
BertyGoldenVector` reproduces the exact base58 payload from berty's own
`links_test.go`, byte for byte. The rendezvous derivation is pinned against
vectors computed with weshnet's `GenerateRendezvousPointForPeriod`, and the HMAC
against RFC 4231, including case 6, the longer-than-block-size key.

## What is deliberately absent

There is **no type here that can hold a secret**. Group secrets, device chain
keys, message keys and ciphertexts never touch a chain: publishing a group
secret hands the group to everyone, and publishing ciphertext is permanent,
expensive, and leaks the social graph through access patterns.

## The privacy trade-off

Publishing a rendezvous seed is equivalent to printing your Berty QR code on a
billboard: anyone can then derive today's rendezvous point and watch the DHT for
it. That is the right trade only for an identity that *wants* to be found.
`SeedCommitment` is the alternative: the chain attests the binding, the seed
travels out of band, and the rendezvous point stays private.

## Cost

`WebLink` is base58 over a ~70-byte payload, which is big-integer work:
`TestWebLink` reports ~19M gas for one encode, `TestWebLinkRoundTrip` ~61M per
encode-plus-decode. That is fine in a `Render` (a query) and worth avoiding
per-row in a list. Signature verification is a native op and costs far less.

**Live realm:** [`r/moul/x/wesh`](https://github.com/moul/gno-contracts/tree/main/r/moul/x/wesh/v0)
· render it at [`/r/moul/x/wesh/v0`](https://gno.land/r/moul/x/wesh/v0).

<!-- BEGIN GNOCONTRACTS FOOTER (generated by `make readmes`; do not edit below) -->

---

Part of **[moul/gno-contracts](https://github.com/moul/gno-contracts)** — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.

**Dependency graph:**

![gno.land/p/moul/x/wesh/v0 dependency graph](https://raw.githubusercontent.com/moul/gno-contracts/main/_assets/gno.land/p/moul/x/wesh/v0/deps.png)

> 🧪 **Highly experimental — potentially vibe-coded.** Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: [DISCLAIMER](https://github.com/moul/gno-contracts/blob/main/DISCLAIMER.md).

<!-- END GNOCONTRACTS FOOTER -->

Functions

not supported for pure packages by the node (vm/qfuncs)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.