| 1 | // Package blob implements the local relay's Blossom and NIP-96 file endpoints. |
| 2 | // |
| 3 | // Service stores immutable blob bytes under Config.Root/blobs, addressed by |
| 4 | // their lowercase SHA-256 digest. Metadata, uploader claims, moderation |
| 5 | // state, tombstones and multipart ranges live in the supplied storage.Store. |
| 6 | // New creates the metadata tables, reconciles files left by an interrupted |
| 7 | // upload and removes stale multipart state before returning a ready service. |
| 8 | // The caller drives service operations and mounts its Handler in the HTTP |
| 9 | // router. Startup and request work run within those calls. |
| 10 | // |
| 11 | // Put validates and hashes the input before making a new object visible. Its |
| 12 | // optional Commit callback runs in the metadata transaction, which lets a |
| 13 | // caller record related ownership or application state atomically with the |
| 14 | // blob claim. Get returns an open file only after metadata and moderation |
| 15 | // checks pass. Delete removes metadata transactionally and then removes the |
| 16 | // content file; DeleteForUploader removes one claim and removes shared bytes |
| 17 | // only when the final claim is gone. |
| 18 | // |
| 19 | // HTTP authorization is supplied by Config.Authorize. The callback returns |
| 20 | // the authenticated pubkey used for ownership and quota checks. Config's |
| 21 | // CanRead, IsOwner, ValidateUpload and RecordReport hooks provide the host |
| 22 | // policy and moderation boundaries without making this package own identity |
| 23 | // or event storage. Multipart uploads are reserved in the metadata database, |
| 24 | // staged under the blob root and finalized only after all declared ranges |
| 25 | // are present. |
| 26 | package blob |