Add IPFS node to L2 for federated content storage

- Add IPFS container to docker-compose
- Add ipfshttpclient dependency
- Add ipfs_client.py module for IPFS operations
- Add ipfs_cid field to Asset model and database schema
- Pin content on L2 IPFS when assets are published/registered

L2 now stores content on its own IPFS node, enabling
federation - content remains available even if L1 goes down.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
gilesb
2026-01-08 18:21:33 +00:00
parent 82cb1cf711
commit 96631e1e4c
5 changed files with 159 additions and 2 deletions

6
db.py
View File

@@ -52,6 +52,7 @@ CREATE TABLE IF NOT EXISTS users (
CREATE TABLE IF NOT EXISTS assets (
name VARCHAR(255) PRIMARY KEY,
content_hash VARCHAR(128) NOT NULL,
ipfs_cid VARCHAR(128),
asset_type VARCHAR(50) NOT NULL,
tags JSONB DEFAULT '[]'::jsonb,
metadata JSONB DEFAULT '{}'::jsonb,
@@ -248,12 +249,13 @@ async def create_asset(asset: dict) -> dict:
"""Create a new asset."""
async with get_connection() as conn:
row = await conn.fetchrow(
"""INSERT INTO assets (name, content_hash, asset_type, tags, metadata,
"""INSERT INTO assets (name, content_hash, ipfs_cid, asset_type, tags, metadata,
url, provenance, description, origin, owner, created_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
RETURNING *""",
asset["name"],
asset["content_hash"],
asset.get("ipfs_cid"),
asset["asset_type"],
json.dumps(asset.get("tags", [])),
json.dumps(asset.get("metadata", {})),