From 293d3da16709a3e19d5041af9f98589216fea196 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Fri, 8 Mar 2024 12:38:47 +0200 Subject: [PATCH 1/2] check collection owner and already branded identity --- action/index.cjs | 42 ++++++++++++++++++++++++++++++++++++++---- src/bot.ts | 48 ++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 82 insertions(+), 8 deletions(-) diff --git a/action/index.cjs b/action/index.cjs index 7f45025..cfcbbf7 100644 --- a/action/index.cjs +++ b/action/index.cjs @@ -188028,6 +188028,11 @@ const robot = (app) => { const allOwnersToCheck = [mainOwner, ...extraOwners]; const apiUrl = getApiUrl(); for (const owner of allOwnersToCheck) { + const alreadyExistingBranding = await isProviderAlreadyBranded(apiUrl, asset, owner); + if (alreadyExistingBranding && alreadyExistingBranding.existing && !alreadyExistingBranding.isUpdate) { + await fail(`${owner} is already branded. Only updates are allowed.`); + return []; + } if (new out_1.Address(owner).isContractAddress()) { const ownerResult = await axios_1.default.get(`${apiUrl}/accounts/${owner}?extract=ownerAddress`); allOwners.push(ownerResult.data); @@ -188038,6 +188043,19 @@ const robot = (app) => { } return [...new Set(allOwners)]; } + async function isProviderAlreadyBranded(apiUrl, identity, provider) { + const providerInfo = await axios_1.default.get(`${apiUrl}/providers/${provider}`); + if (!providerInfo) { + return { existing: false }; + } + if (!providerInfo.data?.identity) { + return { existing: false }; + } + return { + existing: true, + isUpdate: identity === providerInfo.data?.identity, + }; + } async function getAccountOwner(account) { const accountOwner = account; if (new out_1.Address(accountOwner).isContractAddress()) { @@ -188065,11 +188083,27 @@ const robot = (app) => { return tokenOwner; } async function getTokenOwnerFromApi(token, apiUrl) { - const tokenOwnerResponse = await axios_1.default.get(`${apiUrl}/tokens/${token}?extract=owner`); - if (tokenOwnerResponse && tokenOwnerResponse.data) { - return tokenOwnerResponse.data; + try { + const tokenOwnerResponse = await axios_1.default.get(`${apiUrl}/tokens/${token}?extract=owner`); + if (tokenOwnerResponse && tokenOwnerResponse.data) { + return tokenOwnerResponse.data; + } + return ''; + } + catch (error) { + console.log(`Cannot find token owner on the 'tokens' endpoint. Will try the 'collections'`); + } + try { + const tokenOwnerResponse = await axios_1.default.get(`${apiUrl}/collections/${token}?extract=owner`); + if (tokenOwnerResponse && tokenOwnerResponse.data) { + return tokenOwnerResponse.data; + } + return ''; + } + catch (error) { + await fail(`Cannot find token or collection with ID ${token}: ${error}`); + return ''; } - return ''; } function getApiUrl() { switch (network) { diff --git a/src/bot.ts b/src/bot.ts index 51d5124..7f6b456 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -66,6 +66,11 @@ export const robot = (app: Probot) => { const apiUrl = getApiUrl(); for (const owner of allOwnersToCheck) { + const alreadyExistingBranding = await isProviderAlreadyBranded(apiUrl, asset as string, owner); + if (alreadyExistingBranding && alreadyExistingBranding.existing && !alreadyExistingBranding.isUpdate) { + await fail(`${owner} is already branded. Only updates are allowed.`); + return []; + } if (new Address(owner).isContractAddress()) { const ownerResult = await axios.get(`${apiUrl}/accounts/${owner}?extract=ownerAddress`); allOwners.push(ownerResult.data); @@ -77,6 +82,25 @@ export const robot = (app: Probot) => { return [...new Set(allOwners)]; } + async function isProviderAlreadyBranded(apiUrl: string, identity: string, provider: string): Promise<{ + existing: boolean, + isUpdate?: boolean + }> { + const providerInfo = await axios.get(`${apiUrl}/providers/${provider}`); + if (!providerInfo) { + return { existing: false }; + } + + if (!providerInfo.data?.identity) { + return { existing: false }; + } + + return { + existing: true, + isUpdate: identity === providerInfo.data?.identity, + }; + } + async function getAccountOwner(account: string): Promise { const accountOwner = account; if (new Address(accountOwner).isContractAddress()) { @@ -111,12 +135,28 @@ export const robot = (app: Probot) => { } async function getTokenOwnerFromApi(token: string, apiUrl: string): Promise { - const tokenOwnerResponse = await axios.get(`${apiUrl}/tokens/${token}?extract=owner`); - if (tokenOwnerResponse && tokenOwnerResponse.data) { - return tokenOwnerResponse.data; + try { + const tokenOwnerResponse = await axios.get(`${apiUrl}/tokens/${token}?extract=owner`); + if (tokenOwnerResponse && tokenOwnerResponse.data) { + return tokenOwnerResponse.data; + } + + return ''; + } catch (error) { + console.log(`Cannot find token owner on the 'tokens' endpoint. Will try the 'collections'`); } - return ''; + try { + const tokenOwnerResponse = await axios.get(`${apiUrl}/collections/${token}?extract=owner`); + if (tokenOwnerResponse && tokenOwnerResponse.data) { + return tokenOwnerResponse.data; + } + + return ''; + } catch (error) { + await fail(`Cannot find token or collection with ID ${token}: ${error}`); + return ''; + } } function getApiUrl() { From 5e9ee38f5a8c8e157d7a579cb87b56ca3d761599 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Fri, 8 Mar 2024 15:36:49 +0200 Subject: [PATCH 2/2] fixes after review --- action/index.cjs | 62 ++++++++++++++++++++++---------------------- src/bot.ts | 67 ++++++++++++++++++++++-------------------------- 2 files changed, 61 insertions(+), 68 deletions(-) diff --git a/action/index.cjs b/action/index.cjs index cfcbbf7..5cf0832 100644 --- a/action/index.cjs +++ b/action/index.cjs @@ -188034,8 +188034,10 @@ const robot = (app) => { return []; } if (new out_1.Address(owner).isContractAddress()) { - const ownerResult = await axios_1.default.get(`${apiUrl}/accounts/${owner}?extract=ownerAddress`); - allOwners.push(ownerResult.data); + const ownerResult = await fetchStringValueFromApi(apiUrl, "accounts", owner, "ownerAddress"); + if (ownerResult) { + allOwners.push(ownerResult); + } } else { allOwners.push(owner); @@ -188044,17 +188046,23 @@ const robot = (app) => { return [...new Set(allOwners)]; } async function isProviderAlreadyBranded(apiUrl, identity, provider) { - const providerInfo = await axios_1.default.get(`${apiUrl}/providers/${provider}`); - if (!providerInfo) { - return { existing: false }; + try { + const providerInfo = await axios_1.default.get(`${apiUrl}/providers/${provider}`); + if (!providerInfo) { + return { existing: false }; + } + if (!providerInfo.data?.identity) { + return { existing: false }; + } + return { + existing: true, + isUpdate: identity === providerInfo.data?.identity, + }; } - if (!providerInfo.data?.identity) { + catch (error) { + console.error(`API error while fetching the provider data for address ${provider}: ${error}`); return { existing: false }; } - return { - existing: true, - isUpdate: identity === providerInfo.data?.identity, - }; } async function getAccountOwner(account) { const accountOwner = account; @@ -188065,11 +188073,7 @@ const robot = (app) => { } async function getAccountOwnerFromApi(address) { const apiUrl = getApiUrl(); - const accountOwnerResponse = await axios_1.default.get(`${apiUrl}/accounts/${address}?extract=ownerAddress`); - if (accountOwnerResponse && accountOwnerResponse.data) { - return accountOwnerResponse.data; - } - return ''; + return await fetchStringValueFromApi(apiUrl, "accounts", address, "ownerAddress"); } async function getTokenOwner(token) { // since the token owner can be changed at protocol level at any time, it's enough to check the ownership of the token, @@ -188077,31 +188081,25 @@ const robot = (app) => { const apiUrl = getApiUrl(); const tokenOwner = await getTokenOwnerFromApi(token, apiUrl); if (new out_1.Address(tokenOwner).isContractAddress()) { - const ownerResult = await axios_1.default.get(`${apiUrl}/accounts/${tokenOwner}?extract=ownerAddress`); - return ownerResult.data; + return await fetchStringValueFromApi(apiUrl, "accounts", tokenOwner, "ownerAddress"); } return tokenOwner; } async function getTokenOwnerFromApi(token, apiUrl) { - try { - const tokenOwnerResponse = await axios_1.default.get(`${apiUrl}/tokens/${token}?extract=owner`); - if (tokenOwnerResponse && tokenOwnerResponse.data) { - return tokenOwnerResponse.data; - } - return ''; - } - catch (error) { - console.log(`Cannot find token owner on the 'tokens' endpoint. Will try the 'collections'`); + return await fetchStringValueFromApi(apiUrl, "tokens", token, "owner") || + await fetchStringValueFromApi(apiUrl, "collections", token, "owner"); + } + async function fetchStringValueFromApi(apiUrl, endpoint, query, extract) { + let requestUrl = `${apiUrl}/${endpoint}/${query}`; + if (extract) { + requestUrl += `?extract=${extract}`; } try { - const tokenOwnerResponse = await axios_1.default.get(`${apiUrl}/collections/${token}?extract=owner`); - if (tokenOwnerResponse && tokenOwnerResponse.data) { - return tokenOwnerResponse.data; - } - return ''; + const response = await axios_1.default.get(requestUrl); + return response.data; } catch (error) { - await fail(`Cannot find token or collection with ID ${token}: ${error}`); + console.error(`Cannot query API at ${requestUrl}: ${error}`); return ''; } } diff --git a/src/bot.ts b/src/bot.ts index 7f6b456..5851d35 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -72,8 +72,10 @@ export const robot = (app: Probot) => { return []; } if (new Address(owner).isContractAddress()) { - const ownerResult = await axios.get(`${apiUrl}/accounts/${owner}?extract=ownerAddress`); - allOwners.push(ownerResult.data); + const ownerResult = await fetchStringValueFromApi(apiUrl, "accounts", owner, "ownerAddress"); + if (ownerResult) { + allOwners.push(ownerResult); + } } else { allOwners.push(owner); } @@ -86,19 +88,24 @@ export const robot = (app: Probot) => { existing: boolean, isUpdate?: boolean }> { - const providerInfo = await axios.get(`${apiUrl}/providers/${provider}`); - if (!providerInfo) { - return { existing: false }; - } + try { + const providerInfo = await axios.get(`${apiUrl}/providers/${provider}`); + if (!providerInfo) { + return { existing: false }; + } - if (!providerInfo.data?.identity) { + if (!providerInfo.data?.identity) { + return { existing: false }; + } + + return { + existing: true, + isUpdate: identity === providerInfo.data?.identity, + }; + } catch (error) { + console.error(`API error while fetching the provider data for address ${provider}: ${error}`); return { existing: false }; } - - return { - existing: true, - isUpdate: identity === providerInfo.data?.identity, - }; } async function getAccountOwner(account: string): Promise { @@ -112,12 +119,7 @@ export const robot = (app: Probot) => { async function getAccountOwnerFromApi(address: string): Promise { const apiUrl = getApiUrl(); - const accountOwnerResponse = await axios.get(`${apiUrl}/accounts/${address}?extract=ownerAddress`); - if (accountOwnerResponse && accountOwnerResponse.data) { - return accountOwnerResponse.data; - } - - return ''; + return await fetchStringValueFromApi(apiUrl, "accounts", address, "ownerAddress"); } async function getTokenOwner(token: string): Promise { @@ -127,34 +129,27 @@ export const robot = (app: Probot) => { const tokenOwner = await getTokenOwnerFromApi(token, apiUrl); if (new Address(tokenOwner).isContractAddress()) { - const ownerResult = await axios.get(`${apiUrl}/accounts/${tokenOwner}?extract=ownerAddress`); - return ownerResult.data; + return await fetchStringValueFromApi(apiUrl, "accounts", tokenOwner, "ownerAddress"); } return tokenOwner; } async function getTokenOwnerFromApi(token: string, apiUrl: string): Promise { - try { - const tokenOwnerResponse = await axios.get(`${apiUrl}/tokens/${token}?extract=owner`); - if (tokenOwnerResponse && tokenOwnerResponse.data) { - return tokenOwnerResponse.data; - } + return await fetchStringValueFromApi(apiUrl, "tokens", token, "owner") || + await fetchStringValueFromApi(apiUrl, "collections", token, "owner"); + } - return ''; - } catch (error) { - console.log(`Cannot find token owner on the 'tokens' endpoint. Will try the 'collections'`); + async function fetchStringValueFromApi(apiUrl: string, endpoint: string, query: string, extract?: string): Promise { + let requestUrl = `${apiUrl}/${endpoint}/${query}`; + if (extract) { + requestUrl += `?extract=${extract}`; } - try { - const tokenOwnerResponse = await axios.get(`${apiUrl}/collections/${token}?extract=owner`); - if (tokenOwnerResponse && tokenOwnerResponse.data) { - return tokenOwnerResponse.data; - } - - return ''; + const response = await axios.get(requestUrl); + return response.data; } catch (error) { - await fail(`Cannot find token or collection with ID ${token}: ${error}`); + console.error(`Cannot query API at ${requestUrl}: ${error}`); return ''; } }