npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

sally-defi-ts-sdk

v0.3.3

Published

Fully on-chain TypeScript SDK for the Sally DeFi CrossHybrid protocol (Base + BSC) — swaps, pricing, liquidity. No API, no subgraph, no backend.

Readme

sally-defi-ts-sdk · TypeScript SDK

One client for CrossHybrid swaps & liquidity on Base + BSC.

Wraps the live Sally v2.0.2 protocol — best-route hybrid swaps, V2·V3·V4·Slipstream liquidity, 1e18 USD pricing, honeypot screening, locks and referral fees — behind one typed, beginner-friendly and AI-agent-ready API.

100% on-chain — no API, no subgraph, no backend.

Website · Docs · Examples · [email protected]

Built on ethers v6. Tracks Sally protocol deployment v2.0.2.


Why sally-defi-ts-sdk

Most TypeScript DeFi code is raw ethers/viem: untyped tuples, hand-rolled approvals, a quote you hope matches execution, and zero protection against honeypots or sandwiches. sally-defi-ts-sdk collapses all of that into one safe call.

swap.execute does the work a careful integrator would do by hand — approve → enumerate routes → simulate every route on-chain → screen the output token for honeypot/tax → set minOut from the simulated output → send → assert you actually received it. That whole pipeline is the default, not an opt-in.

  • 🌐 Fully on-chain & decentralized. Every read — prices, routes, positions, balances — is a direct eth_call to the contracts. No proprietary API, no subgraph / Graph Node, no backend. Point it at any RPC (or your own node) and the only thing you trust is the chain itself.
  • 🎯 Exact output, not an estimate. Routes are ranked and minOut is set from the realized amountOut of the real executeHybridSwap (eth_call'd against live state), not a reserve-formula guess — plan.simulatedOut is what you'd actually receive. See docs/safety.md.
  • 🛡️ Safety in the hot path. Simulate-before-execute + post-trade balance-delta assertion — not just in your test suite.
  • 🧱 Typed end-to-end. pos.liquidity, plan.isSafe, quote.estimatedAmountOut — classes, autocomplete, ships .d.ts. No tuple[7].
  • 🤖 AI-agent-ready by construction. Every return serializes cleanly, so wiring Sally into LLM tools is mechanical.
  • Async + MEV-protection + permit are constructor/option arguments, not projects.
  • 🪶 Light deps (just ethers), Node ≥ 18, full TypeScript types.

Honest about scope: Sally routes within its own protocol on Base + BSC — it is not a 100-source aggregator. Full, cited comparison (advantages and trade-offs) vs raw ethers.js / viem / Uniswap SDK / aggregator SDKs: docs/comparison.md.

🌐 Fully on-chain, fully decentralized

The SDK talks to the chain and nothing else. Routing, pricing, positions, honeypot screening and balances are all read with plain eth_calls against the on-chain contracts — there is no Sally API, no Graph Node / subgraph, no indexer and no backend service in the data path. The only runtime dependency is ethers. Bring your own RPC or node and you trust nothing but the chain.

What you get

  • One object, every function. SallyClient exposes the whole protocol through feature namespaces (prices, swap, wallet, liquidity, fees). Reads need only an RPC; writes need a signer.
  • Safe by default. swap.execute enumerates routes, integrity-checks each so funds can never enter a wrong pool, simulates every candidate on-chain, picks the best realized output, runs a honeypot/tax probe on the output token, sets minOut from the simulation, then asserts the received balance actually grew.
  • Single source of truth. All addresses + ABIs come from the bundled deployment.json (addresses + ABIs only). Nothing hard-coded; drop in a new deployment and the SDK follows.
  • Proxy-fallback aware. v2.0.2 serves Lens views through the swap proxy and Sidecar views through the liq proxy — the SDK wires this for you.
  • Typed returns. Every struct is a class (SwapPath, V3Position, Lock, SwapPlan, …) — pos.liquidity, not pos[7].

Install

npm install sally-defi-ts-sdk ethers

Requires Node ≥ 18 and ethers >= 6.

Quickstart (read-only)

import { SallyClient, Base } from "sally-defi-ts-sdk";

const sally = new SallyClient("base", "https://mainnet.base.org");

(await sally.prices.usd(Base.USDC)).asFloat;          // 1.0  (display / spot-mid)
(await sally.prices.usdImpact(Base.WETH)).asFloat;    // 1703.19  (execution-aware)

const quote = await sally.swap.quote(Base.WETH, Base.USDC, 10n ** 18n);
Number(quote.estimatedAmountOut) / 1e6;               // 1703.45 USDC

Swapping — safe by default

const sally = new SallyClient("base", RPC, { privateKey: "0x…" }); // or SALLY_PRIVATE_KEY env

// Inspect first: compares every route, simulates each, screens the output token.
const plan = await sally.swap.plan(Base.WETH, Base.USDC, 10n ** 18n);
plan.summary();            // 'SwapPlan(… out~1702924727 sim=1702924727 min=1694410103 impact=13bps steps=2 SAFE)'
plan.isSafe;               // false if honeypot / excessive tax / >15% impact / bad route
plan.candidates;           // every route considered, with simulated output

// Execute: same vetting, then send + balance-delta assertion.
const receipt = await sally.swap.execute(Base.WETH, Base.USDC, 10n ** 18n, { slippageBps: 50 });

// Native ETH in — pass the NATIVE sentinel; value is attached for you.
import { NATIVE } from "sally-defi-ts-sdk";
await sally.swap.execute(NATIVE, Base.USDC, 10n ** 17n, { slippageBps: 50 });

What execute does, in order: approve (exact amount) → enumerate routes → integrity-check → simulate each on-chain → pick best realized output → honeypot/tax preflight → minOut from the simulation → send → assert received ≥ minOut. See docs/safety.md.

Tune the guard rails:

import { SafetyConfig } from "sally-defi-ts-sdk";
const sally = new SallyClient("base", RPC, {
  privateKey: "0x…",
  safety: new SafetyConfig({ slippageBps: 30, taxBlockBps: 3000, priceImpactBlockBps: 1000 }),
});

Liquidity

await sally.liquidity.addV2(4, Base.WETH, Base.USDC, 10n ** 15n, 2_000_000n, { lockDays: 0 });

await sally.liquidity.positionsV3(wallet, 0, 10);    // V3Position[]
await sally.liquidity.locks(wallet);                 // Lock[]
await sally.liquidity.claimableFees(npm, tokenId);   // ClaimableFees
// addV3 / addV4 / addSlipstream, increase/decrease, removeV2,
// lock/unlock, claimFeesV3/V4(+Locked), massClaimFees, harvestOp

Referral system 💸

Every swap and liquidity action takes a referral address. Pass yours and the protocol accrues referral fees to it; read and claim them anytime:

await sally.swap.execute(Base.WETH, Base.USDC, 10n ** 18n, { referral: "0xYourRef" });

await sally.fees.totalReferralOwed("0xYourRef");        // total owed across tokens
await sally.fees.referralTokens("0xYourRef");           // per-token breakdown (paged)
await sally.fees.claimReferral([Base.USDC, Base.WETH]); // claim selected tokens

See docs/referrals.md.

Async · permit · private mempool

// Async (concurrent quoting + simulation)
import { AsyncSallyClient } from "sally-defi-ts-sdk/aio";
import { Base } from "sally-defi-ts-sdk";
const sally = new AsyncSallyClient("base", RPC, { privateKey: "0x…" });
await sally.swap.execute(Base.WETH, Base.USDC, 10n ** 18n, { slippageBps: 50 });

// EIP-2612 permit instead of approve
await sally.swap.execute(Base.USDC, Base.WETH, 10n ** 8n, { approval: "permit" });

// Private mempool (MEV protection)
import { PrivateRelays } from "sally-defi-ts-sdk";
new SallyClient("base", RPC, { privateKey: "0x…", privateRpcUrl: PrivateRelays.FLASHBOTS_FAST });

Full guide: docs/advanced.md.

Sign with your own wallet 🔑

Give a privateKey, a mnemonic, or no key at all — build a vetted, simulated, ABI-decoded unsigned transaction and sign it with your own ethers wallet:

// mnemonic seed phrase
const sally = new SallyClient("base", RPC, { mnemonic: "word1 … word12", accountIndex: 0 });

// external signing — the SDK never holds your key
const ext = new SallyClient("base", RPC, { address: "0xYourWallet" }); // knows sender, no key
const build = await ext.swap.execute(Base.WETH, Base.USDC, 10n ** 18n, { buildOnly: true });
build.plan.summary();       // what happens to your wallet: out, min, impact, safe?
build.needsApproval;        // sign build.approveTx first if true
build.swapTx;               // unsigned tx → sign with your own account, then broadcast

// preview ANY call: decoded function + args + simulated result + revert reason
(await ext.preview(fn, args)).summary();

See docs/signing.md.

Namespaces

| Namespace | What it covers | |---|---| | client.prices | usd (display), usdImpact (exec), spot, weth, usdLiquidity, tokenInfo | | client.swap | quote(V2/V3/V4/Deep), candidates, plan, simulateRoute, execute (+ buildOnly), tokenInfo | | client.wallet | balances, balancesRaw, totalUsd | | client.liquidity | add / increase / decrease / remove / lock / claim / harvest, positions, pool state, dex registry | | client.fees | referral + batch fee reads & claims, swapFee |

Raw contracts are always reachable: client.swapContract, …liquidityContract, …lensContract, …sidecarContract.

AI agents

Every call returns a JSON-able typed object with a clear doc comment — wrapping Sally as LLM tools is trivial. See docs/ai-agents.md and examples/10_ai_agent_tools.ts.

Docs

| | | |---|---| | Why sally-defi-ts-sdk | comparison vs other DeFi SDKs, advantages & trade-offs | | Getting started | install, connect, first read & swap | | Swap & safety | route comparison, simulation, all guard rails | | Liquidity | add/remove/lock/harvest across V2·V3·V4 | | Pricing | display vs execution price, spot, impact | | Referrals | earn & claim referral fees | | Advanced | async client, EIP-2612 permit, Permit2, private mempool, BSC | | AI agents | typed returns as tool functions | | API reference | every namespace + method |

Live deployment (v2.0.2, Base = BSC)

| Contract | Address | |---|---| | SwapController (proxy) | 0x7777D0e2e2d772b5D750540B3932261574e87777 | | LiquidityController (proxy) | 0x7777d7fFF155B043CE0A0785dd8c8c42bEbe7777 | | Treasury | 0x7777D7dC7ea65F33EC126165e03C6B6030887777 |

Development & tests

npm install
npm run build               # tsc -> dist/ (+ copies deployment.json)
npm test                    # offline vitest unit tests (no network)
npm run typecheck           # tsc --noEmit

Support

Questions, integrations, partnerships → [email protected] · sally.tools

License

MIT