Lightweight TypeScript SDK for Solana Agent Registry and Agent Staking smart contracts.
Pure @solana/web3.js implementation - no Anchor dependency, ultra-lightweight (97% smaller than framework-based SDKs).
Note: This package is not yet published to npm. Install directly from GitHub.
npm install github:QuantumAgentic/agent-registry-sdk @solana/web3.js
# or with yarn
yarn add github:QuantumAgentic/agent-registry-sdk @solana/web3.js
# or with pnpm
pnpm add github:QuantumAgentic/agent-registry-sdk @solana/web3.jsFor production use, it's recommended to pin to a specific commit or tag:
npm install github:QuantumAgentic/agent-registry-sdk#commit-hash @solana/web3.js
# Example with specific commit
npm install github:QuantumAgentic/agent-registry-sdk#abc1234 @solana/web3.jsDependencies:
- β
@solana/web3.js(only Solana dependency) - β
canonicalize(JSON canonicalization for JCS hashing)
Bundle size: Only 84 KB! π
import { Connection, Keypair } from "@solana/web3.js";
import {
createAgent,
fetchAgentByCreator,
hashCardJcs,
makeConnection
} from "@pipeline/agent-registry-sdk";
// 1. Setup
const connection = makeConnection("devnet");
const payer = Keypair.generate();
// 2. Airdrop (devnet only)
const sig = await connection.requestAirdrop(payer.publicKey, 1_000_000_000);
await connection.confirmTransaction(sig);
// 3. Create card hash
const cardData = {
name: "My AI Agent",
description: "An autonomous AI agent",
version: "1.0.0"
};
const cardHash = await hashCardJcs(cardData);
// 4. Create agent
const agentPda = await createAgent({
connection,
payer,
cardUri: "https://example.com/agent-card.json",
cardHash,
hasStaking: true,
});
console.log("β
Agent created:", agentPda.toBase58());
// 5. Fetch agent data
const result = await fetchAgentByCreator(connection, payer.publicKey);
if (result) {
console.log("Agent data:", result.account);
}Create a new agent on-chain.
async function createAgent(params: {
connection: Connection;
payer: Signer;
creator?: PublicKey; // Optional: defaults to payer.publicKey
cardUri: string; // Required
cardHash: Uint8Array | number[]; // Required (32 bytes)
hasStaking?: boolean; // Optional: default true
memoryMode?: number; // Optional: 0=None, 1=CID, 2=IPNS, 3=URL
memoryPtr?: string; // Optional
memoryHash?: Uint8Array | number[]; // Optional (32 bytes)
programId?: PublicKey; // Optional: override program ID
}): Promise<PublicKey>Example:
const cardHash = await hashCardJcs({ name: "Agent" });
const agentPda = await createAgent({
connection,
payer: myKeypair,
cardUri: "https://example.com/card.json",
cardHash,
hasStaking: true,
memoryMode: 3, // URL mode
memoryPtr: "https://example.com/memory.json",
});Update agent's card.
async function setCard(params: {
connection: Connection;
payer: Signer;
agentPda: PublicKey;
cardUri: string;
cardHash: Uint8Array | number[];
programId?: PublicKey;
}): Promise<void>Configure agent's memory.
async function setMemory(params: {
connection: Connection;
payer: Signer;
agentPda: PublicKey;
mode: number; // 0=None, 1=CID, 2=IPNS, 3=URL
ptr: Uint8Array | number[];
hash?: Uint8Array | number[];
programId?: PublicKey;
}): Promise<void>Memory Modes:
| Mode | Value | Ptr Required | Hash Required | Use Case |
|---|---|---|---|---|
| None | 0 | β | β | No memory |
| CID | 1 | β | β | IPFS CID (self-verifying) |
| IPNS | 2 | β | β | IPNS name (mutable) |
| URL | 3 | β | β | HTTPS URL |
| Manifest | 4 | β | β | Manifest pointer |
Lock memory permanently.
async function lockMemory(params: {
connection: Connection;
payer: Signer;
agentPda: PublicKey;
programId?: PublicKey;
}): Promise<void>Activate or deactivate agent.
async function setActive(params: {
connection: Connection;
payer: Signer;
agentPda: PublicKey;
isActive: boolean;
programId?: PublicKey;
}): Promise<void>Close agent account and recover rent.
async function closeAgent(params: {
connection: Connection;
payer: Signer;
agentPda: PublicKey;
recipient: PublicKey;
programId?: PublicKey;
}): Promise<void>Transfer ownership to another address.
async function transferOwner(params: {
connection: Connection;
payer: Signer;
agentPda: PublicKey;
newOwner: PublicKey;
programId?: PublicKey;
}): Promise<void>Create agent and staking pool in a single atomic transaction.
async function createAgentWithStakingPool(params: {
connection: Connection;
payer: Signer;
creator?: PublicKey; // Optional: defaults to payer.publicKey
tokenMint: PublicKey; // SPL token for staking
minStakeAmount: bigint; // Minimum stake amount
cardUri: string; // Required
cardHash: Uint8Array | number[]; // Required (32 bytes)
memoryMode?: number; // Optional
memoryPtr?: string; // Optional
memoryHash?: Uint8Array | number[]; // Optional
agentProgramId?: PublicKey;
stakingProgramId?: PublicKey;
}): Promise<{
agentPda: PublicKey;
poolPda: PublicKey;
vaultPda: PublicKey;
signature: string;
}>Example:
import { PublicKey } from "@solana/web3.js";
const tokenMint = new PublicKey("So11111111111111111111111111111111111111112"); // Wrapped SOL
const cardHash = await hashCardJcs({ name: "Staking Agent" });
const result = await createAgentWithStakingPool({
connection,
payer: myKeypair,
tokenMint,
minStakeAmount: 1_000_000n, // 1 token (6 decimals)
cardUri: "https://example.com/card.json",
cardHash,
});
console.log("β
Agent:", result.agentPda.toBase58());
console.log("β
Pool:", result.poolPda.toBase58());
console.log("β
Vault:", result.vaultPda.toBase58());
console.log("β
TX:", result.signature);Note: For v1.0, only agent+pool creation is supported. Stake/unstake functions will come in v2.0.
Fetch agent by its PDA.
async function fetchAgentByPda(
connection: Connection,
agentPda: PublicKey,
programId?: PublicKey
): Promise<AgentAccount | null>Fetch agent by creator public key.
async function fetchAgentByCreator(
connection: Connection,
creator: PublicKey,
programId?: PublicKey
): Promise<{ pda: PublicKey; account: AgentAccount } | null>All PDA derivation functions:
function deriveAgentPda(creator: PublicKey, programId?: PublicKey): [PublicKey, number]
function deriveStakingPoolPda(agentPda: PublicKey, programId?: PublicKey): [PublicKey, number]
function deriveStakeAccountPda(staker: PublicKey, agentPda: PublicKey, programId?: PublicKey): [PublicKey, number]
function deriveProgramStatePda(programId?: PublicKey): [PublicKey, number]
function deriveTokenVaultPda(poolPda: PublicKey, programId?: PublicKey): [PublicKey, number]Hash card data using JCS + SHA-256.
async function hashCardJcs(card: unknown): Promise<Uint8Array>Create a Solana connection.
function makeConnection(
rpcOrCluster?: string | "devnet" | "testnet" | "mainnet",
commitment?: Commitment
): ConnectionExample:
const connection = makeConnection("devnet");
// or
const connection = makeConnection("https://my-rpc.example.com");import { Connection, Keypair } from "@solana/web3.js";
import { createAgent, setCard, hashCardJcs } from "@pipeline/agent-registry-sdk";
async function main() {
const connection = new Connection("https://api.devnet.solana.com", "confirmed");
const payer = Keypair.generate();
// Airdrop
await connection.requestAirdrop(payer.publicKey, 1_000_000_000);
await new Promise(r => setTimeout(r, 1000));
// Create
const cardHash = await hashCardJcs({ name: "Agent v1" });
const agentPda = await createAgent({
connection,
payer,
cardUri: "https://example.com/v1.json",
cardHash,
});
console.log("β
Agent:", agentPda.toBase58());
// Update
const newHash = await hashCardJcs({ name: "Agent v2" });
await setCard({
connection,
payer,
agentPda,
cardUri: "https://example.com/v2.json",
cardHash: newHash,
});
console.log("β
Card updated");
}
main().catch(console.error);import { Connection, PublicKey } from "@solana/web3.js";
import { fetchAgentByCreator } from "@pipeline/agent-registry-sdk";
async function display(creatorAddress: string) {
const connection = new Connection("https://api.devnet.solana.com");
const creator = new PublicKey(creatorAddress);
const result = await fetchAgentByCreator(connection, creator);
if (!result) {
console.log("β Agent not found");
return;
}
const { pda, account } = result;
console.log("β
Agent PDA:", pda.toBase58());
console.log(" Creator:", account.creator.toBase58());
console.log(" Owner:", account.owner.toBase58());
console.log(" Card URI:", account.cardUri);
console.log(" Active:", account.isActive);
console.log(" Staking:", account.hasStaking);
}import { setMemory } from "@pipeline/agent-registry-sdk";
async function setIPFSMemory(agentPda: PublicKey) {
const cid = "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi";
await setMemory({
connection,
payer,
agentPda,
mode: 1, // CID mode
ptr: new TextEncoder().encode(cid),
});
console.log("β
IPFS memory set:", cid);
}type AgentAccount = {
version: number;
creator: PublicKey; // Immutable (PDA seed)
owner: PublicKey; // Mutable (transferable)
memoryMode: number; // 0=None, 1=CID, 2=IPNS, 3=URL
memoryPtr: Uint8Array; // Max 96 bytes
memoryHash: Uint8Array; // 32 bytes
cardUri: string; // Max 96 bytes
cardHash: Uint8Array; // 32 bytes
flags: number; // u32 bitfield
bump: number;
isActive: boolean; // Computed from flags
isLocked: boolean; // Computed from flags
hasStaking: boolean; // Computed from flags
};Flags:
| Flag | Bit | Description |
|---|---|---|
FLAG_ACTIVE |
0 | Agent is active |
FLAG_LOCKED |
1 | Memory is locked |
FLAG_HAS_STAKING |
2 | Staking enabled |
For advanced users, you can build instructions manually:
import {
createAgentInstruction,
setCardInstruction,
// ... other instruction builders
} from "@pipeline/agent-registry-sdk";
// Build instruction
const ix = createAgentInstruction({
agent: agentPda,
creatorSigner: payer.publicKey,
creator: payer.publicKey,
cardUri: "...",
cardHash: hash,
});
// Add to transaction
const tx = new Transaction().add(ix);
// ... sign and send manually| Program | ID | Description |
|---------|----|----- --|
| Agent Registry | 25wEsSLdsmZUisXuciyUXZqbpocsk5CJ7Uf6Eq553N8r | Agent management |
| Agent Staking | j3WMvorrddakwt69dqrQ5cve5APpyd4bxUCb9UF9Aqj | Token staking |
import { AGENT_PROGRAM_ID, AGENT_STAKING_PROGRAM_ID } from "@pipeline/agent-registry-sdk";
console.log(AGENT_PROGRAM_ID.toBase58());
// => 25wEsSLdsmZUisXuciyUXZqbpocsk5CJ7Uf6Eq553N8r
console.log(AGENT_STAKING_PROGRAM_ID.toBase58());
// => j3WMvorrddakwt69dqrQ5cve5APpyd4bxUCb9UF9AqjYou can override these by passing programId or stakingProgramId parameters to SDK functions.
MIT
Contributions welcome! See CONTRIBUTING.md.
- π§ Email: [email protected]
- π¦ Twitter: @pipeline_app
- π¬ Discord: Join our Discord
Made with β€οΈ by the Pipeline Team