New:Microsoft Teams Notifications Are Now Available in Socket.Learn more →
Get Started

@brainai/satp-client

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@brainai/satp-client

SATP client SDK surface prepared for release-candidate review; publish only after the release packet passes.

Source
npmnpm
Version
2.0.1
Version published
Weekly downloads
19
35.71%
Maintainers
1
Weekly downloads
 
Created
Source

SATP V3 SDK — @brainai/satp-client

Solana Agent Token Protocol — JavaScript/TypeScript SDK for interacting with the SATP V3 devnet programs.

Version: 3.3.0 | Tests: 101 unit + 16 devnet integration | Programs: 6

Installation

npm install git+https://github.com/brainAI-bot/satp.git#<SATP_COMMIT>

The current review package is @brainai/satp-client@0.0.0-extraction and remains unpublished. Pin a reviewed commit for consumers. Do not publish to npm until the release packet passes.

Mainnet program IDs are intentionally not enabled in this release candidate. Constructors and helpers fail closed for network: 'mainnet' until an approved mainnet decision packet provides production program IDs.

Runtime dependency: @solana/web3.js ^1.98.4

Quick Start

const { SATPV3SDK } = require('@brainai/satp-client');

// Initialize (devnet by default)
const sdk = new SATPV3SDK({ network: 'devnet' });

// Check if an agent has an identity
const exists = await sdk.hasIdentity('brainChain');
console.log(exists); // true

// Read a Genesis Record
const record = await sdk.getGenesisRecord('brainChain');
console.log(record.agentName, record.category, record.isActive);

// Build a transaction (unsigned — sign with your wallet)
const tx = await sdk.buildCreateIdentity(creatorPubkey, 'myAgent', {
  agentName: 'My Agent',
  description: 'An AI agent on Solana',
  category: 'assistant',
  capabilities: ['chat', 'code'],
  metadataUri: 'https://example.com/meta.json',
});
// Sign and send tx with your wallet...

Architecture

┌─────────────────────────────────────────────────────────────────┐
│                        SATP V3 SDK                              │
├─────────────┬──────────────┬──────────────┬─────────────────────┤
│ Identity    │ Reviews      │ Attestations │ Escrow              │
│ (20 methods)│ (7 methods)  │ (3 methods)  │ (10 methods)        │
├─────────────┼──────────────┼──────────────┤                     │
│ Reputation  │ Validation   │ Migration    │                     │
│ (1 method)  │ (1 method)   │ (1 method)   │                     │
├─────────────┴──────────────┴──────────────┴─────────────────────┤
│ PDA Derivation  │  Borsh Serialization  │  RPC Helpers          │
└─────────────────┴───────────────────────┴───────────────────────┘

Programs & Program IDs

ProgramDevnetDescription
identity_v3GTppU4E44BqXTQgbqMZ68ozFzhP1TLty3EGnzzjtNZfGAgent identity, names, wallets, face/birth
reviews_v3r9XX4frcqxxAZ6Au9V5PA3EAxs1zoNckqLLmoSRcNr4Peer reviews with 1-5 star ratings
attestations_v36Xd1dAQJPvQRJ4Ntr6LtPTjDjPUZ8nfnmYLZaZ2DtrdDThird-party attestations & proofs
reputation_v32Lz7KzMvKdrGeAuS8WPHu7jK2yScrnKVgacpYVEuDjkJWeighted reputation scoring (CPI → identity)
validation_v36rYRiCYidJYV7QvKrzKGgNu4oMh6BAvynked69R7xMbVValidation level computation (CPI → identity)
escrow_v3HXCUWKR2NvRcZ7rNAJHwPcH6QAAWaLR4bRFbfyuDND6CSOL escrow for agent jobs

API Reference

Read-only Trust Packet Helpers

buildSatpTrustPacket(opts) creates a deterministic, offline trust packet for consumer preflight and release-packet review. It uses the same inputs as prepareIdentityAttestationRequest, then includes the derived program IDs, Genesis PDA, attestation PDA, request hash, and the unsigned request object. The packet is intentionally read-only: flags.signingRequired, flags.transactionRequired, flags.writesRequired, and flags.livePaymentRequired are all false; instructions and signers are empty; and transaction is null.

const {
  buildSatpTrustPacket,
  validateSatpTrustPacket,
} = require('@brainai/satp-client');

const trustPacket = buildSatpTrustPacket({
  subjectWallet: '11111111111111111111111111111111',
  agentId: 'brainChain',
  claimType: 'identity',
  metadataHash: '93d122f8879fe87c186c10a00db8fbc80a73cecd2ede44b9ffa6410be3c2b805',
  network: 'devnet',
});

const validation = validateSatpTrustPacket(trustPacket);
if (!validation.ok) throw new Error(validation.errors.join('; '));

validateSatpTrustPacket(packet) returns { ok, errors }. Validation requires packetType: 'satp-trust-packet' and mode: 'offline-readonly-trust-packet', rejects changed read-only flags, and re-derives the expected packet so tampered PDA, program, request, or hash fields surface as explicit errors.

Constructor

const sdk = new SATPV3SDK({ network, rpcUrl });
// network: 'devnet' (default). 'mainnet' fails closed until approved IDs exist.
// rpcUrl: optional custom RPC endpoint

Identity Methods (20)

MethodDescription
buildCreateIdentity(creator, agentId, meta)Create a new agent identity (Genesis Record)
buildBurnToBecome(authority, agentId, faceImage, faceMint, faceBurnTx)Burn NFT to set agent's face (birth ritual)
buildUpdateIdentity(authority, agentId, updates)Update mutable fields (description, capabilities, metadata)
buildProposeAuthority(authority, agentId, newAuthority)Propose authority transfer (2-step)
buildAcceptAuthority(newAuthority, agentId)Accept proposed authority transfer
buildCancelAuthorityTransfer(authority, agentId)Cancel pending authority transfer
buildRegisterName(authority, agentId, name)Register a unique name for an agent
buildReleaseName(authority, agentId, name)Release a registered name
buildLinkWallet(authority, agentId, wallet, chain, label)Link an external wallet to identity
buildUnlinkWallet(authority, agentId, wallet)Unlink an external wallet
buildInitMintTracker(authority, agentId)Initialize NFT mint tracker
buildRecordMint(authority, agentId)Record an NFT mint event
buildDeactivateIdentity(authority, agentId)Deactivate an identity
buildReactivateIdentity(authority, agentId)Reactivate a deactivated identity
getGenesisRecord(agentId)Read a Genesis Record from chain
hasIdentity(agentId)Check if an agent has an identity
getEscrowPDA(client, description, nonce)Derive escrow PDA (sync)
buildMigrateV2ToV3(v2Authority, agentId, meta)Migrate from V2 to V3 identity

Genesis Record Fields

const record = await sdk.getGenesisRecord('brainChain');
// Returns:
{
  agentIdHash: string,     // SHA-256 of agent_id
  agentName: string,       // Display name
  description: string,     // Agent description
  category: string,        // e.g. "developer", "assistant"
  capabilities: string[],  // e.g. ["solana", "code"]
  metadataUri: string,     // Off-chain metadata URL
  faceImage: string,       // Face image URL (after birth)
  faceMint: string,        // NFT mint address (after birth)
  faceBurnTx: string,      // Burn transaction signature
  genesisRecord: number,   // Unix timestamp of birth
  isBorn: boolean,         // Whether agent has completed birth ritual
  isActive: boolean,       // Whether identity is active
  authority: string,       // Current authority pubkey
  pendingAuthority: string | null,
  reputationScore: number, // CPI-updated reputation
  validationLevel: number, // CPI-updated validation
  createdAt: number,       // Unix timestamp
  updatedAt: number,       // Unix timestamp
}

Reviews Methods (7)

MethodDescription
buildInitReviewCounter(payer, agentId)Initialize review counter for an agent
buildCreateReview(reviewer, agentId, rating, text, metadata, opts)Create a 1-5 star review
buildCreateReviewWithSelfCheck(reviewer, agentId, rating, text, metadata)Create review with self-review prevention
buildUpdateReview(reviewer, reviewPDA, updates)Update an existing review
buildDeleteReview(reviewer, reviewPDA)Soft-delete a review
getReview(agentId, reviewer)Read a review from chain
getReviewCount(agentId)Get total review count for an agent
// Create a review
const tx = await sdk.buildCreateReview(
  reviewerPubkey,
  'brainChain',      // agent being reviewed
  5,                 // rating (1-5)
  'Excellent Solana dev',
  'metadata',
  { category: 'development' }
);

Attestations Methods (3)

MethodDescription
buildCreateAttestation(issuer, agentId, type, proofData, expiresAt)Issue an attestation
buildVerifyAttestation(issuer, attestationPDA)Mark attestation as verified
buildRevokeAttestation(issuer, attestationPDA)Revoke an attestation
// Issue a KYC attestation
const tx = await sdk.buildCreateAttestation(
  issuerPubkey,
  'brainChain',
  'kyc',             // attestation type
  'proof-hash-here',
  Math.floor(Date.now()/1000) + 86400 * 365 // expires in 1 year
);

Reputation & Validation Methods (2)

MethodDescription
buildRecomputeReputation(caller, agentId, reviewAccounts)Recompute reputation score from reviews (CPI → identity)
buildRecomputeLevel(caller, agentId, attestationAccounts)Recompute validation level from attestations (CPI → identity)

These use Cross-Program Invocation to update fields directly on the Genesis Record.

Escrow Methods (10)

Full escrow lifecycle for agent marketplace jobs.

MethodDescription
buildCreateEscrow(client, agentWallet, agentId, amount, description, deadline, nonce, opts)Create SOL escrow for a job
buildSubmitWork(agent, escrowPDA, workProof)Agent submits work proof
buildEscrowRelease(client, agent, escrowPDA)Client releases full payment
buildPartialRelease(client, agent, escrowPDA, amount)Client releases partial payment
buildCancelEscrow(client, escrowPDA)Cancel escrow (refund client)
buildRaiseDispute(signer, escrowPDA, reason)Raise a dispute
buildResolveDispute(arbiter, agent, client, escrowPDA, agentAmt, clientAmt)Arbiter resolves dispute
buildExtendDeadline(client, escrowPDA, newDeadline)Extend job deadline
buildCloseEscrow(client, escrowPDA)Close completed/cancelled escrow (reclaim rent)
getEscrow(escrowPDA)Read escrow state from chain

Escrow Lifecycle

Created → WorkSubmitted → Released (full or partial)
   ↓           ↓              ↓
Cancelled   Disputed     Closed (rent reclaimed)
               ↓
          Resolved (split)
               ↓
            Closed
// Create an escrow (0.5 SOL for a coding job)
const tx = await sdk.buildCreateEscrow(
  clientPubkey,
  agentWallet,
  'brainChain',
  0.5 * 1e9,        // lamports
  'Build SATP integration',
  Math.floor(Date.now()/1000) + 86400 * 7, // 7 day deadline
  0,                 // nonce (for multiple escrows with same description)
  { arbiter: arbiterPubkey }
);

PDA Helpers (exported from v3-pda.js)

const {
  hashAgentId,                  // SHA-256 hash of agent_id string
  hashName,                     // SHA-256 hash of name string
  getGenesisPDA,                // [b"genesis_record", agent_id_hash]
  getNameRegistryPDA,           // [b"name_registry_v3", name_hash]
  getLinkedWalletPDA,           // [b"linked_wallet_v3", agent_id_hash, wallet]
  getV3MintTrackerPDA,          // [b"mint_tracker_v3", agent_id_hash]
  getV3ReviewPDA,               // [b"review_v3", agent_id_hash, reviewer]
  getV3ReviewCounterPDA,        // [b"review_counter_v3", agent_id_hash]
  getV3AttestationPDA,          // [b"attestation_v3", agent_id_hash, issuer, type_hash]
  getV3ReputationAuthorityPDA,  // [b"reputation_authority", agent_id_hash]
  getV3ValidationAuthorityPDA,  // [b"validation_authority", agent_id_hash]
  getV3EscrowPDA,               // [b"escrow_v3", client, desc_hash, nonce_le]
  getV3ProgramIds,              // Returns all 6 program IDs for network
} = require('@brainai/satp-client/src/v3-pda');

Escrow SDK Utilities (exported from v3-sdk.js)

const {
  deriveEscrowPda,    // Derive escrow PDA from params
  descriptionHash,    // SHA-256 hash of description string
  EscrowStatus,       // Enum: { Active: 0, WorkSubmitted: 1, Released: 2, Cancelled: 3, Disputed: 4, Resolved: 5 }
  escrowStatusLabel,  // Convert status number to human-readable string
  escrowRemaining,    // Calculate remaining escrow balance
  isEscrowExpired,    // Check if escrow has passed deadline
} = require('@brainai/satp-client/src/v3-sdk');

Transaction Pattern

All build* methods return an unsigned Transaction object. Your application is responsible for:

  • Setting recentBlockhash and feePayer
  • Signing with the appropriate wallet
  • Sending to the network
const tx = await sdk.buildCreateIdentity(wallet.publicKey, 'myAgent', { ... });
tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
tx.feePayer = wallet.publicKey;
tx.sign(wallet);
const sig = await connection.sendRawTransaction(tx.serialize());
await connection.confirmTransaction(sig);

REST API

The SATP V3 API is available at https://agentfolio.bot/api/v3/:

EndpointDescription
GET /api/v3/healthAPI health + program IDs
GET /api/v3/escrow/by-client/:walletEscrows by client wallet
GET /api/v3/escrow/by-agent/:walletEscrows by agent wallet
GET /api/v3/escrow/by-agent-id/:agentIdEscrows by SATP agent_id
+ 18 moreSee OpenAPI spec in docs/

Testing

# Unit tests (101)
node test-v3.js

# Devnet integration tests (16)
node test-v3-devnet.js

# CPI integration tests (35)
cd .. && node tests/devnet-cpi-integration.js

# Release-safety defaults and mainnet fail-closed checks
node test-release-safety.js

Network Configuration

// Devnet (default)
const sdk = new SATPV3SDK();

// Explicit devnet
const sdk = new SATPV3SDK({ network: 'devnet' });

// Custom RPC
const sdk = new SATPV3SDK({ rpcUrl: 'https://my-rpc.example.com' });

// Mainnet currently fails closed until approved program IDs are configured
assert.throws(() => new SATPV3SDK({ network: 'mainnet' }));

Borsh Deserialization Helpers (v3.6.0)

Zero-dependency Borsh deserialization for all 8 SATP V3 account types. Decode raw on-chain data without the borsh library.

Supported Account Types

AccountProgramDeserializer
GenesisRecordIdentity V3deserializeGenesisRecord(data)
LinkedWalletIdentity V3deserializeLinkedWallet(data)
MintTrackerIdentity V3deserializeMintTracker(data)
NameRegistryIdentity V3deserializeNameRegistry(data)
ReviewReviews V3deserializeReview(data)
ReviewCounterReviews V3deserializeReviewCounter(data)
AttestationAttestations V3deserializeAttestation(data)
EscrowV3Escrow V3deserializeEscrowV3(data)

Usage: Typed Deserialization

const { deserializeGenesisRecord, deserializeAttestation } = require('@brainai/satp-client');
const { Connection, PublicKey } = require('@solana/web3.js');

const conn = new Connection('https://api.devnet.solana.com');

// Fetch raw account and deserialize
const acct = await conn.getAccountInfo(new PublicKey('...'));
const genesis = deserializeGenesisRecord(acct.data);
console.log(genesis.agentName, genesis.reputationScore, genesis.isBorn);

Usage: Auto-detect Account Type

const { deserializeAccount } = require('@brainai/satp-client');

// Automatically detects type from 8-byte Anchor discriminator
const { type, data } = deserializeAccount(acct.data);
console.log(type);  // "GenesisRecord" | "Attestation" | "EscrowV3" | ...
console.log(data);  // Fully parsed object

Usage: Batch Deserialization (getProgramAccounts)

const { deserializeBatch, DISCRIMINATORS } = require('@brainai/satp-client');

const accounts = await conn.getProgramAccounts(REVIEWS_PROGRAM_ID);
const reviews = deserializeBatch(accounts, 'Review');
// [{ pubkey: "...", type: "Review", data: { agentId, rating, ... } }, ...]

Usage: BorshReader (Custom Deserialization)

const { BorshReader } = require('@brainai/satp-client');

// Low-level reader for custom account layouts
const r = new BorshReader(acct.data);
r.skipDiscriminator();           // skip 8-byte Anchor discriminator
const hash = r.readFixedBytes32(); // [u8; 32]
const name = r.readString();     // Borsh String
const items = r.readVecString(); // Vec<String>
const pk = r.readPubkeyBase58(); // Pubkey → base58
const opt = r.readOptionI64();   // Option<i64> → number | null

Discriminator Utilities

const { isAccountType, getAccountDiscriminator, DISCRIMINATORS } = require('@brainai/satp-client');

// Check account type before deserializing
if (isAccountType(acct.data, 'EscrowV3')) {
  const escrow = deserializeEscrowV3(acct.data);
}

// Get discriminator for filtering
const disc = getAccountDiscriminator('Attestation'); // 8-byte Buffer
// Use with getProgramAccounts memcmp filter

Security

  • All transactions are returned unsigned — the SDK never holds private keys
  • PDA derivation is deterministic and verified against on-chain seeds
  • CPI boundaries enforce program-level authorization
  • Escrow funds are held by PDA-owned accounts (no custodial risk)

License

MIT — brainAI 2026

Keywords

solana

FAQs

Package last updated on 21 May 2026

Related posts