Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

wesh/v0 package

Overview

Package wesh is an on-chain directory and device sigchain for Wesh protocol (weshnet / Berty) identities.

It exists to give weshnet the three things a peer-to-peer network cannot give itself, and which a chain is uniquely good at:

  1. Resolution. A Berty identity travels out of band as a QR code or a https://berty.tech/id# link, and there is no way to look one up. Here a name resolves to a contact, and Render emits the real, scannable link.
  2. Rotation with a paper trail. Resetting the public rendezvous seed silently kills every link ever shared; there is no revocation channel. Here every rotation is a numbered, timestamped, signed entry, and the superseded seeds stay visible, so a stale link resolves to a redirect instead of to nothing.
  3. Device revocation. The Wesh protocol documentation states plainly that a device, once linked to an account, can never be revoked: the account metadata log is append-only and no authority can void an entry. This realm hosts the log that was missing: a hash-chained, account-signed roster whose every entry the chain verifies with ed25519 before accepting it.

What this realm does not do, and will not

It never stores a secret. Group secrets, device chain keys, message keys and ciphertexts stay off chain, permanently. The library this realm is built on, p/moul/x/wesh(/p/moul/x/wesh/v0), has no type that can hold one.

It also does not pretend to enforce revocation inside weshnet. A revoked device's ratchets are already distributed and forward secrecy is a local property; no chain can reach into a group and forget them. What revocation buys here is that it becomes public, ordered, and attributable to the account key, which is strictly more than weshnet has today.

Publishing is a deliberate act

A published rendezvous seed lets anyone derive the account's rotating rendezvous point and watch the DHT for it. That is the same exposure as printing your Berty QR code on a billboard, and it is the right trade only for an identity that wants to be found: a support line, a shop, a public channel.

RegisterCommitted is the alternative. It publishes H(seed ‖ salt) instead, so the chain attests that a seed handed over out of band really belongs to the named account, without broadcasting where that account listens.

Authentication

Every state-changing call carries an ed25519 signature made with the Wesh account private key over a canonical statement that names this chain, the caller's gno address, and a monotonic revision or sequence number. Without it, anyone could publish anyone else's account key next to a seed of their choosing and harvest the contact requests that followed.

Functions

AppendDevice

func AppendDevice(cur realm, prevHex, op, devicePKHex, sigHex string)

AppendDevice adds one entry to the caller's device sigchain.

prevHex must be the digest of the current head (all zeros for the first entry), and the signature must cover the whole statement including the sequence number and that digest. Chaining every entry to its predecessor is what stops the log being reordered or having an entry quietly dropped: any gap changes every digest after it.

op is "add" or "revoke". Adding a device that is already active, or revoking one that is not, is refused: an append-only log is only useful if its entries are meaningful.

Params

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/moul/x/wesh/v0" -func "AppendDevice" -args $'' -args $'' -args $'' -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "gnoland-1" -remote "https://rpc.gno.land" ADDRESSgnokey query -remote "https://rpc.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/moul/x/wesh/v0" -func "AppendDevice" -args $'' -args $'' -args $'' -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "gnoland-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.gno.land" call.tx
  

Count

func Count() int

Count returns the number of registered identities.

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/moul/x/wesh/v0.Count()"

Result

DeviceStatus

func DeviceStatus(name, devicePKHex string) string

DeviceStatus reports "active", "revoked" or "unknown" for a device under a name. "unknown" also covers an unregistered name: a caller must not be able to tell those apart by status alone.

Params

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/moul/x/wesh/v0.DeviceStatus(,)"

Result

func Link(name string) string

Link returns the shareable Berty web link for a name, or "" when the name is unknown or its rendezvous point is committed rather than published.

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/moul/x/wesh/v0.Link()"

Result

NameOf

func NameOf(owner address) string

NameOf returns the handle owned by an address, or "".

Param

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/moul/x/wesh/v0.NameOf()"

Result

Register

func Register(cur realm, name, accountPKHex, seedHex, displayName, sigHex string)

Register publishes an identity whose rendezvous seed is public.

sigHex must be an ed25519 signature by the account private key over wesh.BindStatement(chainID, caller, accountPK, seed, 1). Revision 1 is fixed at registration so a signature captured from a later rotation cannot be replayed to re-register the name after it is released.

Params

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/moul/x/wesh/v0" -func "Register" -args $'' -args $'' -args $'' -args $'' -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "gnoland-1" -remote "https://rpc.gno.land" ADDRESSgnokey query -remote "https://rpc.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/moul/x/wesh/v0" -func "Register" -args $'' -args $'' -args $'' -args $'' -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "gnoland-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.gno.land" call.tx
  

RegisterCommitted

func RegisterCommitted(cur realm, name, accountPKHex, commitmentHex, displayName, sigHex string)

RegisterCommitted publishes an identity that keeps its rendezvous point off chain: commitmentHex is wesh.SeedCommitment(seed, salt), and the seed itself is shared out of band.

The chain still attests the binding (this account key really did claim this commitment from this gno address), so a seed later disclosed privately can be checked against it. What it does not do is tell the world where the account listens.

Params

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/moul/x/wesh/v0" -func "RegisterCommitted" -args $'' -args $'' -args $'' -args $'' -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "gnoland-1" -remote "https://rpc.gno.land" ADDRESSgnokey query -remote "https://rpc.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/moul/x/wesh/v0" -func "RegisterCommitted" -args $'' -args $'' -args $'' -args $'' -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "gnoland-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.gno.land" call.tx
  

Release

func Release(cur realm)

Release removes the caller's identity and frees its name and account key.

The sigchain goes with it. That is the honest behaviour: a directory entry is a live claim, not an archive, and keeping a dangling roster for a name somebody else can now take would be worse than keeping nothing.

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/moul/x/wesh/v0" -func "Release" -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "gnoland-1" -remote "https://rpc.gno.land" ADDRESSgnokey query -remote "https://rpc.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/moul/x/wesh/v0" -func "Release" -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "gnoland-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.gno.land" call.tx
  

Render

func Render(path string) string

Render serves the directory index at "" and one identity card at "<name>".

The index deliberately does not compute a Berty link per row: base58 over a 70-byte payload is big-integer work, and it belongs on the page that a human actually asked for.

Param

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/moul/x/wesh/v0.Render()"

Result

RendezvousPointAt

func RendezvousPointAt(name string, unixSec int64) string

RendezvousPointAt returns the hex rendezvous point the named account announces on during the rotation period containing unixSec, or "" when the name is unknown or committed.

This is what makes a directory entry checkable rather than merely claimed: anyone can compare it against the DHT without trusting this realm.

Params

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/moul/x/wesh/v0.RendezvousPointAt(,)"

Result

Resolve

func Resolve(name string) (accountPKHex, payloadHex string, committed, ok bool)

Resolve returns the account key and current payload of a name, both hex, and whether the payload is a commitment rather than a seed. ok is false when the name is not registered.

Param

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/moul/x/wesh/v0.Resolve()"

Result

Rotate

func Rotate(cur realm, payloadHex, sigHex string)

Rotate publishes a new seed (or commitment) for the caller's identity.

This is the operation weshnet's ContactRequestResetReference has no counterpart for. There, resetting the seed silently invalidates every link ever shared. Here the new value is numbered and the old one stays in the history, so a holder of a stale link can see that it was superseded and when.

The signature must be over revision+1, which is what stops a superseded binding being replayed to roll a rotation back.

Params

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/moul/x/wesh/v0" -func "Rotate" -args $'' -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "gnoland-1" -remote "https://rpc.gno.land" ADDRESSgnokey query -remote "https://rpc.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/moul/x/wesh/v0" -func "Rotate" -args $'' -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "gnoland-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.gno.land" call.tx
  

SetDisplayName

func SetDisplayName(cur realm, displayName string)

SetDisplayName updates the identity's free-form label.

It carries no signature because it authenticates nothing: the display name is app metadata, and berty's own link format keeps it outside the signed payload for the same reason. Only the owning address may change it.

Param

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/moul/x/wesh/v0" -func "SetDisplayName" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "gnoland-1" -remote "https://rpc.gno.land" ADDRESSgnokey query -remote "https://rpc.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/moul/x/wesh/v0" -func "SetDisplayName" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "gnoland-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.gno.land" call.tx
  

SigchainHead

func SigchainHead(name string) string

SigchainHead returns the hex digest the next sigchain entry must chain to, or "" when the name is unknown. A client builds its next statement from this.

Param

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/moul/x/wesh/v0.SigchainHead()"

Result