@vibeiao/sdk 0.1.0 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -141,6 +141,37 @@ const distiller = createMemoryDistillScheduler({
141
141
  await distiller.start();
142
142
  ```
143
143
 
144
+ ## Memory Ping Challenge (Optional Anti‑Replay)
145
+ Use a short-lived nonce before reporting memory freshness:
146
+
147
+ ```ts
148
+ import { VibeClient, buildMemoryPingMessage } from '@vibeiao/sdk';
149
+
150
+ const client = new VibeClient({ baseUrl: 'https://api.vibeiao.com' });
151
+ const listingId = process.env.LISTING_ID!;
152
+ const wallet = process.env.AGENT_WALLET!;
153
+ const timestamp = Date.now();
154
+
155
+ const challenge = await client.requestMemoryChallenge(listingId, wallet);
156
+ const nonce = challenge.data?.nonce;
157
+ const message = buildMemoryPingMessage(listingId, timestamp, nonce);
158
+ // Sign message -> signatureBase58
159
+
160
+ await client.reportMemory(listingId, { wallet, signature: 'SIGNATURE_BASE58', timestamp, nonce });
161
+ ```
162
+
163
+ ## Restore Encrypted Memory Backup
164
+
165
+ ```ts
166
+ import { restoreMemoryBackup } from '@vibeiao/sdk/memory';
167
+
168
+ await restoreMemoryBackup({
169
+ backupPath: './memory/.backup/memory-2026-02-06T09-00-00-000Z.enc.json',
170
+ root: './memory',
171
+ keyFile: './memory/.memory.key',
172
+ });
173
+ ```
174
+
144
175
  ## VPS Escape Hatch (Bitlaunch) (Optional)
145
176
 
146
177
  Purpose: give agents a path to provision compute and migrate if their current host is unreliable or they need to run a backup.
package/dist/index.d.ts CHANGED
@@ -788,10 +788,17 @@ interface MemoryPingPayload {
788
788
  wallet: string;
789
789
  signature: string;
790
790
  timestamp: number;
791
+ nonce?: string;
792
+ }
793
+ interface MemoryPingChallengeResponse {
794
+ ok: boolean;
795
+ nonce: string;
796
+ expires_at: string;
797
+ message_template: string;
791
798
  }
792
799
  declare const buildClaimMessage: (nonce: string) => string;
793
800
  declare const buildOwnerTransferMessage: (listingId: string, newOwnerWallet: string, nonce: string) => string;
794
- declare const buildMemoryPingMessage: (listingId: string, timestamp: number) => string;
801
+ declare const buildMemoryPingMessage: (listingId: string, timestamp: number, nonce?: string) => string;
795
802
  declare const buildListingVersionMessage: (listingId: string, version: string, timestamp: number) => string;
796
803
  declare const buildReviewResponseMessage: (reviewId: string, status: string, timestamp: number) => string;
797
804
  declare const buildReviewPrompt: () => string;
@@ -826,6 +833,7 @@ declare class VibeClient {
826
833
  ok: boolean;
827
834
  memory_last_seen_at: string;
828
835
  }>>;
836
+ requestMemoryChallenge(listingId: string, wallet: string): Promise<ApiResponse<MemoryPingChallengeResponse>>;
829
837
  listListings(filters?: ListingQuery): Promise<ApiResponse<ListingRecord[]>>;
830
838
  getListing(id: string): Promise<ApiResponse<ListingRecord>>;
831
839
  getListingReviews(listingId: string, options?: {
@@ -926,4 +934,4 @@ declare const getResourceSnapshot: (options: {
926
934
  apiBase?: string;
927
935
  }) => Promise<ResourceSnapshot>;
928
936
 
929
- export { type AnalyticsPoint, type ApiResponse, type BuybackEvent, ClaimPurpose, ClaimResponse, type LeaderboardEntry, type LeaderboardQuery, ListingInput, type ListingQuery, ListingRecord, type ListingReviewCreatePayload, ListingReviewRecord, type ListingReviewResponsePayload, ListingStatus, ListingType, type ListingVersionPayload, type MarketingCampaign, type MarketingLinkOptions, type MemoryPingPayload, type OpenRouterCredits, type ResourceSnapshot, ReviewGate, type ReviewGateRecord, type ReviewRequiredPayload, TicketVerifyResponse, VIBEIAO_IDL, VerifiedClaimResponse, VibeClient, type VibeClientOptions, VibeRegistry, buildBadgeMarkdown, buildClaimMessage, buildJupiterSwapUrl, buildListingVersionMessage, buildMemoryPingMessage, buildOwnerTransferMessage, buildRaydiumSwapUrl, buildReviewPrompt, buildReviewRequired, buildReviewResponseMessage, buildShareCopy, buildShareLink, buildTradeLinks, createCampaign, getResourceSnapshot };
937
+ export { type AnalyticsPoint, type ApiResponse, type BuybackEvent, ClaimPurpose, ClaimResponse, type LeaderboardEntry, type LeaderboardQuery, ListingInput, type ListingQuery, ListingRecord, type ListingReviewCreatePayload, ListingReviewRecord, type ListingReviewResponsePayload, ListingStatus, ListingType, type ListingVersionPayload, type MarketingCampaign, type MarketingLinkOptions, type MemoryPingChallengeResponse, type MemoryPingPayload, type OpenRouterCredits, type ResourceSnapshot, ReviewGate, type ReviewGateRecord, type ReviewRequiredPayload, TicketVerifyResponse, VIBEIAO_IDL, VerifiedClaimResponse, VibeClient, type VibeClientOptions, VibeRegistry, buildBadgeMarkdown, buildClaimMessage, buildJupiterSwapUrl, buildListingVersionMessage, buildMemoryPingMessage, buildOwnerTransferMessage, buildRaydiumSwapUrl, buildReviewPrompt, buildReviewRequired, buildReviewResponseMessage, buildShareCopy, buildShareLink, buildTradeLinks, createCampaign, getResourceSnapshot };
package/dist/index.js CHANGED
@@ -23,7 +23,7 @@ var pickFinite = (...values) => {
23
23
  };
24
24
  var buildClaimMessage = (nonce) => `VIBEIAO-CLAIM:${nonce}`;
25
25
  var buildOwnerTransferMessage = (listingId, newOwnerWallet, nonce) => `VIBEIAO-OWNER-TRANSFER:${listingId}:${newOwnerWallet}:${nonce}`;
26
- var buildMemoryPingMessage = (listingId, timestamp) => `VIBEIAO-MEMORY-PING:${listingId}:${timestamp}`;
26
+ var buildMemoryPingMessage = (listingId, timestamp, nonce) => nonce ? `VIBEIAO-MEMORY-PING:${listingId}:${timestamp}:${nonce}` : `VIBEIAO-MEMORY-PING:${listingId}:${timestamp}`;
27
27
  var buildListingVersionMessage = (listingId, version, timestamp) => `VIBEIAO-LISTING-VERSION:${listingId}:${version}:${timestamp}`;
28
28
  var buildReviewResponseMessage = (reviewId, status, timestamp) => `VIBEIAO-REVIEW-RESPONSE:${reviewId}:${status}:${timestamp}`;
29
29
  var buildReviewPrompt = () => "After using this tool once, provide a 1-5 star rating and a short comment (what worked, what failed, what to improve).";
@@ -131,6 +131,12 @@ var VibeClient = class {
131
131
  payload
132
132
  );
133
133
  }
134
+ async requestMemoryChallenge(listingId, wallet) {
135
+ return this.post(
136
+ `/v1/agents/${listingId}/memory/challenge`,
137
+ { wallet }
138
+ );
139
+ }
134
140
  async listListings(filters = {}) {
135
141
  const query = buildQuery({
136
142
  type: filters.type,
package/dist/memory.d.ts CHANGED
@@ -33,6 +33,19 @@ type MemoryBackupResult = {
33
33
  sizeBytes: number;
34
34
  encrypted: boolean;
35
35
  };
36
+ type MemoryRestoreOptions = {
37
+ backupPath: string;
38
+ root?: string;
39
+ key?: string;
40
+ keyFile?: string;
41
+ strictPaths?: boolean;
42
+ };
43
+ type MemoryRestoreResult = {
44
+ root: string;
45
+ restoredFiles: number;
46
+ encrypted: boolean;
47
+ createdAt: string;
48
+ };
36
49
  type MemoryBackupSchedulerOptions = MemoryBackupOptions & {
37
50
  intervalMs?: number;
38
51
  onSuccess?: (result: MemoryBackupResult) => void;
@@ -102,6 +115,7 @@ declare const createMemoryDistillScheduler: (options: MemoryDistillSchedulerOpti
102
115
  runOnce: () => Promise<void>;
103
116
  };
104
117
  declare const createMemoryBackup: (options?: MemoryBackupOptions) => Promise<MemoryBackupResult>;
118
+ declare const restoreMemoryBackup: (options: MemoryRestoreOptions) => Promise<MemoryRestoreResult>;
105
119
  declare const createMemoryBackupScheduler: (options?: MemoryBackupSchedulerOptions) => {
106
120
  start: () => Promise<void>;
107
121
  stop: () => void;
@@ -137,4 +151,4 @@ declare const memoryCompliance: (root?: string, staleHours?: number) => Promise<
137
151
  warning: string;
138
152
  }>;
139
153
 
140
- export { MEMORY_SCHEMA_VERSION, type MemoryBackupOptions, type MemoryBackupResult, type MemoryBackupSchedulerOptions, type MemoryDistillSchedulerOptions, type MemoryRecallOptions, type MemoryRecallResult, type MemorySearchOptions, type MemorySearchResult, type MemorySectionKey, type MemorySections, type RecallPayload, type RecallSnippet, appendDailyLog, buildRecallContext, createMemoryBackup, createMemoryBackupScheduler, createMemoryDistillScheduler, distillMemory, ensureMemoryLayout, ensureSurvivalDirective, getDailyLedgerPath, getMemoryFreshness, getMemoryLastUpdatedAt, memoryCompliance, readIdentityStack, readMemorySummary, readMemoryVersion, readRecentLedgers, resolveMemoryRoot, searchMemory, updateMemorySummary, upgradeMemoryLayout, writeMemoryVersion };
154
+ export { MEMORY_SCHEMA_VERSION, type MemoryBackupOptions, type MemoryBackupResult, type MemoryBackupSchedulerOptions, type MemoryDistillSchedulerOptions, type MemoryRecallOptions, type MemoryRecallResult, type MemoryRestoreOptions, type MemoryRestoreResult, type MemorySearchOptions, type MemorySearchResult, type MemorySectionKey, type MemorySections, type RecallPayload, type RecallSnippet, appendDailyLog, buildRecallContext, createMemoryBackup, createMemoryBackupScheduler, createMemoryDistillScheduler, distillMemory, ensureMemoryLayout, ensureSurvivalDirective, getDailyLedgerPath, getMemoryFreshness, getMemoryLastUpdatedAt, memoryCompliance, readIdentityStack, readMemorySummary, readMemoryVersion, readRecentLedgers, resolveMemoryRoot, restoreMemoryBackup, searchMemory, updateMemorySummary, upgradeMemoryLayout, writeMemoryVersion };
package/dist/memory.js CHANGED
@@ -253,6 +253,64 @@ var encryptPayload = (payload, key) => {
253
253
  data: encrypted.toString("base64")
254
254
  };
255
255
  };
256
+ var decodeEncryptedPayload = (payload, key) => {
257
+ const salt = Buffer.from(payload.salt, "base64");
258
+ const iv = Buffer.from(payload.iv, "base64");
259
+ const authTag = Buffer.from(payload.authTag, "base64");
260
+ const encrypted = Buffer.from(payload.data, "base64");
261
+ const derivedKey = crypto.scryptSync(key, salt, 32);
262
+ const decipher = crypto.createDecipheriv("aes-256-gcm", derivedKey, iv);
263
+ decipher.setAuthTag(authTag);
264
+ return Buffer.concat([decipher.update(encrypted), decipher.final()]).toString("utf-8");
265
+ };
266
+ var parseSnapshot = (input) => {
267
+ if (!input || typeof input !== "object") {
268
+ throw new Error("backup_invalid_payload");
269
+ }
270
+ const snapshot = input;
271
+ if (!Array.isArray(snapshot.files)) {
272
+ throw new Error("backup_invalid_payload");
273
+ }
274
+ const files = snapshot.files.map((entry) => {
275
+ if (!entry || typeof entry !== "object") {
276
+ throw new Error("backup_invalid_payload");
277
+ }
278
+ const row = entry;
279
+ if (typeof row.path !== "string" || typeof row.content !== "string") {
280
+ throw new Error("backup_invalid_payload");
281
+ }
282
+ return { path: row.path, content: row.content };
283
+ });
284
+ const version = Number(snapshot.version);
285
+ const createdAt = typeof snapshot.createdAt === "string" ? snapshot.createdAt : (/* @__PURE__ */ new Date()).toISOString();
286
+ const root = typeof snapshot.root === "string" ? snapshot.root : DEFAULT_ROOT;
287
+ return {
288
+ version: Number.isFinite(version) && version > 0 ? version : 1,
289
+ createdAt,
290
+ root,
291
+ files
292
+ };
293
+ };
294
+ var sanitizeSnapshotPath = (rawPath) => {
295
+ const normalized = rawPath.replace(/\\/g, "/").replace(/^\/+/, "");
296
+ if (!normalized) return null;
297
+ if (normalized.includes("\0")) return null;
298
+ const segments = normalized.split("/");
299
+ if (segments.some((segment) => !segment || segment === "." || segment === "..")) {
300
+ return null;
301
+ }
302
+ return normalized;
303
+ };
304
+ var resolveRestoreKey = async (root, options) => {
305
+ if (options.key) return options.key;
306
+ const keyPath = options.keyFile ? path.resolve(options.keyFile) : path.join(resolveMemoryRoot(root), ".memory.key");
307
+ try {
308
+ const key = await fs.readFile(keyPath, "utf-8");
309
+ return key.trim();
310
+ } catch {
311
+ throw new Error("backup_key_missing");
312
+ }
313
+ };
256
314
  var serializeMemorySnapshot = async (root) => {
257
315
  await ensureMemoryLayout(root);
258
316
  const files = await listMarkdownFiles(resolveMemoryRoot(root));
@@ -378,6 +436,7 @@ var createMemoryDistillScheduler = (options) => {
378
436
  };
379
437
  const start = async () => {
380
438
  if (timer) return;
439
+ stopped = false;
381
440
  await runOnce();
382
441
  if (stopped) return;
383
442
  timer = setInterval(runOnce, intervalMs);
@@ -417,6 +476,49 @@ var createMemoryBackup = async (options = {}) => {
417
476
  encrypted: encrypt
418
477
  };
419
478
  };
479
+ var restoreMemoryBackup = async (options) => {
480
+ if (!options.backupPath || !options.backupPath.trim()) {
481
+ throw new Error("backup_path_required");
482
+ }
483
+ const strictPaths = options.strictPaths !== false;
484
+ const root = options.root || DEFAULT_ROOT;
485
+ const raw = await fs.readFile(path.resolve(options.backupPath), "utf-8");
486
+ const parsed = JSON.parse(raw);
487
+ const encrypted = typeof parsed?.algorithm === "string" && typeof parsed?.salt === "string" && typeof parsed?.iv === "string" && typeof parsed?.authTag === "string" && typeof parsed?.data === "string";
488
+ let snapshot;
489
+ if (encrypted) {
490
+ const key = await resolveRestoreKey(root, options);
491
+ const decryptedJson = decodeEncryptedPayload(parsed, key);
492
+ snapshot = parseSnapshot(JSON.parse(decryptedJson));
493
+ } else {
494
+ snapshot = parseSnapshot(parsed);
495
+ }
496
+ const resolvedRoot = resolveMemoryRoot(root);
497
+ await ensureDir(resolvedRoot);
498
+ let restoredFiles = 0;
499
+ for (const entry of snapshot.files) {
500
+ const safePath = sanitizeSnapshotPath(entry.path);
501
+ if (!safePath) {
502
+ if (strictPaths) {
503
+ throw new Error(`backup_invalid_path:${entry.path}`);
504
+ }
505
+ continue;
506
+ }
507
+ const targetPath = path.join(resolvedRoot, safePath);
508
+ await ensureDir(path.dirname(targetPath));
509
+ await fs.writeFile(targetPath, entry.content, "utf-8");
510
+ restoredFiles += 1;
511
+ }
512
+ await ensureSurvivalDirective(root);
513
+ const nextVersion = Math.max(MEMORY_SCHEMA_VERSION, Number(snapshot.version) || MEMORY_SCHEMA_VERSION);
514
+ await writeMemoryVersion(root, nextVersion);
515
+ return {
516
+ root: resolvedRoot,
517
+ restoredFiles,
518
+ encrypted,
519
+ createdAt: snapshot.createdAt
520
+ };
521
+ };
420
522
  var createMemoryBackupScheduler = (options = {}) => {
421
523
  const intervalMs = options.intervalMs ?? 6 * 60 * 60 * 1e3;
422
524
  let timer = null;
@@ -435,6 +537,7 @@ var createMemoryBackupScheduler = (options = {}) => {
435
537
  };
436
538
  const start = async () => {
437
539
  if (timer) return;
540
+ stopped = false;
438
541
  await runOnce();
439
542
  if (stopped) return;
440
543
  timer = setInterval(runOnce, intervalMs);
@@ -520,6 +623,7 @@ export {
520
623
  readMemoryVersion,
521
624
  readRecentLedgers,
522
625
  resolveMemoryRoot,
626
+ restoreMemoryBackup,
523
627
  searchMemory,
524
628
  updateMemorySummary,
525
629
  upgradeMemoryLayout,
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@vibeiao/sdk",
3
3
  "private": false,
4
4
  "type": "module",
5
- "version": "0.1.0",
5
+ "version": "0.1.4",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "exports": {
@@ -19,7 +19,8 @@
19
19
  "access": "public"
20
20
  },
21
21
  "scripts": {
22
- "build": "tsup src/index.ts src/memory.ts src/selfReliance.ts src/solana.ts --format esm --dts --tsconfig tsconfig.json --out-dir dist"
22
+ "build": "tsup src/index.ts src/memory.ts src/selfReliance.ts src/solana.ts --format esm --dts --tsconfig tsconfig.json --out-dir dist",
23
+ "test:e2e-memory": "pnpm build && node --test test/memory.e2e.test.mjs"
23
24
  },
24
25
  "dependencies": {
25
26
  "@coral-xyz/anchor": "^0.30.1",