TypeScript SDK guide

@lumi-node/locus-sdk is a faithful TypeScript port of the Rust locus-client crate. PDA derivation, instruction layouts, and query/result hashing all match byte-for-byte, so attestations produced from TypeScript are identical to those produced from Rust.

It has two usage modes:

  • Read-only / browser-safegetProtocolUsage, the account decoders, and ArmsClient need no signer and bundle cleanly for the browser. The homepage counter uses exactly these.
  • Write pathsLocusClient methods take an explicit Keypair signer.

Install

npm install @lumi-node/locus-sdk @solana/web3.js

getProtocolUsage(connection, programId?)

Aggregate, on-chain-attested usage. Returns:

interface ProtocolUsage {
  agents: number;        // # AgentMemory accounts
  totalReads: bigint;    // Σ read_count   — attested retrievals
  totalWrites: bigint;   // Σ write_count  — memory commits
  attestations: number;  // # RetrievalAttestation accounts
  lastActivity: number | null; // latest last_updated (unix seconds)
}

It works by filtering getProgramAccounts on each account’s Anchor discriminator, then decoding the counters — no IDL or backend required.

ArmsClient

Typed wrapper over the ARMS REST API: place, get, query, stateRoot, healthz. See the ARMS REST API page.

LocusClient

const locus = new LocusClient(connection, {
  programId,            // optional, defaults to the deployed program
  armsEndpoint,         // optional, defaults to http://localhost:8080
});

PDA helpers

const [agentPda] = locus.agentPda(ownerPubkey);
const [attestationPda] = locus.attestationPda(agentPda, version, nonce);

Reads

const agent = await locus.getAgentMemory(ownerPubkey);       // AgentMemory | null
const att = await locus.fetchAttestation(attestationPda);    // RetrievalAttestation | null

Writes (require a Keypair)

await locus.initializeAgent(owner, readFeeLamports, metadataUri);
await locus.commitMemory(owner, rootBytes);     // Uint8Array(32)
await locus.updateReadFee(owner, newFee);

Attested retrieval

const result = await locus.queryWithAttestation(requester, agentOwner, embedding, k);
// result.neighbors, result.signature, result.attestationPda,
// result.queryHash, result.resultHash, result.version, result.nonce

This hits ARMS /query, hashes the query and result the same way the Rust SDK does, then records a RetrievalAttestation on-chain (paying the agent’s read fee).

Low-level instruction builders

Every write also has a pure instruction builder (initializeAgentIx, commitMemoryIx, updateReadFeeIx, attestRetrievalIx) returning a TransactionInstruction, so you can compose them into your own transactions or a wallet-adapter flow.

Hashing utilities

import { hashEmbedding, hashNeighbors } from "@lumi-node/locus-sdk";

Both return a 32-byte Uint8Array and match the Rust implementation exactly.