@concrete-xyz/sdk
v1.2.2
Published
Concrete SDK for interacting with vault contracts
Readme
@concrete-xyz/sdk
SDK for interacting with vault contracts on multiple EVM networks.
⚠️ Beta Warning: This package is currently in closed beta. If you encounter any issues, please contact us for support.
Installation
Core SDK
npm install @concrete-xyz/sdkReact Integration
npm install @concrete-xyz/sdk
# Then import from the react subpath
import { useVault } from "@concrete-xyz/sdk/react";Wagmi Integration
npm install @concrete-xyz/sdk
# Then import from the wagmi subpath
import { useVault, useVaultQuery } from "@concrete-xyz/sdk/wagmi";Quick Start
1. Core SDK (Vanilla JavaScript/TypeScript)
For direct usage without React or Wagmi:
import { getVault } from "@concrete-xyz/sdk";
import { ethers } from "ethers";
// Create provider
const provider = new ethers.JsonRpcProvider("YOUR_RPC_URL");
// Create vault instance
const vault = getVault(
"v1", // vault version ("v1" or "v2")
"0x15cE9bE6609db102b70D68ca75a39c555bEa5Fac", // vault address
1, // chainId
provider, // ContractRunner instance
);
// Get vault details
const vaultDetails = await vault.getVaultDetails();
console.log("Vault Symbol:", vaultDetails.symbolDetails);React Integration
For React applications, the SDK provides a custom hook useVault that integrates seamlessly with your existing providers.
Key Features:
- Requires explicit provider and signer instances (both are mandatory)
- Full control over network configuration
- Integrates with any React state management solution
React: useVault(version, address, chainId, provider, signer)
The React hook for interacting with vault contracts. Requires explicit provider and signer instances.
Parameters:
version("v1" | "v2"): The vault contract version to useaddress(string): The vault contract addresschainId(number): The blockchain network chain IDprovider(ContractRunner): Provider for read operationssigner(JsonRpcSigner): Signer for write operations
Returns: Vault instance with all available methods
Usage Example:
import { useVault } from "@concrete-xyz/sdk/react";
import { useCore } from "~/core/providers"; // Your core provider
export default function VaultComponent() {
const { web3 } = useCore();
const provider = web3.networkProvider;
const signer = web3.clientProvider;
const vault = useVault(
"v1", // vault version
"0x585934AfBf1FA9f563b80283F8B916Dd8F66a9b6", // vault address
80084, // chainId (Berachain)
provider, // ContractRunner instance
signer // Signer for write operations
);
// Use vault methods
const vaultDetails = await vault.getVaultDetails();
return <div>Vault: {String(vault)}</div>;
}Wagmi Integration
For applications using Wagmi, the SDK provides a simplified hook that automatically uses Wagmi's context.
Key Features:
- Automatic provider and signer detection
- Seamless integration with Wagmi's ecosystem
- Minimal configuration required
- Built-in TanStack Query integration with
useVaultQuery - Automatic caching and state management
Wagmi: useVault(config)
The Wagmi hook for interacting with vault contracts. Automatically uses Wagmi's configured providers and signers.
Parameters:
config(object):version("v1" | "v2"): The vault contract version to useaddress(string): The vault contract addresschainId(number): The blockchain network chain IDfallbackRpcUrl(string, optional): Fallback RPC URL if wallet is not connected
Returns: Vault instance with all available methods
Usage Example:
import { useVault } from "@concrete-xyz/sdk/wagmi";
export default function VaultComponent() {
const vault = useVault({
version: "v1",
address: "0x585934AfBf1FA9f563b80283F8B916Dd8F66a9b6",
chainId: 80084, // Berachain
});
// Use vault methods
const vaultDetails = await vault.getVaultDetails();
return <div>Vault: {String(vault)}</div>;
}Wagmi: useVaultQuery(options)
The Wagmi hook for querying vault data with automatic caching and state management. Built on top of TanStack Query for optimal performance.
Parameters:
options(object):vault(object): Vault configurationversion("v1" | "v2"): The vault contract version to useaddress(string): The vault contract addresschainId(number): The blockchain network chain IDfallbackRpcUrl(string, optional): Fallback RPC URL if wallet is not connected
queryKey(array): Additional key segments for TanStack Query cachingqueryFn(function): Function that receives the vault instance and returns the data to query- ...other TanStack Query options
Returns: TanStack Query result object with data, isLoading, error, etc.
Usage Example:
import { useVaultQuery } from "@concrete-xyz/sdk/wagmi";
export default function VaultComponent() {
const vaultQuery = useVaultQuery({
vault: {
version: "v1",
address: "0x585934AfBf1FA9f563b80283F8B916Dd8F66a9b6",
chainId: 80084, // Berachain
},
queryKey: ["vaultDetails"],
queryFn: async (vault) => await vault.getVaultDetails(),
});
return (
<div>
<pre>
{JSON.stringify(vaultQuery.data, null, 2)}
</pre>
</div>
);
}Hook Comparison
Key Differences:
- React version: Requires explicit provider and signer instances as separate parameters
- Wagmi version: Uses a config object and automatically uses Wagmi's configured providers and signers
- Wagmi version: Includes additional
useVaultQueryhook for TanStack Query integration - Wagmi version: Supports
fallbackRpcUrlfor scenarios when the wallet is not connected - Both versions: Require vault version ("v1" or "v2") and return the same vault instance with identical methods
Vanilla Examples
1. Get Vault Data
import { getVault } from "@concrete-xyz/sdk";
import { ethers } from "ethers";
const provider = new ethers.JsonRpcProvider("YOUR_RPC_URL");
const vault = getVault("v1", "0x15cE9bE6609db102b70D68ca75a39c555bEa5Fac", 1, provider); // chainId 1 = Ethereum
// Get complete vault information
const vaultDetails = await vault.getVaultDetails();
console.log("Vault Symbol:", vaultDetails.vaultAsset.symbol);
console.log("Underlying Asset:", vaultDetails.underlying.symbol);2. Preview Deposit
// Preview conversion before depositing
const depositAmount = BigInt(1 * 10 ** Number(await vault.getUnderlyingDecimals())); // 18 decimals token
const preview = await vault.previewConversion(depositAmount);
console.log(`Input: ${depositAmount} ${vaultDetails.underlying.symbol}`);
console.log(`Output: ${preview.vaultTokensReciving} ${vaultDetails.vaultAsset.symbol}`);3. Execute Deposit
// You need a signer for write operations
const signer = new ethers.Wallet("YOUR_PRIVATE_KEY", provider);
const vaultWithSigner = getVault("v1", "0x15cE9bE6609db102b70D68ca75a39c555bEa5Fac", 1, provider, signer); // chainId 1 = Ethereum
// Approve tokens first
const approveTx = await vaultWithSigner.approve(vaultWithSigner.getAddress(), depositAmount);
await approveTx.wait();
// Execute deposit
const depositTx = await vaultWithSigner.deposit(depositAmount);
const receipt = await depositTx.wait();
console.log("Deposit successful:", receipt);4. Execute Withdrawal
// Preview withdrawal
const withdrawAmount = BigInt(1 * 10 ** Number(await vault.decimals())); // 18 decimals underlying token + 9 decimal offset
const withdrawalPreview = await vault.previewConversion(withdrawAmount);
console.log(`Input: ${withdrawAmount} ${vaultDetails.vaultAsset.symbol}`);
console.log(`Output: ${withdrawalPreview.underlyingReceiving} ${vaultDetails.underlying.symbol}`);
// Execute withdrawal (using the same signer from previous example)
const withdrawTx = await vaultWithSigner.redeem(withdrawAmount);
const receipt = await withdrawTx.wait();
console.log("Withdrawal successful:", receipt);4.1 Withdrawal queue (v2)
V2 vaults use an epoch-based withdrawal queue. After requesting a withdrawal, funds are processed per epoch; when the epoch is finalized you can claim underlying, or cancel while the epoch is still active/inactive.
const vault = getVault("v2", vaultAddress, chainId, provider, signer);
const requests = await vault.getAllWithdrawQueueRequests(signer.address);
// Each request: { amount, epoch, epochState, claimable, cancelable, claim(), cancel(), ... }Claim (when request.claimable is true):
const request = requests.find((r) => r.claimable);
if (request) {
const tx = await request.claim();
await tx.wait();
}Cancel (when request.cancelable is true):
const request = requests.find((r) => r.cancelable);
if (request) {
const tx = await request.cancel();
await tx.wait();
}5. Get APY Details
import { getVault } from "@concrete-xyz/sdk";
const vault = getVault("v1", "0xE2d8267D285a7ae1eDf48498fF044241d04e9608", 42161); // chainId 42161 = Arbitrum
// Get APY information
const apyDetails = await vault.getApyDetails();
console.log("APY Details:", apyDetails);6. Get Oracle Price
import { getVault } from "@concrete-xyz/sdk";
import { ethers } from "ethers";
const rpcUrl = "https://arb1.arbitrum.io/rpc";
const provider = new ethers.JsonRpcProvider(rpcUrl);
const vault = getVault("v1", "0xE2d8267D285a7ae1eDf48498fF044241d04e9608", 42161, provider); // chainId 42161 = Arbitrum
// Get underlying asset price from oracle
const underlyingPrice = await vault.getUnderlyingPrice();
console.log("Underlying Price:", underlyingPrice);Supported Networks
The SDK supports multiple EVM networks including: Ethereum, Arbitrum, Corn, Morph, Berachain, and Katana.
Network Types:
- Mainnet: Ethereum, Arbitrum
- Testnet: Corn, Morph, Berachain, Katana
Note: Network support may vary based on your specific deployment. Always verify network compatibility before production use.
API Reference
getVault(version, address, chainId, clientProvider, signerProvider?)
Creates a new Vault instance for interacting with vault contracts.
Parameters:
version("v1" | "v2"): The vault contract version to use.address(string): The vault contract addresschainId(number): The blockchain network chain IDclientProvider(ContractRunner): Provider for read operationssignerProvider(JsonRpcSigner, optional): Signer for write operations
Returns: Vault instance
Vault Methods
The vault is an abstraction of a ERC-4626 Tokenized Vault, which in turn is an ERC-20 token that represents shares of underlying assets.
Technically, all ERC-4626 vault methods are available, but the SDK provides a simplified interface focusing on the most commonly used operations. Some less frequently used methods may not be directly exposed through the SDK wrapper.
Commonly used methods (examples):
getVaultDetails(): Get complete vault informationpreviewConversion(amount): Preview deposit/withdrawal conversiondeposit(amount): Deposit underlying tokens for vault tokensredeem(amount): Redeem vault tokens for underlying tokensapprove(spender, amount): Approve token spendingtotalAssets(): Get total assets in vaultsymbol(): Get vault symbol
Using ABI Directly
The SDK also provides access to both human-readable and raw ABI files for advanced use cases:
import abi from "@concrete-xyz/sdk/dist/src/core/contracts/abi/vault.json";
import rawAbi from "@concrete-xyz/sdk/dist/src/core/contracts/raw-abi/vault.json";
// Use vault human readable ABI
console.log(abi);
// Use vault raw ABI
console.log(rawAbi);This allows you to create custom contract instances or integrate with other libraries while maintaining access to the standardized vault interfaces.
