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

@somnia-chain/contracts-sdk

v0.3.0

Published

Somnia contract addresses, ABIs and chain information, typed. Generated from the Somnia contract registry.

Downloads

438

Readme

@somnia-chain/contracts-sdk

Somnia contract addresses, ABIs and chain information, typed. Generated from the Somnia contract registry — the same records every Somnia deploy is reconciled against.

npm install @somnia-chain/contracts-sdk

The package is split by delivery mechanism, deliberately. Addresses and chain information are small and change on every deploy — they live in the root entry, ~170 kB of data. ABIs are megabytes that change only when contracts change — they ship one module per contract, so a client bundle carries exactly the ABIs it imports and a bundle that needs only addresses carries none.

Addresses and networks — the root entry

import { address, tryAddress, contracts, identify } from "@somnia-chain/contracts-sdk";

address("somnia-mainnet", "somnia-markets", "MarketsCore");
// throws on unknown names — the "this must exist" form; every slug and
// name is autocompleted and the address is a literal type

tryAddress("hideki-testnet", "somnia-markets", "MarketsCore"); // Address | null
// the "is it deployed here?" form — projects do not span every network

contracts("somnia-mainnet", "somnia-markets"); // enumerate, for admin screens
identify("somnia-mainnet", "0x1a47…");         // reverse lookup: project, name, kind

allContracts();
// every current deployment across every live network — the dashboard form.
// Retired networks and superseded deployments are excluded by default, so a
// wiped testnet's addresses cannot be rendered as current by forgetting to
// filter: { includeRetiredNetworks, includeSuperseded, project } to widen it.

Entries carry address, kind, status, version, and contract — the Solidity contract name, where a source stated one. kind and status are unions (DeploymentKind, ContractStatus), not string.

Networks: networks (all, retired included), network(slug), liveNetworks(), and toChain(slug, { rpcUrl }) for a viem-Chain-shaped object — you supply the RPC URL, the registry deliberately records no public endpoint. registryVersion says which commit the data came from.

Chain IDs are not unique

Networks are keyed by slug, never by chain id: a testnet regenesis reuses the chain id with none of the state, so one id can name two networks with different contracts at identical addresses.

networksByChainId(50383); // -> both hideki testnets — an array, deliberately

ABIs — typed per contract, or the whole corpus

// Build-time, typed, tree-shakeable: one module per contract.
import { SafeAbi } from "@somnia-chain/contracts-sdk/abi/somnia-accounts/Safe";
// as-const literal — viem infers function names and argument types

// Runtime, whole corpus (~1 MB — server/admin paths):
import { abiFor, abiByHash, verifyAbi, writeFunctions } from "@somnia-chain/contracts-sdk/abis";

abiFor("somnia-mainnet", "somnia-markets", "MarketsCore"); // Abi | null
abiByHash("sha256:…");        // historical ABIs too — decode an old tx correctly
verifyAbi("sha256:…", abi);   // sha256 over key-sorted compact JSON — verify, don't trust filenames
writeFunctions("somnia-mainnet", "somnia-markets", "MarketsCore");
// all state-changing functions — allowlists are application policy, not deployment facts

allContractsWithAbi();
// allContracts() with each ABI resolved to `abiJson` — addresses, networks and
// ABIs in one call. Costs the whole corpus, which is why it lives here.

Not every deployment has an ABI

abiFor returns null, and abiJson is null, for a real share of what the registry holds — around half, concentrated in the testnets. That is a fact about the records, not a gap in the package: the registry records a contract name only where a broadcast log stated it or the repo declared one, and an ABI is looked up by that name. Deployments created from a shared script as per-asset instances — BTC_reader, ADA_oracle — name a role rather than a contract, so they carry an address and no ABI. contract is set on exactly the entries that have one, so it is the field to branch on.

Decoding calldata

Requires viem (optional peer dependency; only this entry needs it).

import { decodeCall, decodeBySelector } from "@somnia-chain/contracts-sdk/decode";

const call = decodeCall("somnia-mainnet", to, data);
// identifies the target, decodes against its recorded ABI, and recurses
// through Safe execTransaction / MultiSend, Multicall3 and upgradeToAndCall —
// what a signer staring at hex actually needs

if (call.status === "decoded") call.signature;   // "transfer(address,uint256)"
else call.selector;                              // undecoded is a variant, not an error

decodeBySelector(data); // 4-byte fallback across every ABI the registry holds

Versioning

The package is a snapshot of the registry, and it is published when that snapshot changes rather than when someone remembers to publish it. The reconciliation lane compares the surface it would generate against the one the last release shipped, and cuts a patch version whenever addresses, ABIs or chain information moved — so a contract deployed today reaches npm on the next lane run. Minor and major versions are cut by hand, for API changes.

Update the dependency to pick up newly deployed contracts — nothing is fetched at runtime.