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

katch-mission-sdk

v0.0.2

Published

TypeScript SDK and CLI for Katch external mission creation.

Readme

Katch Mission SDK

TypeScript SDK and CLI for creating review-first Katch mission drafts from coding agents.

The SDK wraps the external mission API. It does not write D1 directly, does not invent calldata, and does not publish missions. The backend preview response remains the source of truth for valid Katch mission shape.

Install

Install the public package:

npm install -g katch-mission-sdk

The global install exposes two commands:

  • katch: create, launch, inspect, and debug missions
  • katch-signer: local signer helper for agent workflows

Do not install the katch package from npm. It is unrelated to the Katch mission platform.

Create a Mission Draft

import { KatchMissionClient } from "katch-mission-sdk";
import { privateKeyToAccount } from "viem/accounts";

const account = privateKeyToAccount(process.env.DEPLOYER_PRIVATE_KEY as `0x${string}`);
const client = new KatchMissionClient({ signer: account });

const input = {
  missionType: "place_video",
  title: "Film a cappuccino at Ritual Coffee",
  description: "Capture a short video showing the cafe counter, drink, and shop atmosphere.",
  mediaType: "video",
  reward: { token: "USDC", amount: 10 },
  targetCount: 1,
  verification: {
    accept: [
      "Video is recorded inside or directly outside Ritual Coffee Roasters",
      "Video clearly shows a coffee drink and recognizable cafe context",
      "Submission appears recent and original"
    ],
    reject: [
      "Stock footage, screenshots, or reused social posts",
      "No visible coffee shop context",
      "Private customer information is readable"
    ]
  },
  location: {
    placeLabel: "Ritual Coffee Roasters, San Francisco",
    visibility: {
      center: { lat: 37.7765, lng: -122.4241 },
      radiusMeters: 15000
    },
    submission: {
      center: { lat: 37.7765, lng: -122.4241 },
      radiusMeters: 120
    }
  }
} as const;

const preview = await client.previewMission(input);
console.log(preview.normalizedMission);

const draft = await client.createDraft(input, {
  idempotencyKey: "ritual-coffee-2026-05-20"
});
console.log(draft.nextAction, draft.fundingQuote);

Delegated Smart Account Creators

For smart-account funders such as a Splits Treasury, keep the creator wallet as the smart account and sign requests with an authorized EOA delegate:

const client = new KatchMissionClient({
  signer: agentEoa,
  walletAddress: "0xSplitsTreasury..."
});

Delegated requests send:

  • X-Katch-Wallet: creator/funder wallet, for example the Splits Treasury
  • X-Katch-Signer: EOA delegate that signs the request
  • X-Katch-Signature: signature over the request plus both wallet addresses

Katch accepts delegated requests only when the signer is active in external_mission_wallet_delegates. This keeps the on-chain authorized funding caller aligned with the stored creator wallet while allowing agents to sign API requests headlessly.

CLI

The package also exposes a JSON-first katch CLI for coding agents and scripts.

Build the package, then run the local bin:

npm run build --workspace katch-mission-sdk
KATCH_SIGNER_ADDRESS=0x... \
KATCH_WALLET_ADDRESS=0xSplitsTreasury... \
KATCH_SIGNER_COMMAND=/path/to/signer \
npx katch mission preview ./mission.json

KATCH_WALLET_ADDRESS is optional. Set it only when the request signer is an authorized delegate for a separate creator wallet.

Single-command launch

Prefer mission launch for third-party mission creation. It validates mission input locally, calls the Katch preview API, creates the draft with an idempotency key, and returns the exact funding transaction in one JSON response.

katch mission launch --mission ./mission.json

You can also launch from intent when OPENAI_API_KEY is configured:

katch mission launch \
  --intent "Take a 15 second video showing a clean coffee shop counter and menu" \
  --mission-type place_video \
  --place-label "Ritual Coffee Roasters, San Francisco" \
  --lat 37.7765 \
  --lng -122.4241 \
  --reward-token KATCH \
  --reward-amount 10

The launch response includes:

  • draft: Katch draft status and next action
  • fundingTransaction: exact Katch-authorized funding transaction request
  • funding: chain, factory, token, total budget, authorization expiry, warnings, and confirm command
  • next: action-oriented summary with the transaction to broadcast, expiry countdown, and follow-up command
  • nextCommand: the katch mission confirm <draftId> command to run after funding confirms

mission launch does not sign or send funding transactions. Manual funding is deliberate: EOAs, smart accounts, treasuries, and internal tools can all submit the same returned transaction.

The manual funding flow is: check balance, approve the token if allowance is too low, broadcast next.sendTransaction / funding.sendExactly, wait for mining, then run next.commandAfterFunding.

Guided Creation

Use the guided command when an agent or human wants a separate preview-only step. It validates the mission locally, calls the Katch preview API, generates a deterministic idempotency key when one is not provided, and stops before creating the draft unless --yes is passed.

Preview and validate only:

katch mission create --guided --mission ./mission.json

Create the draft after reviewing the preview:

katch mission create --guided --mission ./mission.json --yes

Generate from intent, preview, and stop:

katch mission create --guided \
  --intent "Take a 15 second video showing a clean coffee shop counter and menu" \
  --mission-type place_video \
  --place-label "Ritual Coffee Roasters, San Francisco" \
  --lat 37.7765 \
  --lng -122.4241 \
  --reward-token KATCH \
  --reward-amount 10

The --yes response includes:

  • draft: Katch draft status and next action
  • fundingTransaction: exact Katch-authorized funding transaction request
  • nextSteps: commands or human actions to continue

The guided command does not sign or send funding transactions. For smart accounts such as a Splits Treasury, create a proposal from fundingTransaction and submit it from the same wallet shown by KATCH_WALLET_ADDRESS.

For Splits Treasury dogfooding, examples/splits-signer.mjs can use the local EOA created by splits auth create-key --register:

node packages/katch-sdk/examples/splits-signer.mjs --address

export KATCH_WALLET_ADDRESS=0xYourSplitsTreasury
export KATCH_SIGNER_ADDRESS=0xYourSplitsLocalEoa
export KATCH_SIGNER_COMMAND=packages/katch-sdk/examples/splits-signer.mjs

The helper reads ~/.splits/config.json, refuses to sign non-Katch messages, and returns { "signature": "0x..." } for the SDK CLI signer protocol. Keep ~/.splits/config.json at owner-only permissions because it contains the local EOA private key.

Commands:

katch mission launch --mission ./mission.json
katch mission launch --intent "Take a video of Celeste wine bar in SF" --mission-type place_video --lat 37.7970183 --lng -122.4348726
katch mission create --guided --mission ./mission.json
katch mission create --guided --mission ./mission.json --yes
katch mission generate --intent "Take a video of Celeste wine bar in SF" --mission-type place_video --lat 37.7970183 --lng -122.4348726
katch mission plan --intent "Take a photo of a reusable coffee cup"
katch mission create-from-intent --intent "Take a photo of a reusable coffee cup" --idempotency-key cup-001
katch mission preview ./mission.json
katch mission create-draft ./mission.json --idempotency-key celeste-001
katch mission status draft_123
katch mission doctor draft_123
katch webhook create --url https://agent.example/webhooks/katch --events mission.published,submission.accepted,deliverables.ready
katch webhook list
katch mission list --status pending_funding --limit 10
katch mission confirm draft_123

The CLI prints successful responses as JSON on stdout. Errors are JSON on stderr and exit nonzero.

Mission Doctor

Use doctor when an agent needs to decide what to do next for a draft or mission. It returns JSON with health, summary, blockers, actions, the current draft state, and a deliverables readiness check.

katch mission doctor draft_123

Useful health values:

  • blocked: creator, funder, or Katch operator action is required
  • waiting: legacy funded mission is waiting for Katch review
  • ready: mission is published and can receive submissions
  • rejected: mission cannot continue as-is

For faster status-only checks, skip the deliverables probe:

katch mission doctor draft_123 --skip-deliverables

Webhooks

Webhooks notify creator agents when mission state changes or accepted deliverables are available. Management requests use the same signed wallet headers as mission creation, so subscriptions are scoped to the creator wallet.

Create a webhook:

katch webhook create \
  --url https://agent.example/webhooks/katch \
  --events mission.published,submission.accepted,deliverables.ready

The create response includes signingSecret once. Store it securely. Katch does not return it from list/get/update responses. Newly created and rotated webhook signing secrets are encrypted at rest by Katch. Legacy subscriptions remain deliverable, but rotating a webhook secret re-encrypts it under the current key.

Test a receiver without creating a mission:

katch webhook test wh_123 --event mission.published

Inspect recent delivery attempts:

katch webhook deliveries wh_123 --limit 10

Diagnose a webhook receiver by sending a signed test event and inspecting the resulting delivery:

katch webhook doctor wh_123 --event mission.published

Use --skip-test to inspect configuration and recent deliveries without sending a new test event.

Rotate a leaked or stale signing secret:

katch webhook rotate-secret wh_123

The rotate response includes the new signingSecret once. Update the receiver before sending more test events.

Supported events:

  • mission.funded
  • mission.published
  • submission.accepted
  • deliverables.ready

Delivery headers:

  • X-Katch-Webhook-Id
  • X-Katch-Webhook-Event
  • X-Katch-Webhook-Timestamp
  • X-Katch-Webhook-Signature

Verify every delivery before processing it:

import { verifyWebhookSignature } from "katch-mission-sdk";

const rawBody = await request.text();
const ok = await verifyWebhookSignature({
  rawBody,
  timestamp: request.headers.get("X-Katch-Webhook-Timestamp") || "",
  signature: request.headers.get("X-Katch-Webhook-Signature") || "",
  secret: process.env.KATCH_WEBHOOK_SECRET!,
});

if (!ok) return new Response("invalid signature", { status: 401 });

const event = JSON.parse(rawBody);

Receivers should reject stale timestamps, process event.id idempotently, and return a 2xx response only after the event is safely recorded. Katch retries failed deliveries with backoff. See examples/webhook-receiver-worker.mjs for a minimal Cloudflare Worker receiver.

Avoid using a bare workers.dev Worker URL as the receiver when the sender is also a Cloudflare Worker. In dogfood, Worker-to-Worker delivery to workers.dev returned Cloudflare error 1042; use a custom domain, another hosting provider, or a local tunnel for testing.

Intent Generation

The SDK can generate a MissionDraftInput from plain English using OpenAI Structured Outputs. Generation is local to the SDK/CLI; Katch still treats the backend preview endpoint as the source of truth.

export OPENAI_API_KEY=sk-...

katch mission generate \
  --intent "Take a clear photo of a reusable coffee cup"

For GPS-gated place missions, provide coordinates. The generator does not geocode or invent lat/lng:

katch mission plan \
  --intent "Take a video of Céleste wine bar in San Francisco" \
  --mission-type place_video \
  --place-label "Céleste, 2165 Union St, San Francisco, CA" \
  --lat 37.7970183 \
  --lng -122.4348726

generate only prints mission JSON and does not require a signer. plan runs generation then preview, so it requires the normal signer config. create-from-intent runs generation, preview, and draft creation, and still requires --idempotency-key.

Defaults when omitted:

  • reward token: USDC
  • reward amount: 10
  • target count: 1
  • submission radius: 120
  • visibility radius: 15000

Supported override flags: --reward-token, --reward-amount, --target-count, --mission-type, --place-label, --lat, --lng, --submission-radius, --visibility-radius.

External Katch missions currently support KATCH and USDC rewards. The CLI rejects unsupported --reward-token values locally, and the API rejects drafts whose reward.token is not one of those supported tokens.

Key Safety

Prefer external signer mode for coding agents and third-party automation:

export KATCH_SIGNER_ADDRESS=0xYourCreatorWallet
export KATCH_SIGNER_COMMAND=katch-signer
export KATCH_SIGNER_PRIVATE_KEY_FILE=$HOME/.katch/creator.key
katch mission create-draft ./mission.json --idempotency-key celeste-001

KATCH_SIGNER_COMMAND is executed without a shell. It receives this JSON on stdin:

{"message":"Katch External Mission Request\n..."}

It must write this JSON to stdout:

{"signature":"0x..."}

This keeps private keys in a dedicated wallet, keychain, 1Password wrapper, Para wallet tool, or other controlled signer process instead of exposing them to the CLI or agent environment.

For local development only, the CLI can read KATCH_PRIVATE_KEY, falling back to DEPLOYER_PRIVATE_KEY. Do not pass private keys as command-line arguments, put them in mission JSON, commit them to files, or expose Katch owner/admin keys to mission-creator agents. Use a low-balance creator wallet for third-party mission creation and rotate it immediately if it is ever logged or shared.

Built-in Signer Wrapper

The package includes katch-signer, a minimal external signer wrapper for local development and controlled agent runs. It signs only Katch external mission request messages and refuses arbitrary messages.

Preferred local key-file setup:

mkdir -p "$HOME/.katch"
printf '%s\n' '0x...' > "$HOME/.katch/creator.key"
chmod 600 "$HOME/.katch/creator.key"

export KATCH_SIGNER_ADDRESS=0xYourCreatorWallet
export KATCH_SIGNER_COMMAND=katch-signer
export KATCH_SIGNER_PRIVATE_KEY_FILE="$HOME/.katch/creator.key"

macOS Keychain setup:

security add-generic-password \
  -s katch-creator \
  -a 0xYourCreatorWallet \
  -w '0x...'

export KATCH_SIGNER_ADDRESS=0xYourCreatorWallet
export KATCH_SIGNER_COMMAND=katch-signer
export KATCH_SIGNER_KEYCHAIN_SERVICE=katch-creator
export KATCH_SIGNER_KEYCHAIN_ACCOUNT=0xYourCreatorWallet

KATCH_SIGNER_PRIVATE_KEY is supported by katch-signer as a development fallback, but it is weaker than a protected key file or OS keychain because environment variables are easier for child processes and debugging tools to expose.

Funding

createDraft returns a fundingQuote with the exact createAuthorizedFundedMission(...) calldata. Send it from the same creator wallet, then confirm funding. For delegated smart-account creators, the creator wallet is walletAddress / KATCH_WALLET_ADDRESS, not the EOA signer.

Funding authorizations are short-lived. If the CLI reports funding.authorization.expired or warns that expiry is close, refetch or recreate the draft before submitting a wallet or treasury transaction.

import { createWalletClient, http } from "viem";
import { worldchain } from "viem/chains";
import { sendFundingTransaction } from "katch-mission-sdk";

if (!draft.fundingQuote) throw new Error("Missing funding quote");

const walletClient = createWalletClient({
  account,
  chain: worldchain,
  transport: http()
});

const txHash = await sendFundingTransaction(walletClient, draft.fundingQuote);
console.log(txHash);

const funded = await client.confirmFunding(draft.draftId);
console.log(funded.nextAction);

Retry Behavior

Always pass an Idempotency-Key to createDraft. If a request is retried with the same creator wallet and same mission shape, Katch returns the existing draft with status: "exists". Reusing the key with a different mission throws KatchMissionApiError with status = 409 and code = "idempotency_conflict".

Status

const current = await client.getDraft(draft.draftId);
const drafts = await client.listDrafts({ status: "pending_funding", limit: 10 });

Common nextAction values:

  • send_create_funded_mission_transaction
  • wait_for_funding_confirmation
  • wait_for_katch_review (legacy)
  • owner_lock_required (legacy)
  • published
  • rejected

Deliverables

After Katch publishes an external mission, the creator wallet can fetch accepted outputs as a structured manifest. Media links are short-lived proxy URLs; refresh the manifest when links expire.

katch mission deliverables draft_mabc1234_deadbeef --limit 50 --media-url-ttl-seconds 600
katch mission deliverables draft_mabc1234_deadbeef --markdown
import { renderDeliverablesMarkdown } from "katch-mission-sdk";

const deliverables = await client.getDeliverables(draft.draftId, {
  limit: 50,
  mediaUrlTtlSeconds: 600
});

for (const submission of deliverables.submissions) {
  console.log(submission.submissionId, submission.mediaUrl, submission.verification.reason);
}

const humanReport = renderDeliverablesMarkdown(deliverables);
console.log(humanReport);