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

@manifest-network/manifest-sdk

v0.22.0

Published

Aggregating SDK for building apps on Manifest + Fred (composes @manifest-network/* over manifestjs).

Readme

@manifest-network/manifest-sdk

The app-building SDK for Manifest Network + the Fred deployment platform. Build a full application — query the chain, deploy and manage containerized apps, claim custom domains, batch transactions, watch live status — by composing only this package and manifestjs. It aggregates @manifest-network/manifest-mcp-core, @manifest-network/manifest-mcp-fred, and @manifest-network/manifest-agent-core behind one typed surface.

npm install @manifest-network/manifest-sdk @manifest-network/manifestjs

Quickstart

Create a client, then call its methods. createFredClient returns a fully-wired client — chain reads/writes plus the Fred provider operations — with the ports threaded for you.

import {
  createConfig,
  createFredClient,
  MnemonicWalletProvider,
} from '@manifest-network/manifest-sdk';

const config = createConfig({
  chainId: 'manifest-1',
  rpcUrl: 'https://rpc.manifest.example/',
  gasPrice: '0.01umfx',
});

// A funded Manifest wallet. NEVER hard-code a real mnemonic — load it from your env/secret store.
const walletProvider = new MnemonicWalletProvider(config, process.env.MANIFEST_MNEMONIC!);

const client = await createFredClient({ config, walletProvider });

try {
  // Read — browse the provider catalog (no signing)
  const catalog = await client.browseCatalog();

  // Deploy — one bound call: create the lease, upload the manifest, wait until ready
  const { lease_uuid, provider_url } = await client.deployApp({
    image: 'nginxinc/nginx-unprivileged:alpine',
    port: 8080,
    size: 'docker-micro',
  });

  // Read it back
  const lease = await client.getLease(lease_uuid);
} finally {
  // Always dispose — clients with the same config share (and mutate) one underlying
  // connection; don't hold two against one config key at once (see the cookbook).
  client.dispose();
}

Prerequisites. Deploying broadcasts on-chain transactions and takes a paid lease, so the wallet above must be funded with gas (and billing credit — see the cookbook). For a read-only app, use createManifestReadClient(...), which needs no wallet.

For a stack, ports use "port/protocol" keys. host_port must be omitted (or 0) because Fred assigns it dynamically; ingress: true selects at most one TCP port for public routing. The same PortConfig type is exported from /deploy, /catalog, and /orchestration so each scoped input is self-contained:

import type { PortConfig } from '@manifest-network/manifest-sdk/deploy';

const publicHttp: PortConfig = { ingress: true };
await client.deployApp({
  size: 'docker-micro',
  services: {
    web: {
      image: 'nginxinc/nginx-unprivileged:alpine',
      ports: { '8080/tcp': publicHttp },
    },
  },
});

In the browser (the reference consumer, Barney, is a web app), supply a WalletProvider that wraps your wallet adapter instead of MnemonicWalletProvider:

// cosmos-kit / Keplr / Leap — wrap the offline signer in the WalletProvider port
const walletProvider: WalletProvider = {
  getAddress: async () => address,
  getSigner: async () => getOfflineSigner(),
  signArbitrary, // from useChain() — needed for provider (ADR-036) auth
};

The typed app face

The SDK is the single typed library face for building on Manifest. You reach for two complementary shapes, both fully typed:

  • The bound client (createFredClient / createManifestClient / createManifestReadClient) — the everyday surface. Methods like client.deployApp(...), client.getSKUs(...), client.executeTx(...) close over the ports for you.
  • Scoped free functions on subpaths (/reads, /catalog, /deploy, and /orchestration) — fn(ctx, input) building blocks for when you want to compose or tree-shake a single capability without the whole client.

The stringly, JSON-shaped cosmos_query / cosmos_tx tools you may have seen are the MCP-server face — they live in the separate @manifest-network/manifest-mcp-{chain,lease,fred} packages for LLM/agent hosts and are not part of this SDK. For a low-level on-chain escape hatch from the SDK, use executeTx (multi-message atomic tx, from /deploy) or drop down to CosmosClientManager (re-exported from the root); the typed cosmosQuery / cosmosTx primitives behind those tools are on …/chain as raw query/tx escape hatches.

For a read the SDK doesn't wrap, you don't need a second manifestjs client — the read client exposes manifestjs's own typed query tree at client.query (responses are decoded typed objects with numeric enums, not LCD strings; note it bypasses the rate limiter, so prefer a typed read where one exists). Use it for 1:1 passthroughs like client.query.liftedinit.billing.v1.creditAddress({ tenant }) or client.query.cosmos.bank.v1beta1.balance({ address, denom }). See the cookbook.

Parse at the edges

Domain values are branded types (Address, LeaseUuid, ProviderUuid, SkuUuid, Fqdn). Parse untrusted input at the boundary with the throwing parse* constructors; values the SDK already returns are branded, so you never re-cast them.

import { parseFqdn } from '@manifest-network/manifest-sdk';

// `userDomain` came from a form / CLI arg — validate it before it crosses the boundary
await client.setItemCustomDomain({
  leaseUuid: lease_uuid,                 // already a LeaseUuid (from deployApp) — no cast
  customDomain: parseFqdn(userDomain),   // throws INVALID_ARGUMENT on a bad FQDN
  serviceName: 'web',
});

Typed errors

Most failures throw ManifestMCPError (with a code from ManifestMCPErrorCode); the exception is provider HTTP failures, which throw a separate ProviderApiError that carries status, not a code. Both error shapes carry typed detail — prefer the exported guards over instanceof (unreliable across duplicate package copies):

  • isSkuAmbiguousError(err) narrows err.details to { reason: 'AMBIGUOUS_SKU_NAME', size, candidates } when a SKU name matched more than one active SKU — render a picker from candidates.
  • ProviderApiError.isProviderApiError(err) is a dual-package-safe brand guard for provider HTTP errors (exposes err.status).

The /orchestration deploy flow has a deliberate completed-recovery error contract. An accepted retry_set_domain returns the normal DeployResult; completed salvage_without_domain, cancel_lease, and close_lease choices end the original invocation with non-retryable OPERATION_CANCELLED, details.lease_uuid, and the selected details.recovery_outcome. Terminal choices also carry the authoritative details.stop_outcome and details.lease_state. details.transaction_hash is present exactly when stop_outcome is stopped or cancelled, and absent for already_inactive (including post-broadcast terminal reconciliation). Salvage leaves the live lease in place and billing, so do not automatically clean it up or redeploy.

See the cookbook for a worked example.

Node consumers: keep the SSRF guard on

Provider URLs come from on-chain SKU records, so provider HTTP on Node should run through an SSRF-guarded fetch — it blocks requests to internal hosts before they're sent. The base createFredClient does not guard at connect time by default (it can't — the barrel stays browser-safe), so on Node it emits a one-time warning.

Independently of that connect-time guard, provider-URL string validation is always on and works in the browser too: validateProviderUrl default-denies a provider apiUrl that is a literal private/internal/loopback/metadata IP (ENG-490). Use the exported isUrlSsrfSafe for URLs you validate yourself — notably a provider WebSocket URL (wss://…) in the browser, where the native WebSocket has no connect-time guard. (On Node, createFredClientNode now runs the live-status WebSocket through an SSRF-guarded ws transport as well — see createNodeEventTransport.) The string layer fails open on DNS hostnames (only the Node connect guard / the browser's Private Network Access can catch a hostname that resolves internally), so it is defense-in-depth, not a rebinding-proof guard. Use createFredClientNode from the /node subpath, which is SSRF-safe by default:

import { createFredClientNode } from '@manifest-network/manifest-sdk/node';

const client = await createFredClientNode({ config, walletProvider }); // provider HTTP is guarded

Explicitly injecting any fetch opts out of the automatic guard and its missing-guard warning. A plain globalThis.fetch remains unguarded, so pass it only as a deliberate opt-out; wrap createGuardedFetch() from /node if you need to compose behavior. (Browsers don't need this: same-origin/CORS limits reading a cross-origin response, so the request-level guard is a Node concern. The MANIFEST_FRED_FETCH_GUARDED env knob is MCP-server-only; the library escape hatch is opts.fetch.)

Subpath map

The root barrel carries the client factories, branded types (parse* / as*), the ports, the error vocabulary, and config; the free functions live on scoped, tree-shakable subpaths.

| Import | What's there | |--------|--------------| | @manifest-network/manifest-sdk | Client factories (createFredClient, createManifestClient, createManifestReadClient), brands + parse*/as*, ports (WalletProvider, Signer adapters), the error vocabulary (ManifestMCPError/ManifestMCPErrorCode + the typed guards ProviderApiError/isSkuAmbiguousError), createConfig, and the wholesale type surface (barrel createFredClient is unguarded on Node — prefer createFredClientNode from /node) | | …/reads | Branded read fns: getBalance, getLease, getLeasesByTenant, getSKUs, getProviders, getLeaseByCustomDomain, getBillingParams, getWithdrawableAmount | | …/catalog | browseCatalog, resolveSku, listSkuCandidates, checkDeploymentReadiness, buildManifestPreview, plus its preview input types and PortConfig | | …/deploy | deployApp, restartApp, updateApp, restoreApp / restoreLease (recover a CLOSED/retained lease onto a fresh one), getAppLogs, appStatus, waitForAppReady, waitForLeaseStatus, isLeaseFailureTerminal, executeTx, fundCredits, setItemCustomDomain, stopApp, LeaseState, validateProviderUrl + isUrlSsrfSafe (SSRF-classify a provider URL / WebSocket URL), manifest builders, ADR-036 auth helpers + the deploy-family types (BuildManifestOptions, PortConfig, DeployResult, ManifestDeploySpec, RestoreResult, FredLeaseItem, TxCallOptions) | | …/orchestration | Optional plan/confirm/recover flows: deployApp, manageDomain, closeLease, troubleshootDeployment (callback-driven), plus loadChainDenomMap and the complete ServiceConfig / PortConfig input types. The subpath is browser-bundleable; two opt-in operations require Node when called: deployApp(spec, callbacks, { dataDir }) for manifest persistence and loadChainDenomMap(path) for filesystem-backed chain data | | …/chain | Generic tier-2 chain escape hatches (from core, not the manifest-mcp-chain server): cosmosQuery, cosmosTx — the raw query/tx primitives behind the cosmos_query/cosmos_tx tools | | …/faucet | Testnet faucet ops (browser-safe): requestFaucet, requestFaucetCredit, fetchFaucetStatus (+ FaucetAccount/FaucetDripResult/FaucetStatusResponse/RequestFaucetResult). Testnet/operator concern — deliberately off the root barrel | | …/node | Node-only: createFredClientNode (SSRF-safe fred client), createNodeEventTransport (SSRF-guarded ws transport for the live-status WebSocket — see the note above), createGuardedFetch, isBlocked |

Full worked example

examples/sdk-acceptance is a runnable, compose-only flow — deploy (single + stack), query, custom domain, atomic batch, live-status poll, stop — built from only this SDK + manifestjs, exercised end-to-end against a live chain and bundled for the browser.

Going further

  • SDK cookbook — wallets, the three client factories, reads/txs, the deploy lifecycle, live status, error handling, and the low-level escape hatch.
  • CHANGELOG
  • Architecture

License

MIT