--- a/node/src/chain_spec.rs +++ b/node/src/chain_spec.rs @@ -193,8 +193,7 @@ mint_mode: false, offchain_schema: vec![], schema_version: SchemaVersion::default(), - sponsor: get_account_id_from_seed::("Alice"), - sponsor_confirmed: true, + sponsorship: SponsorshipState::Confirmed(get_account_id_from_seed::("Alice")), const_on_chain_schema: vec![], variable_on_chain_schema: vec![], limits: CollectionLimits::default() --- a/pallets/nft/src/lib.rs +++ b/pallets/nft/src/lib.rs @@ -123,6 +123,42 @@ pub fraction: u128, } +#[derive(Encode, Decode, Debug, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub enum SponsorshipState { + /// The fees are applied to the transaction sender + Disabled, + Unconfirmed(AccountId), + /// Transactions are sponsored by specified account + Confirmed(AccountId), +} + +impl SponsorshipState { + fn sponsor(&self) -> Option<&AccountId> { + match self { + Self::Confirmed(sponsor) => Some(sponsor), + _ => None, + } + } + + fn pending_sponsor(&self) -> Option<&AccountId> { + match self { + Self::Unconfirmed(sponsor) | Self::Confirmed(sponsor) => Some(sponsor), + _ => None, + } + } + + fn confirmed(&self) -> bool { + matches!(self, Self::Confirmed(_)) + } +} + +impl Default for SponsorshipState { + fn default() -> Self { + Self::Disabled + } +} + #[derive(Encode, Decode, Default, Debug, Clone, PartialEq)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct CollectionType { @@ -136,8 +172,7 @@ pub mint_mode: bool, pub offchain_schema: Vec, pub schema_version: SchemaVersion, - pub sponsor: AccountId, // Who pays fees. If set to default address, the fees are applied to the transaction sender - pub sponsor_confirmed: bool, // False if sponsor address has not yet confirmed sponsorship. True otherwise. + pub sponsorship: SponsorshipState, pub limits: CollectionLimits, // Collection private restrictions pub variable_on_chain_schema: Vec, // pub const_on_chain_schema: Vec, // @@ -665,8 +700,7 @@ token_prefix: token_prefix, offchain_schema: Vec::new(), schema_version: SchemaVersion::ImageURL, - sponsor: T::AccountId::default(), - sponsor_confirmed: false, + sponsorship: SponsorshipState::Disabled, variable_on_chain_schema: Vec::new(), const_on_chain_schema: Vec::new(), limits, @@ -922,8 +956,7 @@ let mut target_collection = >::get(collection_id); ensure!(sender == target_collection.owner, Error::::NoPermission); - target_collection.sponsor = new_sponsor; - target_collection.sponsor_confirmed = false; + target_collection.sponsorship = SponsorshipState::Unconfirmed(new_sponsor); >::insert(collection_id, target_collection); Ok(()) @@ -943,9 +976,12 @@ ensure!(>::contains_key(collection_id), Error::::CollectionNotFound); let mut target_collection = >::get(collection_id); - ensure!(sender == target_collection.sponsor, Error::::ConfirmUnsetSponsorFail); + ensure!( + target_collection.sponsorship.pending_sponsor() == Some(&sender), + Error::::ConfirmUnsetSponsorFail + ); - target_collection.sponsor_confirmed = true; + target_collection.sponsorship = SponsorshipState::Confirmed(sender); >::insert(collection_id, target_collection); Ok(()) @@ -969,8 +1005,7 @@ let mut target_collection = >::get(collection_id); ensure!(sender == target_collection.owner, Error::::NoPermission); - target_collection.sponsor = T::AccountId::default(); - target_collection.sponsor_confirmed = false; + target_collection.sponsorship = SponsorshipState::Disabled; >::insert(collection_id, target_collection); Ok(()) @@ -2485,7 +2520,9 @@ // sponsor timeout let block_number = >::block_number() as T::BlockNumber; - let limit = >::get(collection_id).limits.sponsor_transfer_timeout; + let collection = >::get(collection_id); + + let limit = collection.limits.sponsor_transfer_timeout; let mut sponsored = true; if >::contains_key((collection_id, &who)) { let last_tx_block = >::get((collection_id, &who)); @@ -2499,11 +2536,12 @@ } // check free create limit - if (>::get(collection_id).limits.sponsored_data_size >= (_properties.len() as u32)) && - (>::get(collection_id).sponsor_confirmed) && + if (collection.limits.sponsored_data_size >= (_properties.len() as u32)) && (sponsored) { - >::get(collection_id).sponsor + collection.sponsorship.sponsor() + .cloned() + .unwrap_or_default() } else { T::AccountId::default() } @@ -2511,7 +2549,7 @@ Some(Call::transfer(_new_owner, collection_id, item_id, _value)) => { let mut sponsor_transfer = false; - if >::get(collection_id).sponsor_confirmed { + if >::get(collection_id).sponsorship.confirmed() { let collection_limits = >::get(collection_id).limits; let collection_mode = >::get(collection_id).mode; @@ -2598,7 +2636,9 @@ if !sponsor_transfer { T::AccountId::default() } else { - >::get(collection_id).sponsor + >::get(collection_id).sponsorship.sponsor() + .cloned() + .unwrap_or_default() } } --- a/runtime_types.json +++ b/runtime_types.json @@ -31,6 +31,13 @@ "ConstData": "Vec", "VariableData": "Vec" }, + "SponsorshipState": { + "_enum": { + "Disabled": null, + "Unconfirmed": "AccountId", + "Confirmed": "AccountId" + } + }, "CollectionType": { "Owner": "AccountId", "Mode": "CollectionMode", @@ -42,8 +49,7 @@ "MintMode": "bool", "OffchainSchema": "Vec", "SchemaVersion": "SchemaVersion", - "Sponsor": "AccountId", - "SponsorConfirmed": "bool", + "Sponsorship": "SponsorshipState", "Limits": "CollectionLimits", "VariableOnChainSchema": "Vec", "ConstOnChainSchema": "Vec" --- a/tests/package.json +++ b/tests/package.json @@ -26,6 +26,7 @@ "testSetVariableMetaData": "mocha --timeout 9999999 -r ts-node/register ./**/setVariableMetaData.test.ts", "testSetCollectionLimits": "mocha --timeout 9999999 -r ts-node/register ./**/setCollectionLimits.test.ts", "testRemoveCollectionAdmin": "mocha --timeout 9999999 -r ts-node/register ./**/removeCollectionAdmin.test.ts", + "testRemoveCollectionSponsor": "mocha --timeout 9999999 -r ts-node/register ./**/removeCollectionSponsor.test.ts", "testRemoveFromWhiteList": "mocha --timeout 9999999 -r ts-node/register ./**/removeFromWhiteList.test.ts", "testConnection": "mocha --timeout 9999999 -r ts-node/register ./**/connection.test.ts", "testCollection": "mocha --timeout 9999999 -r ts-node/register ./**/createCollection.test.ts", --- a/tests/src/util/helpers.ts +++ b/tests/src/util/helpers.ts @@ -396,8 +396,7 @@ // What to expect expect(result.success).to.be.true; - expect(collection.Sponsor).to.be.equal(nullPublicKey); - expect(collection.SponsorConfirmed).to.be.false; + expect(collection.Sponsorship).to.be.deep.equal({ Disabled: null }); }); }