@byzantine/vault-sdk v1.0.23
Byzantine Vault SDK
A TypeScript/JavaScript SDK for creating and managing vaults with Byzantine Finance Factory contract.
About Byzantine Finance
Byzantine Finance is the first native restaking aggregation and abstraction layer. The protocol allows users to deploy various types of vaults for generating staking and restaking revenues.
This SDK provides a simple interface to interact with the Byzantine Factory contract deployed on:
- Ethereum Mainnet -> Soon
- Holesky Testnet
- Sepolia Testnet
- Hoodi Testnet -> Soon
The factory contract allows users to:
- Create Eigenlayer ERC20 vaults
- Create Symbiotic ERC20 vaults
- Create ERC20 SuperVaults with advanced features
Installation
npm install @byzantine/vault-sdkBasic Setup
- Create a
.envfile in your project root with the following variables:
RPC_URL=https://holesky.infura.io/v3/your_api_key_here
# Choose ONE of the following authentication methods:
MNEMONIC=your_wallet_mnemonic
# OR
PRIVATE_KEY=your_wallet_private_key_without_0x_prefix
DEFAULT_CHAIN_ID=17000 # 17000 for Holesky testnet, 1 for Ethereum Mainnet, 11155111 for Sepolia, 560048 for Hoodi Testnet- Import and initialize the client:
import {
ByzantineClient,
ETH_TOKEN_ADDRESS,
BaseParams,
} from "@byzantine/vault-sdk";
import { ethers } from "ethers";
import * as dotenv from "dotenv";
dotenv.config();
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
const wallet = ethers.Wallet.fromPhrase(process.env.MNEMONIC).connect(provider);
// OR const wallet = new ethers.Wallet(process.env.PRIVATE_KEY).connect(provider);
const client = new ByzantineClient({
chainId: 17000, // 17000 for Holesky, 11155111 for Sepolia, 1 for Mainnet, 560048 for Hoodi
provider: provider,
signer: wallet,
});Quick Start
Creating an Eigenlayer ERC20 Vault
import { ByzantineClient, getNetworkConfig } from "@byzantine/vault-sdk";
import { ethers } from "ethers";
// Initialize with ethers provider and signer
const provider = new ethers.JsonRpcProvider(
"https://holesky.infura.io/v3/YOUR_API_KEY"
);
const wallet = ethers.Wallet.fromPhrase("your mnemonic").connect(provider);
// OR const wallet = new ethers.Wallet(process.env.PRIVATE_KEY).connect(provider);
const client = new ByzantineClient({
chainId: 17000, // Holesky testnet
provider: provider,
signer: wallet,
});
// Get the network configuration for token addresses
const networkConfig = getNetworkConfig(17000);
// Define vault parameters
const baseParams: BaseParams = {
metadata: {
name: "Eigenlayer stETH Vault",
description: "An Eigenlayer vault for stETH restaking",
image_url: "https://example.com/updated-vault-image.png",
social_twitter: "https://x.com/byzantine_fi",
social_discord: "https://discord.gg/byzantine",
social_telegram: "https://t.me/byzantine",
social_website: "https://byzantine.fi",
social_github: "https://github.com/byzantine-finance",
},
token_address: networkConfig.stETHAddress,
is_deposit_limit: true,
deposit_limit: ethers.parseUnits("1000", 18),
is_private: false,
is_tokenized: true,
token_name: "Byzantine stETH Vault",
token_symbol: "bstETH",
curator_fee: 500, // 5% (500 basis points)
role_manager: wallet.address,
role_version_manager: wallet.address,
role_deposit_limit_manager: wallet.address,
role_deposit_whitelist_manager: wallet.address,
role_curator_fee_claimer: wallet.address,
role_curator_fee_claimer_admin: wallet.address,
};
const eigenlayerParams: EigenlayerParams = {
operator_id: "0xb564e795f9877b416cd1af86c98cf8d3d94d760d", // Replace with actual operator ID
role_validator_manager: wallet.address,
};
// Create the vault
const tx = await client.createEigenlayerERC20Vault({
base: baseParams,
eigenlayer: eigenlayerParams,
});
// Wait for confirmation
const receipt = await tx.wait();
console.log(`Vault created in block ${receipt.blockNumber}`);
// Determine the vault address from the logs
const vaultAddress = receipt.logs[0].address;
console.log(`Vault created at address: ${vaultAddress}`);Creating an Eigenlayer Native (ETH) Vault
// -
// All import and initialize client as shown above
// -
// Define vault parameters
const nativeParams: NativeParams = {
byzVaultParams: {
metadata: {
name: "Eigenlayer ETH Vault",
description: "An Eigenlayer vault for ETH restaking",
},
token_address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
is_deposit_limit: true,
deposit_limit: ethers.parseEther("100"),
is_private: false,
is_tokenized: true,
token_name: "Byzantine ETH Vault",
token_symbol: "bETH",
curator_fee: 300, // 3% (300 basis points)
role_manager: wallet.address,
role_version_manager: wallet.address,
role_deposit_limit_manager: wallet.address,
role_deposit_whitelist_manager: wallet.address,
role_curator_fee_claimer: wallet.address,
role_curator_fee_claimer_admin: wallet.address,
},
operator_id:
"0x0000000000000000000000000000000000000000000000000000000000000000",
roles_validator_manager: [wallet.address],
};
const eigenlayerParams: EigenlayerParams = {
delegation_set_role_holder: wallet.address,
operator: "0xb564e795f9877b416cd1af86c98cf8d3d94d760d",
approver_signature_and_expiry: {
signature: "0x",
expiry: 0,
},
approver_salt:
"0x0000000000000000000000000000000000000000000000000000000000000000",
};
const eigenPodParams: EigenpodParams = {
eigen_pod_manager: address,
};
// Create the vault
const tx = await client.createEigenlayerNativeVault({
base: nativeParams,
eigenlayer: eigenlayerParams,
eigenpod: eigenPodParams,
});
// Wait for confirmation
const receipt = await tx.wait();Creating a Symbiotic ERC20 Vault
// -
// All import and initialize client as shown above
// -
// Define vault parameters
const baseParams: BaseParams = {
// Either metadata (that will be converted to URI) or directly URI
metadata:
"data:application/json;base64,eyJuYW1lIjoiU3ltYmlvdGljIG1FVEggVmF1bHQiLCJkZXNjcmlwdGlvbiI6IkEgU3ltYmlvdGljIHZhdWx0IGZvciBtRVRIIHJlc3Rha2luZyIsImltYWdlX3VybCI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdXBkYXRlZC12YXVsdC1pbWFnZS5wbmciLCJzb2NpYWxfdHdpdHRlciI6Imh0dHBzOi8veC5jb20vYnl6YW50aW5lX2ZpIiwic29jaWFsX2Rpc2NvcmQiOiJodHRwczovL2Rpc2NvcmQuZ2cvYnl6YW50aW5lIiwic29jaWFsX3RlbGVncmFtIjoiaHR0cHM6Ly90Lm1lL2J5emFudGluZSIsInNvY2lhbF93ZWJzaXRlIjoiaHR0cHM6Ly9ieXphbnRpbmUuZmkiLCJzb2NpYWxfZ2l0aHViIjoiaHR0cHM6Ly9naXRodWIuY29tL2J5emFudGluZS1maSJ9",
token_address: "0x8d09a4502Cc8Cf1547aD300E066060D043f6982D", // wstETH
is_deposit_limit: true,
deposit_limit: ethers.parseUnits("500", 18), // 500 wstETH
is_private: false,
is_tokenized: true,
token_name: "Byzantine wstETH Symbiotic Vault",
token_symbol: "bwstETHs",
curator_fee: 200, // 2% (200 basis points)
role_manager: wallet.address,
role_version_manager: wallet.address,
role_deposit_limit_manager: wallet.address,
role_deposit_whitelist_manager: wallet.address,
role_curator_fee_claimer: wallet.address,
role_curator_fee_claimer_admin: wallet.address,
};
const symbioticParams: SymbioticParams = {
vault_version: 1,
vault_epoch_duration: 604800, // 7 days in seconds
slasher_type: SlasherType.VETO,
slasher_veto_duration: 86400, // 1 day in seconds
slasher_number_epoch_to_set_delay: 3,
burner_delay_settings_applied: 21, // 21 days
burner_global_receiver: "0x25133c2c49A343F8312bb6e896C1ea0Ad8CD0EBd", // Global receiver for wstETH
burner_network_receiver: [],
burner_operator_network_receiver: [],
delegator_type: DelegatorType.NETWORK_RESTAKE,
delegator_hook: "0x0000000000000000000000000000000000000001", // Delegator hook address
delegator_operator: "0x0000000000000000000000000000000000000000", // Not used for NETWORK_RESTAKE
delegator_network: "0x0000000000000000000000000000000000000000", // Not used for NETWORK_RESTAKE
role_delegator_set_hook: address,
role_delegator_set_network_limit: [address],
role_delegator_set_operator_network_limit: [address],
role_burner_owner_burner: address,
};
// Create the vault
const tx = await client.createSymbioticERC20Vault({
base: baseParams,
symbiotic: symbioticParams,
});
// Wait for confirmation
const receipt = await tx.wait();Creating a ERC20 SuperVault
// -
// All import and initialize client as shown above
// -
// Define vault parameters
const baseParams = {
metadata: {
name: "SuperVault osETH",
description: "A SuperVault for osETH with high yields",
},
token_address: networkConfig.osETHAddress, // osETH addresss
is_deposit_limit: true,
deposit_limit: ethers.parseUnits("1000000", 18), // 1M osETH (18 decimals)
is_private: false, // Private SuperVault
is_tokenized: true,
token_name: "Byzantine osETH SuperVault",
token_symbol: "bsosETHs",
curator_fee: 600, // 6% (600 basis points)
// Roles - replace with actual addresses in production
role_manager: address,
role_version_manager: address,
role_deposit_limit_manager: address,
role_deposit_whitelist_manager: address,
role_curator_fee_claimer: address,
role_curator_fee_claimer_admin: address,
};
const symbioticParams = {
vault_version: 1,
vault_epoch_duration: 604800, // 7 days in seconds
slasher_type: SlasherType.VETO,
slasher_veto_duration: 86400, // 1 day in seconds
slasher_number_epoch_to_set_delay: 3,
burner_delay_settings_applied: 21, // 21 days
burner_global_receiver: "0x25133c2c49A343F8312bb6e896C1ea0Ad8CD0EBd", // Global receiver for wstETH
burner_network_receiver: [],
burner_operator_network_receiver: [],
delegator_type: DelegatorType.NETWORK_RESTAKE,
delegator_hook: "0x0000000000000000000000000000000000000001", // Delegator hook address
delegator_operator: "0x0000000000000000000000000000000000000000", // Not used for NETWORK_RESTAKE
delegator_network: "0x0000000000000000000000000000000000000000", // Not used for NETWORK_RESTAKE
role_delegator_set_hook: address,
role_delegator_set_network_limit: [address],
role_delegator_set_operator_network_limit: [address],
role_burner_owner_burner: address,
};
const eigenlayerParams = {
// Eigenlayer specific params
delegation_set_role_holder: address,
operator: "0xb564e795f9877b416cd1af86c98cf8d3d94d760d", // Blockshard
approver_signature_and_expiry: {
signature: "0x", // null signature
expiry: 0, // no expiry
},
approver_salt:
"0x0000000000000000000000000000000000000000000000000000000000000000", // null salt
};
const ratio = 500; // 5%
const curator = address;
// Create the vault
const tx = await client.createSuperVaultERC20({
base: baseParams,
symbiotic: symbioticParams,
eigenlayer: eigenlayerParams,
ratio: ratio,
curator: curator,
});
// Wait for confirmation
const receipt = await tx.wait();Available Functions
Create Vaults
// Create Eigenlayer ERC20
await client.createEigenlayerERC20Vault(params);
// Create Eigenlayer Native
await client.createEigenlayerNativeVault(params);
// Create Symbiotic ERC20
await client.createSymbioticERC20Vault(params);
// Create SuperVault ERC20
await client.createSuperVaultERC20(params);Curate
// Whitelist Management
await client.isAddressWhitelisted(vaultAddress, address);
await client.isVaultPrivate(vaultAddress);
await client.setAddressesWhitelistStatus(vaultAddress, addresses, canDeposit);
await client.setVaultPrivateStatus(vaultAddress, isPrivate);
// Deposit Limit Management
await client.getVaultDepositLimit(vaultAddress);
await client.isDepositLimitEnabled(vaultAddress);
await client.setVaultDepositLimit(vaultAddress, limit);
await client.setDepositLimitStatus(vaultAddress, enabled);
// Metadata Management
await client.getVaultMetadata(vaultAddress);
await client.updateVaultMetadata(vaultAddress, metadata);
// Fee Management
await client.getVaultFeePercentage(vaultAddress);
await client.getUnclaimedFees(vaultAddress);
await client.setVaultFeePercentage(vaultAddress, feePercentage);
await client.claimVaultFees(vaultAddress);
// SuperVault Management
await client.getDistributionRatio(supervaultAddress);
await client.getUnderlyingVaults(supervaultAddress);
await client.updateDistributionRatio(supervaultAddress, ratio);
await client.forceRebalance(supervaultAddress);
// Shares Management
await client.isSharesTokenized(vaultAddress);
await client.getSharesName(vaultAddress);
await client.getSharesSymbol(vaultAddress);
await client.getTotalShares(vaultAddress);
await client.getSharesBalance(vaultAddress, userAddress);
await client.convertToShares(vaultAddress, assets);
await client.convertToAssets(vaultAddress, shares);
// Role Management
await client.isManager(vaultAddress, RoleType.CURATOR, userAddress); // Global getter of the roles
await client.isRoleManager(vaultAddress, userAddress);
await client.isVersionManager(vaultAddress, userAddress);
await client.isWhitelistManager(vaultAddress, userAddress);
await client.isLimitManager(vaultAddress, userAddress);
await client.isDelegationManager(vaultAddress, userAddress);
await client.isOperatorNetworkSharesManager(vaultAddress, userAddress);
await client.isOperatorNetworkLimitManager(vaultAddress, userAddress);
await client.isNetworkLimitManager(vaultAddress, userAddress);
await client.isCurator(vaultAddress, userAddress);
await client.isCuratorFeeClaimer(vaultAddress, userAddress);
await client.isCuratorFeeClaimerAdmin(vaultAddress, userAddress);
await client.isOwnerBurner(vaultAddress, userAddress);
await client.isValidatorsManager(vaultAddress, userAddress);
await client.setManager(vaultAddress, RoleType.CURATOR, userAddress); // Global setter of the roles
await client.setRoleManager(vaultAddress, userAddress, enable);
await client.setVersionManager(vaultAddress, userAddress, enable);
await client.setWhitelistManager(vaultAddress, userAddress, enable);
await client.setLimitManager(vaultAddress, userAddress, enable);
await client.setDelegationManager(vaultAddress, userAddress, enable);
await client.setOperatorNetworkSharesManager(vaultAddress, userAddress, enable);
await client.setOperatorNetworkLimitManager(vaultAddress, userAddress, enable);
await client.setNetworkLimitManager(vaultAddress, userAddress, enable);
await client.setCurator(vaultAddress, userAddress, enable);
await client.setCuratorFeeClaimer(vaultAddress, userAddress, enable);
await client.setCuratorFeeClaimerAdmin(vaultAddress, userAddress, enable);
await client.setOwnerBurner(vaultAddress, userAddress, enable);
await client.setValidatorsManager(vaultAddress, userAddress, enable);Staker
// Vault Information
await client.getVaultAsset(vaultAddress);
await client.getUserWalletBalance(assetAddress, userAddress);
await client.getUserVaultBalance(vaultAddress, userAddress);
await client.getVaultTVL(vaultAddress);
await client.getUserAllowance(assetAddress, userAddress, vaultAddress);
await client.getVaultType(vaultAddress); // Return RestakingProtocol ( "EigenLayer" | "Symbiotic" | "SuperVault" )
await client.isSymbioticVault(vaultAddress);
await client.isEigenVault(vaultAddress);
await client.isSupervault(vaultAddress);
// Deposit
await client.approveVault(assetAddress, vaultAddress, amount);
await client.depositToVault(vaultAddress, amount, autoApprove);
// Withdraw
await client.withdrawFromVault(vaultAddress, amount);
await client.redeemSharesFromVault(vaultAddress, shares);
await client.isClaimable(vaultAddress, requestId);
await client.completeWithdrawal(vaultAddress, requestId);
await client.getWithdrawalRequest(vaultAddress, requestId);
// Eigenlayer
await client.getEigenOperator(vaultAddress);
await client.setEigenOperator(
vaultAddress,
operator,
approverSignatureAndExpiry,
approverSalt
);
// Symbiotic
await client.getEpochAt(vaultAddress, timestamp);
await client.getEpochDuration(vaultAddress);
await client.getCurrentEpoch(vaultAddress);
await client.getCurrentEpochStart(vaultAddress);
await client.getPreviousEpochStart(vaultAddress);
await client.getNextEpochStart(vaultAddress);
await client.getSymVaultAddress(vaultAddress);
await client.getBurnerAddress(vaultAddress);
await client.getDelegatorAddress(vaultAddress);
await client.getDelegatorType(vaultAddress);
await client.getDelegatorOperator(vaultAddress); // Only for OSD
await client.getDelegatorNetwork(vaultAddress); // Only for OSD & ONSDVault Types
Eigenlayer Vaults
Eigenlayer vaults allow users to deposit ETH or ERC20 tokens for restaking on Eigenlayer's protocol. The two types available are:
- Eigenlayer Native (ETH) - For restaking ETH natively
- Eigenlayer ERC20 - For restaking supported ERC20 tokens (e.g., stETH, rETH)
Symbiotic Vaults
Symbiotic vaults provide enhanced features for ERC20 tokens, allowing customizable delegation strategies and slashing parameters.
SuperVaults
SuperVaults are advanced vaults with additional features for managing ERC20 tokens with greater customization and control.
Testing
The SDK includes comprehensive tests for all vault types and operations:
# Install dependencies
npm install
# Build the SDK
npm run build
# Run all tests (requires environment variables in .env file)
npm run test
# Run specific vault creation tests
npm run test:eigen-erc20 # Test Eigenlayer ERC20 vault creation
npm run test:eigen-native # Test Eigenlayer Native vault creation
npm run test:symbiotic-erc20 # Test Symbiotic ERC20 vault creation
npm run test:supervault-erc20 # Test SuperVault ERC20 creation
# Run vault operation tests
npm run test:vault-read-data # Test reading vault data
npm run test:vault-operation # Test vault operations (deposit/withdraw)
npm run test:vault-metadata # Test vault metadata operations
npm run test:vault-claim-withdrawals # Test withdrawal claim process
npm run test:vault-roles # Test role management operationsSupported Networks
- Ethereum Mainnet (Chain ID: 1) -> Soon
- Holesky Testnet (Chain ID: 17000)
- Sepolia Testnet (Chain ID: 11155111)
- Hoodi Testnet (Chain ID: 560048) -> Soon
By default, the SDK is configured to use Holesky testnet (Chain ID: 17000). To use Ethereum Mainnet, specify chainId: 1 when initializing the client. chainId: 11155111 for Sepolia Testnet. chainId: 560048 for Hoodi Testnet.
NPM Package
This SDK is available on npm as @byzantine/vault-sdk.
Security
All Byzantine Finance contracts have been thoroughly audited.
License
MIT
5 months ago
5 months ago
5 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
7 months ago
7 months ago