-
-
- {" "}
- Submit Verification after verifing with brighID app.{" "}
+
+
+
+ Submit Verification after verifing with brighID app. This might take
+ up to 5 minutes.
{refreshUserProfile && (
diff --git a/components/containers/provider-dashboard/helpers/checkCollectionAddress.ts b/components/containers/provider-dashboard/helpers/checkCollectionAddress.ts
new file mode 100644
index 00000000..b4475853
--- /dev/null
+++ b/components/containers/provider-dashboard/helpers/checkCollectionAddress.ts
@@ -0,0 +1,35 @@
+import { PublicClient, erc721ABI, readContracts } from "wagmi";
+
+//check erc721 collection address
+
+export const checkCollectionAddress = async (
+ provider: PublicClient,
+ collectionAddress: string,
+ chainId: number
+) => {
+ if (!provider) return;
+
+ const contracts = [{
+ abi: erc721ABI,
+ address: collectionAddress as any,
+ functionName: "name",
+ chainId: chainId,
+ }, {
+ abi: erc721ABI,
+ address: collectionAddress as any,
+ functionName: "symbol",
+ chainId: chainId,
+ }, {
+ abi: erc721ABI,
+ address: collectionAddress as any,
+ functionName: "ownerOf",
+ args:[1n],
+ chainId: chainId,
+ }];
+
+ const data = await readContracts({
+ contracts,
+ });
+ const res = data.filter(item => item.status === 'success');
+ return res.length === 3;
+};
diff --git a/components/containers/provider-dashboard/helpers/createErc20Raffle.ts b/components/containers/provider-dashboard/helpers/createErc20Raffle.ts
index adfa4bb4..4f05835f 100644
--- a/components/containers/provider-dashboard/helpers/createErc20Raffle.ts
+++ b/components/containers/provider-dashboard/helpers/createErc20Raffle.ts
@@ -1,5 +1,5 @@
import { ZERO_ADDRESS } from "@/constants";
-import { ProviderDashboardFormDataProp, ConstraintParamValues } from "@/types";
+import { ProviderDashboardFormDataProp, RequirementProps } from "@/types";
import { prizeTapABI } from "@/types/abis/contracts";
import { toWei } from "@/utils/numbersBigNumber";
import { PublicClient, getContract, parseEther } from "viem";
@@ -21,7 +21,7 @@ const createErc20RaffleCallback = async (
endTime: bigint,
isNativeToken: boolean,
winnersCount: bigint,
- totalAmount: string
+ totalAmount: string
) => {
if (!provider || !signer) return;
const gasEstimate = await provider.estimateContractGas({
@@ -32,7 +32,9 @@ const createErc20RaffleCallback = async (
args: [
isNativeToken
? parseEther(new Big(payableAmount).toFixed())
- : BigInt(toWei((Number(new Big(payableAmount).toFixed())), tokenDecimals)),
+ : BigInt(
+ toWei(Number(new Big(payableAmount).toFixed()), tokenDecimals)
+ ),
currencyAddress,
maxParticipants,
1n,
@@ -41,7 +43,7 @@ const createErc20RaffleCallback = async (
winnersCount,
"0x0000000000000000000000000000000000000000000000000000000000000000",
],
- value: currencyAddress == ZERO_ADDRESS ? parseEther(totalAmount): 0n,
+ value: currencyAddress == ZERO_ADDRESS ? parseEther(totalAmount) : 0n,
});
return signer?.writeContract({
@@ -52,8 +54,10 @@ const createErc20RaffleCallback = async (
gasPrice: gasEstimate,
args: [
isNativeToken
- ? parseEther(new Big(payableAmount).toFixed())
- : BigInt(toWei((Number(new Big(payableAmount).toFixed())), tokenDecimals)),
+ ? parseEther(new Big(payableAmount).toFixed())
+ : BigInt(
+ toWei(Number(new Big(payableAmount).toFixed()), tokenDecimals)
+ ),
currencyAddress,
maxParticipants,
1n,
@@ -70,7 +74,7 @@ export const createErc20Raffle = async (
data: ProviderDashboardFormDataProp,
provider: PublicClient,
signer: GetWalletClientResult,
- requirementList: ConstraintParamValues[],
+ requirementList: RequirementProps[],
address: string,
userToken: string,
setCreateRaffleLoading: any,
@@ -91,7 +95,9 @@ export const createErc20Raffle = async (
data.tokenAmount,
data.isNativeToken ? 18 : data.tokenDecimals
);
- const twitter = "https://twitter.com/" + data.twitter?.replace("@", "");
+ const twitter = data.twitter
+ ? "https://twitter.com/" + data.twitter?.replace("@", "")
+ : null;
const discord = data.discord
? "https://discord.com/" + data.discord.replace("@", "")
: null;
@@ -99,34 +105,64 @@ export const createErc20Raffle = async (
? "https://t.me/" + data.telegram.replace("@", "")
: null;
const creatorUrl = data.creatorUrl ? "https://" + data.creatorUrl : null;
- const constraints = requirementList.map((item) => item.pk);
- const reversed_constraints = requirementList.filter(item => item.isNotSatisfy).map(ids => ids.pk);
- const raffleData = {
- name: prizeName,
- description: data.description,
- contract: raffleContractAddress,
- creator_name: data.provider,
- creator_address: address,
- prize_amount: prizeAmount,
- prize_asset: data.tokenContractAddress,
- prize_name: prizeName,
- prize_symbol: prizeSymbol,
- decimals: decimals,
- chain: Number(data.selectedChain.pk),
- constraints,
- constraint_params: btoa(JSON.stringify({})),
- deadline: deadline(data.endTimeStamp),
- max_number_of_entries: maxNumberOfEntries,
- start_at: startAt(data.startTimeStamp),
- winnersCount: data.winnersCount,
- discord_url: discord,
- twitter_url: twitter,
- creator_url: creatorUrl,
- telegram_url: telegram,
- reversed_constraints: reversed_constraints.length > 1 ? reversed_constraints.join(',') : reversed_constraints.length == 1 ? reversed_constraints[0].toString() : undefined,
- email_url: data.email,
- necessary_information: data.necessaryInfo,
- };
+ const constraints = requirementList.map((item) => item.pk.toString());
+ const reversed_constraints = requirementList
+ .filter((item) => item.isNotSatisfy)
+ .map((ids) => ids.pk);
+
+ const constraintFileList: any = requirementList
+ .filter((item) => item.constraintFile)
+ .map((item) => item.constraintFile);
+
+ const constraint_params = requirementList.reduce((obj: any, item: any) => {
+ obj[item.name] = item.params;
+ return obj;
+ }, {});
+
+ const formData = new FormData();
+
+ const reversed =
+ reversed_constraints.length > 1
+ ? reversed_constraints.join(",")
+ : reversed_constraints.length == 1
+ ? reversed_constraints[0].toString()
+ : "";
+
+ for (let i = 0; i < constraints.length; i++) {
+ formData.append("constraints", constraints[i]);
+ }
+
+ if (constraintFileList) {
+ for (let i = 0; i < constraintFileList.length; i++) {
+ formData.append("constraint_files", constraintFileList[i]);
+ }
+ }
+
+ if (reversed) {
+ formData.append("reversed_constraints", reversed);
+ }
+
+ formData.append("name", prizeName);
+ formData.append("contract", raffleContractAddress);
+ formData.append("creator_name", data.provider!);
+ formData.append("creator_address", address);
+ formData.append("prize_amount", prizeAmount.toString());
+ formData.append("prize_asset", data.tokenContractAddress);
+ formData.append("prize_name", prizeName);
+ formData.append("chain", data.selectedChain.pk);
+ formData.append("constraint_params", btoa(JSON.stringify(constraint_params)));
+ formData.append("description", data.description ?? "");
+ formData.append("prize_symbol", prizeSymbol);
+ formData.append("deadline", deadline(data.endTimeStamp));
+ formData.append("max_number_of_entries", maxNumberOfEntries);
+ formData.append("start_at", startAt(data.startTimeStamp));
+ formData.append("winners_count", data.winnersCount.toString());
+ formData.append("discord_url", discord! ?? "");
+ formData.append("twitter_url", twitter! ?? "");
+ formData.append("creator_url", creatorUrl! ?? "");
+ formData.append("telegram_url", telegram! ?? "");
+ formData.append("email_url", data.email!);
+ formData.append("necessary_information", data.necessaryInfo!);
const raffleContract: any = getContract({
address: raffleContractAddress as any,
@@ -134,8 +170,6 @@ export const createErc20Raffle = async (
publicClient: provider,
});
-
-
try {
setCreateRaffleLoading(true);
@@ -162,7 +196,7 @@ export const createErc20Raffle = async (
confirmations: 1,
});
- const raffle = await createRaffleApi(userToken, raffleData);
+ const raffle = await createRaffleApi(userToken, formData);
if (!raffle.success) {
return false;
@@ -176,8 +210,14 @@ export const createErc20Raffle = async (
txHash: transactionInfo.transactionHash,
message: "Created raffle successfully.",
});
+
setCreateRaffleLoading(false);
- updateCreateRaffleTx(userToken, rafflePk, transactionInfo.transactionHash);
+
+ await updateCreateRaffleTx(
+ userToken,
+ rafflePk,
+ transactionInfo.transactionHash
+ );
} catch (e: any) {
console.log(e);
setCreteRaffleResponse({
diff --git a/components/containers/provider-dashboard/helpers/createErc20TokenDistribution.ts b/components/containers/provider-dashboard/helpers/createErc20TokenDistribution.ts
new file mode 100644
index 00000000..d276308e
--- /dev/null
+++ b/components/containers/provider-dashboard/helpers/createErc20TokenDistribution.ts
@@ -0,0 +1,147 @@
+import {
+ ProviderDashboardFormDataProp,
+ RequirementProps,
+} from "@/types/provider-dashboard";
+import { parseEther } from "viem";
+import { GetWalletClientResult } from "wagmi/dist/actions";
+import { deadline, startAt } from "./deadlineAndStartAt";
+import { toWei } from "@/utils";
+import { createTokenDistribution } from "@/utils/api";
+import { estimateGas } from "@/utils/wallet";
+import { PublicClient } from "wagmi";
+
+export const createErc20TokenDistribution = async (
+ data: ProviderDashboardFormDataProp,
+ provider: PublicClient,
+ signer: GetWalletClientResult,
+ requirementList: RequirementProps[],
+ address: string,
+ userToken: string,
+ setCreateRaffleLoading: any,
+ setCreteRaffleResponse: any
+) => {
+ // const raffleContractAddress = data.selectedChain?.erc20PrizetapAddr;
+ const maxNumberOfEntries = data.maxNumberOfEntries
+ ? data.maxNumberOfEntries
+ : "1000000000";
+ const prizeName = data.isNativeToken
+ ? data.selectedChain.symbol
+ : data.tokenSymbol;
+ // const prizeSymbol = data.isNativeToken
+ // ? data.selectedChain.symbol
+ // : data.tokenSymbol;
+ // const decimals = data.isNativeToken ? 18 : data.tokenDecimals;
+ const prizeAmount = toWei(
+ data.tokenAmount,
+ data.isNativeToken ? 18 : data.tokenDecimals
+ );
+ const twitter = data.twitter
+ ? "https://twitter.com/" + data.twitter?.replace("@", "")
+ : null;
+ const discord = data.discord
+ ? "https://discord.com/" + data.discord.replace("@", "")
+ : null;
+ const telegram = data.telegram
+ ? "https://t.me/" + data.telegram.replace("@", "")
+ : null;
+ const creatorUrl = data.creatorUrl ? "https://" + data.creatorUrl : null;
+ const constraints = requirementList.map((item) => item.pk);
+ const reversed_constraints = requirementList
+ .filter((item) => item.isNotSatisfy)
+ .map((ids) => ids.pk);
+ const constraint_params = requirementList
+ .filter((item) => item.params)
+ .map((item) => ({ [item.name]: item.params }));
+
+ const distributionData = {
+ name: prizeName,
+ distributor: data.provider,
+ distributor_address: address,
+ distributor_url: creatorUrl,
+ discord_url: discord,
+ twitter_url: twitter,
+ email_url: data.email,
+ telegram_url: telegram,
+ token: prizeName,
+ tokenAddress: data.tokenContractAddress,
+ amount: prizeAmount,
+ chain: data.selectedChain.pk,
+ contract: "0x3a798714Af3dB4E2517cf122d5Cd7B18599f5dBC",
+ constraint_params: btoa(
+ JSON.stringify(constraint_params.length > 0 ? constraint_params[0] : {})
+ ),
+ constraints,
+ reversed_constraints:
+ reversed_constraints.length > 1
+ ? reversed_constraints.join(",")
+ : reversed_constraints.length == 1
+ ? reversed_constraints[0].toString()
+ : undefined,
+ start_at: startAt(data.startTimeStamp),
+ deadline: deadline(data.endTimeStamp),
+ max_number_of_claims: maxNumberOfEntries,
+ notes: data.description,
+ necessary_information: data.necessaryInfo,
+ // prize_symbol: prizeSymbol,
+ // decimals: decimals,
+ // winnersCount: data.winnersCount,
+ };
+
+ try {
+ setCreateRaffleLoading(true);
+
+ const raffle = await createTokenDistribution(userToken, distributionData);
+
+ console.log(BigInt(parseEther(data.tokenAmount)));
+ let tx = {
+ to: "0x3a798714Af3dB4E2517cf122d5Cd7B18599f5dBC" as any,
+ value: BigInt(parseEther(data.tokenAmount)),
+ };
+
+ const estimatedGas = await estimateGas(provider, {
+ from: address,
+ to: "0x3a798714Af3dB4E2517cf122d5Cd7B18599f5dBC",
+ value: BigInt(tx.value),
+ }).catch((err: any) => {
+ return err;
+ });
+
+ const hash = await signer
+ ?.sendTransaction({
+ ...tx,
+ ...(estimatedGas ? { gasLimit: estimatedGas } : {}),
+ })
+ .then(async (tx) => {
+ await provider.waitForTransactionReceipt({
+ hash: tx,
+ confirmations: 1,
+ });
+ return tx;
+ });
+
+ console.log(hash);
+
+ // if (!raffle.success) {
+ // return false;
+ // }
+
+ // const rafflePk = raffle.data.id;
+
+ setCreteRaffleResponse({
+ success: true,
+ state: "Done",
+ txHash: hash,
+ message: "Created raffle successfully.",
+ });
+
+ setCreateRaffleLoading(false);
+ } catch (e: any) {
+ console.log(e);
+ setCreteRaffleResponse({
+ success: false,
+ state: "Retry",
+ message: "Something went wrong. Please try again!",
+ });
+ setCreateRaffleLoading(false);
+ }
+};
diff --git a/components/containers/provider-dashboard/helpers/createErc721Raffle.ts b/components/containers/provider-dashboard/helpers/createErc721Raffle.ts
index 2ca23adb..0195f6c4 100644
--- a/components/containers/provider-dashboard/helpers/createErc721Raffle.ts
+++ b/components/containers/provider-dashboard/helpers/createErc721Raffle.ts
@@ -1,6 +1,6 @@
-import { ConstraintParamValues, ProviderDashboardFormDataProp } from "@/types";
+import { RequirementProps, ProviderDashboardFormDataProp } from "@/types";
import { prizeTap721ABI } from "@/types/abis/contracts";
-import { getContract } from "viem";
+import { getContract } from "viem";
import { PublicClient } from "wagmi";
import { deadline, startAt } from "./deadlineAndStartAt";
import { createRaffleApi, updateCreateRaffleTx } from "@/utils/api";
@@ -15,7 +15,7 @@ export const createErc721RaffleCallback = async (
nftIds: string[],
maxParticipants: bigint,
startTime: bigint,
- endTime: bigint,
+ endTime: bigint
) => {
if (!provider || !signer) return;
@@ -26,7 +26,7 @@ export const createErc721RaffleCallback = async (
functionName: "createRaffle",
args: [
currencyAddress,
- nftIds.map(item => BigInt(item)),
+ nftIds.map((item) => BigInt(item)),
maxParticipants,
1n,
startTime,
@@ -43,7 +43,7 @@ export const createErc721RaffleCallback = async (
functionName: "createRaffle",
args: [
currencyAddress,
- nftIds.map(item => BigInt(item)),
+ nftIds.map((item) => BigInt(item)),
maxParticipants,
1n,
startTime,
@@ -59,7 +59,7 @@ export const createErc721Raffle = async (
data: ProviderDashboardFormDataProp,
provider: PublicClient,
signer: GetWalletClientResult,
- requirementList: ConstraintParamValues[],
+ requirementList: RequirementProps[],
address: string,
userToken: string,
setCreateRaffleLoading: any,
@@ -69,54 +69,91 @@ export const createErc721Raffle = async (
const maxNumberOfEntries = data.maxNumberOfEntries
? data.maxNumberOfEntries
: "1000000000";
- const constraints = requirementList.map((item) => item.pk);
- const reversed_constraints = requirementList.filter(item => item.isNotSatisfy).map(ids => ids.pk);
+ const constraints = requirementList.map((item) => item.pk.toString());
+ const reversed_constraints = requirementList
+ .filter((item) => item.isNotSatisfy)
+ .map((ids) => ids.pk);
+
+ const constraintFileList: any = requirementList
+ .filter((item) => item.constraintFile)
+ .map((item) => item.constraintFile);
+
+ const constraint_params = requirementList.reduce((obj: any, item: any) => {
+ obj[item.name] = item.params;
+ return obj;
+ }, {});
+
const prizeName = data.nftName;
- const twitter = 'https://twitter.com/' + data.twitter?.replace('@', '');
- const discord = data.discord ? 'https://discord.com/' + data.discord.replace('@', '') : null;
- const telegram = data.telegram ? 'https://t.me/' + data.telegram.replace('@', '') : null;
- const creatorUrl = data.creatorUrl ? 'https://' + data.creatorUrl : null;
+ const twitter = data.twitter
+ ? "https://twitter.com/" + data.twitter?.replace("@", "")
+ : null;
+ const discord = data.discord
+ ? "https://discord.com/" + data.discord.replace("@", "")
+ : null;
+ const telegram = data.telegram
+ ? "https://t.me/" + data.telegram.replace("@", "")
+ : null;
+ const creatorUrl = data.creatorUrl ? "https://" + data.creatorUrl : null;
+
+ const reversed =
+ reversed_constraints.length > 1
+ ? reversed_constraints.join(",")
+ : reversed_constraints.length == 1
+ ? reversed_constraints[0].toString()
+ : "";
+
+ const nftIdsToString =
+ data.nftTokenIds.length > 1
+ ? data.nftTokenIds.join(",")
+ : data.nftTokenIds[0];
+
+ const formData = new FormData();
if (!data.nftTokenIds) return;
- const raffleData = {
- name: prizeName,
- description: data.description,
- contract: raffleContractAddress,
- creator_name: data.provider,
- prizeAmount: 1,
- decimals: 18,
- creator_address: address,
- prize_asset: data.nftContractAddress,
- prize_name: prizeName,
- prize_symbol: data.nftSymbol,
- chain: Number(data.selectedChain.pk),
- constraints,
- constraint_params: btoa(JSON.stringify({})),
- deadline: deadline(data.endTimeStamp),
- max_number_of_entries: maxNumberOfEntries,
- start_at: startAt(data.startTimeStamp),
- nftIds: data.nftTokenIds.length > 1 ? data.nftTokenIds.join(',') : data.nftTokenIds[0],
- isPrizeNft: true,
- winnersCount: data.nftTokenIds.length,
- discord_url:discord,
- twitter_url:twitter,
- creator_url:creatorUrl,
- telegram_url: telegram,
- reversed_constraints: reversed_constraints.length > 1 ? reversed_constraints.join(',') : reversed_constraints.length == 1 ? reversed_constraints[0].toString() : undefined,
- email_url:data.email,
- necessary_information:data.necessaryInfo
- };
-
-
+ for (let i = 0; i < constraints.length; i++) {
+ formData.append("constraints", constraints[i]);
+ }
+
+ if (constraintFileList) {
+ for (let i = 0; i < constraintFileList.length; i++) {
+ formData.append("constraint_files", constraintFileList[i]);
+ }
+ }
+
+ if (reversed) {
+ formData.append("reversed_constraints", reversed);
+ }
+ formData.append("name", prizeName!);
+ formData.append("description", data.description ?? "");
+ formData.append("contract", raffleContractAddress);
+ formData.append("creator_name", data.provider!);
+ formData.append("prize_amount", "1");
+ formData.append("creator_address", address);
+ formData.append("prize_asset", data.nftContractAddress);
+ formData.append("prize_name", prizeName!);
+ formData.append("prize_symbol", data.nftSymbol!);
+ formData.append("chain", data.selectedChain.pk);
+ formData.append("constraint_params", btoa(JSON.stringify(constraint_params)));
+ formData.append("deadline", deadline(data.endTimeStamp));
+ formData.append("max_number_of_entries", maxNumberOfEntries);
+ formData.append("start_at", startAt(data.startTimeStamp));
+ formData.append("nft_ids", nftIdsToString);
+ formData.append("is_prize_nft", "true");
+ formData.append("winners_count", data.nftTokenIds.length.toString());
+ formData.append("discord_url", discord! ?? "");
+ formData.append("twitter_url", twitter! ?? "");
+ formData.append("creator_url", creatorUrl! ?? "");
+ formData.append("telegram_url", telegram! ?? "");
+ formData.append("email_url", data.email!);
+ formData.append("necessary_information", data.necessaryInfo!);
+
const raffleContract: any = getContract({
address: raffleContractAddress as any,
abi: prizeTap721ABI,
publicClient: provider,
});
-
-
try {
setCreateRaffleLoading(true);
const response = await createErc721RaffleCallback(
@@ -128,35 +165,38 @@ export const createErc721Raffle = async (
data.nftTokenIds,
BigInt(maxNumberOfEntries),
data.startTimeStamp,
- data.endTimeStamp,
+ data.endTimeStamp
);
-
- const raffle = await createRaffleApi(userToken, raffleData);
-
- if (!raffle.success) {
- return false;
- }
-
- const rafflePk = raffle.data.id;
-
- if (!response) return;
+ if (!response) throw new Error("Contract hash not found");
- await provider.waitForTransactionReceipt({
+ const transactionInfo = await provider.waitForTransactionReceipt({
hash: response,
confirmations: 1,
});
+ const raffle = await createRaffleApi(userToken, formData);
+
+ if (!raffle.success) {
+ return false;
+ }
+
+ const rafflePk = raffle.data.id;
+
setCreteRaffleResponse({
success: true,
state: "Done",
- txHash: response,
+ txHash: transactionInfo.transactionHash,
message: "Created raffle successfully.",
});
setCreateRaffleLoading(false);
- await updateCreateRaffleTx(userToken, rafflePk, response);
+ await updateCreateRaffleTx(
+ userToken,
+ rafflePk,
+ transactionInfo.transactionHash
+ );
} catch (e: any) {
console.log(e);
setCreteRaffleResponse({
diff --git a/components/containers/provider-dashboard/helpers/getErc20TokenContract.ts b/components/containers/provider-dashboard/helpers/getErc20TokenContract.ts
index b7e89acf..0e35948a 100644
--- a/components/containers/provider-dashboard/helpers/getErc20TokenContract.ts
+++ b/components/containers/provider-dashboard/helpers/getErc20TokenContract.ts
@@ -10,6 +10,7 @@ export const getErc20TokenContract = async (
setData: any,
setIsErc20Approved: any,
setTokenContractStatus: any,
+ setApproveAllowance: any,
) => {
if (!provider || !address) return;
@@ -52,11 +53,7 @@ export const getErc20TokenContract = async (
tokenDecimals: r3,
userTokenBalance: r4?.toString(),
}));
- setIsErc20Approved(
- Number(fromWei(r5.toString(), r3)) != 0 &&
- Number(fromWei(r5.toString(), r3)) >= Number(data.totalAmount)
- );
-
+ setApproveAllowance(Number(fromWei(r5.toString(), r3)))
setTokenContractStatus((prev: any) => ({...prev,
isValid: ContractValidationStatus.Valid,
checking: false,}))
diff --git a/components/containers/provider-dashboard/helpers/isValidContractAddress.ts b/components/containers/provider-dashboard/helpers/isValidContractAddress.ts
new file mode 100644
index 00000000..d1c8134a
--- /dev/null
+++ b/components/containers/provider-dashboard/helpers/isValidContractAddress.ts
@@ -0,0 +1,14 @@
+import { PublicClient } from "viem";
+
+export const isValidContractAddress =
+ async (contractAddress: string, provider: PublicClient) => {
+ try {
+ const res = await provider?.getBytecode({
+ address: contractAddress as any,
+ });
+ if(res == undefined) return false
+ return res != "0x";
+ } catch {
+ return false;
+ }
+ }
diff --git a/components/containers/provider-dashboard/hooks/useAddRequirement.ts b/components/containers/provider-dashboard/hooks/useAddRequirement.ts
index 48ff6eda..75b06afb 100644
--- a/components/containers/provider-dashboard/hooks/useAddRequirement.ts
+++ b/components/containers/provider-dashboard/hooks/useAddRequirement.ts
@@ -1,23 +1,38 @@
"use client";
-import { ConstraintParamValues } from "@/types";
+import { RequirementProps } from "@/types";
-const useAddRequirement = (handleBackToRequirementModal: any, insertRequirement:any, updateRequirement:any) => {
+const useAddRequirement = (
+ handleBackToConstraintListModal: any,
+ insertRequirement: any,
+ updateRequirement: any
+) => {
const addRequirements = (
- existRequirement: any,
- params: ConstraintParamValues | null,
- id: number,
+ existRequirement: RequirementProps | null,
+ pk: number,
name: string,
title: string,
- isNotSatisfy: boolean
+ isNotSatisfy: boolean,
+ requirementValues: any,
+ constraintFiles: any
) => {
- if (id) {
- handleBackToRequirementModal();
- if (!existRequirement) {
- insertRequirement(params, id, name, title, isNotSatisfy);
- } else {
- updateRequirement(id, params, isNotSatisfy);
- }
+ handleBackToConstraintListModal();
+ if (!existRequirement) {
+ insertRequirement(
+ pk,
+ name,
+ title,
+ isNotSatisfy,
+ requirementValues,
+ constraintFiles
+ );
+ } else {
+ updateRequirement(
+ existRequirement,
+ isNotSatisfy,
+ requirementValues,
+ constraintFiles
+ );
}
};
return addRequirements;
diff --git a/components/containers/provider-dashboard/layout.tsx b/components/containers/provider-dashboard/layout.tsx
index ce0d406c..d4719af9 100644
--- a/components/containers/provider-dashboard/layout.tsx
+++ b/components/containers/provider-dashboard/layout.tsx
@@ -1,6 +1,6 @@
"use client";
-import { FC, PropsWithChildren, useEffect, useState } from "react";
+import { FC, PropsWithChildren } from "react";
import Header from "./Header";
import { usePathname } from "next/navigation";
import RoutePath from "@/utils/routes";
@@ -69,12 +69,10 @@ const ProviderTabs: FC = () => {
>
Gas Tap
diff --git a/components/containers/token-tap/Modals/InitialBody.tsx b/components/containers/token-tap/Modals/InitialBody.tsx
index 35f420b0..e9756af2 100644
--- a/components/containers/token-tap/Modals/InitialBody.tsx
+++ b/components/containers/token-tap/Modals/InitialBody.tsx
@@ -8,7 +8,7 @@ import { FC } from "react";
import { Token } from "@/types";
import { useTokenTapContext } from "@/context/tokenTapProvider";
import { DropIconWrapper } from "../../modals/claimModal.style";
-import WalletAddress from "../../prize-tap/Modals/wallet-address";
+import WalletAddress from "../../../../app/prizetap/components/Modals/wallet-address";
const InitialBody: FC<{
token: Token;
diff --git a/components/containers/token-tap/searchInput.tsx b/components/containers/token-tap/searchInput.tsx
index 4b0258c3..3738017b 100644
--- a/components/containers/token-tap/searchInput.tsx
+++ b/components/containers/token-tap/searchInput.tsx
@@ -58,7 +58,7 @@ const SearchInput = ({ className = "" }: SearchInputProps) => {
>
{
+ if (!userToken || chainList.length) return;
+ updateChainList();
+ updateActiveClaimHistory();
+ updateOneTimeClaimedList();
+ updateFuelChampionList();
+ }, [
+ chainList.length,
+ updateActiveClaimHistory,
+ updateChainList,
+ updateFuelChampionList,
+ updateOneTimeClaimedList,
+ userToken,
+ ]);
+
useEffect(() => {
if (activeChain) {
setActiveClaimReceipt(
diff --git a/context/prizeTapProvider.tsx b/context/prizeTapProvider.tsx
index 91924e9d..f6a88fbd 100644
--- a/context/prizeTapProvider.tsx
+++ b/context/prizeTapProvider.tsx
@@ -20,8 +20,8 @@ import {
import { useUserProfileContext } from "./userProfile";
import { useRefreshWithInitial } from "@/utils/hooks/refresh";
import { FAST_INTERVAL } from "@/constants";
-import { Address, useContractWrite } from "wagmi";
-import { prizeTap721ABI, prizeTapABI } from "@/types/abis/contracts";
+import { useContractWrite } from "wagmi";
+import { prizeTapABI } from "@/types/abis/contracts";
import { useWalletAccount } from "@/utils/wallet";
import { waitForTransaction } from "wagmi/actions";
import { useGlobalContext } from "./globalProvider";
@@ -191,7 +191,6 @@ const PrizeTapProvider: FC = ({
const id = enrollOrClaimPayload?.userEntry?.pk;
- console.log(id);
setClaimOrEnrollLoading(true);
if (claimMethod !== "Claim") {
@@ -256,7 +255,7 @@ const PrizeTapProvider: FC = ({
const openEnrollModal = useCallback(
(raffle: Prize, method: string | null) => {
- if (!isConnected) {
+ if (!isConnected && method !== "Winners") {
setIsWalletPromptOpen(true);
return;
}
diff --git a/context/providerDashboardContext.tsx b/context/providerDashboardContext.tsx
index 00247b08..da6303bd 100644
--- a/context/providerDashboardContext.tsx
+++ b/context/providerDashboardContext.tsx
@@ -2,7 +2,7 @@
import {
Chain,
- ConstraintParamValues,
+ RequirementProps,
ConstraintProps,
ContractStatus,
ContractValidationStatus,
@@ -10,7 +10,6 @@ import {
ErrorObjectProp,
NftRangeProps,
NftStatusProp,
- Prize,
ProviderDashboardFormDataProp,
UploadedFileProps,
UserRafflesProps,
@@ -49,6 +48,7 @@ import { checkNftsAreValid } from "@/components/containers/provider-dashboard/he
import { checkSocialMediaValidation } from "@/components/containers/provider-dashboard/helpers/checkSocialMediaValidation";
import Big from "big.js";
import { NullCallback } from "@/utils";
+import { isValidContractAddress } from "@/components/containers/provider-dashboard/helpers/isValidContractAddress";
const formInitialData: ProviderDashboardFormDataProp = {
provider: "",
description: "",
@@ -158,7 +158,7 @@ export const ProviderDashboardContext = createContext<{
handleSelectConstraint: (constraint: ConstraintProps) => void;
isModalOpen: boolean;
selectedConstraintTitle: string | null;
- handleBackToRequirementModal: () => void;
+ handleBackToConstraintListModal: () => void;
chainList: Chain[];
selectedChain: Chain | null;
setSelectedChain: (chain: Chain) => void;
@@ -174,18 +174,18 @@ export const ProviderDashboardContext = createContext<{
selectNewOffer: boolean;
handleSelectNewOffer: (select: boolean) => void;
insertRequirement: (
- requirement: ConstraintParamValues | null,
- id: number,
+ pk: number,
name: string,
title: string,
- isNotSatisfy: boolean
+ isNotSatisfy: boolean,
+ requirementValues: any
) => void;
- requirementList: ConstraintParamValues[];
- deleteRequirement: (id: number) => void;
+ requirementList: RequirementProps[];
+ deleteRequirement: (pk: number) => void;
updateRequirement: (
- id: number,
- requirements: ConstraintParamValues | null,
- isNotSatisfy: boolean
+ requirement: RequirementProps,
+ isNotSatisfy: boolean,
+ requirementValues: any
) => void;
handleSelectNativeToken: (e: boolean) => void;
handleCreateRaffle: () => void;
@@ -198,9 +198,8 @@ export const ProviderDashboardContext = createContext<{
isErc20Approved: boolean;
isApprovedAll: boolean;
approveLoading: boolean;
- constraintsList: ConstraintProps[];
+ constraintsListApi: ConstraintProps[] | undefined;
handleApproveErc721Token: () => void;
- handleGetConstraints: () => void;
updateChainList: () => void;
handleCheckForReason: (raffle: UserRafflesProps) => void;
handleShowUserDetails: (raffle: UserRafflesProps) => void;
@@ -235,8 +234,7 @@ export const ProviderDashboardContext = createContext<{
endDateState: any;
setEndDateState: (date: any) => void;
userRaffle: UserRafflesProps | undefined;
- handleSetClaimPeriodic: (e: boolean) => void;
- claimPeriodic: boolean;
+ allChainList: Chain[] | undefined;
}>({
page: 0,
setPage: NullCallback,
@@ -256,7 +254,7 @@ export const ProviderDashboardContext = createContext<{
handleSelectConstraint: NullCallback,
isModalOpen: false,
selectedConstraintTitle: null,
- handleBackToRequirementModal: NullCallback,
+ handleBackToConstraintListModal: NullCallback,
chainList: [],
selectedChain: null,
setSelectedChain: NullCallback,
@@ -287,10 +285,9 @@ export const ProviderDashboardContext = createContext<{
handleApproveErc20Token: NullCallback,
isErc20Approved: false,
approveLoading: false,
- constraintsList: [],
+ constraintsListApi: [] as any,
isApprovedAll: false,
handleApproveErc721Token: NullCallback,
- handleGetConstraints: NullCallback,
updateChainList: NullCallback,
handleCheckForReason: NullCallback,
handleShowUserDetails: NullCallback,
@@ -333,17 +330,21 @@ export const ProviderDashboardContext = createContext<{
endDateState: null,
setEndDateState: NullCallback,
userRaffle: {} as any,
- claimPeriodic: false,
- handleSetClaimPeriodic: NullCallback,
+ allChainList: [] as any,
});
const ProviderDashboard: FC<
- PropsWithChildren & { rafflesInitial?: UserRafflesProps }
-> = ({ children, rafflesInitial }) => {
- const [requirementList, setRequirementList] = useState<
- ConstraintParamValues[]
- >([]);
+ PropsWithChildren & {
+ rafflesInitial?: UserRafflesProps;
+ allChains?: Chain[];
+ constraintListApi?: ConstraintProps[];
+ }
+> = ({ children, rafflesInitial, allChains, constraintListApi }) => {
+ const [requirementList, setRequirementList] = useState(
+ []
+ );
+ const [allChainList] = useState(allChains);
const [selectNewOffer, setSelectNewOffer] = useState(false);
const [searchPhrase, setSearchPhrase] = useState("");
@@ -419,11 +420,11 @@ const ProviderDashboard: FC<
const [numberOfNfts, setNumberOfNfts] = useState("");
- const [claimPeriodic, setClaimPeriodic] = useState(false);
-
const [data, setData] =
useState(formInitialData);
+ const [approveAllowance, setApproveAllowance] = useState(0);
+
const [socialMediaValidation, setSocialMediaValidation] = useState({
creatorUrl: true,
twitter: true,
@@ -446,7 +447,9 @@ const ProviderDashboard: FC<
);
};
- const [constraintsList, setConstraintsList] = useState([]);
+ const [constraintsListApi, setConstraintsListApi] = useState<
+ ConstraintProps[] | undefined
+ >(constraintListApi);
const { userToken } = useUserProfileContext();
const signer = useWalletSigner();
@@ -467,45 +470,14 @@ const ProviderDashboard: FC<
);
}, [chainList, searchPhrase]);
- const deleteRequirement = (id: number) => {
- setRequirementList((prev) => prev.filter((item) => item.pk != id));
+ const deleteRequirement = (pk: number) => {
+ setRequirementList((prev) => prev.filter((item) => item.pk != pk));
};
const handleSelectNewOffer = (select: boolean) => {
setSelectNewOffer(select);
};
- const updateRequirement = (
- id: number,
- requirements: ConstraintParamValues | null,
- isNotSatisfy: boolean
- ) => {
- if (!requirements) return;
-
- const newItem = requirementList.map((item) => {
- if (item.pk == id) {
- return { ...requirements, isNotSatisfy };
- }
- return item;
- });
-
- setRequirementList(newItem);
- };
-
- const isValidContractAddress = useCallback(
- async (contractAddress: string) => {
- try {
- const res = await provider?.getBytecode({
- address: contractAddress as any,
- });
- return res != "0x";
- } catch {
- return false;
- }
- },
- [provider]
- );
-
const checkContractInfo = useCallback(async () => {
if (!data.isNft && provider && address) {
await getErc20TokenContract(
@@ -514,7 +486,8 @@ const ProviderDashboard: FC<
provider,
setData,
setIsErc20Approved,
- setTokenContractStatus
+ setTokenContractStatus,
+ setApproveAllowance
);
}
@@ -533,7 +506,10 @@ const ProviderDashboard: FC<
const checkContractAddress = useCallback(
async (contractAddress: string) => {
const step1Check = isAddress(contractAddress);
- const step2Check = await isValidContractAddress(contractAddress);
+ const step2Check = await isValidContractAddress(
+ contractAddress,
+ provider
+ );
const isValid = !!(step1Check && step2Check);
if (isValid) {
checkContractInfo();
@@ -826,6 +802,7 @@ const ProviderDashboard: FC<
...prev,
totalAmount: new Big(totalAmount).toFixed(),
}));
+ setIsErc20Approved(approveAllowance >= Number(totalAmount));
} else {
setData((prev) => ({
...prev,
@@ -872,12 +849,6 @@ const ProviderDashboard: FC<
setSearchPhrase("");
};
- const handleGetConstraints = async () => {
- if (constraintsList.length != 0) return;
- const res = await getConstraintsApi();
- setConstraintsList(res);
- };
-
const handleChange = (e: {
target: { type: any; name: any; checked: any; value: any };
}) => {
@@ -910,7 +881,7 @@ const ProviderDashboard: FC<
setSelectedConstrains(constraint);
};
- const handleBackToRequirementModal = () => {
+ const handleBackToConstraintListModal = () => {
setSelectedConstrains(null);
setSelectedConstraintTitle(null);
};
@@ -1012,25 +983,48 @@ const ProviderDashboard: FC<
};
const insertRequirement = (
- requirement: ConstraintParamValues | null,
- id: number,
+ pk: number,
name: string,
title: string,
- isNotSatisfy: boolean
+ isNotSatisfy: boolean,
+ requirementValues: any,
+ file?: []
) => {
setRequirementList([
...requirementList,
{
- pk: id,
- values: !requirement ? null : { 1: "", 2: "", 3: "" },
- name,
- title,
- isNotSatisfy,
+ pk: pk,
+ params: requirementValues,
+ name: name,
+ title: title,
+ isNotSatisfy: isNotSatisfy,
isReversed: isNotSatisfy,
+ constraintFile: file,
},
]);
};
+ const updateRequirement = (
+ requirement: RequirementProps,
+ isNotSatisfy: boolean,
+ requirementValues: any,
+ file?: []
+ ) => {
+ if (!requirement) return;
+ const newItem = requirementList.map((item) => {
+ if (item.pk == requirement.pk) {
+ return {
+ ...requirement,
+ isNotSatisfy,
+ params: requirementValues,
+ constraintFile: file,
+ };
+ }
+ return item;
+ });
+ setRequirementList(newItem);
+ };
+
const handleCheckForReason = (raffle: UserRafflesProps) => {
setPage(5);
setSelectedRaffleForCheckReason(raffle);
@@ -1071,10 +1065,10 @@ const ProviderDashboard: FC<
}));
setIsShowingDetails(true);
setSelectNewOffer(true);
- // raffle.isPrizeNft
- // ? handleSetContractStatus(true, true, false, true)
- // : handleSetContractStatus(false, true, false, true);
- setConstraintsList(await getConstraintsApi());
+ setNumberOfNfts(
+ raffle.nftIds ? raffle.nftIds.split(",").length.toString() : ""
+ );
+ setConstraintsListApi(await getConstraintsApi());
setRequirementList(
raffle.constraints.map((constraint) =>
constraint.isReversed
@@ -1174,7 +1168,7 @@ const ProviderDashboard: FC<
selectedConstrains,
handleSelectConstraint,
selectedConstraintTitle,
- handleBackToRequirementModal,
+ handleBackToConstraintListModal,
chainList,
selectedChain,
setSelectedChain,
@@ -1207,10 +1201,9 @@ const ProviderDashboard: FC<
handleApproveErc20Token,
isErc20Approved,
approveLoading,
- constraintsList,
+ constraintsListApi,
isApprovedAll,
handleApproveErc721Token,
- handleGetConstraints,
updateChainList,
handleCheckForReason,
handleShowUserDetails,
@@ -1239,8 +1232,7 @@ const ProviderDashboard: FC<
endDateState,
setEndDateState,
userRaffle,
- claimPeriodic,
- handleSetClaimPeriodic: setClaimPeriodic,
+ allChainList,
}}
>
{children}
diff --git a/context/providerDashboardTokenTapContext.tsx b/context/providerDashboardTokenTapContext.tsx
index beba50f9..b13cbc14 100644
--- a/context/providerDashboardTokenTapContext.tsx
+++ b/context/providerDashboardTokenTapContext.tsx
@@ -2,7 +2,7 @@
import {
Chain,
- ConstraintParamValues,
+ RequirementProps,
ConstraintProps,
ContractStatus,
ContractValidationStatus,
@@ -10,7 +10,6 @@ import {
ErrorObjectProp,
NftRangeProps,
NftStatusProp,
- Prize,
ProviderDashboardFormDataProp,
UploadedFileProps,
UserRafflesProps,
@@ -39,9 +38,8 @@ import { getErc721TokenContract } from "@/components/containers/provider-dashboa
import { getErc20TokenContract } from "@/components/containers/provider-dashboard/helpers/getErc20TokenContract";
import { isAddress, zeroAddress } from "viem";
import { ZERO_ADDRESS } from "@/constants";
-import { getConstraintsApi, getProviderDashboardValidChain } from "@/utils/api";
-import { createErc721Raffle } from "@/components/containers/provider-dashboard/helpers/createErc721Raffle";
-import { createErc20Raffle } from "@/components/containers/provider-dashboard/helpers/createErc20Raffle";
+import { getConstraintsApi, getTokenTapValidChain } from "@/utils/api";
+import { createErc20TokenDistribution } from "@/components/containers/provider-dashboard/helpers/createErc20TokenDistribution";
import { approveErc721Token } from "@/components/containers/provider-dashboard/helpers/approveErc721Token";
import { approveErc20Token } from "@/components/containers/provider-dashboard/helpers/approveErc20Token";
import { checkNftsAreValid } from "@/components/containers/provider-dashboard/helpers/checkAreNftsValid";
@@ -49,6 +47,7 @@ import { checkNftsAreValid } from "@/components/containers/provider-dashboard/he
import { checkSocialMediaValidation } from "@/components/containers/provider-dashboard/helpers/checkSocialMediaValidation";
import Big from "big.js";
import { NullCallback } from "@/utils";
+import { isValidContractAddress } from "@/components/containers/provider-dashboard/helpers/isValidContractAddress";
const formInitialData: ProviderDashboardFormDataProp = {
provider: "",
description: "",
@@ -138,6 +137,7 @@ const errorMessages = {
endLessThanStart: "The end time cannot be less than the start time.",
invalidInput: "Invalid input",
};
+
export const TokenTapContext = createContext<{
page: number;
setPage: (page: number) => void;
@@ -157,7 +157,7 @@ export const TokenTapContext = createContext<{
handleSelectConstraint: (constraint: ConstraintProps) => void;
isModalOpen: boolean;
selectedConstraintTitle: string | null;
- handleBackToRequirementModal: () => void;
+ handleBackToConstraintListModal: () => void;
chainList: Chain[];
selectedChain: Chain | null;
setSelectedChain: (chain: Chain) => void;
@@ -173,18 +173,18 @@ export const TokenTapContext = createContext<{
selectNewOffer: boolean;
handleSelectNewOffer: (select: boolean) => void;
insertRequirement: (
- requirement: ConstraintParamValues | null,
- id: number,
+ pk: number,
name: string,
title: string,
- isNotSatisfy: boolean
+ isNotSatisfy: boolean,
+ requirementValues: any
) => void;
- requirementList: ConstraintParamValues[];
+ requirementList: RequirementProps[];
deleteRequirement: (id: number) => void;
updateRequirement: (
- id: number,
- requirements: ConstraintParamValues | null,
- isNotSatisfy: boolean
+ requirement: RequirementProps,
+ isNotSatisfy: boolean,
+ requirementValues: any
) => void;
handleSelectNativeToken: (e: boolean) => void;
handleCreateRaffle: () => void;
@@ -197,9 +197,8 @@ export const TokenTapContext = createContext<{
isErc20Approved: boolean;
isApprovedAll: boolean;
approveLoading: boolean;
- constraintsList: ConstraintProps[];
+ constraintsListApi: ConstraintProps[] | undefined;
handleApproveErc721Token: () => void;
- handleGetConstraints: () => void;
updateChainList: () => void;
handleCheckForReason: (raffle: UserRafflesProps) => void;
handleShowUserDetails: (raffle: UserRafflesProps) => void;
@@ -236,6 +235,7 @@ export const TokenTapContext = createContext<{
userRaffle: UserRafflesProps | undefined;
handleSetClaimPeriodic: (e: boolean) => void;
claimPeriodic: boolean;
+ allChainList: Chain[] | undefined;
}>({
page: 0,
setPage: NullCallback,
@@ -255,7 +255,7 @@ export const TokenTapContext = createContext<{
handleSelectConstraint: NullCallback,
isModalOpen: false,
selectedConstraintTitle: null,
- handleBackToRequirementModal: NullCallback,
+ handleBackToConstraintListModal: NullCallback,
chainList: [],
selectedChain: null,
setSelectedChain: NullCallback,
@@ -286,10 +286,9 @@ export const TokenTapContext = createContext<{
handleApproveErc20Token: NullCallback,
isErc20Approved: false,
approveLoading: false,
- constraintsList: [],
+ constraintsListApi: [] as any,
isApprovedAll: false,
handleApproveErc721Token: NullCallback,
- handleGetConstraints: NullCallback,
updateChainList: NullCallback,
handleCheckForReason: NullCallback,
handleShowUserDetails: NullCallback,
@@ -334,14 +333,21 @@ export const TokenTapContext = createContext<{
userRaffle: {} as any,
claimPeriodic: false,
handleSetClaimPeriodic: NullCallback,
+ allChainList: [] as any,
});
const TokenTapProvider: FC<
- PropsWithChildren & { rafflesInitial?: UserRafflesProps }
-> = ({ children, rafflesInitial }) => {
- const [requirementList, setRequirementList] = useState<
- ConstraintParamValues[]
- >([]);
+ PropsWithChildren & {
+ rafflesInitial?: UserRafflesProps;
+ allChains?: Chain[];
+ constraintListApi?: ConstraintProps[];
+ }
+> = ({ children, rafflesInitial, allChains, constraintListApi }) => {
+ const [requirementList, setRequirementList] = useState(
+ []
+ );
+
+ const [allChainList] = useState(allChains);
const [selectNewOffer, setSelectNewOffer] = useState(false);
@@ -377,6 +383,8 @@ const TokenTapProvider: FC<
canDisplayStatus: false,
});
+ const [approveAllowance, setApproveAllowance] = useState(0);
+
const [insufficientBalance, setInsufficientBalance] =
useState(false);
@@ -445,7 +453,9 @@ const TokenTapProvider: FC<
);
};
- const [constraintsList, setConstraintsList] = useState([]);
+ const [constraintsListApi, setConstraintsListApi] = useState<
+ ConstraintProps[] | undefined
+ >(constraintListApi);
const { userToken } = useUserProfileContext();
const signer = useWalletSigner();
@@ -474,37 +484,6 @@ const TokenTapProvider: FC<
setSelectNewOffer(select);
};
- const updateRequirement = (
- id: number,
- requirements: ConstraintParamValues | null,
- isNotSatisfy: boolean
- ) => {
- if (!requirements) return;
-
- const newItem = requirementList.map((item) => {
- if (item.pk == id) {
- return { ...requirements, isNotSatisfy };
- }
- return item;
- });
-
- setRequirementList(newItem);
- };
-
- const isValidContractAddress = useCallback(
- async (contractAddress: string) => {
- try {
- const res = await provider?.getBytecode({
- address: contractAddress as any,
- });
- return res != "0x";
- } catch {
- return false;
- }
- },
- [provider]
- );
-
const checkContractInfo = useCallback(async () => {
if (!data.isNft && provider && address) {
await getErc20TokenContract(
@@ -513,7 +492,8 @@ const TokenTapProvider: FC<
provider,
setData,
setIsErc20Approved,
- setTokenContractStatus
+ setTokenContractStatus,
+ setApproveAllowance
);
}
@@ -532,7 +512,10 @@ const TokenTapProvider: FC<
const checkContractAddress = useCallback(
async (contractAddress: string) => {
const step1Check = isAddress(contractAddress);
- const step2Check = await isValidContractAddress(contractAddress);
+ const step2Check = await isValidContractAddress(
+ contractAddress,
+ provider
+ );
const isValid = !!(step1Check && step2Check);
if (isValid) {
checkContractInfo();
@@ -825,6 +808,7 @@ const TokenTapProvider: FC<
...prev,
totalAmount: new Big(totalAmount).toFixed(),
}));
+ setIsErc20Approved(approveAllowance >= Number(totalAmount));
} else {
setData((prev) => ({
...prev,
@@ -853,7 +837,7 @@ const TokenTapProvider: FC<
const updateChainList = useCallback(async () => {
try {
- const newChainList = await getProviderDashboardValidChain();
+ const newChainList = await getTokenTapValidChain();
setChainList(newChainList);
} catch (e) {}
}, []);
@@ -871,12 +855,6 @@ const TokenTapProvider: FC<
setSearchPhrase("");
};
- const handleGetConstraints = async () => {
- if (constraintsList.length != 0) return;
- const res = await getConstraintsApi();
- setConstraintsList(res);
- };
-
const handleChange = (e: {
target: { type: any; name: any; checked: any; value: any };
}) => {
@@ -909,7 +887,7 @@ const TokenTapProvider: FC<
setSelectedConstrains(constraint);
};
- const handleBackToRequirementModal = () => {
+ const handleBackToConstraintListModal = () => {
setSelectedConstrains(null);
setSelectedConstraintTitle(null);
};
@@ -984,52 +962,62 @@ const TokenTapProvider: FC<
const handleCreateRaffle = () => {
if (!address || !address || !provider || !userToken || !signer) return;
-
- if (!data.isNft) {
- createErc20Raffle(
- data,
- provider,
- signer,
- requirementList,
- address,
- userToken,
- setCreateRaffleLoading,
- setCreteRaffleResponse
- );
- } else {
- createErc721Raffle(
- data,
- provider,
- signer,
- requirementList,
- address,
- userToken,
- setCreateRaffleLoading,
- setCreteRaffleResponse
- );
- }
+ createErc20TokenDistribution(
+ data,
+ provider,
+ signer,
+ requirementList,
+ address,
+ userToken,
+ setCreateRaffleLoading,
+ setCreteRaffleResponse
+ );
};
const insertRequirement = (
- requirement: ConstraintParamValues | null,
- id: number,
+ pk: number,
name: string,
title: string,
- isNotSatisfy: boolean
+ isNotSatisfy: boolean,
+ requirementValues: any,
+ file?: []
) => {
setRequirementList([
...requirementList,
{
- pk: id,
- values: !requirement ? null : { 1: "", 2: "", 3: "" },
- name,
- title,
- isNotSatisfy,
+ pk: pk,
+ params: requirementValues,
+ name: name,
+ title: title,
+ isNotSatisfy: isNotSatisfy,
isReversed: isNotSatisfy,
+ constraintFile: file,
},
]);
};
+ const updateRequirement = (
+ requirement: RequirementProps,
+ isNotSatisfy: boolean,
+ requirementValues: any,
+ file?: []
+ ) => {
+ if (!requirement) return;
+ const newItem = requirementList.map((item) => {
+ if (item.pk == requirement.pk) {
+ return {
+ ...requirement,
+ isNotSatisfy,
+ params: requirementValues,
+ constraintFile: file,
+ };
+ }
+ return item;
+ });
+
+ setRequirementList(newItem);
+ };
+
const handleCheckForReason = (raffle: UserRafflesProps) => {
setPage(5);
setSelectedRaffleForCheckReason(raffle);
@@ -1070,10 +1058,10 @@ const TokenTapProvider: FC<
}));
setIsShowingDetails(true);
setSelectNewOffer(true);
- // raffle.isPrizeNft
- // ? handleSetContractStatus(true, true, false, true)
- // : handleSetContractStatus(false, true, false, true);
- setConstraintsList(await getConstraintsApi());
+ setNumberOfNfts(
+ raffle.nftIds ? raffle.nftIds.split(",").length.toString() : ""
+ );
+ setConstraintsListApi(await getConstraintsApi());
setRequirementList(
raffle.constraints.map((constraint) =>
constraint.isReversed
@@ -1173,7 +1161,7 @@ const TokenTapProvider: FC<
selectedConstrains,
handleSelectConstraint,
selectedConstraintTitle,
- handleBackToRequirementModal,
+ handleBackToConstraintListModal,
chainList,
selectedChain,
setSelectedChain,
@@ -1206,10 +1194,9 @@ const TokenTapProvider: FC<
handleApproveErc20Token,
isErc20Approved,
approveLoading,
- constraintsList,
+ constraintsListApi,
isApprovedAll,
handleApproveErc721Token,
- handleGetConstraints,
updateChainList,
handleCheckForReason,
handleShowUserDetails,
@@ -1240,6 +1227,7 @@ const TokenTapProvider: FC<
userRaffle,
claimPeriodic,
handleSetClaimPeriodic: setClaimPeriodic,
+ allChainList,
}}
>
{children}
diff --git a/context/socialAccountContext.tsx b/context/socialAccountContext.tsx
new file mode 100644
index 00000000..daa94dd2
--- /dev/null
+++ b/context/socialAccountContext.tsx
@@ -0,0 +1,13 @@
+import { UserConnection } from "@/types";
+import { NullCallback } from "@/utils";
+import { useContext, createContext } from "react";
+
+export const useSocialACcountContext = () => useContext(SocialAccountContext);
+
+export const SocialAccountContext = createContext<{
+ connections: UserConnection;
+ addConnection: (key: string, data: any) => void;
+}>({
+ connections: {},
+ addConnection: NullCallback,
+});
diff --git a/package.json b/package.json
index 27c10e00..adb354ba 100644
--- a/package.json
+++ b/package.json
@@ -49,6 +49,7 @@
"@types/big.js": "^6.2.2",
"@types/bn.js": "^5.1.5",
"@types/node": "latest",
+ "@types/nprogress": "^0.2.3",
"@types/react": "latest",
"@types/react-dom": "latest",
"@types/react-lottie": "^1.2.10",
diff --git a/public/assets/images/404.svg b/public/assets/images/404.svg
new file mode 100644
index 00000000..0c77ecc7
--- /dev/null
+++ b/public/assets/images/404.svg
@@ -0,0 +1,256 @@
+
diff --git a/public/assets/images/provider-dashboard/deposit-nft.png b/public/assets/images/provider-dashboard/deposit-nft.png
new file mode 100644
index 0000000000000000000000000000000000000000..d47b0c165f93f67eff454bec001e2c405d8a8c2f
GIT binary patch
literal 77736
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