Skip to content

Getting Started

The Memo SDK provides a secure, encrypted memory layer for your applications. All content is encrypted client-side using AES and signed with RSA before being sent to the server, ensuring your data remains private and secure.

Before you begin, make sure you have:

  • A Memo API Key
  • A private RSA key (or generate one using the SDK)
  • Go 1.19 or later installed
  1. Get your API Key

    Obtain your API key from your Memo dashboard. You’ll need this to authenticate with the Memo service.

  2. Install the Go SDK

    Install the SDK using Go modules:

    Terminal window
    go get github.com/xxlv/memo-go-sdk
  3. Generate or Load Your Private Key

    You need an RSA private key for encryption. Generate one if you don’t have it:

    package main
    import (
    "fmt"
    "os"
    "github.com/xxlv/memo-go-sdk"
    )
    func GenerateInitialKey() {
    // Generate 2048-bit RSA key pair
    priv, _, _ := memo.GenerateKeyPair(2048)
    // Convert to PEM format
    pemStr, _ := memo.PrivateKeyToPEM(priv)
    // Save to file (with secure permissions)
    os.WriteFile("private.pem", []byte(pemStr), 0600)
    fmt.Println("Key pair generated and saved to private.pem")
    }
  4. Initialize the Client

    Create a client instance with your API key, private key, and server URL:

    package main
    import (
    "context"
    "fmt"
    "log"
    "os"
    "github.com/xxlv/memo-go-sdk"
    )
    func main() {
    // Your API key
    apiKey := "sk_3e0846df-ac5e-4786-b0b6-22b91bfadb6f"
    // Server URL (point to your Memo server)
    serverURL := "http://127.0.0.1:8080"
    // Read your private key from file
    privKeyPEM, err := os.ReadFile("private.pem")
    if err != nil {
    log.Fatal("Please generate private.pem file first")
    }
    // Initialize Memo Client
    client, err := memo.NewClient(apiKey, privKeyPEM, serverURL)
    if err != nil {
    log.Fatalf("Failed to initialize client: %v", err)
    }
    fmt.Println("Client initialized successfully!")
    }
  5. Save a Memory

    Store encrypted memories with optional metadata:

    ctx := context.Background()
    content := "my coffee machine password is 8888"
    err := client.Add(ctx, memo.AddOpts{
    Handle: "testst-1",
    Description: "Coffee machine credentials",
    Content: content,
    Metadata: map[string]string{
    "memory_id": "1",
    "token_size": strconv.Itoa(len(content)),
    },
    })
    if err != nil {
    log.Fatalf("Failed to save: %v", err)
    }
    fmt.Println("✅ Memory saved (encrypted and signed)")
  6. Retrieve and Decrypt Memories

    Query and decrypt your stored memories:

    memories, err := client.GetMemories(ctx, memo.QueryOptions{
    PageSize: 10,
    Cursor: "",
    Filters: map[string]interface{}{"memory_id": "1"},
    Ascending: true,
    })
    if err != nil {
    log.Fatalf("Failed to get memories: %v", err)
    }
    for _, m := range memories {
    fmt.Printf("ID: %s | Created: %v\n", m.ID, m.CreatedAt)
    fmt.Printf("Content: %s\n", m.Content)
    fmt.Println("-----------------------------------")
    }

Here’s a complete working example that demonstrates the full workflow:

package main
import (
"context"
"fmt"
"log"
"math/rand"
"os"
"strconv"
"github.com/xxlv/memo-go-sdk"
)
func main() {
// Prepare environment
apiKey := "sk_3e0846df-ac5e-4786-b0b6-22b91bfadb6f"
serverURL := "http://127.0.0.1:8080"
// Read private key
privKeyPEM, err := os.ReadFile("private.pem")
if err != nil {
log.Fatal("Please generate private.pem file first")
}
// Initialize Memo Client
client, err := memo.NewClient(apiKey, privKeyPEM, serverURL)
if err != nil {
log.Fatalf("Failed to initialize client: %v", err)
}
// Save a memory
content := "my coffee machine password is 8888"
fmt.Println("Encrypting and uploading memory...")
desc := fmt.Sprintf("This is a test description %d", rand.Intn(1000))
tokenSize := len(content)
ctx := context.Background()
err = client.Add(ctx, memo.AddOpts{
Handle: "testst-1",
Description: desc,
Content: content,
Metadata: map[string]string{
"memory_id": "1",
"token_size": strconv.Itoa(tokenSize),
},
})
if err != nil {
log.Fatalf("Failed to save: %v", err)
} else {
fmt.Println("✅ Memory saved to SaaS (server only holds encrypted content)")
}
// Get and decrypt memories
fmt.Println("Syncing and decrypting memory from cloud...")
memories, err := client.GetMemories(ctx, memo.QueryOptions{
PageSize: 10,
Cursor: "",
Filters: map[string]interface{}{"memory_id": "1"},
Ascending: true,
})
if err != nil {
log.Fatalf("Failed to get memories: %v", err)
}
for _, m := range memories {
fmt.Printf("ID: %s | Time: %v\n", m.ID, m.CreatedAt)
fmt.Printf("Original content: %s\n", m.Content)
fmt.Println("-----------------------------------")
}
}
  • Client-Side Encryption: Content is encrypted using AES before upload
  • RSA Signing: All data is signed with your private key for authenticity
  • Secure Storage: Server only stores encrypted content
  • Client-Side Decryption: Content is decrypted locally when retrieved