Part of RFC-27 (tracker: #4194). Depends on #4198 and #4200.
What
- Per-environment verifier URLs in
config/src/constants.rs alongside the existing RPC/program constants, with a --ip-verifier-url override for local and devnet.
- In
crates/doublezero-daemon-cli/src/connect.rs: derive the User PDA, request a proof, and use the client_ip the service returns as the authoritative value. resolve_client_ip / get_public_ipv4 (ifconfig.me) becomes a UX convenience for display and pre-flight checks, not the source of truth.
- If the user passed
--client-ip explicitly and it disagrees with what the service observed, fail with a message that names both addresses. Guessing between them is worse than stopping.
- Multi-homed hosts. The proof is only valid if the verification request egresses from the same address the tunnel will use. Bind the outbound request to the selected source address where one is specified, and document the failure mode when the host picks a different egress.
- Error messages that distinguish service unreachable, non-routable source address, and onchain proof rejection. A user behind CGNAT will hit this and needs to know why.
- If the service is unreachable, attempt creation without a proof and let the program decide. That succeeds while the feature flag is off and fails cleanly once it is on, which is the behavior we want during rollout.
Acceptance
- Tests with a mocked verifier covering the happy path, service unreachable, and
--client-ip disagreement.
- Manual verification against local devnet end to end.
Part of RFC-27 (tracker: #4194). Depends on #4198 and #4200.
What
config/src/constants.rsalongside the existing RPC/program constants, with a--ip-verifier-urloverride for local and devnet.crates/doublezero-daemon-cli/src/connect.rs: derive the User PDA, request a proof, and use theclient_ipthe service returns as the authoritative value.resolve_client_ip/get_public_ipv4(ifconfig.me) becomes a UX convenience for display and pre-flight checks, not the source of truth.--client-ipexplicitly and it disagrees with what the service observed, fail with a message that names both addresses. Guessing between them is worse than stopping.Acceptance
--client-ipdisagreement.