begin embedded pds with xrpc endpoints and well-known

This commit is contained in:
Evan Jarrett
2025-10-14 20:25:08 -05:00
parent 2ee8bd8786
commit 18fe0684d3
17 changed files with 1252 additions and 29 deletions
+105
View File
@@ -0,0 +1,105 @@
package pds
import (
"context"
"crypto/ecdsa"
"fmt"
"os"
"path/filepath"
"github.com/bluesky-social/indigo/carstore"
"github.com/bluesky-social/indigo/models"
"github.com/bluesky-social/indigo/repo"
)
// HoldPDS is a minimal ATProto PDS implementation for a hold service
type HoldPDS struct {
did string
publicURL string
carstore carstore.CarStore
session *carstore.DeltaSession
repo *repo.Repo
dbPath string
uid models.Uid
signingKey *ecdsa.PrivateKey
}
// NewHoldPDS creates or opens a hold PDS with SQLite carstore
func NewHoldPDS(ctx context.Context, did, publicURL, dbPath, keyPath string) (*HoldPDS, error) {
// Ensure directory exists
dir := filepath.Dir(dbPath)
if err := os.MkdirAll(dir, 0755); err != nil {
return nil, fmt.Errorf("failed to create database directory: %w", err)
}
// Generate or load signing key
signingKey, err := GenerateOrLoadKey(keyPath)
if err != nil {
return nil, fmt.Errorf("failed to initialize signing key: %w", err)
}
// Create and open SQLite-backed carstore
// dbPath is the directory, carstore creates and opens db.sqlite3 inside it
sqlStore, err := carstore.NewSqliteStore(dbPath)
if err != nil {
return nil, fmt.Errorf("failed to create sqlite store: %w", err)
}
cs := sqlStore.CarStore()
// For a single-user hold, we use a fixed UID (1)
uid := models.Uid(1)
// Try to get existing repo head
_, err = cs.GetUserRepoHead(ctx, uid)
var session *carstore.DeltaSession
var r *repo.Repo
if err != nil {
// Repo doesn't exist yet, create new delta session
session, err = cs.NewDeltaSession(ctx, uid, nil)
if err != nil {
return nil, fmt.Errorf("failed to create delta session: %w", err)
}
// Create new repo with session as blockstore (needs pointer)
r = repo.NewRepo(ctx, did, session)
} else {
// TODO: Load existing repo
// For now, just create a new session
session, err = cs.NewDeltaSession(ctx, uid, nil)
if err != nil {
return nil, fmt.Errorf("failed to create delta session: %w", err)
}
r = repo.NewRepo(ctx, did, session)
}
return &HoldPDS{
did: did,
publicURL: publicURL,
carstore: cs,
session: session,
repo: r,
dbPath: dbPath,
uid: uid,
signingKey: signingKey,
}, nil
}
// DID returns the hold's DID
func (p *HoldPDS) DID() string {
return p.did
}
// SigningKey returns the hold's signing key
func (p *HoldPDS) SigningKey() *ecdsa.PrivateKey {
return p.signingKey
}
// Close closes the session and carstore
func (p *HoldPDS) Close() error {
// TODO: Close session properly
return nil
}