While Railnet is not fully live, the integration and distribution of Advanced Strategies is done directly from the Vault 7540.
Prerequisites
Before integrating, make sure you have the following.Advanced Strategy distribution address
Each Advanced Strategy is distributed from a single shared 7540 Vault. For testing, use the ready-to-use deployments on mainnets below.| Network | Chain ID | Asset | Strategy | 7540 Vault address |
|---|---|---|---|---|
| Ethereum | 1 | WBTC | WBTC Test Yield | 0x4255f01607F785dE275b8ec1255f3a938dA17f63 |
| Ethereum | 84532 | USDC | USDC Test Yield | 0x7baeb9f29a284567b1c85b2469f456911bca1f81 |
Referral code
Every deposit your platform routes carries areferral address as a function parameter. This is what attributes the deposit to your organization for reporting and revenue share. The attribution is recorded on-chain via the Referral event:
Solidity
Reporting API
The Railnet Reporting API powers vault details, position tracking, and activity history. Full documentation, including request and response schemas, is available at docs.api.railnet.org/#tag/Async-Vaults.Reporting
Use the Railnet Reporting API to surface vault details, user positions, and activity history inside your platform. All endpoints share the base path/v1/railnet/async-vaults.
Fetch vault information
To populate your platform’s vault listing or product detail page (name, asset, icon, APY, TVL, share price, fees), query the/vaults endpoint.
GET
vault_ids(query): filter to one or more specific vaults. Each id is formatted as<chain_id>_<vault_address>. Multiple values are comma-separated.chain_ids,asset_ids,status(query, optional): additional filters. See the /vaults reference for the full list.
data array of vault objects, with fields grouped by:
- Identity:
name,symbol,state(Open/Closing/Closed). - Underlying asset:
deposit_asset.symbol,deposit_asset.decimals(usedecimalsto format_in_assetamounts). - Vault performance:
apy.last_7d,apy.last_30d,apy.last_1y,apy.all_time(returned in percentage points). - TVL:
total_value_in_asset(TVL in min units of the deposit asset),total_value_in_usd(USD). - Share price:
share_price_in_asset,share_price_in_usd(use to convert between shares and assets when previewing operations). - Fees:
fees.management_bps,fees.performance_bps,fees.protocol_bps(basis points). - Freshness:
updated_at— when the data was last refreshed.
cURL
JSON
Vault activity
/vaults gives you the vault’s current state. To complement it with the vault’s recent activity (deposits, redemptions, NAV proposals and NAV settlements), query the /operations endpoint with only the vault_ids parameter and no wallets. This returns vault-scoped activity across all users, sorted by timestamp.
GET
vault_ids(query, required): one or more vault ids (<chain_id>_<vault_address>). Multiple values are comma-separated.wallets(query): omit to get vault-scoped activity across all users. When set, the endpoint returns wallet-scoped activity instead — see Get user activity.
data array of operation entries, returned newest-first. Without a wallets filter, the feed mixes vault-level events (no wallet field) with user-level events (each carries a wallet field; the same five types are surfaced in Get user activity when scoped to a wallet).
Vault-level events:
nav_proposal: the asset manager has proposed a new NAV for the next settlement.proposed_nav_in_assetis the proposed value in the deposit asset’s min units. Capital does not move at this stage — it’s an announcement.nav_update: the proposed NAV has been applied on-chain.total_assetsis the new vault NAV (deposit asset’s min units), used as the share price reference until the next NAV update.settlement: an epoch has been settled.epoch_ididentifies which epoch was processed;settlement_typeis"deposit"or"redeem"(a single epoch settles one direction);total_assetsandtotal_supplyreflect vault state immediately after settlement.
request_deposit: a user submitted an async deposit request.amount_in_assetis the deposited amount;epoch_idis the epoch the request will settle in.cancel_deposit: a user canceled a pending deposit request before settlement.epoch_idmatches the canceled request.claim_shares: a user claimed shares from a settled deposit.amount_in_assetis the deposit consumed;amount_in_sharesis the shares minted. Sync deposits also produce this row but skip the request and settlement steps.request_redemption: a user submitted an async redemption request.amount_in_sharesis the shares put in escrow;epoch_idis the epoch.claim_assets: a user claimed assets from a settled redemption.amount_in_assetis the underlying received;amount_in_sharesis the shares burned.
vault_id, vault_chain_id, vault_address, tx_hash, and timestamp. User-level events additionally carry wallet, plus sender, recipient, controller, and owner where applicable.
Example request:
cURL
JSON
Get user positions
To display a user’s position inside a vault (current balance, rewards earned, pending deposits, pending redemptions), query the/positions endpoint.
GET
wallets(query, required): the user wallet(s) you want to retrieve positions for. Multiple values are comma-separated.vault_ids(query): scope to one or more specific vaults. Each id is<chain_id>_<vault_address>. Multiple values are comma-separated.
data array of position objects, one per (wallet, vault) pair, with fields grouped by:
- Current balance:
balance_in_asset(the user’s position expressed in the vault’s underlying asset, in min units),balance_in_usd(USD),balance_in_shares(yield-bearing receipt token amount). You can abstract the receipt token away and display only the underlying-asset amount. - Rewards earned:
total_rewards_in_asset,total_rewards_in_usd(cumulative yield generated since the user first deposited). - Pending deposits:
pending_deposits.unfulfilledlists requests still awaiting settlement;pending_deposits.claimable_in_shares/claimable_in_assetis what is settled and ready for the user to claim on-chain (calldeposit/minton the vault). - Pending redemptions: mirror of the above for redeem requests;
pending_redemptions.claimable_in_asset/claimable_in_sharesis what the user can claim on-chain viaredeem/withdraw. - Lifetime activity:
net_deposited_in_asset,net_withdrawn_in_asset(in min units of the deposit asset). - Freshness:
updated_at.
cURL
JSON
Get user activity
To display a user’s transaction history (deposit requests, cancellations, share claims, redemption requests, asset claims), query the same/operations endpoint used for vault activity, this time scoped to one or more wallets.
GET
vault_ids(query, required): one or more vault ids (<chain_id>_<vault_address>). Multiple values are comma-separated.wallets(query, required): the user wallet(s) whose history you want. Multiple values are comma-separated.
data array of user-level operation entries, returned newest-first. Each entry includes:
type: the action the user took. The values you will encounter arerequest_deposit,cancel_deposit,claim_shares(claiming after a settled deposit),request_redemption, andclaim_assets(claiming after a settled redemption). Sync paths produce the sameclaim_*records but skip the request and settlement steps.- Amounts:
amount_in_assetand / oramount_in_sharesdepending on the operation type. Format with the correspondingdecimalsfrom/vaults. - Vault context:
vault_id,vault_chain_id,vault_address. Useful when you query multiplevault_idsat once and need to know which vault each row belongs to. - On-chain reference:
tx_hashandtimestamp. Usetx_hashto link out to a block explorer. - Request identifiers:
epoch_idonrequest_deposit,cancel_deposit, andrequest_redemption. This is the same id you receive from therequestDeposit/requestRedeemcalls on-chain and the same id reported onsettlementrows from the vault activity feed, so you can join the user’s request to the settlement that fulfilled it. - Counterparties:
sender,recipient,controller,owner(set per operation type). Most platforms only need to display the user’s own wallet, but these are useful when your platform manages claims on behalf of users (controller != owner).
cURL
JSON
Vault interactions
Now that you have access to the full reporting data, you can start interacting with the vaults. In this section, we cover how to perform deposits and redemptions via direct contract calls, along with related actions such as canceling a deposit, claiming shares, and claiming assets.Deposit flow
The 7540 Vault supports two deposit paths:- Synchronous: the user deposits and receives shares in the same transaction. Available when the vault’s NAV is fresh and sync mode permits it.
- Asynchronous: the user submits a request, the asset manager settles at the next NAV update, and the user (or your platform on their behalf) claims the resulting shares.
The two paths are mutually exclusive: the vault enforces which one to use based on whether the vault’s NAV is currently fresh.
- When the NAV is fresh and sync mode permits sync deposits, only
syncDepositworks (requestDepositreverts withOnlySyncDepositAllowed). - When the NAV is expired, only
requestDepositworks (syncDepositreverts withTotalAssetsExpired).
Choose the deposit path
Before you submit the user’s transaction, your platform must callpreviewSyncDeposit on the vault to find out which path is currently active.
Solidity
assets: the amount of underlying asset (in the asset’s min units) the user is about to deposit. The vault uses this both as the gate input (returns0if sync deposit is not currently allowed) and to compute the corresponding number of shares net of entry fees.
shares: the number of vault shares the user would receive after the entry fee. A non-zero value means the sync path is the only one currently allowed (requestDepositwould revert withOnlySyncDepositAllowed). A zero value means the async path is the only one currently allowed (syncDepositwould revert withTotalAssetsExpiredorSyncOperationNotAllowed).
TypeScript
Approve the vault
Both deposit paths (sync and async) require the user’s wallet to have approved the 7540 Vault to spend the deposit amount of the underlying asset. Before submittingsyncDeposit or requestDeposit, your platform must check the current allowance and, if it is insufficient, prompt the user to send a new approval.
Check the current allowance
Call Parameters:
allowance on the underlying ERC-20 asset contract:Solidity
owner: the user’s wallet address (the holder of the deposit asset).spender: the 7540 Vault address.
owner. If this is less than the deposit amount the user intends to make, you must request a new approval before calling either deposit function.Request approval if insufficient
Prompt the user to send an approval transaction to the underlying asset contract:Parameters:
Solidity
spender: the 7540 Vault address.amount: the amount the vault is allowed to pull, in the asset’s min units. Pass at least the deposit amount.
value = 0. After it confirms, you can submit the deposit transaction.Synchronous deposit
WhenpreviewSyncDeposit returns a non-zero value, the user can deposit and receive shares in a single transaction. Make sure the vault is approved to pull assets of the underlying token from the depositor first.
Solidity
assets: the amount of underlying to deposit, in the asset’s min units. Must be>0and within the vault’smaxCapheadroom (totalAssets() + assets + siloBalance <= maxCap()); otherwise the call reverts withMaxCapReached.receiver: the address that will receive the minted shares.referral: your Railnet-assigned referral address. Use the zero address (0x0000000000000000000000000000000000000000) for testing if you do not have a referral address yet.
shares: the number of vault shares minted toreceiver, net of the entry fee.
Native ETH path: if the underlying asset is wETH, you can fund the deposit with native ETH by passing
msg.value and leaving assets = 0. The vault wraps the ETH on the user’s behalf. Sending msg.value when the underlying is not wETH reverts with CantDepositNativeToken.TypeScript
Asynchronous deposit
WhenpreviewSyncDeposit returns 0, the user must use the async path: request → settle → claim. Make sure the vault is approved to pull assets from the owner first.
Submit the request
Solidity
assets: the amount of underlying to deposit, in the asset’s min units. Subject to the vault’smaxCap(MaxCapReachedrevert if exceeded).controller: the address that owns the request and can later claim the resulting shares. Set it equal toownerunless your platform manages claims on behalf of users (e.g. claiming into a different receiver).owner: the address that provides the underlying.referral: your Railnet-assigned referral address. Use the zero address (0x0000000000000000000000000000000000000000) for testing.
requestId: the epoch ID this request was registered against. You do not need to store it for the normal claim flow: the Reporting API tracks settlement state by wallet. The id is still useful as a cross-reference to the matchingsettlementrow in the/operationsfeed (where it appears asepoch_id) for observability or audit purposes.
Cancel the request (optional, same epoch only)
If the user changes their mind before the next settlement, the controller can cancel the request and recover the full deposited amount.Parameters: none. The vault uses
Solidity
msg.sender as the controller.Behavior: refunds the full deposited amount of the controller’s pending request to msg.sender. Only works while the request is still in the current epoch; once a settlement has rolled the epoch, the call reverts with RequestNotCancelable.Wait for settlement
After the next NAV update, the asset manager settles the epoch and the user’s shares become claimable. The recommended way to detect this is via the Reporting API’s Fields to watch inside
/positions endpoint: you are most likely already polling it for the user’s portfolio view, and it aggregates settlement state per (wallet, vault) so you do not need to track requestIds yourself.GET
data[0].pending_deposits:unfulfilled: array of requests still in escrow, waiting for the next settlement. While this is non-empty, the user’s deposit is “pending” in your UI.claimable_in_asset: total asset amount that has settled and is ready to claim, in the asset’s min units. Pass this directly todeposit(Option A in the next step).claimable_in_shares: total share amount that has settled and is ready to claim, in share min units. Pass this directly tomint(Option B in the next step).
claimable_in_asset > 0 (or claimable_in_shares > 0), the request is settled and the user can claim. pending_deposits.claimable_in_* is aggregated across all of the user’s settled-but-unclaimed deposits in this vault, so a single value covers multiple settled epochs.Claim shares
Once Parameters:The share price used for the claim is locked at settlement time, regardless of when the user claims.
pending_deposits.claimable_in_asset > 0, the controller (or anyone they have authorized) can claim the shares. Two equivalent functions are available so you can claim in whichever unit is more convenient: pass claimable_in_asset to deposit (Option A), or claimable_in_shares to mint (Option B). Both support partial claims.- Option A: claim by asset amount
Solidity
assets: the asset amount to claim, in the asset’s min units. Must be<=pending_deposits.claimable_in_assetfrom the/positionsresponse. Pass any positive value<=claimable for partial claims.receiver: the address that receives the minted shares.controller: the request controller.
shares: the number of shares minted toreceiver, computed at the epoch’s snapshot share price net of the entry fee that was active at settlement.
Some strategies are configured to auto-claim shares on behalf of depositors during settlement. In that case, shares appear in
receiver’s wallet without your platform calling deposit or mint. Always check balanceOf(receiver) (or claimableDepositRequest) before prompting the user to claim.TypeScript
Redemption flow
The 7540 Vault supports two redemption paths:- Synchronous (instant): the user burns their shares and receives the underlying assets in the same transaction. Available when sync mode permits it, NAV is fresh, and the strategy holds enough liquid assets to cover the payout.
- Asynchronous: the user submits a redeem request, the asset manager settles at the next NAV update, and the user (or your platform) claims the resulting assets.
Unlike the deposit flow (where the vault enforces which path is active), redemption gives you a real choice:
requestRedeem always works, and syncRedeem is an opportunistic single-transaction shortcut when conditions are met. Prefer sync when it is available, since it spares the user the wait for the next settlement.referral parameter on redemption; attribution carries forward from the original deposit.
Choose the redemption path
Two conditions must hold for sync redeem to succeed: the vault’spreviewSyncRedeem returns a non-zero value, and the strategy’s treasury holds enough underlying to honor the payout. previewSyncRedeem checks the first; the second has to be verified separately because the preview function does not look at the treasury’s balance.
Solidity
shares: the number of vault shares the user intends to redeem.
assets: the amount of underlying the user would receive net of exit and haircut fees. Returns0if sync redeem is not currently possible (paused, sync mode disabled, NAV expired, or async-only mode active). A non-zero value means sync redeem is eligible, but you still need to verify treasury liquidity before submitting.
previewSyncRedeem only confirms that sync redeem is allowed by the vault’s policy; it does not check that the treasury actually holds the assets to pay out. To verify, take the treasury_address field from the /vaults response and read its balance with the standard ERC-20 balanceOf view on the deposit asset contract:
Solidity
TypeScript
Synchronous redemption
When bothpreviewSyncRedeem(shares) > 0 AND the strategy’s treasury holds enough underlying, the user can burn shares and receive assets in a single transaction.
Solidity
shares: the number of vault shares to burn. The full amount is always burned (no partial output).msg.sendermust own these shares; sync redeem cannot be called on behalf of another address.receiver: the address that receives the underlying assets.minimumAssets: slippage floor. The call reverts withBelowMinimumAssets(assets, minimumAssets)if the post-fee output is below this. Compute it frompreviewSyncRedeem(shares)minus an acceptable buffer (e.g. 50 to 100 bps).
assets: the amount of underlying transferred toreceiver, net of exit fee and haircut fee. Always>= minimumAssetson success.
Fees applied: an exit fee (capped at 2%) and a haircut fee (capped at 20%, burned and accruing to remaining shareholders) may be applied. Sync redemptions can be intentionally more expensive than async redemptions: the haircut discourages runs and protects long-term holders.
TypeScript
Asynchronous redemption
When sync redemption is unavailable (or you simply prefer the async path: lower fees, no haircut), use the request → settle → claim flow.Submit the request
Solidity
shares: the number of vault shares to redeem.controller: the address that owns the request and can later claim the resulting assets. Set it equal toownerunless your platform manages claims on behalf of users.owner: the holder of the shares being redeemed. Ifmsg.sender != owner, the caller must be an approved operator on the vault, or hold an ERC-20 allowance fromownerfor at leastshares.
requestId: the epoch ID this request was registered against. You do not need to store it for the normal claim flow: the Reporting API tracks settlement state by wallet. The id is still useful as a cross-reference to the matchingsettlementrow in the/operationsfeed (where it appears asepoch_id) for observability or audit purposes.
OnlyOneRequestAllowed revert).Wait for settlement
After the next NAV update, the asset manager settles the epoch and the user’s assets become claimable. The recommended way to detect this is via the Reporting API’s Fields to watch inside
/positions endpoint: you are most likely already polling it for the user’s portfolio view, and it aggregates settlement state per (wallet, vault) so you do not need to track requestIds yourself.GET
data[0].pending_redemptions:unfulfilled: array of requests still in escrow, waiting for the next settlement. While this is non-empty, the user’s redemption is “pending” in your UI.claimable_in_shares: total share amount that has settled and is ready to claim, in share min units. Pass this directly toredeem(Option A in the next step).claimable_in_asset: total asset amount that has settled and is ready to claim, in the asset’s min units. Pass this directly towithdraw(Option B in the next step).
claimable_in_shares > 0 (or claimable_in_asset > 0), the request is settled and the user can claim. pending_redemptions.claimable_in_* is aggregated across all of the user’s settled-but-unclaimed redemptions in this vault, so a single value covers multiple settled epochs.Async redemption settlement is all-or-nothing per epoch. If the strategy is short on liquid assets when the asset manager attempts to settle, the request stays pending and is retried at the next NAV update. The user does not need to (and cannot) resubmit.
Claim assets
Once
pending_redemptions.claimable_in_shares > 0, the controller (or anyone they have authorized) can claim the assets. Two equivalent functions are available so you can claim in whichever unit is more convenient: pass claimable_in_shares to redeem (Option A), or claimable_in_asset to withdraw (Option B). Both support partial claims.The redemption price is locked at settlement time, regardless of when the user claims.Some strategies are configured to auto-claim assets on behalf of redeemers during settlement. In that case, assets appear in
receiver’s wallet without your platform calling redeem or withdraw. Always check balanceOf(receiver) (in the underlying asset) or pending_redemptions.claimable_in_asset from /positions before prompting the user to claim.TypeScript
Next steps
Advanced Strategies overview
Architecture, vault lifecycle, NAV reporting, fee structure, and roles.
Vault 7540 mechanics
How the 7540 Vault enforces sync vs. async paths and settles requests.
Reporting API reference
Full request and response schemas for vault, position, and operations endpoints.
Integrate a Conduit
Build an earn experience on top of a Railnet Conduit instead.