sx-pub Phase 3: federation — outbox, inbox, follow, delivery, HTTP signatures

New endpoints:
- GET /pub/outbox — paginated activity feed
- POST /pub/inbox — receive Follow/Accept/Publish from remote servers
- POST /pub/follow — follow a remote sx-pub server
- GET /pub/followers — list accepted followers
- GET /pub/following — list who we follow

Federation mechanics:
- HTTP Signature generation (RSA-SHA256) for signed outgoing requests
- HTTP Signature verification for incoming requests
- Auto-accept Follow → store follower → send Accept back
- Accept handling → update following state
- Publish mirroring → pin remote CID to local IPFS
- deliver_to_followers → fan out signed activities to all follower inboxes
- Publish now records activity in outbox for federation delivery

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-25 01:38:36 +00:00
parent cf130c4174
commit aa1d4d7a67
3 changed files with 632 additions and 1 deletions

View File

@@ -45,6 +45,13 @@ def _register_sx_helpers() -> None:
"pub-collection-items": _pub_collection_items,
"pub-resolve-document": _pub_resolve_document,
"pub-fetch-cid": _pub_fetch_cid,
"pub-outbox-data": _pub_outbox_data,
"pub-followers-data": _pub_followers_data,
"pub-following-data": _pub_following_data,
"pub-follow-remote": _pub_follow_remote,
"pub-process-inbox": _pub_process_inbox,
"pub-deliver-to-followers": _pub_deliver_to_followers,
"pub-request-body": _pub_request_body,
})
@@ -1764,3 +1771,38 @@ async def _pub_resolve_document(collection_slug, slug):
async def _pub_fetch_cid(cid):
from .pub_helpers import fetch_cid
return await fetch_cid(cid)
async def _pub_outbox_data(page=""):
from .pub_helpers import outbox_data
return await outbox_data(page)
async def _pub_followers_data():
from .pub_helpers import followers_data
return await followers_data()
async def _pub_following_data():
from .pub_helpers import following_data
return await following_data()
async def _pub_follow_remote(actor_url):
from .pub_helpers import follow_remote
return await follow_remote(actor_url)
async def _pub_process_inbox(body_sx):
from .pub_helpers import process_inbox
return await process_inbox(body_sx)
async def _pub_deliver_to_followers(activity_sx):
from .pub_helpers import deliver_to_followers
return await deliver_to_followers(activity_sx)
async def _pub_request_body():
from .pub_helpers import get_request_body
return await get_request_body()