> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/zkp2p/zkp2p-contracts/llms.txt
> Use this file to discover all available pages before exploring further.

# Creating Deposits (Maker Side)

> Learn how to create liquidity deposits as a maker in the ZKP2P protocol

As a maker (liquidity provider), you create deposits to offer USDC for purchase in exchange for fiat payments. This guide walks through the process of creating and managing deposits.

## Overview

Deposits are created on the **Escrow contract** and define:

* The amount of USDC available for trading
* Accepted payment methods (Venmo, PayPal, Wise, etc.)
* Supported fiat currencies and minimum conversion rates
* Intent amount limits (min/max per trade)
* Optional access control and delegation

## Creating a Deposit

<Steps>
  <Step title="Approve token transfer">
    First, approve the Escrow contract to transfer USDC on your behalf:

    ```typescript theme={null}
    import { ethers } from "ethers";
    import { Escrow } from "@typechain/Escrow";
    import { ERC20 } from "@typechain/ERC20";

    const USDC_ADDRESS = "0x...";
    const ESCROW_ADDRESS = "0x...";

    const usdc = new ethers.Contract(USDC_ADDRESS, ERC20_ABI, signer) as ERC20;
    const escrow = new ethers.Contract(ESCROW_ADDRESS, Escrow_ABI, signer) as Escrow;

    // Approve escrow to transfer 1000 USDC (6 decimals)
    const amount = ethers.utils.parseUnits("1000", 6);
    await usdc.approve(ESCROW_ADDRESS, amount);
    ```
  </Step>

  <Step title="Prepare payment method configuration">
    Define which payment methods you accept and their parameters:

    ```typescript theme={null}
    // Generate payment method hashes
    const venmoHash = ethers.utils.keccak256(
      ethers.utils.toUtf8Bytes("venmo")
    );
    const paypalHash = ethers.utils.keccak256(
      ethers.utils.toUtf8Bytes("paypal")
    );

    // Your payment account identifiers (hashed for privacy)
    const venmoPayeeDetails = ethers.utils.keccak256(
      ethers.utils.toUtf8Bytes("your-venmo-username")
    );
    const paypalPayeeDetails = ethers.utils.keccak256(
      ethers.utils.toUtf8Bytes("your-paypal-email")
    );

    // Configure payment method data
    const paymentMethods = [venmoHash, paypalHash];
    const paymentMethodData = [
      {
        intentGatingService: "0x...", // Optional: address(0) for no gating
        payeeDetails: venmoPayeeDetails,
        data: "0x" // Additional verification data if needed
      },
      {
        intentGatingService: "0x0000000000000000000000000000000000000000",
        payeeDetails: paypalPayeeDetails,
        data: "0x"
      }
    ];
    ```
  </Step>

  <Step title="Define currency conversion rates">
    Set minimum conversion rates for each payment method's supported currencies:

    ```typescript theme={null}
    // Currency codes (keccak256 hashed)
    const USD = ethers.utils.keccak256(ethers.utils.toUtf8Bytes("USD"));
    const EUR = ethers.utils.keccak256(ethers.utils.toUtf8Bytes("EUR"));

    // Conversion rates in 18 decimals (1e18 = 1:1 rate)
    const currencies = [
      // Venmo: support USD only
      [
        {
          code: USD,
          minConversionRate: ethers.utils.parseEther("1.0") // 1 USDC = 1 USD
        }
      ],
      // PayPal: support USD and EUR
      [
        {
          code: USD,
          minConversionRate: ethers.utils.parseEther("1.0")
        },
        {
          code: EUR,
          minConversionRate: ethers.utils.parseEther("0.92") // 1 USDC = 0.92 EUR min
        }
      ]
    ];
    ```
  </Step>

  <Step title="Create the deposit">
    Call `createDeposit` with all parameters:

    ```typescript theme={null}
    const tx = await escrow.createDeposit({
      token: USDC_ADDRESS,
      amount: ethers.utils.parseUnits("1000", 6), // 1000 USDC
      intentAmountRange: {
        min: ethers.utils.parseUnits("10", 6),   // Min 10 USDC per trade
        max: ethers.utils.parseUnits("500", 6)   // Max 500 USDC per trade
      },
      paymentMethods: paymentMethods,
      paymentMethodData: paymentMethodData,
      currencies: currencies,
      delegate: "0x0000000000000000000000000000000000000000", // Optional
      intentGuardian: "0x0000000000000000000000000000000000000000", // Optional
      retainOnEmpty: true // Keep deposit config when funds depleted
    });

    const receipt = await tx.wait();
    console.log("Deposit created!", receipt.transactionHash);

    // Extract depositId from event
    const event = receipt.events?.find(e => e.event === "DepositReceived");
    const depositId = event?.args?.depositId;
    console.log("Deposit ID:", depositId.toString());
    ```
  </Step>
</Steps>

## Managing Your Deposit

### Adding Funds

Add more USDC to an existing deposit:

```typescript theme={null}
// Approve additional funds first
await usdc.approve(ESCROW_ADDRESS, ethers.utils.parseUnits("500", 6));

// Add to deposit
await escrow.addFunds(
  depositId,
  ethers.utils.parseUnits("500", 6)
);
```

### Removing Funds

Withdraw available liquidity (automatically prunes expired intents if needed):

```typescript theme={null}
await escrow.removeFunds(
  depositId,
  ethers.utils.parseUnits("200", 6)
);
```

### Updating Conversion Rates

<CodeGroup>
  ```typescript Update Single Currency theme={null}
  await escrow.setCurrencyMinRate(
    depositId,
    venmoHash,
    USD,
    ethers.utils.parseEther("1.01") // New rate: 1 USDC = 1.01 USD
  );
  ```

  ```typescript Add New Currency theme={null}
  const GBP = ethers.utils.keccak256(ethers.utils.toUtf8Bytes("GBP"));

  await escrow.addCurrencies(
    depositId,
    paypalHash,
    [
      {
        code: GBP,
        minConversionRate: ethers.utils.parseEther("0.79")
      }
    ]
  );
  ```
</CodeGroup>

### Updating Intent Limits

```typescript theme={null}
await escrow.setIntentRange(
  depositId,
  {
    min: ethers.utils.parseUnits("20", 6),  // New min: 20 USDC
    max: ethers.utils.parseUnits("1000", 6) // New max: 1000 USDC
  }
);
```

### Pausing/Resuming Intent Acceptance

<CodeGroup>
  ```typescript Pause theme={null}
  // Stop accepting new intents
  await escrow.setAcceptingIntents(depositId, false);
  ```

  ```typescript Resume theme={null}
  // Resume accepting intents (only if sufficient liquidity)
  await escrow.setAcceptingIntents(depositId, true);
  ```
</CodeGroup>

### Managing Payment Methods

<CodeGroup>
  ```typescript Add Payment Method theme={null}
  const zelle = ethers.utils.keccak256(ethers.utils.toUtf8Bytes("zelle"));

  await escrow.addPaymentMethods(
    depositId,
    [zelle],
    [{
      intentGatingService: "0x0000000000000000000000000000000000000000",
      payeeDetails: ethers.utils.keccak256(
        ethers.utils.toUtf8Bytes("your-zelle-email")
      ),
      data: "0x"
    }],
    [[
      { code: USD, minConversionRate: ethers.utils.parseEther("1.0") }
    ]]
  );
  ```

  ```typescript Deactivate Payment Method theme={null}
  // Deactivate without deleting (existing intents can still be fulfilled)
  await escrow.setPaymentMethodActive(depositId, venmoHash, false);
  ```

  ```typescript Reactivate Payment Method theme={null}
  await escrow.setPaymentMethodActive(depositId, venmoHash, true);
  ```
</CodeGroup>

## Delegation

Delegate deposit management to another address:

<CodeGroup>
  ```typescript Set Delegate theme={null}
  const delegateAddress = "0x...";
  await escrow.setDelegate(depositId, delegateAddress);
  ```

  ```typescript Remove Delegate theme={null}
  await escrow.removeDelegate(depositId);
  ```
</CodeGroup>

Delegates can perform all deposit management functions except withdrawing funds.

## Withdrawing Your Deposit

Fully close a deposit and withdraw all available funds:

```typescript theme={null}
// Withdraws all available liquidity
// Prunes expired intents automatically
// Closes deposit if no active intents remain
await escrow.withdrawDeposit(depositId);
```

<Note>
  If active (non-expired) intents exist, the deposit won't close completely. Call `withdrawDeposit` again after intents expire or are fulfilled.
</Note>

## Reading Deposit State

```typescript theme={null}
// Get full deposit info
const deposit = await escrow.getDeposit(depositId);
console.log("Depositor:", deposit.depositor);
console.log("Available:", deposit.remainingDeposits.toString());
console.log("Locked in intents:", deposit.outstandingIntentAmount.toString());
console.log("Accepting intents:", deposit.acceptingIntents);

// Get payment methods
const methods = await escrow.getDepositPaymentMethods(depositId);

// Get currencies for a payment method
const venmocurrencies = await escrow.getDepositCurrencies(depositId, venmoHash);

// Get conversion rate for a specific currency
const usdRate = await escrow.getDepositCurrencyMinRate(
  depositId,
  venmoHash,
  USD
);
console.log("Venmo USD rate:", ethers.utils.formatEther(usdRate));

// Check for expired intents
const [expiredHashes, reclaimable] = await escrow.getExpiredIntents(depositId);
console.log("Expired intents:", expiredHashes.length);
console.log("Reclaimable amount:", reclaimable.toString());
```

## Best Practices

<CardGroup cols={2}>
  <Card title="Monitor Liquidity" icon="chart-line">
    Regularly check `remainingDeposits` and add funds when low to ensure continuous availability.
  </Card>

  <Card title="Set Competitive Rates" icon="badge-percent">
    Adjust conversion rates based on market conditions to attract more takers.
  </Card>

  <Card title="Use Reasonable Limits" icon="ruler">
    Set intent amount ranges that balance accessibility with risk tolerance.
  </Card>

  <Card title="Enable Retention" icon="database">
    Set `retainOnEmpty: true` to keep your deposit configuration when funds are depleted.
  </Card>
</CardGroup>

## Contract Reference

See the full [Escrow contract interface](/contracts/escrow) for all available functions and events.
