Build an earn experience on top of Railnet — deposits, withdrawals, balances, and reporting
This guide walks you through integrating a deployed Conduit into your platform. By the end, you’ll be able to show balances, handle deposits and withdrawals, preview operations with fees, and monitor positions through the Railnet API.
This guide assumes a Conduit has already been deployed for your platform. If you need to deploy one first, see Create a Conduit.
// The underlying asset (e.g., USDC)address asset = conduit.asset();// The underlying Vehicle (strategy) the Conduit wrapsIVehicle vehicle = conduit.getVehicle();// Whether the Conduit is open for depositsbool enabled = conduit.isEnabled();
Use estimate() to show users what they’ll receive after fees before they commit to a transaction. Use convert() for a pure conversion without fees (e.g., displaying portfolio value).
// How many shares will the user get for 100 USDC? (includes fees)Asset[] memory input = new Asset[](1);input[0] = Asset({asset: address(usdc), value: 100e6});Asset[] memory estimated = conduit.estimate( input, Mode.DEPOSIT, EstimationType.OUTPUT);// estimated[0].value = shares the user will receive// How much USDC for redeeming 50 shares? (includes fees)Asset[] memory redeemInput = new Asset[](1);redeemInput[0] = Asset({asset: address(conduit), value: 50e18});Asset[] memory redeemEstimate = conduit.estimate( redeemInput, Mode.REDEEM, EstimationType.OUTPUT);// redeemEstimate[0].value = USDC the user will receive
estimate() includes all fee types (deposit, redeem, management, performance). Use it for transaction previews. Use convert() for display-only share-to-asset conversions where fees don’t apply.
Users deposit base assets (e.g., USDC) and receive Conduit shares representing proportional ownership. The Conduit handles all interaction with the underlying strategy.
1
Approve the Conduit
The user approves the Conduit to spend their tokens.
IERC20(usdc).approve(address(conduit), amount);
2
Create the deposit
Query memory query = Query({ owner: address(conduit), receiver: address(conduit), mode: Mode.DEPOSIT, input: new Asset[](1), output: new Asset[](0), salt: bytes32(uint256(nonce)), data: ""});query.input[0] = Asset({ asset: address(usdc), value: amount});// Create the deposit — auto-processes for sync strategiesconduit.create(query, userAddress);
For sync strategies (e.g., Aave, Compound), the deposit settles in the same transaction. The user receives shares immediately.For async strategies (e.g., Ethena, Syrup), the query enters PROCESSING. A keeper calls process() automatically when the underlying protocol is ready — the user doesn’t need to take any further action.
Users return Conduit shares and receive the underlying asset.
1
Approve Conduit shares
conduit.approve(address(conduit), shareAmount);
2
Create the withdrawal
Query memory query = Query({ owner: address(conduit), receiver: address(conduit), mode: Mode.REDEEM, input: new Asset[](1), output: new Asset[](0), salt: bytes32(uint256(nonce)), data: ""});query.input[0] = Asset({ asset: address(conduit), value: shareAmount});// Create the withdrawal — auto-processes for sync strategiesconduit.create(query, userAddress);
Same behavior as deposits: sync strategies settle immediately, async strategies are settled automatically by keepers.
For async strategies, keepers monitor active queries and call process() when the underlying protocol is ready to settle. Your platform doesn’t need to build monitoring infrastructure, and users never need to return for a second transaction. The experience is identical for sync and async strategies from the user’s perspective.
The Railnet GraphQL API provides indexed on-chain data for building dashboards, tracking operations, and generating reports. Use it alongside on-chain view calls for a complete picture.