Shadow Delegation
Implement non-custodial NFT delegation using Delegate Registry v2 and the shadow delegation pattern, enforced via Yuga Labs’ ExclusiveDelegateResolver.
Last updated
Implement non-custodial NFT delegation using Delegate Registry v2 and the shadow delegation pattern, enforced via Yuga Labs’ ExclusiveDelegateResolver.
Last updated
Yuga Labs uses shadow delegation to let holders of Ape NFTs on Ethereum delegate access to a wallet on ApeChain. This allows users to verify ownership and participate in ApeChain experiences without bridging or moving their Apes.
By combining Delegate Registry v2
and ExclusiveDelegateResolver
, Yuga enables onchain delegation that’s:
Non-custodial: the NFT stays in the original wallet
Cross-chain: access is granted to a different wallet on another chain
Exclusive: only one delegate per token is valid at a time
Delegate Registry v2
provides the primitives for onchain NFT access control, forming the base layer upon which shadow delegation builds customizable, scoped, and enforceable delegation logic.
Use cases include:
Assign agents to act on behalf of wallets across chains
Enable wearables, emotes, or other metadata-bound behaviors
Grant permissions in identity systems, social graphs, or gaming avatars
Build composable avatars and modular inventories
Delegate from cold to hot wallets with restricted rights
Enable temporary, non-custodial NFT lending
Enforce execution rights on specific chains or applications
Delegate Registry v2 is an onchain registry that allows users to grant permission to other addresses to act on their behalf. It serves as a data layer, returning a boolean for whether a delegation exists.
Delegations can be scoped:
to specific tokens via checkDelegateForERC721
to particular contracts checkDelegateForContract
across all tokens and contracts checkDelegateForAll
The registry does not enforce rules like exclusivity, expiration, or precedence. It simply stores data.
ExclusiveDelegateResolver
, developed by Yuga Labs, is responsible for interpreting that data and enforcing logic.
Resolver contracts apply custom logic to interpret delegation records by answering:
"Who currently has the right to act on this token, under these rules?"
Yuga Labs’ ExclusiveDelegateResolver
is used in production (e.g. Otherside, ApeChain) to enforce exclusive, scoped, onchain delegation, letting one wallet act on behalf of another without moving the NFT.
It scans delegations scoped to a rightsNamespace
value and applies specificity rules (token > contract > all-assets
) to return the active delegate.
Shadow delegation is a design pattern that combines Delegate Registry v2
with a resolver like ExclusiveDelegateResolver
to enable non-custodial, exclusive delegation, scoped by use case and enforced onchain.
In this pattern:
Only one delegation per token (or namespace) should be valid at a time
Previous delegates must be explicitly revoked before a new one is assigned
Asset ownership remains with the original holder; no escrow or transfers
This pattern works by combining scoped delegation rights with onchain resolution logic, described in detail in the next section.
Shadow delegation follows a simple 3-step flow:
Delegate access to a token using delegateERC721()
Resolve the active delegate using ExclusiveDelegateResolver
Enforce the delegation with an onchain check (e.g. require(msg.sender == delegate)
)
The owner calls delegateERC721()
on the registry to assign a delegate for a specific NFT:
delegate
: The address receiving the delegation.
contract_
: The NFT contract address.
tokenId
: The specific token ID to delegate.
rights
: A bytes32
value representing delegation scope.
value
: Set to true
to enable, or false
to revoke.
In the shadow delegation pattern, you must scope delegation to a unique chain or application context by computing a rights
value. Use the following utility:
⚠️ Revoke Before Reassigning
Delegate Registry v2 overwrites existing records instead of appending new ones. If you're delegating to an address that was already assigned under the same rights
, first revoke the old record with value = false
.
Since ExclusiveDelegateResolver
does not track write order or timestamps, failing to revoke may result in the wrong delegate being resolved.
Once delegation is recorded, you can resolve it using ExclusiveDelegateResolver
, which applies namespace-based resolution logic (token > contract > all-assets) and scopes based on the first 24 bytes of the rights
field. This means a token-level delegation takes priority over a contract-level one under the same namespace.
Resolver interface:
Example usage:
This reinforces the resolver concept from Core Concept #2. The registry stores raw data and the resolver interprets it according to a rule set (in this case, exclusivity via specificity).
Whenever your application or NFT/game logic needs to check control, replace ownerOf(tokenId)
or raw ownership checks with delegation resolution:
This enforces non-custodial, exclusive access via the resolver logic, honoring only the delegate for the scoped rights.
Shadow delegation
with Delegate Registry v2
and ExclusiveDelegateResolver
enables:
Fully onchain delegation logic
Exclusive, non-custodial access
Use case-specific scoping via rightsNamespace
Developers can build on this pattern by customizing how delegations are scoped and managed, without needing to deploy their own resolver contract.
💡 Use multicall()
to Minimize UX & Gas
Apps can batch the revocation and reassignment into a single transaction using the registry’s method to reduce friction and cost.
🛠️ See It Live Yuga Labs uses this pattern in production. See how their performs explicit revocation before reassignment (lines 933–991).
Delegate Registry v2:
ApeChain Shadow Delegations:
Yuga’s Exclusive Resolver: