@wayne-zhang/ovault-evm
v0.0.5
Published
Zircuit OVault Implementation SDK
Maintainers
Readme
Installation
pnpm add @wayne-zhang/ovault-evmnpm install @wayne-zhang/ovault-evmOVault SDK
This is an SDK to make depositing/redeeming on OVaults simple.
Usage
All information required can be retrieved by calling OVaultSyncMessageBuilder.generateOVaultInputs.
You pass a GenerateOVaultSyncInputsProps object (see src/types.ts). Key points:
amountis an unscaled string (e.g."1.23")tokenLocalDecimalsis required to parse the unscaled amount into local-chain unitstokenHubDecimalsshould be the asset/share decimals on the hub chain (used forpreviewDeposit/previewRedeem)txArgsis now an object:{ base: [...], permitParams: [...] | null }- Optional EIP-2612 support via
supportsEip2612+sendWithPermit/depositAndSendWithPermit
{
srcEid: number,
hubEid: number,
dstEid: number,
walletAddress: `0x${string}`,
dstAddress?: `0x${string}`, // If no dstAddress is supplied, it's assumed to be the same as the source wallet address
vaultAddress: `0x${string}`,
composerAddress: `0x${string}`,
oftHubAddress: `0x${string}`, // hub-chain underlying OFT (used for hub redeem quotes/fees)
vaultTokenAddress: `0x${string}`, // source-chain VaultToken (shares) OFT address (used for spoke redeem quotes/fees)
hubChain: Chain, // This is a Viem chain definition
sourceChain: Chain, // This is a Viem chain definition
operation: OVaultSyncOperations,
amount: string, // unscaled string (e.g. "1.23")
tokenLocalDecimals: number,
tokenHubDecimals?: number,
slippage: number, // such as 0.01 for 1% slippage
buffer?: number, // optional fee buffer (e.g. 0.3 => +30%)
referralCode?: string, // optional referral code forwarded via oftCmd
oftAddress: `0x${string}`, // source-chain OFT/OFTAdapter address
tokenAddress: `0x${string}`, // source-chain ERC20 address (or 0x0 for native)
supportsEip2612?: boolean,
requiresZeroApprovalReset?: boolean,
}For full information about the input object check GenerateOVaultSyncInputsProps in src/types.ts.
You will receive an OVaultSyncInputs object back containing all information you need to build the transaction.
Example
Base Functionality
Below is an example of how to deposit tokens using the Viem client on a server side environment.
const input = {
srcEid: 40245, // eid for base-sepolia
hubEid: 40231, // eid for arbitrum-sepolia
dstEid: 40245, // eid for base-sepolia
// Optional. If dstAddress is not specified it will default to the walletAddress on the dst chain
dstAddress: "0x0000000000000000000000000000000000000000",
walletAddress: "0x0000000000000000000000000000000000000000",
vaultAddress: "0x0000000000000000000000000000000000000000",
// Address of the OVault Composer on the Hub Chain. Should implement IVaultComposerSync
composerAddress: "0x0000000000000000000000000000000000000000",
oftHubAddress: "0x0000000000000000000000000000000000000000",
vaultTokenAddress: "0x0000000000000000000000000000000000000000",
// Supply the Viem Chain Definitions for the hub and source chain. This is so the sdk can
// quote fees and perform read operations
hubChain: arbitrumSepolia,
sourceChain: baseSepolia,
operation: OVaultSyncOperations.DEPOSIT,
amount: "1.0", // unscaled string
tokenLocalDecimals: 18,
tokenHubDecimals: 18,
slippage: 0.01, // 1% slippage
// Address of the token/oft. The token is an ERC20. They can be the same address.
tokenAddress: "0x0000000000000000000000000000000000000000",
oftAddress: "0x0000000000000000000000000000000000000000",
} as const;
const inputs = await OVaultSyncMessageBuilder.generateOVaultInputs(input);
const account = privateKeyToAccount("YOUR PRIVATE KEY HERE");
const walletClient = createWalletClient({
account,
chain: srcChain.chain,
transport: http(),
}).extend(publicActions);
if (inputs.approval) {
// Approve token if required
const approvalTx = await walletClient.writeContract({
address: inputs.approval.tokenAddress,
abi: ERC20Abi,
functionName: "approve",
args: [inputs.approval.spender, inputs.approval.amount],
});
await walletClient.waitForTransactionReceipt({ hash: approvalTx });
}
const tx = await walletClient.writeContract({
address: inputs.contractAddress,
abi: inputs.abi,
value: inputs.messageFee.nativeFee,
functionName: inputs.contractFunctionName,
args: inputs.txArgs.base as any,
});For more example usage see test/sdk/transfer.test.ts.
Tracking transactions
To track cross-chain progress, use:
import { trackOVaultSyncTransaction } from "@wayne-zhang/ovault-evm"trackOVaultSyncTransaction(txHash, { sourceChain, hubChain, dstChain }, withdrawalInfo?)
If you are tracking withdrawals where multiple messages may exist, you can provide withdrawalInfo (OVaultWithdrawalInfo) so the tracker can pick the correct message index.
Development
- Build/typecheck:
npm run -s sdk:build - Run SDK tests:
npm run -s sdk:test
