feat(adapter-evm-core): add hasIdentityKeyPurpose IRS read for saga resume - #66
Merged
Merged
Conversation
…esume Expose a declared key-purpose probe matching getFactoryIdentity semantics: has / lacks / read_failed (transport failures never collapse into lacks). Implements the IRSCapability method declared ahead of publication in openzeppelin-ui PR #202. Merge ui-types #202 before this adapters release. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a declared, saga-safe IRS key-purpose read:
hasIdentityKeyPurpose.What
Before this change, the only key-purpose probe was internal
identityKeyHasPurpose, which awaitsreadContractwith no try/catch. A transport failure propagates as a raw throw. There was no declared read a consumer can safely branch on when resuming a partially completed onboard.This PR adds
lookupIdentityKeyPurpose(reader) and exposeshasIdentityKeyPurposeonEvmIRSCapability, matching thegetFactoryIdentityconvention (found/not_found/read_failed→ herehas/lacks/read_failed).Why it matters
A consumer wrapping the internal probe naively (
catch→ treat aslacks) will re-attemptgrantHolderManagementKey.addKeyreverts on duplicate purpose — that is the orphan trap.This week, that exact defect family — an RPC error collapsed into a negative answer — stranded three Sepolia identities that could not be re-onboarded. The three-way union is not over-engineering; it is the minimum surface that prevents a fourth address landing in the same state.
read_failedis a value, never an exception and neverlacks. Tests assert this explicitly:Ordering with openzeppelin-ui PR #202
openzeppelin-ui PR #202 declares
hasIdentityKeyPurposeonIRSCapabilityin@openzeppelin/ui-typesahead of this implementation publishing. A reviewer seeing a declared-but-not-yet-shipped method should read that as intentional contract-first sequencing, not drift.Release coordination (important): Once #202 publishes,
IRSCapabilitywill requirehasIdentityKeyPurposewhile published@openzeppelin/adapter-evm2.4.0 does not implement it. Consumers on a caretui-typesrange could type-check cleanly against a method the installed runtime lacks and crash at call time. The adapter itself avoids a compile break in that window viaas unknown as EvmIRSCapabilityatcapabilities/irs.ts:106— that cast papers over the gap for this repo's build, not for downstream apps. This adapters release should land before or with the ui-types publish, not after.Red-first caveat (honest)
The new tests fail on
origin/mainbecause the API is additive (6/6TypeError: … is not a function) — a weaker RED than a behavioural failure on pre-existing code. The behavioural guarantee is pinned by the explicitnot.toEqual({ status: 'lacks' })assertion on RPC failure, not by catching a pre-existing wrong return value. Evidence:scratchpad/key-purpose-evidence.md(internal).Semver
Minor (
@openzeppelin/adapter-evm) — additive capability read consumed by SC009 saga resume.Test plan
pnpm --filter @openzeppelin/adapter-evm-core typecheck lint test buildpnpm --filter @openzeppelin/adapter-evm typecheck testorigin/mainsrc (zero false greens); 6/6 pass with implementationMade with Cursor