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

@0xsoulful/sdk

v0.1.8

Published

Typed client SDK for Soul contracts, generated from Foundry artifacts using viem + wagmi.

Readme

@0xsoulful/sdk

Typed client SDK for Soul contracts, generated from Foundry artifacts using viem + wagmi.

Install

npm i @0xsoulful/sdk viem

Quickstart (env-aware SDK)

import { createWalletClient, createPublicClient, http } from "viem";
import { createSdk } from "@0xsoulful/sdk";

const RPC_URL = process.env.RPC_URL!;
const publicClient = createPublicClient({ transport: http(RPC_URL) });
const walletClient = createWalletClient({ transport: http(RPC_URL), account: /* your account */ });

// SOUL_ENV selects addresses from packages/sdk/src/addresses.ts for chain
// export SOUL_ENV=dev | main  (defaults to main)
const sdk = createSdk({ client: publicClient });

// Use OfferManager module
const offer = sdk.offer();
await offer.depositLyx(walletClient, 1n * 10n ** 18n);

SoulToken usage

High-level helpers for the SOUL host and its auction/burn extensions.

import { createWalletClient, createPublicClient, http } from "viem";
import { createSdk } from "@0xsoulful/sdk";

const client = createPublicClient({ transport: http(process.env.RPC_URL!) });
const wallet = createWalletClient({ transport: http(process.env.RPC_URL!), account: /* your account */ });

const sdk = createSdk({ client });
const soul = sdk.soul();

// Read current auction type ("native" | "stable" | "none")
const kind = await soul.getAuctionType();

if (kind === "native") {
  // Quote current price in wei and extension address
  const { priceWei, extension, round } = await soul.quotePurchaseWithLyx();

  // Purchase with native LYX at the current price (optional slippage guard)
  await soul.purchaseWithLyx({ walletClient: wallet, maxPriceWei: priceWei });
}

// Request burn of N SOUL via burn extension wired on host
await soul.requestBurn({ walletClient: wallet, amount: 1n });

// Native auction helpers
const { priceWei } = await soul.quotePurchaseWithLyx();
// Watch for USD crossing and trigger callback slightly before
const unwatchUsd = await soul.watchUsdCrossing({
  targetUsd1e18: 30n * 10n ** 18n,
  preflightSeconds: 5,
  onTrigger: async ({ currentUsd, currentWei }) => {
    // e.g., place buy or alert
  },
});

// Stop watching
unwatchUsd();

Notes:

  • Address selection is environment-aware. Set SOUL_ENV=dev to use dev deployments on chain 42.
  • You can override addresses or merge extension ABIs when creating the SDK if needed.

Development

  • Build contracts: npm run contracts:build
  • Generate SDK: npm run sdk:prepare
  • Only codegen (viem): npm run sdk:codegen

Versioning & Releases

This repo uses Changesets. To release:

  1. Create a changeset: npx changeset
  2. Commit and merge to main.
  3. Run npm run release to version and publish @0xsoulful/sdk.

Address management

Addresses are auto-extracted from Foundry broadcast/**/run-latest.json into src/addresses.ts.

Environments on the same chain (main vs dev)

  • The SDK supports two environments on the same chain id (e.g., LUKSO mainnet 42): main and dev.
  • Environment is inferred from the Foundry script folder name:
    • If the broadcast path contains a script directory with Dev in its name (case-insensitive), those deployments go under dev.
    • Otherwise, deployments go under main.

You can select the environment in-app by setting process.env.SOUL_ENV = "dev" | "main" (or globalThis.SOUL_ENV in the browser), or by passing the env parameter to helpers like getAddress.

The generated shape is:

export const deployments: {
  [chainId: number]: {
    main: Record<string, string>;
    dev: Record<string, string>;
  };
}

For legacy flat outputs, the SDK will mirror the single map to both main and dev for backward compatibility.

Offer SDK (OfferManager + Extensions)

High-level API for creating and executing SOUL auction offers through the LSP17-extendable OfferManager host. Works for both user-side (signing + deposits) and keeper-side (execution).

Quickstart

import { createPublicClient, createWalletClient, http } from "viem";
import { createSdk } from "@0xsoulful/sdk";

const publicClient = createPublicClient({ transport: http(process.env.RPC_URL!) });
const walletClient = createWalletClient({ transport: http(process.env.RPC_URL!), account: /* your account */ });

const sdk = createSdk({ client: publicClient });

// 1) User deposits LYX
await sdk.offer().depositLyx(walletClient, 5n * 10n ** 18n);

// 2) User signs a Limit offer
const signedLimit = await sdk.offer().signLimitOffer(walletClient, {
  maker: /* user */, recipient: /* 0x0 => defaults to maker */, maxPriceWei: 3_400_000_000_000_000_000n,
  validAfter: 0n, validBefore: 0n, salt: BigInt(Date.now())
});

// 3) Keeper executes when eligible
await sdk.offer().executeLimit(walletClient, signedLimit);

API

  • Balances
    • depositLyx(wallet, amountWei)
    • withdrawLyx(wallet, amountWei)
    • getBalance(user)
  • Signing
    • signLimitOffer(wallet, offer){ offer, signature }
    • signDcaOffer(wallet, offer){ offer, signature }
  • Execution (keeper or user)
    • executeLimit(walletOrKeeper, signedOffer)
    • executeDca(walletOrKeeper, signedOffer)
  • Introspection
    • getExtensionForSelector(selector)

Offchain storage

Store the object returned by signLimitOffer / signDcaOffer along with metadata:

{
  "kind": "limit",                    
  "offer": { /* typed offer */ },     
  "signature": "0x...",              
  "maker": "0x...",                  
  "salt": "...",                     
  "createdAt": 1710000000000
}

The keeper fetches these, pre-filters by validity window, user balance, price cap (and DCA cadence via progress), then calls executeLimit / executeDca. See documents/technical/Keeper-Execution-Guide.md.