git.delta.rocks / unique-network / refs/commits / b1fdfb5da5b7

difftreelog

wip migrating confirmSponsorship

rkv2022-09-09parent: #ad65cb1.patch.diff
in: master

2 files changed

modifiedtests/package.jsondiffbeforeafterboth
--- a/tests/package.json
+++ b/tests/package.json
@@ -44,6 +44,7 @@
     "testAddCollectionAdmin": "mocha --timeout 9999999 -r ts-node/register ./**/addCollectionAdmin.test.ts",
     "testSetSchemaVersion": "mocha --timeout 9999999 -r ts-node/register ./**/setSchemaVersion.test.ts",
     "testSetCollectionLimits": "mocha --timeout 9999999 -r ts-node/register ./**/setCollectionLimits.test.ts",
+    "testChangeCollectionOwner": "mocha --timeout 9999999 -r ts-node/register ./**/change-collection-owner.test.ts",
     "testSetCollectionSponsor": "mocha --timeout 9999999 -r ts-node/register ./**/setCollectionSponsor.test.ts",
     "testConfirmSponsorship": "mocha --timeout 9999999 -r ts-node/register ./**/confirmSponsorship.test.ts",
     "testRemoveCollectionAdmin": "mocha --timeout 9999999 -r ts-node/register ./**/removeCollectionAdmin.test.ts",
modifiedtests/src/confirmSponsorship.test.tsdiffbeforeafterboth
37 Pallets,37 Pallets,
38} from './util/helpers';38} from './util/helpers';
39import {IKeyringPair} from '@polkadot/types/types';39import {IKeyringPair} from '@polkadot/types/types';
40import {usingPlaygrounds} from './util/playgrounds';
4041
41chai.use(chaiAsPromised);42chai.use(chaiAsPromised);
42const expect = chai.expect;43const expect = chai.expect;
4344
45let donor: IKeyringPair;
46
47before(async () => {
48 await usingPlaygrounds(async (_, privateKey) => {
49 donor = privateKey('//Alice');
50 });
51});
52
44let alice: IKeyringPair;53let alice: IKeyringPair;
45let bob: IKeyringPair;54let bob: IKeyringPair;
46let charlie: IKeyringPair;55let charlie: IKeyringPair;
4756
48describe('integration test: ext. confirmSponsorship():', () => {57describe('integration test: ext. confirmSponsorship():', () => {
4958
50 before(async () => {59 before(async () => {
51 await usingApi(async (api, privateKeyWrapper) => {60 await usingPlaygrounds(async (helper) => {
52 alice = privateKeyWrapper('//Alice');61 [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 0n], donor);
53 bob = privateKeyWrapper('//Bob');
54 charlie = privateKeyWrapper('//Charlie');
55 });62 });
56 });63 });
5764
58 it('Confirm collection sponsorship', async () => {65 it('Confirm collection sponsorship', async () => {
59 const collectionId = await createCollectionExpectSuccess();66 await usingPlaygrounds(async (helper) => {
67 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
60 await setCollectionSponsorExpectSuccess(collectionId, bob.address);68 await collection.setSponsor(alice, bob.address);
61 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');69 await collection.confirmSponsorship(bob);
70 });
62 });71 });
72
63 it('Add sponsor to a collection after the same sponsor was already added and confirmed', async () => {73 it('Add sponsor to a collection after the same sponsor was already added and confirmed', async () => {
64 const collectionId = await createCollectionExpectSuccess();74 await usingPlaygrounds(async (helper) => {
75 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
65 await setCollectionSponsorExpectSuccess(collectionId, bob.address);76 await collection.setSponsor(alice, bob.address);
66 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');77 await collection.confirmSponsorship(bob);
67 await setCollectionSponsorExpectSuccess(collectionId, bob.address);78 await collection.setSponsor(alice, bob.address);
79 });
68 });80 });
69 it('Add new sponsor to a collection after another sponsor was already added and confirmed', async () => {81 it('Add new sponsor to a collection after another sponsor was already added and confirmed', async () => {
70 const collectionId = await createCollectionExpectSuccess();82 await usingPlaygrounds(async (helper) => {
83 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
71 await setCollectionSponsorExpectSuccess(collectionId, bob.address);84 await collection.setSponsor(alice, bob.address);
72 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');85 await collection.confirmSponsorship(charlie);
73 await setCollectionSponsorExpectSuccess(collectionId, charlie.address);86 });
74 });87 });
7588
76 it('NFT: Transfer fees are paid by the sponsor after confirmation', async () => {89 it('NFT: Transfer fees are paid by the sponsor after confirmation', async () => {
77 const collectionId = await createCollectionExpectSuccess();90 await usingPlaygrounds(async (helper) => {
78 await setCollectionSponsorExpectSuccess(collectionId, bob.address);
79 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
80
81 await usingApi(async (api, privateKeyWrapper) => {
82 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();91 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
83
84 // Find unused address
85 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);
86
87 // Mint token for unused address92 await collection.setSponsor(alice, bob.address);
88 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', zeroBalance.address);
89
90 // Transfer this tokens from unused address to Alice93 await collection.confirmSponsorship(bob);
91 const zeroToAlice = api.tx.unique.transfer(normalizeAccountId(zeroBalance.address), collectionId, itemId, 0);94 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);
92 const events = await submitTransactionAsync(zeroBalance, zeroToAlice);95 const token = await collection.mintToken(alice, {Substrate: charlie.address});
93 const result = getGenericResult(events);96 await token.transfer(charlie, {Substrate: alice.address});
94 expect(result.success).to.be.true;
95
96 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();97 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);
97
98 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;98 expect(bobBalanceAfter < bobBalanceBefore).to.be.true;
99 });99 });
100
101 });100 });
102101
103 it('Fungible: Transfer fees are paid by the sponsor after confirmation', async () => {102 it('Fungible: Transfer fees are paid by the sponsor after confirmation', async () => {
104 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});103 await usingPlaygrounds(async (helper) => {
105 await setCollectionSponsorExpectSuccess(collectionId, bob.address);
106 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
107
108 await usingApi(async (api, privateKeyWrapper) => {
109 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();104 const collection = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);
110
111 // Find unused address
112 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);
113
114 // Mint token for unused address105 await collection.setSponsor(alice, bob.address);
115 const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', zeroBalance.address);
116
117 // Transfer this tokens from unused address to Alice106 await collection.confirmSponsorship(bob);
118 const zeroToAlice = api.tx.unique.transfer(normalizeAccountId(zeroBalance.address), collectionId, itemId, 1);107 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);
119 const events1 = await submitTransactionAsync(zeroBalance, zeroToAlice);108 await collection.mint(alice, {Substrate: charlie.address}, 100n);
120 const result1 = getGenericResult(events1);109 await collection.transfer(charlie, {Substrate: alice.address}, 1n);
121 expect(result1.success).to.be.true;
122
123 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();110 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);
124
125 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;111 expect(bobBalanceAfter < bobBalanceBefore).to.be.true;
126 });112 });
127 });113 });
128114
129 it('ReFungible: Transfer fees are paid by the sponsor after confirmation', async function() {115 it('ReFungible: Transfer fees are paid by the sponsor after confirmation', async function() {
130 await requirePallets(this, [Pallets.ReFungible]);116 await usingPlaygrounds(async (helper) => {
131
132 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});117 const collection = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
133 await setCollectionSponsorExpectSuccess(collectionId, bob.address);118 await collection.setSponsor(alice, bob.address);
134 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');119 await collection.confirmSponsorship(bob);
135
136 await usingApi(async (api, privateKeyWrapper) => {
137 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();120 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);
138
139 // Find unused address121 const token = await collection.mintToken(alice, {Substrate: charlie.address}, 100n);
140 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);
141
142 // Mint token for unused address
143 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', zeroBalance.address);
144
145 // Transfer this tokens from unused address to Alice122 await token.transfer(charlie, {Substrate: alice.address}, 1n);
146 const zeroToAlice = api.tx.unique.transfer(normalizeAccountId(zeroBalance.address), collectionId, itemId, 1);
147 const events1 = await submitTransactionAsync(zeroBalance, zeroToAlice);123 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);
148 const result1 = getGenericResult(events1);
149
150 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();
151
152 expect(result1.success).to.be.true;
153 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;124 expect(bobBalanceAfter < bobBalanceBefore).to.be.true;
154 });125 });
155 });126 });
156127
157 it('CreateItem fees are paid by the sponsor after confirmation', async () => {128 it('CreateItem fees are paid by the sponsor after confirmation', async () => {
158 const collectionId = await createCollectionExpectSuccess();129 await usingPlaygrounds(async (helper) => {
130 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
159 await setCollectionSponsorExpectSuccess(collectionId, bob.address);131 await collection.setSponsor(alice, bob.address);
160 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');132 await collection.confirmSponsorship(bob);
133 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
134 await collection.addToAllowList(alice, {Substrate: charlie.address});
161135
162 // Enable collection allow list136 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);
163 await enableAllowListExpectSuccess(alice, collectionId);137 await collection.mintToken(charlie, {Substrate: charlie.address});
138 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);
164139
165 // Enable public minting140 expect(bobBalanceAfter < bobBalanceBefore).to.be.true;
166 await enablePublicMintingExpectSuccess(alice, collectionId);
167
168 // Create Item
169 await usingApi(async (api, privateKeyWrapper) => {
170 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
171
172 // Find unused address
173 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);
174
175 // Add zeroBalance address to allow list
176 await addToAllowListExpectSuccess(alice, collectionId, zeroBalance.address);
177
178 // Mint token using unused address as signer
179 await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address);
180
181 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();
182
183 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;
184 });141 });
185 });142 });
186143
187 it('NFT: Sponsoring of transfers is rate limited', async () => {144 it('NFT: Sponsoring of transfers is rate limited', async () => {
188 const collectionId = await createCollectionExpectSuccess();145 await usingPlaygrounds(async (helper) => {
146 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
189 await setCollectionSponsorExpectSuccess(collectionId, bob.address);147 await collection.setSponsor(alice, bob.address);
190 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');148 await collection.confirmSponsorship(bob);
191149
192 await usingApi(async (api, privateKeyWrapper) => {150 const token = await collection.mintToken(alice, {Substrate: alice.address});
193 // Find unused address151 await token.transfer(alice, {Substrate: charlie.address});
194 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);152 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);
195153
196 // Mint token for alice154 const transferTx = async () => token.transfer(charlie, {Substrate: alice.address});
197 const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);155 await expect(transferTx()).to.be.rejectedWith('Inability to pay some fees');
156 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);
198157
199 // Transfer this token from Alice to unused address and back158 expect(bobBalanceAfter === bobBalanceBefore).to.be.true;
200 // Alice to Zero gets sponsored
201 const aliceToZero = api.tx.unique.transfer(normalizeAccountId(zeroBalance.address), collectionId, itemId, 0);
202 const events1 = await submitTransactionAsync(alice, aliceToZero);
203 const result1 = getGenericResult(events1);
204
205 // Second transfer should fail
206 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
207 const zeroToAlice = api.tx.unique.transfer(normalizeAccountId(alice.address), collectionId, itemId, 0);
208 const badTransaction = async function () {
209 await submitTransactionExpectFailAsync(zeroBalance, zeroToAlice);
210 };
211 await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees');
212 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();
213
214 // Try again after Zero gets some balance - now it should succeed
215 const balancetx = api.tx.balances.transfer(zeroBalance.address, 1n * UNIQUE);
216 await submitTransactionAsync(alice, balancetx);
217 const events2 = await submitTransactionAsync(zeroBalance, zeroToAlice);
218 const result2 = getGenericResult(events2);
219
220 expect(result1.success).to.be.true;
221 expect(result2.success).to.be.true;
222 expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);
223 });159 });
224 });160 });
225161
226 it('Fungible: Sponsoring is rate limited', async () => {162 it('Fungible: Sponsoring is rate limited', async () => {
227 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});163 await usingPlaygrounds(async (helper) => {
164 const collection = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
228 await setCollectionSponsorExpectSuccess(collectionId, bob.address);165 await collection.setSponsor(alice, bob.address);
229 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');166 await collection.confirmSponsorship(bob);
230167
231 await usingApi(async (api, privateKeyWrapper) => {168 await collection.mint(alice, {Substrate: charlie.address}, 100n);
232 // Find unused address169 await collection.transfer(charlie, {Substrate: charlie.address}, 1n);
233 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);170 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);
234171
235 // Mint token for unused address172 const transferTx = async () => collection.transfer(charlie, {Substrate: charlie.address});
236 const itemId = await createItemExpectSuccess(alice, collectionId, 'Fungible', zeroBalance.address);173 await expect(transferTx()).to.be.rejected;
174 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);
237175
238 // Transfer this tokens in parts from unused address to Alice176 expect(bobBalanceAfter === bobBalanceBefore).to.be.true;
239 const zeroToAlice = api.tx.unique.transfer(normalizeAccountId(zeroBalance.address), collectionId, itemId, 1);
240 const events1 = await submitTransactionAsync(zeroBalance, zeroToAlice);
241 const result1 = getGenericResult(events1);
242 expect(result1.success).to.be.true;
243
244 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
245 await expect(submitTransactionExpectFailAsync(zeroBalance, zeroToAlice)).to.be.rejected;
246 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();
247
248 // Try again after Zero gets some balance - now it should succeed
249 const balancetx = api.tx.balances.transfer(zeroBalance.address, 1n * UNIQUE);
250 await submitTransactionAsync(alice, balancetx);
251 const events2 = await submitTransactionAsync(zeroBalance, zeroToAlice);
252 const result2 = getGenericResult(events2);
253 expect(result2.success).to.be.true;
254
255 expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);
256 });177 });
257 });178 });
258179
259 it('ReFungible: Sponsoring is rate limited', async function() {180 it('ReFungible: Sponsoring is rate limited', async function() {
260 await requirePallets(this, [Pallets.ReFungible]);181 await usingPlaygrounds(async (helper) => {
182 const collection = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
183 await collection.setSponsor(alice, bob.address);
184 await collection.confirmSponsorship(bob);
261185
262 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});186 const token = await collection.mintToken(alice, {Substrate: charlie.address}, 100n);
263 await setCollectionSponsorExpectSuccess(collectionId, bob.address);
264 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');187 await token.transfer(charlie, {Substrate: alice.address});
265188
266 await usingApi(async (api, privateKeyWrapper) => {189 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);
190 const transferTx = async () => token.transfer(charlie, {Substrate: alice.address});
267 // Find unused address191 await expect(transferTx()).to.be.rejectedWith('Inability to pay some fees');
268 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);192 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);
269193
270 // Mint token for alice194 expect(bobBalanceAfter === bobBalanceBefore).to.be.true;
271 const itemId = await createItemExpectSuccess(alice, collectionId, 'ReFungible', zeroBalance.address);
272
273 const zeroToAlice = api.tx.unique.transfer(normalizeAccountId(alice.address), collectionId, itemId, 1);
274
275 // Zero to alice gets sponsored
276 const events1 = await submitTransactionAsync(zeroBalance, zeroToAlice);
277 const result1 = getGenericResult(events1);
278 expect(result1.success).to.be.true;
279
280 // Second transfer should fail
281 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
282 await expect(submitTransactionExpectFailAsync(zeroBalance, zeroToAlice)).to.be.rejectedWith('Inability to pay some fees');
283 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();
284 expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);
285
286 // Try again after Zero gets some balance - now it should succeed
287 const balancetx = api.tx.balances.transfer(zeroBalance.address, 1n * UNIQUE);
288 await submitTransactionAsync(alice, balancetx);
289 const events2 = await submitTransactionAsync(zeroBalance, zeroToAlice);
290 const result2 = getGenericResult(events2);
291 expect(result2.success).to.be.true;
292 });195 });
293 });196 });
294197
295 it('NFT: Sponsoring of createItem is rate limited', async () => {198 it('NFT: Sponsoring of createItem is rate limited', async () => {
296 const collectionId = await createCollectionExpectSuccess();199 await usingPlaygrounds(async (helper) => {
200 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});
297 await setCollectionSponsorExpectSuccess(collectionId, bob.address);201 await collection.setSponsor(alice, bob.address);
298 await confirmSponsorshipExpectSuccess(collectionId, '//Bob');202 await collection.confirmSponsorship(bob);
203 await collection.setPermissions(alice, {mintMode: true, access: 'AllowList'});
204 await collection.addToAllowList(alice, {Substrate: charlie.address});
299205
300 // Enable collection allow list206 await collection.mintToken(charlie, {Substrate: charlie.address});
301 await enableAllowListExpectSuccess(alice, collectionId);
302207
303 // Enable public minting208 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);
304 await enablePublicMintingExpectSuccess(alice, collectionId);209 const mintTx = async () => collection.mintToken(charlie, {Substrate: charlie.address});
210 await expect(mintTx()).to.be.rejectedWith('Inability to pay some fees');
211 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);
305212
306 await usingApi(async (api, privateKeyWrapper) => {213 expect(bobBalanceAfter === bobBalanceBefore).to.be.true;
307 // Find unused address
308 const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);
309
310 // Add zeroBalance address to allow list
311 await addToAllowListExpectSuccess(alice, collectionId, zeroBalance.address);
312
313 // Mint token using unused address as signer - gets sponsored
314 await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address);
315
316 // Second mint should fail
317 const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
318
319 const badTransaction = async function () {
320 await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address);
321 };
322 await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees');
323 const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();
324
325 // Try again after Zero gets some balance - now it should succeed
326 const balancetx = api.tx.balances.transfer(zeroBalance.address, 1n * UNIQUE);
327 await submitTransactionAsync(alice, balancetx);
328 await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address);
329
330 expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);
331 });214 });
332 });215 });
333
334});216});
335217
336describe('(!negative test!) integration test: ext. confirmSponsorship():', () => {218describe('(!negative test!) integration test: ext. confirmSponsorship():', () => {