1.0.23 • Published 5 months ago

@byzantine/vault-sdk v1.0.23

Weekly downloads
-
License
MIT
Repository
github
Last release
5 months ago

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:

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-sdk

Basic Setup

  1. Create a .env file 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
  1. 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 & ONSD

Vault 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 operations

Supported 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

1.0.23

5 months ago

1.0.22

5 months ago

1.0.21

5 months ago

1.0.20

6 months ago

1.0.19

6 months ago

1.0.18

6 months ago

1.0.17

6 months ago

1.0.16

6 months ago

1.0.15

6 months ago

1.0.14

6 months ago

1.0.13

6 months ago

1.0.12

6 months ago

1.0.11

6 months ago

1.0.10

6 months ago

1.0.9

6 months ago

1.0.8

6 months ago

1.0.7

6 months ago

1.0.6

6 months ago

1.0.5

6 months ago

1.0.4

6 months ago

1.0.3

6 months ago

1.0.2

6 months ago

1.0.1

7 months ago

1.0.0

7 months ago