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
Approve token transfer
First, approve the Escrow contract to transfer USDC on your behalf: 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 );
Prepare payment method configuration
Define which payment methods you accept and their parameters: // 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"
}
];
Define currency conversion rates
Set minimum conversion rates for each payment method’s supported currencies: // 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
}
]
];
Create the deposit
Call createDeposit with all parameters: 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 ());
Managing Your Deposit
Adding Funds
Add more USDC to an existing deposit:
// 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):
await escrow . removeFunds (
depositId ,
ethers . utils . parseUnits ( "200" , 6 )
);
Updating Conversion Rates
Update Single Currency
Add New Currency
await escrow . setCurrencyMinRate (
depositId ,
venmoHash ,
USD ,
ethers . utils . parseEther ( "1.01" ) // New rate: 1 USDC = 1.01 USD
);
Updating Intent Limits
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
// Stop accepting new intents
await escrow . setAcceptingIntents ( depositId , false );
Managing Payment Methods
Add Payment Method
Deactivate Payment Method
Reactivate Payment Method
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" ) }
]]
);
Delegation
Delegate deposit management to another address:
Set Delegate
Remove Delegate
const delegateAddress = "0x..." ;
await escrow . setDelegate ( depositId , delegateAddress );
Delegates can perform all deposit management functions except withdrawing funds.
Withdrawing Your Deposit
Fully close a deposit and withdraw all available funds:
// Withdraws all available liquidity
// Prunes expired intents automatically
// Closes deposit if no active intents remain
await escrow . withdrawDeposit ( depositId );
If active (non-expired) intents exist, the deposit won’t close completely. Call withdrawDeposit again after intents expire or are fulfilled.
Reading Deposit State
// 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
Monitor Liquidity Regularly check remainingDeposits and add funds when low to ensure continuous availability.
Set Competitive Rates Adjust conversion rates based on market conditions to attract more takers.
Use Reasonable Limits Set intent amount ranges that balance accessibility with risk tolerance.
Enable Retention Set retainOnEmpty: true to keep your deposit configuration when funds are depleted.
Contract Reference
See the full Escrow contract interface for all available functions and events.