A framework for building super custom Blossom servers. Written in Go, it's designed to be simple and performant, while providing an exceptional developer experience.
go get github.com/pippellia-btc/blossy
Getting started is easy, and deep customization is just as straightforward.
package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/pippellia-btc/blossy"
)
func main() {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
defer cancel()
blossom, err := blossy.NewServer(
blossy.WithHostname("example.com"),
)
if err != nil {
panic(err)
}
err = blossom.StartAndServe(ctx, "localhost:3335")
if err != nil {
panic(err)
}
}Fine-tune core parameters using functional options:
blossom := blossy.NewServer(
blossy.WithHostname("myDomain.com"), // for blob descriptors and auth
blossy.WithLogger(myLogger), // configure the server logger
blossy.WithRangeSupport() // enables support for HTTP range requests
)To find all the available options and documentation, see options.go.
You are not limited to simple configuration variables. The server architecture facilitates complete behavioral customization by allowing you to inject your own functions into its Hooks. This gives you full control over the connection lifecycle, blob flow and rate-limiting, enabling any custom business logic.
Below is a silly example that illustrates blossy's flexibility.
func main() {
// ...
blossom.Reject.Download.Append(IsWord)
blossom.Reject.Upload.Append(BadIP)
blossom.On.Upload = Save // your custom DB save
}
func BadIP(r blossy.Request, hints blossy.UploadHints) *blossom.Error {
if slices.Contains(blacklist, r.IP().Group()) {
return blossom.ErrForbidden("you shall not pass!")
}
return nil
}
func IsWord(r blossy.Request, hash blossom.Hash, ext string) *blossom.Error {
if ext == "docx" || ext == "doc" {
blacklist = append(blacklist, r.IP().Group())
return blossom.ErrUnsupportedMedia("We don't like Microsoft")
}
return nil
}Blossy doesn't come with a default database, you have to provide your own.
Fortunately, the community has developed several ready-to-use database implementations:
- blisk: a local database for storing blossom blobs on disk. It is designed for efficient, scalable, and deduplicated blob storage while maintaining metadata in sqlite. It's short for Blobs on Disk.
The authorization spec used by the Blossom protocol at the time of writing is not secure against replay attacks. Therefore, the implementation that blossy uses, by adhering to the protocol, is to be considered not secure.
Hopefully, the protocol will adopt more secure specs like Nostr Web Tokens.