POST /v1/auth/near validates the NEP-413 payload's recipient against a server-side config.expected_recipient by exact string match (crates/services/src/auth/near.rs:116-122). Nothing published by the service exposes that value.
A native client therefore has to compile in a literal. That has two consequences worth weighing separately:
Guessing wrong is cheap to fix. Every ceremony fails at the first call, we notice immediately, and we ship a corrected build.
Changing it later is not. Because the value is baked into shipped binaries, a change breaks every already-deployed client at the same moment, and no server-side action reaches them — each user needs a new build. For a desktop app on a slow update cadence that is a long tail of accounts that simply cannot log in, and the failure is indistinguishable from "the wallet login is broken."
That asymmetry is the reason for this issue. We are not blocked today; we would just rather not build a fleet-wide breakage mode into the client if a small change avoids it.
What would resolve it
Publishing the expected recipient somewhere unauthenticated, so a client reads it at ceremony start instead of hardcoding it. A field on an existing unauthenticated response would be enough — it needs no new endpoint and is not sensitive, since it is the value the client is required to send.
For comparison, our own equivalent ceremony exposes a capabilities endpoint precisely so clients never hardcode the ceremony's parameters; there is currently no counterpart here.
Context
Trace Commons is building NEAR-wallet login so contributors can obtain a NEAR AI inference credential from the desktop app. We have contributed to this repo before (#1026) and to nearai/ironwire (eleven merged PRs). Happy to open the PR if you tell us where you would want the value surfaced — we did not want to pick a place in your API surface unilaterally.
Two smaller things noticed while reading, no action expected
- The generated OpenAPI document at
/api-docs/openapi.json (110 paths) omits every /v1/auth/* route, so absence there does not indicate absence from the service. It briefly misled us.
info.description refers to /users/me/access_tokens; the served path is /v1/users/me/access-tokens (hyphen).
POST /v1/auth/nearvalidates the NEP-413 payload's recipient against a server-sideconfig.expected_recipientby exact string match (crates/services/src/auth/near.rs:116-122). Nothing published by the service exposes that value.A native client therefore has to compile in a literal. That has two consequences worth weighing separately:
Guessing wrong is cheap to fix. Every ceremony fails at the first call, we notice immediately, and we ship a corrected build.
Changing it later is not. Because the value is baked into shipped binaries, a change breaks every already-deployed client at the same moment, and no server-side action reaches them — each user needs a new build. For a desktop app on a slow update cadence that is a long tail of accounts that simply cannot log in, and the failure is indistinguishable from "the wallet login is broken."
That asymmetry is the reason for this issue. We are not blocked today; we would just rather not build a fleet-wide breakage mode into the client if a small change avoids it.
What would resolve it
Publishing the expected recipient somewhere unauthenticated, so a client reads it at ceremony start instead of hardcoding it. A field on an existing unauthenticated response would be enough — it needs no new endpoint and is not sensitive, since it is the value the client is required to send.
For comparison, our own equivalent ceremony exposes a capabilities endpoint precisely so clients never hardcode the ceremony's parameters; there is currently no counterpart here.
Context
Trace Commons is building NEAR-wallet login so contributors can obtain a NEAR AI inference credential from the desktop app. We have contributed to this repo before (#1026) and to
nearai/ironwire(eleven merged PRs). Happy to open the PR if you tell us where you would want the value surfaced — we did not want to pick a place in your API surface unilaterally.Two smaller things noticed while reading, no action expected
/api-docs/openapi.json(110 paths) omits every/v1/auth/*route, so absence there does not indicate absence from the service. It briefly misled us.info.descriptionrefers to/users/me/access_tokens; the served path is/v1/users/me/access-tokens(hyphen).