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

@steerprotocol/collateral-rail-sdk

v0.1.0

Published

TypeScript SDK for Collateral Rail hook integrations (browser and Node.js)

Readme

Collateral Rail SDK

TypeScript SDK for interacting with Collateral Rail protocol contracts from Node.js and browser environments.

The package is built with viem and wagmi and supports:

  • Protocol action read/write helpers (CollateralManager, CollateralSettlementController, RegisteredIssuerBrokerAdapter, RiskConfig, HybridCollateralSettlementHook, ChainlinkOracleAdapter, SampleStablecoin)
  • Swap call builders with hook-aware hookData and optional signed-quote flow
  • Settlement and risk event decoding
  • Error decoding for protocol-specific reverts
  • Market launch planning helpers
  • Signed quote helper surfaces (signSignedSwapQuote, buildSignedSwapQuotePayload, splitSignature)
  • Registered issuer hook-data and broker-payload builders for the USDM1 AtomicBroker rail

Signed Quote Quick Rules

  • Signed quote mode is optional; no signed quote uses canonical Model 1 behavior.
  • If a signed quote is supplied and validation fails, settlement reverts (no same-transaction fallback).
  • expiry is a Unix timestamp in seconds.
  • maxAbsAmount is compared against abs(amountSpecified) for the swap.

Client Model

Primary SDK API is viem-first and is stable across environments:

  • PublicClient for reads (Node.js, scripts, backend services, server-side rendering)
  • WalletClient for writes (Node.js + browser signing)

@wagmi/cli generated actions are included as an optional typed layer for teams that already use wagmi.

Why this design

  • Avoids a breaking refactor in environments that don’t use wagmi
  • Keeps transport and signer concerns explicit
  • Preserves compatibility for backend tooling, tests, and multi-runtime usage

Client Compatibility

Recommended pattern (stable)

import {
  createProtocolPublicClient,
  createProtocolWalletClient,
  previewCollateralManagerSwap,
} from "@steerprotocol/collateral-rail-sdk";
import { optimismSepolia } from "viem/chains";

const publicClient = createProtocolPublicClient({
  chain: optimismSepolia,
  rpcUrl: "https://sepolia.optimism.io",
});
const walletClient = createProtocolWalletClient({
  chain: optimismSepolia,
  rpcUrl: "https://sepolia.optimism.io",
});

await previewCollateralManagerSwap(
  publicClient,
  collateralManager,
  sender,
  poolKey,
  swapParams,
);

Optional wagmi-typed action path

For teams already on wagmi, generated typed contract actions are available as:

import { generated } from "@steerprotocol/collateral-rail-sdk";

// generated.readCollateralManagerMaxMintable(config, { address, args: [account] })
// generated.writeCollateralManagerSetOracleAdapter(config, { address, args: [adapter] })

This is additive and does not replace the viem-first helpers.

Installation

npm install @steerprotocol/collateral-rail-sdk

Browser (wagmi) Example

import {
  clientsFromWagmiConfig,
  buildExactInputSignedQuoteCallDescriptor,
  buildSwapIntent,
  signSignedSwapQuote,
  type SignedSwapQuoteBase,
} from "@steerprotocol/collateral-rail-sdk";
import { sepolia } from "viem/chains";

const clients = clientsFromWagmiConfig({ config: wagmiConfig });

const params = {
  amountSpecified: -10_000000n,
  sqrtPriceLimitX96: 0n,
  amountOutMinimum: 0n,
  zeroForOne: true,
};

const intent = buildSwapIntent(params, undefined);
console.log(intent.direction); // "mint"

const swapInput = {
  executorAddress: "0x...", // SignedCollateralSwapRouter address
  poolKey: {
    currency0: "0x111...",
    currency1: "0x222...",
    fee: 3000,
    tickSpacing: 60,
    hooks: "0x...",
  },
  amountIn: 1n,
  amountOutMin: 1n,
  sqrtPriceLimitX96: 0n, // executor applies the direction-based unbounded native v4 default
  zeroForOne: true,
  hookData: "0x1234", // signed quote bytes or explicit controller hook data
  receiver: "0xRecipient",
  deadline: BigInt(Math.floor(Date.now() / 1000) + 180),
};

const call = buildExactInputSignedQuoteCallDescriptor(swapInput);

// pass `call` to your write path.

// Signed-quote mode
const quote: SignedSwapQuoteBase = {
  poolId: "0x2222222222222222222222222222222222222222222222222222222222222222",
  trader: "0x3333333333333333333333333333333333333333",
  maxAbsAmount: 1_000000n,
  quotedPriceE18: 1_000_000000000000000000n,
  // unix timestamp in seconds
  expiry: 1_700_000_000n,
};
const signedSwapQuote = await signSignedSwapQuote(
  clients.walletClient,
  "0xCollateralManager",
  11155111,
  quote,
  "0x3333333333333333333333333333333333333333",
);
const signedCall = buildExactInputSignedQuoteCallDescriptor({
  ...swapInput,
  signedSwapQuote,
});

// pass `signedCall` when a signed quote is required.

Registered issuer AtomicBroker hook data

For the registered-issuer path, build compact hook data from the signed quote plus the AtomicBroker permit payload. The SDK does not fetch or bless API responses; callers should pass the settlement-ready subset returned by their issuer service.

Registered-issuer broker payloads are exact issuer-leg intents. The signed swap quote can bound the overall swap with maxAbsAmount, but the broker payload must authorize the exact issuer leg that should be settled through the issuer. If the pool, broker, or manager risk state makes that exact issuer leg unavailable at execution time, the hook can route zero through the issuer and leave execution to the pool path; it will not resize a 10-unit broker permit into a 4-unit issuer fill.

import {
  REGISTERED_ISSUER_ACTION,
  encodeRegisteredIssuerBrokerPayload,
  encodeRegisteredIssuerHookData,
} from "@steerprotocol/collateral-rail-sdk";

const brokerPayload = encodeRegisteredIssuerBrokerPayload({
  issuerId,
  action: REGISTERED_ISSUER_ACTION.Mint,
  collateralPrice,
  usdmPrice,
  depositPermit,
});

const hookData = encodeRegisteredIssuerHookData({
  issuerId,
  quote: signedSwapQuote,
  brokerPayload,
});

const call = buildExactInputSignedQuoteCallDescriptor({
  ...swapInput,
  hookData,
});

Use getRegisteredIssuerConfig, setRegisteredIssuerConfig, and getRegisteredIssuerBrokerCapacity for controller/adapter reads and admin setup.

Liquidation helpers

Liquidation account discovery is intentionally caller-owned. Bots and sidecars should choose their own candidate source, block window, indexing strategy, and retry policy. Once a candidate account is known, the SDK provides the controller reads and hook-data construction needed to build an exact liquidation swap.

import {
  buildExactInputLiquidationCallDescriptor,
  buildLiquidationHookDataFromPreview,
  getMaxLiquidatable,
  previewLiquidation,
  simulateExactInputLiquidationSwap,
} from "@steerprotocol/collateral-rail-sdk";

const maxRepay = await getMaxLiquidatable(
  publicClient,
  liquidationController,
  collateralManager,
  account,
);
if (maxRepay === 0n) {
  return;
}

const preview = await previewLiquidation(
  publicClient,
  liquidationController,
  collateralManager,
  account,
  maxRepay,
);

const deadline = BigInt(Math.floor(Date.now() / 1000) + 180);
const hookData = buildLiquidationHookDataFromPreview({
  manager: collateralManager,
  account,
  repayAmount: maxRepay,
  preview,
  deadline,
});

const route = {
  executorAddress: "0xSignedCollateralSwapRouter",
  amountIn: maxRepay,
  amountOutMin: preview.collateralOut,
  zeroForOne: true,
  receiver: liquidator,
  deadline,
  poolKey,
  hookData,
};

await simulateExactInputLiquidationSwap(publicClient, route);
const call = buildExactInputLiquidationCallDescriptor(route);

The encoded hook data binds the manager, account, repay amount, expected collateral out, minimum collateral out, and deadline. If the account state changes between preview and execution, the controller/hook path is designed to fail closed rather than silently resize the liquidation leg.

Node.js Example

import {
  createProtocolPublicClient,
  createProtocolWalletClient,
  getCollateralManagerMaxMintable,
  previewCollateralManagerSwap,
} from "@steerprotocol/collateral-rail-sdk";
import { optimismSepolia } from "viem/chains";

const rpc = "https://sepolia.optimism.io";
const publicClient = createProtocolPublicClient({
  chain: optimismSepolia,
  rpcUrl: rpc,
});
const walletClient = createProtocolWalletClient({
  chain: optimismSepolia,
  rpcUrl: rpc,
});

const maxMintable = await getCollateralManagerMaxMintable(
  publicClient,
  "0xCollateralManager",
  "0xUser"
);

const preview = await previewCollateralManagerSwap(
  publicClient,
  "0xCollateralManager",
  "0xUser",
  {
    currency0: "0x111...",
    currency1: "0x222...",
    fee: 3000,
    tickSpacing: 60,
    hooks: "0x...",
  },
  {
    amountSpecified: -1_000000n,
    sqrtPriceLimitX96: 0n,
    amountOutMinimum: 0n,
    zeroForOne: true,
  }
);

Scripts

  • npm run build – builds dist/ ESM and CJS outputs
  • npm run generate – regenerates typed action constants from local ABIs via @wagmi/cli
  • npm test – runs unit tests
  • npm run typecheck – runs TypeScript checking

Typed action generation

To refresh the generated action layer:

npm run generate

The generated output is exposed as:

import { generated } from "@steerprotocol/collateral-rail-sdk";

Notes

  • The SDK intentionally keeps transports injectable so the same action helpers work in both backend and frontend runtimes.
  • setMinter and other owner-only actions require your wallet to be authorized by the destination contract.
  • settleCollateralManagerSwap is for hook-authorized callback contexts (tests/simulations/operator tooling), not standard app swap execution.

Notes on migration timeline

  • Existing viem helpers remain the stable path and default for now.
  • Generated wagmi actions are available for typed access where useful.
  • A full migration to a wagmi-centric runtime would be an explicit separate release.

For production signed quote swaps, prefer the SignedCollateralSwapRouter builders. They expose sqrtPriceLimitX96 directly; 0n leaves the executor on the direction-based unbounded default, while amount min/max fields remain the final economic slippage checks.