pallet-scarcity: coinage-style NFT ownership with feeless rest-time-prioritized transfers - #12730
pallet-scarcity: coinage-style NFT ownership with feeless rest-time-prioritized transfers#12730shawntabrizi wants to merge 10 commits into
Conversation
|
Pushed two design updates from downstream review: Metadata is now a two-level mutable key/value store. The item definition's separate Metadata lives in its own storage maps rather than on the definition, chiefly for PoV: in-struct, a full metadata set (~9 KB at these bounds) would be pulled into the proof by every operation touching the definition, including The 39 tests / 47 with Note |
Ports a downstream fix that had not reached this branch: an instance is backed by NftsByOwner, the Instances reverse index, and its own InstanceDeposits ticket — the footprint counted two, and omitted the instance key and ticket size. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…act-level [codex]
Summary
A new FRAME pallet for Scarcity collectibles (Parity's gaming/Trinity initiative): NFT-like instances under a coinage-style ownership model — one instance per fresh, balance-less purse public key — with feeless transfers authorized by the purse key itself through a
TransactionExtension, prioritized by the instance's rest time (seconds since it last moved).Draft: seeking directional review on the transaction-extension approach and priority calibration before polish (benchmarks are placeholder weights).
Model
Collection → ItemDefinition → instance: item definitions are immutable once written (typed, on-chain-comparableStatpairs + an opaque metadata blob;Kind/next_varianttagging for a later fusion mechanic). The same definition can be minted many times; each copy is a discrete instance with a permanentInstanceId.NftsByOwner: Map<AccountId, Nft>plus a stable reverse indexInstances: Map<InstanceId, AccountId>. Wallets derive a fresh key per instance from the root secret; instance identity (not key identity) is the stable external handle.InstanceId.The
AsScarcitytransaction extensionMirrors the origin-modifier pattern (validate → elevate a custom
Origin::Nft { owner, nft }→ consume the instance inprepare→ restore + quadratic backoff lock on failed dispatch):SignedbeforeCheckNonce/payment run — purse keys need neither nonce nor balance.min(now − last_moved, cap): recently-moved instances sink under congestion; rested ones rise. This is the anti-spam for free transfers (a per-instance wall-clock rate limit).providespool tag + transaction mortality + failure locks; destination pre-validation at the pool keeps user error from reaching dispatch.movescounter on each instance serves as the authorization epoch for future detached-signature flows.Testing
21 unit tests, including direct
validate/prepare/post_dispatch_detailspipeline coverage: priority scaling + cap, same-block double-use, restore-and-lock on failed dispatch with quadratic backoff, pool-side rejections (side-effect-free), one-instance-per-key on both mint and transfer, reverse-index consistency, item-definition immutability.Deliberately out of scope here
Claim/distribution (a separate ring-membership-based pallet downstream), fusion, burn, storage deposits (companion allowance systems), benchmarking (placeholder
WeightInfo), and runtime integration (to follow; requires the origin-modifier placement noted above).🤖 Generated with Claude Code