Portfolio Management API
Overview
The Velvet Portfolio Management API enables you to manage and rebalance tokenized portfolios (vaults) programmatically. With this API, you can:
Retrieve and inspect all portfolios (vaults) created by a given owner.
Rebalance portfolios by selling one token and buying another.
Execute trades using on-chain calls.
Deposit and withdraw tokens from portfolios.
Obtain helper information, such as the number of portfolio tokens a user holds.
This guide will walk you through key endpoints and illustrate how to integrate the provided data and call parameters into your applications.
Prerequisites
A wallet with a private key to sign blockchain transactions.
A JSON-RPC provider URL for your target chain (for instance, Base chain with chainId = 8453).
Familiarity with Ethereum-compatible contracts, tokens, and basic web3 concepts.
Trade Flow Overview
To execute a trade withing a Velvet portfolio (vault), follow these steps:
Fetch All Created Vaults: Retrieve all portfolios (vaults) associated with a specific owner.
Use the Rebalance API Endpoint: Generate the necessary call data and parameters for the intended trade.
Execute the Trade On-Chain: Use the parameters from the Rebalance API to call the vault’s rebalance contract function.
Fetch All Created Vaults
Endpoint: GET https://api.velvet.capital/api/v3/portfolio/owner/<OWNER_WALLET_ADDRESS>?chain=base
Description: Retrieves all vaults created by a specified owner on the Velvet V3 platform.
URL Parameters:
OWNER_WALLET_ADDRESS(string): The Ethereum address of the owner.
Response:
Copy
jsonCopy code{
"data": [
{
"portfolioId": "string",
"portfolio": "string",
"name": "string",
"symbol": "string",
"public": true,
"initialized": true,
"confirmed": true,
"tokenExclusionManager": "string",
"rebalancing": "string", // ← Use this address in next steps
"owner": "string",
"assetManagementConfig": "string",
"accessController": "string",
"feeModule": "string",
"vaultAddress": "string",
"gnosisModule": "string",
"whitelistedUsers": [],
"whitelistedTokens": [],
"whitelistAccessGrantedUsers": [],
"assetManagerAccessGrantedUsers": [],
"chainID": 8453,
"chainName": "base",
"txnHash": "string",
"createdAt": "Date",
"updatedAt": "Date",
"creatorName": "string",
"description": "string",
"avatar": "string"
}
]
}Usage: From the response, note the rebalancing address, which will be needed to prepare the trade in the next step.
Rebalance API Endpoint
Endpoint: POST https://eventsapi.velvetdao.xyz/api/v3/rebalance
Description: Generates the necessary parameters (call data, handler address, etc.) to execute a trade within a portfolio’s rebalance contract.
Request Body:
Copy
jsonCopy code{
"rebalanceAddress": "string",
"sellToken": "string",
"buyToken": "string",
"sellAmount": "string",
"slippage": "string",
"remainingTokens": ["string"],
"owner": "string"
}Parameters:
rebalanceAddress(string, required): The rebalance contract address retrieved from the "Fetch All Created Vaults" response.sellToken(string, required): The token address you want to sell.buyToken(string, required): The token address you want to buy.sellAmount(string, required): The amount ofsellTokento sell (in smallest unit, e.g., if USDC is 6 decimals,1 USDC=1000000).slippage(string, required): Allowed slippage in basis points. For example,"100"means 1%.remainingTokens(array, required): The list of tokens that will remain in the vault after the trade.owner(string, required): The vault owner’s Ethereum address.
Response:
Copy
jsonCopy code{
"newTokens": ["string"],
"sellTokens": ["string"],
"sellAmounts": ["string"],
"handler": "string",
"callData": "string",
"estimateGas": "string",
"gasPrice": "string"
}Note: Use the returned data (newTokens, sellTokens, sellAmounts, handler, and callData) to execute the trade in the next step.
Executing the Trade On-Chain
After obtaining the necessary parameters from the Rebalance API, you can execute the trade by interacting directly with the rebalance contract on-chain.
Prerequisite: Install Ethers.js:
Copy
bashCopy codenpm install [email protected]Example Code:
Copy
javascriptCopy codeimport { ethers } from 'ethers'
const provider = new ethers.providers.JsonRpcProvider('<RPC_URL>')
const privateKey = '<OWNER_WALLET_PRIVATE_KEY>'
const wallet = new ethers.Wallet(privateKey, provider)
const RebalanceABI = [
{
inputs: [
{
components: [
{ internalType: 'address[]', name: '_newTokens', type: 'address[]' },
{ internalType: 'address[]', name: '_sellTokens', type: 'address[]' },
{ internalType: 'uint256[]', name: '_sellAmounts', type: 'uint256[]' },
{ internalType: 'address', name: '_handler', type: 'address' },
{ internalType: 'bytes', name: '_callData', type: 'bytes' }
],
internalType: 'struct FunctionParameters.RebalanceIntent',
name: 'rebalanceData',
type: 'tuple'
}
],
name: 'updateTokens',
outputs: [],
stateMutability: 'nonpayable',
type: 'function'
}
]
const RebalanceInstance = new ethers.Contract(
'VAULT_REBALANCING_ADDRESS',
RebalanceABI,
wallet
)
async function executeRebalance(newTokens, sellTokens, sellAmounts, handler, callData, estimateGas, gasPrice) {
try {
console.log('Executing Trade...')
const tx = await RebalanceInstance.updateTokens(
{
_newTokens: newTokens,
_sellTokens: sellTokens,
_sellAmounts: sellAmounts,
_handler: handler,
_callData: callData
},
{
gasLimit: ethers.BigNumber.from(estimateGas).add('1000000'),
gasPrice: gasPrice
}
)
console.log('Transaction successful:', tx)
} catch (error) {
console.error('Transaction failed:', error)
}
}Rebalance Transaction API
Endpoint: POST https://eventsapi.velvetdao.xyz/api/v3/rebalance/txn
Description: Initiates a rebalance transaction directly. Useful when you already know the parameters required to perform the rebalance.
Request Body:
Copy
jsonCopy code{
"rebalanceAddress": "0x19bc26a8e42727a2567d244cca344ceddd0493ae",
"sellToken": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
"buyToken": "0xb6fe221fe9eef5aba221c348ba20a1bf5e73624c",
"sellAmount": "883373",
"slippage": "100",
"remainingTokens": [
"0xb6fe221fe9eef5aba221c348ba20a1bf5e73624c",
"0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452"
],
"owner": "0x86F91b660a5432CE4654D84B3AbAD38A6645425e"
}Parameters:
Similar to the Rebalance API Endpoint (above), but returns direct transaction data for immediate execution.
Portfolio Deposit API
Endpoint: POST https://eventsapi.velvetdao.xyz/api/v3/portfolio/deposit
Description: Deposits a specified amount of tokens into a given portfolio.
Request Body:
Copy
jsonCopy code{
"portfolio": "0x444ef5b66f3dc7f3d36fe607f84fcb2f3a666902",
"depositAmount": "1000000",
"depositToken": "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb",
"user": "0x3C96e2Fc58332746fbBAB5eC44f01572F99033ed",
"depositType": "batch",
"tokenType": "erc20"
}Parameters:
portfolio: The portfolio contract address.depositAmount: The amount to deposit (in token’s smallest unit).depositToken: The token’s contract address being deposited.user: The depositor’s Ethereum address.depositType: The deposit mode (e.g.,batch).tokenType: The type of token (e.g.,erc20).
Response: Returns transaction data (to, data, gasLimit, gasPrice) needed to broadcast the transaction.
Example Code: After approval, send the returned transaction data via wallet.sendTransaction(tx).
Portfolio Withdraw API
Endpoint: POST https://eventsapi.velvetdao.xyz/api/v3/portfolio/withdraw
Description: Initiates a withdrawal from a specified portfolio.
Request Body:
Copy
jsonCopy code{
"portfolio": "0xc4dc922c90d44d07ea5d1aa8c08253ebc17e42c2",
"withdrawAmount": "8999999999989636786",
"withdrawToken": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"user": "0x86F91b660a5432CE4654D84B3AbAD38A6645425e",
"withdrawType": "batch",
"tokenType": "erc20"
}Parameters:
portfolio: The portfolio address.withdrawAmount: The withdrawal amount (in smallest unit).withdrawToken: The token address to withdraw.user: The user’s Ethereum address initiating the withdrawal.withdrawType: The withdrawal mode (e.g.batch).tokenType: The type of token (e.g.,erc20).
Response: Returns transaction data needed to finalize the withdrawal transaction on-chain.
Edge Case: If the portfolio contains only one token and the user wishes to withdraw that same token, use the multiTokenWithdrawalfunction from the portfolio contract’s ABI.
Helper Functions
Get Portfolio Token Amount
Function: getPortfolioTokenAmount(portfolioAddress, account, chainId=8453)
Description: Returns the number of portfolio tokens a user holds.
Example:
Copy
javascriptCopy codeexport const getPortfolioTokenAmount = async (portfolioAddress, account, chainId = 8453) => {
try {
const web3 = getWeb3Provider(chainId);
const ContractInstance = new web3.eth.Contract(
portfolio_abi,
portfolioAddress
);
const contractData = await ContractInstance.methods.balanceOf(account).call();
return web3.utils.fromWei(contractData, 'ether');
} catch (error) {
console.log(error, 'error');
}
};Conclusion
With the endpoints and code samples provided, you should be able to:
Discover and manage all your Velvet vaults.
Programmatically prepare and execute trades through the Rebalance interface.
Deposit and withdraw tokens from portfolios.
Monitor and query token amounts within portfolios.
For a seamless integration, ensure you handle proper token approvals and confirm transactions on-chain. By following these guidelines and examples, you can fully leverage the Velvet Portfolio Management API.
Happy coding!
Last updated