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

@artblocks/abx-sdk

v0.1.0-alpha.13

Published

ABX SDK (Layer 2) — the neutral, low-level library that turns protocol operations into typed function calls. No provider, no chain, no UX baked in.

Readme

@artblocks/abx-sdk

The neutral, low-level TypeScript library for the ABX protocol — deploy, reconstruct from chain, resolve a token, verify content. It picks no provider, no UX, and (beyond a default chain target) no chain. Every ABX surface is built on this: the abx CLI is a shell over it, the reference resolver reads through it, and a competing provider can import this same public library. If you're scripting one-off operations, the CLI is usually faster to reach for — install with abx skill install and let an agent drive it. Reach for the SDK when you're building something programmatic: a server, a mint endpoint, a scheduled job.

ESM-only, built on viem, requires Node 22.5+. The package's main entry is browser-safe — bundled and tested under platform: 'browser' on every change.

Install

npm install @artblocks/abx-sdk viem
import { makePublicClient, ensureFactory, deployOneOfOne } from '@artblocks/abx-sdk';
import { oneOfOneImageAbi } from '@artblocks/abx-sdk/abi';

The send-injection model

Every write returns a PreparedTx — unsigned, with a human-readable summary/fields for a sign page. The SDK never signs or broadcasts; it takes one function you provide:

type SendTx = (tx: PreparedTx) => Promise<TransactionReceipt>;

Every deploy*/ensure*/prepare*-and-execute function takes a SendTx as an argument, so how a transaction gets signed is entirely your call:

  • makeHotSender({ wallet, account, publicClient, onEvent? }) — for an env/hot key. Pins the nonce once (a distributed RPC can briefly serve a stale count right after a send, so it tracks the nonce locally rather than re-reading it), detects an eth_estimateGas that came back impossibly low (a sign the node hasn't seen a just-deployed target's code yet) and retries rather than sending an under-funded transaction, and throws a typed TxRevertedError — never reports a burned, reverted transaction as "confirmed."
  • Bring your own — a browser wallet, a Safe/multisig flow, a queue you drain later. Anything that signs a PreparedTx.data and returns a TransactionReceipt works.

Sequences: runPrepared(txs, send) sends a list in order. batchOps(ops) collapses same-target runs into one Multicallable.multicall transaction — several owner edits become one signature, all-or-nothing.

Worked example: deploy → upload → mint → read

import {
  makePublicClient, makeWalletClient, makeHotSender,
  ensureFactory, deployOneOfOne, saltFor, predictClone,
  prepareMint, runPrepared, listTokens, reconstructProject, readSaleConfig,
  encodeTag, type OneOfOneInitParams,
} from '@artblocks/abx-sdk';
import { resolveBackend, uploadAndLocate } from '@artblocks/abx-storage';
import { zeroAddress, toHex } from 'viem';

const publicClient = makePublicClient({ chainKey: 'base-sepolia' });
const { wallet, account } = makeWalletClient({ chainKey: 'base-sepolia' }); // reads ABX_DEPLOYER_PK
const send = makeHotSender({ wallet, account, publicClient });

// 1. Deploy — resolve (or bootstrap) the chain's trust anchor, then deploy a clone.
const factory = await ensureFactory(publicClient, send, { chainId: 84532 });
const salt = saltFor(account.address); // front-run-proof: reserves the address to this signer
const clone = await predictClone(publicClient, { factory, salt });

// 2. Upload — put the image somewhere fetchable before baking its URL on-chain.
const backend = resolveBackend({ backend: 'ipfs' }); // or 'cloud' / 'arweave' / 'fs'
const bytes = new Uint8Array(/* … read your file … */);
const { locator } = await uploadAndLocate(backend, 'art.png', { bytes, contentType: 'image/png' });

const params: OneOfOneInitParams = {
  owner: account.address,
  mintTo: zeroAddress, // defer minting to step 3
  name: 'My Piece', symbol: 'MYPC',
  tokenURIBase: '', tokenURIRenderer: zeroAddress,
  contractURIBase: '', contractURIRenderer: zeroAddress,
  royaltyReceiver: account.address, royaltyBps: 500,
  transferValidator: zeroAddress, // plain ERC-721; see ERC-721C in the site docs to opt in
  tokenFields: [
    // Bake the uploaded locator on-chain as the `image` field (an ipfs:// URI here; `arweave`/
    // `url`/`keccak256` are the other off-chain representations — see the site docs for the choice,
    // and `stageFieldContent` to put the bytes fully on-chain instead).
    { field: encodeTag('image'), representation: encodeTag('ipfs'), value: toHex(locator) },
  ],
  contractFields: [],
};
const { txHash } = await deployOneOfOne(send, publicClient, { factory, params, salt });

// 3. Mint — deploy deferred it (mintTo was the zero address), so mint explicitly.
await runPrepared([prepareMint({ contract: clone, to: account.address, chainId: 84532 })], send);

// 4. Read — straight from chain, no indexer required.
const listing = await listTokens(publicClient, clone);              // owners, seeds, params
const state = await reconstructProject(publicClient, {              // full protocol state
  address: clone, fromBlock: (await publicClient.getBlockNumber()) - 100n,
});

encodeTag/decodeTag (from the same package) turn a field name like "image" into the bytes32 tag the contract expects — spelled out above only so the snippet is self-contained. Selling through the shared fixed-price minter is prepareConfigureSale + preparePurchase + readSaleConfig(publicClient, minter, clone) — see the SDK reference for the full surface (Series, code/generative projects, on-chain content staging, ERC-721C, and more).

Browser use

The package's main entry (.) has no Node-only imports — it's bundled under platform: 'browser' and asserted clean of node:* resolution on every change. In a browser:

  • Pass rpcUrls: [...] explicitly to makePublicClient/makeWalletClient — there's no process.env to fall back to, and the SDK never assumes one.
  • Sign with a connected wallet (build the SendTx yourself around it) rather than makeHotSender, which expects a local WalletClient backed by a key.
  • Never import @artblocks/abx-sdk/node — that subpath is the only place .env loading lives (loadDotEnv, needs node:fs/node:path) and it will break a browser bundle. A host (a CLI, a server) calls loadDotEnv() once at startup; the SDK core just reads whatever's already in process.env via a tiny readEnv that's a no-op outside Node.

The only signing-key env var the SDK ever reads is ABX_DEPLOYER_PK (via makeWalletClient/ envSigningKey) — and only as a fallback when you don't pass privateKey/rpcUrls explicitly.

More

Full API by task (deploy, sell, operate, read, embed in a browser, talk to a resolver) is in the SDK reference on the docs site. Protocol specs live in specs/ in the repo.