Skip to content

Commit

Permalink
Add erc1155 to token gating group conditions (#1382)
Browse files Browse the repository at this point in the history
* feat: add erc1155 to token gating group conditions

* fix: add tokenId to fetchContractInfo function

* lock file updated

---------

Co-authored-by: rohitmalhotra1420 <rohit.malhotra1420@gmail.com>
  • Loading branch information
kalashshah and rohitmalhotra1420 authored Aug 7, 2024
1 parent ec13651 commit 6396697
Show file tree
Hide file tree
Showing 13 changed files with 30,361 additions and 21,517 deletions.
2 changes: 1 addition & 1 deletion packages/uiweb/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"uuid": "^9.0.1"
},
"peerDependencies": {
"@pushprotocol/restapi": "1.7.19",
"@pushprotocol/restapi": "1.7.25",
"@pushprotocol/socket": "^0.5.0",
"react": ">=16.8.0",
"styled-components": "^6.0.8"
Expand Down
39 changes: 37 additions & 2 deletions packages/uiweb/src/lib/components/chat/CreateGroup/AddCriteria.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
checkIfCustomEndpoint,
checkIfGuild,
checkIfPushInvite,
checkIfTokenId,
checkIfTokenNFT,
fetchContractInfo,
getCategoryDropdownValues,
Expand All @@ -56,6 +57,7 @@ const AddCriteria = ({ handlePrevious, onClose, criteriaStateManager }: ModalHea
const [guildComparison, setGuildComparison] = useState('');
const [selectedChainValue, setSelectedChainValue] = useState<number>(0);
const [contract, setContract] = useState<string>('');
const [tokenId, setTokenId] = useState<string>('');
const [inviteCheckboxes, setInviteCheckboxes] = useState<{
admin: boolean;
owner: boolean;
Expand Down Expand Up @@ -154,6 +156,12 @@ const AddCriteria = ({ handlePrevious, onClose, criteriaStateManager }: ModalHea
title: 'Custom Endpoint',
function: () => setSelectedCategoryValue(3),
},
{
id: 4,
value: CATEGORY.ERC1155,
title: 'Token ERC1155',
function: () => setSelectedCategoryValue(4),
},
],
GUILD: {
value: CATEGORY.ROLES,
Expand All @@ -170,6 +178,10 @@ const AddCriteria = ({ handlePrevious, onClose, criteriaStateManager }: ModalHea
value: SUBCATEGORY.HOLDER,
title: 'Holder',
},
ERC1155: {
value: SUBCATEGORY.HOLDER,
title: 'Holder',
},
INVITE: {
value: SUBCATEGORY.DEFAULT,
title: 'Default',
Expand Down Expand Up @@ -256,7 +268,7 @@ const AddCriteria = ({ handlePrevious, onClose, criteriaStateManager }: ModalHea

let subCategory = 'DEFAULT';
if (_type === 'PUSH') {
if (category === CATEGORY.ERC20 || category === CATEGORY.ERC721) {
if (category === CATEGORY.ERC20 || category === CATEGORY.ERC721 || category === CATEGORY.ERC1155) {
subCategory = SUBCATEGORY.HOLDER;
} else if (category === CATEGORY.CustomEndpoint) {
subCategory = 'GET';
Expand All @@ -283,6 +295,7 @@ const AddCriteria = ({ handlePrevious, onClose, criteriaStateManager }: ModalHea
dropdownQuantityRangeValues,
selectedChainValue,
dropdownChainsValues,
tokenId: Number(tokenId),
}),
};

Expand Down Expand Up @@ -320,7 +333,11 @@ const AddCriteria = ({ handlePrevious, onClose, criteriaStateManager }: ModalHea
const pushData = oldValue.data as PushData;

// sub category
if (oldValue.category === CATEGORY.ERC20 || oldValue.category === CATEGORY.ERC721) {
if (
oldValue.category === CATEGORY.ERC20 ||
oldValue.category === CATEGORY.ERC721 ||
oldValue.category === CATEGORY.ERC1155
) {
if (pushData.token) {
setUnit(pushData.token);
}
Expand All @@ -335,6 +352,7 @@ const AddCriteria = ({ handlePrevious, onClose, criteriaStateManager }: ModalHea
dropdownChainsValues.findIndex((obj) => obj.value === contractAndChain[0] + ':' + contractAndChain[1])
);
setContract(contractAndChain.length === 3 ? contractAndChain[2] : '');
setTokenId(pushData.tokenId?.toString() || '');
setQuantity({
value: pushData.amount || 0,
range: dropdownQuantityRangeValues.findIndex((obj) => obj.value === pushData.comparison),
Expand Down Expand Up @@ -374,6 +392,7 @@ const AddCriteria = ({ handlePrevious, onClose, criteriaStateManager }: ModalHea
setDecimals,
selectedChainValue,
dropdownChainsValues,
tokenId: Number(tokenId)
});
}, 2000);
return () => clearTimeout(getData);
Expand Down Expand Up @@ -536,6 +555,22 @@ const AddCriteria = ({ handlePrevious, onClose, criteriaStateManager }: ModalHea
/>
{!!validationErrors?.tokenError && <ErrorSpan>{validationErrors?.tokenError}</ErrorSpan>}
</Section>
{checkIfTokenId({ dropdownCategoryValues, dropdownTypeValues, selectedCategoryValue, selectedTypeValue }) && (
<Section
gap="10px"
flexDirection="column"
alignItems="start"
>
<TextInput
labelName="Token Id"
inputValue={tokenId}
onInputChange={(e: any) => setTokenId(e.target.value)}
placeholder="e.g. 2"
error={!!validationErrors?.tokenId}
/>
{!!validationErrors?.tokenId && <ErrorSpan>{validationErrors?.tokenId}</ErrorSpan>}
</Section>
)}
<Section
gap="10px"
flexDirection="column"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,17 @@ const CriteriaSection = ({ criteria }: { criteria: ConditionData }) => {
const checkIfNftToken = () => {
if (
criteria?.category === CATEGORY.ERC721 ||
criteria?.category === CATEGORY.ERC20
criteria?.category === CATEGORY.ERC20 ||
criteria?.category === CATEGORY.ERC1155
)
return true;
return false;
};

const checkIfIDToken = () => {
return criteria?.category === CATEGORY.ERC1155;
};

const getGuildRole = () => {
if (!criteria?.data?.['comparison']) {
return 'SPECIFIC';
Expand Down Expand Up @@ -123,12 +128,26 @@ const CriteriaSection = ({ criteria }: { criteria: ConditionData }) => {
justifyContent="space-between"
alignItems="center"
>
<Span fontWeight="700" color={theme.textColor?.modalHeadingText}>
<Span fontWeight="500" color={theme.textColor?.modalSubHeadingText}>
{getTokenNftComparisionLabel()}{' '}
{checkIfIDToken() ?
<Section>
<Span fontWeight="500" color={theme.textColor?.modalSubHeadingText}>
{getTokenNftComparisionLabel()}{' '}
</Span>
<Section flexDirection='column' alignItems='start' margin="0px 0px 0px 8px">
<Span color={theme.textColor?.modalSubHeadingText} fontSize='10px'>
{criteria?.data?.['amount']} {tokenSymbol}
</Span>
<Span color={theme.textColor?.modalHeadingText} textAlign='flex-start'>ID: {criteria?.data?.['tokenId']}</Span>
</Section>
</Section>
:
<Span fontWeight="700" color={theme.textColor?.modalHeadingText}>
<Span fontWeight="500" color={theme.textColor?.modalSubHeadingText}>
{getTokenNftComparisionLabel()}{' '}
</Span>
{criteria?.data?.['amount']} {tokenSymbol}
</Span>
{criteria?.data?.['amount']} {tokenSymbol}
</Span>
}
<ChainIconSVG padding="3px 6px 0 0" >
{
NETWORK_ICON_DETAILS[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,24 @@ export const checkIfTokenNFT = ({
selectedTypeValue,
selectedCategoryValue,
});
if (category === CATEGORY.ERC20 || category === CATEGORY.ERC721) return true;
if (category === CATEGORY.ERC20 || category === CATEGORY.ERC721 || category === CATEGORY.ERC1155) return true;

return false;
};

export const checkIfTokenId = ({
dropdownCategoryValues,
dropdownTypeValues,
selectedCategoryValue,
selectedTypeValue,
}: InputFunctionParams) => {
const category = getSelectedCategoryValue({
dropdownCategoryValues,
dropdownTypeValues,
selectedTypeValue,
selectedCategoryValue,
});
if (category === CATEGORY.ERC1155) return true;

return false;
};
Expand Down Expand Up @@ -184,6 +201,7 @@ type FetchContractInfoParamType = {
setUnit: Dispatch<SetStateAction<string>>;
setDecimals: Dispatch<SetStateAction<number>>;
contract: string;
tokenId: number;
dropdownChainsValues: Array<DropdownValueType>;
selectedChainValue: number;
} & InputFunctionParams;
Expand All @@ -199,6 +217,7 @@ export const fetchContractInfo = async ({
setDecimals,
selectedChainValue,
dropdownChainsValues,
tokenId,
}: FetchContractInfoParamType) => {
setValidationErrors((prev: any) => ({ ...prev, tokenError: undefined }));

Expand All @@ -215,7 +234,8 @@ export const fetchContractInfo = async ({
_category,
_chainInfo,
setUnit,
setDecimals
setDecimals,
tokenId
);
};

Expand All @@ -228,6 +248,7 @@ type GetCriteriaDataParamType = {
selectedChainValue: number;
decimals: number;
unit: string;
tokenId: number;
url: string;
guildId: string;
specificRoleId: string;
Expand Down Expand Up @@ -257,17 +278,19 @@ export const getCriteriaData = ({
dropdownQuantityRangeValues,
selectedChainValue,
dropdownChainsValues,
tokenId,
}: GetCriteriaDataParamType): Data => {
if (type === 'PUSH') {
if (category === CATEGORY.ERC20 || category === CATEGORY.ERC721) {
if (category === CATEGORY.ERC20 || category === CATEGORY.ERC721 || category === CATEGORY.ERC1155) {
const selectedChain =
dropdownChainsValues[selectedChainValue].value || 'eip155:1';
return {
contract: `${selectedChain}:${contract}`,
amount: quantity.value,
comparison: dropdownQuantityRangeValues[quantity.range].value,
decimals: category === CATEGORY.ERC20 ? decimals : undefined,
decimals: (category === CATEGORY.ERC20 || category === CATEGORY.ERC1155) ? decimals : undefined,
token: unit,
tokenId,
};
} else if (category === CATEGORY.INVITE) {
const _inviteRoles = [];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ConditionArray } from '../exportedTypes';
import * as PushAPI from '@pushprotocol/restapi';
import { fetchERC20Info, fetchERC721nfo } from './tokenHelpers';

export interface GroupRulesType {
CHAT: ConditionArray[];
Expand Down
24 changes: 19 additions & 5 deletions packages/uiweb/src/lib/components/chat/helpers/tokenGatedGroup.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import axios from 'axios';
import { ethers } from 'ethers';

import { fetchERC20Info, fetchERC721nfo } from './tokenHelpers';
import { fetchERC20Info, fetchERC721nfo, fetchERC1155Info } from './tokenHelpers';
import {
CATEGORY,
CriteriaStateType,
Expand Down Expand Up @@ -124,10 +124,15 @@ const validateTokenData = async (condition: Rule): Promise<CriteriaValidationErr
if (!ethers.utils.isAddress(address)) {
return { tokenError: `Invalid contract address` };
}
const [err] =
condition.category === CATEGORY.ERC721
? await fetchERC721nfo(address, chainId)
: await fetchERC20Info(address, chainId);

let err;
if (condition.category === CATEGORY.ERC1155) {
err = (await fetchERC1155Info(address, chainId, data.tokenId ?? 0))?.[0];
} else if (condition.category === CATEGORY.ERC721) {
err = (await fetchERC721nfo(address, chainId))?.[0];
} else {
err = (await fetchERC20Info(address, chainId))?.[0];
}

if (err) {
return { tokenError: `Invalid ${condition.category} contract` };
Expand All @@ -139,6 +144,15 @@ const validateTokenData = async (condition: Rule): Promise<CriteriaValidationErr
return { tokenAmount: `Amount cannot be in negative` };
}
}

if(condition.category === CATEGORY.ERC1155) {
if(data.tokenId === undefined || Number.isNaN(data.tokenId)) {
return { tokenId: 'Invalid Token ID' };
} else if(data.tokenId < 0) {
return { tokenId: 'Token ID cannot be in negative' };
}
}

return {};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,10 @@ const TokenContractABI = [
},
];

export { NFTContractABI, TokenContractABI };
const ERC1155ContractABI = [
'function uri(uint256 _id) external view returns (string memory)',
'function supportsInterface(bytes4 interfaceID) external view returns (bool)'
];


export { NFTContractABI, TokenContractABI, ERC1155ContractABI };
Loading

0 comments on commit 6396697

Please sign in to comment.