# How to implement the proposal validation?

## Good to Know

In this example, we will use reactJS, Ether.js and formik to handle the form on the frontend. You will find a full code example with all imports at the end of tutorial.&#x20;

## ① The proposal validation process

To validate a proposal the buyer have to send the validated amount to the escrow contract, in our Dapp, this step happen by clicking on the validate proposal button in the `ValidateProposalModal` component.

But let's see how the process is organized

**1 - `ServiceDetail` component :** you will have in this component the mapping of all proposal, it use the `ProposalItem` component.

```tsx
<div className='grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-4'>
  {validatedProposal ? (
    <ProposalItem proposal={validatedProposal} />
  ) : (
    proposals.map((proposal, i) => {
      return (
        <div key={i}>
          {(service.status === ServiceStatusEnum.Opened ||
            proposal.status === ProposalStatusEnum.Validated) && (
            <ProposalItem proposal={proposal} />
          )}
        </div>
      );
    })
  )}
</div>
```

**2-`ProposalItem`** component : this component will display all the proposal details and it use the `ValidateProposalModal`

```tsx
<div className='flex flex-row gap-4 justify-between items-center border-t border-gray-100 pt-4'>
  <p className='text-gray-900 font-bold line-clamp-1 flex-1'>
    {renderTokenAmount(proposal.rateToken, proposal.rateAmount)}
  </p>
  {account && isBuyer && proposal.status === ProposalStatusEnum.Pending && (
    <ValidateProposalModal proposal={proposal} account={account} />
  )}
</div>
```

**3-`ValidateProposalModal`**&#x63;omponent : this component will display a modal with all the information of the proposal, including the fee's summary, total, account balance

* **Validate proposal** button : on submit, it will call ValidateProposal function

```tsx
const onSubmit = async () => {
    if (!signer || !provider) {
      return;
    }
    await validateProposal(
      signer,
      provider,
      proposal.service.id,
      proposal.seller.id,
      proposal.rateToken.address,
      proposal.cid,
      totalAmount,
    );
    setShow(false);
  };
```

* **Decline** button : used to decline a proposal
* **Contact the seller** button : used to contact and chat with the seller with the xmtp decentralized instant message service

Let's focus on `ValidateProposalModal` component

**4-`ValidateProposal`** component : this component is the **core** of the proposal validation process.

As you can see below it take a few parameter

```tsx
export const validateProposal = async (
  signer: Signer,
  provider: Provider,
  serviceId: string,
  proposalId: string,
  rateToken: string,
  cid: string,
  value: ethers.BigNumber,
): Promise<void> => {
  const talentLayerEscrow = new Contract(
    config.contracts.talentLayerEscrow,
    TalentLayerEscrow.abi,
    signer,
  );
```

1. `signer: Signer`: This parameter is of type `Signer` and is required. It represents the Ethereum account that will sign the transaction.
2. `provider: Provider`: This parameter is of type `Provider` and is required. It represents the Ethereum network provider that will be used to submit the transaction.
3. `serviceId: string`: This parameter is of type `string` and is required. It represents the ID of the service concerned by the proposal.
4. `proposalId: string`: This parameter is of type `string` and is required. It represents the ID of the proposal that is being validated.
5. `rateToken: string`: This parameter is of type `string` and is required. It represents the address of the ERC-20 token that is being used to pay for the service. If this is set to `ethers.constants.AddressZero`, then the payment is being made in Ether
6. `cid: string`: This parameter is of type `string` and is required. It represents the IPFS CID of the evidence that is being used to validate the proposal.
7. `value: ethers.BigNumber`: This parameter is of type `ethers.BigNumber` and is required. It represents the amount of tokens or that is being used to pay for the service.

Then you have the `createTranscation` call, the proposal will be validated as soon as the transcation is validated

\==> If the used token is ETH then the createTransaction is directly call with the right parameter

```tsx
if (rateToken === ethers.constants.AddressZero) {
  const tx1 = await talentLayerEscrow.createTransaction(
    parseInt(serviceId, 10),
    parseInt(proposalId, 10),
    metaEvidenceCid,
    cid,
    {
      value,
    },
);
```

\==> If the token is another ERC-20 token then you have have to pass trought a few more validation step as&#x20;

* Check the ERC-20 token balance

```tsx
const balance = await ERC20Token.balanceOf(signer.getAddress());
  if (balance.lt(value)) {
    throw new Error('Insufficient balance');
}
```

* Check the token allowance

```tsx
const allowance = await ERC20Token.allowance(
    signer.getAddress(),
    config.contracts.talentLayerEscrow,
  );

  if (allowance.lt(value)) {
    const tx1 = await ERC20Token.approve(config.contracts.talentLayerEscrow, value);
    const receipt1 = await toast.promise(provider.waitForTransaction(tx1.hash), {
      pending: {
        render() {
          return (
            <TransactionToast
              message='Your approval is in progress'
              transactionHash={tx1.hash}
            />
          );
        },
      },
      success: 'Transaction validated',
      error: 'An error occurred while updating your profile',
    });
    if (receipt1.status !== 1) {
      throw new Error('Approve Transaction failed');
    }
  }
```

Then we can create the new createTransaction

```tsx
const tx2 = await talentLayerEscrow.createTransaction(
    parseInt(serviceId, 10),
    parseInt(proposalId, 10),
    metaEvidenceCid,
    cid,
);
```

## See the Full Code Implemented on Our Demo DAPP

* **ServiceDetail** : <https://github.com/TalentLayer-Labs/indie-frontend/blob/main/src/components/ServiceDetail.tsx>
* ProposalItem : <https://github.com/TalentLayer-Labs/indie-frontend/blob/main/src/components/ProposalItem.tsx>
* ValidateProposalModal : <https://github.com/TalentLayer-Labs/indie-frontend/blob/main/src/components/Modal/ValidateProposalModal.tsx>
* ValidateProposal : <https://github.com/TalentLayer-Labs/indie-frontend/blob/main/src/contracts/acceptProposal.tsx>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.talentlayer.org/technical-guides/lower-level-guides/how-to-guides/how-to-implement-the-proposal-validation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
