# `gno.land/r/moul/x/wesh/v0` **An on-chain directory and device sigchain for Wesh protocol (weshnet / Berty) identities**, built on [`p/moul/x/wesh`](https://github.com/moul/gno-contracts/tree/main/p/moul/x/wesh/v0). ``` gnokey maketx call -pkgpath gno.land/r/moul/x/wesh/v0 -func Register \ -args alice -args -args -args "Alice" -args ``` `Render` then emits a link a Berty client can actually open: ``` https://berty.tech/id#contact/oZBLFpzghxrATkepWvDPNX9pHYqi6BWgP45x…/name=Alice ``` ## What it is for Wesh is peer-to-peer and end-to-end encrypted, and it has three gaps that only an authenticated, ordered, publicly auditable record can close: 1. **Resolution.** A Berty identity travels out of band and cannot be looked up. Here a name resolves to a contact, and the realm renders the real link. 2. **Rotation with a paper trail.** Resetting the rendezvous seed silently kills every link ever shared. Here every rotation is numbered, signed and kept, so a stale link is recognisably stale rather than merely dead. 3. **Device revocation.** Wesh cannot revoke a device at all. This realm hosts the missing log: hash-chained, account-signed, and verified on chain with `crypto/ed25519` before an entry is accepted. ## API | call | what it does | |---|---| | `Register(cur, name, accountPK, seed, displayName, sig)` | claim a name, publishing the rendezvous seed | | `RegisterCommitted(cur, name, accountPK, commitment, displayName, sig)` | claim a name, publishing only `H(seed ‖ salt)` | | `Rotate(cur, payload, sig)` | publish a new seed/commitment at `revision+1` | | `AppendDevice(cur, prev, op, devicePK, sig)` | append `add` or `revoke` to the sigchain | | `SetDisplayName(cur, name)` · `Release(cur)` | update the label · free the name | | `Resolve` · `Link` · `RendezvousPointAt` · `DeviceStatus` · `SigchainHead` · `NameOf` · `Count` | read-only, for gnoweb and other realms | ## Authentication Every state-changing call carries an **ed25519 signature made with the Wesh account key**, over a canonical statement naming the kind, the chain id, the caller's gno address, and a monotonic revision or sequence number. Each field is there to stop one attack: - without the **kind**, a binding signature could be replayed as a device one; - without the **chain id**, a testnet binding replays on mainnet; - without the **gno address**, anyone could publish someone else's account key next to a seed they control and harvest the contact requests; - without the **revision / sequence**, a superseded statement could roll a rotation back or fork the sigchain. All five are covered by a negative test apiece. ## What it never stores No group secret, no device chain key, no message key, no ciphertext: the library it is built on has no type that can hold one. And it does not pretend to *enforce* revocation inside weshnet: a revoked device's ratchets are already distributed. What revocation buys here is that it becomes public, ordered and attributable, which is strictly more than weshnet has today. ## Publishing is opt-in exposure A published seed lets anyone derive the account's rotating rendezvous point. That is the right trade for a support line, a shop or a public channel, and the wrong one for a private account, which is what `RegisterCommitted` is for. **Library:** [`p/moul/x/wesh`](https://github.com/moul/gno-contracts/tree/main/p/moul/x/wesh/v0). --- 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/r/moul/x/wesh/v0 dependency graph](https://raw.githubusercontent.com/moul/gno-contracts/main/_assets/gno.land/r/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).