# Proposal: shadow accounts that can hold NFTs and prove their owner’s control

**URL:** <https://community.starknet.io/t/proposal-shadow-accounts-that-can-hold-nfts-and-prove-their-owner-s-control/116462>\
**Category:** 📜 Development Proposals\
**Created:** [November 3, 2026, 4:23pm UTC](https://community.starknet.io/t/proposal-shadow-accounts-that-can-hold-nfts-and-prove-their-owner-s-control/116462 "2026-11-03T16:23:06Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![broody](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/broody/32/85966_2.png) [@broody](https://community.starknet.io/u/broody)\
**Post date:** [November 3, 2026, 4:23pm UTC](https://community.starknet.io/t/proposal-shadow-accounts-that-can-hold-nfts-and-prove-their-owner-s-control/116462/1 "2026-11-03T16:23:06Z")

</div>

\*\*Hello, while working with shadow accounts I ran into a scenario related to NFT ownership. Proposal below, let me know what you think. Thanks.

Problem.\*\* The shadow account class exposes no `supports_interface`, so OpenZeppelin’s acceptance checks refuse every `safe_transfer_from` to a shadow and every ERC-1155 transfer or checked mint. A shadow can receive an ERC-721 only by plain `transfer_from`, and an ERC-1155 only from a contract written to skip the check. And since a shadow holds no key and answers no `is_valid_signature`, its owner can’t prove control of it, or of what it holds, without a paid private action.

**Part 1, holding: SRC-5 and the receiver interfaces.** The shadow class answers `supports_interface` for ISRC5, IERC721Receiver and IERC1155Receiver, and implements `on_erc721_received`, `on_erc1155_received` and `on_erc1155_batch_received`, each returning its interface id and keeping no state. Every standard NFT contract then delivers to shadows unchanged. Nothing about how a shadow acts changes: the pool stays its only driver.

**Part 2, proof of control: a verify-only signer.** `set_signer(key)`, reachable only through the shadow’s own run, so only its owner through a proof, stores a Stark public key; a later call rotates it. `is_valid_signature(hash, signature)` returns `'VALID'` against that key, with SRC-6’s semantics. The class offers no ` __validate__ ` or ` __execute__ ` and does not declare SRC-6: it never claims to be an account, and the key grants no execution.

**What it enables.** “This shadow holds token X” is a public read; “I control this shadow” becomes a free SNIP-12 signature that every existing verifier accepts with the shadow as signer. A shadow can also sign marketplace listings, with one on-chain approval through the pool, so private-side holdings become sellable where their contracts allow it.
