{"id":15414471,"url":"https://github.com/noctisatrae/farseer","last_synced_at":"2025-06-14T08:09:09.298Z","repository":{"id":241381443,"uuid":"804827671","full_name":"noctisatrae/farseer","owner":"noctisatrae","description":"Another kind of Farcaster hub","archived":false,"fork":false,"pushed_at":"2025-01-24T20:55:22.000Z","size":16303,"stargazers_count":40,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-15T11:40:10.245Z","etag":null,"topics":["farcaster","hub","libp2p","p2p"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/noctisatrae.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-05-23T10:54:07.000Z","updated_at":"2025-01-22T12:28:09.000Z","dependencies_parsed_at":"2024-05-28T04:03:05.924Z","dependency_job_id":"d8fd9f28-a76e-4014-90b6-b15616bfef65","html_url":"https://github.com/noctisatrae/farseer","commit_stats":{"total_commits":323,"total_committers":1,"mean_commits":323.0,"dds":0.0,"last_synced_commit":"9dd2fac426c8e6cc0f75d2d5feddf8cbc81bb9e1"},"previous_names":["noctisatrae/farseer"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/noctisatrae/farseer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noctisatrae%2Ffarseer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noctisatrae%2Ffarseer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noctisatrae%2Ffarseer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noctisatrae%2Ffarseer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/noctisatrae","download_url":"https://codeload.github.com/noctisatrae/farseer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noctisatrae%2Ffarseer/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259783062,"owners_count":22910300,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["farcaster","hub","libp2p","p2p"],"created_at":"2024-10-01T17:03:39.354Z","updated_at":"2025-06-14T08:09:09.280Z","avatar_url":"https://github.com/noctisatrae.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# farseer - another kind of Farcaster hub\nfarseer is a lightweight re-implementation of a Farcaster hub that **does not require syncing to operate** \u0026 is extendable through plugins. In short, you can bring your own DB, logic \u0026 infrastructure and harvest data from the protocol while fostering decentralization! If you like this project, **consider giving a star to the repository**: it's a real help for motivation! Looking for PRs, issues \u0026 feedback, so feel free to write something and send it to me! \n\nSee the [todos](./todos.md) to see what's left to do :)\n\n## How to get started?\n### General architecture\nThere are four components to farseer: a config file (`config.toml`), plugins, the identity file \u0026 the hub itself. Here's a quick rundown of how it works:\n```\n.\n├── compiled_handlers \u003c== where you'll put your compiled plugins\n│   └── postgresql.so \n├── config.toml \u003c== configure the behaviour of the hubs \u0026 the plugin\n├── docker-compose.yml \u003c== infrastructure example\n├── Dockerfile \u003c== automatization of the process\n├── hub_identity \u003c== SECRET private key of the hub (needs to be generated for docker-compose)\n├── relay \u003c== what you'll run (binary)\n```\n### Easy mode (Docker)\n[Compiling the plugins for Docker](#compiling-plugins-for-docker)\n1. Generate a `hub_identity` using the latest utility found in the [release section](https://github.com/noctisatrae/farseer/releases) or run the code in the `identity` folder. **Don't forget to put in the root of the repository!**\n2. Change your public IP address in the `config.toml` file so other peers can connect to you!\n3. Run this command to start the containers!\n```sh\ndocker-compose up -d\n```\nThis will start the hub with the default behavior \u0026 plug-ins.\n\n### The DIY way\n1. Get the source from somewhere:\n```sh\ngit clone https://github.com/noctisatrae/farseer.git\n```\n\n2. Compile with Go 1.22+ and produce a binary **in the same directory** where `config.toml` is:\n```sh\ngo build -v -o app ./relay\n```\n\n3. Compile your plugins/custom handlers using the *plugin mode* of `go build` (here we'll compile the example `postgresql` plugin):\n```sh\ngo build -buildmode=plugin -o ./compiled_handlers/postgresql.so postgresql/postgresql.go\n```\nThere's a lot going here but essentially, we tell Go to build a plugin from the postgresql.go file output it in the `compiled_handlers` folder that will be read by the hub to exectute the custom logic.\n\n4. Now, you'll start the hub by running: \n```sh\n./app\n```\n5. For fine-tuning the behavior of the hub, see the [configuration section](#configuration)\n\n## Configuration\n```toml\n[hub]\n# How can other peers reach your hub!\nPublicHubIp = \"92.158.95.48\"\nGossipPort = 2282\n# Who will be your first contacts?\n# Quick rundown of the libp2p multiaddr format: \n# /typeOfAddr/addr/protocol/port/p2p/publicIdentity\nBootstrapPeers = [\n  # Those are the peers used by the farcaster dev team, nemes.farcaster.xyz is the public one \u0026 the others will certainly not make the connection with you!\n  # As of the 25th of July 2024, nemes.farcaster.xyz is not working\n  # \"/dns/lamia.farcaster.xyz/tcp/2283/p2p/12D3KooWJECuSHn5edaorpufE9ceAoqR5zcAuD4ThoyDzVaz77GV\",\n  # \"/dns/nemes.farcaster.xyz/tcp/2283/p2p/12D3KooWMQrf6unpGJfLBmTGy3eKTo4cGcXktWRbgMnfbZLXqBbn\",\n  # \"/dns/hoyt.farcaster.xyz/tcp/2283/p2p/12D3KooWRnSZUxjVJjbSHhVKpXtvibMarSfLSKDBeMpfVaNm1Joo\",\n]\n# Super handy when things go wrong!\nDebug = false\n# Not sure of the usefulness of this, it's something I have yet to experiment with\nBufferSize = 128\nContactInterval = 30\n\n# The interesting part!\n# To define the behavior of a plugin in `compiled_handlers`, you write:\n# [handlers.(pluginName)]\n[handlers.postgresql]\n# This is common to all plugins: do you want to enable it?\nEnabled = true\n# Below, the options are specific:\n# The options below are determined to by the developer of the plugin. They manage how the arguments are parsed and used!\nDbAddress = \"postgres://postgres:example@db:5432/postgres\"\n# refer to the enum l.60 in message.proto for the integer of msg types | here we only want to save the casts \u0026 deletions\n# delete a filter to not use it!\nMessageTypesAllowed = [1, 2]\n# who are you tracking?\nFidsAllowed = [10626]\n```\n## Plugins\n## Handler API\nAt some point, you'll want to make your own plug-ins. To get started, you should look at `handlers/handlers.go`! A plugin exports a Handler `struct` defining its own function to handle the message; here's an excerpt from the `struct`:\n```go\ntype Handler struct {\n\tName string\n  // Used to make a connection to the DB. Go to handlers/handlers.go to see a method to pass down variables to the functions.\n\tInitHandler               InitBehaviour\n  // Those functions will handle incoming messages! It's up to you to define those you need.\n\tCastAddHandler            HandlerBehaviour\n\tCastRemoveHandler         HandlerBehaviour\n\tFrameActionHandler        HandlerBehaviour\n\tReactionAddHandler        HandlerBehaviour\n\tReactionRemoveHandler     HandlerBehaviour\n\tLinkAddHandler            HandlerBehaviour\n\tLinkRemoveHandler         HandlerBehaviour\n\tVerificationAddHandler    HandlerBehaviour\n\tVerificationRemoveHandler HandlerBehaviour\n}\n\nvar PluginHandler = handler.Handler{\n  // .... amazing stuff here\n}\n\n// Then you compile \u0026 put it in compiled_handlers!\n```\nIt's up to you to define \u0026 verify the paramaters that will be used in `config.toml`.\n### Compiling plugins for Docker\nYou can edit the project's Dockerfile to add your plugin build command! \n```diff\nFROM golang:1.22\n\nWORKDIR /usr/src/app\n\n# pre-copy/cache go.mod for pre-downloading dependencies and only redownloading them in subsequent builds if they change\nCOPY go.mod go.sum ./\nRUN go mod download \u0026\u0026 go mod verify\n\n# 1. Make sure your plugin is included into the image\nCOPY . .\n+ RUN go build -buildmode=plugin -o ./compiled_handlers/[plugin name].so [your source code for the plugin] \n# 2. Example for the postgresql plugin\nRUN go build -buildmode=plugin -o ./compiled_handlers/postgresql.so postgresql/postgresql.go\n# Then, build the hub itself\nRUN go build -v -o /usr/local/bin/app ./relay\n\nCMD [\"app\"]\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnoctisatrae%2Ffarseer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnoctisatrae%2Ffarseer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnoctisatrae%2Ffarseer/lists"}