Skip to main content
This walkthrough explains how to integrate Centrifuge vaults on Base and X Layer with a Para-powered EVM wallet. It is a step-by-step guide for depositing into and redeeming from Centrifuge vaults in a TypeScript web application. The vault sits in front of the Centrifuge protocol so integrators don’t have to deal with its complexity: you deposit USDC into the vault and receive the freely transferable deRWA token. The examples below use five live vaults across two different chains, Base and X Layer. They are worked examples rather than an exhaustive list. The same contract interface applies to every Centrifuge vault, so an integration written against one of these works against the others by changing the chain and the addresses. More products and chains are live already, and new ones are added regularly. The current list is published at docs.centrifuge.io.

Overview

The vaults in this guide provide a small contract interface for investing in tokenized real-world asset products. Users deposit an accepted asset, such as USDC, and receive product shares. Depending on the vault configuration, a deposit either completes immediately or enters a settlement queue. Redemptions are always asynchronous. The user submits a redemption request, waits for settlement, and then claims the resulting asset. The integration must therefore distinguish between:
  • Synchronous deposit: one transaction deposits the asset and returns deRWA tokens.
  • Asynchronous deposit: one transaction creates the request and a later transaction claims deRWA tokens.
  • Asynchronous redemption: one transaction creates the request and a later transaction claims the asset.

Reference Deployments

The code in this guide uses the vaults below. Base and X Layer are two independent chains, each with its own RPC endpoint, gas token, and USDC contract, so a deployment on one is unrelated to a deployment on the other even when the product is the same.

Base (Chain ID 8453, Gas in ETH)

X Layer (Chain ID 196, Gas in OKB)

The three X Layer vaults accept the same USDC contract and all use synchronous deposits with asynchronous redemption, the same mode as deJAAA on Base. Other products and chains are live beyond these five vaults, and the set keeps growing. Look up the current addresses in the Centrifuge deployments reference rather than hardcoding this table into a long-lived integration.

How It Works

Across these deployments, deposits are synchronous for deJAAA, deHYB and deJTRSY, and asynchronous for deSPXA. Redemptions are asynchronous (ERC-7540 style) everywhere: you submit a request, the issuer fulfills it during their settlement cycle (this can take hours or days), and then you claim the result. Deposit mode is a property of the vault, not of the chain or product. Read asyncDeposit() from the vault instead of assuming the mode from its name. Three things to know before writing any code:
  1. There is no claim() function. Claiming a fulfilled deposit is done by calling deposit(...), and claiming a fulfilled redemption by calling redeem(...).
  2. Requests are self-directed. The controller and owner parameters in the request functions must be your own address.
  3. mint() and withdraw() don’t exist. Only deposit() and redeem() are supported, so don’t point generic ERC-4626/7540 tooling at this vault.
These deployments allow anyone to claim a controller’s entire settled balance on their behalf, but the receiver must be that same controller. Partial third-party claims are not supported.

What You Need

  • Node.js 18 or later.
  • A package manager such as npm, pnpm, or yarn.
  • A Para API key, a completed Para authentication flow, and an EVM wallet for the authenticated user.
  • The Para Web SDK, Para’s viem integration, and viem.
  • A mainnet RPC endpoint for the chain you target, Base or X Layer in this guide.
  • The gas token of that chain in the signing wallet, ETH on Base or OKB on X Layer.
  • USDC on that same chain for deposits. The USDC contract is different on each chain.
  • The authoritative vault ABI and a standard ERC-20 ABI.
  • A user interface that represents pending and claimable states separately.
  • Para handles signing without exposing or storing the user’s private key in your application.

Install Dependencies


Step-by-Step Integration (TypeScript + Para + viem)

All the code in this guide lives in a single file and uses Para’s Web SDK, Para’s viem integration, and viem.

Setup

Start with the Para and viem imports:
Define the supported deployments in one place. This walkthrough selects Base by default; change selectedNetwork to deployments.xLayer to use an X Layer sync-deposit or redemption flow.
We only need approve and balanceOf from the ERC-20s:
And from the vault, the request/claim functions plus the two views that track a request’s lifecycle in each direction:
Complete Para authentication before creating the account and clients. createParaViemAccount selects the first available EVM wallet unless you pass a specific address or walletId.
Finally, a small helper so every write waits for inclusion and fails loudly on revert:
That’s all the setup. Everything below uses these constants, clients, and the helper directly.

Case 1: Sync Deposit

In sync mode there is no request and no claim: approve USDC, call deposit, and the shares arrive in the same transaction.

Case 2: Async Deposit

deSPXA on Base is the only asynchronous-deposit product in this guide. This case requires selectedNetwork = deployments.base and uses asyncProduct from that deployment.

Step 1: Approve USDC

The vault pulls your USDC when you submit the request, so it needs an allowance first. USDC uses 6 decimals:

Step 2: Submit the Request

requestDeposit takes the amount plus a controller and an owner. Both must be your own address (the caller). Your USDC is transferred immediately and the request enters the queue:

Step 3: Wait for Fulfillment

The issuer settles requests in epochs, so fulfillment is not instant. Two views, both denominated in USDC, tell you where your request stands: pending is what’s still queued and claimable is what’s already settled and ready.
Fulfillment can also be partial: requests settle in order across all investors, so claimable may cover only part of your request for a while. You can claim partial amounts as they become available.
In a real service, poll these views from a background job or cron. Fulfillment can take hours or days depending on the product’s settlement cycle.
Do not use pending === 0 as the only terminal signal. Rounding dust can leave a small pending amount that is not claimable, and these vaults do not expose request cancellation.

Step 4: Claim Your Shares

Once claimable > 0, claim by calling deposit. Passing maxUint256 as the amount claims everything that’s ready, so you don’t have to compute it first:
The deSPXA shares (18 decimals) are now in your wallet:
One nice property: if you submit a new requestDeposit while you still have a claimable balance from a previous one, the vault auto-claims the old one to you first. You’ll never strand settled funds by re-requesting.

Case 3: Async Redemption

The redemption flow mirrors the asynchronous deposit flow: request, wait, and claim, but moving shares in and USDC out. The selected redemptionProduct can be any of the five products listed above as long as it belongs to selectedNetwork.

Step 1: Approve Shares

requestRedeem pulls the selected product’s shares via transferFrom, so approve the vault first. All share tokens listed in this guide use 18 decimals:

Step 2: Submit the Request

Same rule as deposits: controller and owner must be your own address.

Step 3: Wait for Fulfillment

Same pattern as deposits, with the redeem-side views. Note these are denominated in shares, not USDC:

Step 4: Claim Your USDC

Claim by calling redeem. Again, maxUint256 claims everything that’s settled:
The example selects deJAAA. On Base, set redemptionProduct to selectedNetwork.products.deSPXA to redeem deSPXA. On X Layer, select deJAAA, deHYB, or deJTRSY from selectedNetwork.products.

Conclusions

These vaults require direct contract integration for deposits and redemptions, giving enough flexibility to be integrated into many different applications. Synchronous deposits complete atomically, while deSPXA deposits use a request-and-claim lifecycle. Redemptions are asynchronous for every listed product. Para supplies the authenticated viem account and wallet client used to sign each transaction. The five vaults covered here, two on Base and three on X Layer, are examples of the pattern rather than the full catalogue. Once these deposit and redemption flows are implemented, supporting another product or another chain is a matter of pointing the same code at different addresses. The Centrifuge deployments reference is the place to check as new ones ship.