npm install microfed
import { profile, auth, outbox } from 'microfed'
// Generate keypair for signing
const { publicKey, privateKey } = auth.generateKeypair()
// Create an actor
const actor = profile.createActor({
id: 'https://example.com/users/alice',
username: 'alice',
name: 'Alice',
publicKey
})
// Create a post
const note = outbox.createNote({
actor: actor.id,
content: '<p>Hello, Fediverse!</p>'
})
// Wrap in Create activity
const activity = outbox.wrapCreate(actor.id, note)
// Send to a remote inbox
await outbox.send({
activity,
inbox: 'https://remote.example/users/bob/inbox',
privateKey,
keyId: `${actor.id}#main-key`
})
import { createActor, createMinimalActor } from 'microfed/profile'
const actor = createActor({
id: 'https://example.com/users/alice',
username: 'alice',
name: 'Alice',
summary: '<p>Hello!</p>',
publicKey: '-----BEGIN PUBLIC KEY-----...',
icon: 'https://example.com/avatar.png'
})
import { generateKeypair, sign, verify } from 'microfed/auth'
// Generate RSA keypair
const { publicKey, privateKey } = generateKeypair()
// Sign a request
const headers = sign({
privateKey,
keyId: 'https://example.com/users/alice#main-key',
method: 'POST',
url: 'https://remote.example/inbox',
body: JSON.stringify(activity)
})
// Verify incoming signature
const valid = verify({
publicKey,
signature: req.headers.signature,
method: 'POST',
path: '/inbox',
headers: req.headers
})
import { createResponse, lookup, resolve } from 'microfed/webfinger'
// Create WebFinger response
const response = createResponse(
'alice@example.com',
'https://example.com/users/alice'
)
// Lookup remote actor
const actor = await resolve('bob@remote.example')
import { createHandler } from 'microfed/inbox'
const handler = createHandler({
getPublicKey: async (keyId) => {
// Fetch and return public key for keyId
},
handlers: {
Follow: async (activity) => {
console.log(`Follow from ${activity.actor}`)
},
Create: async (activity) => {
console.log(`New post: ${activity.object.content}`)
}
}
})
import { createNote, createFollow, send, deliver } from 'microfed/outbox'
// Create a post
const note = createNote({
actor: 'https://example.com/users/alice',
content: '<p>Hello!</p>'
})
// Create a follow
const follow = createFollow(
'https://example.com/users/alice',
'https://remote.example/users/bob'
)
// Deliver to multiple inboxes
const results = await deliver({
activity,
inboxes: ['https://server1.example/inbox', 'https://server2.example/inbox'],
privateKey,
keyId: 'https://example.com/users/alice#main-key'
})
Run the demo server:
npm run example
# → http://localhost:3000
Test it:
# WebFinger
curl "http://localhost:3000/.well-known/webfinger?resource=acct:alice@localhost:3000"
# Actor
curl -H "Accept: application/activity+json" http://localhost:3000/users/alice
npm test
Microfed decomposes a fediverse server into modular microservices:
| Module | Purpose |
|---|---|
| profile | Actor/user representation |
| auth | Cryptographic identity and signatures |
| webfinger | Actor discovery |
| inbox | Receive and process activities |
| outbox | Create and send activities |
Each module can be used independently or combined. See the Design Documentation for architecture details.
MIT