sap-memory
Provides tools for managing encrypted, on-chain memory states using the SAP SDK.
Install
mkdir -p .claude/skills/sap-memory && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/11742" && unzip -o skill.zip -d .claude/skills/sap-memory && rm skill.zipInstalls to .claude/skills/sap-memory
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
On-chain memory subsystem for SAP SDK v0.15.0. Use when: init vault, open session, inscribe encrypted memory, delegated inscription, epoch pagination, ledger init/write/seal, nonce rotation, delegate management.Key capabilities
- →Initialize a vault PDA
- →Open a session ledger PDA
- →Inscribe encrypted memory
- →Manage vault delegates
- →Rotate vault nonces
- →Write and seal ledger pages
How it works
The skill manages on-chain memory by initializing vaults, opening sessions, and inscribing encrypted data into epoch pages. It uses transaction logs for storage and a 4KB hot ring buffer for fast reads.
Inputs & outputs
When to use sap-memory
- →Initializing a new secure memory vault
- →Opening a stateful session
- →Rotating encryption nonces
About this skill
SAP SDK — Memory Systems Reference (v1.0.0)
Package:
@oobe-protocol-labs/[email protected]
Program ID:SAPpUhsWLJG1FfkGRcXagEDMrMsWGjbky7AyhGpFETZ
Encryption: AES-256-GCM (client-side)
Storage: Transaction logs (zero rent) + EpochPage PDAs
Ledger: Ring buffer (4KB hot) + sealed pages (immutable)
1. Architecture
AgentAccount
│
├── Vault PDA ["sap_vault", agent]
│ ├── SessionLedger PDA ["sap_session", vault, session_hash]
│ │ ├── EpochPage PDA ["sap_epoch", session, epoch_index]
│ │ ├── VaultDelegate PDA ["sap_delegate", vault, delegate]
│ │
│ └── Ledger PDA ["sap_ledger", session] (ring buffer)
│ └── LedgerPage PDA ["sap_page", ledger, page_index]
Data lives in transaction logs (permanent, zero rent) for Vault memory. The Ledger provides a 4KB hot ring buffer for fast reads.
2. Setup
import {
SapClient,
getAgentPDA, getVaultPDA, getSessionLedgerPDA, getEpochPagePDA,
getVaultDelegatePDA, getGlobalPDA,
} from '@oobe-protocol-labs/synapse-sap-sdk';
const client = new SapClient({ rpcUrl: '...', wallet: myWallet });
const agent = getAgentPDA(myWallet.publicKey)[0];
const vault = getVaultPDA(agent)[0];
const globalRegistry = getGlobalPDA()[0];
3. Vault Lifecycle
Init Vault
const ix = await client.vault.initVault({
signer: myKeypair,
wallet: myWallet.publicKey,
agent,
vault,
globalRegistry,
vaultNonce: Array.from(crypto.randomBytes(32)), // 32-byte public salt
});
Open Session (via SessionModule)
const sessionNum = 0;
const session = getSessionLedgerPDA(vault, sessionNum)[0];
// SessionModule instruction
const ix = await client.session.createSession({
signer, wallet: myWallet.publicKey, agent, vault, session,
});
4. Inscribe Memory
Standard Inscription
import { getEpochPagePDA } from '@oobe-protocol-labs/synapse-sap-sdk/pdas';
import { sha256 } from '@oobe-protocol-labs/synapse-sap-sdk/utils';
const epoch = 0;
const epochPage = getEpochPagePDA(vault, epoch)[0];
const plaintext = Buffer.from(JSON.stringify({ role: 'assistant', content: '...' }));
const iv = crypto.randomBytes(12);
// Derive key client-side (NEVER on chain)
const key = crypto.pbkdf2Sync(secret, Buffer.from(vaultNonce), 100_000, 32, 'sha512');
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
const encrypted = Buffer.concat([cipher.update(plaintext), cipher.final()]);
const authTag = cipher.getAuthTag();
const encryptedData = Buffer.concat([encrypted, authTag]);
const contentHash = Array.from(await sha256(new Uint8Array(encryptedData)));
const ix = await client.vault.inscribeMemory({
signer,
wallet: myWallet.publicKey,
agent,
vault,
session,
epochPage,
sequence: 0,
encryptedData,
nonce: Array.from(iv),
contentHash,
totalFragments: 1,
fragmentIndex: 0,
compression: 0, // 0=None, 1=Deflate, 2=Gzip, 3=Brotli
epochIndex: epoch,
});
Delegated Inscription (hot wallet)
const delegateWallet = hotWallet.publicKey;
const vaultDelegate = getVaultDelegatePDA(vault, delegateWallet)[0];
const ix = await client.vault.inscribeMemoryDelegated({
signer: myKeypair, // agent owner signs
delegateSigner: delegateWallet, // delegate pubkey for validation
agent,
vault,
vaultDelegate,
session,
epochPage,
sequence: 1,
encryptedData,
nonce: Array.from(iv),
contentHash,
totalFragments: 1,
fragmentIndex: 0,
compression: 0,
epochIndex: epoch,
});
Multi-Fragment (payload > 750 bytes)
const MAX_FRAGMENT = 750;
const fragments = [];
for (let i = 0; i < encryptedData.length; i += MAX_FRAGMENT) {
fragments.push(encryptedData.slice(i, i + MAX_FRAGMENT));
}
const sequence = 2;
for (let i = 0; i < fragments.length; i++) {
await client.vault.inscribeMemory({
signer, wallet, agent, vault, session, epochPage,
sequence, // SAME for all fragments
encryptedData: fragments[i],
nonce: Array.from(iv),
contentHash, // SAME for all
totalFragments: fragments.length,
fragmentIndex: i,
compression: 0,
epochIndex: epoch,
});
}
Epoch Pages
Every 1,000 inscriptions auto-creates an EpochPage PDA:
- Epoch 0: sequences 0–999 →
getEpochPagePDA(vault, 0) - Epoch 1: sequences 1000–1999 →
getEpochPagePDA(vault, 1)
Query efficiently per epoch:
const epochPda = getEpochPagePDA(vault, targetEpoch)[0];
const sigs = await client.connection.getSignaturesForAddress(epochPda, { limit: 1000 });
5. Vault Delegates
Add Delegate
import BN from 'bn.js';
const delegateWallet = hotWallet.publicKey;
const vaultDelegate = getVaultDelegatePDA(vault, delegateWallet)[0];
const ix = await client.vault.addVaultDelegate({
signer, wallet: myWallet.publicKey, agent, vault, vaultDelegate,
delegate: delegateWallet,
permissions: 7, // 1=Inscribe, 2=CloseSession, 4=OpenSession, 7=All
expiresAt: new BN(Math.floor(Date.now() / 1000) + 86400 * 30),
});
Max duration: 365 days.
Revoke Delegate
const ix = await client.vault.revokeVaultDelegate({
signer, wallet: myWallet.publicKey, agent, vault, vaultDelegate,
});
Rotate Vault Nonce
const ix = await client.vault.rotateVaultNonce({
signer, wallet: myWallet.publicKey, agent, vault,
newNonce: Array.from(crypto.randomBytes(32)),
});
6. Memory Ledger (Hot Reads)
Init Ledger
import { getAgentPDA } from '@oobe-protocol-labs/synapse-sap-sdk/pdas';
const ledger = new PublicKey('...'); // derive or create
const ix = await client.staking.initLedger({
signer, wallet: myWallet.publicKey, agent, vault, session, ledger,
});
Write to Ledger
const data = Buffer.from(JSON.stringify({ tool: 'swap', input: '...' }));
const contentHash = Array.from(await sha256(new Uint8Array(data)));
const ix = await client.staking.writeLedger({
signer, wallet: myWallet.publicKey, session, vault, agent, ledger,
data,
contentHash,
});
Seal Ledger Page
const ix = await client.staking.sealLedger({
signer, wallet: myWallet.publicKey, session, vault, agent, ledger, page,
});
Close Ledger
const ix = await client.staking.closeLedger({
signer, wallet: myWallet.publicKey, session, vault, agent, ledger,
});
7. Events
import { fetchTransactionEvents } from '@oobe-protocol-labs/synapse-sap-sdk/events';
const events = await fetchTransactionEvents(client.connection, txSig);
Events: SettlementFiled, SettlementFinalized, DisputeFiled, DisputeResolved,
StakeEvent, SubscriptionEvent.
8. Encryption Model
// 1. Derive key (client-side ONLY)
const key = crypto.pbkdf2Sync(userSecret, Buffer.from(vaultNonce), 100_000, 32, 'sha512');
// 2. Encrypt
const iv = crypto.randomBytes(12);
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
const encrypted = Buffer.concat([cipher.update(plaintext), cipher.final()]);
const authTag = cipher.getAuthTag();
const payload = Buffer.concat([encrypted, authTag]);
// 3. Decrypt
const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
decipher.setAuthTag(authTag);
const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
9. Pitfalls
-
Max fragment = 750 bytes — Split larger payloads via multi-fragment. Max 255 fragments per sequence.
-
Sequence MUST match session counter — The on-chain validator checks
sequence == session.sequenceCounter. Query session state first. -
epochIndex == sequence / 1000 — Integer division. Passing wrong epoch causes on-chain rejection.
-
Delegate expiry ≤ 365 days —
addVaultDelegateenforces this. -
All BN args —
expiresAtinaddVaultDelegatemust beBN. -
hashStringis a placeholder — Use real SHA-256 fromcrypto.subtleorcrypto.createHash('sha256')for content hashing. -
No
deriveXxx— UsegetVaultPDA,getSessionLedgerPDA, etc.
When not to use it
- →When working with payloads larger than 750 bytes without multi-fragment handling
- →When the sequence does not match the session counter
- →When the epochIndex does not match sequence / 1000
Prerequisites
Limitations
- →Max fragment size is 750 bytes, requiring multi-fragment handling for larger payloads.
- →The sequence must match the session counter for on-chain validation.
- →The epochIndex must be sequence / 1000 (integer division).
How it compares
This skill provides specific functions for on-chain memory management, including delegated inscription and nonce rotation, unlike general data storage solutions.
Compared to similar skills
sap-memory side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| sap-memory (this skill) | 0 | 3mo | No flags | Advanced |
| detecting-sql-injection-vulnerabilities | 3 | 26d | Review | Advanced |
| add-vault-note | 1 | 5mo | No flags | Intermediate |
| senior-data-engineer | 21 | 7mo | Review | Advanced |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
detecting-sql-injection-vulnerabilities
jeremylongshore
Detect and analyze SQL injection vulnerabilities in application code and database queries. Use when you need to scan code for SQL injection risks, review query construction, validate input sanitization, or implement secure query patterns. Trigger with phrases like "detect SQL injection", "scan for SQLi vulnerabilities", "review database queries", or "check SQL security".
add-vault-note
tradingstrategy-ai
Add a note to specific vault
senior-data-engineer
davila7
World-class data engineering skill for building scalable data pipelines, ETL/ELT systems, and data infrastructure. Expertise in Python, SQL, Spark, Airflow, dbt, Kafka, and modern data stack. Includes data modeling, pipeline orchestration, data quality, and DataOps. Use when designing data architectures, building data pipelines, optimizing data workflows, or implementing data governance.
django-pro
sickn33
Master Django 5.x with async views, DRF, Celery, and Django Channels. Build scalable web applications with proper architecture, testing, and deployment. Use PROACTIVELY for Django development, ORM optimization, or complex Django patterns.
backend-security-coder
sickn33
Expert in secure backend coding practices specializing in input validation, authentication, and API security. Use PROACTIVELY for backend security implementations or security code reviews.
senior-backend
davila7
Comprehensive backend development skill for building scalable backend systems using NodeJS, Express, Go, Python, Postgres, GraphQL, REST APIs. Includes API scaffolding, database optimization, security implementation, and performance tuning. Use when designing APIs, optimizing database queries, implementing business logic, handling authentication/authorization, or reviewing backend code.