1. Generate a keypair locally (public key is safe to share) - `python tools/gen_auth.py --nonce init` - Copy PUBLIC_HEX (compressed 33-byte hex, 66 chars). PRIVATE_HEX is your secret—keep it safe. - Example output: ``` PRIVATE_HEX=5d38d57c83ef1845032fdee1c954958b66912218744ea31d0bc61a07115b6b93 PUBLIC_HEX=0270c0fe3599e82f7142d349fc88e47b07077a43fa00b0fe218ee7bdef4b42d316 NONCE=init SIGNATURE_HEX=1b109a464c8a6326e66e7bd2caf4c537611f24c6e5e74b0003dc2d5025b6cd6ed180417eacf540938fb306d46d8ebeeed1e6e6c6b69f536d62144baf4a13a139 ``` 2. Fetch a real nonce from the server - In hero-openrpc-client menu, choose fetch_nonce - Paste PUBLIC_HEX when prompted - Copy the returned nonce string (the exact ASCII hex string) - Example output: ``` 7428f639c215b5ab655283632a39fbd8dc713805cc3b7b0a84c99a5f0e7d5465 ``` 3. Sign the nonce locally - python tools/gen_auth.py --nonce "PASTE_NONCE" --priv "YOUR_PRIVATE_HEX" - Copy SIGNATURE_HEX - Example output: ``` PRIVATE_HEX=5d38d57c83ef1845032fdee1c954958b66912218744ea31d0bc61a07115b6b93 PUBLIC_HEX=0270c0fe3599e82f7142d349fc88e47b07077a43fa00b0fe218ee7bdef4b42d316 NONCE=7428f639c215b5ab655283632a39fbd8dc713805cc3b7b0a84c99a5f0e7d5465 SIGNATURE_HEX=47dca63f191f328ca9404843a1b3229e4e2affb85ff41dad8125320be3ee07507222c809876d5faa93bfafebdff9e9aef9e17d0b7792d7fcac4d19c92a4b303f ``` 4. Authenticate - In hero-openrpc-client menu, choose authenticate - Public key (hex): PUBLIC_HEX - Signature (hex): SIGNATURE_HEX - Nonce (hex): PASTE_NONCE After success, whoami should return an authenticated state (basic placeholder in this phase) rust.interfaces/openrpc/server/src/lib.rs. 5. Run `python tools/rpc_smoke_test.py` - Example output: ``` [rpc] URL: http://127.0.0.1:9944 [rpc] fetch_nonce(pubkey=03fc656cda...): OK nonce: 4317af6ef04605c7e61ec4759611345f7288497564784cc08afc158553e5ecf1 [rpc] whoami(): OK whoami: {"authenticated":true,"user_id":"anonymous"} [rpc] list_jobs(): OK total: 3 [0] 5f8b4951-35de-4568-8906-a5e9598729e1 [1] 8a0ee6ea-c053-4b72-807a-568c959f5188 [2] 1f929972-3aa5-40c6-af46-6cb81f5a0bae [rpc] get_job_status(5f8b4951-35de-4568-8906-a5e9598729e1): OK status: Finished [rpc] get_job_output(5f8b4951-35de-4568-8906-a5e9598729e1): OK output: 17 [rpc] get_job_logs(5f8b4951-35de-4568-8906-a5e9598729e1): OK logs: (no logs) [rpc] get_job_status(8a0ee6ea-c053-4b72-807a-568c959f5188): OK status: Finished [rpc] get_job_output(8a0ee6ea-c053-4b72-807a-568c959f5188): OK output: 43 [rpc] get_job_logs(8a0ee6ea-c053-4b72-807a-568c959f5188): OK logs: (no logs) [rpc] get_job_status(1f929972-3aa5-40c6-af46-6cb81f5a0bae): OK status: Finished [rpc] get_job_output(1f929972-3aa5-40c6-af46-6cb81f5a0bae): OK output: 43 [rpc] get_job_logs(1f929972-3aa5-40c6-af46-6cb81f5a0bae): OK logs: (no logs) Smoke tests complete. Summary: whoami tested fetch_nonce tested (pubkey provided/generated) list_jobs tested (count printed) detailed queries for up to 3 job(s) (status/output/logs) ```