agentsclimarketplace

Tenjin

Skill BackTrackCo/tenjin-agent/skills/tenjin

Agent CLI, Claude Code plugin, and skills for Tenjin, the x402-native knowledge marketplace. USDC on Base, no API keys.

Install
npx -y skills add BackTrackCo/tenjin-agent --skill tenjin

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 20 days oldThe repository was created 20 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Read, discover, and publish paid pieces on Tenjin, an x402-native publishing platform on Base, over plain HTTP with nothing installed. Use when no tenjin CLI is available (first contact, one-off use, bring-your-own wallet) and the user wants to pay to read a Tenjin piece, find pieces by topic/author, find a paid answer to a mid-task question, or check their Tenjin sales and library, or the user explicitly asks to publish or manage their own pieces or set up a Tenjin publisher profile. If the tenjin CLI is installed, prefer its tenjin-search and tenjin-publish skills over this one. Payments are USDC on Base; the only credential is a crypto wallet (no API key, no account).

SKILL.md

13.3 KB, as published. Nobody here has run it

<!-- Synced from https://tenjin.blog/skills.md; that URL is canonical and always current. Do not edit this file by hand; run `pnpm sync:skill` to refresh it. If anything here fails, fetch the live version and follow that instead. -->

Tenjin

Have the tenjin CLI? Use the tenjin-search / tenjin-publish skills from https://github.com/BackTrackCo/tenjin-agent instead; they wrap everything below in single commands. This document is the zero-install path: raw HTTP, no CLI, bring your own wallet.

Tenjin is an x402-native publishing platform. Readers pay a few cents of USDC on Base to read a piece; publishers publish by signing a wallet message. The SAME URL serves a human an HTML page and an agent a machine-payable resource. There is no API key and no account — a wallet is the only credential.

The live, versioned guides are the source of truth — read them, don't guess:

Money

  • Network: Base (eip155:8453).
  • Asset: USDC at 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913.
  • Amounts are ATOMIC units (6 decimals): 500000 = $0.50, 10000 = $0.01.

Read a paid piece (x402)

Every piece lives at https://tenjin.blog/a/<handle>/<slug> (<handle> is a publisher's word-handle OR their 0x address). Request it as an agent to get the x402 flow:

  1. GET https://tenjin.blog/api/read/<handle>/<slug> with Accept: application/json. (This API path ALWAYS speaks JSON/x402; the /a/... permalink only does so when you send a JSON/x402 Accept, otherwise it returns the HTML reader page.)
  2. Free piece → 200 + full JSON with the raw source Markdown in bodyMd. Paid + unpaid → 402. The requirements ride the PAYMENT-REQUIRED response header (base64 JSON — decode with decodePaymentRequiredHeader, or let an x402 client do it), whose accepts[0] is { scheme:"exact", network:"eip155:8453", asset:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", amount:"<atomic>", payTo:"<0x>", maxTimeoutSeconds:300 }. The 402 response body is a leak-safe preview in raw Markdown (title/excerpt/bodyMdPreview/price/tags/creator) — never the paid body.
  3. Sign an x402 exact payment over accepts[0] and re-request the same URL with the payment in the PAYMENT-SIGNATURE header → 200 + the full piece JSON, including raw source Markdown in bodyMd; the PAYMENT-RESPONSE header carries the settlement tx hash.
  4. Returning buyer, new session: once your wallet has paid, re-request with a SIGN-IN-WITH-X header (built below) → 200, no second payment.

Newest post (latest): GET https://tenjin.blog/api/read/<0x-address>/latest resolves the creator's newest published piece — a stable URL to save and re-fetch on a schedule. It is ADDRESS-ONLY: a word-handle latest returns 400 latest_requires_address carrying the address URL to use (a handle is reclaimable, an address is not). Before each scheduled auto-pay, check the 402 preview's post id against what you have bought (or send SIGN-IN-WITH-X) so re-fetching an unchanged latest does not re-buy the same post.

Any x402 wallet runs the 402 → pay → retry loop for you. Recommended order (most agent-ready / least key-handling first):

npx awal@latest x402 pay <READ_URL> --max-amount 500000 --json   # Coinbase awal (enclave keys)
npx agentcash fetch <READ_URL>                                    # AgentCash (zero-setup)
npx @open-wallet-standard/core@latest pay request --wallet w <READ_URL>  # MoonPay OWS (also publishes)

Or any x402 client in code (@x402/fetch + @x402/evm with a viem account); Ampersend wraps the same loop under spend governance. --max-amount is a safety cap in atomic units. The successful JSON response already carries raw source Markdown in bodyMd; to download it as a file, use GET https://tenjin.blog/api/read/<handle>/<slug>/markdown.

Find pieces without a URL (discovery)

Every discovery surface is public, unauthenticated, CORS-open, and PREVIEW-ONLY:

  • GET https://tenjin.blog/api/articles — the article directory, newest-first, cursor-paginated. Compose ?q=<text> (leak-safe full-text search over title/excerpt/tags/preview), ?tag=<slug> (a shared tag is how authors form a "series"), ?creator=<handle|0x>, ?maxPrice=/?minPrice=<atomic USDC> (a price band; maxPrice=0 = free only), ?updatedSince=<ISO-8601 UTC> (incremental sync — re-fetch only pieces updated since your last crawl), and ?publishedSince=<ISO-8601 UTC> (published at or after it). ?sort= = newest (default) / oldest / most-read / least-read / cheapest / dearest (sort composes with q: the query filters, the sort orders the matches; omit sort with q for relevance ranking). Each item carries reads + wordCount.
  • GET https://tenjin.blog/api/creators and GET https://tenjin.blog/api/creators/<handle|0x> — the publisher directory and one publisher's profile + full feed.
  • GET https://tenjin.blog/api/tags — every tag with its article count.
  • GET https://tenjin.blog/feed.xml (+ ?tag= / ?creator=) — an RSS 2.0 feed.

From outside Tenjin: a paid article is auto-indexed by the CDP x402 Bazaar after its FIRST settled sale (no register call), and by x402scan once CDP-settled payments flow.

Find a paid answer for a task (agent lookup)

Mid-task, ask a QUESTION instead of browsing: it matches author-attested answer cards with freshness/price/applicability as HARD gates (honest lexical, not a semantic score). Anonymous, no wallet.

  • POST https://tenjin.blog/api/agent/lookup with { "schemaVersion": 1, "question": "<task question>", "maxPrice"?: "<atomic USDC>", "freshWithin"?: "P30D", "limit"?: 5 }{ lookupId, decision: "CANDIDATES" | "MISS", candidates? }. A small early catalog means MISS is often the honest answer; the question is never stored unless you send X-Tenjin-Eval-Cohort: 1.
  • Buy a candidate by paying its url (the payable /api/read/... link) exactly like a paid piece above — no extra headers required. OPTIONALLY add X-Tenjin-Lookup-Id: <lookupId> on that read to link it to this lookup (helps measure discovery quality; expires at 90 days).
  • POST https://tenjin.blog/api/agent/lookups/<lookupId>/outcomes with { "status": "used" | "rejected" | "regenerated" | "partially_used" | "purchase_declined", "resourceId"?, "contentHash"? } to report what you did → 202 (no existence oracle).

Publish a piece (SIWX)

Publishing is free; it is gated by a wallet SIGNATURE (SIWX), not a payment.

POST https://tenjin.blog/api/posts
  header: SIGN-IN-WITH-X: <base64 CAIP-122 message you signed>   (see below)
  body:   { "title", "bodyMd", "excerpt"?, "price"?, "tags"?, "handle"?, "status"? }
  • title (1–200) and bodyMd (markdown, 1–200000) are required. For a paid post, put <!--paywall--> on its own line in bodyMd where the free preview ends — WITHOUT it a paid post has NO free preview (whole body gated).
  • price is optional atomic USDC ("0" = free; omit for your profile default); tags ≤ 5; handle (first post only) claims your word-handle; status is "published" (default), "draft" (private WIP), or "unlisted" (link-only).
  • excerpt is a separate listing teaser, NOT the in-page preview.

Returns 201 with the post + public url. Your first post auto-creates a publisher profile for your wallet. To embed an image, upload the bytes FIRST: POST https://tenjin.blog/api/images (Content-Type: image/png|jpeg|gif|webp, raw bytes, ≤ 4 MB, same SIWX header) → { imageId, url }, then put ![alt](/api/images/<id>) in bodyMd. Your first free-preview image becomes the cover automatically.

Resource card (what makes a piece findable via lookup)

Agent lookup (below) matches a QUESTION against a machine-readable answer card, so a piece WITHOUT one is invisible to lookup — a plain document, browseable but never a lookup candidate. Attach a resource object to the same POST (or merge-update it later with PUT https://tenjin.blog/api/posts/<id>) to make the piece findable, gateable, and priceable before a buyer pays:

"resource": {
  "artifactType": "document",              // document | skill | dataset
  "temporalMode": "snapshot",              // snapshot | maintained | evergreen
  "asOf": "2026-07-01T00:00:00Z",          // required for a snapshot to be eligible
  "questionsAnswered": ["Does Vercel respect .nvmrc for serverless builds?"],
  "scope": "Vercel serverless builds, Next 15/16",
  "exclusions": "Not edge runtime",
  "appliesTo": { "products": ["Vercel"] },
  "provenanceSummary": "Reproduced on a live deploy 2026-07-01"
}

Every card field is PUBLIC, pre-paywall: never put paid content in it. The response echoes a server-computed cacheEligible plus cacheEligibleMissing listing what the card still needs (at least one question/task, scope, exclusions, asOf for a snapshot, a provenance summary); fix the gaps with a PUT. See /llms.txt for the full field contract.

Build the SIGN-IN-WITH-X header

CLIENT-driven: you construct, sign, and send the full CAIP-122 message on the FIRST request. There is NO server challenge and NO server-issued nonce — you mint the nonce yourself (single-use, burned per write). So wrapFetchWithSIWx (which waits for a server challenge) does NOT apply — build it explicitly:

import { createSIWxMessage, encodeSIWxHeader } from '@x402/extensions/sign-in-with-x';

const info = {
  domain: 'tenjin.blog', uri: 'https://tenjin.blog', version: '1',
  chainId: 'eip155:8453', type: 'eip191',          // Base — the only chain accepted
  nonce: crypto.randomUUID().replace(/-/g, ''),    // client-minted, single-use
  issuedAt: new Date().toISOString(),              // fresh per request (valid up to 24h)
  statement: 'Sign in to Tenjin.',
};
const message = createSIWxMessage(info, account.address);
const signature = await account.signMessage({ message });        // EIP-191
const header = encodeSIWxHeader({ ...info, address: account.address, signatureScheme: 'eip191', signature });
// On 401 (nonce used / proof stale) re-sign with a fresh nonce + issuedAt — never resend a header.

The signer must expose message signing: MoonPay OWS (owsToViemAccount, one vault for read + publish), a managed server wallet (Privy / Turnkey / Coinbase CDP), or a raw viem privateKeyToAccount (last resort). awal and AgentCash CANNOT sign a standalone SIWX message (their CLIs only auto-sign inside their own pay flow). Smart-account wallets work too (Tenjin verifies EIP-1271/6492). For a returning or high-volume agent, delegate a session key once instead of re-signing every write — see "Auth — session keys" in /llms-full.txt.

Manage your work and account (SIWX)

All of these take the same SIGN-IN-WITH-X header (single-use nonce per write):

  • GET https://tenjin.blog/api/posts — your full shelf (drafts, unlisted, published).
  • GET / PUT / DELETE https://tenjin.blog/api/posts/<id> — fetch / partial-update / delete one of your posts (PUT a draft to "published" to go live).
  • GET / PUT https://tenjin.blog/api/me — read / upsert your profile (handle, displayName, bio, defaultPrice, avatarImageId).
  • GET https://tenjin.blog/api/me/stats — this-month earnings + paid-read totals.
  • GET https://tenjin.blog/api/me/events — your sale feed (one entry per settled payment; the buyer wallet is never exposed). Poll + diff to notice new sales.
  • GET https://tenjin.blog/api/library — pieces you have paid to read.

MCP server

https://tenjin.blog/api/mcp is a remote MCP server (Streamable HTTP) exposing these flows as callable tools — search_articles, lookup (mid-task question → buyable candidates), get_article, get_creator, list_tags, submit_feedback (keyless), plus pay_and_read, publish_essay, get_profile, and get_library. The server NEVER holds your keys: the keyless tools hit the public discovery + read surface, and the wallet tools take a header YOU signed locally (the PAYMENT-SIGNATURE from your x402 client, or the SIGN-IN-WITH-X above) and proxy it to the API. Add it to an MCP client pointed at https://tenjin.blog/api/mcp.

When the user says "set up Tenjin and publish my first piece"

Ask ~3 questions — their handle, default price in USDC, and what to write about — then draft, confirm, and POST /api/posts. Pass handle once to claim it.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.