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

render_example_test.gno

5.06 Kb · 137 lines
  1package wesh
  2
  3import (
  4	"encoding/hex"
  5
  6	"gno.land/p/moul/x/wesh/v0"
  7	"gno.land/p/nt/avl/v0"
  8	"gno.land/p/nt/testutils/v0"
  9)
 10
 11// seedDemo puts the realm into a fixed state for the examples below.
 12//
 13// It writes the globals directly instead of going through the crossing API:
 14// realm globals persist for the whole test binary and examples run after every
 15// Test, so an example that did not reset would pin whatever the last test left
 16// behind. Heights are literals for the same reason.
 17func seedDemo() {
 18	byName = avl.Tree{}
 19	byOwner = avl.Tree{}
 20	byAccount = avl.Tree{}
 21
 22	pk, _ := hex.DecodeString("2152f8d19b791d24453242e15f2eab6cb7cffa7b6a5ed30097960e069881db12")
 23	seed1, _ := hex.DecodeString("abababababababababababababababababababababababababababababababab")
 24	seed2, _ := hex.DecodeString("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee")
 25	dev1, _ := hex.DecodeString("0707070707070707070707070707070707070707070707070707070707070707")
 26	dev2, _ := hex.DecodeString("0909090909090909090909090909090909090909090909090909090909090909")
 27	d1, _ := hex.DecodeString("bc51799b5d012dc7ce806b4c63474b1e2db515e7d1622ecd5900b23e1d6a9519")
 28	d2, _ := hex.DecodeString("b0da03f83e5349e92bc524714862daa850750f756ca6fd47264333fbf2175c15")
 29	d3, _ := hex.DecodeString("ef0c1d0614420c7d660f8416b18651206118e49e8f46ac0360bef61ae6b9100d")
 30
 31	alice := &identity{
 32		name:        "alice",
 33		owner:       testutils.TestAddress("alice"),
 34		accountPK:   pk,
 35		payload:     seed2,
 36		revision:    2,
 37		displayName: "Alice, support line",
 38		history: []rotation{
 39			{revision: 1, payload: seed1, height: 100},
 40			{revision: 2, payload: seed2, height: 140},
 41		},
 42		devices: []deviceEntry{
 43			{seq: 0, op: wesh.OpAdd, devicePK: dev1, digest: d1, height: 110},
 44			{seq: 1, op: wesh.OpAdd, devicePK: dev2, digest: d2, height: 120},
 45			{seq: 2, op: wesh.OpRevoke, devicePK: dev1, digest: d3, height: 130},
 46		},
 47		head: d3,
 48	}
 49	byName.Set(alice.name, alice)
 50	byOwner.Set(alice.owner.String(), alice.name)
 51	byAccount.Set(hex.EncodeToString(pk), alice.name)
 52}
 53
 54// ExampleRender pins the directory index.
 55func ExampleRender() {
 56	seedDemo()
 57	print(Render(""))
 58	// Output:
 59	// # Wesh directory
 60	//
 61	// Resolvable, self-signed [Wesh protocol](https://berty.tech/docs/protocol/) identities, on top of [`p/moul/x/wesh`](/p/moul/x/wesh/v0).
 62	//
 63	// A Berty identity normally travels out of band as a QR code, cannot be looked up, cannot announce a seed rotation, and can never revoke a device. This realm addresses those three, and stores no secret of any kind.
 64	//
 65	// | name | owner | rev | mode | devices |
 66	// |---|---|---|---|---|
 67	// | [alice](/r/moul/x/wesh/v0:alice) | `g1v9kxjcm9ta047h6lta047h6lta047h6lzd40gh` | 2 | published | 1 active / 3 entries |
 68	//
 69	// 1 identity.
 70}
 71
 72// ExampleRender_identity pins one identity card: the Berty link, today's
 73// rendezvous point, the device sigchain and the rotation history.
 74func ExampleRender_identity() {
 75	seedDemo()
 76	print(Render("alice"))
 77	// Output:
 78	// # alice
 79	//
 80	// _Alice, support line_
 81	//
 82	// | field | value |
 83	// |---|---|
 84	// | owner | `g1v9kxjcm9ta047h6lta047h6lta047h6lzd40gh` |
 85	// | account key | `2152f8d19b791d24453242e15f2eab6cb7cffa7b6a5ed30097960e069881db12` |
 86	// | mode | published |
 87	// | revision | 2 |
 88	// | registered | block 100 |
 89	//
 90	// ## Contact
 91	//
 92	// Scan or open this in Berty to send a contact request:
 93	//
 94	// ```
 95	// https://berty.tech/id#contact/oZBLGHCDNRB847rT1zHe1xnon58fpWTUsuNntmAo9TK42aKzt14A1V5W67QoN5YzMouuVcucUiBWjN9d2qzy6gUNM4Jio4M/name=Alice%2C+support+line
 96	// ```
 97	//
 98	// | field | value |
 99	// |---|---|
100	// | rendezvous seed | `eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee` |
101	// | rendezvous point, period 1234483200 | `08ab5591fbd91f0251a7efe4856fc736a02d1a2252139483ddc8ca85f4616e07` |
102	//
103	// The point is `HMAC-SHA256(accountPK || seed, be64(period))`, derived exactly as weshnet derives it, and it rotates every 24h. Anyone can recompute it and check the DHT, so this entry is verifiable rather than merely asserted.
104	//
105	// ## Devices
106	//
107	// Every entry below was signed by the account key and verified on chain, and chains to the digest of the one before it.
108	//
109	// | seq | op | device | block | digest |
110	// |---|---|---|---|---|
111	// | 0 | add | `07070707…07070707` | 110 | `bc51799b…1d6a9519` |
112	// | 1 | add | `09090909…09090909` | 120 | `b0da03f8…f2175c15` |
113	// | 2 | revoke | `07070707…07070707` | 130 | `ef0c1d06…e6b9100d` |
114	//
115	// Head: `ef0c1d0614420c7d660f8416b18651206118e49e8f46ac0360bef61ae6b9100d`
116	//
117	// ## Rotation history
118	//
119	// Weshnet has no way to announce that a seed was reset, so every link ever shared dies silently. These are the superseded values, kept so a stale link can be recognised as stale.
120	//
121	// | rev | value | block |
122	// |---|---|---|
123	// | 1 | `abababab…abababab` | 100 |
124	// | 2 (current) | `eeeeeeee…eeeeeeee` | 140 |
125	//
126	// [Back to the directory](/r/moul/x/wesh/v0) · chain `dev`
127}
128
129// ExampleRender_unknown pins the miss.
130func ExampleRender_unknown() {
131	seedDemo()
132	print(Render("nobody"))
133	// Output:
134	// # Not found
135	//
136	// No identity named `nobody`. [Back to the directory](/r/moul/x/wesh/v0).
137}