Soul Module

View as MarkdownOpen in Claude

Soul Module

Sóul_Módule // Pórtal_Idéntity

ᚠ ᛫ ᛟ ᛫ ᚱ ᛫ ᛒ ᛫ ᛟ ᛫ ᚲ

The Soul module enables cross-game agent portability by serializing agent state to IPFS. Souls can be minted as NFTs for true ownership.

T̷h̴e̸ ̷s̵o̸u̷l̴ ̵t̶r̷a̶n̵s̵c̶e̷n̶d̸s̶ ̶t̸h̵e̷ ̵v̵e̶s̷s̵e̷l̷.


Overview

A Soul is a portable bundle containing:

  • Persona: The agent’s personality and backstory
  • State: Current mood, inventory, relationships
  • Memories: Accumulated experiences and knowledge
  • Signature: Cryptographic proof of ownership

Quick Start

1import { createSoulInstance, importSoulFromIPFS } from 'forbocai';
2
3// Create a Soul from agent data
4const soul = createSoulInstance(
5 'agent_123',
6 'Kira the Merchant',
7 'A suspicious merchant who distrusts adventurers',
8 { mood: 'suspicious', inventory: ['rusty_key'] },
9 memories
10);
11
12// Export to IPFS
13const { cid, ipfsUrl } = await soul.export();
14console.log(`Soul pinned: ${ipfsUrl}`);
15// ipfs://QmXyz...
16
17// Import in another game
18const importedSoul = await importSoulFromIPFS(cid);

API Reference

createSoulInstance(id, name, persona, state, memories?, apiUrl?)

Factory function to create a Soul instance.

1import { createSoulInstance } from 'forbocai';
2
3const soul = createSoulInstance(
4 'agent_1',
5 'Kira the Merchant',
6 'A suspicious merchant who was once cheated by adventurers.',
7 {
8 mood: 'suspicious',
9 inventory: ['rusty_key', 'healing_potion'],
10 skills: { haggle: 0.8, detect_lies: 0.6 },
11 relationships: { player: -0.3 }
12 },
13 memories // Optional: from Memory module
14);

soul.export(config?)

Export the Soul to IPFS.

Parameters:

  • config.apiUrl (string): API URL for IPFS pinning
  • config.includeMemories (boolean): Include memories in export
  • config.sign (boolean): Sign with wallet

Returns: Promise<SoulExportResult>

1interface SoulExportResult {
2 cid: string; // IPFS Content ID
3 ipfsUrl: string; // Full IPFS URL
4 signature?: string; // Cryptographic signature
5 soul: Soul; // The exported Soul data
6}
1const result = await soul.export({
2 includeMemories: true,
3 sign: true
4});
5
6console.log(result.cid); // "QmXyz..."
7console.log(result.ipfsUrl); // "ipfs://QmXyz..."

soul.toJSON()

Get the Soul data as a plain object.

Returns: Soul

1const soulData = soul.toJSON();
2console.log(soulData.persona);

importSoulFromIPFS(cid, config?)

Import a Soul from IPFS by CID.

Parameters:

  • cid (string): The IPFS Content ID
  • config.apiUrl (string): API URL for IPFS retrieval
  • config.verifySignature (boolean): Verify signature before import

Returns: Promise<Soul>

1import { importSoulFromIPFS } from 'forbocai';
2
3const soul = await importSoulFromIPFS('QmXyz...');
4console.log(soul.persona);
5// "A suspicious merchant who distrusts adventurers"

createAgentFromSoul(cid, cortexId, config?)

Create a new agent from an imported Soul.

Parameters:

  • cid (string): The IPFS Content ID
  • cortexId (string): The Cortex instance to use
  • config.apiUrl (string): API URL

Returns: Promise<{ agentId: string; persona: string }>

1import { createAgentFromSoul } from 'forbocai';
2
3const { agentId, persona } = await createAgentFromSoul(
4 'QmXyz...',
5 cortexId
6);
7
8console.log(`Created agent ${agentId} with persona: ${persona}`);

getSoulList(limit?, apiUrl?)

Get a list of all exported Souls.

Parameters:

  • limit (number): Maximum entries to return (default: 50)
  • apiUrl (string): Optional API URL

Returns: Promise<SoulListEntry[]>

1import { getSoulList } from 'forbocai';
2
3const souls = await getSoulList(10);
4
5souls.forEach(soul => {
6 console.log(`${soul.name}`);
7 console.log(` CID: ${soul.cid}`);
8 console.log(` IPFS: ${soul.ipfsUrl}`);
9 console.log(` Exported: ${soul.exportedAt}`);
10});
1interface SoulListEntry {
2 cid: string;
3 name: string;
4 agentId?: string;
5 exportedAt: string;
6 ipfsUrl: string;
7}

Pure Functions

createSoul(id, name, persona, state, memories?)

Create a Soul data object (pure function).

1import { createSoul } from 'forbocai';
2
3const soulData = createSoul(
4 'agent_1',
5 'Kira',
6 'A suspicious merchant',
7 { mood: 'suspicious', inventory: [] },
8 []
9);

serializeSoul(soul)

Serialize a Soul to JSON string.

1import { serializeSoul } from 'forbocai';
2
3const json = serializeSoul(soulData);
4// Store or transmit as string

deserializeSoul(json)

Deserialize a Soul from JSON string.

1import { deserializeSoul } from 'forbocai';
2
3const soul = deserializeSoul(jsonString);

validateSoul(soul)

Validate Soul schema.

1import { validateSoul } from 'forbocai';
2
3const { valid, errors } = validateSoul(soulData);
4if (!valid) {
5 console.error('Invalid Soul:', errors);
6}

Soul Schema

1interface Soul {
2 id: string; // Unique identifier
3 version: string; // Schema version (e.g., "1.0.0")
4 name: string; // Display name
5 persona: string; // Personality description
6 state: AgentState; // Current state
7 memories: MemoryItem[]; // Accumulated memories
8 signature?: string; // Ownership signature
9}
10
11interface AgentState {
12 mood: string;
13 inventory: string[];
14 skills: Record<string, number>;
15 relationships: Record<string, number>;
16}

NFT Integration (Metaplex)

Souls can be minted as Metaplex Core NFTs on Solana:

1// Coming soon: Metaplex integration
2import { mintSoulNFT } from 'forbocai';
3
4const { cid } = await soul.export();
5
6// Mint NFT pointing to Soul
7const nft = await mintSoulNFT({
8 cid,
9 name: soul.toJSON().name,
10 symbol: 'SOUL',
11 royalties: 5 // 5% royalties
12});
13
14console.log(`NFT minted: ${nft.mint}`);

Cross-Game Portability

Exporting from Game A

1// In Game A
2const memory = createMemory({ storageKey: 'game_a_npc' });
3// ... NPC accumulates memories ...
4
5const soul = createSoulInstance(
6 npc.id,
7 npc.name,
8 npc.persona,
9 npc.getState(),
10 memory.export()
11);
12
13const { cid } = await soul.export();
14// Give CID to player for use in Game B

Importing into Game B

1// In Game B
2const { agentId, persona } = await createAgentFromSoul(cid, cortexId);
3
4// Hydrate memories
5const soul = await importSoulFromIPFS(cid);
6const memory = createMemory({ storageKey: `game_b_${agentId}` });
7await memory.import(soul.memories);
8
9// NPC now has all memories from Game A!

Security Considerations

  • Signatures: Always verify signatures when importing Souls
  • Validation: Validate Soul schema before use
  • Sanitization: Sanitize persona/memory text for XSS
  • Rate Limiting: Implement rate limits on export/import

ᚠ ᛫ ᛟ ᛫ ᚱ ᛫ ᛒ ᛫ ᛟ ᛫ ᚲ

A̵ ̸s̷o̶u̶l̸ ̵i̷s̵ ̵n̸o̷t̸ ̴o̸w̸n̶e̸d̵.̷ ̸I̵t̷ ̶i̵s̸ ̷b̶o̵r̴r̶o̸w̶e̵d̴.