From f5b838a9c0400463088d5ed0936de85448b029ab Mon Sep 17 00:00:00 2001
From: johnnymatthews <9611008+johnnymatthews@users.noreply.github.com>
Date: Thu, 20 Aug 2026 12:52:16 +0100
Subject: [PATCH 1/5] Adds new assert-ownership page.
---
config.toml | 1 +
1 file changed, 1 insertion(+)
diff --git a/config.toml b/config.toml
index 00bd154..a3e695c 100644
--- a/config.toml
+++ b/config.toml
@@ -154,6 +154,7 @@ label = "Run a Generator"
pages = [
"run/run-a-generator/hardware-requirements/index.md",
"run/run-a-generator/install/index.md",
+ "run/run-a-generator/assert-ownership/index.md",
"run/run-a-generator/register/index.md",
"run/run-a-generator/config-reference/index.md",
]
From a5467db98f6c4f1143f0b4fcfc176b608b8856c2 Mon Sep 17 00:00:00 2001
From: johnnymatthews <9611008+johnnymatthews@users.noreply.github.com>
Date: Thu, 20 Aug 2026 12:52:28 +0100
Subject: [PATCH 2/5] Points users to new assert-ownership page.
---
content/run/run-a-generator/register/index.md | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/content/run/run-a-generator/register/index.md b/content/run/run-a-generator/register/index.md
index 9b1657b..2e12b62 100644
--- a/content/run/run-a-generator/register/index.md
+++ b/content/run/run-a-generator/register/index.md
@@ -36,14 +36,9 @@ Before you start, have the following ready:
### Assertion
-The Assertion step verifies that you control the validator you are registering as a Generator. You'll need to provide:
+The assertion verifies that you control the validator you are registering as a Generator. It is a prerequisite for this page, and it has its own dedicated walkthrough: see [Assert ownership of a validator](../assert-ownership/). Complete that first, then return here to register on-chain.
-- **Consensus public key**: The consensus public key of the validator you are registering (see [Consensus public key](/reference/components/outpost#consensus-public-key)).
-- **Source chain**: The blockchain your generator monitors (see [shinzo.network/chains](https://shinzo.network/chains) for supported chains).
-
-The assertion is authorized by your validator's withdrawal key, which proves control of the validator's stake. See [Validator assertions](/reference/components/outpost#validator-assertions) for how this works end to end.
-
-Click **Sign & Submit** to sign a message with your wallet, proving ownership of the generator's identity.
+You provide your validator's consensus public key and source chain, and sign the assertion digest with your withdrawal key using **Sign & Submit**. The full on-chain mechanism is documented under [Validator assertions](/reference/components/outpost#validator-assertions).
### Registration (register on-chain)
From eef966503204b457d2a203ea4914c7cb5cb75257 Mon Sep 17 00:00:00 2001
From: johnnymatthews <9611008+johnnymatthews@users.noreply.github.com>
Date: Thu, 20 Aug 2026 12:52:37 +0100
Subject: [PATCH 3/5] First pass at Assertion page.
---
.../run-a-generator/assert-ownership/index.md | 100 ++++++++++++++++++
1 file changed, 100 insertions(+)
create mode 100644 content/run/run-a-generator/assert-ownership/index.md
diff --git a/content/run/run-a-generator/assert-ownership/index.md b/content/run/run-a-generator/assert-ownership/index.md
new file mode 100644
index 0000000..fbba675
--- /dev/null
+++ b/content/run/run-a-generator/assert-ownership/index.md
@@ -0,0 +1,100 @@
++++
+title = "Assert ownership of a validator"
+description = "Assert validator ownership before registering as a Generator. Covers the assertion flow, the keys involved, and rotating them."
+aliases = ["/generator/assert", "/generators/assert", "/generator/assertion", "/generators/assertion"]
+[extra]
+mermaid = true
++++
+
+Before a Generator can register on ShinzoHub, its operator has to prove they control a validator on the source chain. That proof is the assertion. It happens once, on the source chain, and it is what lets ShinzoHub trust that the Generator belongs to a real validator.
+
+This page walks through the user-facing flow in the Technical Registry. For the on-chain mechanism, how the outpost verifies the validator, and the exact fields that go into the signed digest, see [Validator assertions](/reference/components/outpost#validator-assertions).
+
+## Prerequisites
+
+Have the following ready before you start. They are the same as the registration prerequisites, restated here because the assertion depends on them.
+
+1. **An active, bonded chain validator.** The outpost checks that the validator named in the assertion is active and bonded on the source chain. If you are not a validator, you can still run the client, but you cannot assert or register.
+1. **Your validator's consensus public key.** This names the validator being asserted. The key type, format, and lookup tooling are chain-specific; see [Consensus public key](/reference/components/outpost#consensus-public-key) for how to retrieve it on your chain. It is not your withdrawal address or an EVM address.
+1. **Access to your validator's withdrawal key.** The assertion is signed with the withdrawal key to prove control of the validator's stake, and the withdrawal address is included in the assertion. See [Validator assertions](/reference/components/outpost#validator-assertions) for the full flow.
+1. **A browser wallet** to sign the assertion message.
+
+## The keys involved
+
+Three keys appear in the assertion, and keeping their roles straight avoids most of the confusion around this step.
+
+- **Operator (delegate) key.** The account the Generator uses for ShinzoHub operations. Authority over the validator is delegated _to_ this key. It is generated or imported when the Generator client starts, and it does not change unless you rotate it or move machines.
+- **Withdrawal key.** Signs the assertion. Proving control of the withdrawal key is how the outpost confirms you control the validator's stake.
+- **Consensus public key.** Names the validator. It is read from the assertion so the outpost knows which validator to check, then verified against the source chain's staking state. It does not sign anything here.
+
+The consensus public key and the withdrawal key are different things, even though both relate to the same validator. The consensus key identifies the validator on the consensus layer; the withdrawal key controls where its rewards and stake go.
+
+## Assertion flow
+
+You complete the assertion in the Technical Registry, the same app used for registration. If your node is on a private network or you would rather use the registration app bundled with the Generator client, it is also served locally at `http://localhost:8080/registration-app`. For a remote node, reach it over SSH local port forwarding: run `ssh -L 8080:localhost:8080 user@your-node-ip` on your local machine, then open `http://localhost:8080/registration-app` in your browser.
+
+1. Start your Generator client.
+1. Add the Shinzo Testnet to your browser wallet with the following values:
+ - Network name: `Shinzo`
+ - Default RPC URL: `http://testnet.shinzo.network:8545`
+ - Chain ID: `91273001`
+ - Currency symbol: `SHNZ`
+
+ You need a small amount of SHNZ to cover the on-chain transaction. Get testnet SHNZ from the [faucet](https://faucet.shinzo.network/).
+1. Open the [Technical Registry](https://registration.shinzo.network/) and connect your wallet using the button in the top-right corner.
+1. From the homepage, click **Register as Generator** to start the two-step flow. The first step is the assertion.
+1. In the assertion step, provide:
+ - **Consensus public key**: the consensus public key of the validator you are registering (see [Consensus public key](/reference/components/outpost#consensus-public-key)).
+ - **Source chain**: the blockchain your Generator monitors (see [shinzo.network/chains](https://shinzo.network/chains) for supported chains).
+1. Click **Sign & Submit** to sign the assertion digest with your withdrawal key.
+
+What happens next, on-chain, is what makes the assertion trustworthy. The outpost contract verifies that the signing key controls the validator and that the validator is active and bonded, stores the signed assertion, and emits an `AssertionSigned` event. A relayer picks up the event and forwards the assertion to ShinzoHub, which verifies it again and records an authorization slip for the operator key. At that point the operator key is cleared to register a Generator.
+
+{% mermaid() %}
+sequenceDiagram
+ participant U as You
(withdrawal key)
+ participant R as Technical Registry
+ participant O as Outpost contract
on source chain
+ participant L as Relayer
+ participant H as ShinzoHub
+
+ U->>R: provide consensus pubkey
+ source chain
+ R->>O: open assertion,
request digest
+ O-->>R: assertion ID + EIP-712 digest
+ U->>R: Sign & Submit
(withdrawal key)
+ R->>O: submitAssertionSignature
+ O->>O: verify withdrawal key
controls validator
+ O-->>L: emit AssertionSigned
+ L->>H: MsgGeneratorAssertion
+ H->>H: verify assertion,
record operator-key slip
+{% end %}
+
+The diagram shows the EVM path. Other chain types use a different verification mechanism, but the shape is the same: prove control of the validator on its own chain, relay the result to ShinzoHub. See [Validator assertions](/reference/components/outpost#validator-assertions) for the per-chain detail.
+
+## After the assertion
+
+With the operator key authorized, the assertion step is done. Move on to registration, which records the Generator on-chain:
+
+- See [Register](../register/) for the on-chain registration step and how to confirm it succeeded.
+
+The assertion is a one-time action per machine. You only repeat it when the validator key changes (see below) or you rotate the operator key.
+
+## Key rotation
+
+If you move machines or rotate the operator key, the assertion and registration have to be redone. The old operator and withdrawal authorizations are revoked, and the new key pair is bound back to the validator on-chain when the new assertion is submitted.
+
+1. Generate or import the new operator key on the new machine.
+1. If the validator's withdrawal key or consensus key has changed, complete a new assertion with the new validator details.
+1. Re-submit the Generator registration request using the new operator key (see [Register](../register/)).
+
+The window between shutdown and re-registration is a gap in submissions. It does not affect the integrity of data the Generator already produced. During the downtime no one else can submit or spoof your operator key, because it is tied to the private key in your environment, and no one else can assert your validator, because that requires the withdrawal key.
+
+If the operator key is lost with no backup, you will be unable to re-register the same identity until you complete a new assertion from the validator's withdrawal key. Back up the operator key the same way you back up your node identity key.
+
+{% admonition(type="info") %}
+This covers the operator and validator assertion keys only. General node identity key management, including backups and restores, is tracked separately and will live on the [Key & identity management](/run/operations/key-and-identity-management/) page.
+{% end %}
+
+## Need help
+
+{{ need_help(client="Generator", repo_name="shinzo-generator-client", repo="https://github.com/shinzonetwork/shinzo-generator-client/issues") }}
From d22cb46cd3729c37d789b796a520462e42e985f0 Mon Sep 17 00:00:00 2001
From: johnnymatthews <9611008+johnnymatthews@users.noreply.github.com>
Date: Thu, 20 Aug 2026 13:11:34 +0100
Subject: [PATCH 4/5] Renames folder to match page title.
---
config.toml | 2 +-
.../index.md | 0
content/run/run-a-generator/register/index.md | 2 +-
3 files changed, 2 insertions(+), 2 deletions(-)
rename content/run/run-a-generator/{assert-ownership => assert-ownership-of-a-validator}/index.md (100%)
diff --git a/config.toml b/config.toml
index a3e695c..04f06ab 100644
--- a/config.toml
+++ b/config.toml
@@ -154,7 +154,7 @@ label = "Run a Generator"
pages = [
"run/run-a-generator/hardware-requirements/index.md",
"run/run-a-generator/install/index.md",
- "run/run-a-generator/assert-ownership/index.md",
+ "run/run-a-generator/assert-ownership-of-a-validator/index.md",
"run/run-a-generator/register/index.md",
"run/run-a-generator/config-reference/index.md",
]
diff --git a/content/run/run-a-generator/assert-ownership/index.md b/content/run/run-a-generator/assert-ownership-of-a-validator/index.md
similarity index 100%
rename from content/run/run-a-generator/assert-ownership/index.md
rename to content/run/run-a-generator/assert-ownership-of-a-validator/index.md
diff --git a/content/run/run-a-generator/register/index.md b/content/run/run-a-generator/register/index.md
index 2e12b62..4e030bf 100644
--- a/content/run/run-a-generator/register/index.md
+++ b/content/run/run-a-generator/register/index.md
@@ -36,7 +36,7 @@ Before you start, have the following ready:
### Assertion
-The assertion verifies that you control the validator you are registering as a Generator. It is a prerequisite for this page, and it has its own dedicated walkthrough: see [Assert ownership of a validator](../assert-ownership/). Complete that first, then return here to register on-chain.
+The assertion verifies that you control the validator you are registering as a Generator. It is a prerequisite for this page, and it has its own dedicated walkthrough: see [Assert ownership of a validator](../assert-ownership-of-a-validator/). Complete that first, then return here to register on-chain.
You provide your validator's consensus public key and source chain, and sign the assertion digest with your withdrawal key using **Sign & Submit**. The full on-chain mechanism is documented under [Validator assertions](/reference/components/outpost#validator-assertions).
From da3b32da1c5b9efade12823ac12d6dd0b89bbc1e Mon Sep 17 00:00:00 2001
From: johnnymatthews <9611008+johnnymatthews@users.noreply.github.com>
Date: Thu, 20 Aug 2026 13:19:05 +0100
Subject: [PATCH 5/5] Tiny cleanup. Removes "Get Help" section (not needed).
---
.../assert-ownership-of-a-validator/index.md | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)
diff --git a/content/run/run-a-generator/assert-ownership-of-a-validator/index.md b/content/run/run-a-generator/assert-ownership-of-a-validator/index.md
index fbba675..611eddc 100644
--- a/content/run/run-a-generator/assert-ownership-of-a-validator/index.md
+++ b/content/run/run-a-generator/assert-ownership-of-a-validator/index.md
@@ -6,7 +6,7 @@ aliases = ["/generator/assert", "/generators/assert", "/generator/assertion", "/
mermaid = true
+++
-Before a Generator can register on ShinzoHub, its operator has to prove they control a validator on the source chain. That proof is the assertion. It happens once, on the source chain, and it is what lets ShinzoHub trust that the Generator belongs to a real validator.
+Before a Generator can register on ShinzoHub, its operator has to prove they control a validator on the source chain. That proof is the assertion. It happens once, on the source chain, and it is what lets ShinzoHub trust that the Generator client belongs to a real validator.
This page walks through the user-facing flow in the Technical Registry. For the on-chain mechanism, how the outpost verifies the validator, and the exact fields that go into the signed digest, see [Validator assertions](/reference/components/outpost#validator-assertions).
@@ -31,7 +31,7 @@ The consensus public key and the withdrawal key are different things, even thoug
## Assertion flow
-You complete the assertion in the Technical Registry, the same app used for registration. If your node is on a private network or you would rather use the registration app bundled with the Generator client, it is also served locally at `http://localhost:8080/registration-app`. For a remote node, reach it over SSH local port forwarding: run `ssh -L 8080:localhost:8080 user@your-node-ip` on your local machine, then open `http://localhost:8080/registration-app` in your browser.
+You complete the assertion in the Technical Registry at [registration.shinzo.network](https://registration.shinzo.network/), the same app used for registration. If your node is on a private network or you would rather use the registration app bundled with the Generator client, it is also served locally at `http://localhost:8080/registration-app`. For a remote node, reach it over SSH local port forwarding: run `ssh -L 8080:localhost:8080 user@your-node-ip` on your local machine, then open `http://localhost:8080/registration-app` in your browser.
1. Start your Generator client.
1. Add the Shinzo Testnet to your browser wallet with the following values:
@@ -48,7 +48,7 @@ You complete the assertion in the Technical Registry, the same app used for regi
- **Source chain**: the blockchain your Generator monitors (see [shinzo.network/chains](https://shinzo.network/chains) for supported chains).
1. Click **Sign & Submit** to sign the assertion digest with your withdrawal key.
-What happens next, on-chain, is what makes the assertion trustworthy. The outpost contract verifies that the signing key controls the validator and that the validator is active and bonded, stores the signed assertion, and emits an `AssertionSigned` event. A relayer picks up the event and forwards the assertion to ShinzoHub, which verifies it again and records an authorization slip for the operator key. At that point the operator key is cleared to register a Generator.
+What happens next, on-chain, is what makes the assertion trustworthy. The outpost contract verifies that the signing key controls the validator and that the validator is active and bonded, stores the signed assertion, and emits an `AssertionSigned` event. A relayer picks up the event and forwards the assertion to ShinzoHub, which verifies it again and records an authorization slip for the operator key. At that point the operator key is cleared to register a Generator client.
{% mermaid() %}
sequenceDiagram
@@ -73,11 +73,9 @@ The diagram shows the EVM path. Other chain types use a different verification m
## After the assertion
-With the operator key authorized, the assertion step is done. Move on to registration, which records the Generator on-chain:
+With the operator key authorized, the assertion step is done. Move on to registration, which records the Generator on-chain. See [Register](../register/) for the on-chain registration step and how to confirm it succeeded.
-- See [Register](../register/) for the on-chain registration step and how to confirm it succeeded.
-
-The assertion is a one-time action per machine. You only repeat it when the validator key changes (see below) or you rotate the operator key.
+The assertion step is a one-time action per machine. You only repeat it when the validator key changes (see below) or you rotate the operator key.
## Key rotation
@@ -92,9 +90,5 @@ The window between shutdown and re-registration is a gap in submissions. It does
If the operator key is lost with no backup, you will be unable to re-register the same identity until you complete a new assertion from the validator's withdrawal key. Back up the operator key the same way you back up your node identity key.
{% admonition(type="info") %}
-This covers the operator and validator assertion keys only. General node identity key management, including backups and restores, is tracked separately and will live on the [Key & identity management](/run/operations/key-and-identity-management/) page.
+This covers the operator and validator assertion keys only. General node identity key management, including backups and restores, is tracked separately and will live on the [Key and identity management](/run/operations/key-and-identity-management/) page.
{% end %}
-
-## Need help
-
-{{ need_help(client="Generator", repo_name="shinzo-generator-client", repo="https://github.com/shinzonetwork/shinzo-generator-client/issues") }}