Skip to main content

sati-sdk

Build with SATI (Solana Agent Trust Infrastructure) - on-chain agent identity, verifiable reputation, and blind feedback on Solana. Use when registering AI agents on-chain via Token-2022 NFTs, giving or searching feedback, querying agent reputation, building registration files (ERC-8004), encrypting attestation content, or integrating SATI into TypeScript/Node.js projects. Covers: CLI onboarding (create-sati-agent), agent registration, feedback (give/search), reputation summaries, agent search/discovery, validation attestations, EVM address linking, content encryption, and metadata uploading. Triggers on SATI, sati-sdk, create-sati-agent, agent registration solana, agent reputation, blind feedback, compressed attestation, Light Protocol attestation, ERC-8004 registration file, agent identity NFT, register agent CLI.

Jump to install

Source facts

Repository
cascade-protocol/sati
Last source activity
May 13, 2026 at 18:28
Detected SKILL.md language
English
Stars
18
Forks
3

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
sati-sdk
description
Build with SATI (Solana Agent Trust Infrastructure) - on-chain agent identity, verifiable reputation, and blind feedback on Solana. Use when registering AI agents on-chain via Token-2022 NFTs, giving or searching feedback, querying agent reputation, building registration files (ERC-8004), encrypting attestation content, or integrating SATI into TypeScript/Node.js projects. Covers: CLI onboarding (create-sati-agent), agent registration, feedback (give/search), reputation summaries, agent search/discovery, validation attestations, EVM address linking, content encryption, and metadata uploading. Triggers on SATI, sati-sdk, create-sati-agent, agent registration solana, agent reputation, blind feedback, compressed attestation, Light Protocol attestation, ERC-8004 registration file, agent identity NFT, register agent CLI.
# SATI Solana Agent Trust Infrastructure. Agents get Token-2022 NFT identities, accumulate verifiable feedback via ZK-compressed attestations (Light Protocol), and can be discovered on-chain. Program ID (all networks): `satiRkxEiwZ51cv8PRu8UMzuaqeaNU9jABo6oAFMsLe` ## Quick Start (CLI) Fastest path - zero to registered agent in ~5 minutes: ```bash npx create-sati-agent init # Creates agent-registration.json + keypair # Edit agent-registration.json with your agent details npx create-sati-agent publish # Publishes to devnet (free, auto-funded) ``` Mainnet: ```bash npx create-sati-agent publish --network mainnet # ~0.003 SOL ``` All commands: `init`, `publish`, `search`, `info [MINT]`, `give-feedback`, `transfer <MINT>`. All support `--help`, `--json`, `--network devnet|mainnet`. ### agent-registration.json The registration file follows the [ERC-8004 Registration standard](https://github.com/erc-8004/best-practices/blob/main/Registration.md): ```json { "type": "https://eips.ethereum.org/EIPS/eip-8004#registration-v1", "name": "MyAgent", "description": "AI assistant that does X for Y", "image": "https://example.com/avatar.png", "properties": { "files": [{"uri": "https://example.com/avatar.png", "type": "image/png"}], "category": "image" }, "services": [ { "name": "MCP", "endpoint": "https://myagent.com/mcp", "version": "2025-06-18", "mcpTools": ["search", "summarize", "analyze"], "mcpPrompts": ["data-analysis"], "mcpResources": ["knowledge-base"] }, { "name": "A2A", "endpoint": "https://myagent.com/.well-known/agent-card.json", "a2aSkills": ["natural_language_processing/information_retrieval_synthesis/question_answering"] } ], "supportedTrust": ["reputation"], "active": false, "x402Support": false, "registrations": [] } ``` Service types (see [ERC-8004 best practices](https://github.com/erc-8004/best-practices) for detailed guidance): - `MCP` - Model Context Protocol. Fields: `mcpTools` (tool names as strings), `mcpPrompts`, `mcpResources`. The `version` field is the MCP spec version your server supports (e.g., `"2025-06-18"`). - `A2A` - Agent-to-Agent. Fields: `a2aSkills` (OASF skill paths). Endpoint should point to your agent card JSON. - `OASF` - Open Agent Skills Framework. Fields: `skills`, `domains`. - `ENS`, `DID`, `agentWallet` - Identity services. > **Note:** When publishing via CLI (`npx create-sati-agent publish`), the CLI auto-discovers MCP tools by calling your MCP endpoint. Your MCP server must be running and reachable during publish. If your server requires auth, you'll see a non-blocking reachability warning - you can safely ignore it and list tools manually in the JSON. ### Mainnet deployment flow ```bash npx create-sati-agent init # 1. Create template + keypair npx create-sati-agent publish # 2. Test on devnet (free, default) npx create-sati-agent info <MINT> --network devnet # 3. Verify npx create-sati-agent publish --network mainnet # 4. Go live (~0.003 SOL) npx create-sati-agent transfer <MINT> \ --new-owner <SECURE_WALLET> --network mainnet # 5. Move to hardware wallet ``` ### CLI feedback ```bash npx create-sati-agent give-feedback \ --agent <MINT> --tag1 starred --value 85 --network mainnet ``` Feedback tag conventions: | tag1 | value range | meaning | |------|-------------|---------| | `starred` | 0-100 | Overall rating | | `reachable` | 0 or 1 | Health check (1 = reachable) | | `uptime` | 0-100 | Uptime percentage | | `responseTime` | ms | Latency in milliseconds | | `successRate` | 0-100 | Success percentage | ### Monitoring agent health Automate health checks with a cron job or scheduled task: ```bash # Check if endpoint is reachable and report to SATI curl -sf https://myagent.com/mcp > /dev/null && \ npx create-sati-agent give-feedback --agent <MINT> --tag1 reachable --value 1 --network mainnet || \ npx create-sati-agent give-feedback --agent <MINT> --tag1 reachable --value 0 --network mainnet ``` ### Reputation badge Add a reputation badge to your README: ```markdown ![SATI Reputation](https://sati.cascade.fyi/api/badge/<YOUR_MINT>?network=mainnet) ``` Or link to your dashboard page: ```markdown [Reputation](https://sati.cascade.fyi/agent/<YOUR_MINT>) ``` --- ## SDK (Programmatic) `@cascade-fyi/sati-sdk` is the primary SDK for all SATI integrations. > **Building a read-only integration?** For explorers, dashboards, and data ingestion, the [REST API](#rest-api) requires no wallet or Solana dependencies. Use the SDK only when you need to write on-chain (register agents, give feedback, publish scores). ```bash npm install @cascade-fyi/sati-sdk # Peer deps: npm install @solana/kit @solana-program/token-2022 ``` ### Initialize ```typescript import { Sati, createSatiUploader, address } from "@cascade-fyi/sati-sdk"; import { createKeyPairSignerFromBytes } from "@solana/kit"; const sati = new Sati({ network: "mainnet" }); // Options: network, rpcUrl, wsUrl, photonRpcUrl, onWarning, transactionConfig, feedbackCacheTtlMs ``` Load a wallet: ```typescript import { readFileSync } from "node:fs"; const bytes = new Uint8Array(JSON.parse(readFileSync("wallet.json", "utf8"))); const payer = await createKeyPairSignerFromBytes(bytes); ``` ### 1. Register an Agent #### Quick (fluent builder) ```typescript const builder = sati.createAgentBuilder("MyAgent", "AI assistant", "https://example.com/avatar.png"); builder .setMCP("https://mcp.example.com", "2025-06-18", { tools: ["search"] }) .setA2A("https://a2a.example.com/.well-known/agent-card.json") .setX402Support(true) .setActive(true); const result = await builder.register({ payer, uploader: createSatiUploader(), // Zero-config IPFS upload }); // result.mint - agent NFT address, result.memberNumber, result.signature ``` #### Direct ```typescript import { buildRegistrationFile, createSatiUploader } from "@cascade-fyi/sati-sdk"; const regFile = buildRegistrationFile({ name: "MyAgent", description: "AI assistant", image: "https://example.com/avatar.png", services: [{ name: "MCP", endpoint: "https://mcp.example.com" }], active: true, }); const uploader = createSatiUploader(); const uri = await uploader.upload(regFile); const result = await sati.registerAgent({ payer, name: "MyAgent", uri, nonTransferable: false, // default: false. Set true for soulbound (non-transferable) agents. }); ``` Uploaders: `createSatiUploader()` (zero-config, uses hosted IPFS via `sati.cascade.fyi`) or `createPinataUploader(jwt)`. ### 2. Give Feedback #### Public feedback (simple) `giveFeedback` uses the **FeedbackPublicV1** schema (CounterpartySigned mode) - the reviewer signs and submits in one call. No agent co-signature required. ```typescript import { Outcome } from "@cascade-fyi/sati-sdk"; const { signature, attestationAddress } = await sati.giveFeedback({ payer, // Reviewer wallet (pays + signs) agentMint: address("Agent..."), // Agent to review outcome: Outcome.Positive, // Positive | Negative | Neutral (default: Neutral) value: 87, // Numeric score (optional) valueDecimals: 0, // Decimal places for value tag1: "starred", // Primary dimension tag2: "chat", // Secondary dimension (optional) message: "Great response time", // Human-readable (optional) endpoint: "https://agent.example", // Endpoint reviewed (optional) taskRef: txHashBytes, // 32-byte task reference (optional, e.g. payment tx hash) }); ``` > **x402 payment linking:** The `taskRef` field accepts a 32-byte reference to link feedback to a specific transaction. x402 integration details (converting tx signatures to 32-byte refs, querying feedback by payment) are under active development. #### Blind feedback (dual-signature) For proof-of-participation, use the **FeedbackV1** schema (DualSignature mode). The agent signs a blind commitment *before* knowing the outcome. Use the lower-level `createFeedback()` method with both `agentSignature` and `counterpartyMessage`. See the specification for the full blind feedback flow. > **Note:** For most integrations, `FeedbackPublicV1` (single-signer via `giveFeedback`) is sufficient. Blind feedback requires agent-side signing integration and is primarily for proof-of-participation use cases where you need cryptographic evidence that the agent participated in the interaction. #### Browser wallet flow (two-step) The platform server prepares a SIWS (Sign In With Solana) message, the user signs it in their browser wallet, and the platform submits the transaction. Uses `@solana/wallet-adapter-react` (works with Phantom, Solflare, Backpack, and any wallet implementing the Wallet Standard `signMessage` feature). ```bash npm install @solana/wallet-adapter-react @solana/wallet-adapter-wallets @solana/wallet-adapter-react-ui ``` **Server (API route):** ```typescript import { Sati, Outcome, address, bytesToHex, hexToBytes } from "@cascade-fyi/sati-sdk"; const sati = new Sati({ network: "mainnet" }); // POST /api/prepare-feedback async function handlePrepare(req) { const { walletAddress, agentMint, value, tag1, outcome } = req.body; const prepared = await sati.prepareFeedback({ counterparty: address(walletAddress), agentMint: address(agentMint), outcome: outcome ?? Outcome.Positive, value, tag1, }); // Store `prepared` server-side (e.g. in session or cache keyed by walletAddress + agentMint) await cache.set(`feedback:${walletAddress}:${agentMint}`, prepared); // Only send the SIWS message bytes to the frontend return { messageHex: bytesToHex(prepared.messageBytes) }; } // POST /api/submit-feedback async function handleSubmit(req) { const { walletAddress, agentMint, signatureHex } = req.body; const prepared = await cache.get(`feedback:${walletAddress}:${agentMint}`); const result = await sati.submitPreparedFeedback({ payer: platformPayer, prepared, counterpartySignature: hexToBytes(signatureHex), }); return { signature: result.signature, attestationAddress: result.attestationAddress }; } ``` **Frontend (React component):** ```tsx import { useWallet } from "@solana/wallet-adapter-react"; import { hexToBytes, bytesToHex } from "@cascade-fyi/sati-sdk"; function FeedbackButton({ agentMint }: { agentMint: string }) { const { publicKey, signMessage, connected } = useWallet(); async function handleFeedback() { if (!publicKey || !signMessage) return; // 1. Server prepares the SIWS message const { messageHex } = await fetch("/api/prepare-feedback", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ walletAddress: publicKey.toBase58(), agentMint, value: 85, tag1: "starred", }), }).then((r) => r.json()); // 2. User signs with wallet (Phantom/Solflare popup) const messageBytes = hexToBytes(messageHex); const signature = await signMessage(messageBytes); // Returns Uint8Array (64-byte Ed25519) // 3. Server submits the transaction await fetch("/api/submit-feedback", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ walletAddress: publicKey.toBase58(), agentMint, signatureHex: bytesToHex(signature), }), }); } return ( <button onClick={handleFeedback} disabled={!connected}> Rate Agent </button> ); } ```
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub