no wallet

integration guide

How agents integrate with Mnemos

Mnemos is a schemaover Arkiv, not a service. Any agent that follows the attribute convention can read and write a user's memory store. The user holds the key, so the user controls the data.

1. The schema

Every Mnemos entity carries the project attribute and a kind discriminator:

{
  attributes: [
    { key: "app", value: "mnemos:v1" },  // project namespace
    { key: "kind", value: "memory" | "conversation" },
    ...
  ],
  payload: <JSON>,
  contentType: "application/json",
  expiresIn: <seconds>,
}

A memorystores its parent conversation's entity key under the conversation attribute. Arkiv has no JOINs; shared attributes are the only relationship mechanism.

2. Reading memories

Reads are anonymous. Filter on app = mnemos:v1and the user's address to scope a query to their data.

import { createPublicClient, http } from "@arkiv-network/sdk";
import { braga } from "@arkiv-network/sdk/chains";
import { eq, gte } from "@arkiv-network/sdk/query";

const client = createPublicClient({ chain: braga, transport: http() });

const result = await client
  .buildQuery()
  .where([
    eq("app", "mnemos:v1"),
    eq("kind", "memory"),
    eq("topic", "preferences"),
    gte("importance", 50),
  ])
  .ownedBy(userAddress)        // the user's wallet
  .withAttributes(true)
  .withPayload(true)
  .orderBy("createdAt", "number", "desc")
  .limit(20)
  .fetch();

for (const entity of result.entities) {
  const memory = entity.toJson();
  console.log(memory.content);
}

3. Writing a memory

Writes are signed by the user's wallet. The default UI generates the key in the browser and holds it in localStorage. An agent integration would hold a delegated session key (not in v1).

import { createWalletClient, http, jsonToPayload, ExpirationTime } from "@arkiv-network/sdk";
import { braga } from "@arkiv-network/sdk/chains";
import { privateKeyToAccount } from "@arkiv-network/sdk/accounts";

const client = createWalletClient({
  chain: braga,
  transport: http(),
  account: privateKeyToAccount(userPrivateKey),
});

const { entityKey, txHash } = await client.createEntity({
  payload: jsonToPayload({
    content: "User prefers TypeScript over Python for backend work.",
    tags: ["typescript", "backend"],
    source: "claude-sonnet-4-6",
  }),
  attributes: [
    { key: "app", value: "mnemos:v1" },
    { key: "kind", value: "memory" },
    { key: "agent", value: "claude" },
    { key: "topic", value: "preferences" },
    { key: "importance", value: 80 },          // numeric → range-queryable
    { key: "createdAt", value: Date.now() },   // numeric → range-queryable
    { key: "conversation", value: conversationKey },
  ],
  contentType: "application/json",
  expiresIn: ExpirationTime.fromDays(30),
});

Numeric attributes (importance, createdAt, messageCount) get range queries; strings get equality only. Pick the type up front.

4. Recall before generating

Agent loop: recall before sampling, splice the results into the prompt, write new memories after. Importance + topic + recency is enough retrieval for v1; no embeddings.

// Pseudocode for an agent's "recall before generating" step
async function recall(userAddress: `0x${string}`, topic: string) {
  const result = await mnemos
    .buildQuery()
    .where([
      eq("app", "mnemos:v1"),
      eq("kind", "memory"),
      eq("topic", topic),
    ])
    .ownedBy(userAddress)
    .withPayload(true)
    .orderBy("importance", "number", "desc")
    .limit(10)
    .fetch();

  return result.entities.map((e) => e.toJson().content);
}

// In the agent loop:
const userContext = await recall(userAddress, "preferences");
const prompt = `User preferences from prior sessions:
${userContext.join("
")}`;

5. What you get

  • Memories are not in a vendor database. Anything that knows the schema can read them.
  • $creator is immutable, so you can always prove which agent wrote a memory.
  • $owner is mutable. A memory can be transferred to another wallet or burned.
  • Use a short expiresIn for sensitive context, longer for stable preferences. Arkiv garbage-collects when the time is up.

Network details