export const metadata = {
    title: 'Federation Example',
    description:
        'A description of how a typical federation flow might look like',
}

# Example

This page describes a typical federation flow between two servers, `a.social` and `b.social`, in several different contexts. {{ className: 'lead' }}

<Note>
    All examples, domains, names and timestamps are **fictional** and are used **for illustrative purposes only**.

    Some details have been slightly simplified for clarity.
</Note>

## Sending a Note

`@alice` on `a.social` creates a note with the following content:

```markdown
Hello, @joe@b.social! How are you doing today?
```

`@alice` has mentioned `@joe@b.social` in the note.

### Resolving the Mention

`a.social` resolves the mention by querying `b.social` for the user `joe` using WebFinger.

```bash {{ title: "cURL example" }}
curl https://b.social/.well-known/webfinger?resource=acct:joe@b.social -H "Accept: application/json"
```

`b.social` responds with the following JSON:

```json
{
    "subject": "acct:joe@b.social",
    "links": [
        { // [!code focus:5]
            "rel": "self",
            "type": "application/vnd.versia+json",
            "href": "https://b.social/.versia/entities/User/joe"
        }
    ]
}
```

<Note>
    In a real Versia implementation, usernames would **not** be included in user profile's URL, as they can be changed. Instead, the `id` could be used.
    
    This is done for brevity here.
</Note>

### Fetching the User

`a.social` fetches the user profile of `joe` from `b.social` using the URL provided in the WebFinger response.

```bash
# The request is signed by a.social's instance private key
curl https://b.social/.versia/entities/User/joe \
    -H "Accept: application/vnd.versia+json" \
    -H "User-Agent: CoolServer/1.0 (https://coolserver.com)" \
    -H "Versia-Signature: /CjB2L9bcvRg+uP19B4/rqy7Ji9/cqMFPlL3GVCIndnQjYyOpBzJEAl9weDnXm7Jrqa3y6sBC+EYWKThO2r9Bw==" \
    -H "Versia-Signed-By: a.social" \
    -H "Versia-Signed-At: 1729241687"
```

`b.social` responds with the following JSON:

```json
{
    "id": "bde22zi3ca8762", // [!code focus:3]
    "type": "User",
    "created_at": "2024-10-13T18:48:19Z",
    "avatar": {
        "image/webp": {
            "content": "https://cdn.b.social/avatars/joe.webp",
            "remote": true,
            "description": null,
            "size": null,
            "hash": null,
            "thumbhash": null,
            "width": null,
            "height": null,
            "fps": null,
            "duration": null
        }
    }, // [!code focus:3]
    "display_name": "Joe Swanson (Winter Arc :gigachad:)",
    "username": "joe",
    "bio": null,
    "header": null,
    "fields": [],
    "manually_approves_followers": false,
    "indexable": true,
    "extensions": {
        "pub.versia:custom_emojis": {
            "emojis": [
                {
                    "name": ":gigachad:",
                    "content": {
                        "image/png": {
                            "content": "https://cdn.b.social/emojis/gigachad.png",
                            "remote": true,
                            "description": null,
                            "size": null,
                            "hash": null,
                            "thumbhash": null,
                            "width": null,
                            "height": null,
                            "fps": null,
                            "duration": null
                        }
                    }
                }
            ]
        }
    },
}
```

`a.social` now has the user profile of `joe` and can display the note with the correct user information.

### Serializing the Note

Finally, `a.social` serializes the note to send it to `joe`.

```json
{
    "id": "782addd9-c051-4eea-8ba4-23d561d0c5bb", // [!code focus:6]
    "type": "Note",
    "created_at": "2024-12-01T12:19:06Z",
    "author": "alice",
    "category": "microblog",
    "content": {
        "text/html": { // [!code focus:12]
            "content": "Hello, <a class=\"u-url mention\" href=\"https://b.social/users/bde22zi3ca8762\">@joe@b.social</a>! How are you doing today?",
            "remote": false,
            "description": null,
            "size": null,
            "hash": null,
            "thumbhash": null,
            "width": null,
            "height": null,
            "fps": null,
            "duration": null
        },
        "text/plain": {
            "content": "Hello, @joe@b.social! How are you doing today?",
            "remote": false,
            "description": null,
            "size": null,
            "hash": null,
            "thumbhash": null,
            "width": null,
            "height": null,
            "fps": null,
            "duration": null
        }
    },
    "group": "public",
    "mentions": [ // [!code focus:3]
        "b.social:bde22zi3ca8762"
    ],
    "attachments": [],
    "is_sensitive": false,
    "previews": [],
    "replies_to": null,
    "quotes": null,
    "subject": null,
    "device": null,
}
```

It is now time for `a.social` to send the note to `joe`.

### Sending the Note

`a.social` sends the note to `joe`'s inbox at `b.social`.

```bash
curl -X POST https://b.social/.versia/v0.6/inbox \
    -H "Content-Type: application/vnd.versia+json; charset=utf-8" \
    -H "Accept: application/json" \
    -H "User-Agent: CoolerServer/1.0 (https://coolerserver.com)" \
    # The request is signed by Alice's private key
    -H "Versia-Signature: 9BrfplAPVH6OEqlV5eX7MazaZAInSCPODZcBEvMliBi/OwfbCAsezlb0O9jUX9ZcbBA68ThA4WUgS9V+42rfAQ==" \
    -H "Versia-Signed-By: a.social" \
    -H "Versia-Signed-At: 1733051946"
```

`b.social` responds with a `202 Accepted` status code.

### Displaying the Note

The software on `b.social` processes the note and shows it to `joe` using whatever interface it has.

`joe` can now see the note from `@alice` on `a.social` and respond to it.