EquiFlowquiFlow
ILLUSTRATIVE · @equiflow/sdk is not yet published. Code examples are illustrative.
Developers · TypeScript SDK · npm · MIT

EquiFlow SDK · TypeScript

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.

Quick start ↓GitHub ↗
Bundle size
27 kB
gzipped, ESM
Test coverage
94%
vitest + foundry fork
Weekly downloads
11,402
last 7 days
Minimal viable script
// 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);
>> EXPECT · sealed in ~1.8s · 1 signature · 0 ETH gas
Quick start · 4 steps · ~3 min

From npm install to first pledge.

01

Install the SDK and viem

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
02

Initialise a client

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",
});
03

Pledge and borrow

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());
04

Handle the receipt

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 | ...
}
Recipes · 4 copy-pasteable scripts

Examples worth stealing

Pledge & borrow

Pledge tokenized equity and mint USDG in a single signature. Falls back to two calls when no paymaster is configured.

>> EXAMPLES / pledge.ts
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 reference · 6 surfaces

What lives where

REST equivalent ↗
ModuleImport pathPurposeExports
ef.vault@equiflow/sdk/vaultpledge, repay, withdraw, liquidate, simulate*. The most-used module.9 fns
ef.accounts@equiflow/sdk/accountsSmart-account creation, EIP-7702 delegation, counterfactual address resolution.5 fns
ef.pyth@equiflow/sdk/pythRead normalized prices, refresh feeds, decode Pyth attestations off-chain.6 fns
ef.paymaster@equiflow/sdk/paymasterBuild, sponsor, and submit ERC-4337 user operations. Bundled into vault.* helpers.4 fns
ef.events@equiflow/sdk/eventsTyped subscriptions for Pledged, Repaid, Liquidated, InterestAccrued.5 fns
ef.utils@equiflow/sdk/utilsHealth-factor math, USD ↔ token conversion, basis-point helpers, fmt.usd.14 fns
Core types · re-exported from @equiflow/sdk/types

Type signatures you'll actually reach for

type · PledgeParams
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
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
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).

Comparison · pick your altitude

SDK vs raw wagmi vs REST API

@equiflow/sdkRaw wagmi + viemREST API
Pledge + borrow1 call · ef.vault.pledge()4 calls · approve → wait → contract write → wait1 POST · /v1/aa/userop
Gas sponsorshipbuilt-in · paymaster opt-inDIY · build, sign, submit userOpautomatic when key has sponsor scope
Type safetyfull · custom errors typedABI-derived · errors are stringsOpenAPI 3.1 · client gen
Health-factor mathef.utils.healthFactor()manual · read collateralUsd + borrowedUsdGET /v1/portfolio/:addr
Liquidation streamfor await · ef.liquidations.watch()log filters · manual reconciliationwebhook position.liquidated
Bundle size27 kB gz+viem +abitype = 84 kB gz0 — server-side
SHIPPING TODAY?Three command lines and you're calling the vault. The SDK ships TypeScript declarations and a Foundry-tested fork runner so your tests don't touch mainnet.