Integrators
This guide describes how to integrate Credit Vaults into Web3 applications using both the Pareto REST API and smart contracts. It is intended for technical audiences familiar with Web3 and frontend frameworks.
Smart contract instantiation
To interact with on-chain vaults, tokens, and queue contracts, a Web3 contract instance must be created using the ABI and contract address:
const contract = new web3.eth.Contract(abi, address);
This pattern is required for calling methods such as depositAA
, requestWithdraw
, approve
. Refer to the Web3.js documentation for full syntax details.
API access
All API routes below belong to the public Pareto API at https://api.pareto.credit
. Refer to the API chapter for a complete overview.
1. Required vault data
These steps outline the minimum data required to render a vault and enable interactions.
Load Vault Entity
Use either:
GET /v1/vaults/{_id}
— by IDGET /v1/vaults?address=0x...
— by address
Only vaults with visibility: PUBLIC
should be displayed to users.
Retrieve Signatures
Each vault contains a signatures
array of the form:
interface VaultSignature {
_id: string;
entity: "ALL" | "LENDER" | "MANAGER";
}
Filter all entries where entity === 'LENDER'
and use the _id
values to load them. This returns the full signature definitions required to enable future user interactions.
GET /v1/signatures?_id=signatureId1,signatureId2
Fetch latest Vault Block
Fetch up-to-date vault metrics. This includes share price, APRs, TVL, and queue configuration.
GET /v1/vault-latest-block?vaultId={vault._id}
2. Required wallet access data
Defines the required checks and data fetches needed immediately after wallet connection to verify access and authorization for vault operations.
Check wallet access
To verify if a wallet is allowed to interact with the vault, instantiate the contract using the cdoEpoch
ABI and address retrieved from the vault JSON:
const cdoEpochContract = new web3.eth.Contract(
vault.cdoEpoch.abi,
vault.cdoEpoch.address
);
const isAllowed = await cdoEpochContract.methods
.isWalletAllowed(walletAddress)
.call();
If isAllowed
is false, initiate a KYC flow using Keyring Connect SDK. Only after KYC is completed, it's possible to proceed with next steps.
3. Deposit flow
Outlines the required contract state and transactions to successfully execute a deposit into a vault.
Verify allowance and balance
Instantiate the token contract using the vault token ABI and address:
const tokenContract = new web3.eth.Contract(token.abi, token.address);
const allowance = await tokenContract.methods
.allowance(walletAddress, spenderAddress)
.call({ from: walletAddress });
const balance = await tokenContract.methods
.balanceOf(walletAddress)
.call({ from: walletAddress });
Spender can be found in:
vault.cdoEpoch.address
ifNETTING
vault.depositQueue.address
ifRUNNING
4. Withdraw flow
Describes how to prepare, calculate, and submit a withdrawal request from a vault, depending on its current status and configuration.
Fetch user balance and max withdrawable amount
const vaultTokenContract = new web3.eth.Contract(
vaultToken.abi,
vaultToken.address
);
const balance = await vaultTokenContract.methods
.balanceOf(walletAddress)
.call({ from: walletAddress });
const maxWithdrawable = await cdoEpochContract.methods
.maxWithdrawable(walletAddress, vault.address)
.call({ from: walletAddress });
Check allowance
The allowance must be verified only when the vault is in RUNNING state and uses the withdrawQueue. In this case, the withdrawQueue
contract address should be used as spender
.
const spender = vault.cdoEpoch.withdrawQueue.address;
const allowance = await tokenContract.methods
.allowance(walletAddress, spender)
.call({ from: walletAddress });
Submit withdrawal request
Track requests in the block.requests
array
// during NETTING period
await vaultContract.methods
.requestWithdraw(lpAmount, vault.address)
.send({ from: walletAddress });
// during cycle RUNNING
await withdrawQueueContract.methods
.requestWithdraw(lpAmount)
.send({ from: walletAddress });
Managing requests
There are 3 types of request:
DEPOSIT
: available during theRUNNING
state of the vault cycleWITHDRAW
: available during theRUNNING
state of the vault cycle. This request can be "standard" or "instant" depending on the next cycle APR.REDEEM
: available during theWAITING
state of the vault cycle. This request can be "standard" or "instant" depending on the next cycle APR.
All requests must be claimed by users after they have been processed:
DEPOSIT
: this request can be claimed starting from the nextWAITING
periodWITHDRAW
:if standard: the request can be claimed at the end of the next cycle, during the
WAITING
periodif instant: the request can be claimed during the
RUNNING
period of the next cycle, after the instant withdrawal delay (usually few days).
REDEEM
:if standard: the request can be claimed at the end of the next cycle, during the
WAITING
periodif instant: the request can be claimed during the
RUNNING
period of the next cycle, after the instant withdrawal delay (usually few days).
All vault requests are tracked in the requests
array of the vaultBlock
object. Each entry in this array represents a user-initiated interaction awaiting processing.
interface VaultBlockRequest {
type: "DEPOSIT" | "WITHDRAW" | "REDEEM";
amount: iBigInt;
block: Block;
isInstant?: boolean;
requestedOn: string;
walletId: string;
walletAddress: string;
status:
| "PENDING"
| "PROCESSED"
| "CLAIMABLE"
| "INSTANT_CLAIMABLE"
| "CLAIMED";
epochNumber?: number;
}
where
type
: Indicates if it's aDEPOSIT
,WITHDRAW
, orREDEEM
.status
: Tracks the lifecycle of the request (e.g.,PENDING
,CLAIMABLE
, etc.).isInstant
: Only present for withdrawals that qualify as "instant".block
: Indicates the vault block in which the request was recorded.epochNumber
: the epochNumber that must be passed to the requests methods
Requests are retrieved from the latest vault block:
GET /v1/vault-latest-block?vaultId={vaultId}
Deposit requests
Handled via the queue contract vault.cdoEpoch.depositQueue
It's possible to claim the request if
status === 'CLAIMED'
await depositQueueContract.methods
.claimDepositRequest(request.epochNumber)
.send({ from: walletAddress });
It's possible to cancel the request if
status === 'PENDING'
await depositQueueContract.methods
.deleteRequest(request.epochNumber)
.send({ from: walletAddress });
Withdraw requests
Handled via the queue contract vault.cdoEpoch.withdrawQueue
For both standard and instant requests, it's possible to claim the request if
status === 'CLAIMED'
await withdrawQueueContract.methods
.claimWithdrawRequest(request.epochNumber)
.send({ from: walletAddress });
It's possible to cancel the request if
status === 'PENDING'
await withdrawQueueContract.methods
.deleteWithdrawRequest(request.epochNumber)
.send({ from: walletAddress });
Redeem requests
Handled via the main vault contract vault.cdoEpoch
It's possible to claim the request if
status === 'CLAIMED'
:
await cdoEpochContract.methods
.claimWithdrawRequest()
.send({ from: walletAddress });
If
request.isInstant === true
it's possible to use:
await cdoEpochContract.methods
.claimInstantWithdrawRequest()
.send({ from: walletAddress });
Lifecycle summary
DEPOSIT
RUNNING
Next WAITING period
WITHDRAW (standard)
RUNNING
End of next cycle (WAITING)
WITHDRAW (instant)
RUNNING
RUNNING of next cycle (after instant withdrawal delay)
REDEEM (standard)
WAITING
End of next cycle (WAITING)
REDEEM (instant)
WAITING
RUNNING of next cycle (after instant withdrawal delay)
Last updated