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.

1

Use either:

  • GET /v1/vaults/{_id} — by ID

  • GET /v1/vaults?address=0x... — by address

Only vaults with visibility: PUBLIC should be displayed to users.

2

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
3

Retrieve underlying Token

Retrieve token information with:

GET /v1/tokens/{vault.tokenId}

4

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.

1

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.

2

Signature Validation

Check if the required signatures have been signed:

GET /v1/signatures/{signatureId}/check?walletAddress=0x...123

otherwise

const hash = await web3.eth.personal.sign(
  atob(walletMessage),
  walletAddress,
  ""
);

Submit the signed hash:

POST /v1/signatures/{signatureId}/sign

3

Retrieve Wallet Position

Retrieve the wallet position to track users' deposits, claims, and balances.

GET /v1/vaults/{vaultId}/position?walletAddress={walletAddress}

3. Deposit flow

Outlines the required contract state and transactions to successfully execute a deposit into a vault.

1

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 if NETTING

  • vault.depositQueue.address if RUNNING

2

Approve token spending

Make sure the amount respects the token's decimals (6 for USDC, USDT, 18 for the majority of ERC-20 tokens).

await tokenContract.methods
  .approve(spenderAddress, amount)
  .send({ from: walletAddress });
3

Submit Deposit Transaction

// during NETTING period
await cdoEpochContract.methods.depositAA(amount).send({ from: walletAddress });
// during cycle RUNNING
await depositQueueContract.methods
  .requestDeposit(amount)
  .send({ from: walletAddress });

4. Withdraw flow

Describes how to prepare, calculate, and submit a withdrawal request from a vault, depending on its current status and configuration.

1

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 });
2

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 });
3

Compute the LP tokens required

const percentage = 1000000 / maxWithdrawable;
const lpAmount = LPDeposited * percentage;
4

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 the RUNNING state of the vault cycle

  • WITHDRAW: available during the RUNNING state of the vault cycle. This request can be "standard" or "instant" depending on the next cycle APR.

  • REDEEM: available during the WAITING 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 next WAITING period

  • WITHDRAW:

    • if standard: the request can be claimed at the end of the next cycle, during the WAITING period

    • if 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 period

    • if 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.

Request schema
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 a DEPOSIT, WITHDRAW, or REDEEM.

  • 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

Request type
When
Claimable From

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