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

@satoshai/abi-cli

v1.0.0

Published

CLI to fetch Stacks contract ABIs and generate TypeScript definitions.

Readme

@satoshai/abi-cli

npm version CI License: MIT

CLI tool to fetch ABIs from deployed Stacks blockchain contracts and output TypeScript-ready definitions (as const).

Install

# Global install
npm install -g @satoshai/abi-cli

# Or run directly with npx
npx @satoshai/abi-cli fetch <contract>

Usage

Basic — fetch and write to file

By default, the CLI writes a TypeScript file named after the contract to the current directory:

abi-cli fetch SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-pool-v2-01
# → writes amm-pool-v2-01.ts

The generated file looks like:

import type { ClarityAbi } from '@stacks/transactions';

// ABI for SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-pool-v2-01
// Generated by @satoshai/abi-cli

export const abi = {
  "functions": [...],
  "variables": [...],
  ...
} as const satisfies ClarityAbi;

export type Abi = typeof abi;

Output to stdout

Use --stdout to print the output instead of writing a file:

abi-cli fetch SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-pool-v2-01 --stdout

Custom output path

abi-cli fetch SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-pool-v2-01 -o ./abis/amm-pool.ts

JSON format

# Write to file (amm-pool-v2-01.json)
abi-cli fetch SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-pool-v2-01 --format json

# Print to stdout
abi-cli fetch SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-pool-v2-01 --format json --stdout

Networks

Defaults to mainnet. Use -n / --network to switch:

# Testnet
abi-cli fetch ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.my-contract -n testnet

# Devnet (localhost:3999)
abi-cli fetch ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.my-contract -n devnet

# Custom Stacks API URL
abi-cli fetch SP...contract -n https://my-node.example.com

Multiple contracts

Comma-separate contract IDs to fetch several at once:

abi-cli fetch SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-pool-v2-01,SP2C2YFP12AJZB1KD5HQ4XFRYGEK02H70HVK8GQH.arkadiko-swap-v2-1
# → writes amm-pool-v2-01.ts and arkadiko-swap-v2-1.ts

Sync — config-driven multi-contract sync

For projects with multiple contracts, create a config file to keep ABIs in sync declaratively.

Create abi.config.json in your project root:

{
  "outDir": "./src/abis",
  "format": "ts",
  "network": "mainnet",
  "contracts": [
    { "id": "SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-pool-v2-01", "name": "amm-pool" },
    { "id": "SP2C2YFP12AJZB1KD5HQ4XFRYGEK02H70HVK8GQH.arkadiko-swap-v2-1", "name": "arkadiko-swap" },
    { "id": "ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.my-contract", "network": "testnet" }
  ]
}

The name field controls the output filename. This decouples your imports from the on-chain contract ID — when you upgrade to a new contract version, change the id but keep the name. Your imports stay the same.

Or use abi.config.ts for type-safe config with autocomplete:

import type { AbiConfig } from '@satoshai/abi-cli';

export default {
  outDir: './src/abis',
  format: 'ts',
  network: 'mainnet',
  contracts: [
    { id: 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-pool-v2-01', name: 'amm-pool' },
    { id: 'SP2C2YFP12AJZB1KD5HQ4XFRYGEK02H70HVK8GQH.arkadiko-swap-v2-1', name: 'arkadiko-swap' },
  ],
} satisfies AbiConfig;

Then run:

abi-cli sync
# → reads abi.config.json (or .ts), writes all ABIs to outDir

This generates:

src/abis/
├── amm-pool.ts
├── arkadiko-swap.ts
└── index.ts          # barrel file with re-exports

The barrel file re-exports all ABIs with camelCase names:

export { abi as ammPoolAbi } from './amm-pool.js';
export { abi as arkadikoSwapAbi } from './arkadiko-swap.js';

Use --config / -c to point to a custom config path:

abi-cli sync --config ./configs/my-abis.json

Config schema

| Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | outDir | string | yes | — | Output directory for generated files | | format | "ts" \| "json" | no | "ts" | Output format | | network | string | no | "mainnet" | Default network for all contracts | | contracts | ContractEntry[] | yes | — | List of contracts to sync | | contracts[].id | string | yes | — | Contract ID in address.name format | | contracts[].name | string | no | contract name from ID | Alias for output filename and barrel export | | contracts[].network | string | no | top-level network | Per-contract network override |

Check — CI staleness detection

Use --check to verify local files are in sync with on-chain ABIs without writing anything. Exits with code 1 if any files are stale or missing.

# Single contract
abi-cli fetch SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-pool-v2-01 --check

# All contracts from config
abi-cli sync --check

Add it to your CI pipeline to catch stale types:

- name: Check ABIs are up-to-date
  run: npx @satoshai/abi-cli sync --check

Flags Reference

abi-cli fetch

| Flag | Alias | Default | Description | |------|-------|---------|-------------| | --network | -n | mainnet | Network: mainnet, testnet, devnet, or a custom URL | | --output | -o | <contract-name>.<format> | Output file path (single contract only) | | --format | -f | ts | Output format: ts or json | | --stdout | | false | Print to stdout instead of writing a file | | --check | | false | Check if local files match on-chain ABI (exit 1 if stale) | | --help | | | Show help |

abi-cli sync

| Flag | Alias | Default | Description | |------|-------|---------|-------------| | --config | -c | auto-discover | Path to config file | | --check | | false | Check if local files match on-chain ABIs (exit 1 if stale) | | --help | | | Show help |

Programmatic API

import { fetchContractAbi, generateTypescript, generateJson, parseContractId } from '@satoshai/abi-cli';

// Fetch an ABI
const abi = await fetchContractAbi('mainnet', 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM', 'amm-pool-v2-01');

// Generate TypeScript (as const)
const tsCode = generateTypescript('SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-pool-v2-01', abi);

// Generate JSON
const json = generateJson(abi);

// Parse a contract ID string
const { address, name } = parseContractId('SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-pool-v2-01');

Config loading

import { loadConfig, validateConfig } from '@satoshai/abi-cli';
import type { AbiConfig, ContractEntry } from '@satoshai/abi-cli';

// Load and validate from file (auto-discovers abi.config.json/.ts)
const config = await loadConfig();

// Or from a specific path
const config2 = await loadConfig('./my-config.json');

// Validate a raw object
const validated = validateConfig({ outDir: './abis', contracts: [{ id: 'SP1.token' }] });

Types are re-exported from @stacks/transactions:

import type { ClarityAbi, ClarityAbiFunction, ClarityAbiType } from '@satoshai/abi-cli';

License

MIT