Repository navigation
Conversation
Adds a relay plugin that stores signed key authorizations and attaches them to the access key's next `eth_fillTransaction` until the key is active onchain. `Actions.accessKey.signAuthorization` saves locally signed authorizations through `relay_setKeyAuthorization`, and the plugin stores multisig key authorizations once they reach quorum. Remote `withRelay` transports opt in with `keyAuthorization: true`. Deprecates `KeyAuthorizationManager` and the `keyAuthorizationManager` account option. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011m6WzEXC4aBoYHHxaU7X9X
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🦋 Changeset detectedLatest commit: 30d2d56 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011m6WzEXC4aBoYHHxaU7X9X
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9b081c9bbd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| export type Parameters = RelayProxyParameters & { | ||
| /** Whether the relay stores key authorizations with `Relay.keyAuthorization`. Defaults to `false`. */ | ||
| keyAuthorization?: boolean | undefined | ||
| } |
There was a problem hiding this comment.
Preserve remote keyAuthorization in the transport type
When the remote overload is called with { keyAuthorization: true }, the implementation adds keyAuthorization to the runtime transport value, but the overload still returns the fixed withRelay.ReturnValue/Relay type containing only { multisig: true }. Consequently, client.transport.keyAuthorization is a type error specifically for remote relays even though the capability is enabled and is correctly inferred in local mode. Make the remote overload generic over these parameters and include { keyAuthorization: true } when the literal option is enabled.
AGENTS.md reference: AGENTS.md:L70-L76
Useful? React with 👍 / 👎.
| await next() | ||
| // The multisig plugin validates the config and owner approvals before | ||
| // reporting success, so the completed authorization can be stored as is. |
There was a problem hiding this comment.
Revalidate completed multisig authorizations before storing
When a multisig authorization reaches quorum after its expiry, this branch stores it without the expiry check used by relay_setKeyAuthorization; the subsequent fill immediately removes it, so the approval call reports success but the advertised first-use transaction fails with an unauthorized key. Likewise, retrying an already-successful operation after the multisig config changes can restore an authorization whose config is no longer current, causing it to be attached and rejected repeatedly. Re-run the completed authorization through the expiry and multisig verification checks before writing it to the pending store.
Useful? React with 👍 / 👎.
`relay_setKeyAuthorization` now only replaces a pending authorization that expires earlier, so a replayed older authorization cannot replace a newer one. Writes use atomic compare-and-set, entries expire with the authorization (at most 30 days), and authorizations for keys that are already active are not stored. `Relay.keyAuthorization` now requires an atomic store. Also removes the friction log entry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011m6WzEXC4aBoYHHxaU7X9X
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 30d2d56046
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (await store.compareAndSet(key, current, value, { expiresAt })) return true | ||
| // Another writer replaced the value, so compare against the new one. | ||
| return write(store, options) |
There was a problem hiding this comment.
When an atomic store repeatedly loses compareAndSet because of sustained contention, or an adapter returns false without making progress, this recursively retries forever, leaving relay_setKeyAuthorization requests pending and continuously hitting the backing store. The existing multisig operation updater caps the same retry loop at 32 attempts and raises a conflict error; apply a similar bound here so a contended key cannot consume relay resources indefinitely.
Useful? React with 👍 / 👎.
| /** Signs a key authorization locally without saving it to a relay. @internal */ | ||
| export async function inner< |
There was a problem hiding this comment.
Keep the signing helper off the public action
Declaring inner as an exported member of the exported signAuthorization namespace exposes Actions.accessKey.signAuthorization.inner at runtime and in the package declarations, unintentionally turning an implementation detail into a public API that consumers can depend on. Move this helper to a module-local function rather than attaching it to the public action.
AGENTS.md reference: AGENTS.md:L99-L99
Useful? React with 👍 / 👎.
What is this PR solving?
This PR adds the
Relay.keyAuthorizationplugin to viem/tempo, which stores signed key authorizations and attaches them to an access key's next transaction. This enables applications to authorize access keys offchain and have them register onchain in a single transaction.The plugin:
Actions.accessKey.signAuthorizationvia therelay_setKeyAuthorizationRPC methodeth_fillTransactionrequests for the corresponding access keykeyAuthorization: trueoption)This replaces the deprecated
KeyAuthorizationManageraccount option with a relay-based approach that works better with coordinated multisig flows.Changes
Core Implementation
src/tempo/internal/relay/keyAuthorization.ts: New plugin implementation with request handling forrelay_setKeyAuthorization,multisig_approveKeyAuthorization, andeth_fillTransactionmethodssrc/tempo/Relay.ts: AddedRelay.keyAuthorizationexport and type definitionssrc/tempo/Transport.ts: UpdatedwithRelayto detect and advertise key authorization capabilitysrc/tempo/internal/relay/plugin.ts: Added plugin registration for capability detectionIntegration
src/tempo/actions/accessKey.ts: UpdatedsignAuthorizationto automatically submit signed authorizations to relays with key authorization storagesrc/tempo/Account.ts: DeprecatedkeyAuthorizationManageraccount optionsrc/tempo/KeyAuthorizationManager.ts: Marked as deprecatedDocumentation
site/pages/tempo/relay/plugins/key-authorization.mdx: New comprehensive plugin documentation with recipes for single-signature and multisig flowssite/pages/tempo/actions/accessKey.signAuthorization.mdx: Added note about relay integrationsite/pages/tempo/guides/relay/: Updated relay guides to include the new pluginsite/vocs.config.ts: Added plugin to navigationTests
src/tempo/internal/relay/keyAuthorization.test.ts: Comprehensive test suite covering:relay_setKeyAuthorizationRPC method validationsrc/tempo/internal/relay/multisig.test.ts: Added integration tests for multisig key authorizationsChangelog
.changeset/relay-key-authorization.md: Documented the new feature and deprecationTest Plan
The PR includes comprehensive test coverage:
keyAuthorization.test.tscovering all major scenariosmultisig.test.tsfor coordinated multisig authorizationshttps://claude.ai/code/session_011m6WzEXC4aBoYHHxaU7X9X