Pledge equity, mint USDG, liquidate, and stream positions in under twenty lines. Built on viem, fully typed, zero hidden network calls. Drop-in for any Node, Bun, or browser runtime.
// pledge.ts — 7 lines
import { ef } from "./client";
const r = await ef.vault.pledge({
account: wallet,
token: "TSLA",
amount: 12_500000000000000000n,
borrowUsd: 3_200000000000000000000n,
});
console.log(r.txHash, r.healthFactor.value);Tree-shakeable ESM. The SDK depends on viem for transport but does not pin a version.
pnpm add @equiflow/sdk viem # or npm i @equiflow/sdk viem # or bun add @equiflow/sdk viem
createClient binds the SDK to a chain, an RPC, and (optionally) a paymaster URL for gas-sponsored ops.
import { createEquiFlowClient } from "@equiflow/sdk";
import { robinhoodChainTestnet } from "@equiflow/sdk/chains";
export const ef = createEquiFlowClient({
chain: robinhoodChainTestnet,
transport: "https://rpc.testnet.chain.robinhood.com",
paymaster: "https://gas.equiflow.io/v1/userop",
});One call. The SDK assembles approve + pledgeAndBorrow into a single UserOperation when a paymaster is configured.
import { parseUnits } from "viem";
const receipt = await ef.vault.pledge({
account: wallet,
token: "TSLA",
amount: parseUnits("12.5", 18),
borrowUsd: parseUnits("3200", 18),
});
console.log(receipt.txHash, receipt.healthFactor.toString());Receipts contain the on-chain tx hash, the new position snapshot, and (when AA was used) the bundler hash.
if (receipt.status === "sealed") {
toast.success(`Borrowed ${formatUsd(receipt.borrowedUsd)}`);
router.push(`/portfolio`);
} else if (receipt.status === "reverted") {
console.error(receipt.error); // typed: ExceedsLtv | StalePrice | ...
}Pledge tokenized equity and mint USDG in a single signature. Falls back to two calls when no paymaster is configured.
import { createEquiFlowClient } from "@equiflow/sdk";
import { robinhoodChainTestnet } from "@equiflow/sdk/chains";
import { privateKeyToAccount } from "viem/accounts";
import { parseUnits } from "viem";
const ef = createEquiFlowClient({
chain: robinhoodChainTestnet,
transport: process.env.RBN_RPC_URL!,
paymaster: process.env.EF_PAYMASTER_URL!,
});
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const receipt = await ef.vault.pledge({
account,
token: "TSLA",
amount: parseUnits("12.5", 18),
borrowUsd: parseUnits("3200", 18),
slippageBps: 25,
});
if (receipt.status !== "sealed") throw new Error(receipt.error?.name);
console.log({
tx: receipt.txHash,
hf: receipt.healthFactor.toString(),
borrowed: receipt.borrowedUsd.toString(),
userOp: receipt.userOpHash, // undefined when no paymaster
});| Module | Import path | Purpose | Exports |
|---|---|---|---|
| ef.vault | @equiflow/sdk/vault | pledge, repay, withdraw, liquidate, simulate*. The most-used module. | 9 fns |
| ef.accounts | @equiflow/sdk/accounts | Smart-account creation, EIP-7702 delegation, counterfactual address resolution. | 5 fns |
| ef.pyth | @equiflow/sdk/pyth | Read normalized prices, refresh feeds, decode Pyth attestations off-chain. | 6 fns |
| ef.paymaster | @equiflow/sdk/paymaster | Build, sponsor, and submit ERC-4337 user operations. Bundled into vault.* helpers. | 4 fns |
| ef.events | @equiflow/sdk/events | Typed subscriptions for Pledged, Repaid, Liquidated, InterestAccrued. | 5 fns |
| ef.utils | @equiflow/sdk/utils | Health-factor math, USD ↔ token conversion, basis-point helpers, fmt.usd. | 14 fns |
type PledgeParams = {
account: Account | LocalAccount;
token: StockSymbol | Address;
amount: bigint; // collateral, base units
borrowUsd: bigint; // USDG, 1e18
slippageBps?: number; // default 50 (0.50%)
paymaster?: `0x${string}` | "paymaster" | false;
};Argument shape for vault.pledge(). The same shape is reused for simulate*().
type Position = {
user: Address;
collateralUsd: bigint;
borrowedUsd: bigint;
hf: number; // 1.000 = liquidation threshold
ltvBps: number;
isLiquidatable: boolean;
pledges: Pledge[];
};Snapshot returned by ef.positions.of(user) and embedded in every receipt.
type HealthFactor = {
value: number; // floating, derived from 1e18 raw
raw: bigint; // pass to contracts that take uint256
band: "safe" | "watch" | "callable";
collateralRoom: bigint; // USDG you could still borrow
dropToLiquidation: number; // % price drop before HF=1
};Returned by ef.utils.healthFactor(position) and ef.vault.hfOf(user).
| @equiflow/sdk | Raw wagmi + viem | REST API | |
|---|---|---|---|
| Pledge + borrow | 1 call · ef.vault.pledge() | 4 calls · approve → wait → contract write → wait | 1 POST · /v1/aa/userop |
| Gas sponsorship | built-in · paymaster opt-in | DIY · build, sign, submit userOp | automatic when key has sponsor scope |
| Type safety | full · custom errors typed | ABI-derived · errors are strings | OpenAPI 3.1 · client gen |
| Health-factor math | ef.utils.healthFactor() | manual · read collateralUsd + borrowedUsd | GET /v1/portfolio/:addr |
| Liquidation stream | for await · ef.liquidations.watch() | log filters · manual reconciliation | webhook position.liquidated |
| Bundle size | 27 kB gz | +viem +abitype = 84 kB gz | 0 — server-side |