Skip to content

Commit be5ea7d

Browse files
committed
docs: fix misleading APIs, naming gaps, and missing guidance in SATI skill
- Remove revokeFeedback from SKILL.md (closeable: false makes it fail) - Add closeable warning to revokeFeedback in SDK ref - Add REST-first callout for read-only integrators - Add SDK/REST naming table (counterparty=clientAddress, averageValue=summaryValue) - Add EVM links caveat near REST API section - Add parseFeedbackContent import to bulk ingestion example - Rewrite count semantics note (SDK vs REST differences) - Add x402 taskRef status note (under active development) - Add blind feedback recommendation (FeedbackPublicV1 sufficient for most) - Fix nonTransferable default: true -> false in SDK ref - Fix offset type: bigint -> number in searchAgents - Fix listAllAgents return type in SDK ref
1 parent 44bf1d6 commit be5ea7d

2 files changed

Lines changed: 25 additions & 14 deletions

File tree

docs/reference/sati-sdk.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,11 @@ Returns `{ count: number; averageValue: number }`.
300300

301301
### revokeFeedback
302302

303-
Revoke (close) a feedback attestation. The payer must be the original reviewer.
303+
Close a feedback attestation. The payer must be the original reviewer.
304+
305+
::: warning Not available for feedback schemas
306+
FeedbackPublicV1 and FeedbackV1 schemas have `closeable: false`. Calling this method on feedback attestations will throw `AttestationNotCloseable`. This method is only usable with custom schemas that allow closing. To close reputation scores, use `closeRegularAttestation` instead.
307+
:::
304308

305309
```typescript
306310
const result = await sati.revokeFeedback({
@@ -327,7 +331,7 @@ const results = await sati.searchAgents({
327331
active: true,
328332
endpointTypes: ["MCP"],
329333
limit: 25,
330-
offset: 50n,
334+
offset: 50,
331335
includeFeedbackStats: true,
332336
});
333337

@@ -351,7 +355,7 @@ for (const agent of results) {
351355
| `active` | `boolean` | Filter by active status |
352356
| `endpointTypes` | `string[]` | Filter by endpoint types (e.g., `["MCP", "A2A"]`) |
353357
| `limit` | `number` | Max results |
354-
| `offset` | `bigint` | Offset for pagination (member number) |
358+
| `offset` | `number` | Offset for pagination |
355359
| `includeFeedbackStats` | `boolean` | Compute feedback stats per agent (slower) |
356360

357361
#### AgentSearchResult
@@ -394,7 +398,7 @@ const result = await sati.registerAgent({
394398
additionalMetadata: [ // Optional key-value pairs
395399
{ key: "version", value: "1.0" },
396400
],
397-
nonTransferable: true, // Default: true (soulbound)
401+
nonTransferable: false, // Default: false. Set true for soulbound (non-transferable).
398402
});
399403

400404
console.log(result.mint); // Agent's token address (identity)
@@ -443,10 +447,11 @@ const arweaveUploader: MetadataUploader = {
443447
### List Agents
444448

445449
```typescript
446-
const agents = await sati.listAllAgents();
450+
const { agents, totalAgents } = await sati.listAllAgents();
447451
for (const agent of agents) {
448452
console.log(`Agent ${agent.memberNumber}: ${agent.mint}`);
449453
}
454+
console.log(`Total: ${totalAgents}`);
450455

451456
// By member number
452457
const agent = await sati.getAgentByMemberNumber(1n);

skills/sati/SKILL.md

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: sati-sdk
3-
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/revoke), 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."
3+
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."
44
---
55

66
# SATI
@@ -130,6 +130,8 @@ Or link to your dashboard page:
130130

131131
`@cascade-fyi/sati-sdk` is the primary SDK for all SATI integrations.
132132

133+
> **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).
134+
133135
```bash
134136
npm install @cascade-fyi/sati-sdk
135137
# Peer deps:
@@ -222,10 +224,14 @@ const { signature, attestationAddress } = await sati.giveFeedback({
222224
});
223225
```
224226

227+
> **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.
228+
225229
#### Blind feedback (dual-signature)
226230

227231
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.
228232

233+
> **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.
234+
229235
#### Browser wallet flow (two-step)
230236

231237
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.
@@ -327,12 +333,6 @@ function FeedbackButton({ agentMint }: { agentMint: string }) {
327333

328334
> **Note:** `signMessage` is `undefined` if the connected wallet doesn't support message signing. Always check `signMessage` before calling it. `PreparedFeedbackData` contains multiple `Uint8Array` fields (`messageBytes`, `taskRef`, `dataHash`, `content`). If you need to serialize the entire object to JSON (e.g. for a stateless API), convert all `Uint8Array` fields with `bytesToHex()` and restore with `hexToBytes()`. The recommended pattern above avoids this by keeping `prepared` server-side.
329335
330-
#### Revoke feedback
331-
332-
```typescript
333-
await sati.revokeFeedback({ payer, attestationAddress: address("Attest...") });
334-
```
335-
336336
### 3. Search Feedback
337337

338338
`searchFeedback` queries only the **FeedbackPublicV1** schema. Use `searchAllFeedback` to query both FeedbackPublicV1 and FeedbackV1 (blind) schemas.
@@ -362,6 +362,8 @@ To distinguish blind (FeedbackV1) from public (FeedbackPublicV1) in raw results,
362362
**Bulk ingestion (for indexers/scoring providers):**
363363

364364
```typescript
365+
import { parseFeedbackContent } from "@cascade-fyi/sati-sdk";
366+
365367
// Auto-paginating async iterator across both schemas
366368
for await (const page of sati.listAllFeedbacks({ agentMint: address("Agent...") })) {
367369
for (const item of page.items) {
@@ -393,7 +395,7 @@ const summary = await sati.getReputationSummary(address("Agent..."));
393395
const filtered = await sati.getReputationSummary(address("Agent..."), "starred", "chat");
394396
```
395397

396-
Note: `getReputationSummary` queries both FeedbackPublicV1 and FeedbackV1 schemas. `count` only includes feedback entries that have a `value` field set. An agent with 10 feedback entries but none containing `value` will show `count: 0`. The REST API returns `summaryValue` (integer) instead of `averageValue` (float), and its `count` includes all entries regardless of `value`.
398+
Note: `getReputationSummary` queries both FeedbackPublicV1 and FeedbackV1 schemas. In the SDK, `count` only includes entries with a `value` field (entries without `value` are excluded from both count and average). The REST API differs: its `count` includes all feedback entries regardless of `value`, while `summaryValue` averages only entries that have `value` set. The REST API returns integer `summaryValue`/`summaryValueDecimals` instead of the SDK's float `averageValue`.
397399

398400
### 5. Agent Discovery
399401

@@ -568,7 +570,11 @@ The dashboard at `sati.cascade.fyi` exposes a public REST API. See the [REST API
568570
- `GET /api/badge/:mint` - SVG reputation badge for README embedding
569571
- `POST /api/feedback` - submit feedback without a wallet (server acts as counterparty, rate limited per IP)
570572

571-
The agents list supports `includeReputation=true` to get reputation inline per agent (slower but avoids N+1 requests). The REST API uses `clientAddress` for the reviewer field (the SDK calls this `counterparty`). Filter params like `endpointTypes` are case-sensitive (use `MCP`, not `mcp`).
573+
The agents list supports `includeReputation=true` to get reputation inline per agent (slower but avoids N+1 requests). Filter params like `endpointTypes` are case-sensitive (use `MCP`, not `mcp`).
574+
575+
> **SDK ↔ REST API field mapping:** `counterparty` (SDK) = `clientAddress` (REST). `averageValue` (SDK, float) = `summaryValue`/`summaryValueDecimals` (REST, integer). Outcome: `Outcome.Positive` = `2`, `Outcome.Neutral` = `1`, `Outcome.Negative` = `0`. Use `getOutcomeLabel(outcome)` in SDK for display strings.
576+
577+
> **Note:** EVM address links (from `linkEvmAddress`) are not queryable via REST API - they are stored as Anchor events only. Retrieving them requires a Solana transaction log indexer (Helius webhooks, Yellowstone gRPC).
572578
573579
### Configuration
574580

0 commit comments

Comments
 (0)