Skip to content

Commit c7b9af9

Browse files
feat: Add detailed ToS data to collection publishing (#3187)
* feat: Add detailed ToS data to colleciton publishing * fix: Include hashes when publishing standard collections as well
1 parent fe9b2bc commit c7b9af9

File tree

3 files changed

+71
-13
lines changed

3 files changed

+71
-13
lines changed

src/lib/api/builder.ts

+13-2
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,11 @@ type BaseCuration = {
205205
updated_at: Date
206206
}
207207

208+
export enum TermsOfServiceEvent {
209+
PUBLISH_COLLECTION = 'publish_collection_tos',
210+
PUBLISH_THIRD_PARTY_ITEMS = 'publish_third_party_items_tos'
211+
}
212+
208213
export type RemoteCollectionCuration = {
209214
collection_id: string
210215
assignee?: string
@@ -898,8 +903,10 @@ export class BuilderAPI extends BaseAPI {
898903
return fromRemoteCollection(remoteCollection)
899904
}
900905

901-
saveTOS = async (collection: Collection, email: string): Promise<void> => {
902-
await this.request('post', `/collections/${collection.id}/tos`, { params: { email, collection_address: collection.contractAddress } })
906+
saveTOS = async (event: TermsOfServiceEvent, collection: Collection, email: string, hashes?: string[]): Promise<void> => {
907+
await this.request('post', `/collections/${collection.id}/tos`, {
908+
params: { event, email, collection_address: collection.contractAddress, ...(hashes ? { hashes } : {}) }
909+
})
903910
}
904911

905912
lockCollection = async (collection: Collection): Promise<string> => {
@@ -1041,6 +1048,10 @@ export class BuilderAPI extends BaseAPI {
10411048
)
10421049
}
10431050

1051+
async deleteVirtualThirdParty(thirdPartId: string): Promise<void> {
1052+
await this.request('delete', `/thirdParties/${thirdPartId}`)
1053+
}
1054+
10441055
isAxiosError(error: any): error is AxiosError {
10451056
return error.isAxiosError as boolean
10461057
}

src/modules/collection/sagas.spec.ts

+48-9
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ import { ItemCuration } from 'modules/curations/itemCuration/types'
6969
import { subscribeToNewsletterRequest } from 'modules/newsletter/action'
7070
import { Cheque } from 'modules/thirdParty/types'
7171
import { CurationSortOptions, CurationStatus } from 'modules/curations/types'
72-
import { BuilderAPI, FetchCollectionsParams } from 'lib/api/builder'
72+
import { BuilderAPI, FetchCollectionsParams, TermsOfServiceEvent } from 'lib/api/builder'
7373
import { PaginatedResource, PaginationStats } from 'lib/api/pagination'
7474
import { extractThirdPartyId } from 'lib/urn'
7575
import {
@@ -903,6 +903,7 @@ describe('when executing the approval flow', () => {
903903
describe('when publishing a collection', () => {
904904
let collection: Collection
905905
let items: Item[]
906+
let itemsContentHash: string[]
906907
const email = 'email@domain.com'
907908

908909
const address = '0xa'
@@ -911,6 +912,7 @@ describe('when publishing a collection', () => {
911912
beforeEach(() => {
912913
collection = { salt: 'some salt', id: 'someId', name: 'name' } as Collection
913914
items = []
915+
itemsContentHash = []
914916
})
915917

916918
describe('when saving the collection fails', () => {
@@ -957,7 +959,10 @@ describe('when publishing a collection', () => {
957959
[select(getAddress), [address]],
958960
[call(getChainIdByNetwork, Network.MATIC), ChainId.MATIC_MUMBAI],
959961
[retry(10, 500, mockBuilder.lockCollection, lockedCollection), newLock],
960-
[retry(10, 500, mockBuilder.saveTOS, lockedCollection, email), undefined],
962+
[
963+
retry(10, 500, mockBuilder.saveTOS, TermsOfServiceEvent.PUBLISH_COLLECTION, lockedCollection, email, itemsContentHash),
964+
undefined
965+
],
961966
[matchers.call.fn(sendTransaction), Promise.resolve(txHash)]
962967
])
963968
.not.put(saveCollectionRequest(collection))
@@ -1118,6 +1123,7 @@ describe('when publishing a collection', () => {
11181123
{ ...mockedItem, id: 'fstItem', contents: { ...mockedItem.contents, 'aFile.png': 'QmOldHash' } },
11191124
{ ...mockedItem, id: 'sndItem', contents: { 'someFile.png': 'newHash' } }
11201125
]
1126+
itemsContentHash = items.map(item => item.currentContentHash ?? '').filter(Boolean)
11211127
})
11221128

11231129
it('should put an action to save each of the items that have contents hashed with an older version', () => {
@@ -1133,7 +1139,7 @@ describe('when publishing a collection', () => {
11331139
[select(getAddress), [address]],
11341140
[call(getChainIdByNetwork, Network.MATIC), ChainId.MATIC_MUMBAI],
11351141
[retry(10, 500, mockBuilder.lockCollection, collection), newLock],
1136-
[retry(10, 500, mockBuilder.saveTOS, collection, email), undefined],
1142+
[retry(10, 500, mockBuilder.saveTOS, TermsOfServiceEvent.PUBLISH_COLLECTION, collection, email, itemsContentHash), undefined],
11371143
[matchers.call.fn(sendTransaction), Promise.resolve(txHash)]
11381144
])
11391145
.put(saveItemRequest(items[0], {}))
@@ -1191,7 +1197,7 @@ describe('when publishing a collection', () => {
11911197
[select(getAddress), [address]],
11921198
[call(getChainIdByNetwork, Network.MATIC), ChainId.MATIC_MUMBAI],
11931199
[retry(10, 500, mockBuilder.lockCollection, collection), newLock],
1194-
[retry(10, 500, mockBuilder.saveTOS, collection, email), undefined],
1200+
[retry(10, 500, mockBuilder.saveTOS, TermsOfServiceEvent.PUBLISH_COLLECTION, collection, email, itemsContentHash), undefined],
11951201
[matchers.call.fn(sendTransaction), Promise.resolve(txHash)]
11961202
])
11971203
.put(saveCollectionRequest(collection))
@@ -2024,6 +2030,7 @@ describe('when publishing a collection with fiat', () => {
20242030
let subscribeToNewsletter: boolean
20252031
let collection: Collection
20262032
let items: Item[]
2033+
let itemsContentHash: string[]
20272034
let serverItems: Item[]
20282035
let email: string
20292036
let paymentMethod: PaymentMethod
@@ -2058,6 +2065,7 @@ describe('when publishing a collection with fiat', () => {
20582065
describe('when no items are provided', () => {
20592066
beforeEach(() => {
20602067
items = []
2068+
itemsContentHash = []
20612069
})
20622070

20632071
describe('when the collection has the same amount of items in the server as locally', () => {
@@ -2081,7 +2089,10 @@ describe('when publishing a collection with fiat', () => {
20812089
[call([mockBuilder, 'fetchCollectionItems'], collection.id), serverItems],
20822090
[select(getAddress), 'address'],
20832091
[call(getChainIdByNetwork, Network.MATIC), ChainId.MATIC_MUMBAI],
2084-
[retry(10, 500, mockBuilder.saveTOS, collection, email), undefined],
2092+
[
2093+
retry(10, 500, mockBuilder.saveTOS, TermsOfServiceEvent.PUBLISH_COLLECTION, collection, email, itemsContentHash),
2094+
undefined
2095+
],
20852096
[call([config, config.get], 'WERT_PUBLISH_FEES_ENV'), wertEnv]
20862097
])
20872098
.dispatch(publishCollectionRequest(collection, items, email, subscribeToNewsletter, paymentMethod))
@@ -2101,7 +2112,10 @@ describe('when publishing a collection with fiat', () => {
21012112
[call([mockBuilder, 'fetchCollectionItems'], collection.id), serverItems],
21022113
[select(getAddress), 'address'],
21032114
[call(getChainIdByNetwork, Network.MATIC), ChainId.MATIC_MUMBAI],
2104-
[retry(10, 500, mockBuilder.saveTOS, collection, email), undefined],
2115+
[
2116+
retry(10, 500, mockBuilder.saveTOS, TermsOfServiceEvent.PUBLISH_COLLECTION, collection, email, itemsContentHash),
2117+
undefined
2118+
],
21052119
[call([config, config.get], 'WERT_PUBLISH_FEES_ENV'), wertEnv]
21062120
])
21072121
.dispatch(publishCollectionRequest(collection, items, email, subscribeToNewsletter, paymentMethod))
@@ -2122,7 +2136,10 @@ describe('when publishing a collection with fiat', () => {
21222136
[call([mockBuilder, 'fetchCollectionItems'], collection.id), serverItems],
21232137
[select(getAddress), from],
21242138
[call(getChainIdByNetwork, Network.MATIC), ChainId.MATIC_MUMBAI],
2125-
[retry(10, 500, mockBuilder.saveTOS, collection, email), undefined],
2139+
[
2140+
retry(10, 500, mockBuilder.saveTOS, TermsOfServiceEvent.PUBLISH_COLLECTION, collection, email, itemsContentHash),
2141+
undefined
2142+
],
21262143
[call([config, config.get], 'WERT_PUBLISH_FEES_ENV'), wertEnv],
21272144
[put(fetchRaritiesRequest()), undefined],
21282145
[
@@ -2148,7 +2165,18 @@ describe('when publishing a collection with fiat', () => {
21482165
[call([mockBuilder, 'fetchCollectionItems'], collection.id), serverItems],
21492166
[select(getAddress), from],
21502167
[call(getChainIdByNetwork, Network.MATIC), ChainId.MATIC_MUMBAI],
2151-
[retry(10, 500, mockBuilder.saveTOS, collection, email), undefined],
2168+
[
2169+
retry(
2170+
10,
2171+
500,
2172+
mockBuilder.saveTOS,
2173+
TermsOfServiceEvent.PUBLISH_COLLECTION,
2174+
collection,
2175+
email,
2176+
itemsContentHash
2177+
),
2178+
undefined
2179+
],
21522180
[call([config, config.get], 'WERT_PUBLISH_FEES_ENV'), wertEnv],
21532181
[put(fetchRaritiesRequest()), undefined],
21542182
[
@@ -2174,7 +2202,18 @@ describe('when publishing a collection with fiat', () => {
21742202
[call([mockBuilder, 'fetchCollectionItems'], collection.id), serverItems],
21752203
[select(getAddress), from],
21762204
[call(getChainIdByNetwork, Network.MATIC), ChainId.MATIC_MUMBAI],
2177-
[retry(10, 500, mockBuilder.saveTOS, collection, email), undefined],
2205+
[
2206+
retry(
2207+
10,
2208+
500,
2209+
mockBuilder.saveTOS,
2210+
TermsOfServiceEvent.PUBLISH_COLLECTION,
2211+
collection,
2212+
email,
2213+
itemsContentHash
2214+
),
2215+
undefined
2216+
],
21782217
[call([config, config.get], 'WERT_PUBLISH_FEES_ENV'), wertEnv],
21792218
[put(fetchRaritiesRequest()), undefined],
21802219
[

src/modules/collection/sagas.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ import {
109109
import { areSynced, isEmote, isValidText, isWearable, toInitializeItems } from 'modules/item/utils'
110110
import { locations } from 'routing/locations'
111111
import { getCollectionId } from 'modules/location/selectors'
112-
import { BuilderAPI, FetchCollectionsParams } from 'lib/api/builder'
112+
import { BuilderAPI, FetchCollectionsParams, TermsOfServiceEvent } from 'lib/api/builder'
113113
import { getArrayOfPagesFromTotal, PaginatedResource } from 'lib/api/pagination'
114114
import { extractThirdPartyId } from 'lib/urn'
115115
import { closeModal, CloseModalAction, CLOSE_MODAL, openModal } from 'decentraland-dapps/dist/modules/modal/actions'
@@ -433,7 +433,15 @@ export function* collectionSaga(legacyBuilderClient: BuilderAPI, client: Builder
433433
const manager = getContract(ContractName.CollectionManager, maticChainId)
434434

435435
// We wait for TOS to end first to avoid locking the collection preemptively if this endpoint fails
436-
yield retry(10, 500, legacyBuilderClient.saveTOS, collection, email)
436+
yield retry(
437+
10,
438+
500,
439+
legacyBuilderClient.saveTOS,
440+
TermsOfServiceEvent.PUBLISH_COLLECTION,
441+
collection,
442+
email,
443+
items.map(item => item.currentContentHash ?? '').filter(Boolean)
444+
)
437445

438446
let txHash: string
439447

0 commit comments

Comments
 (0)