1234567891011121314151617import {expect} from 'chai';18import {IKeyringPair} from '@polkadot/types/types';19import {EthUniqueHelper, itEth, usingEthPlaygrounds} from './util';20import {TCollectionMode} from '../util/playgrounds/types';21import {Pallets, requirePalletsOrSkip} from '../util';2223let donor: IKeyringPair;24 25before(async function () {26 await usingEthPlaygrounds(async (_helper, privateKey) => {27 donor = await privateKey({filename: __filename});28 });29});3031async function testCollectionCreatedAndDestroy(helper: EthUniqueHelper, mode: TCollectionMode) {32 const owner = await helper.eth.createAccountWithBalance(donor);33 const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['CollectionCreated', 'CollectionDestroyed']}]);34 const {collectionAddress, events: ethEvents} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');35 await helper.wait.newBlocks(1);36 {37 expect(ethEvents).to.be.like([38 {39 event: 'CollectionCreated',40 args: {41 owner: owner,42 collectionId: collectionAddress,43 },44 },45 ]);46 expect(subEvents).to.be.like([{method: 'CollectionCreated'}]);47 ethEvents.pop();48 subEvents.pop();49 }50 {51 const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);52 const result = await collectionHelper.methods.destroyCollection(collectionAddress).send({from:owner});53 await helper.wait.newBlocks(1);54 expect(result.events).to.be.like({55 CollectionDestroyed: {56 returnValues: {57 collectionId: collectionAddress,58 },59 },60 });61 expect(subEvents).to.be.like([{method: 'CollectionDestroyed'}]);62 }63 unsubscribe();64}6566async function testCollectionPropertySetAndCollectionPropertyDeleted(helper: EthUniqueHelper, mode: TCollectionMode) {67 const owner = await helper.eth.createAccountWithBalance(donor);68 const {collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');69 const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);70 const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);71 72 const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['CollectionPropertySet', 'CollectionPropertyDeleted']}]);73 {74 const ethEvents: any = [];75 collectionHelper.events.allEvents((_: any, event: any) => {76 ethEvents.push(event);77 });78 await collection.methods.setCollectionProperties([{key: 'A', value: [0,1,2,3]}]).send({from:owner});79 await helper.wait.newBlocks(1);80 expect(ethEvents).to.be.like([81 {82 event: 'CollectionChanged',83 returnValues: {84 collectionId: collectionAddress,85 },86 },87 ]);88 expect(subEvents).to.be.like([{method: 'CollectionPropertySet'}]);89 subEvents.pop();90 }91 {92 const ethEvents: any = [];93 collectionHelper.events.allEvents((_: any, event: any) => {94 ethEvents.push(event);95 });96 await collection.methods.deleteCollectionProperties(['A']).send({from:owner});97 await helper.wait.newBlocks(1);98 expect(ethEvents).to.be.like([99 {100 event: 'CollectionChanged',101 returnValues: {102 collectionId: collectionAddress,103 },104 },105 ]);106 expect(subEvents).to.be.like([{method: 'CollectionPropertyDeleted'}]);107 }108 unsubscribe();109}110111async function testPropertyPermissionSet(helper: EthUniqueHelper, mode: TCollectionMode) {112 const owner = await helper.eth.createAccountWithBalance(donor);113 const {collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');114 const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);115 const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);116 const eethEvents: any = [];117 collectionHelper.events.allEvents((_: any, event: any) => {118 eethEvents.push(event);119 });120 const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['PropertyPermissionSet']}]);121 await collection.methods.setTokenPropertyPermission('testKey', true, true, true).send({from: owner});122 await helper.wait.newBlocks(1);123 expect(eethEvents).to.be.like([124 {125 event: 'CollectionChanged',126 returnValues: {127 collectionId: collectionAddress,128 },129 },130 ]);131 expect(subEvents).to.be.like([{method: 'PropertyPermissionSet'}]);132 unsubscribe();133}134135async function testAllowListAddressAddedAndAllowListAddressRemoved(helper: EthUniqueHelper, mode: TCollectionMode) {136 const owner = await helper.eth.createAccountWithBalance(donor);137 const user = helper.ethCrossAccount.createAccount();138 const {collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');139 const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);140 const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);141 const ethEvents: any[] = [];142 collectionHelper.events.allEvents((_: any, event: any) => {143 ethEvents.push(event);144 });145146 const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['AllowListAddressAdded', 'AllowListAddressRemoved']}]);147 {148 await collection.methods.addToCollectionAllowListCross(user).send({from: owner});149 await helper.wait.newBlocks(1);150 expect(ethEvents).to.be.like([151 {152 event: 'CollectionChanged',153 returnValues: {154 collectionId: collectionAddress,155 },156 },157 ]);158 expect(subEvents).to.be.like([{method: 'AllowListAddressAdded'}]);159 ethEvents.pop();160 subEvents.pop();161 }162 {163 await collection.methods.removeFromCollectionAllowListCross(user).send({from: owner});164 await helper.wait.newBlocks(1);165 expect(ethEvents.length).to.be.eq(1);166 expect(ethEvents).to.be.like([167 {168 event: 'CollectionChanged',169 returnValues: {170 collectionId: collectionAddress,171 },172 },173 ]);174 expect(subEvents).to.be.like([{method: 'AllowListAddressRemoved'}]);175 }176 unsubscribe();177}178179async function testCollectionAdminAddedAndCollectionAdminRemoved(helper: EthUniqueHelper, mode: TCollectionMode) {180 const owner = await helper.eth.createAccountWithBalance(donor);181 const user = helper.ethCrossAccount.createAccount();182 const {collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');183 const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);184 const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);185 const ethEvents: any = [];186 collectionHelper.events.allEvents((_: any, event: any) => {187 ethEvents.push(event);188 });189 const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['CollectionAdminAdded', 'CollectionAdminRemoved']}]);190 {191 await collection.methods.addCollectionAdminCross(user).send({from: owner});192 await helper.wait.newBlocks(1);193 expect(ethEvents).to.be.like([194 {195 event: 'CollectionChanged',196 returnValues: {197 collectionId: collectionAddress,198 },199 },200 ]);201 expect(subEvents).to.be.like([{method: 'CollectionAdminAdded'}]);202 ethEvents.pop();203 subEvents.pop();204 }205 {206 await collection.methods.removeCollectionAdminCross(user).send({from: owner});207 await helper.wait.newBlocks(1);208 expect(ethEvents).to.be.like([209 {210 event: 'CollectionChanged',211 returnValues: {212 collectionId: collectionAddress,213 },214 },215 ]);216 expect(subEvents).to.be.like([{method: 'CollectionAdminRemoved'}]);217 }218 unsubscribe();219}220221async function testCollectionLimitSet(helper: EthUniqueHelper, mode: TCollectionMode) {222 const owner = await helper.eth.createAccountWithBalance(donor);223 const {collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');224 const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);225 const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);226 const ethEvents: any = [];227 collectionHelper.events.allEvents((_: any, event: any) => {228 ethEvents.push(event);229 });230 const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['CollectionLimitSet']}]);231 {232 await collection.methods.setCollectionLimit('ownerCanTransfer', 0n).send({from: owner});233 await helper.wait.newBlocks(1);234 expect(ethEvents).to.be.like([235 {236 event: 'CollectionChanged',237 returnValues: {238 collectionId: collectionAddress,239 },240 },241 ]);242 expect(subEvents).to.be.like([{method: 'CollectionLimitSet'}]);243 }244 unsubscribe();245}246247async function testCollectionOwnedChanged(helper: EthUniqueHelper, mode: TCollectionMode) {248 const owner = await helper.eth.createAccountWithBalance(donor);249 const new_owner = helper.ethCrossAccount.createAccount();250 const {collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');251 const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);252 const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);253 const ethEvents: any = [];254 collectionHelper.events.allEvents((_: any, event: any) => {255 ethEvents.push(event);256 });257 const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['CollectionOwnerChanged']}]);258 {259 await collection.methods.changeCollectionOwnerCross(new_owner).send({from: owner});260 await helper.wait.newBlocks(1);261 expect(ethEvents).to.be.like([262 {263 event: 'CollectionChanged',264 returnValues: {265 collectionId: collectionAddress,266 },267 },268 ]);269 expect(subEvents).to.be.like([{method: 'CollectionOwnerChanged'}]);270 }271 unsubscribe();272}273274async function testCollectionPermissionSet(helper: EthUniqueHelper, mode: TCollectionMode) {275 const owner = await helper.eth.createAccountWithBalance(donor);276 const {collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');277 const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);278 const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);279 const ethEvents: any = [];280 collectionHelper.events.allEvents((_: any, event: any) => {281 ethEvents.push(event);282 });283 const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['CollectionPermissionSet']}]);284 {285 await collection.methods.setCollectionMintMode(true).send({from: owner});286 await helper.wait.newBlocks(1);287 expect(ethEvents).to.be.like([288 {289 event: 'CollectionChanged',290 returnValues: {291 collectionId: collectionAddress,292 },293 },294 ]);295 expect(subEvents).to.be.like([{method: 'CollectionPermissionSet'}]);296 ethEvents.pop();297 subEvents.pop();298 }299 {300 await collection.methods.setCollectionAccess(1).send({from: owner});301 await helper.wait.newBlocks(1);302 expect(ethEvents).to.be.like([303 {304 event: 'CollectionChanged',305 returnValues: {306 collectionId: collectionAddress,307 },308 },309 ]);310 expect(subEvents).to.be.like([{method: 'CollectionPermissionSet'}]);311 }312 unsubscribe();313}314315async function testCollectionSponsorSetAndSponsorshipConfirmedAndCollectionSponsorRemoved(helper: EthUniqueHelper, mode: TCollectionMode) {316 const owner = await helper.eth.createAccountWithBalance(donor);317 const sponsor = await helper.ethCrossAccount.createAccountWithBalance(donor);318 const {collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');319 const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);320 const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);321 const ethEvents: any = [];322 collectionHelper.events.allEvents((_: any, event: any) => {323 ethEvents.push(event);324 });325 const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{326 section: 'common', names: ['CollectionSponsorSet', 'SponsorshipConfirmed', 'CollectionSponsorRemoved',327 ]}]);328 {329 await collection.methods.setCollectionSponsorCross(sponsor).send({from: owner});330 await helper.wait.newBlocks(1);331 expect(ethEvents).to.be.like([332 {333 event: 'CollectionChanged',334 returnValues: {335 collectionId: collectionAddress,336 },337 },338 ]);339 expect(subEvents).to.be.like([{method: 'CollectionSponsorSet'}]);340 ethEvents.pop();341 subEvents.pop();342 }343 {344 await collection.methods.confirmCollectionSponsorship().send({from: sponsor.eth});345 await helper.wait.newBlocks(1);346 expect(ethEvents).to.be.like([347 {348 event: 'CollectionChanged',349 returnValues: {350 collectionId: collectionAddress,351 },352 },353 ]);354 expect(subEvents).to.be.like([{method: 'SponsorshipConfirmed'}]);355 ethEvents.pop();356 subEvents.pop();357 }358 {359 await collection.methods.removeCollectionSponsor().send({from: owner});360 await helper.wait.newBlocks(1);361 expect(ethEvents).to.be.like([362 {363 event: 'CollectionChanged',364 returnValues: {365 collectionId: collectionAddress,366 },367 },368 ]);369 expect(subEvents).to.be.like([{method: 'CollectionSponsorRemoved'}]);370 }371 unsubscribe();372}373374async function testTokenPropertySetAndTokenPropertyDeleted(helper: EthUniqueHelper, mode: TCollectionMode) {375 const owner = await helper.eth.createAccountWithBalance(donor);376 const {collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');377 const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);378 const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);379 const result = await collection.methods.mint(owner).send({from: owner});380 const tokenId = result.events.Transfer.returnValues.tokenId;381 await collection.methods.setTokenPropertyPermission('A', true, true, true).send({from: owner});382383384 const ethEvents: any = [];385 collectionHelper.events.allEvents((_: any, event: any) => {386 ethEvents.push(event);387 });388 const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['TokenPropertySet', 'TokenPropertyDeleted']}]);389 {390 await collection.methods.setProperties(tokenId, [{key: 'A', value: [1,2,3]}]).send({from: owner});391 await helper.wait.newBlocks(1);392 expect(ethEvents).to.be.like([393 {394 event: 'TokenChanged',395 returnValues: {396 collectionId: collectionAddress,397 },398 },399 ]);400 expect(subEvents).to.be.like([{method: 'TokenPropertySet'}]);401 ethEvents.pop();402 subEvents.pop();403 }404 {405 await collection.methods.deleteProperties(tokenId, ['A']).send({from: owner});406 await helper.wait.newBlocks(1);407 expect(ethEvents).to.be.like([408 {409 event: 'TokenChanged',410 returnValues: {411 collectionId: collectionAddress,412 },413 },414 ]);415 expect(subEvents).to.be.like([{method: 'TokenPropertyDeleted'}]);416 }417 unsubscribe();418}419420describe('[FT] Sync sub & eth events', () => {421 const mode: TCollectionMode = 'ft';422423 itEth('CollectionCreated and CollectionDestroyed events', async ({helper}) => {424 await testCollectionCreatedAndDestroy(helper, mode);425 });426427 itEth('CollectionChanged event for CollectionPropertySet and CollectionPropertyDeleted', async ({helper}) => {428 await testCollectionPropertySetAndCollectionPropertyDeleted(helper, mode);429 });430 431 itEth('CollectionChanged event for AllowListAddressAdded, AllowListAddressRemoved', async ({helper}) => {432 await testAllowListAddressAddedAndAllowListAddressRemoved(helper, mode);433 });434 435 itEth('CollectionChanged event for CollectionAdminAdded, CollectionAdminRemoved', async ({helper}) => {436 await testCollectionAdminAddedAndCollectionAdminRemoved(helper, mode);437 });438 439 itEth('CollectionChanged event for CollectionLimitSet', async ({helper}) => {440 await testCollectionLimitSet(helper, mode);441 });442 443 itEth('CollectionChanged event for CollectionOwnerChanged', async ({helper}) => {444 await testCollectionOwnedChanged(helper, mode);445 });446 447 itEth('CollectionChanged event for CollectionPermissionSet', async ({helper}) => {448 await testCollectionPermissionSet(helper, mode);449 });450451 itEth('CollectionChanged event for CollectionSponsorSet, SponsorshipConfirmed, CollectionSponsorRemoved', async ({helper}) => {452 await testCollectionSponsorSetAndSponsorshipConfirmedAndCollectionSponsorRemoved(helper, mode);453 });454});455456describe('[NFT] Sync sub & eth events', () => {457 const mode: TCollectionMode = 'nft';458459 itEth('CollectionCreated and CollectionDestroyed events', async ({helper}) => {460 await testCollectionCreatedAndDestroy(helper, mode);461 });462463 itEth('CollectionChanged event for CollectionPropertySet and CollectionPropertyDeleted', async ({helper}) => {464 await testCollectionPropertySetAndCollectionPropertyDeleted(helper, mode);465 });466 467 itEth('CollectionChanged event for PropertyPermissionSet', async ({helper}) => {468 await testPropertyPermissionSet(helper, mode);469 });470 471 itEth('CollectionChanged event for AllowListAddressAdded, AllowListAddressRemoved', async ({helper}) => {472 await testAllowListAddressAddedAndAllowListAddressRemoved(helper, mode);473 });474 475 itEth('CollectionChanged event for CollectionAdminAdded, CollectionAdminRemoved', async ({helper}) => {476 await testCollectionAdminAddedAndCollectionAdminRemoved(helper, mode);477 });478 479 itEth('CollectionChanged event for CollectionLimitSet', async ({helper}) => {480 await testCollectionLimitSet(helper, mode);481 });482 483 itEth('CollectionChanged event for CollectionOwnerChanged', async ({helper}) => {484 await testCollectionOwnedChanged(helper, mode);485 });486 487 itEth('CollectionChanged event for CollectionPermissionSet', async ({helper}) => {488 await testCollectionPermissionSet(helper, mode);489 });490491 itEth('CollectionChanged event for CollectionSponsorSet, SponsorshipConfirmed, CollectionSponsorRemoved', async ({helper}) => {492 await testCollectionSponsorSetAndSponsorshipConfirmedAndCollectionSponsorRemoved(helper, mode);493 });494 495 itEth('CollectionChanged event for TokenPropertySet, TokenPropertyDeleted', async ({helper}) => {496 await testTokenPropertySetAndTokenPropertyDeleted(helper, mode);497 });498});499500describe('[RFT] Sync sub & eth events', () => {501 const mode: TCollectionMode = 'rft';502503 before(async function() {504 await usingEthPlaygrounds(async (helper, privateKey) => {505 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);506 const _donor = await privateKey({filename: __filename});507 });508 });509510 itEth('CollectionCreated and CollectionDestroyed events', async ({helper}) => {511 await testCollectionCreatedAndDestroy(helper, mode);512 });513514 itEth('CollectionChanged event for CollectionPropertySet and CollectionPropertyDeleted', async ({helper}) => {515 await testCollectionPropertySetAndCollectionPropertyDeleted(helper, mode);516 });517 518 itEth('CollectionChanged event for PropertyPermissionSet', async ({helper}) => {519 await testPropertyPermissionSet(helper, mode);520 });521 522 itEth('CollectionChanged event for AllowListAddressAdded, AllowListAddressRemoved', async ({helper}) => {523 await testAllowListAddressAddedAndAllowListAddressRemoved(helper, mode);524 });525 526 itEth('CollectionChanged event for CollectionAdminAdded, CollectionAdminRemoved', async ({helper}) => {527 await testCollectionAdminAddedAndCollectionAdminRemoved(helper, mode);528 });529 530 itEth('CollectionChanged event for CollectionLimitSet', async ({helper}) => {531 await testCollectionLimitSet(helper, mode);532 });533 534 itEth('CollectionChanged event for CollectionOwnerChanged', async ({helper}) => {535 await testCollectionOwnedChanged(helper, mode);536 });537 538 itEth('CollectionChanged event for CollectionPermissionSet', async ({helper}) => {539 await testCollectionPermissionSet(helper, mode);540 });541542 itEth('CollectionChanged event for CollectionSponsorSet, SponsorshipConfirmed, CollectionSponsorRemoved', async ({helper}) => {543 await testCollectionSponsorSetAndSponsorshipConfirmedAndCollectionSponsorRemoved(helper, mode);544 });545 546 itEth('CollectionChanged event for TokenPropertySet, TokenPropertyDeleted', async ({helper}) => {547 await testTokenPropertySetAndTokenPropertyDeleted(helper, mode);548 });549});