mirror of
https://github.com/hzrd149/blossom.git
synced 2025-12-11 07:48:49 +00:00
Compare commits
1 Commits
1d855e1633
...
cashu-paym
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
988660d8b3 |
@@ -41,8 +41,8 @@ See the [BUDs](./buds) folder and specifically [BUD-01](./buds/01.md) and [BUD-0
|
|||||||
- [BUD-03: User Server List](./buds/03.md)
|
- [BUD-03: User Server List](./buds/03.md)
|
||||||
- [BUD-04: Mirroring blobs](./buds/04.md)
|
- [BUD-04: Mirroring blobs](./buds/04.md)
|
||||||
- [BUD-06: Upload requirements](./buds/06.md)
|
- [BUD-06: Upload requirements](./buds/06.md)
|
||||||
|
- [BUD-07: Paid upload and download](./buds/07.md)
|
||||||
- [BUD-08: Nostr File Metadata Tags](./buds/08.md)
|
- [BUD-08: Nostr File Metadata Tags](./buds/08.md)
|
||||||
- [BUD-10: Chunked blobs](./buds/10.md)
|
|
||||||
|
|
||||||
## Event kinds
|
## Event kinds
|
||||||
|
|
||||||
@@ -50,7 +50,6 @@ See the [BUDs](./buds) folder and specifically [BUD-01](./buds/01.md) and [BUD-0
|
|||||||
| ------- | ------------------- | ------------------ |
|
| ------- | ------------------- | ------------------ |
|
||||||
| `24242` | Authorization event | [01](./buds/01.md) |
|
| `24242` | Authorization event | [01](./buds/01.md) |
|
||||||
| `10063` | User Server List | [03](./buds/03.md) |
|
| `10063` | User Server List | [03](./buds/03.md) |
|
||||||
| `2001` | Merkle tree | [10](./buds/10.md) |
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -8,13 +8,7 @@ _All pubkeys MUST be in hex format_
|
|||||||
|
|
||||||
## Cross origin headers
|
## Cross origin headers
|
||||||
|
|
||||||
Servers MUST set the `Access-Control-Allow-Origin: *` header on all responses to ensure compatibility with applications hosted on other domains.
|
Servers MUST set the `Access-Control-Allow-Origin: *`, `Access-Control-Allow-Headers: Authorization,*` and `Access-Control-Allow-Methods: GET, PUT, DELETE` headers on all endpoints to ensure compatibility with apps hosted on other domains
|
||||||
|
|
||||||
For [preflight](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#preflighted_requests) (`OPTIONS`) requests,
|
|
||||||
servers MUST also set, at minimum, the `Access-Control-Allow-Headers: Authorization, *` and `Access-Control-Allow-Methods: GET, PUT,
|
|
||||||
DELETE` headers.
|
|
||||||
|
|
||||||
The header `Access-Control-Max-Age: 86400` MAY be set to cache the results of a preflight request for 24 hours.
|
|
||||||
|
|
||||||
## Authorization events
|
## Authorization events
|
||||||
|
|
||||||
|
|||||||
@@ -42,9 +42,9 @@ The endpoint MUST return a [Blob Descriptor](#blob-descriptor) if the upload was
|
|||||||
|
|
||||||
Servers MAY reject an upload for any reason and should respond with the appropriate HTTP `4xx` status code and an error message explaining the reason for the rejection
|
Servers MAY reject an upload for any reason and should respond with the appropriate HTTP `4xx` status code and an error message explaining the reason for the rejection
|
||||||
|
|
||||||
### Upload Authorization (Optional)
|
### Upload Authorization (required)
|
||||||
|
|
||||||
Servers MAY accept an authorization event when uploading blobs and should perform additional checks
|
Servers MUST accept an authorization event when uploading blobs and should perform additional checks
|
||||||
|
|
||||||
1. The `t` tag MUST be set to `upload`
|
1. The `t` tag MUST be set to `upload`
|
||||||
2. MUST contain at least one `x` tag matching the sha256 hash of the blob being uploaded
|
2. MUST contain at least one `x` tag matching the sha256 hash of the blob being uploaded
|
||||||
@@ -67,7 +67,7 @@ Example Authorization event:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## GET /list/pubkey - List Blobs (Optional)
|
## GET /list/pubkey - List Blobs
|
||||||
|
|
||||||
The `/list/<pubkey>` endpoint MUST return a JSON array of [Blob Descriptor](#blob-descriptor) that where uploaded by the specified pubkey
|
The `/list/<pubkey>` endpoint MUST return a JSON array of [Blob Descriptor](#blob-descriptor) that where uploaded by the specified pubkey
|
||||||
|
|
||||||
|
|||||||
36
buds/07.md
Normal file
36
buds/07.md
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
BUD-07
|
||||||
|
======
|
||||||
|
|
||||||
|
Paid upload and download
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
`draft` `optional`
|
||||||
|
|
||||||
|
Cashu payments for uploads and downloads
|
||||||
|
|
||||||
|
## Paid Upload
|
||||||
|
|
||||||
|
The server may require payment for uploading blob by returning a `402` status code the `PUT /upload` endpoint (and `HEAD /upload` if [BUD-06](./06.md) is supported)
|
||||||
|
|
||||||
|
## Paid Downloads
|
||||||
|
|
||||||
|
The server may also require payment for downloads by responding with a `402` status code for `GET /<sha256` and `HEAD /<sha256>` endpoints
|
||||||
|
|
||||||
|
## Payment Flow
|
||||||
|
|
||||||
|
When the server is requesting payment for an endpoint it MUST respond with `402` and a `X-Cashu` header containing a base64 encoded json object (payment request)
|
||||||
|
|
||||||
|
The payment request should contain an `amount`, `mints`, `unit`, and `pubkey` fields
|
||||||
|
|
||||||
|
- `amount` The amount of ecash being requested
|
||||||
|
- `mints` An array of mints that this server uses
|
||||||
|
- `unit` The cashu `unit` from the `mints`
|
||||||
|
- `pubkey` (optional) a 33 byte pubkey to lock the tokens too. see [NUT-11](https://github.com/cashubtc/nuts/blob/main/11.md)
|
||||||
|
|
||||||
|
When the client receives a `402` response and with a `X-Cashu` header it may retry the request with a payment
|
||||||
|
|
||||||
|
The payment should be a serialized cashu token according to [NUT-00](https://github.com/cashubtc/nuts/blob/main/00.md#v4-tokens)
|
||||||
|
|
||||||
|
## Payment Checks
|
||||||
|
|
||||||
|
Optionally a server may respond with `402` to the `HEAD /upload`, `HEAD /<sha156>` if it supports [BUD-06](./06.md)
|
||||||
115
buds/10.md
115
buds/10.md
@@ -1,115 +0,0 @@
|
|||||||
# BUD-10
|
|
||||||
|
|
||||||
## Chunked blobs
|
|
||||||
|
|
||||||
`draft` `optional`
|
|
||||||
|
|
||||||
Breaking large blobs into smaller chunks for distribution
|
|
||||||
|
|
||||||
### Chunking
|
|
||||||
|
|
||||||
The client MAY break large blobs into any number or size of chunks. although its recommended to use the size `1Mb` or `4Mb` for small and large chunks
|
|
||||||
|
|
||||||
Clients MUST NOT pad the remaining chunk, If clients need privacy they should use random chunk sizes and optionally encrypt the large blob
|
|
||||||
|
|
||||||
Clients MUST create a merkle tree using the chunk hashes as the leaf nodes
|
|
||||||
|
|
||||||
### Publishing
|
|
||||||
|
|
||||||
Clients should publish a `2001` kind event after chunking the file in order to store the list of chunks
|
|
||||||
|
|
||||||
The events MUST contain an ordered list of `chunk` tags with the sha256 hashes of the chunks
|
|
||||||
|
|
||||||
The `content` field MUST be a human readable description of the chunked file
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"tags": [
|
|
||||||
[ "chunk", "7e668b56a58c7891e0cf263ea3f093b75eebade23d663a45aa9920f347b3d671"],
|
|
||||||
[ "chunk", "9b9c44a91396f19fd8700986eb0586dff2dcccf96c75bc2caefef302bcd78da1"],
|
|
||||||
[ "chunk", "7a281548f1223664b855b10b08e59e84389ccabeb742517f6cd75eda2724a798"],
|
|
||||||
[ "chunk", "fadeccee86b123088bbc452df10e8fbc99d4c2f22a70ef7a35605ec8e439c345"],
|
|
||||||
[ "chunk", "5d62398419e6d136771541f3d2215e0ce31b1be45e99dbc64b43a4b734b447ca"],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The event MUST have an `x` tag with the sha256 hash of the ordered concatenated hashes of each chunk
|
|
||||||
|
|
||||||
Example using `xxd` and `sha256sum`:
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
hashes=(
|
|
||||||
"7e668b56a58c7891e0cf263ea3f093b75eebade23d663a45aa9920f347b3d671"
|
|
||||||
"9b9c44a91396f19fd8700986eb0586dff2dcccf96c75bc2caefef302bcd78da1"
|
|
||||||
"7a281548f1223664b855b10b08e59e84389ccabeb742517f6cd75eda2724a798"
|
|
||||||
"fadeccee86b123088bbc452df10e8fbc99d4c2f22a70ef7a35605ec8e439c345"
|
|
||||||
"5d62398419e6d136771541f3d2215e0ce31b1be45e99dbc64b43a4b734b447ca"
|
|
||||||
)
|
|
||||||
|
|
||||||
concatenated=""
|
|
||||||
for hex in "${hex_array[@]}"; do
|
|
||||||
concatenated="${concatenated}${hex}"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Chunks:"
|
|
||||||
printf '%s\n' "${hex_array[@]}"
|
|
||||||
|
|
||||||
echo -e "\nConcatenated:"
|
|
||||||
echo "$concatenated"
|
|
||||||
|
|
||||||
echo -e "\nRoot hash:"
|
|
||||||
echo "$concatenated" | xxd -r -p | sha256sum
|
|
||||||
```
|
|
||||||
|
|
||||||
The final `chunk` tags and `x` tag should look something like this
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"tags": [
|
|
||||||
[ "chunk", "7e668b56a58c7891e0cf263ea3f093b75eebade23d663a45aa9920f347b3d671"],
|
|
||||||
[ "chunk", "9b9c44a91396f19fd8700986eb0586dff2dcccf96c75bc2caefef302bcd78da1"],
|
|
||||||
[ "chunk", "7a281548f1223664b855b10b08e59e84389ccabeb742517f6cd75eda2724a798"],
|
|
||||||
[ "chunk", "fadeccee86b123088bbc452df10e8fbc99d4c2f22a70ef7a35605ec8e439c345"],
|
|
||||||
[ "chunk", "5d62398419e6d136771541f3d2215e0ce31b1be45e99dbc64b43a4b734b447ca"],
|
|
||||||
[ "x", "2d839865ac17d8bb10168490a88107637619f79dac21275fcec1705162581f39" ],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Metadata
|
|
||||||
|
|
||||||
The `2001` event MAY include additional metadata tags to help other clients know the filename, mime type or servers to download from
|
|
||||||
|
|
||||||
Metadata tags:
|
|
||||||
- `name` Filename
|
|
||||||
- `mime` Mime type of file
|
|
||||||
- `size` Total size in bytes of the file
|
|
||||||
- `server` (multiple) Recommended servers to download chunks from
|
|
||||||
|
|
||||||
### Examples
|
|
||||||
|
|
||||||
Example `2001` event
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "fd2f4da046851170576e7a09009e63f752dc469c61a24faca514b2cedfe641aa",
|
|
||||||
"pubkey": "5328e6c743a50271745e16476590ba7ea3dc591c65f3a5e2b03430814c1dabc0",
|
|
||||||
"created_at": 1731405194,
|
|
||||||
"kind": 2001,
|
|
||||||
"content": "Here is the original version",
|
|
||||||
"tags": [
|
|
||||||
[ "chunk", "7e668b56a58c7891e0cf263ea3f093b75eebade23d663a45aa9920f347b3d671"],
|
|
||||||
[ "chunk", "9b9c44a91396f19fd8700986eb0586dff2dcccf96c75bc2caefef302bcd78da1"],
|
|
||||||
[ "chunk", "7a281548f1223664b855b10b08e59e84389ccabeb742517f6cd75eda2724a798"],
|
|
||||||
[ "chunk", "fadeccee86b123088bbc452df10e8fbc99d4c2f22a70ef7a35605ec8e439c345"],
|
|
||||||
[ "chunk", "5d62398419e6d136771541f3d2215e0ce31b1be45e99dbc64b43a4b734b447ca"],
|
|
||||||
[ "x", "2d839865ac17d8bb10168490a88107637619f79dac21275fcec1705162581f39" ],
|
|
||||||
[ "name", "example.mp4" ],
|
|
||||||
[ "mime", "video/mp4" ],
|
|
||||||
[ "size", "4823449" ],
|
|
||||||
[ "server", "https://cdn.example.com" ],
|
|
||||||
[ "server", "https://nostr.download" ]
|
|
||||||
],
|
|
||||||
"sig": "cd589a4ea702185c69d1fec93a7704265071b674c5708a1da04d08bcba873f5277bc0abb379cbb014852fafa2ac951ed49abbdba60028a4f02ef4e31ff2599cb"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
Reference in New Issue
Block a user